diff --git a/src/app/app_menus.cpp b/src/app/app_menus.cpp index ba3b17bcd..aa99d07b3 100644 --- a/src/app/app_menus.cpp +++ b/src/app/app_menus.cpp @@ -266,9 +266,9 @@ AppMenuItem::Native get_native_shortcut_for_command( const Params& params = Params()) { AppMenuItem::Native native; - Key* key = KeyboardShortcuts::instance()->command(commandId, params); + KeyPtr key = KeyboardShortcuts::instance()->command(commandId, params); if (key) { - native.shortcut = get_os_shortcut_from_key(key); + native.shortcut = get_os_shortcut_from_key(key.get()); native.keyContext = key->keycontext(); } return native; @@ -276,7 +276,7 @@ AppMenuItem::Native get_native_shortcut_for_command( } // anonymous namespace -she::Shortcut get_os_shortcut_from_key(Key* key) +she::Shortcut get_os_shortcut_from_key(const Key* key) { if (key && !key->accels().empty()) { const ui::Accelerator& accel = key->accels().front(); @@ -556,7 +556,9 @@ Widget* AppMenus::createInvalidVersionMenuitem() return menuitem; } -void AppMenus::applyShortcutToMenuitemsWithCommand(Command* command, const Params& params, Key* key) +void AppMenus::applyShortcutToMenuitemsWithCommand(Command* command, + const Params& params, + const KeyPtr& key) { updateMenusList(); for (Menu* menu : m_menus) @@ -564,7 +566,10 @@ void AppMenus::applyShortcutToMenuitemsWithCommand(Command* command, const Param applyShortcutToMenuitemsWithCommand(menu, command, params, key); } -void AppMenus::applyShortcutToMenuitemsWithCommand(Menu* menu, Command* command, const Params& params, Key* key) +void AppMenus::applyShortcutToMenuitemsWithCommand(Menu* menu, + Command* command, + const Params& params, + const KeyPtr& key) { for (auto child : menu->children()) { if (child->type() == kMenuItemWidget) { diff --git a/src/app/app_menus.h b/src/app/app_menus.h index 90bd4cdc2..bf53212a3 100644 --- a/src/app/app_menus.h +++ b/src/app/app_menus.h @@ -9,6 +9,7 @@ #pragma once #include "app/i18n/xml_translator.h" +#include "app/ui/key.h" #include "app/widget_type_mismatch.h" #include "base/disable_copying.h" #include "base/unique_ptr.h" @@ -25,7 +26,6 @@ namespace she { } namespace app { - class Key; class Command; class Params; @@ -60,7 +60,8 @@ namespace app { Menu* getPalettePopupMenu() { return m_palettePopupMenu; } Menu* getInkPopupMenu() { return m_inkPopupMenu; } - void applyShortcutToMenuitemsWithCommand(Command* command, const Params& params, Key* key); + void applyShortcutToMenuitemsWithCommand(Command* command, const Params& params, + const KeyPtr& key); void syncNativeMenuItemKeyShortcuts(); private: @@ -68,7 +69,8 @@ namespace app { Menu* convertXmlelemToMenu(TiXmlElement* elem); Widget* convertXmlelemToMenuitem(TiXmlElement* elem); Widget* createInvalidVersionMenuitem(); - void applyShortcutToMenuitemsWithCommand(Menu* menu, Command* command, const Params& params, Key* key); + void applyShortcutToMenuitemsWithCommand(Menu* menu, Command* command, const Params& params, + const KeyPtr& key); void syncNativeMenuItemKeyShortcuts(Menu* menu); void updateMenusList(); void createNativeMenus(); @@ -93,7 +95,7 @@ namespace app { XmlTranslator m_xmlTranslator; }; - she::Shortcut get_os_shortcut_from_key(Key* key); + she::Shortcut get_os_shortcut_from_key(const Key* key); } // namespace app diff --git a/src/app/commands/cmd_advanced_mode.cpp b/src/app/commands/cmd_advanced_mode.cpp index ef6f9495e..156d01a88 100644 --- a/src/app/commands/cmd_advanced_mode.cpp +++ b/src/app/commands/cmd_advanced_mode.cpp @@ -62,7 +62,7 @@ void AdvancedModeCommand::onExecute(Context* context) if (oldMode == MainWindow::NormalMode && pref.advancedMode.showAlert()) { - Key* key = KeyboardShortcuts::instance()->command(this->id().c_str()); + KeyPtr key = KeyboardShortcuts::instance()->command(this->id().c_str()); if (!key->accels().empty()) { app::gen::AdvancedMode window; diff --git a/src/app/commands/cmd_keyboard_shortcuts.cpp b/src/app/commands/cmd_keyboard_shortcuts.cpp index 5dee5ce61..6c75a4fe4 100644 --- a/src/app/commands/cmd_keyboard_shortcuts.cpp +++ b/src/app/commands/cmd_keyboard_shortcuts.cpp @@ -126,7 +126,7 @@ class KeyItem : public ListItem { public: KeyItem(const std::string& text, - Key* key, + const KeyPtr& key, AppMenuItem* menuitem, const int level, HeaderItem* headerItem) @@ -144,11 +144,7 @@ public: setBorder(border); } - ~KeyItem() { - delete m_keyOrig; - } - - Key* key() { return m_key; } + KeyPtr key() { return m_key; } AppMenuItem* menuitem() const { return m_menuitem; } void restoreKeys() { @@ -156,7 +152,7 @@ public: *m_key = *m_keyOrig; if (m_menuitem && !m_keyOrig) - m_menuitem->setKey(NULL); + m_menuitem->setKey(nullptr); } std::string searchableText() const { @@ -440,8 +436,8 @@ private: m_hotAccel = -1; } - Key* m_key; - Key* m_keyOrig; + KeyPtr m_key; + KeyPtr m_keyOrig; AppMenuItem* m_menuitem; int m_level; ui::Accelerators m_newAccels; @@ -513,7 +509,7 @@ private: fillMenusList(menus(), AppMenus::instance()->getRootMenu(), 0); fillToolsList(tools(), App::instance()->toolBox()); - for (Key* key : *app::KeyboardShortcuts::instance()) { + for (const KeyPtr& key : *app::KeyboardShortcuts::instance()) { if (key->type() == KeyType::Tool || key->type() == KeyType::Quicktool) { continue; @@ -714,7 +710,7 @@ private: for (Tool* tool : *toolbox) { std::string text = tool->getText(); - Key* key = app::KeyboardShortcuts::instance()->tool(tool); + KeyPtr key = app::KeyboardShortcuts::instance()->tool(tool); KeyItem* keyItem = new KeyItem(text, key, nullptr, 0, &m_headerItem); m_allKeyItems.push_back(keyItem); @@ -801,7 +797,7 @@ void KeyboardShortcutsCommand::addMissingKeyboardShortcutsForCommands() { std::set commandsAlreadyAdded; auto keys = app::KeyboardShortcuts::instance(); - for (Key* key : *keys) { + for (const KeyPtr& key : *keys) { if (key->type() != KeyType::Command) continue; diff --git a/src/app/commands/cmd_new_brush.cpp b/src/app/commands/cmd_new_brush.cpp index 2e166b963..24f870f32 100644 --- a/src/app/commands/cmd_new_brush.cpp +++ b/src/app/commands/cmd_new_brush.cpp @@ -165,7 +165,7 @@ void NewBrushCommand::createBrush(const Site& site, const Mask* mask) Params params; params.set("change", "custom"); params.set("slot", base::convert_to(slot).c_str()); - Key* key = KeyboardShortcuts::instance()->command( + KeyPtr key = KeyboardShortcuts::instance()->command( CommandId::ChangeBrush(), params); if (key && !key->accels().empty()) { std::string tooltip; diff --git a/src/app/commands/filters/cmd_replace_color.cpp b/src/app/commands/filters/cmd_replace_color.cpp index f6ef4e06f..87d1b29c4 100644 --- a/src/app/commands/filters/cmd_replace_color.cpp +++ b/src/app/commands/filters/cmd_replace_color.cpp @@ -105,7 +105,7 @@ private: bool onProcessMessage(ui::Message* msg) override { switch (msg->type()) { case ui::kKeyDownMessage: { - const Key* key = + const KeyPtr key = KeyboardShortcuts::instance()->command(CommandId::SwitchColors()); if (key && key->isPressed(msg)) { // Switch colors diff --git a/src/app/modules/gui.cpp b/src/app/modules/gui.cpp index 584d7ccab..85e2da9a9 100644 --- a/src/app/modules/gui.cpp +++ b/src/app/modules/gui.cpp @@ -377,7 +377,7 @@ bool CustomizedGuiManager::onProcessMessage(Message* msg) if (Manager::onProcessMessage(msg)) return true; - for (const Key* key : *KeyboardShortcuts::instance()) { + for (const KeyPtr& key : *KeyboardShortcuts::instance()) { if (key->isPressed(msg)) { // Cancel menu-bar loops (to close any popup menu) App::instance()->mainWindow()->getMenuBar()->cancelMenuLoop(); @@ -392,7 +392,7 @@ bool CustomizedGuiManager::onProcessMessage(Message* msg) // Collect all tools with the pressed keyboard-shortcut for (tools::Tool* tool : *toolbox) { - Key* key = KeyboardShortcuts::instance()->tool(tool); + const KeyPtr key = KeyboardShortcuts::instance()->tool(tool); if (key && key->isPressed(msg)) possibles.push_back(tool); } diff --git a/src/app/ui/app_menuitem.cpp b/src/app/ui/app_menuitem.cpp index 9154cf1fd..1e635d7ad 100644 --- a/src/app/ui/app_menuitem.cpp +++ b/src/app/ui/app_menuitem.cpp @@ -49,7 +49,7 @@ AppMenuItem::~AppMenuItem() delete m_native; } -void AppMenuItem::setKey(Key* key) +void AppMenuItem::setKey(const KeyPtr& key) { m_key = key; syncNativeMenuItemKeyShortcut(); @@ -66,7 +66,7 @@ void AppMenuItem::setNative(const Native& native) void AppMenuItem::syncNativeMenuItemKeyShortcut() { if (m_native) { - she::Shortcut shortcut = get_os_shortcut_from_key(m_key); + she::Shortcut shortcut = get_os_shortcut_from_key(m_key.get()); m_native->shortcut = shortcut; m_native->menuItem->setShortcut(shortcut); diff --git a/src/app/ui/app_menuitem.h b/src/app/ui/app_menuitem.h index 9fcfd085a..47d292761 100644 --- a/src/app/ui/app_menuitem.h +++ b/src/app/ui/app_menuitem.h @@ -9,7 +9,7 @@ #pragma once #include "app/commands/params.h" -#include "app/ui/key_context.h" +#include "app/ui/key.h" #include "she/shortcut.h" #include "ui/menu.h" @@ -18,7 +18,6 @@ namespace she { } namespace app { - class Key; class Command; // A widget that represent a menu item of the application. @@ -39,8 +38,8 @@ namespace app { const Params& params = Params()); ~AppMenuItem(); - Key* key() { return m_key; } - void setKey(Key* key); + KeyPtr key() { return m_key; } + void setKey(const KeyPtr& key); Command* getCommand() { return m_command; } const Params& getParams() const { return m_params; } @@ -58,7 +57,7 @@ namespace app { void onValidate() override; private: - Key* m_key; + KeyPtr m_key; Command* m_command; Params m_params; Native* m_native; diff --git a/src/app/ui/brush_popup.cpp b/src/app/ui/brush_popup.cpp index 0734ae4c8..4a0f63c74 100644 --- a/src/app/ui/brush_popup.cpp +++ b/src/app/ui/brush_popup.cpp @@ -410,7 +410,7 @@ void BrushPopup::regenerate(const gfx::Rect& box) Params params; params.set("change", "custom"); params.set("slot", base::convert_to(slot).c_str()); - Key* key = KeyboardShortcuts::instance()->command( + KeyPtr key = KeyboardShortcuts::instance()->command( CommandId::ChangeBrush(), params); if (key && !key->accels().empty()) shortcut = key->accels().front().toString(); diff --git a/src/app/ui/doc_view.cpp b/src/app/ui/doc_view.cpp index d17bc4d08..71d6c2fe4 100644 --- a/src/app/ui/doc_view.cpp +++ b/src/app/ui/doc_view.cpp @@ -113,8 +113,8 @@ protected: case kKeyDownMessage: case kKeyUpMessage: if (static_cast(msg)->repeat() == 0) { - Key* lmb = KeyboardShortcuts::instance()->action(KeyAction::LeftMouseButton); - Key* rmb = KeyboardShortcuts::instance()->action(KeyAction::RightMouseButton); + KeyPtr lmb = KeyboardShortcuts::instance()->action(KeyAction::LeftMouseButton); + KeyPtr rmb = KeyboardShortcuts::instance()->action(KeyAction::RightMouseButton); // Convert action keys into mouse messages. if (lmb->isPressed(msg) || rmb->isPressed(msg)) { diff --git a/src/app/ui/key.h b/src/app/ui/key.h new file mode 100644 index 000000000..bf2db7a7c --- /dev/null +++ b/src/app/ui/key.h @@ -0,0 +1,136 @@ +// Aseprite +// Copyright (C) 2001-2018 David Capello +// +// This program is distributed under the terms of +// the End-User License Agreement for Aseprite. + +#ifndef APP_UI_KEY_H_INCLUDED +#define APP_UI_KEY_H_INCLUDED +#pragma once + +#include "app/commands/params.h" +#include "app/ui/key_context.h" +#include "base/convert_to.h" +#include "ui/accelerator.h" + +#include +#include + +namespace ui { + class Message; +} + +namespace app { + class Command; + + namespace tools { + class Tool; + } + + enum class KeySource { + Original, + UserDefined + }; + + enum class KeyType { + Command, + Tool, + Quicktool, + Action, + }; + + // TODO This should be called "KeyActionModifier" or something similar + enum class KeyAction { + None = 0x00000000, + CopySelection = 0x00000001, + SnapToGrid = 0x00000002, + AngleSnap = 0x00000004, + MaintainAspectRatio = 0x00000008, + LockAxis = 0x00000010, + AddSelection = 0x00000020, + SubtractSelection = 0x00000040, + AutoSelectLayer = 0x00000080, + LeftMouseButton = 0x00000100, + RightMouseButton = 0x00000200, + StraightLineFromLastPoint = 0x00000400, + MoveOrigin = 0x00000800, + SquareAspect = 0x00001000, + DrawFromCenter = 0x00002000, + ScaleFromCenter = 0x00004000, + AngleSnapFromLastPoint = 0x00008000, + RotateShape = 0x00010000, + }; + + inline KeyAction operator&(KeyAction a, KeyAction b) { + return KeyAction(int(a) & int(b)); + } + + class Key { + public: + Key(Command* command, const Params& params, KeyContext keyContext); + Key(KeyType type, tools::Tool* tool); + explicit Key(KeyAction action); + + KeyType type() const { return m_type; } + const ui::Accelerators& accels() const { + return (m_useUsers ? m_users: m_accels); + } + const ui::Accelerators& origAccels() const { return m_accels; } + const ui::Accelerators& userAccels() const { return m_users; } + const ui::Accelerators& userRemovedAccels() const { return m_userRemoved; } + + void add(const ui::Accelerator& accel, KeySource source); + bool isPressed(ui::Message* msg) const; + bool isPressed() const; + bool isLooselyPressed() const; + + bool hasAccel(const ui::Accelerator& accel) const; + void disableAccel(const ui::Accelerator& accel); + + // Resets user accelerators to the original ones. + void reset(); + + // for KeyType::Command + Command* command() const { return m_command; } + const Params& params() const { return m_params; } + KeyContext keycontext() const { return m_keycontext; } + // for KeyType::Tool or Quicktool + tools::Tool* tool() const { return m_tool; } + // for KeyType::Action + KeyAction action() const { return m_action; } + + std::string triggerString() const; + + private: + KeyType m_type; + ui::Accelerators m_accels; // Default accelerators (from gui.xml) + ui::Accelerators m_users; // User-defined accelerators + ui::Accelerators m_userRemoved; // Default accelerators removed by user + bool m_useUsers; + KeyContext m_keycontext; + + // for KeyType::Command + Command* m_command; + Params m_params; + // for KeyType::Tool or Quicktool + tools::Tool* m_tool; + // for KeyType::Action + KeyAction m_action; + }; + + typedef std::shared_ptr KeyPtr; + typedef std::vector Keys; + + std::string convertKeyContextToString(KeyContext keyContext); + std::string convertKeyContextToUserFriendlyString(KeyContext keyContext); + +} // namespace app + +namespace base { + + template<> app::KeyAction convert_to(const std::string& from); + template<> std::string convert_to(const app::KeyAction& from); + +} // namespace base + +#endif diff --git a/src/app/ui/keyboard_shortcuts.cpp b/src/app/ui/keyboard_shortcuts.cpp index 0b786b4e1..ae38892b7 100644 --- a/src/app/ui/keyboard_shortcuts.cpp +++ b/src/app/ui/keyboard_shortcuts.cpp @@ -301,9 +301,6 @@ KeyboardShortcuts::~KeyboardShortcuts() void KeyboardShortcuts::clear() { - for (Key* key : m_keys) { - delete key; - } m_keys.clear(); } @@ -347,7 +344,7 @@ void KeyboardShortcuts::importFile(TiXmlElement* rootElement, KeySource source) } // add the keyboard shortcut to the command - Key* key = this->command(command_name, params, keycontext); + KeyPtr key = this->command(command_name, params, keycontext); if (key && command_key) { Accelerator accel(command_key); @@ -385,7 +382,7 @@ void KeyboardShortcuts::importFile(TiXmlElement* rootElement, KeySource source) if (tool_id) { tools::Tool* tool = App::instance()->toolBox()->getToolById(tool_id); if (tool) { - Key* key = this->tool(tool); + KeyPtr key = this->tool(tool); if (key && tool_key) { LOG(VERBOSE) << "KEYS: Shortcut for tool " << tool_id << ": " << tool_key << "\n"; Accelerator accel(tool_key); @@ -413,7 +410,7 @@ void KeyboardShortcuts::importFile(TiXmlElement* rootElement, KeySource source) if (tool_id) { tools::Tool* tool = App::instance()->toolBox()->getToolById(tool_id); if (tool) { - Key* key = this->quicktool(tool); + KeyPtr key = this->quicktool(tool); if (key && tool_key) { LOG(VERBOSE) << "KEYS: Shortcut for quicktool " << tool_id << ": " << tool_key << "\n"; Accelerator accel(tool_key); @@ -441,7 +438,7 @@ void KeyboardShortcuts::importFile(TiXmlElement* rootElement, KeySource source) if (tool_action) { KeyAction action = base::convert_to(tool_action); if (action != KeyAction::None) { - Key* key = this->action(action); + KeyPtr key = this->action(action); if (key && tool_key) { LOG(VERBOSE) << "KEYS: Shortcut for action " << tool_action << ": " << tool_key << "\n"; Accelerator accel(tool_key); @@ -496,20 +493,20 @@ void KeyboardShortcuts::exportFile(const std::string& filename) void KeyboardShortcuts::exportKeys(TiXmlElement& parent, KeyType type) { - for (Key* key : m_keys) { + for (KeyPtr& key : m_keys) { // Save only user defined accelerators. if (key->type() != type) continue; for (const ui::Accelerator& accel : key->userRemovedAccels()) - exportAccel(parent, key, accel, true); + exportAccel(parent, key.get(), accel, true); for (const ui::Accelerator& accel : key->userAccels()) - exportAccel(parent, key, accel, false); + exportAccel(parent, key.get(), accel, false); } } -void KeyboardShortcuts::exportAccel(TiXmlElement& parent, Key* key, const ui::Accelerator& accel, bool removed) +void KeyboardShortcuts::exportAccel(TiXmlElement& parent, const Key* key, const ui::Accelerator& accel, bool removed) { TiXmlElement elem("key"); @@ -555,17 +552,17 @@ void KeyboardShortcuts::exportAccel(TiXmlElement& parent, Key* key, const ui::Ac void KeyboardShortcuts::reset() { - for (Key* key : m_keys) + for (KeyPtr& key : m_keys) key->reset(); } -Key* KeyboardShortcuts::command(const char* commandName, const Params& params, KeyContext keyContext) +KeyPtr KeyboardShortcuts::command(const char* commandName, const Params& params, KeyContext keyContext) { Command* command = Commands::instance()->byId(commandName); if (!command) - return NULL; + return nullptr; - for (Key* key : m_keys) { + for (KeyPtr& key : m_keys) { if (key->type() == KeyType::Command && key->keycontext() == keyContext && key->command() == command && @@ -574,49 +571,49 @@ Key* KeyboardShortcuts::command(const char* commandName, const Params& params, K } } - Key* key = new Key(command, params, keyContext); + KeyPtr key = std::make_shared(command, params, keyContext); m_keys.push_back(key); return key; } -Key* KeyboardShortcuts::tool(tools::Tool* tool) +KeyPtr KeyboardShortcuts::tool(tools::Tool* tool) { - for (Key* key : m_keys) { + for (KeyPtr& key : m_keys) { if (key->type() == KeyType::Tool && key->tool() == tool) { return key; } } - Key* key = new Key(KeyType::Tool, tool); + KeyPtr key = std::make_shared(KeyType::Tool, tool); m_keys.push_back(key); return key; } -Key* KeyboardShortcuts::quicktool(tools::Tool* tool) +KeyPtr KeyboardShortcuts::quicktool(tools::Tool* tool) { - for (Key* key : m_keys) { + for (KeyPtr& key : m_keys) { if (key->type() == KeyType::Quicktool && key->tool() == tool) { return key; } } - Key* key = new Key(KeyType::Quicktool, tool); + KeyPtr key = std::make_shared(KeyType::Quicktool, tool); m_keys.push_back(key); return key; } -Key* KeyboardShortcuts::action(KeyAction action) +KeyPtr KeyboardShortcuts::action(KeyAction action) { - for (Key* key : m_keys) { + for (KeyPtr& key : m_keys) { if (key->type() == KeyType::Action && key->action() == action) { return key; } } - Key* key = new Key(action); + KeyPtr key = std::make_shared(action); m_keys.push_back(key); return key; } @@ -625,7 +622,7 @@ void KeyboardShortcuts::disableAccel(const ui::Accelerator& accel, const KeyContext keyContext, const Key* newKey) { - for (Key* key : m_keys) { + for (KeyPtr& key : m_keys) { if (key->keycontext() == keyContext && key->hasAccel(accel) && // Tools can contain the same keyboard shortcut @@ -651,7 +648,7 @@ KeyContext KeyboardShortcuts::getCurrentKeyContext() bool KeyboardShortcuts::getCommandFromKeyMessage(Message* msg, Command** command, Params* params) { - for (Key* key : m_keys) { + for (KeyPtr& key : m_keys) { if (key->type() == KeyType::Command && key->isPressed(msg)) { if (command) *command = key->command(); if (params) *params = key->params(); @@ -664,7 +661,7 @@ bool KeyboardShortcuts::getCommandFromKeyMessage(Message* msg, Command** command tools::Tool* KeyboardShortcuts::getCurrentQuicktool(tools::Tool* currentTool) { if (currentTool && currentTool->getInk(0)->isSelection()) { - Key* key = action(KeyAction::CopySelection); + KeyPtr key = action(KeyAction::CopySelection); if (key && key->isPressed()) return NULL; } @@ -673,7 +670,7 @@ tools::Tool* KeyboardShortcuts::getCurrentQuicktool(tools::Tool* currentTool) // Iterate over all tools for (tools::Tool* tool : *toolbox) { - Key* key = quicktool(tool); + KeyPtr key = quicktool(tool); // Collect all tools with the pressed keyboard-shortcut if (key && key->isPressed()) { @@ -688,7 +685,7 @@ KeyAction KeyboardShortcuts::getCurrentActionModifiers(KeyContext context) { KeyAction flags = KeyAction::None; - for (Key* key : m_keys) { + for (KeyPtr& key : m_keys) { if (key->type() == KeyType::Action && key->keycontext() == context && key->isLooselyPressed()) { @@ -699,7 +696,7 @@ KeyAction KeyboardShortcuts::getCurrentActionModifiers(KeyContext context) return flags; } -std::string key_tooltip(const char* str, app::Key* key) +std::string key_tooltip(const char* str, const app::Key* key) { std::string res; if (str) diff --git a/src/app/ui/keyboard_shortcuts.h b/src/app/ui/keyboard_shortcuts.h index f550e160b..93d32d4c8 100644 --- a/src/app/ui/keyboard_shortcuts.h +++ b/src/app/ui/keyboard_shortcuts.h @@ -8,124 +8,16 @@ #define APP_UI_KEYBOARD_SHORTCUTS_H_INCLUDED #pragma once -#include "app/commands/params.h" -#include "app/ui/key_context.h" -#include "base/convert_to.h" +#include "app/ui/key.h" #include "base/disable_copying.h" #include "obs/signal.h" -#include "ui/accelerator.h" - -#include class TiXmlElement; -namespace ui { - class Message; -} - namespace app { - class Command; - class Params; - - namespace tools { - class Tool; - } - - enum class KeySource { - Original, - UserDefined - }; - - enum class KeyType { - Command, - Tool, - Quicktool, - Action, - }; - - // TODO This should be called "KeyActionModifier" or something similar - enum class KeyAction { - None = 0x00000000, - CopySelection = 0x00000001, - SnapToGrid = 0x00000002, - AngleSnap = 0x00000004, - MaintainAspectRatio = 0x00000008, - LockAxis = 0x00000010, - AddSelection = 0x00000020, - SubtractSelection = 0x00000040, - AutoSelectLayer = 0x00000080, - LeftMouseButton = 0x00000100, - RightMouseButton = 0x00000200, - StraightLineFromLastPoint = 0x00000400, - MoveOrigin = 0x00000800, - SquareAspect = 0x00001000, - DrawFromCenter = 0x00002000, - ScaleFromCenter = 0x00004000, - AngleSnapFromLastPoint = 0x00008000, - RotateShape = 0x00010000, - }; - - inline KeyAction operator&(KeyAction a, KeyAction b) { - return KeyAction(int(a) & int(b)); - } - - class Key { - public: - Key(Command* command, const Params& params, KeyContext keyContext); - Key(KeyType type, tools::Tool* tool); - explicit Key(KeyAction action); - - KeyType type() const { return m_type; } - const ui::Accelerators& accels() const { - return (m_useUsers ? m_users: m_accels); - } - const ui::Accelerators& origAccels() const { return m_accels; } - const ui::Accelerators& userAccels() const { return m_users; } - const ui::Accelerators& userRemovedAccels() const { return m_userRemoved; } - - void add(const ui::Accelerator& accel, KeySource source); - bool isPressed(ui::Message* msg) const; - bool isPressed() const; - bool isLooselyPressed() const; - - bool hasAccel(const ui::Accelerator& accel) const; - void disableAccel(const ui::Accelerator& accel); - - // Resets user accelerators to the original ones. - void reset(); - - // for KeyType::Command - Command* command() const { return m_command; } - const Params& params() const { return m_params; } - KeyContext keycontext() const { return m_keycontext; } - // for KeyType::Tool or Quicktool - tools::Tool* tool() const { return m_tool; } - // for KeyType::Action - KeyAction action() const { return m_action; } - - std::string triggerString() const; - - private: - KeyType m_type; - ui::Accelerators m_accels; // Default accelerators (from gui.xml) - ui::Accelerators m_users; // User-defined accelerators - ui::Accelerators m_userRemoved; // Default accelerators removed by user - bool m_useUsers; - KeyContext m_keycontext; - - // for KeyType::Command - Command* m_command; - Params m_params; - // for KeyType::Tool or Quicktool - tools::Tool* m_tool; - // for KeyType::Action - KeyAction m_action; - }; - class KeyboardShortcuts { public: - typedef std::vector Keys; typedef Keys::iterator iterator; typedef Keys::const_iterator const_iterator; @@ -143,11 +35,11 @@ namespace app { void exportFile(const std::string& filename); void reset(); - Key* command(const char* commandName, + KeyPtr command(const char* commandName, const Params& params = Params(), KeyContext keyContext = KeyContext::Any); - Key* tool(tools::Tool* tool); - Key* quicktool(tools::Tool* tool); - Key* action(KeyAction action); + KeyPtr tool(tools::Tool* tool); + KeyPtr quicktool(tools::Tool* tool); + KeyPtr action(KeyAction action); void disableAccel(const ui::Accelerator& accel, const KeyContext keyContext, @@ -166,14 +58,14 @@ namespace app { KeyboardShortcuts(); void exportKeys(TiXmlElement& parent, KeyType type); - void exportAccel(TiXmlElement& parent, Key* key, const ui::Accelerator& accel, bool removed); + void exportAccel(TiXmlElement& parent, const Key* key, const ui::Accelerator& accel, bool removed); Keys m_keys; DISABLE_COPYING(KeyboardShortcuts); }; - std::string key_tooltip(const char* str, Key* key); + std::string key_tooltip(const char* str, const Key* key); inline std::string key_tooltip(const char* str, const char* commandName, @@ -181,24 +73,14 @@ namespace app { KeyContext keyContext = KeyContext::Any) { return key_tooltip( str, KeyboardShortcuts::instance()->command( - commandName, params, keyContext)); + commandName, params, keyContext).get()); } inline std::string key_tooltip(const char* str, KeyAction keyAction) { return key_tooltip( - str, KeyboardShortcuts::instance()->action(keyAction)); + str, KeyboardShortcuts::instance()->action(keyAction).get()); } - std::string convertKeyContextToString(KeyContext keyContext); - std::string convertKeyContextToUserFriendlyString(KeyContext keyContext); - } // namespace app -namespace base { - - template<> app::KeyAction convert_to(const std::string& from); - template<> std::string convert_to(const app::KeyAction& from); - -} // namespace base - #endif diff --git a/src/app/ui/select_accelerator.cpp b/src/app/ui/select_accelerator.cpp index 513320736..7f58e37d7 100644 --- a/src/app/ui/select_accelerator.cpp +++ b/src/app/ui/select_accelerator.cpp @@ -181,7 +181,7 @@ void SelectAccelerator::updateAssignedTo() { std::string res = "None"; - for (Key* key : *KeyboardShortcuts::instance()) { + for (const KeyPtr& key : *KeyboardShortcuts::instance()) { if (key->keycontext() == m_keyContext && key->hasAccel(m_accel)) { res = key->triggerString(); diff --git a/src/app/ui/status_bar.cpp b/src/app/ui/status_bar.cpp index 0f3b1d6b6..77a24f8f9 100644 --- a/src/app/ui/status_bar.cpp +++ b/src/app/ui/status_bar.cpp @@ -409,7 +409,7 @@ public: m_indicators->addTextIndicator(tool->getText().c_str()); // Tool shortcut - Key* key = KeyboardShortcuts::instance()->tool(tool); + KeyPtr key = KeyboardShortcuts::instance()->tool(tool); if (key && !key->accels().empty()) { add(theme->parts.iconKey(), true); m_indicators->addTextIndicator(key->accels().front().toString().c_str()); diff --git a/src/app/ui/timeline/ani_controls.cpp b/src/app/ui/timeline/ani_controls.cpp index cfd4fb82f..35c7126e8 100644 --- a/src/app/ui/timeline/ani_controls.cpp +++ b/src/app/ui/timeline/ani_controls.cpp @@ -120,7 +120,7 @@ std::string AniControls::getTooltipFor(int index) const if (cmd) { tooltip = cmd->friendlyName(); - Key* key = KeyboardShortcuts::instance()->command(cmd->id().c_str()); + KeyPtr key = KeyboardShortcuts::instance()->command(cmd->id().c_str()); if (key && !key->accels().empty()) { tooltip += "\n\nShortcut: "; tooltip += key->accels().front().toString(); diff --git a/src/app/ui/toolbar.cpp b/src/app/ui/toolbar.cpp index 67a2e3690..a4bbce062 100644 --- a/src/app/ui/toolbar.cpp +++ b/src/app/ui/toolbar.cpp @@ -506,7 +506,7 @@ void ToolBar::openTipWindow(int group_index, Tool* tool) } // Tool shortcut - Key* key = KeyboardShortcuts::instance()->tool(tool); + KeyPtr key = KeyboardShortcuts::instance()->tool(tool); if (key && !key->accels().empty()) { tooltip += "\n\n"; tooltip += fmt::format(Strings::tools_shortcut(),