Add "play" button in MiniEditorWindow (UI only)

At this moment the button isn't functional because the current frame
position is stored in the sprite (instead of the Editor). In this case,
when the "play" button is pressed, the mini-editor should show other
frames instead of the current one (should play the whole animation).
This commit is contained in:
David Capello 2013-01-20 21:58:16 -03:00
parent 337af9715e
commit 544a63cc28
12 changed files with 234 additions and 12 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

After

Width:  |  Height:  |  Size: 9.9 KiB

View File

@ -128,9 +128,9 @@
</tools>
<parts>
<part id="radio_normal" x="32" y="32" w="8" h="8" />
<part id="radio_selected" x="32" y="48" w="8" h="8" />
<part id="radio_disabled" x="32" y="32" w="8" h="8" />
<part id="radio_normal" x="64" y="64" w="8" h="8" />
<part id="radio_selected" x="64" y="80" w="8" h="8" />
<part id="radio_disabled" x="64" y="64" w="8" h="8" />
<part id="check_normal" x="48" y="64" w="8" h="8" />
<part id="check_selected" x="48" y="80" w="8" h="8" />
<part id="check_disabled" x="48" y="64" w="8" h="8" />
@ -151,6 +151,12 @@
<part id="window_close_button_normal" x="16" y= "0" w="9" h="11" />
<part id="window_close_button_hot" x="16" y="16" w="9" h="11" />
<part id="window_close_button_selected" x="16" y="32" w="9" h="11" />
<part id="window_play_button_normal" x="25" y= "0" w="9" h="11" />
<part id="window_play_button_hot" x="25" y="16" w="9" h="11" />
<part id="window_play_button_selected" x="25" y="32" w="9" h="11" />
<part id="window_stop_button_normal" x="34" y= "0" w="9" h="11" />
<part id="window_stop_button_hot" x="34" y="16" w="9" h="11" />
<part id="window_stop_button_selected" x="34" y="32" w="9" h="11" />
<part id="slider_full" x="0" y="144" w1="5" w2="6" w3="5" h1="5" h2="5" h3="6" />
<part id="slider_empty" x="16" y="144" w1="5" w2="6" w3="5" h1="5" h2="5" h3="6" />
<part id="slider_full_focused" x="0" y="160" w1="5" w2="6" w3="5" h1="5" h2="5" h3="6" />

74
src/skin/skin_button.h Normal file
View File

