From 5f33b55a11940d0a9abc604dbfe60de2739692e0 Mon Sep 17 00:00:00 2001 From: David Capello Date: Thu, 30 Nov 2017 14:51:13 -0300 Subject: [PATCH] Add new commands to show color bar menus/options Added QuickCommand class to create commands in the relevant place (e.g. the ColorBar commands can be created in ColorBar::registerCommands()). --- data/strings/en.ini | 5 + src/app/CMakeLists.txt | 1 + src/app/commands/cmd_add_color.cpp | 3 +- .../commands/cmd_background_from_layer.cpp | 4 +- src/app/commands/cmd_cancel.cpp | 1 + src/app/commands/cmd_change_brush.cpp | 1 + src/app/commands/cmd_change_color.cpp | 1 + src/app/commands/cmd_change_pixel_format.cpp | 1 + src/app/commands/cmd_frame_properties.cpp | 3 +- src/app/commands/cmd_keyboard_shortcuts.cpp | 52 ++++- src/app/commands/cmd_layer_opacity.cpp | 1 + src/app/commands/cmd_load_mask.cpp | 2 +- src/app/commands/cmd_move_mask.h | 3 +- src/app/commands/cmd_scroll.cpp | 3 +- src/app/commands/cmd_select_tile.cpp | 2 +- src/app/commands/cmd_set_color_selector.cpp | 3 +- src/app/commands/cmd_set_ink_type.cpp | 3 +- src/app/commands/cmd_timeline.cpp | 1 + src/app/commands/cmd_zoom.cpp | 3 +- src/app/commands/command.cpp | 29 +-- src/app/commands/command.h | 4 +- src/app/commands/commands.cpp | 9 +- src/app/commands/commands.h | 7 +- src/app/commands/quick_command.cpp | 44 ++++ src/app/commands/quick_command.h | 33 +++ src/app/context.cpp | 2 + src/app/ui/color_bar.cpp | 196 ++++++++++-------- src/app/ui/color_bar.h | 4 + 28 files changed, 307 insertions(+), 114 deletions(-) create mode 100644 src/app/commands/quick_command.cpp create mode 100644 src/app/commands/quick_command.h diff --git a/data/strings/en.ini b/data/strings/en.ini index ca086a4eb..f1c4775df 100644 --- a/data/strings/en.ini +++ b/data/strings/en.ini @@ -163,6 +163,11 @@ clear = &Delete unlink = &Unlink link_cels = &Link Cels +[commands] +ShowPaletteSortOptions = Show Palette Sort Options +ShowPalettePresets = Show Palette Presets +ShowPaletteOptions = Show Palette Options + [document_tab_popup_menu] duplicate_view = Duplicate &View open_with_os = &Open with OS diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt index ef8ec2e5e..de7ce9e90 100644 --- a/src/app/CMakeLists.txt +++ b/src/app/CMakeLists.txt @@ -364,6 +364,7 @@ add_library(app-lib commands/filters/filter_target_buttons.cpp commands/filters/filter_window.cpp commands/filters/filter_worker.cpp + commands/quick_command.cpp console.cpp context.cpp context_flags.cpp diff --git a/src/app/commands/cmd_add_color.cpp b/src/app/commands/cmd_add_color.cpp index d4407ecd3..3d03922f3 100644 --- a/src/app/commands/cmd_add_color.cpp +++ b/src/app/commands/cmd_add_color.cpp @@ -1,5 +1,5 @@ // Aseprite -// Copyright (C) 2016 David Capello +// Copyright (C) 2016-2017 David Capello // // This program is distributed under the terms of // the End-User License Agreement for Aseprite. @@ -32,6 +32,7 @@ public: AddColorCommand(); protected: + bool onNeedsParams() const override { return true; } void onLoadParams(const Params& params) override; bool onEnabled(Context* ctx) override; void onExecute(Context* ctx) override; diff --git a/src/app/commands/cmd_background_from_layer.cpp b/src/app/commands/cmd_background_from_layer.cpp index f350e2b2c..b669930fb 100644 --- a/src/app/commands/cmd_background_from_layer.cpp +++ b/src/app/commands/cmd_background_from_layer.cpp @@ -1,5 +1,5 @@ // Aseprite -// Copyright (C) 2001-2016 David Capello +// Copyright (C) 2001-2017 David Capello // // This program is distributed under the terms of // the End-User License Agreement for Aseprite. @@ -31,7 +31,7 @@ protected: BackgroundFromLayerCommand::BackgroundFromLayerCommand() : Command("BackgroundFromLayer", - "BackgroundFromLayer", + "Background From Layer", CmdRecordableFlag) { } diff --git a/src/app/commands/cmd_cancel.cpp b/src/app/commands/cmd_cancel.cpp index fd4f6adfb..404f47198 100644 --- a/src/app/commands/cmd_cancel.cpp +++ b/src/app/commands/cmd_cancel.cpp @@ -29,6 +29,7 @@ public: Command* clone() const override { return new CancelCommand(*this); } protected: + bool onNeedsParams() const override { return true; } void onLoadParams(const Params& params) override; void onExecute(Context* context) override; diff --git a/src/app/commands/cmd_change_brush.cpp b/src/app/commands/cmd_change_brush.cpp index 22ab4d02b..af9dce2a2 100644 --- a/src/app/commands/cmd_change_brush.cpp +++ b/src/app/commands/cmd_change_brush.cpp @@ -37,6 +37,7 @@ public: ChangeBrushCommand(); protected: + bool onNeedsParams() const override { return true; } void onLoadParams(const Params& params) override; void onExecute(Context* context) override; std::string onGetFriendlyName() const override; diff --git a/src/app/commands/cmd_change_color.cpp b/src/app/commands/cmd_change_color.cpp index 2d24a94fe..625d53245 100644 --- a/src/app/commands/cmd_change_color.cpp +++ b/src/app/commands/cmd_change_color.cpp @@ -38,6 +38,7 @@ public: ChangeColorCommand(); protected: + bool onNeedsParams() const override { return true; } void onLoadParams(const Params& params) override; void onExecute(Context* context) override; std::string onGetFriendlyName() const override; diff --git a/src/app/commands/cmd_change_pixel_format.cpp b/src/app/commands/cmd_change_pixel_format.cpp index 1c0621d51..e738a96f5 100644 --- a/src/app/commands/cmd_change_pixel_format.cpp +++ b/src/app/commands/cmd_change_pixel_format.cpp @@ -334,6 +334,7 @@ public: Command* clone() const override { return new ChangePixelFormatCommand(*this); } protected: + bool onNeedsParams() const override { return true; } void onLoadParams(const Params& params) override; bool onEnabled(Context* context) override; bool onChecked(Context* context) override; diff --git a/src/app/commands/cmd_frame_properties.cpp b/src/app/commands/cmd_frame_properties.cpp index 7ec67526c..b163d3388 100644 --- a/src/app/commands/cmd_frame_properties.cpp +++ b/src/app/commands/cmd_frame_properties.cpp @@ -1,5 +1,5 @@ // Aseprite -// Copyright (C) 2001-2016 David Capello +// Copyright (C) 2001-2017 David Capello // // This program is distributed under the terms of // the End-User License Agreement for Aseprite. @@ -32,6 +32,7 @@ public: Command* clone() const override { return new FramePropertiesCommand(*this); } protected: + bool onNeedsParams() const override { return true; } void onLoadParams(const Params& params) override; bool onEnabled(Context* context) override; void onExecute(Context* context) override; diff --git a/src/app/commands/cmd_keyboard_shortcuts.cpp b/src/app/commands/cmd_keyboard_shortcuts.cpp index 0ed72181c..25a16ff63 100644 --- a/src/app/commands/cmd_keyboard_shortcuts.cpp +++ b/src/app/commands/cmd_keyboard_shortcuts.cpp @@ -11,6 +11,7 @@ #include "app/app.h" #include "app/app_menus.h" #include "app/commands/command.h" +#include "app/commands/commands.h" #include "app/context.h" #include "app/file_selector.h" #include "app/i18n/strings.h" @@ -39,6 +40,8 @@ #include "keyboard_shortcuts.xml.h" +#include + #define KEYBOARD_FILENAME_EXTENSION "aseprite-keys" namespace app { @@ -503,8 +506,9 @@ private: deleteAllKeyItems(); // Load keyboard shortcuts - fillList(menus(), AppMenus::instance()->getRootMenu(), 0); - fillList(tools(), App::instance()->toolBox()); + fillMenusList(menus(), AppMenus::instance()->getRootMenu(), 0); + fillToolsList(tools(), App::instance()->toolBox()); + for (Key* key : *app::KeyboardShortcuts::instance()) { if (key->type() == KeyType::Tool || key->type() == KeyType::Quicktool) { @@ -682,7 +686,7 @@ private: } } - void fillList(ListBox* listbox, Menu* menu, int level) { + void fillMenusList(ListBox* listbox, Menu* menu, int level) { for (auto child : menu->children()) { if (AppMenuItem* menuItem = dynamic_cast(child)) { if (menuItem == AppMenus::instance()->getRecentListMenuitem()) @@ -697,12 +701,12 @@ private: listbox->addChild(keyItem); if (menuItem->hasSubmenu()) - fillList(listbox, menuItem->getSubmenu(), level+1); + fillMenusList(listbox, menuItem->getSubmenu(), level+1); } } } - void fillList(ListBox* listbox, ToolBox* toolbox) { + void fillToolsList(ListBox* listbox, ToolBox* toolbox) { for (Tool* tool : *toolbox) { std::string text = tool->getText(); @@ -739,6 +743,8 @@ protected: void onExecute(Context* context) override; private: + void addMissingKeyboardShortcutsForCommands(); + std::string m_search; }; @@ -756,6 +762,8 @@ void KeyboardShortcutsCommand::onLoadParams(const Params& params) void KeyboardShortcutsCommand::onExecute(Context* context) { + addMissingKeyboardShortcutsForCommands(); + // Here we copy the m_search field because // KeyboardShortcutsWindow::fillAllLists() modifies this same // KeyboardShortcutsCommand instance (so m_search will be "") @@ -787,6 +795,40 @@ void KeyboardShortcutsCommand::onExecute(Context* context) AppMenus::instance()->syncNativeMenuItemKeyShortcuts(); } +void KeyboardShortcutsCommand::addMissingKeyboardShortcutsForCommands() +{ + std::set commandsAlreadyAdded; + auto keys = app::KeyboardShortcuts::instance(); + for (Key* key : *keys) { + if (key->type() != KeyType::Command) + continue; + + if (key->params().empty()) + commandsAlreadyAdded.insert(key->command()->id()); + } + + std::vector ids; + Commands* commands = Commands::instance(); + commands->getAllIds(ids); + + for (const std::string& id : ids) { + Command* command = commands->byId(id.c_str()); + + // Don't add commands that need params (they will be added to + // the list using the list of keyboard shortcuts from gui.xml). + if (command->needsParams()) + continue; + + auto it = commandsAlreadyAdded.find(command->id()); + if (it != commandsAlreadyAdded.end()) + continue; + + // Create the new Key element in KeyboardShortcuts for this + // command without params. + keys->command(command->id().c_str()); + } +} + Command* CommandFactory::createKeyboardShortcutsCommand() { return new KeyboardShortcutsCommand; diff --git a/src/app/commands/cmd_layer_opacity.cpp b/src/app/commands/cmd_layer_opacity.cpp index b81c7da41..0abdc392e 100644 --- a/src/app/commands/cmd_layer_opacity.cpp +++ b/src/app/commands/cmd_layer_opacity.cpp @@ -29,6 +29,7 @@ public: LayerOpacityCommand(); protected: + bool onNeedsParams() const override { return true; } void onLoadParams(const Params& params) override; bool onEnabled(Context* context) override; void onExecute(Context* context) override; diff --git a/src/app/commands/cmd_load_mask.cpp b/src/app/commands/cmd_load_mask.cpp index fbfc2380a..61a3ac0e8 100644 --- a/src/app/commands/cmd_load_mask.cpp +++ b/src/app/commands/cmd_load_mask.cpp @@ -39,7 +39,7 @@ protected: LoadMaskCommand::LoadMaskCommand() : Command("LoadMask", - "LoadMask", + "Load Mask", CmdRecordableFlag) { m_filename = ""; diff --git a/src/app/commands/cmd_move_mask.h b/src/app/commands/cmd_move_mask.h index 7e6343803..86d8bd729 100644 --- a/src/app/commands/cmd_move_mask.h +++ b/src/app/commands/cmd_move_mask.h @@ -1,5 +1,5 @@ // Aseprite -// Copyright (C) 2001-2016 David Capello +// Copyright (C) 2001-2017 David Capello // // This program is distributed under the terms of // the End-User License Agreement for Aseprite. @@ -34,6 +34,7 @@ namespace app { gfx::Point getDelta(Context* context) const; protected: + bool onNeedsParams() const override { return true; } void onLoadParams(const Params& params) override; bool onEnabled(Context* context) override; void onExecute(Context* context) override; diff --git a/src/app/commands/cmd_scroll.cpp b/src/app/commands/cmd_scroll.cpp index f24abf90f..cd79c9811 100644 --- a/src/app/commands/cmd_scroll.cpp +++ b/src/app/commands/cmd_scroll.cpp @@ -1,5 +1,5 @@ // Aseprite -// Copyright (C) 2001-2015 David Capello +// Copyright (C) 2001-2017 David Capello // // This program is distributed under the terms of // the End-User License Agreement for Aseprite. @@ -38,6 +38,7 @@ public: Command* clone() const override { return new ScrollCommand(*this); } protected: + bool onNeedsParams() const override { return true; } void onLoadParams(const Params& params) override; bool onEnabled(Context* context) override; void onExecute(Context* context) override; diff --git a/src/app/commands/cmd_select_tile.cpp b/src/app/commands/cmd_select_tile.cpp index d6c9606cf..77382e598 100644 --- a/src/app/commands/cmd_select_tile.cpp +++ b/src/app/commands/cmd_select_tile.cpp @@ -1,5 +1,5 @@ // Aseprite -// Copyright (C) 2015, 2016 David Capello +// Copyright (C) 2015-2017 David Capello // // This program is distributed under the terms of // the End-User License Agreement for Aseprite. diff --git a/src/app/commands/cmd_set_color_selector.cpp b/src/app/commands/cmd_set_color_selector.cpp index 1638c592d..8b866e853 100644 --- a/src/app/commands/cmd_set_color_selector.cpp +++ b/src/app/commands/cmd_set_color_selector.cpp @@ -1,5 +1,5 @@ // Aseprite -// Copyright (C) 2016 David Capello +// Copyright (C) 2016-2017 David Capello // // This program is distributed under the terms of // the End-User License Agreement for Aseprite. @@ -21,6 +21,7 @@ public: Command* clone() const override { return new SetColorSelectorCommand(*this); } protected: + bool onNeedsParams() const override { return true; } void onLoadParams(const Params& params) override; bool onChecked(Context* context) override; void onExecute(Context* context) override; diff --git a/src/app/commands/cmd_set_ink_type.cpp b/src/app/commands/cmd_set_ink_type.cpp index 5758f72e7..29a9c0c46 100644 --- a/src/app/commands/cmd_set_ink_type.cpp +++ b/src/app/commands/cmd_set_ink_type.cpp @@ -1,5 +1,5 @@ // Aseprite -// Copyright (C) 2001-2016 David Capello +// Copyright (C) 2001-2017 David Capello // // This program is distributed under the terms of // the End-User License Agreement for Aseprite. @@ -23,6 +23,7 @@ public: Command* clone() const override { return new SetInkTypeCommand(*this); } protected: + bool onNeedsParams() const override { return true; } void onLoadParams(const Params& params) override; bool onChecked(Context* context) override; void onExecute(Context* context) override; diff --git a/src/app/commands/cmd_timeline.cpp b/src/app/commands/cmd_timeline.cpp index 440da6cfa..99f693367 100644 --- a/src/app/commands/cmd_timeline.cpp +++ b/src/app/commands/cmd_timeline.cpp @@ -25,6 +25,7 @@ public: Command* clone() const override { return new TimelineCommand(*this); } protected: + bool onNeedsParams() const override { return true; } void onLoadParams(const Params& params) override; void onExecute(Context* context) override; bool onChecked(Context* ctx) override; diff --git a/src/app/commands/cmd_zoom.cpp b/src/app/commands/cmd_zoom.cpp index 7043ba3b4..7ae6bac71 100644 --- a/src/app/commands/cmd_zoom.cpp +++ b/src/app/commands/cmd_zoom.cpp @@ -1,5 +1,5 @@ // Aseprite -// Copyright (C) 2001-2016 David Capello +// Copyright (C) 2001-2017 David Capello // // This program is distributed under the terms of // the End-User License Agreement for Aseprite. @@ -30,6 +30,7 @@ public: Command* clone() const override { return new ZoomCommand(*this); } protected: + bool onNeedsParams() const override { return true; } void onLoadParams(const Params& params) override; bool onEnabled(Context* context) override; void onExecute(Context* context) override; diff --git a/src/app/commands/command.cpp b/src/app/commands/command.cpp index d7d9e6459..753b76c78 100644 --- a/src/app/commands/command.cpp +++ b/src/app/commands/command.cpp @@ -1,5 +1,5 @@ // Aseprite -// Copyright (C) 2001-2015 David Capello +// Copyright (C) 2001-2017 David Capello // // This program is distributed under the terms of // the End-User License Agreement for Aseprite. @@ -30,6 +30,11 @@ std::string Command::friendlyName() const return onGetFriendlyName(); } +bool Command::needsParams() const +{ + return onNeedsParams(); +} + void Command::loadParams(const Params& params) { onLoadParams(params); @@ -62,33 +67,31 @@ void Command::execute(Context* context) onExecute(context); } -/** - * Converts specified parameters to class members. - */ +bool Command::onNeedsParams() const +{ + // By default a command can be called without params + return false; +} + +// Converts specified parameters to class members. void Command::onLoadParams(const Params& params) { // do nothing } -/** - * Preconditions to execute the command - */ +// Preconditions to execute the command bool Command::onEnabled(Context* context) { return true; } -/** - * Should the menu-item be checked? - */ +// Should the menu-item be checked? bool Command::onChecked(Context* context) { return false; } -/** - * Execute the command (after checking the preconditions). - */ +// Execute the command (after checking the preconditions). void Command::onExecute(Context* context) { // Do nothing diff --git a/src/app/commands/command.h b/src/app/commands/command.h index 0cfe27666..40739dc20 100644 --- a/src/app/commands/command.h +++ b/src/app/commands/command.h @@ -1,5 +1,5 @@ // Aseprite -// Copyright (C) 2001-2015 David Capello +// Copyright (C) 2001-2017 David Capello // // This program is distributed under the terms of // the End-User License Agreement for Aseprite. @@ -30,12 +30,14 @@ namespace app { const std::string& id() const { return m_id; } std::string friendlyName() const; + bool needsParams() const; void loadParams(const Params& params); bool isEnabled(Context* context); bool isChecked(Context* context); void execute(Context* context); protected: + virtual bool onNeedsParams() const; virtual void onLoadParams(const Params& params); virtual bool onEnabled(Context* context); virtual bool onChecked(Context* context); diff --git a/src/app/commands/commands.cpp b/src/app/commands/commands.cpp index d53b71fa7..97ad9299d 100644 --- a/src/app/commands/commands.cpp +++ b/src/app/commands/commands.cpp @@ -70,10 +70,17 @@ Command* Commands::byId(const char* id) return (it != m_commands.end() ? it->second: nullptr); } -void Commands::add(Command* command) +Commands* Commands::add(Command* command) { auto lid = base::string_to_lower(command->id()); m_commands[lid] = command; + return this; +} + +void Commands::getAllIds(std::vector& ids) +{ + for (auto& it : m_commands) + ids.push_back(it.second->id()); } } // namespace app diff --git a/src/app/commands/commands.h b/src/app/commands/commands.h index 876dee8d4..ceeff0d44 100644 --- a/src/app/commands/commands.h +++ b/src/app/commands/commands.h @@ -1,5 +1,5 @@ // Aseprite -// Copyright (C) 2001-2015, 2017 David Capello +// Copyright (C) 2001-2017 David Capello // // This program is distributed under the terms of // the End-User License Agreement for Aseprite. @@ -12,6 +12,7 @@ #include #include +#include namespace app { @@ -35,7 +36,9 @@ namespace app { static Commands* instance(); Command* byId(const char* id); - void add(Command* command); + Commands* add(Command* command); + + void getAllIds(std::vector& ids); private: std::map m_commands; diff --git a/src/app/commands/quick_command.cpp b/src/app/commands/quick_command.cpp new file mode 100644 index 000000000..38bd0e3b4 --- /dev/null +++ b/src/app/commands/quick_command.cpp @@ -0,0 +1,44 @@ +// Aseprite +// Copyright (C) 2017 David Capello +// +// This program is distributed under the terms of +// the End-User License Agreement for Aseprite. + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "app/commands/quick_command.h" + +#include "app/i18n/strings.h" + +namespace app { + +QuickCommand::QuickCommand(const char* id, std::function execute) + : Command(id, id, CmdUIOnlyFlag) + , m_execute(execute) +{ +} + +QuickCommand::~QuickCommand() +{ +} + +QuickCommand* QuickCommand::clone() const +{ + return new QuickCommand(*this); +} + +void QuickCommand::onExecute(Context* context) +{ + m_execute(); +} + +std::string QuickCommand::onGetFriendlyName() const +{ + std::string id = "commands."; + id += this->id(); + return Strings::instance()->translate(id.c_str()); +} + +} // namespace app diff --git a/src/app/commands/quick_command.h b/src/app/commands/quick_command.h new file mode 100644 index 000000000..2a6ea65aa --- /dev/null +++ b/src/app/commands/quick_command.h @@ -0,0 +1,33 @@ +// Aseprite +// Copyright (C) 2017 David Capello +// +// This program is distributed under the terms of +// the End-User License Agreement for Aseprite. + +#ifndef APP_COMMANDS_QUICK_COMMAND_H_INCLUDED +#define APP_COMMANDS_QUICK_COMMAND_H_INCLUDED +#pragma once + +#include "app/commands/command.h" + +#include + +namespace app { + + class QuickCommand : public Command { + public: + QuickCommand(const char* id, std::function execute); + ~QuickCommand(); + + QuickCommand* clone() const override; + + protected: + void onExecute(Context* context) override; + std::string onGetFriendlyName() const override; + + std::function m_execute; + }; + +} // namespace app + +#endif diff --git a/src/app/context.cpp b/src/app/context.cpp index d65ba40c0..83353d649 100644 --- a/src/app/context.cpp +++ b/src/app/context.cpp @@ -64,6 +64,8 @@ void Context::executeCommand(Command* command, const Params& params) try { m_flags.update(this); + ASSERT(!command->needsParams() || !params.empty()); + command->loadParams(params); CommandExecutionEvent ev(command); diff --git a/src/app/ui/color_bar.cpp b/src/app/ui/color_bar.cpp index b66c0f345..62aab868b 100644 --- a/src/app/ui/color_bar.cpp +++ b/src/app/ui/color_bar.cpp @@ -24,6 +24,7 @@ #include "app/commands/command.h" #include "app/commands/commands.h" #include "app/commands/params.h" +#include "app/commands/quick_command.h" #include "app/console.h" #include "app/context_access.h" #include "app/document_api.h" @@ -277,6 +278,7 @@ ColorBar::ColorBar(int align) base::Bind(&ColorBar::setupTooltips, this, tooltipManager)); setEditMode(false); + registerCommands(); } ColorBar::~ColorBar() @@ -487,92 +489,17 @@ void ColorBar::onPaletteButtonClick() setEditMode(!inEditMode()); break; - case PalButton::SORT: { - gfx::Rect bounds = m_buttons.getItem(item)->bounds(); - - Menu menu; - MenuItem - rev("Reverse Colors"), - grd("Gradient"), - hue("Sort by Hue"), - sat("Sort by Saturation"), - bri("Sort by Brightness"), - lum("Sort by Luminance"), - red("Sort by Red"), - grn("Sort by Green"), - blu("Sort by Blue"), - alp("Sort by Alpha"), - asc("Ascending"), - des("Descending"); - menu.addChild(&rev); - menu.addChild(&grd); - menu.addChild(new ui::MenuSeparator); - menu.addChild(&hue); - menu.addChild(&sat); - menu.addChild(&bri); - menu.addChild(&lum); - menu.addChild(new ui::MenuSeparator); - menu.addChild(&red); - menu.addChild(&grn); - menu.addChild(&blu); - menu.addChild(&alp); - menu.addChild(new ui::MenuSeparator); - menu.addChild(&asc); - menu.addChild(&des); - - if (m_ascending) asc.setSelected(true); - else des.setSelected(true); - - rev.Click.connect(base::Bind(&ColorBar::onReverseColors, this)); - grd.Click.connect(base::Bind(&ColorBar::onGradient, this)); - hue.Click.connect(base::Bind(&ColorBar::onSortBy, this, SortPaletteBy::HUE)); - sat.Click.connect(base::Bind(&ColorBar::onSortBy, this, SortPaletteBy::SATURATION)); - bri.Click.connect(base::Bind(&ColorBar::onSortBy, this, SortPaletteBy::VALUE)); - lum.Click.connect(base::Bind(&ColorBar::onSortBy, this, SortPaletteBy::LUMA)); - red.Click.connect(base::Bind(&ColorBar::onSortBy, this, SortPaletteBy::RED)); - grn.Click.connect(base::Bind(&ColorBar::onSortBy, this, SortPaletteBy::GREEN)); - blu.Click.connect(base::Bind(&ColorBar::onSortBy, this, SortPaletteBy::BLUE)); - alp.Click.connect(base::Bind(&ColorBar::onSortBy, this, SortPaletteBy::ALPHA)); - asc.Click.connect(base::Bind(&ColorBar::setAscending, this, true)); - des.Click.connect(base::Bind(&ColorBar::setAscending, this, false)); - - menu.showPopup(gfx::Point(bounds.x, bounds.y+bounds.h)); + case PalButton::SORT: + showPaletteSortOptions(); break; - } - case PalButton::PRESETS: { - if (!m_palettePopup) { - try { - m_palettePopup.reset(new PalettePopup()); - } - catch (const std::exception& ex) { - Console::showException(ex); - return; - } - } - - if (!m_palettePopup->isVisible()) { - gfx::Rect bounds = m_buttons.getItem(item)->bounds(); - - m_palettePopup->showPopup( - gfx::Rect(bounds.x, bounds.y+bounds.h, - ui::display_w()/2, ui::display_h()*3/4)); - } - else { - m_palettePopup->closeWindow(NULL); - } + case PalButton::PRESETS: + showPalettePresets(); break; - } - case PalButton::OPTIONS: { - Menu* menu = AppMenus::instance()->getPalettePopupMenu(); - if (menu) { - gfx::Rect bounds = m_buttons.getItem(item)->bounds(); - - menu->showPopup(gfx::Point(bounds.x, bounds.y+bounds.h)); - } + case PalButton::OPTIONS: + showPaletteOptions(); break; - } } } @@ -1306,4 +1233,111 @@ void ColorBar::fixColorIndex(ColorButton& colorButton) } } +void ColorBar::registerCommands() +{ + Commands::instance() + ->add( + new QuickCommand( + "ShowPaletteSortOptions", + [this]{ this->showPaletteSortOptions(); })) + ->add( + new QuickCommand( + "ShowPalettePresets", + [this]{ this->showPalettePresets(); })) + ->add( + new QuickCommand( + "ShowPaletteOptions", + [this]{ this->showPaletteOptions(); })); +} + +void ColorBar::showPaletteSortOptions() +{ + gfx::Rect bounds = m_buttons.getItem( + static_cast(PalButton::SORT))->bounds(); + + Menu menu; + MenuItem + rev("Reverse Colors"), + grd("Gradient"), + hue("Sort by Hue"), + sat("Sort by Saturation"), + bri("Sort by Brightness"), + lum("Sort by Luminance"), + red("Sort by Red"), + grn("Sort by Green"), + blu("Sort by Blue"), + alp("Sort by Alpha"), + asc("Ascending"), + des("Descending"); + menu.addChild(&rev); + menu.addChild(&grd); + menu.addChild(new ui::MenuSeparator); + menu.addChild(&hue); + menu.addChild(&sat); + menu.addChild(&bri); + menu.addChild(&lum); + menu.addChild(new ui::MenuSeparator); + menu.addChild(&red); + menu.addChild(&grn); + menu.addChild(&blu); + menu.addChild(&alp); + menu.addChild(new ui::MenuSeparator); + menu.addChild(&asc); + menu.addChild(&des); + + if (m_ascending) asc.setSelected(true); + else des.setSelected(true); + + rev.Click.connect(base::Bind(&ColorBar::onReverseColors, this)); + grd.Click.connect(base::Bind(&ColorBar::onGradient, this)); + hue.Click.connect(base::Bind(&ColorBar::onSortBy, this, SortPaletteBy::HUE)); + sat.Click.connect(base::Bind(&ColorBar::onSortBy, this, SortPaletteBy::SATURATION)); + bri.Click.connect(base::Bind(&ColorBar::onSortBy, this, SortPaletteBy::VALUE)); + lum.Click.connect(base::Bind(&ColorBar::onSortBy, this, SortPaletteBy::LUMA)); + red.Click.connect(base::Bind(&ColorBar::onSortBy, this, SortPaletteBy::RED)); + grn.Click.connect(base::Bind(&ColorBar::onSortBy, this, SortPaletteBy::GREEN)); + blu.Click.connect(base::Bind(&ColorBar::onSortBy, this, SortPaletteBy::BLUE)); + alp.Click.connect(base::Bind(&ColorBar::onSortBy, this, SortPaletteBy::ALPHA)); + asc.Click.connect(base::Bind(&ColorBar::setAscending, this, true)); + des.Click.connect(base::Bind(&ColorBar::setAscending, this, false)); + + menu.showPopup(gfx::Point(bounds.x, bounds.y+bounds.h)); +} + +void ColorBar::showPalettePresets() +{ + if (!m_palettePopup) { + try { + m_palettePopup.reset(new PalettePopup()); + } + catch (const std::exception& ex) { + Console::showException(ex); + return; + } + } + + if (!m_palettePopup->isVisible()) { + gfx::Rect bounds = m_buttons.getItem( + static_cast(PalButton::PRESETS))->bounds(); + + m_palettePopup->showPopup( + gfx::Rect(bounds.x, bounds.y+bounds.h, + ui::display_w()/2, ui::display_h()*3/4)); + } + else { + m_palettePopup->closeWindow(NULL); + } +} + +void ColorBar::showPaletteOptions() +{ + Menu* menu = AppMenus::instance()->getPalettePopupMenu(); + if (menu) { + gfx::Rect bounds = m_buttons.getItem( + static_cast(PalButton::OPTIONS))->bounds(); + + menu->showPopup(gfx::Point(bounds.x, bounds.y+bounds.h)); + } +} + } // namespace app diff --git a/src/app/ui/color_bar.h b/src/app/ui/color_bar.h index 4ac0d5fda..123bbf689 100644 --- a/src/app/ui/color_bar.h +++ b/src/app/ui/color_bar.h @@ -141,6 +141,10 @@ namespace app { int setPaletteEntry(const app::Color& color); void updateCurrentSpritePalette(const char* operationName); void setupTooltips(ui::TooltipManager* tooltipManager); + void registerCommands(); + void showPaletteSortOptions(); + void showPalettePresets(); + void showPaletteOptions(); static void fixColorIndex(ColorButton& color); class ScrollableView : public ui::View {