diff --git a/data/skins/default/sheet.png b/data/skins/default/sheet.png index c5b0f7e1f..4c3401f7c 100644 Binary files a/data/skins/default/sheet.png and b/data/skins/default/sheet.png differ diff --git a/data/skins/default/skin.xml b/data/skins/default/skin.xml index b294031d2..76aaa5fc7 100644 --- a/data/skins/default/skin.xml +++ b/data/skins/default/skin.xml @@ -55,6 +55,7 @@ + diff --git a/src/gui/close_event.h b/src/gui/close_event.h new file mode 100644 index 000000000..f27233414 --- /dev/null +++ b/src/gui/close_event.h @@ -0,0 +1,30 @@ +// ASE gui library +// Copyright (C) 2001-2011 David Capello +// +// This source file is ditributed under a BSD-like license, please +// read LICENSE.txt for more information. + +#ifndef GUI_CLOSE_EVENT_H_INCLUDED +#define GUI_CLOSE_EVENT_H_INCLUDED + +#include "gui/event.h" + +class CloseEvent : public Event +{ +public: + enum Trigger { + ByCode, // The CloseEvent was generated by code. + ByUser, // The CloseEvent was generated by the user. + }; + + CloseEvent(Component* source, Trigger trigger) + : Event(source) + , m_trigger(trigger){ } + + Trigger getTrigger() const { return m_trigger; } + +private: + Trigger m_trigger; +}; + +#endif // GUI_CLOSE_EVENT_H_INCLUDED diff --git a/src/gui/frame.cpp b/src/gui/frame.cpp index 9ba2bcc25..f85330b07 100644 --- a/src/gui/frame.cpp +++ b/src/gui/frame.cpp @@ -275,7 +275,17 @@ bool Frame::onProcessMessage(Message* msg) case JM_CLOSE: // Fire Close signal { - CloseEvent ev; + CloseEvent::Trigger trigger; + if (m_killer && + m_killer->getName() && + strcmp(m_killer->getName(), "theme_close_button") == 0) { + trigger = CloseEvent::ByUser; + } + else { + trigger = CloseEvent::ByCode; + } + + CloseEvent ev(this, trigger); Close(ev); } break; diff --git a/src/gui/frame.h b/src/gui/frame.h index d98e5b4b2..d57a2cbed 100644 --- a/src/gui/frame.h +++ b/src/gui/frame.h @@ -10,11 +10,12 @@ #include "base/compiler_specific.h" #include "base/signal.h" #include "gfx/point.h" +#include "gui/close_event.h" #include "gui/event.h" #include "gui/hit_test_event.h" #include "gui/widget.h" -class CloseEvent { }; // TODO +class CloseEvent; class Frame : public Widget { diff --git a/src/modules/editors.cpp b/src/modules/editors.cpp index 8f70f9880..52fbd0f44 100644 --- a/src/modules/editors.cpp +++ b/src/modules/editors.cpp @@ -21,6 +21,7 @@ #include "modules/editors.h" #include "app.h" +#include "core/cfg.h" #include "document_wrappers.h" #include "gui/gui.h" #include "modules/gui.h" @@ -67,6 +68,7 @@ Widget* box_editors = NULL; static EditorList editors; static Frame* mini_editor_frame = NULL; +static bool mini_editor_enabled = true; // True if the user wants to use the mini editor static Editor* mini_editor = NULL; static int is_document_in_some_editor(Document* document); @@ -77,6 +79,7 @@ static int count_parents(Widget* widget); static void create_mini_editor_frame(); static void hide_mini_editor_frame(); static void update_mini_editor_frame(Editor* editor); +static void on_mini_editor_frame_close(CloseEvent& ev); class WrappedEditor : public Editor, public EditorListener @@ -96,24 +99,7 @@ public: } void scrollChanged(Editor* editor) OVERRIDE { - // Show the mini editor if it wasn't created yet and the user - // zoomed in, or if the mini-editor was created and the zoom of - // both editors is not the same. - if ((!mini_editor && editor->getZoom() > 0) || - (mini_editor && mini_editor->getZoom() != editor->getZoom())) { - // If the mini frame does not exist, create it - if (!mini_editor_frame) - create_mini_editor_frame(); - - if (!mini_editor_frame->isVisible()) - mini_editor_frame->open_window_bg(); - - update_mini_editor_frame(editor); - } - // Hide the mini editor - else { - hide_mini_editor_frame(); - } + update_mini_editor_frame(editor); } void documentChanged(Editor* editor) OVERRIDE { @@ -140,11 +126,14 @@ public: int init_module_editors() { + mini_editor_enabled = get_config_bool("MiniEditor", "Enabled", true); return 0; } void exit_module_editors() { + set_config_bool("MiniEditor", "Enabled", mini_editor_enabled); + if (mini_editor_frame) { save_window_pos(mini_editor_frame, "MiniEditor"); @@ -506,6 +495,18 @@ void make_unique_editor(Editor* editor) editor->updateEditor(); } +bool is_mini_editor_enabled() +{ + return mini_editor_enabled; +} + +void enable_mini_editor(bool state) +{ + mini_editor_enabled = state; + + update_mini_editor_frame(current_editor); +} + static int is_document_in_some_editor(Document* document) { for (EditorList::iterator it = editors.begin(); it != editors.end(); ++it) { @@ -566,9 +567,14 @@ static void create_mini_editor_frame() mini_editor_frame->set_autoremap(false); mini_editor_frame->set_wantfocus(false); + // Hook Close button to disable mini-editor when the frame is closed. + mini_editor_frame->Close.connect(&on_mini_editor_frame_close); + + // Create the new for the mini editor View* newView = new EditorView(EditorView::AlwaysSelected); jwidget_expansive(newView, true); + // Create mini editor mini_editor = new MiniEditor(); editors.push_back(EditorItem(mini_editor, EditorItem::Mini)); @@ -597,12 +603,26 @@ static void hide_mini_editor_frame() static void update_mini_editor_frame(Editor* editor) { - if (!mini_editor) + if (!mini_editor_enabled || !editor) { + hide_mini_editor_frame(); return; + } Document* document = editor->getDocument(); - if (document && document->getSprite()) { + // Show the mini editor if it wasn't created yet and the user + // zoomed in, or if the mini-editor was created and the zoom of + // both editors is not the same. + if (document && document->getSprite() && + ((!mini_editor && editor->getZoom() > 0) || + (mini_editor && mini_editor->getZoom() != editor->getZoom()))) { + // If the mini frame does not exist, create it + if (!mini_editor_frame) + create_mini_editor_frame(); + + if (!mini_editor_frame->isVisible()) + mini_editor_frame->open_window_bg(); + gfx::Rect visibleBounds = editor->getVisibleSpriteBounds(); gfx::Point pt = visibleBounds.getCenter(); @@ -616,7 +636,20 @@ static void update_mini_editor_frame(Editor* editor) mini_editor->centerInSpritePoint(pt.x, pt.y); } else { - // When the editor does not have a document, we hide the mini-editor. hide_mini_editor_frame(); } } + +static void on_mini_editor_frame_close(CloseEvent& ev) +{ + if (ev.getTrigger() == CloseEvent::ByUser) { + // Here we don't use "enable_mini_editor" to change the state of + // "mini_editor_enabled" because we're coming from a close event + // of the frame. + mini_editor_enabled = false; + + // Redraw the tool bar because it shows the mini editor enabled state. + // TODO abstract this event + app_get_toolbar()->invalidate(); + } +} diff --git a/src/modules/editors.h b/src/modules/editors.h index 538c79544..58edf4c41 100644 --- a/src/modules/editors.h +++ b/src/modules/editors.h @@ -50,5 +50,8 @@ void split_editor(Editor* editor, int align); void close_editor(Editor* editor); void make_unique_editor(Editor* editor); +bool is_mini_editor_enabled(); +void enable_mini_editor(bool state); + #endif diff --git a/src/widgets/toolbar.cpp b/src/widgets/toolbar.cpp index ff3b61f55..475b07ec2 100644 --- a/src/widgets/toolbar.cpp +++ b/src/widgets/toolbar.cpp @@ -30,6 +30,7 @@ #include "gui/gui.h" #include "modules/gfx.h" #include "modules/gui.h" +#include "modules/editors.h" #include "skin/skin_theme.h" #include "tools/tool_box.h" #include "ui_context.h" @@ -49,12 +50,12 @@ class ToolBar : public Widget // What tool is selected for each tool-group std::map m_selected_in_group; + // Index of the tool group or special button highlighted. + int m_hot_index; + // What tool has the mouse above Tool* m_hot_tool; - // Does the configuration button have the mouse above? - bool m_hot_conf; - // True if the popup-window must be opened when a tool-button is hot bool m_open_on_hot; @@ -68,6 +69,10 @@ class ToolBar : public Widget bool m_tipOpened; public: + static const int NoneIndex = -1; + static const int ConfigureToolIndex = -2; + static const int MiniEditorVisibilityIndex = -3; + ToolBar(); ~ToolBar(); @@ -150,7 +155,7 @@ ToolBar::ToolBar() this->border_width.b = 0; m_hot_tool = NULL; - m_hot_conf = false; + m_hot_index = NoneIndex; m_open_on_hot = false; m_popupFrame = NULL; m_tipWindow = NULL; @@ -205,7 +210,7 @@ bool ToolBar::onProcessMessage(Message* msg) int face, nw; if (UIContext::instance()->getSettings()->getCurrentTool() == tool || - m_hot_tool == tool) { + m_hot_index == c) { nw = PART_TOOLBUTTON_HOT_NW; face = theme->get_button_hot_face_color(); } @@ -229,16 +234,17 @@ bool ToolBar::onProcessMessage(Message* msg) } } - toolrc = getToolGroupBounds(-1); + // Draw button to show tool configuration + toolrc = getToolGroupBounds(ConfigureToolIndex); toolrc.offset(-msg->draw.rect.x1, -msg->draw.rect.y1); + bool isHot = (m_hot_index == ConfigureToolIndex); theme->draw_bounds_nw(doublebuffer, toolrc, - m_hot_conf ? PART_TOOLBUTTON_HOT_NW: - PART_TOOLBUTTON_LAST_NW, - m_hot_conf ? theme->get_button_hot_face_color(): - theme->get_button_normal_face_color()); + isHot ? PART_TOOLBUTTON_HOT_NW: + PART_TOOLBUTTON_LAST_NW, + isHot ? theme->get_button_hot_face_color(): + theme->get_button_normal_face_color()); - // Draw the tool icon BITMAP* icon = theme->get_toolicon("configuration"); if (icon) { set_alpha_blender(); @@ -247,6 +253,27 @@ bool ToolBar::onProcessMessage(Message* msg) toolrc.y+toolrc.h/2-icon->h/2); } + // Draw button to show/hide mini editor + toolrc = getToolGroupBounds(MiniEditorVisibilityIndex); + toolrc.offset(-msg->draw.rect.x1, -msg->draw.rect.y1); + isHot = (m_hot_index == MiniEditorVisibilityIndex || + is_mini_editor_enabled()); + theme->draw_bounds_nw(doublebuffer, + toolrc, + isHot ? PART_TOOLBUTTON_HOT_NW: + PART_TOOLBUTTON_LAST_NW, + isHot ? theme->get_button_hot_face_color(): + theme->get_button_normal_face_color()); + + icon = theme->get_toolicon("minieditor"); + if (icon) { + set_alpha_blender(); + draw_trans_sprite(doublebuffer, icon, + toolrc.x+toolrc.w/2-icon->w/2, + toolrc.y+toolrc.h/2-icon->h/2); + } + + // Blit result to screen blit(doublebuffer, ji_screen, 0, 0, msg->draw.rect.x1, msg->draw.rect.y1, @@ -278,23 +305,28 @@ bool ToolBar::onProcessMessage(Message* msg) } } - toolrc = getToolGroupBounds(-1); + toolrc = getToolGroupBounds(ConfigureToolIndex); if (msg->mouse.y >= toolrc.y && msg->mouse.y < toolrc.y+toolrc.h) { Command* conf_tools_cmd = CommandsModule::instance()->getCommandByName(CommandId::ConfigureTools); UIContext::instance()->executeCommand(conf_tools_cmd); } + + toolrc = getToolGroupBounds(MiniEditorVisibilityIndex); + if (msg->mouse.y >= toolrc.y && msg->mouse.y < toolrc.y+toolrc.h) { + // Switch the state of the mini editor + enable_mini_editor(!is_mini_editor_enabled()); + } break; } case JM_MOTION: { ToolBox* toolbox = App::instance()->getToolBox(); int groups = toolbox->getGroupsCount(); - Tool* hot_tool = NULL; - bool hot_conf = false; + Tool* new_hot_tool = NULL; + int new_hot_index = NoneIndex; Rect toolrc; - int tip_index = -1; ToolGroupList::iterator it = toolbox->begin_group(); @@ -304,30 +336,34 @@ bool ToolBar::onProcessMessage(Message* msg) toolrc = getToolGroupBounds(c); if (msg->mouse.y >= toolrc.y && msg->mouse.y < toolrc.y+toolrc.h) { - hot_tool = tool; + new_hot_tool = tool; + new_hot_index = c; - if ((m_open_on_hot) && (m_hot_tool != hot_tool)) + if ((m_open_on_hot) && (m_hot_tool != new_hot_tool)) openPopupFrame(c, tool_group); - - tip_index = c; break; } } - toolrc = getToolGroupBounds(-1); + toolrc = getToolGroupBounds(ConfigureToolIndex); if (msg->mouse.y >= toolrc.y && msg->mouse.y < toolrc.y+toolrc.h) { - hot_conf = true; + new_hot_index = ConfigureToolIndex; + } + + toolrc = getToolGroupBounds(MiniEditorVisibilityIndex); + if (msg->mouse.y >= toolrc.y && msg->mouse.y < toolrc.y+toolrc.h) { + new_hot_index = MiniEditorVisibilityIndex; } // hot button changed - if (m_hot_tool != hot_tool || - m_hot_conf != hot_conf) { - m_hot_tool = hot_tool; - m_hot_conf = hot_conf; + if (new_hot_tool != m_hot_tool || + new_hot_index != m_hot_index) { + m_hot_tool = new_hot_tool; + m_hot_index = new_hot_index; invalidate(); - if (m_hot_tool || m_hot_conf) - openTipWindow(tip_index, m_hot_tool); + if (m_hot_index != NoneIndex) + openTipWindow(m_hot_index, m_hot_tool); else closeTipWindow(); @@ -344,7 +380,7 @@ bool ToolBar::onProcessMessage(Message* msg) m_tipOpened = false; m_hot_tool = NULL; - m_hot_conf = false; + m_hot_index = NoneIndex; invalidate(); app_get_statusbar()->clearText(); @@ -459,14 +495,23 @@ Rect ToolBar::getToolGroupBounds(int group_index) Rect rc(getBounds()); rc.shrink(getBorder()); - if (group_index >= 0) { - rc.y += group_index*(iconsize.h-1*jguiscale()); - rc.h = group_index < groups-1 ? iconsize.h+1*jguiscale(): - iconsize.h+2*jguiscale(); - } - else { - rc.y += groups*(iconsize.h-1*jguiscale())+ 8*jguiscale(); - rc.h = iconsize.h+2*jguiscale(); + switch (group_index) { + + case ConfigureToolIndex: + rc.y += groups*(iconsize.h-1*jguiscale())+ 8*jguiscale(); + rc.h = iconsize.h+2*jguiscale(); + break; + + case MiniEditorVisibilityIndex: + rc.y += rc.h - iconsize.h - 2*jguiscale(); + rc.h = iconsize.h+2*jguiscale(); + break; + + default: + rc.y += group_index*(iconsize.h-1*jguiscale()); + rc.h = group_index < groups-1 ? iconsize.h+1*jguiscale(): + iconsize.h+2*jguiscale(); + break; } return rc; @@ -502,7 +547,7 @@ void ToolBar::openTipWindow(int group_index, Tool* tool) closeTipWindow(); std::string tooltip; - if (tool) { + if (tool && group_index >= 0) { tooltip = tool->getText(); if (tool->getTips().size() > 0) { tooltip += ":\n"; @@ -518,9 +563,17 @@ void ToolBar::openTipWindow(int group_index, Tool* tool) tooltip += buf; } } - else { + else if (group_index == ConfigureToolIndex) { tooltip = "Configure Tool"; } + else if (group_index == MiniEditorVisibilityIndex) { + if (is_mini_editor_enabled()) + tooltip = "Disable Mini-Editor"; + else + tooltip = "Enable Mini-Editor"; + } + else + return; m_tipWindow = new TipWindow(tooltip.c_str(), true); m_tipWindow->setArrowAlign(JI_TOP | JI_RIGHT);