@ -0,0 +1,74 @@
/* ASEPRITE
* Copyright (C) 2001-2012 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef SKIN_BUTTON_H_INCLUDED
#define SKIN_BUTTON_H_INCLUDED
#include "skin/skin_parts.h"
#include "skin/skin_theme.h"
#include "ui/button.h"
#include "ui/graphics.h"
#include "ui/paint_event.h"
template<typename Base = ui::Button>
class SkinButton : public Base
{
public:
SkinButton(SkinPart partNormal,
SkinPart partHot,
SkinPart partSelected)
: Base("")
, m_partNormal(partNormal)
, m_partHot(partHot)
, m_partSelected(partSelected)
{
}
void setParts(SkinPart partNormal,
SkinPart partHot,
SkinPart partSelected) {
m_partNormal = partNormal;
m_partHot = partHot;
m_partSelected = partSelected;
invalidate();
}
protected:
void onPaint(ui::PaintEvent& ev) OVERRIDE {
gfx::Rect bounds(getClientBounds());
Graphics* g = ev.getGraphics();
SkinTheme* theme = static_cast<SkinTheme*>(getTheme());
SkinPart part;
if (isSelected())
part = m_partSelected;
else if (hasMouseOver())
part = m_partHot;
else
part = m_partNormal;
g->drawAlphaBitmap(theme->get_part(part), bounds.x, bounds.y);
}
private:
SkinPart m_partNormal;
SkinPart m_partHot;
SkinPart m_partSelected;
};
#endif

View File

@ -20,7 +20,7 @@
#define SKIN_PARTS_H_INCLUDED
// Available parts in the skin sheet
enum {
enum SkinPart {
PART_RADIO_NORMAL,
PART_RADIO_SELECTED,
@ -160,6 +160,14 @@ enum {
PART_WINDOW_CLOSE_BUTTON_HOT,
PART_WINDOW_CLOSE_BUTTON_SELECTED,
PART_WINDOW_PLAY_BUTTON_NORMAL,
PART_WINDOW_PLAY_BUTTON_HOT,
PART_WINDOW_PLAY_BUTTON_SELECTED,
PART_WINDOW_STOP_BUTTON_NORMAL,
PART_WINDOW_STOP_BUTTON_HOT,
PART_WINDOW_STOP_BUTTON_SELECTED,
PART_SLIDER_FULL_NW,
PART_SLIDER_FULL_N,
PART_SLIDER_FULL_NE,

View File

@ -165,6 +165,12 @@ SkinTheme::SkinTheme()
sheet_mapping["window_close_button_normal"] = PART_WINDOW_CLOSE_BUTTON_NORMAL;
sheet_mapping["window_close_button_hot"] = PART_WINDOW_CLOSE_BUTTON_HOT;
sheet_mapping["window_close_button_selected"] = PART_WINDOW_CLOSE_BUTTON_SELECTED;
sheet_mapping["window_play_button_normal"] = PART_WINDOW_PLAY_BUTTON_NORMAL;
sheet_mapping["window_play_button_hot"] = PART_WINDOW_PLAY_BUTTON_HOT;
sheet_mapping["window_play_button_selected"] = PART_WINDOW_PLAY_BUTTON_SELECTED;
sheet_mapping["window_stop_button_normal"] = PART_WINDOW_STOP_BUTTON_NORMAL;
sheet_mapping["window_stop_button_hot"] = PART_WINDOW_STOP_BUTTON_HOT;
sheet_mapping["window_stop_button_selected"] = PART_WINDOW_STOP_BUTTON_SELECTED;
sheet_mapping["slider_full"] = PART_SLIDER_FULL_NW;
sheet_mapping["slider_empty"] = PART_SLIDER_EMPTY_NW;
sheet_mapping["slider_full_focused"] = PART_SLIDER_FULL_FOCUSED_NW;
@ -394,6 +400,12 @@ void SkinTheme::reload_fonts()
m_minifont = loadFont("UserMiniFont", "skins/" + m_selected_skin + "/minifont.png");
}
gfx::Size SkinTheme::get_part_size(int part_i) const
{
BITMAP* bmp = get_part(part_i);
return gfx::Size(bmp->w, bmp->h);
}
void SkinTheme::onRegenerate()
{
scrollbar_size = 12 * jguiscale();
@ -787,7 +799,7 @@ void SkinTheme::getWindowMask(Widget* widget, Region& region)
region = widget->getBounds();
}
void SkinTheme::mapDecorativeWidget(Widget* widget)
void SkinTheme::setDecorativeWidgetBounds(Widget* widget)
{
if (widget->getId() == kThemeCloseButtonId) {
Widget* window = widget->getParent();
@ -797,8 +809,8 @@ void SkinTheme::mapDecorativeWidget(Widget* widget)
rect->y2 = m_part[PART_WINDOW_CLOSE_BUTTON_NORMAL]->h;
jrect_displace(rect,
window->rc->x2 - 3 - jrect_w(rect),
window->rc->y1 + 3);
window->rc->x2 - 3*jguiscale() - jrect_w(rect),
window->rc->y1 + 3*jguiscale());
jwidget_set_rect(widget, rect);
jrect_free(rect);

View File

@ -19,7 +19,7 @@
#ifndef SKIN_THEME_H_INCLUDED
#define SKIN_THEME_H_INCLUDED
#include "gfx/rect.h"
#include "gfx/fwd.h"
#include "skin/skin_parts.h"
#include "ui/color.h"
#include "ui/rect.h"
@ -122,7 +122,7 @@ public:
ui::Cursor* getCursor(ui::CursorType type);
void initWidget(ui::Widget* widget);
void getWindowMask(ui::Widget* widget, gfx::Region& region);
void mapDecorativeWidget(ui::Widget* widget);
void setDecorativeWidgetBounds(ui::Widget* widget);
void paintDesktop(ui::PaintEvent& ev);
void paintBox(ui::PaintEvent& ev);
@ -155,6 +155,7 @@ public:
BITMAP* get_part(int part_i) const { return m_part[part_i]; }
BITMAP* get_toolicon(const char* tool_id) const;
gfx::Size get_part_size(int part_i) const;
// helper functions to draw bounds/hlines with sheet parts
void draw_bounds_array(BITMAP* bmp, int x1, int y1, int x2, int y2, int parts[8]);

View File

@ -43,7 +43,7 @@ namespace ui {
virtual Cursor* getCursor(CursorType type) = 0;
virtual void initWidget(Widget* widget) = 0;
virtual void getWindowMask(ui::Widget* widget, gfx::Region& region) = 0;
virtual void mapDecorativeWidget(ui::Widget* widget) = 0;
virtual void setDecorativeWidgetBounds(ui::Widget* widget) = 0;
virtual void paintDesktop(PaintEvent& ev) = 0;
virtual void paintBox(PaintEvent& ev) = 0;

View File

@ -557,6 +557,11 @@ void Widget::saveLayout()
(*it)->saveLayout();
}
void Widget::setDecorativeWidgetBounds()
{
onSetDecorativeWidgetBounds();
}
/**********************************************************************/
/* position and geometry */
@ -1364,6 +1369,13 @@ void Widget::onInitTheme(InitThemeEvent& ev)
}
}
void Widget::onSetDecorativeWidgetBounds()
{
if (m_theme) {
m_theme->setDecorativeWidgetBounds(this);
}
}
void Widget::onEnable()
{
// Do nothing

View File

@ -235,6 +235,8 @@ namespace ui {
void loadLayout();
void saveLayout();
void setDecorativeWidgetBounds();
// ===============================================================
// POSITION & GEOMETRY
// ===============================================================
@ -327,6 +329,7 @@ namespace ui {
virtual void onPaint(PaintEvent& ev);
virtual void onBroadcastMouseMessage(WidgetsList& targets);
virtual void onInitTheme(InitThemeEvent& ev);
virtual void onSetDecorativeWidgetBounds();
virtual void onEnable();
virtual void onDisable();
virtual void onSelect();

View File

@ -517,12 +517,12 @@ void Window::windowSetPosition(JRect rect)
jrect_copy(this->rc, rect);
Rect cpos = getChildrenBounds();
/* set all the children to the same "child_pos" */
// Set all the children to the same "cpos"
UI_FOREACH_WIDGET(getChildren(), it) {
Widget* child = *it;
if (child->isDecorative())
child->getTheme()->mapDecorativeWidget(child);
child->setDecorativeWidgetBounds();
else
child->setBounds(cpos);
}

View File

@ -20,14 +20,17 @@
#include "widgets/mini_editor.h"
#include "base/bind.h"
#include "gfx/rect.h"
#include "ini_file.h"
#include "modules/editors.h"
#include "modules/gui.h"
#include "skin/skin_button.h"
#include "skin/skin_theme.h"
#include "ui/base.h"
#include "ui/button.h"
#include "ui/close_event.h"
#include "ui/message.h"
#include "ui/rect.h"
#include "ui/system.h"
#include "widgets/editor/editor.h"
@ -38,9 +41,78 @@ using namespace ui;
namespace widgets {
class MiniPlayButton : public SkinButton<Button>
{
public:
MiniPlayButton()
: SkinButton<Button>(PART_WINDOW_PLAY_BUTTON_NORMAL,
PART_WINDOW_PLAY_BUTTON_HOT,
PART_WINDOW_PLAY_BUTTON_SELECTED)
, m_isPlaying(false)
{
setup_bevels(this, 0, 0, 0, 0);
setDecorative(true);
}
bool isPlaying() { return m_isPlaying; }
protected:
void onClick(Event& ev) OVERRIDE
{
SkinButton<Button>::onClick(ev);
m_isPlaying = !m_isPlaying;
if (m_isPlaying)
setParts(PART_WINDOW_STOP_BUTTON_NORMAL,
PART_WINDOW_STOP_BUTTON_HOT,
PART_WINDOW_STOP_BUTTON_SELECTED);
else
setParts(PART_WINDOW_PLAY_BUTTON_NORMAL,
PART_WINDOW_PLAY_BUTTON_HOT,
PART_WINDOW_PLAY_BUTTON_SELECTED);
}
void onSetDecorativeWidgetBounds() OVERRIDE
{
SkinTheme* theme = static_cast<SkinTheme*>(getTheme());
Widget* window = getParent();
JRect rect = jrect_new(0, 0, 0, 0);
gfx::Size playSize = theme->get_part_size(PART_WINDOW_PLAY_BUTTON_NORMAL);
gfx::Size closeSize = theme->get_part_size(PART_WINDOW_CLOSE_BUTTON_NORMAL);
rect->x2 = playSize.w;
rect->y2 = playSize.h;
jrect_displace(rect,
window->rc->x2 - 3*jguiscale()
- playSize.w - 1*jguiscale() - closeSize.w,
window->rc->y1 + 3*jguiscale());
jwidget_set_rect(this, rect);
jrect_free(rect);
}
bool onProcessMessage(Message* msg) OVERRIDE
{
switch (msg->type) {
case JM_SETCURSOR:
jmouse_set_cursor(kArrowCursor);
return true;
}
return SkinButton<Button>::onProcessMessage(msg);
}
private:
bool m_isPlaying;
};
MiniEditorWindow::MiniEditorWindow()
: Window(false, "Mini-Editor")
, m_docView(NULL)
, m_playButton(new MiniPlayButton())
, m_playTimer(10)
{
child_spacing = 0;
setAutoRemap(false);
@ -56,6 +128,11 @@ MiniEditorWindow::MiniEditorWindow()
load_window_pos(this, "MiniEditor");
m_isEnabled = get_config_bool("MiniEditor", "Enabled", true);
m_playButton->Click.connect(Bind<void>(&MiniEditorWindow::onPlayClicked, this));
addChild(m_playButton);
m_playTimer.Tick.connect(&MiniEditorWindow::onPlaybackTick, this);
}
MiniEditorWindow::~MiniEditorWindow()
@ -90,6 +167,11 @@ void MiniEditorWindow::onClose(ui::CloseEvent& ev)
}
}
void MiniEditorWindow::onPlayClicked()
{
resetTimer();
}
void MiniEditorWindow::updateUsingEditor(Editor* editor)
{
if (!m_isEnabled || !editor) {
@ -141,4 +223,20 @@ void MiniEditorWindow::hideWindow()
closeWindow(NULL);
}
void MiniEditorWindow::resetTimer()
{
if (m_playButton->isPlaying()) {
m_playTimer.start();
}
else {
m_playTimer.stop();
}
}
void MiniEditorWindow::onPlaybackTick()
{
// TODO
invalidate();
}
} // namespace widgets

View File

@ -19,11 +19,14 @@
#ifndef WIDGETS_MINI_EDITOR_VIEW_H_INCLUDED
#define WIDGETS_MINI_EDITOR_VIEW_H_INCLUDED
#include "ui/timer.h"
#include "ui/window.h"
#include "widgets/document_view.h"
namespace widgets {
class MiniPlayButton;
class MiniEditorWindow : public ui::Window
{
public:
@ -39,10 +42,15 @@ namespace widgets {
void onClose(ui::CloseEvent& ev) OVERRIDE;
private:
void onPlayClicked();
void onPlaybackTick();
void hideWindow();
void resetTimer();
bool m_isEnabled;
DocumentView* m_docView;
MiniPlayButton* m_playButton;
ui::Timer m_playTimer;
};
} // namespace widgets