diff --git a/data/skins/default_skin/sheet.png b/data/skins/default_skin/sheet.png index 312303c0b..9205af386 100644 Binary files a/data/skins/default_skin/sheet.png and b/data/skins/default_skin/sheet.png differ diff --git a/data/skins/default_skin/skin.xml b/data/skins/default_skin/skin.xml index 535b4b262..bba20b71b 100644 --- a/data/skins/default_skin/skin.xml +++ b/data/skins/default_skin/skin.xml @@ -1,6 +1,6 @@ @@ -91,10 +91,22 @@ - + + + + + + + + + + + + + @@ -111,8 +123,51 @@ - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a2d40ef02..ea44cd2ef 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -213,6 +213,7 @@ add_library(aseprite-library raster/stock.cpp raster/undo.cpp settings/ui_settings_impl.cpp + skin/button_icon_impl.cpp skin/skin_theme.cpp skin/skin_property.cpp skin/skin_slider_property.cpp diff --git a/src/commands/cmd_configure_tools.cpp b/src/commands/cmd_configure_tools.cpp index 1277eb92f..f9f220fb9 100644 --- a/src/commands/cmd_configure_tools.cpp +++ b/src/commands/cmd_configure_tools.cpp @@ -36,6 +36,7 @@ #include "raster/pen.h" #include "raster/sprite.h" #include "settings/settings.h" +#include "skin/skin_parts.h" #include "sprite_wrappers.h" #include "tools/tool.h" #include "ui_context.h" @@ -276,9 +277,9 @@ void ConfigureTools::onExecute(Context* context) PenType type = tool_settings->getPen()->getType(); brush_type = group_button_new(3, 1, type, - GFX_BRUSH_CIRCLE, - GFX_BRUSH_SQUARE, - GFX_BRUSH_LINE); + PART_BRUSH_CIRCLE, + PART_BRUSH_SQUARE, + PART_BRUSH_LINE); brush_type->setName("brush_type"); } diff --git a/src/core/modules.cpp b/src/core/modules.cpp index ff9dd4530..a9a59f8cc 100644 --- a/src/core/modules.cpp +++ b/src/core/modules.cpp @@ -21,7 +21,6 @@ #include "core/modules.h" #include "effect/effect.h" #include "modules/editors.h" -#include "modules/gfx.h" #include "modules/gui.h" #include "modules/palettes.h" #include "modules/rootmenu.h" @@ -45,7 +44,6 @@ static Module module[] = DEF_MODULE(palette, 0), DEF_MODULE(effect, 0), - DEF_MODULE(graphics, REQUIRE_INTERFACE), DEF_MODULE(gui, REQUIRE_INTERFACE), DEF_MODULE(rootmenu, REQUIRE_INTERFACE), DEF_MODULE(editors, REQUIRE_INTERFACE), diff --git a/src/dialogs/aniedit.cpp b/src/dialogs/aniedit.cpp index 0f5e4401b..930fe04c4 100644 --- a/src/dialogs/aniedit.cpp +++ b/src/dialogs/aniedit.cpp @@ -150,7 +150,8 @@ static void anieditor_clean_clk(JWidget widget); static void anieditor_set_scroll(JWidget widget, int x, int y, bool use_refresh_region); static int anieditor_get_layer_index(JWidget widget, const Layer* layer); -static void icon_rect(BITMAP* icon, int x1, int y1, int x2, int y2, bool is_selected, bool is_hot, bool is_clk); +static void icon_rect(BITMAP* icon_normal, BITMAP* icon_selected, int x1, int y1, int x2, int y2, + bool is_selected, bool is_hot, bool is_clk); bool animation_editor_is_movingcel() { @@ -461,10 +462,11 @@ static bool anieditor_msg_proc(JWidget widget, JMessage msg) - HDRSIZE + anieditor->scroll_y) / LAYSIZE; - /* is the mouse on a layer's label? */ + // Is the mouse on a layer's label? if (mx < anieditor->separator_x) { - BITMAP* icon1 = get_gfx(GFX_BOX_SHOW); - BITMAP* icon2 = get_gfx(GFX_BOX_UNLOCK); + SkinTheme* theme = static_cast(widget->getTheme()); + BITMAP* icon1 = theme->get_part(PART_LAYER_VISIBLE); + BITMAP* icon2 = theme->get_part(PART_LAYER_EDITABLE); int x1, y1, x2, y2, y_mid; x1 = 0; @@ -1026,8 +1028,7 @@ static void anieditor_draw_layer(JWidget widget, JRect clip, int layer_index) { AniEditor* anieditor = anieditor_data(widget); Layer *layer = anieditor->layers[layer_index]; - BITMAP *icon1 = get_gfx(layer->is_readable() ? GFX_BOX_SHOW: GFX_BOX_HIDE); - BITMAP *icon2 = get_gfx(layer->is_writable() ? GFX_BOX_UNLOCK: GFX_BOX_LOCK); + SkinTheme* theme = static_cast(widget->getTheme()); bool selected_layer = (layer == anieditor->sprite->getCurrentLayer()); bool is_hot = (anieditor->hot_part == A_PART_LAYER && anieditor->hot_layer == layer_index); bool is_clk = (anieditor->clk_part == A_PART_LAYER && anieditor->clk_layer == layer_index); @@ -1036,6 +1037,10 @@ static void anieditor_draw_layer(JWidget widget, JRect clip, int layer_index) (is_clk ? ji_color_selected(): ji_color_face())); int fg = selected_layer ? ji_color_background(): ji_color_foreground(); + BITMAP* icon1 = theme->get_part(layer->is_readable() ? PART_LAYER_VISIBLE: PART_LAYER_HIDDEN); + BITMAP* icon2 = theme->get_part(layer->is_writable() ? PART_LAYER_EDITABLE: PART_LAYER_LOCKED); + BITMAP* icon1_selected = theme->get_part(layer->is_readable() ? PART_LAYER_VISIBLE_SELECTED: PART_LAYER_HIDDEN_SELECTED); + BITMAP* icon2_selected = theme->get_part(layer->is_writable() ? PART_LAYER_EDITABLE_SELECTED: PART_LAYER_LOCKED_SELECTED); int x1, y1, x2, y2, y_mid; int cx1, cy1, cx2, cy2; int u; @@ -1075,7 +1080,7 @@ static void anieditor_draw_layer(JWidget widget, JRect clip, int layer_index) u = x1+ICONSEP; /* draw the eye (readable flag) */ - icon_rect(icon1, + icon_rect(icon1, icon1_selected, u, y_mid-icon1->h/2-ICONBORDER, u+ICONBORDER+icon1->w+ICONBORDER-1, @@ -1089,7 +1094,7 @@ static void anieditor_draw_layer(JWidget widget, JRect clip, int layer_index) u += u+ICONBORDER+icon1->w+ICONBORDER; /* draw the padlock (writable flag) */ - icon_rect(icon2, + icon_rect(icon2, icon2_selected, u, y_mid-icon1->h/2-ICONBORDER, u+ICONBORDER+icon2->w+ICONBORDER-1, @@ -1102,12 +1107,12 @@ static void anieditor_draw_layer(JWidget widget, JRect clip, int layer_index) u += ICONBORDER+icon2->w+ICONBORDER+ICONSEP; - /* draw the layer's name */ + // Draw the layer's name. jdraw_text(ji_screen, widget->getFont(), layer->getName().c_str(), u, y_mid - ji_font_get_size(widget->getFont())/2, fg, bg, true, jguiscale()); - /* the background should be underlined */ + // The background should be underlined. if (layer->is_background()) { hline(ji_screen, u, @@ -1131,7 +1136,7 @@ static void anieditor_draw_layer_padding(JWidget widget) x2 = x1 + anieditor->separator_x - 1; y2 = y1 + LAYSIZE - 1; - /* padding in the bottom side */ + // Padding in the bottom side. if (y2+1 <= widget->rc->y2-1) { rectfill(ji_screen, x1, y2+1, x2, widget->rc->y2-1, theme->get_editor_face_color()); @@ -1499,12 +1504,12 @@ static int anieditor_get_layer_index(JWidget widget, const Layer* layer) return -1; } -/* auxiliary routine to draw an icon in the layer-part */ -static void icon_rect(BITMAP *icon, int x1, int y1, int x2, int y2, +// Auxiliary routine to draw an icon in the layer-part. +static void icon_rect(BITMAP* icon_normal, BITMAP* icon_selected, int x1, int y1, int x2, int y2, bool is_selected, bool is_hot, bool is_clk) { int icon_x = x1+ICONBORDER; - int icon_y = (y1+y2)/2-icon->h/2; + int icon_y = (y1+y2)/2-icon_normal->h/2; int facelight = is_hot && is_clk ? ji_color_faceshadow(): ji_color_facelight(); int faceshadow = is_hot && is_clk ? ji_color_facelight(): ji_color_faceshadow(); @@ -1517,8 +1522,9 @@ static void icon_rect(BITMAP *icon, int x1, int y1, int x2, int y2, ji_color_hotface()); } + set_alpha_blender(); if (is_selected) - jdraw_inverted_sprite(ji_screen, icon, icon_x, icon_y); + draw_trans_sprite(ji_screen, icon_selected, icon_x, icon_y); else - draw_sprite(ji_screen, icon, icon_x, icon_y); + draw_trans_sprite(ji_screen, icon_normal, icon_x, icon_y); } diff --git a/src/dialogs/filesel.cpp b/src/dialogs/filesel.cpp index 2f019c91c..3988079c5 100644 --- a/src/dialogs/filesel.cpp +++ b/src/dialogs/filesel.cpp @@ -39,6 +39,7 @@ #include "modules/gfx.h" #include "modules/gui.h" #include "recent_files.h" +#include "skin/skin_parts.h" #include "widgets/fileview.h" #if (DEVICE_SEPARATOR != 0) && (DEVICE_SEPARATOR != '\0') @@ -157,9 +158,21 @@ base::string ase_file_selector(const base::string& message, jwidget_focusrest(goforward, false); jwidget_focusrest(goup, false); - add_gfxicon_to_button(goback, GFX_ARROW_LEFT, JI_CENTER | JI_MIDDLE); - add_gfxicon_to_button(goforward, GFX_ARROW_RIGHT, JI_CENTER | JI_MIDDLE); - add_gfxicon_to_button(goup, GFX_ARROW_UP, JI_CENTER | JI_MIDDLE); + set_gfxicon_to_button(goback, + PART_COMBOBOX_ARROW_LEFT, + PART_COMBOBOX_ARROW_LEFT_SELECTED, + PART_COMBOBOX_ARROW_LEFT_DISABLED, + JI_CENTER | JI_MIDDLE); + set_gfxicon_to_button(goforward, + PART_COMBOBOX_ARROW_RIGHT, + PART_COMBOBOX_ARROW_RIGHT_SELECTED, + PART_COMBOBOX_ARROW_RIGHT_DISABLED, + JI_CENTER | JI_MIDDLE); + set_gfxicon_to_button(goup, + PART_COMBOBOX_ARROW_UP, + PART_COMBOBOX_ARROW_UP_SELECTED, + PART_COMBOBOX_ARROW_UP_DISABLED, + JI_CENTER | JI_MIDDLE); setup_mini_look(goback); setup_mini_look(goforward); diff --git a/src/gui/button.cpp b/src/gui/button.cpp index 45d41ad01..0c26c6ab2 100644 --- a/src/gui/button.cpp +++ b/src/gui/button.cpp @@ -24,46 +24,24 @@ ButtonBase::ButtonBase(const char* text, int type, int behaviorType, int drawType) : Widget(type) + , m_behaviorType(behaviorType) + , m_drawType(drawType) + , m_iconInterface(NULL) { - m_behaviorType = behaviorType; - m_drawType = drawType; - m_icon = NULL; - m_iconAlign = JI_LEFT | JI_MIDDLE; - this->setAlign(JI_CENTER | JI_MIDDLE); this->setText(text); jwidget_focusrest(this, true); // Initialize theme - this->type = m_drawType; // TODO Remove this nasty trick + this->type = m_drawType; // TODO Fix this nasty trick initTheme(); this->type = type; } ButtonBase::~ButtonBase() { -} - -void ButtonBase::setButtonIcon(BITMAP* icon) -{ - m_icon = icon; - invalidate(); -} - -void ButtonBase::setButtonIconAlign(int iconAlign) -{ - m_iconAlign = iconAlign; - invalidate(); -} - -BITMAP* ButtonBase::getButtonIcon() -{ - return m_icon; -} - -int ButtonBase::getButtonIconAlign() -{ - return m_iconAlign; + if (m_iconInterface) + m_iconInterface->destroy(); } int ButtonBase::getBehaviorType() const @@ -76,6 +54,16 @@ int ButtonBase::getDrawType() const return m_drawType; } +void ButtonBase::setIconInterface(IButtonIcon* iconInterface) +{ + if (m_iconInterface) + m_iconInterface->destroy(); + + m_iconInterface = iconInterface; + + invalidate(); +} + void ButtonBase::onClick(Event& ev) { // Fire Click() signal @@ -286,30 +274,11 @@ bool ButtonBase::onProcessMessage(JMessage msg) void ButtonBase::onPreferredSize(PreferredSizeEvent& ev) { struct jrect box, text, icon; - int icon_w = 0; - int icon_h = 0; - - if (m_icon) { - icon_w = m_icon->w; - icon_h = m_icon->h; - } - else { - switch (m_drawType) { - - case JI_CHECK: - icon_w = getTheme()->check_icon_size; - icon_h = getTheme()->check_icon_size; - break; - - case JI_RADIO: - icon_w = getTheme()->radio_icon_size; - icon_h = getTheme()->radio_icon_size; - break; - } - } jwidget_get_texticon_info(this, &box, &text, &icon, - m_iconAlign, icon_w, icon_h); + m_iconInterface ? m_iconInterface->getIconAlign(): 0, + m_iconInterface ? m_iconInterface->getWidth(): 0, + m_iconInterface ? m_iconInterface->getHeight(): 0); ev.setPreferredSize(this->border_width.l + jrect_w(&box) + this->border_width.r, this->border_width.t + jrect_h(&box) + this->border_width.b); diff --git a/src/gui/button.h b/src/gui/button.h index f4a7897bf..908a6b799 100644 --- a/src/gui/button.h +++ b/src/gui/button.h @@ -15,6 +15,19 @@ struct BITMAP; class Event; +class IButtonIcon +{ +public: + virtual ~IButtonIcon() { } + virtual void destroy() = 0; + virtual int getWidth() = 0; + virtual int getHeight() = 0; + virtual BITMAP* getNormalIcon() = 0; + virtual BITMAP* getSelectedIcon() = 0; + virtual BITMAP* getDisabledIcon() = 0; + virtual int getIconAlign() = 0; +}; + // Generic button class ButtonBase : public Widget { @@ -25,15 +38,16 @@ public: int drawType); virtual ~ButtonBase(); - void setButtonIcon(BITMAP* icon); - void setButtonIconAlign(int iconAlign); - - BITMAP* getButtonIcon(); - int getButtonIconAlign(); - int getBehaviorType() const; int getDrawType() const; + // Sets the interface used to get icons for the button depending its + // state. This interface is deleted automatically in the ButtonBase dtor. + void setIconInterface(IButtonIcon* iconInterface); + + // Used by the current theme to draw the button icon. + IButtonIcon* getIconInterface() const { return m_iconInterface; } + // Signals Signal1 Click; @@ -52,8 +66,7 @@ private: bool m_pressedStatus; int m_behaviorType; int m_drawType; - BITMAP* m_icon; - int m_iconAlign; + IButtonIcon* m_iconInterface; }; // Pushable button to execute commands diff --git a/src/gui/combobox.cpp b/src/gui/combobox.cpp index b69349740..9a49d4aba 100644 --- a/src/gui/combobox.cpp +++ b/src/gui/combobox.cpp @@ -14,6 +14,17 @@ using namespace gfx; +class ComboBoxButton : public Button +{ +public: + ComboBoxButton() : Button("") { } + + void onPaint(PaintEvent& ev) + { + getTheme()->paintComboBoxButton(ev); + } +}; + struct ComboBox::Item { std::string text; @@ -26,14 +37,13 @@ struct ComboBox::Item (index >= 0 && index < combobox->getItemCount()) static bool combobox_entry_msg_proc(JWidget widget, JMessage msg); -static bool combobox_button_msg_proc(JWidget widget, JMessage msg); static bool combobox_listbox_msg_proc(JWidget widget, JMessage msg); ComboBox::ComboBox() : Widget(JI_COMBOBOX) { m_entry = new Entry(256, ""); - m_button = new Button(""); + m_button = new ComboBoxButton(); m_window = NULL; m_selected = 0; m_editable = false; @@ -48,7 +58,6 @@ ComboBox::ComboBox() jwidget_focusrest(this, true); jwidget_add_hook(m_entry, JI_WIDGET, combobox_entry_msg_proc, NULL); - jwidget_add_hook(m_button, JI_WIDGET, combobox_button_msg_proc, NULL); jwidget_expansive(m_entry, true); @@ -359,18 +368,6 @@ static bool combobox_entry_msg_proc(JWidget widget, JMessage msg) return false; } -static bool combobox_button_msg_proc(JWidget widget, JMessage msg) -{ - switch (msg->type) { - - case JM_DRAW: - widget->getTheme()->draw_combobox_button((ButtonBase*)widget, &msg->draw.rect); - return true; - - } - return false; -} - static bool combobox_listbox_msg_proc(JWidget widget, JMessage msg) { ComboBox* combobox = reinterpret_cast(widget->user_data[0]); diff --git a/src/gui/draw.cpp b/src/gui/draw.cpp index 651e7bf28..73a4b8015 100644 --- a/src/gui/draw.cpp +++ b/src/gui/draw.cpp @@ -197,19 +197,6 @@ void jdraw_text(BITMAP* bmp, FONT* font, const char *s, int x, int y, } } -void jdraw_inverted_sprite(BITMAP *bmp, BITMAP *sprite, int x, int y) -{ - if (bitmap_color_depth(bmp) == 8) { - draw_character_ex(bmp, sprite, x, y, makecol(255, 255, 255), -1); - } - else { - drawing_mode(DRAW_MODE_TRANS, NULL, 0, 0); - set_invert_blender(0, 0, 0, 255); - draw_lit_sprite(bmp, sprite, x, y, 255); - drawing_mode(DRAW_MODE_SOLID, NULL, 0, 0); - } -} - void ji_move_region(JRegion region, int dx, int dy) { int c, nrects = JI_REGION_NUM_RECTS(region); diff --git a/src/gui/theme.cpp b/src/gui/theme.cpp index ee49f3e35..e502eee59 100644 --- a/src/gui/theme.cpp +++ b/src/gui/theme.cpp @@ -32,8 +32,6 @@ Theme::Theme() this->desktop_color = 0; this->textbox_fg_color = 0; this->textbox_bg_color = 0; - this->check_icon_size = 0; - this->radio_icon_size = 0; this->scrollbar_size = 0; this->guiscale = 1; } diff --git a/src/gui/theme.h b/src/gui/theme.h index 3e0a9fe7d..7e939f3ff 100644 --- a/src/gui/theme.h +++ b/src/gui/theme.h @@ -24,8 +24,6 @@ public: int desktop_color; int textbox_fg_color; int textbox_bg_color; - int check_icon_size; - int radio_icon_size; int scrollbar_size; int guiscale; @@ -62,7 +60,7 @@ public: virtual void draw_separator(JWidget widget, JRect clip) = 0; virtual void paintSlider(PaintEvent& ev) = 0; virtual void draw_combobox_entry(Entry* widget, JRect clip) = 0; - virtual void draw_combobox_button(ButtonBase* widget, JRect clip) = 0; + virtual void paintComboBoxButton(PaintEvent& ev) = 0; virtual void draw_textbox(JWidget widget, JRect clip) = 0; virtual void draw_view(JWidget widget, JRect clip) = 0; virtual void draw_view_scrollbar(JWidget widget, JRect clip) = 0; diff --git a/src/modules/gfx.cpp b/src/modules/gfx.cpp index 4d7700f2a..3289e3679 100644 --- a/src/modules/gfx.cpp +++ b/src/modules/gfx.cpp @@ -41,75 +41,8 @@ #include "skin/skin_theme.h" #include "widgets/editor.h" -static BITMAP* gfx_bmps[GFX_BITMAP_COUNT]; - -#include "modules/gfxdata.cpp" - using namespace gfx; -static void convert_data_to_bitmap(DATA *data, BITMAP** bmp) -{ - int scale = jguiscale(); - const char *p; - int x, y; - int black = makecol(0, 0, 0); - int gray = makecol(128, 128, 128); - int white = makecol(255, 255, 255); - int mask; - - *bmp = create_bitmap(data->w * scale, - data->h * scale); - mask = bitmap_mask_color(*bmp); - - p = data->line; - for (y=0; y<(*bmp)->h; y+=scale) { - for (x=0; x<(*bmp)->w; x+=scale) { - rectfill(*bmp, x, y, x+scale-1, y+scale-1, - (*p == '#') ? black: - (*p == '%') ? gray: - (*p == '.') ? white: mask); - p++; - } - } -} - -// Slot for App::PaletteChange signal -static void on_palette_change_signal() -{ - for (int c=0; cPaletteChange.connect(&on_palette_change_signal); - return 0; -} - -void exit_module_graphics() -{ - for (int c=0; cPaletteChange.connect(&on_palette_change_signal); - /* icon buttons */ - icon_buttons = jlist_new(); - return 0; } @@ -361,9 +357,6 @@ void exit_module_gui() ji_screen_created = false; } - jlist_free(icon_buttons); - icon_buttons = NULL; - jmanager_free(manager); // Destroy the default font of the current theme @@ -839,41 +832,21 @@ void setup_bevels(Widget* widget, int b1, int b2, int b3, int b4) widget->setProperty(skinProp); } -/**********************************************************************/ -/* Icon in buttons */ - -/* adds a button in the list of "icon_buttons" to restore the icon - when the palette changes, the "user_data[3]" is used to save the - "gfx_id" (the same ID that is used in "get_gfx()" from - "modules/gfx.c"), also this routine adds a hook to - JI_SIGNAL_DESTROY to remove the button from the "icon_buttons" - list when the widget is free */ -void add_gfxicon_to_button(ButtonBase* button, int gfx_id, int icon_align) +// Sets the IconInterface pointer interface of the button to show the +// specified set of icons. Each icon is a part of the SkinTheme. +void set_gfxicon_to_button(ButtonBase* button, + int normal_part_id, + int selected_part_id, + int disabled_part_id, int icon_align) { - button->user_data[3] = (void*)gfx_id; + ButtonIconImpl* buttonIcon = + new ButtonIconImpl(static_cast(button->getTheme()), + normal_part_id, + selected_part_id, + disabled_part_id, + icon_align); - jwidget_add_hook(button, JI_WIDGET, button_with_icon_msg_proc, NULL); - - button->setButtonIcon(get_gfx(gfx_id)); - button->setButtonIconAlign(icon_align); - - jlist_append(icon_buttons, button); -} - -void set_gfxicon_in_button(ButtonBase* button, int gfx_id) -{ - button->user_data[3] = (void*)gfx_id; - - button->setButtonIcon(get_gfx(gfx_id)); - - button->invalidate(); -} - -static bool button_with_icon_msg_proc(JWidget widget, JMessage msg) -{ - if (msg->type == JM_DESTROY) - jlist_remove(icon_buttons, widget); - return false; + button->setIconInterface(buttonIcon); } /**********************************************************************/ @@ -1295,11 +1268,4 @@ static void on_palette_change_signal() { // Regenerate the theme CurrentTheme::get()->regenerate(); - - // Fixup the icons - JLink link; - JI_LIST_FOR_EACH(icon_buttons, link) { - ButtonBase* button = reinterpret_cast(link->data); - button->setButtonIcon(get_gfx((size_t)button->user_data[3])); - } } diff --git a/src/modules/gui.h b/src/modules/gui.h index 27feeb4f0..06ed2f84a 100644 --- a/src/modules/gui.h +++ b/src/modules/gui.h @@ -94,8 +94,10 @@ void get_widgets(Widget* window, ...); void setup_mini_look(Widget* widget); void setup_bevels(Widget* widget, int b1, int b2, int b3, int b4); -void add_gfxicon_to_button(ButtonBase* button, int gfx_id, int icon_align); -void set_gfxicon_in_button(ButtonBase* button, int gfx_id); +void set_gfxicon_to_button(ButtonBase* button, + int normal_part_id, + int selected_part_id, + int disabled_part_id, int icon_align); RadioButton* radio_button_new(int radio_group, int b1, int b2, int b3, int b4); CheckBox* check_button_new(const char* text, int b1, int b2, int b3, int b4); diff --git a/src/skin/button_icon_impl.cpp b/src/skin/button_icon_impl.cpp new file mode 100644 index 000000000..eeb9131fc --- /dev/null +++ b/src/skin/button_icon_impl.cpp @@ -0,0 +1,73 @@ +/* ASE - Allegro Sprite Editor + * Copyright (C) 2001-2011 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 + */ + +#include "config.h" + +#include + +#include "skin/button_icon_impl.h" +#include "skin/skin_theme.h" + +ButtonIconImpl::ButtonIconImpl(SkinTheme* theme, + int normalIcon, + int selectedIcon, + int disabledIcon, + int iconAlign) + : m_theme(theme) + , m_normalIcon(normalIcon) + , m_selectedIcon(selectedIcon) + , m_disabledIcon(disabledIcon) + , m_iconAlign(iconAlign) +{ + ASSERT(theme != NULL); +} + +void ButtonIconImpl::destroy() +{ + delete this; +} + +int ButtonIconImpl::getWidth() +{ + return m_theme->get_part(m_normalIcon)->w; +} + +int ButtonIconImpl::getHeight() +{ + return m_theme->get_part(m_normalIcon)->h; +} + +BITMAP* ButtonIconImpl::getNormalIcon() +{ + return m_theme->get_part(m_normalIcon); +} + +BITMAP* ButtonIconImpl::getSelectedIcon() +{ + return m_theme->get_part(m_selectedIcon); +} + +BITMAP* ButtonIconImpl::getDisabledIcon() +{ + return m_theme->get_part(m_disabledIcon); +} + +int ButtonIconImpl::getIconAlign() +{ + return m_iconAlign; +} diff --git a/src/skin/button_icon_impl.h b/src/skin/button_icon_impl.h new file mode 100644 index 000000000..0cdd0ea80 --- /dev/null +++ b/src/skin/button_icon_impl.h @@ -0,0 +1,52 @@ +/* ASE - Allegro Sprite Editor + * Copyright (C) 2001-2011 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 BUTTON_ICON_IMPL_H_INCLUDED +#define BUTTON_ICON_IMPL_H_INCLUDED + +#include "gui/button.h" + +class SkinTheme; + +class ButtonIconImpl : public IButtonIcon +{ +public: + ButtonIconImpl(SkinTheme* theme, + int normalIcon, + int selectedIcon, + int disabledIcon, + int iconAlign); + + // IButtonIcon implementation + void destroy(); + int getWidth(); + int getHeight(); + BITMAP* getNormalIcon(); + BITMAP* getSelectedIcon(); + BITMAP* getDisabledIcon(); + int getIconAlign(); + +public: + SkinTheme* m_theme; + int m_normalIcon; + int m_selectedIcon; + int m_disabledIcon; + int m_iconAlign; +}; + +#endif diff --git a/src/skin/skin_parts.h b/src/skin/skin_parts.h index 206aa0793..490978b44 100644 --- a/src/skin/skin_parts.h +++ b/src/skin/skin_parts.h @@ -220,7 +220,18 @@ enum { PART_SEPARATOR_HORZ, PART_SEPARATOR_VERT, - PART_COMBOBOX_ARROW, + PART_COMBOBOX_ARROW_DOWN, + PART_COMBOBOX_ARROW_DOWN_SELECTED, + PART_COMBOBOX_ARROW_DOWN_DISABLED, + PART_COMBOBOX_ARROW_UP, + PART_COMBOBOX_ARROW_UP_SELECTED, + PART_COMBOBOX_ARROW_UP_DISABLED, + PART_COMBOBOX_ARROW_LEFT, + PART_COMBOBOX_ARROW_LEFT_SELECTED, + PART_COMBOBOX_ARROW_LEFT_DISABLED, + PART_COMBOBOX_ARROW_RIGHT, + PART_COMBOBOX_ARROW_RIGHT_SELECTED, + PART_COMBOBOX_ARROW_RIGHT_DISABLED, PART_TOOLBUTTON_NORMAL_NW, PART_TOOLBUTTON_NORMAL_N, @@ -249,6 +260,15 @@ enum { PART_TOOLBUTTON_LAST_SW, PART_TOOLBUTTON_LAST_W, + PART_TOOLBUTTON_PUSHED_NW, + PART_TOOLBUTTON_PUSHED_N, + PART_TOOLBUTTON_PUSHED_NE, + PART_TOOLBUTTON_PUSHED_E, + PART_TOOLBUTTON_PUSHED_SE, + PART_TOOLBUTTON_PUSHED_S, + PART_TOOLBUTTON_PUSHED_SW, + PART_TOOLBUTTON_PUSHED_W, + PART_TAB_NORMAL_NW, PART_TAB_NORMAL_N, PART_TAB_NORMAL_NE, @@ -397,6 +417,54 @@ enum { PART_TOOLTIP_ARROW_SW, PART_TOOLTIP_ARROW_W, + PART_ANI_FIRST, + PART_ANI_FIRST_SELECTED, + PART_ANI_FIRST_DISABLED, + PART_ANI_PREVIOUS, + PART_ANI_PREVIOUS_SELECTED, + PART_ANI_PREVIOUS_DISABLED, + PART_ANI_PLAY, + PART_ANI_PLAY_SELECTED, + PART_ANI_PLAY_DISABLED, + PART_ANI_NEXT, + PART_ANI_NEXT_SELECTED, + PART_ANI_NEXT_DISABLED, + PART_ANI_LAST, + PART_ANI_LAST_SELECTED, + PART_ANI_LAST_DISABLED, + + PART_TARGET_ONE, + PART_TARGET_ONE_SELECTED, + PART_TARGET_FRAMES, + PART_TARGET_FRAMES_SELECTED, + PART_TARGET_LAYERS, + PART_TARGET_LAYERS_SELECTED, + PART_TARGET_FRAMES_LAYERS, + PART_TARGET_FRAMES_LAYERS_SELECTED, + + PART_BRUSH_CIRCLE, + PART_BRUSH_CIRCLE_SELECTED, + PART_BRUSH_SQUARE, + PART_BRUSH_SQUARE_SELECTED, + PART_BRUSH_LINE, + PART_BRUSH_LINE_SELECTED, + + PART_SCALE_ARROW_1, + PART_SCALE_ARROW_2, + PART_SCALE_ARROW_3, + PART_ROTATE_ARROW_1, + PART_ROTATE_ARROW_2, + PART_ROTATE_ARROW_3, + + PART_LAYER_VISIBLE, + PART_LAYER_VISIBLE_SELECTED, + PART_LAYER_HIDDEN, + PART_LAYER_HIDDEN_SELECTED, + PART_LAYER_EDITABLE, + PART_LAYER_EDITABLE_SELECTED, + PART_LAYER_LOCKED, + PART_LAYER_LOCKED_SELECTED, + PARTS }; diff --git a/src/skin/skin_theme.cpp b/src/skin/skin_theme.cpp index 4c920f4d7..b6da2c24e 100644 --- a/src/skin/skin_theme.cpp +++ b/src/skin/skin_theme.cpp @@ -32,6 +32,7 @@ #include "loadpng.h" #include "modules/gui.h" #include "resource_finder.h" +#include "skin/button_icon_impl.h" #include "skin/skin_property.h" #include "skin/skin_slider_property.h" #include "skin/skin_theme.h" @@ -120,10 +121,22 @@ SkinTheme::SkinTheme() sheet_mapping["mini_slider_thumb_focused"] = PART_MINI_SLIDER_THUMB_FOCUSED; sheet_mapping["separator_horz"] = PART_SEPARATOR_HORZ; sheet_mapping["separator_vert"] = PART_SEPARATOR_VERT; - sheet_mapping["combobox_arrow"] = PART_COMBOBOX_ARROW; + sheet_mapping["combobox_arrow_down"] = PART_COMBOBOX_ARROW_DOWN; + sheet_mapping["combobox_arrow_down_selected"] = PART_COMBOBOX_ARROW_DOWN_SELECTED; + sheet_mapping["combobox_arrow_down_disabled"] = PART_COMBOBOX_ARROW_DOWN_DISABLED; + sheet_mapping["combobox_arrow_up"] = PART_COMBOBOX_ARROW_UP; + sheet_mapping["combobox_arrow_up_selected"] = PART_COMBOBOX_ARROW_UP_SELECTED; + sheet_mapping["combobox_arrow_up_disabled"] = PART_COMBOBOX_ARROW_UP_DISABLED; + sheet_mapping["combobox_arrow_left"] = PART_COMBOBOX_ARROW_LEFT; + sheet_mapping["combobox_arrow_left_selected"] = PART_COMBOBOX_ARROW_LEFT_SELECTED; + sheet_mapping["combobox_arrow_left_disabled"] = PART_COMBOBOX_ARROW_LEFT_DISABLED; + sheet_mapping["combobox_arrow_right"] = PART_COMBOBOX_ARROW_RIGHT; + sheet_mapping["combobox_arrow_right_selected"] = PART_COMBOBOX_ARROW_RIGHT_SELECTED; + sheet_mapping["combobox_arrow_right_disabled"] = PART_COMBOBOX_ARROW_RIGHT_DISABLED; sheet_mapping["toolbutton_normal"] = PART_TOOLBUTTON_NORMAL_NW; sheet_mapping["toolbutton_hot"] = PART_TOOLBUTTON_HOT_NW; sheet_mapping["toolbutton_last"] = PART_TOOLBUTTON_LAST_NW; + sheet_mapping["toolbutton_pushed"] = PART_TOOLBUTTON_PUSHED_NW; sheet_mapping["tab_normal"] = PART_TAB_NORMAL_NW; sheet_mapping["tab_selected"] = PART_TAB_SELECTED_NW; sheet_mapping["tab_bottom_selected"] = PART_TAB_BOTTOM_SELECTED_NW; @@ -142,6 +155,49 @@ SkinTheme::SkinTheme() sheet_mapping["scrollbar_thumb"] = PART_SCROLLBAR_THUMB_NW; sheet_mapping["tooltip"] = PART_TOOLTIP_NW; sheet_mapping["tooltip_arrow"] = PART_TOOLTIP_ARROW_NW; + sheet_mapping["ani_first"] = PART_ANI_FIRST; + sheet_mapping["ani_first_selected"] = PART_ANI_FIRST_SELECTED; + sheet_mapping["ani_first_disabled"] = PART_ANI_FIRST_DISABLED; + sheet_mapping["ani_previous"] = PART_ANI_PREVIOUS; + sheet_mapping["ani_previous_selected"] = PART_ANI_PREVIOUS_SELECTED; + sheet_mapping["ani_previous_disabled"] = PART_ANI_PREVIOUS_DISABLED; + sheet_mapping["ani_play"] = PART_ANI_PLAY; + sheet_mapping["ani_play_selected"] = PART_ANI_PLAY_SELECTED; + sheet_mapping["ani_play_disabled"] = PART_ANI_PLAY_DISABLED; + sheet_mapping["ani_next"] = PART_ANI_NEXT; + sheet_mapping["ani_next_selected"] = PART_ANI_NEXT_SELECTED; + sheet_mapping["ani_next_disabled"] = PART_ANI_NEXT_DISABLED; + sheet_mapping["ani_last"] = PART_ANI_LAST; + sheet_mapping["ani_last_selected"] = PART_ANI_LAST_SELECTED; + sheet_mapping["ani_last_disabled"] = PART_ANI_LAST_DISABLED; + sheet_mapping["target_one"] = PART_TARGET_ONE; + sheet_mapping["target_one_selected"] = PART_TARGET_ONE_SELECTED; + sheet_mapping["target_frames"] = PART_TARGET_FRAMES; + sheet_mapping["target_frames_selected"] = PART_TARGET_FRAMES_SELECTED; + sheet_mapping["target_layers"] = PART_TARGET_LAYERS; + sheet_mapping["target_layers_selected"] = PART_TARGET_LAYERS_SELECTED; + sheet_mapping["target_frames_layers"] = PART_TARGET_FRAMES_LAYERS; + sheet_mapping["target_frames_layers_selected"] = PART_TARGET_FRAMES_LAYERS_SELECTED; + sheet_mapping["brush_circle"] = PART_BRUSH_CIRCLE; + sheet_mapping["brush_circle_selected"] = PART_BRUSH_CIRCLE_SELECTED; + sheet_mapping["brush_square"] = PART_BRUSH_SQUARE; + sheet_mapping["brush_square_selected"] = PART_BRUSH_SQUARE_SELECTED; + sheet_mapping["brush_line"] = PART_BRUSH_LINE; + sheet_mapping["brush_line_selected"] = PART_BRUSH_LINE_SELECTED; + sheet_mapping["scale_arrow_1"] = PART_SCALE_ARROW_1; + sheet_mapping["scale_arrow_2"] = PART_SCALE_ARROW_2; + sheet_mapping["scale_arrow_3"] = PART_SCALE_ARROW_3; + sheet_mapping["rotate_arrow_1"] = PART_ROTATE_ARROW_1; + sheet_mapping["rotate_arrow_2"] = PART_ROTATE_ARROW_2; + sheet_mapping["rotate_arrow_3"] = PART_ROTATE_ARROW_3; + sheet_mapping["layer_visible"] = PART_LAYER_VISIBLE; + sheet_mapping["layer_visible_selected"] = PART_LAYER_VISIBLE_SELECTED; + sheet_mapping["layer_hidden"] = PART_LAYER_HIDDEN; + sheet_mapping["layer_hidden_selected"] = PART_LAYER_HIDDEN_SELECTED; + sheet_mapping["layer_editable"] = PART_LAYER_EDITABLE; + sheet_mapping["layer_editable_selected"] = PART_LAYER_EDITABLE_SELECTED; + sheet_mapping["layer_locked"] = PART_LAYER_LOCKED; + sheet_mapping["layer_locked_selected"] = PART_LAYER_LOCKED_SELECTED; reload_skin(); } @@ -202,8 +258,6 @@ std::string SkinTheme::get_font_filename() const void SkinTheme::onRegenerate() { - check_icon_size = 8 * jguiscale(); - radio_icon_size = 8 * jguiscale(); scrollbar_size = 12 * jguiscale(); desktop_color = COLOR_DISABLED; @@ -295,7 +349,13 @@ void SkinTheme::onRegenerate() int y = strtol(xmlPart->Attribute("y"), NULL, 10); int w = xmlPart->Attribute("w") ? strtol(xmlPart->Attribute("w"), NULL, 10): 0; int h = xmlPart->Attribute("h") ? strtol(xmlPart->Attribute("h"), NULL, 10): 0; - int c = sheet_mapping[part_id]; + std::map::iterator it = sheet_mapping.find(part_id); + if (it == sheet_mapping.end()) { + throw base::Exception("Unknown part specified in '%s':\n" + "\n", xml_filename.c_str(), part_id); + } + + int c = it->second; if (w > 0 && h > 0) { // Crop the part from the sheet @@ -406,6 +466,13 @@ void SkinTheme::init_widget(JWidget widget) case JI_CHECK: BORDER(2 * scale); widget->child_spacing = 4 * scale; + + static_cast(widget)->setIconInterface + (new ButtonIconImpl(static_cast(widget->getTheme()), + PART_CHECK_NORMAL, + PART_CHECK_SELECTED, + PART_CHECK_DISABLED, + JI_LEFT | JI_MIDDLE)); break; case JI_ENTRY: @@ -447,6 +514,13 @@ void SkinTheme::init_widget(JWidget widget) button->child_spacing = 0; button->min_w = 15 * jguiscale(); button->min_h = 16 * jguiscale(); + + static_cast(button)->setIconInterface + (new ButtonIconImpl(static_cast(button->getTheme()), + PART_COMBOBOX_ARROW_DOWN, + PART_COMBOBOX_ARROW_DOWN_SELECTED, + PART_COMBOBOX_ARROW_DOWN_DISABLED, + JI_CENTER | JI_MIDDLE)); } break; @@ -470,6 +544,13 @@ void SkinTheme::init_widget(JWidget widget) case JI_RADIO: BORDER(2 * scale); widget->child_spacing = 4 * scale; + + static_cast(widget)->setIconInterface + (new ButtonIconImpl(static_cast(widget->getTheme()), + PART_RADIO_NORMAL, + PART_RADIO_SELECTED, + PART_RADIO_DISABLED, + JI_LEFT | JI_MIDDLE)); break; case JI_SEPARATOR: @@ -626,17 +707,16 @@ void SkinTheme::paintBox(PaintEvent& ev) void SkinTheme::paintButton(PaintEvent& ev) { ButtonBase* widget = static_cast(ev.getSource()); - BITMAP* icon_bmp = widget->getButtonIcon(); - int icon_align = widget->getButtonIconAlign(); + IButtonIcon* iconInterface = widget->getIconInterface(); struct jrect box, text, icon; int x1, y1, x2, y2; int fg, bg, part_nw; JRect crect; jwidget_get_texticon_info(widget, &box, &text, &icon, - icon_align, - icon_bmp ? icon_bmp->w : 0, - icon_bmp ? icon_bmp->h : 0); + iconInterface ? iconInterface->getIconAlign(): 0, + iconInterface ? iconInterface->getWidth() : 0, + iconInterface ? iconInterface->getHeight() : 0); // Tool buttons are smaller bool isMiniLook = false; @@ -688,44 +768,28 @@ void SkinTheme::paintButton(PaintEvent& ev) draw_textstring(NULL, fg, bg, false, widget, crect, get_button_selected_offset()); jrect_free(crect); - // icon - if (icon_bmp) { + // Paint the icon + if (iconInterface) { if (widget->isSelected()) jrect_displace(&icon, get_button_selected_offset(), get_button_selected_offset()); - // enabled - if (widget->isEnabled()) { - // selected - if (widget->isSelected()) { - jdraw_inverted_sprite(ji_screen, icon_bmp, icon.x1, icon.y1); - } - // non-selected - else { - draw_sprite(ji_screen, icon_bmp, icon.x1, icon.y1); - } - } - // disabled - else { - _ji_theme_draw_sprite_color(ji_screen, icon_bmp, icon.x1+jguiscale(), icon.y1+jguiscale(), - COLOR_BACKGROUND); - _ji_theme_draw_sprite_color(ji_screen, icon_bmp, icon.x1, icon.y1, - COLOR_DISABLED); - } + paintIcon(widget, ev.getGraphics(), iconInterface, icon.x1-widget->rc->x1, icon.y1-widget->rc->y1); } } void SkinTheme::paintCheckBox(PaintEvent& ev) { ButtonBase* widget = static_cast(ev.getSource()); + IButtonIcon* iconInterface = widget->getIconInterface(); struct jrect box, text, icon; int bg; jwidget_get_texticon_info(widget, &box, &text, &icon, - widget->getButtonIconAlign(), - this->check_icon_size, - this->check_icon_size); + iconInterface ? iconInterface->getIconAlign(): 0, + iconInterface ? iconInterface->getWidth() : 0, + iconInterface ? iconInterface->getHeight() : 0); // background jdraw_rectfill(widget->rc, bg = BGCOLOR); @@ -741,12 +805,9 @@ void SkinTheme::paintCheckBox(PaintEvent& ev) /* text */ draw_textstring(NULL, -1, bg, false, widget, &text, 0); - /* icon */ - set_alpha_blender(); - draw_trans_sprite(ji_screen, - widget->isSelected() ? m_part[PART_CHECK_SELECTED]: - m_part[PART_CHECK_NORMAL], - icon.x1, icon.y1); + // Paint the icon + if (iconInterface) + paintIcon(widget, ev.getGraphics(), iconInterface, icon.x1-widget->rc->x1, icon.y1-widget->rc->y1); // draw focus if (widget->hasFocus()) { @@ -1045,13 +1106,14 @@ void SkinTheme::draw_panel(JWidget widget, JRect clip) void SkinTheme::paintRadioButton(PaintEvent& ev) { ButtonBase* widget = static_cast(ev.getSource()); + IButtonIcon* iconInterface = widget->getIconInterface(); struct jrect box, text, icon; int bg = BGCOLOR; jwidget_get_texticon_info(widget, &box, &text, &icon, - widget->getButtonIconAlign(), - this->radio_icon_size, - this->radio_icon_size); + iconInterface ? iconInterface->getIconAlign(): 0, + iconInterface ? iconInterface->getWidth() : 0, + iconInterface ? iconInterface->getHeight() : 0); /* background */ jdraw_rectfill(widget->rc, bg); @@ -1067,12 +1129,9 @@ void SkinTheme::paintRadioButton(PaintEvent& ev) /* text */ draw_textstring(NULL, -1, bg, false, widget, &text, 0); - /* icon */ - set_alpha_blender(); - draw_trans_sprite(ji_screen, - widget->isSelected() ? m_part[PART_RADIO_SELECTED]: - m_part[PART_RADIO_NORMAL], - icon.x1, icon.y1); + // Paint the icon + if (iconInterface) + paintIcon(widget, ev.getGraphics(), iconInterface, icon.x1-widget->rc->x1, icon.y1-widget->rc->y1); // draw focus if (widget->hasFocus()) { @@ -1316,52 +1375,44 @@ void SkinTheme::draw_combobox_entry(Entry* widget, JRect clip) draw_entry_caret(widget, x, y); } -void SkinTheme::draw_combobox_button(ButtonBase* widget, JRect clip) +void SkinTheme::paintComboBoxButton(PaintEvent& ev) { - BITMAP* icon_bmp = m_part[PART_COMBOBOX_ARROW]; - struct jrect icon; - int x1, y1, x2, y2; - int fg, bg, part_nw; + Button* widget = static_cast(ev.getSource()); + Graphics* g = ev.getGraphics(); + IButtonIcon* iconInterface = widget->getIconInterface(); + int bg, part_nw; - /* with mouse */ - if (widget->isSelected() || - (widget->isEnabled() && widget->hasMouseOver())) { - fg = get_button_hot_text_color(); + if (widget->isSelected()) { + bg = get_button_selected_face_color(); + part_nw = PART_TOOLBUTTON_PUSHED_NW; + } + // With mouse + else if (widget->isEnabled() && widget->hasMouseOver()) { bg = get_button_hot_face_color(); part_nw = PART_TOOLBUTTON_HOT_NW; } - /* without mouse */ + // Without mouse else { - fg = get_button_normal_text_color(); bg = get_button_normal_face_color(); part_nw = PART_TOOLBUTTON_LAST_NW; } - /* widget position */ - x1 = widget->rc->x1; - y1 = widget->rc->y1; - x2 = widget->rc->x2-1; - y2 = widget->rc->y2-1; + gfx::Rect rc = widget->getClientBounds(); // external background - rectfill(ji_screen, x1, y1, x2, y2, BGCOLOR); + g->fillRect(BGCOLOR, rc); // draw borders - draw_bounds_nw(ji_screen, x1, y1, x2, y2, part_nw, bg); + draw_bounds_nw(g, rc, part_nw, bg); - // icon - icon.x1 = (x1+x2)/2 - icon_bmp->w/2; - icon.y1 = (y1+y2)/2 - icon_bmp->h/2; - icon.x2 = icon.x1 + icon_bmp->w; - icon.y2 = icon.y1 + icon_bmp->h; + // Paint the icon + if (iconInterface) { + // Icon + int x = rc.x + rc.w/2 - iconInterface->getWidth()/2; + int y = rc.y + rc.h/2 - iconInterface->getHeight()/2; - if (widget->isSelected()) - jrect_displace(&icon, - get_button_selected_offset(), - get_button_selected_offset()); - - set_alpha_blender(); - draw_trans_sprite(ji_screen, icon_bmp, icon.x1, icon.y1); + paintIcon(widget, ev.getGraphics(), iconInterface, x, y); + } } void SkinTheme::draw_textbox(JWidget widget, JRect clip) @@ -1954,6 +2005,26 @@ void SkinTheme::less_bevel(int *bevel) if (bevel[3] > 0) --bevel[3]; } +void SkinTheme::paintIcon(Widget* widget, Graphics* g, IButtonIcon* iconInterface, int x, int y) +{ + BITMAP* icon_bmp = NULL; + + // enabled + if (widget->isEnabled()) { + if (widget->isSelected()) // selected + icon_bmp = iconInterface->getSelectedIcon(); + else + icon_bmp = iconInterface->getNormalIcon(); + } + // disabled + else { + icon_bmp = iconInterface->getDisabledIcon(); + } + + if (icon_bmp) + g->drawAlphaBitmap(icon_bmp, x, y); +} + /* controls the "X" button in a window to close it */ bool SkinTheme::theme_frame_button_msg_proc(JWidget widget, JMessage msg) { diff --git a/src/skin/skin_theme.h b/src/skin/skin_theme.h index d7a6be62a..d00e67672 100644 --- a/src/skin/skin_theme.h +++ b/src/skin/skin_theme.h @@ -28,10 +28,11 @@ #include "gui/theme.h" #include "gui/system.h" -class Graphics; - #include "skin_parts.h" +class Graphics; +class IButtonIcon; + // This is the GUI theme used by ASE (which use images from data/skins // directory). class SkinTheme : public Theme @@ -78,7 +79,7 @@ public: void draw_separator(JWidget widget, JRect clip); void paintSlider(PaintEvent& ev); void draw_combobox_entry(Entry* widget, JRect clip); - void draw_combobox_button(ButtonBase* widget, JRect clip); + void paintComboBoxButton(PaintEvent& ev); void draw_textbox(JWidget widget, JRect clip); void draw_view(JWidget widget, JRect clip); void draw_view_scrollbar(JWidget widget, JRect clip); @@ -174,6 +175,8 @@ private: void draw_bevel_box(int x1, int y1, int x2, int y2, int c1, int c2, int *bevel); void less_bevel(int *bevel); + void paintIcon(Widget* widget, Graphics* g, IButtonIcon* iconInterface, int x, int y); + static bool theme_frame_button_msg_proc(JWidget widget, JMessage msg); static bool theme_combobox_button_msg_proc(JWidget widget, JMessage msg); diff --git a/src/util/clipboard.cpp b/src/util/clipboard.cpp index 6e4825575..645e96072 100644 --- a/src/util/clipboard.cpp +++ b/src/util/clipboard.cpp @@ -39,6 +39,8 @@ #include "raster/stock.h" #include "raster/undo.h" #include "settings/settings.h" +#include "skin/skin_parts.h" +#include "skin/skin_theme.h" #include "sprite_wrappers.h" #include "ui_context.h" #include "undoable.h" @@ -780,49 +782,50 @@ static void draw_box(BITMAP *bmp, static void draw_icon(BITMAP *bmp, int x, int y, int mode, fixed angle) { - BITMAP *gfx; + SkinTheme* theme = static_cast(CurrentTheme::get()); + BITMAP* gfx; angle &= (255<<16); - /* 0 degree */ + // 0 degree if ((angle > ((256-16)<<16)) || (angle <= ((0+16)<<16))) { - gfx = get_gfx (mode == SCALE_MODE ? GFX_SCALE_3: GFX_ROTATE_3); - draw_sprite_h_flip (bmp, gfx, x, y-gfx->h/2); + gfx = theme->get_part(mode == SCALE_MODE ? PART_SCALE_ARROW_3: PART_ROTATE_ARROW_3); + draw_sprite_ex(bmp, gfx, x, y-gfx->h/2, DRAW_SPRITE_TRANS, DRAW_SPRITE_H_FLIP); } - /* 45 degree */ + // 45 degree else if ((angle >= ((32-16)<<16)) && (angle <= ((32+16)<<16))) { - gfx = get_gfx (mode == SCALE_MODE ? GFX_SCALE_1: GFX_ROTATE_1); - draw_sprite_h_flip (bmp, gfx, x, y-gfx->h); + gfx = theme->get_part(mode == SCALE_MODE ? PART_SCALE_ARROW_1: PART_ROTATE_ARROW_1); + draw_sprite_ex(bmp, gfx, x, y-gfx->h, DRAW_SPRITE_TRANS, DRAW_SPRITE_H_FLIP); } - /* 90 degree */ + // 90 degree else if ((angle >= ((64-16)<<16)) && (angle <= ((64+16)<<16))) { - gfx = get_gfx (mode == SCALE_MODE ? GFX_SCALE_2: GFX_ROTATE_2); - draw_sprite (bmp, gfx, x-gfx->w/2, y-gfx->h); + gfx = theme->get_part(mode == SCALE_MODE ? PART_SCALE_ARROW_2: PART_ROTATE_ARROW_2); + draw_sprite_ex(bmp, gfx, x-gfx->w/2, y-gfx->h, DRAW_SPRITE_TRANS, DRAW_SPRITE_NO_FLIP); } - /* 135 degree */ + // 135 degree else if ((angle >= ((96-16)<<16)) && (angle <= ((96+16)<<16))) { - gfx = get_gfx (mode == SCALE_MODE ? GFX_SCALE_1: GFX_ROTATE_1); - draw_sprite (bmp, gfx, x-gfx->w, y-gfx->h); + gfx = theme->get_part(mode == SCALE_MODE ? PART_SCALE_ARROW_1: PART_ROTATE_ARROW_1); + draw_sprite_ex(bmp, gfx, x-gfx->w, y-gfx->h, DRAW_SPRITE_TRANS, DRAW_SPRITE_NO_FLIP); } - /* 180 degree */ + // 180 degree else if ((angle >= ((128-16)<<16)) && (angle <= ((128+16)<<16))) { - gfx = get_gfx (mode == SCALE_MODE ? GFX_SCALE_3: GFX_ROTATE_3); - draw_sprite (bmp, gfx, x-gfx->w, y-gfx->h/2); + gfx = theme->get_part(mode == SCALE_MODE ? PART_SCALE_ARROW_3: PART_ROTATE_ARROW_3); + draw_sprite_ex(bmp, gfx, x-gfx->w, y-gfx->h/2, DRAW_SPRITE_TRANS, DRAW_SPRITE_NO_FLIP); } - /* 225 degree */ + // 225 degree else if ((angle >= ((160-16)<<16)) && (angle <= ((160+16)<<16))) { - gfx = get_gfx (mode == SCALE_MODE ? GFX_SCALE_1: GFX_ROTATE_1); - draw_sprite_v_flip (bmp, gfx, x-gfx->w, y); + gfx = theme->get_part(mode == SCALE_MODE ? PART_SCALE_ARROW_1: PART_ROTATE_ARROW_1); + draw_sprite_ex(bmp, gfx, x-gfx->w, y, DRAW_SPRITE_TRANS, DRAW_SPRITE_V_FLIP); } - /* 270 degree */ + // 270 degree else if ((angle >= ((192-16)<<16)) && (angle <= ((192+16)<<16))) { - gfx = get_gfx (mode == SCALE_MODE ? GFX_SCALE_2: GFX_ROTATE_2); - draw_sprite_v_flip (bmp, gfx, x-gfx->w/2, y); + gfx = theme->get_part(mode == SCALE_MODE ? PART_SCALE_ARROW_2: PART_ROTATE_ARROW_2); + draw_sprite_ex(bmp, gfx, x-gfx->w/2, y, DRAW_SPRITE_TRANS, DRAW_SPRITE_V_FLIP); } - /* 315 degree */ + // 315 degree else if ((angle >= ((224-16)<<16)) && (angle <= ((224+16)<<16))) { - gfx = get_gfx (mode == SCALE_MODE ? GFX_SCALE_1: GFX_ROTATE_1); - draw_sprite_vh_flip (bmp, gfx, x, y); + gfx = theme->get_part(mode == SCALE_MODE ? PART_SCALE_ARROW_1: PART_ROTATE_ARROW_1); + draw_sprite_ex(bmp, gfx, x, y, DRAW_SPRITE_TRANS, DRAW_SPRITE_VH_FLIP); } } diff --git a/src/widgets/groupbut.cpp b/src/widgets/groupbut.cpp index b943c5b64..f8d37ef90 100644 --- a/src/widgets/groupbut.cpp +++ b/src/widgets/groupbut.cpp @@ -72,7 +72,7 @@ JWidget group_button_new(int w, int h, int first_selected, ...) radio->setName(buf); if (icon >= 0) - add_gfxicon_to_button(radio, icon, JI_CENTER | JI_MIDDLE); + set_gfxicon_to_button(radio, icon, icon+1, icon, JI_CENTER | JI_MIDDLE); radio->Click.connect(Bind(&radio_change_hook, vbox)); diff --git a/src/widgets/statebar.cpp b/src/widgets/statebar.cpp index 88ab2c0a7..8272e8719 100644 --- a/src/widgets/statebar.cpp +++ b/src/widgets/statebar.cpp @@ -86,7 +86,7 @@ StatusBar::StatusBar() #define ICON_NEW(name, icon, action) \ { \ BUTTON_NEW((name), NULL, (action)); \ - add_gfxicon_to_button((name), (icon), JI_CENTER | JI_MIDDLE); \ + set_gfxicon_to_button((name), icon, icon##_SELECTED, icon##_DISABLED, JI_CENTER | JI_MIDDLE); \ } jwidget_focusrest(this, true); @@ -110,11 +110,11 @@ StatusBar::StatusBar() setup_mini_look(m_slider); - ICON_NEW(m_b_first, GFX_ANI_FIRST, ACTION_FIRST); - ICON_NEW(m_b_prev, GFX_ANI_PREV, ACTION_PREV); - ICON_NEW(m_b_play, GFX_ANI_PLAY, ACTION_PLAY); - ICON_NEW(m_b_next, GFX_ANI_NEXT, ACTION_NEXT); - ICON_NEW(m_b_last, GFX_ANI_LAST, ACTION_LAST); + ICON_NEW(m_b_first, PART_ANI_FIRST, ACTION_FIRST); + ICON_NEW(m_b_prev, PART_ANI_PREVIOUS, ACTION_PREV); + ICON_NEW(m_b_play, PART_ANI_PLAY, ACTION_PLAY); + ICON_NEW(m_b_next, PART_ANI_NEXT, ACTION_NEXT); + ICON_NEW(m_b_last, PART_ANI_LAST, ACTION_LAST); m_slider->Change.connect(Bind(&slider_change_hook, m_slider)); jwidget_set_min_size(m_slider, JI_SCREEN_W/5, 0); diff --git a/src/widgets/tabs.cpp b/src/widgets/tabs.cpp index 864397369..c4ec4dd00 100644 --- a/src/widgets/tabs.cpp +++ b/src/widgets/tabs.cpp @@ -69,8 +69,15 @@ Tabs::Tabs(ITabsHandler* handler) jwidget_focusrest(m_button_left, false); jwidget_focusrest(m_button_right, false); - add_gfxicon_to_button(m_button_left, GFX_ARROW_LEFT, JI_CENTER | JI_MIDDLE); - add_gfxicon_to_button(m_button_right, GFX_ARROW_RIGHT, JI_CENTER | JI_MIDDLE); + set_gfxicon_to_button(m_button_left, + PART_COMBOBOX_ARROW_LEFT, + PART_COMBOBOX_ARROW_LEFT_SELECTED, + PART_COMBOBOX_ARROW_LEFT_DISABLED, JI_CENTER | JI_MIDDLE); + + set_gfxicon_to_button(m_button_right, + PART_COMBOBOX_ARROW_RIGHT, + PART_COMBOBOX_ARROW_RIGHT_SELECTED, + PART_COMBOBOX_ARROW_RIGHT_DISABLED, JI_CENTER | JI_MIDDLE); jwidget_add_hook(m_button_left, tabs_type(), tabs_button_msg_proc, (void *)-1); jwidget_add_hook(m_button_right, tabs_type(), tabs_button_msg_proc, (void *)+1); diff --git a/src/widgets/target.cpp b/src/widgets/target.cpp index b0a8640b8..292466faa 100644 --- a/src/widgets/target.cpp +++ b/src/widgets/target.cpp @@ -32,11 +32,13 @@ #include "modules/gfx.h" #include "modules/gui.h" #include "raster/image.h" +#include "skin/skin_parts.h" #include "widgets/target.h" static bool channel_change_hook(ButtonBase* widget, Widget* data); static bool images_change_hook(ButtonBase* widget, Widget* data); -static int get_target_image_gfx(int target); +static int get_target_normal_icon(int target); +static int get_target_selected_icon(int target); /** * Creates a new button to handle "targets" to apply some effect in @@ -108,7 +110,9 @@ JWidget target_button_new(int imgtype, bool with_channels) with_channels ? 0: 2, with_channels ? 0: 2, 2, 2); setup_mini_look(images); - add_gfxicon_to_button(images, get_target_image_gfx(default_targets), + set_gfxicon_to_button(images, + get_target_normal_icon(default_targets), + get_target_selected_icon(default_targets), -1, JI_CENTER | JI_MIDDLE); /* make hierarchy */ @@ -199,23 +203,40 @@ static bool images_change_hook(ButtonBase* widget, Widget* target_button) target |= TARGET_ALL_FRAMES; } - set_gfxicon_in_button(widget, get_target_image_gfx(target)); + set_gfxicon_to_button(widget, + get_target_normal_icon(target), + get_target_selected_icon(target), -1, + JI_CENTER | JI_MIDDLE); target_button->user_data[0] = (void *)target; jwidget_emit_signal(target_button, SIGNAL_TARGET_BUTTON_CHANGE); return true; } -static int get_target_image_gfx(int target) +static int get_target_normal_icon(int target) { if (target & TARGET_ALL_FRAMES) { - return target & TARGET_ALL_LAYERS ? - GFX_TARGET_FRAMES_LAYERS: - GFX_TARGET_FRAMES; + return (target & TARGET_ALL_LAYERS) ? + PART_TARGET_FRAMES_LAYERS: + PART_TARGET_FRAMES; } else { - return target & TARGET_ALL_LAYERS ? - GFX_TARGET_LAYERS: - GFX_TARGET_ONE; + return (target & TARGET_ALL_LAYERS) ? + PART_TARGET_LAYERS: + PART_TARGET_ONE; + } +} + +static int get_target_selected_icon(int target) +{ + if (target & TARGET_ALL_FRAMES) { + return (target & TARGET_ALL_LAYERS) ? + PART_TARGET_FRAMES_LAYERS_SELECTED: + PART_TARGET_FRAMES_SELECTED; + } + else { + return (target & TARGET_ALL_LAYERS) ? + PART_TARGET_LAYERS_SELECTED: + PART_TARGET_ONE_SELECTED; } }