diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 99fce2761..6c09f440f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -342,6 +342,7 @@ add_library(aseprite-library util/pic_file.cpp util/render.cpp util/thmbnail.cpp + widgets/button_set.cpp widgets/color_bar.cpp widgets/color_button.cpp widgets/color_selector.cpp @@ -364,7 +365,6 @@ add_library(aseprite-library widgets/editor/tool_loop_impl.cpp widgets/editor/transform_handles.cpp widgets/fileview.cpp - widgets/groupbut.cpp widgets/hex_color_entry.cpp widgets/menuitem2.cpp widgets/palette_view.cpp diff --git a/src/commands/cmd_configure_tools.cpp b/src/commands/cmd_configure_tools.cpp index 3b1141793..8f586b975 100644 --- a/src/commands/cmd_configure_tools.cpp +++ b/src/commands/cmd_configure_tools.cpp @@ -40,9 +40,9 @@ #include "tools/point_shape.h" #include "tools/tool.h" #include "ui_context.h" +#include "widgets/button_set.h" #include "widgets/color_button.h" #include "widgets/editor/editor.h" -#include "widgets/groupbut.h" #include "widgets/statebar.h" #include @@ -52,10 +52,52 @@ using namespace tools; static Frame* window = NULL; -static bool brush_preview_msg_proc(JWidget widget, Message* msg); - static bool window_close_hook(JWidget widget, void *data); -static bool brush_type_change_hook(JWidget widget, void *data); + +class BrushPreview : public Widget +{ +public: + BrushPreview() : Widget(JI_WIDGET) { + } + +protected: + bool onProcessMessage(Message* msg) + { + switch (msg->type) { + + case JM_DRAW: { + BITMAP *bmp = create_bitmap(jrect_w(this->rc), + jrect_h(this->rc)); + + Tool* current_tool = UIContext::instance() + ->getSettings() + ->getCurrentTool(); + + IPenSettings* pen_settings = UIContext::instance() + ->getSettings() + ->getToolSettings(current_tool) + ->getPen(); + + ASSERT(pen_settings != NULL); + + UniquePtr pen(new Pen(pen_settings->getType(), + pen_settings->getSize(), + pen_settings->getAngle())); + + clear_to_color(bmp, makecol(0, 0, 0)); + image_to_allegro(pen->get_image(), bmp, + bmp->w/2 - pen->get_size()/2, + bmp->h/2 - pen->get_size()/2, NULL); + blit(bmp, ji_screen, 0, 0, this->rc->x1, this->rc->y1, + bmp->w, bmp->h); + destroy_bitmap(bmp); + return true; + } + } + + return Widget::onProcessMessage(msg); + } +}; // Slot for App::Exit signal static void on_exit_delete_this_widget() @@ -67,7 +109,7 @@ static void on_exit_delete_this_widget() static void on_pen_size_after_change() { Slider* brush_size = window->findChildT("brush_size"); - Widget* brush_preview = window->findChild("brush_preview"); + BrushPreview* brushPreview = window->findChildT("brush_preview"); ASSERT(brush_size != NULL); @@ -82,15 +124,15 @@ static void on_pen_size_after_change() brush_size->setValue(tool_settings->getPen()->getSize()); // Regenerate the preview - brush_preview->invalidate(); + brushPreview->invalidate(); } static void on_current_tool_change() { Slider* brush_size = window->findChildT("brush_size"); Slider* brush_angle = window->findChildT("brush_angle"); - Widget* brush_type = window->findChild("brush_type"); - Widget* brush_preview = window->findChild("brush_preview"); + ButtonSet* brush_type = window->findChildT("brush_type"); + BrushPreview* brushPreview = window->findChildT("brush_preview"); Widget* opacity_label = window->findChild("opacity_label"); Slider* opacity = window->findChildT("opacity"); Widget* tolerance_label = window->findChild("tolerance_label"); @@ -115,10 +157,10 @@ static void on_current_tool_change() air_speed->setValue(tool_settings->getSpraySpeed()); // Select the brush type - group_button_select(brush_type, tool_settings->getPen()->getType()); + brush_type->setSelectedItem(tool_settings->getPen()->getType()); // Regenerate the preview - brush_preview->invalidate(); + brushPreview->invalidate(); // True if the current tool needs opacity options bool hasOpacity = (current_tool->getInk(0)->isPaint() || @@ -183,6 +225,8 @@ private: CheckBox* m_snapToGrid; CheckBox* m_onionSkin; CheckBox* m_viewGrid; + Widget* m_brushPreview; + ButtonSet* m_brushType; Slider* m_brushSize; Slider* m_brushAngle; Slider* m_opacity; @@ -190,6 +234,7 @@ private: Slider* m_sprayWidth; Slider* m_airSpeed; + void onWindowClose(); void onTiledClick(); void onTiledXYClick(int tiled_axis, CheckBox* checkbox); void onViewGridClick(); @@ -197,12 +242,13 @@ private: void onSetGridClick(); void onSnapToGridClick(); void onOnionSkinClick(); - void onBrushSizeSliderChange(Widget* brush_preview); - void onBrushAngleSliderChange(Widget* brush_preview); + void onBrushSizeSliderChange(); + void onBrushAngleSliderChange(); void onOpacitySliderChange(); void onToleranceSliderChange(); void onSprayWidthSliderChange(); void onAirSpeedSliderChange(); + void onBrushTypeChange(); }; @@ -216,9 +262,8 @@ ConfigureTools::ConfigureTools() void ConfigureTools::onExecute(Context* context) { Button* set_grid; - JWidget brush_preview_box; - JWidget brush_type_box, brush_type; - JWidget brush_preview; + Widget* brush_preview_box; + Widget* brush_type_box; bool first_time = false; if (!window) { @@ -258,16 +303,13 @@ void ConfigureTools::onExecute(Context* context) /* brush-preview */ if (first_time) { - brush_preview = new Widget(JI_WIDGET); - brush_preview->min_w = 32 + 4; - brush_preview->min_h = 32 + 4; - - brush_preview->setName("brush_preview"); - jwidget_add_hook(brush_preview, JI_WIDGET, - brush_preview_msg_proc, NULL); + m_brushPreview = new BrushPreview(); + m_brushPreview->min_w = 32 + 4; + m_brushPreview->min_h = 32 + 4; + m_brushPreview->setName("brush_preview"); } else { - brush_preview = window->findChild("brush_preview"); + m_brushPreview = window->findChild("brush_preview"); } // Current settings @@ -279,15 +321,15 @@ void ConfigureTools::onExecute(Context* context) if (first_time) { PenType type = tool_settings->getPen()->getType(); - brush_type = group_button_new(3, 1, type, - PART_BRUSH_CIRCLE, - PART_BRUSH_SQUARE, - PART_BRUSH_LINE); + m_brushType = new ButtonSet(3, 1, type, + PART_BRUSH_CIRCLE, + PART_BRUSH_SQUARE, + PART_BRUSH_LINE); - brush_type->setName("brush_type"); + m_brushType->setName("brush_type"); } else { - brush_type = window->findChild("brush_type"); + m_brushType = window->findChildT("brush_type"); } if (settings->getTiledMode() != TILED_NONE) { @@ -303,11 +345,11 @@ void ConfigureTools::onExecute(Context* context) if (first_time) { // Append children - brush_preview_box->addChild(brush_preview); - brush_type_box->addChild(brush_type); + brush_preview_box->addChild(m_brushPreview); + brush_type_box->addChild(m_brushType); // Slots - window->Close.connect(Bind(&window_close_hook, (JWidget)window, (void*)0)); + window->Close.connect(Bind(&ConfigureTools::onWindowClose, this)); m_tiled->Click.connect(Bind(&ConfigureTools::onTiledClick, this)); m_tiledX->Click.connect(Bind(&ConfigureTools::onTiledXYClick, this, TILED_X_AXIS, m_tiledX)); m_tiledY->Click.connect(Bind(&ConfigureTools::onTiledXYClick, this, TILED_Y_AXIS, m_tiledY)); @@ -322,14 +364,13 @@ void ConfigureTools::onExecute(Context* context) App::instance()->CurrentToolChange.connect(&on_current_tool_change); // Append hooks - m_brushSize->Change.connect(Bind(&ConfigureTools::onBrushSizeSliderChange, this, brush_preview)); - m_brushAngle->Change.connect(Bind(&ConfigureTools::onBrushAngleSliderChange, this, brush_preview)); + m_brushSize->Change.connect(Bind(&ConfigureTools::onBrushSizeSliderChange, this)); + m_brushAngle->Change.connect(Bind(&ConfigureTools::onBrushAngleSliderChange, this)); m_opacity->Change.connect(&ConfigureTools::onOpacitySliderChange, this); m_tolerance->Change.connect(&ConfigureTools::onToleranceSliderChange, this); m_airSpeed->Change.connect(&ConfigureTools::onAirSpeedSliderChange, this); m_sprayWidth->Change.connect(&ConfigureTools::onSprayWidthSliderChange, this); - - HOOK(brush_type, SIGNAL_GROUP_BUTTON_CHANGE, brush_type_change_hook, brush_preview); + m_brushType->ItemChange.connect(&ConfigureTools::onBrushTypeChange, this); } // Update current pen properties @@ -345,59 +386,14 @@ void ConfigureTools::onExecute(Context* context) window->open_window_bg(); } -static bool brush_preview_msg_proc(JWidget widget, Message* msg) +void ConfigureTools::onWindowClose() { - switch (msg->type) { - - case JM_DRAW: { - BITMAP *bmp = create_bitmap(jrect_w(widget->rc), - jrect_h(widget->rc)); - - Tool* current_tool = UIContext::instance() - ->getSettings() - ->getCurrentTool(); - - IPenSettings* pen_settings = UIContext::instance() - ->getSettings() - ->getToolSettings(current_tool) - ->getPen(); - - ASSERT(pen_settings != NULL); - - Pen* pen = new Pen(pen_settings->getType(), - pen_settings->getSize(), - pen_settings->getAngle()); - - clear_to_color(bmp, makecol(0, 0, 0)); - image_to_allegro(pen->get_image(), bmp, - bmp->w/2 - pen->get_size()/2, - bmp->h/2 - pen->get_size()/2, NULL); - blit(bmp, ji_screen, 0, 0, widget->rc->x1, widget->rc->y1, - bmp->w, bmp->h); - destroy_bitmap(bmp); - - delete pen; - return true; - } - } - - return false; + save_window_pos(window, "ConfigureTool"); } -static bool window_close_hook(JWidget widget, void *data) +void ConfigureTools::onBrushTypeChange() { - /* isn't running anymore */ -/* window = NULL; */ - - /* save window configuration */ - save_window_pos(widget, "ConfigureTool"); - - return false; -} - -static bool brush_type_change_hook(JWidget widget, void *data) -{ - PenType type = (PenType)group_button_get_selected(widget); + PenType type = (PenType)m_brushType->getSelectedItem(); Tool* current_tool = UIContext::instance() ->getSettings() @@ -409,7 +405,7 @@ static bool brush_type_change_hook(JWidget widget, void *data) ->getPen() ->setType(type); - ((Widget*)data)->invalidate(); + m_brushPreview->invalidate(); app_get_statusbar() ->setStatusText(250, @@ -417,11 +413,9 @@ static bool brush_type_change_hook(JWidget widget, void *data) type == PEN_TYPE_CIRCLE ? "Circle": type == PEN_TYPE_SQUARE ? "Square": type == PEN_TYPE_LINE ? "Line": "Unknown"); - - return true; } -void ConfigureTools::onBrushSizeSliderChange(Widget* brush_preview) +void ConfigureTools::onBrushSizeSliderChange() { Tool* current_tool = UIContext::instance() ->getSettings() @@ -433,10 +427,10 @@ void ConfigureTools::onBrushSizeSliderChange(Widget* brush_preview) ->getPen() ->setSize(m_brushSize->getValue()); - brush_preview->invalidate(); + m_brushPreview->invalidate(); } -void ConfigureTools::onBrushAngleSliderChange(Widget* brush_preview) +void ConfigureTools::onBrushAngleSliderChange() { Tool* current_tool = UIContext::instance() ->getSettings() @@ -448,7 +442,7 @@ void ConfigureTools::onBrushAngleSliderChange(Widget* brush_preview) ->getPen() ->setAngle(m_brushAngle->getValue()); - brush_preview->invalidate(); + m_brushPreview->invalidate(); } void ConfigureTools::onOpacitySliderChange() diff --git a/src/modules/gui.cpp b/src/modules/gui.cpp index b2999dd43..1a6566920 100644 --- a/src/modules/gui.cpp +++ b/src/modules/gui.cpp @@ -824,19 +824,6 @@ void set_gfxicon_to_button(ButtonBase* button, // Button style (convert radio or check buttons and draw it like // normal buttons) -RadioButton* radio_button_new(int radio_group, int b1, int b2, int b3, int b4) -{ - RadioButton* widget = new RadioButton(NULL, radio_group, JI_BUTTON); - - widget->setRadioGroup(radio_group); - widget->setAlign(JI_CENTER | JI_MIDDLE); - - setup_mini_look(widget); - setup_bevels(widget, b1, b2, b3, b4); - - return widget; -} - CheckBox* check_button_new(const char *text, int b1, int b2, int b3, int b4) { CheckBox* widget = new CheckBox(text, JI_BUTTON); diff --git a/src/modules/gui.h b/src/modules/gui.h index abd425ac1..cee069a95 100644 --- a/src/modules/gui.h +++ b/src/modules/gui.h @@ -102,7 +102,6 @@ void set_gfxicon_to_button(ButtonBase* button, 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/widgets/button_set.cpp b/src/widgets/button_set.cpp new file mode 100644 index 000000000..25eae1a3e --- /dev/null +++ b/src/widgets/button_set.cpp @@ -0,0 +1,148 @@ +/* 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 + */ + +#include "config.h" + +#include +#include + +#include "base/bind.h" +#include "gui/box.h" +#include "gui/button.h" +#include "gui/hook.h" +#include "gui/list.h" +#include "gui/system.h" +#include "gui/theme.h" +#include "gui/widget.h" +#include "modules/gui.h" +#include "widgets/button_set.h" + +static JWidget find_selected(JWidget widget); +static int select_button(JWidget widget, int index); + +class ButtonSet::Item : public RadioButton +{ +public: + Item(int index, int radioGroup, int b1, int b2, int b3, int b4) + : RadioButton(NULL, radioGroup, JI_BUTTON) + , m_index(index) + { + setRadioGroup(radioGroup); + setAlign(JI_CENTER | JI_MIDDLE); + + setup_mini_look(this); + setup_bevels(this, b1, b2, b3, b4); + } + + int getIndex() const { return m_index; } + +private: + int m_index; +}; + +ButtonSet::ButtonSet(int w, int h, int firstSelected, ...) + : Box(JI_VERTICAL | JI_HOMOGENEOUS) +{ + Box* hbox = NULL; + int x, y, icon; + va_list ap; + int c = 0; + char buf[256]; + + va_start(ap, firstSelected); + + jwidget_noborders(this); + + for (y=0; y 1) { + hbox = new Box(JI_HORIZONTAL | JI_HOMOGENEOUS); + jwidget_noborders(hbox); + } + + for (x=0; xid + 0x1000, + x == 0 && y == 0 ? 2: 0, + x == w-1 && y == 0 ? 2: 0, + x == 0 && y == h-1 ? 2: 0, + x == w-1 && y == h-1 ? 2: 0); + + m_items.push_back(item); + + usprintf(buf, "radio%d", c); + item->setName(buf); + + if (icon >= 0) + set_gfxicon_to_button(item, icon, icon+1, icon, JI_CENTER | JI_MIDDLE); + + item->Click.connect(Bind(&ButtonSet::onItemChange, this)); + + if (c == firstSelected) + item->setSelected(true); + + if (hbox) + hbox->addChild(item); + else + this->addChild(item); + + c++; + } + + if (hbox) + this->addChild(hbox); + } + + va_end(ap); +} + +int ButtonSet::getSelectedItem() const +{ + Item* sel = findSelectedItem(); + + if (sel) + return sel->getIndex(); + else + return -1; +} + +void ButtonSet::setSelectedItem(int index) +{ + Item* sel = findSelectedItem(); + + if (!sel || sel->getIndex() != index) { + sel->setSelected(false); + m_items[index]->setSelected(true); + } +} + +ButtonSet::Item* ButtonSet::findSelectedItem() const +{ + for (Items::const_iterator it=m_items.begin(), end=m_items.end(); + it != end; ++it) { + if ((*it)->isSelected()) + return *it; + } + return NULL; +} + +void ButtonSet::onItemChange() +{ + ItemChange(); +} diff --git a/src/widgets/groupbut.h b/src/widgets/button_set.h similarity index 64% rename from src/widgets/groupbut.h rename to src/widgets/button_set.h index d44d49d0b..ae2d2f941 100644 --- a/src/widgets/groupbut.h +++ b/src/widgets/button_set.h @@ -16,15 +16,31 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef WIDGETS_GROUPBUT_H_INCLUDED -#define WIDGETS_GROUPBUT_H_INCLUDED +#ifndef WIDGETS_BUTTON_SET_H_INCLUDED +#define WIDGETS_BUTTON_SET_H_INCLUDED -/* TODO use some JI_SIGNAL_USER */ -#define SIGNAL_GROUP_BUTTON_CHANGE 0x10000 +#include "gui/box.h" -JWidget group_button_new (int w, int h, int first_selected, ...); +class ButtonSet : public Box +{ + class Item; + typedef std::vector Items; -int group_button_get_selected (JWidget group); -void group_button_select (JWidget group, int index); +public: + ButtonSet(int w, int h, int firstSelected, ...); + + int getSelectedItem() const; + void setSelectedItem(int index); + + Signal0 ItemChange; + +protected: + void onItemChange(); + +private: + Item* findSelectedItem() const; + + Items m_items; +}; #endif diff --git a/src/widgets/groupbut.cpp b/src/widgets/groupbut.cpp deleted file mode 100644 index ffedc3ecc..000000000 --- a/src/widgets/groupbut.cpp +++ /dev/null @@ -1,158 +0,0 @@ -/* 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 - */ - -#include "config.h" - -#include -#include - -#include "base/bind.h" -#include "gui/box.h" -#include "gui/button.h" -#include "gui/hook.h" -#include "gui/list.h" -#include "gui/system.h" -#include "gui/theme.h" -#include "gui/widget.h" -#include "modules/gui.h" -#include "widgets/groupbut.h" - -static JWidget find_selected(JWidget widget); -static int select_button(JWidget widget, int index); - -static bool radio_change_hook(JWidget vbox); - -JWidget group_button_new(int w, int h, int first_selected, ...) -{ - Box* vbox = new Box(JI_VERTICAL | JI_HOMOGENEOUS); - Box* hbox = NULL; - RadioButton* radio; - int x, y, icon; - va_list ap; - int c = 0; - char buf[256]; - - va_start(ap, first_selected); - - jwidget_noborders(vbox); - - for (y=0; y 1) { - hbox = new Box(JI_HORIZONTAL | JI_HOMOGENEOUS); - jwidget_noborders(hbox); - } - - for (x=0; xid+0x1000, - x == 0 && y == 0 ? 2: 0, - x == w-1 && y == 0 ? 2: 0, - x == 0 && y == h-1 ? 2: 0, - x == w-1 && y == h-1 ? 2: 0); - - radio->user_data[1] = (void*)c; - - usprintf(buf, "radio%d", c); - radio->setName(buf); - - if (icon >= 0) - set_gfxicon_to_button(radio, icon, icon+1, icon, JI_CENTER | JI_MIDDLE); - - radio->Click.connect(Bind(&radio_change_hook, vbox)); - - if (c == first_selected) - radio->setSelected(true); - - if (hbox) - hbox->addChild(radio); - else - vbox->addChild(radio); - - c++; - } - - if (hbox) - vbox->addChild(hbox); - } - - va_end(ap); - - return vbox; -} - -int group_button_get_selected(JWidget group) -{ - JWidget sel = find_selected(group); - - if (sel) - return (long)sel->user_data[1]; - else - return -1; -} - -void group_button_select(JWidget group, int index) -{ - JWidget sel = find_selected(group); - - if (!sel || (long)sel->user_data[1] != index) { - sel->setSelected(false); - select_button(group, index); - } -} - -static JWidget find_selected(JWidget widget) -{ - JWidget sel; - JLink link; - - if (widget->isSelected()) - return widget; - else { - JI_LIST_FOR_EACH(widget->children, link) - if ((sel = find_selected(reinterpret_cast(link->data)))) - return sel; - - return NULL; - } -} - -static int select_button(JWidget widget, int index) -{ - JLink link; - - if (widget->type == JI_RADIO) { - if ((long)widget->user_data[1] == index) { - widget->setSelected(true); - return true; - } - } - else { - JI_LIST_FOR_EACH(widget->children, link) - if (select_button(reinterpret_cast(link->data), index)) - return true; - } - - return false; -} - -static bool radio_change_hook(JWidget vbox) -{ - jwidget_emit_signal(vbox, SIGNAL_GROUP_BUTTON_CHANGE); - return true; -} diff --git a/src/widgets/toolbar.cpp b/src/widgets/toolbar.cpp index 3243a0906..54dacb0d8 100644 --- a/src/widgets/toolbar.cpp +++ b/src/widgets/toolbar.cpp @@ -34,7 +34,6 @@ #include "skin/skin_theme.h" #include "tools/tool_box.h" #include "ui_context.h" -#include "widgets/groupbut.h" #include "widgets/statebar.h" #include