From a65f0a52381e647f77d4ae564a1cc22b30e90704 Mon Sep 17 00:00:00 2001 From: Kuruyia <8174691+Kuruyia@users.noreply.github.com> Date: Tue, 17 Jan 2023 08:16:02 +0100 Subject: [PATCH] feat: Support macOS keyboard shortcuts (#889) --- lib/libimhex/include/hex/api/keybinding.hpp | 18 +++++++ .../source/content/main_menu_items.cpp | 19 ++++--- plugins/builtin/source/content/shortcuts.cpp | 8 +-- .../source/content/views/view_hex_editor.cpp | 49 ++++++++++--------- 4 files changed, 59 insertions(+), 35 deletions(-) diff --git a/lib/libimhex/include/hex/api/keybinding.hpp b/lib/libimhex/include/hex/api/keybinding.hpp index 551e4206e..48f391aa0 100644 --- a/lib/libimhex/include/hex/api/keybinding.hpp +++ b/lib/libimhex/include/hex/api/keybinding.hpp @@ -184,6 +184,24 @@ namespace hex { constexpr static auto SHIFT = Key(static_cast(0x4000'0000)); constexpr static auto SUPER = Key(static_cast(0x8000'0000)); +#if defined(OS_MACOS) + constexpr static auto CTRLCMD = SUPER; + + constexpr static auto CTRL_NAME = "CTRL"; + constexpr static auto ALT_NAME = "OPT"; + constexpr static auto SHIFT_NAME = "SHIFT"; + constexpr static auto SUPER_NAME = "CMD"; + constexpr static auto CTRLCMD_NAME = SUPER_NAME; +#else + constexpr static auto CTRLCMD = CTRL; + + constexpr static auto CTRL_NAME = "CTRL"; + constexpr static auto ALT_NAME = "ALT"; + constexpr static auto SHIFT_NAME = "SHIFT"; + constexpr static auto SUPER_NAME = "SUPER"; + constexpr static auto CTRLCMD_NAME = CTRL_NAME; +#endif + class ShortcutManager { public: static void addGlobalShortcut(const Shortcut &shortcut, const std::function &callback); diff --git a/plugins/builtin/source/content/main_menu_items.cpp b/plugins/builtin/source/content/main_menu_items.cpp index 99d8c3533..49a5c2a18 100644 --- a/plugins/builtin/source/content/main_menu_items.cpp +++ b/plugins/builtin/source/content/main_menu_items.cpp @@ -4,12 +4,15 @@ #include #include +#include #include #include #include #include #include "content/global_actions.hpp" +using namespace std::literals::string_literals; + namespace hex::plugin::builtin { static bool g_demoWindowOpen = false; @@ -21,7 +24,7 @@ namespace hex::plugin::builtin { ContentRegistry::Interface::addMenuItem("hex.builtin.menu.file", 1050, [&] { bool taskRunning = TaskManager::getRunningTaskCount() > 0; - if (ImGui::MenuItem("hex.builtin.menu.file.create_file"_lang, "CTRL + N", false, !taskRunning)) { + if (ImGui::MenuItem("hex.builtin.menu.file.create_file"_lang, (CTRLCMD_NAME + " + N"s).c_str(), false, !taskRunning)) { auto newProvider = hex::ImHexApi::Provider::createProvider("hex.builtin.provider.mem_file", true); if (newProvider != nullptr && !newProvider->open()) hex::ImHexApi::Provider::remove(newProvider); @@ -29,7 +32,7 @@ namespace hex::plugin::builtin { EventManager::post(newProvider); } - if (ImGui::MenuItem("hex.builtin.menu.file.open_file"_lang, "CTRL + O", false, !taskRunning)) { + if (ImGui::MenuItem("hex.builtin.menu.file.open_file"_lang, (CTRLCMD_NAME + " + O"s).c_str(), false, !taskRunning)) { EventManager::post("Open File"); } @@ -44,7 +47,7 @@ namespace hex::plugin::builtin { ImGui::EndMenu(); } - if (ImGui::MenuItem("hex.builtin.menu.file.reload_file"_lang, "CTRL + R", false, !taskRunning && ImHexApi::Provider::isValid())) { + if (ImGui::MenuItem("hex.builtin.menu.file.reload_file"_lang, (CTRLCMD_NAME + " + R"s).c_str(), false, !taskRunning && ImHexApi::Provider::isValid())) { auto provider = ImHexApi::Provider::get(); provider->close(); @@ -58,7 +61,7 @@ namespace hex::plugin::builtin { bool providerValid = ImHexApi::Provider::isValid(); bool taskRunning = TaskManager::getRunningTaskCount() > 0; - if (ImGui::MenuItem("hex.builtin.menu.file.close"_lang, "CTRL + W", false, providerValid && !taskRunning)) { + if (ImGui::MenuItem("hex.builtin.menu.file.close"_lang, (CTRLCMD_NAME + " + W"s).c_str(), false, providerValid && !taskRunning)) { ImHexApi::Provider::remove(ImHexApi::Provider::get()); } @@ -77,11 +80,11 @@ namespace hex::plugin::builtin { openProject(); } - if (ImGui::MenuItem("hex.builtin.menu.file.save_project"_lang, "ALT + S", false, providerValid && ProjectFile::hasPath())) { + if (ImGui::MenuItem("hex.builtin.menu.file.save_project"_lang, (ALT_NAME + " + S"s).c_str(), false, providerValid && ProjectFile::hasPath())) { saveProject(); } - if (ImGui::MenuItem("hex.builtin.menu.file.save_project_as"_lang, "ALT + SHIFT + S", false, providerValid && provider->isWritable())) { + if (ImGui::MenuItem("hex.builtin.menu.file.save_project_as"_lang, (ALT_NAME + " + "s + SHIFT_NAME + " + S"s).c_str(), false, providerValid && provider->isWritable())) { saveProjectAs(); } }); @@ -242,9 +245,9 @@ namespace hex::plugin::builtin { auto provider = ImHexApi::Provider::get(); bool providerValid = ImHexApi::Provider::isValid(); - if (ImGui::MenuItem("hex.builtin.menu.edit.undo"_lang, "CTRL + Z", false, providerValid && provider->canUndo())) + if (ImGui::MenuItem("hex.builtin.menu.edit.undo"_lang, (CTRLCMD_NAME + " + Z"s).c_str(), false, providerValid && provider->canUndo())) provider->undo(); - if (ImGui::MenuItem("hex.builtin.menu.edit.redo"_lang, "CTRL + Y", false, providerValid && provider->canRedo())) + if (ImGui::MenuItem("hex.builtin.menu.edit.redo"_lang, (CTRLCMD_NAME + " + Y"s).c_str(), false, providerValid && provider->canRedo())) provider->redo(); }); diff --git a/plugins/builtin/source/content/shortcuts.cpp b/plugins/builtin/source/content/shortcuts.cpp index 61b718eff..94d1d27a6 100644 --- a/plugins/builtin/source/content/shortcuts.cpp +++ b/plugins/builtin/source/content/shortcuts.cpp @@ -8,23 +8,23 @@ namespace hex::plugin::builtin { void registerShortcuts() { // New file - ShortcutManager::addGlobalShortcut(CTRL + Keys::N, [] { + ShortcutManager::addGlobalShortcut(CTRLCMD + Keys::N, [] { EventManager::post("Create File"); }); // Open file - ShortcutManager::addGlobalShortcut(CTRL + Keys::O, [] { + ShortcutManager::addGlobalShortcut(CTRLCMD + Keys::O, [] { EventManager::post("Open File"); }); // Close file - ShortcutManager::addGlobalShortcut(CTRL + Keys::W, [] { + ShortcutManager::addGlobalShortcut(CTRLCMD + Keys::W, [] { if (ImHexApi::Provider::isValid()) ImHexApi::Provider::remove(ImHexApi::Provider::get()); }); // Reload file - ShortcutManager::addGlobalShortcut(CTRL + Keys::R, [] { + ShortcutManager::addGlobalShortcut(CTRLCMD + Keys::R, [] { if (ImHexApi::Provider::isValid()) { auto provider = ImHexApi::Provider::get(); diff --git a/plugins/builtin/source/content/views/view_hex_editor.cpp b/plugins/builtin/source/content/views/view_hex_editor.cpp index 5fca798c3..6349f2ca5 100644 --- a/plugins/builtin/source/content/views/view_hex_editor.cpp +++ b/plugins/builtin/source/content/views/view_hex_editor.cpp @@ -1,6 +1,7 @@ #include "content/views/view_hex_editor.hpp" #include +#include #include #include #include @@ -13,6 +14,8 @@ #include +using namespace std::literals::string_literals; + namespace hex::plugin::builtin { /* Popups */ @@ -674,21 +677,21 @@ namespace hex::plugin::builtin { void ViewHexEditor::registerShortcuts() { // Save operations - ShortcutManager::addShortcut(this, CTRL + Keys::S, [] { + ShortcutManager::addShortcut(this, CTRLCMD + Keys::S, [] { save(); }); - ShortcutManager::addShortcut(this, CTRL + SHIFT + Keys::S, [] { + ShortcutManager::addShortcut(this, CTRLCMD + SHIFT + Keys::S, [] { saveAs(); }); // Select All - ShortcutManager::addShortcut(this, CTRL + Keys::A, [this] { + ShortcutManager::addShortcut(this, CTRLCMD + Keys::A, [this] { if (ImHexApi::Provider::isValid()) this->setSelection(size_t(0), ImHexApi::Provider::get()->getActualSize()); }); // Select range - ShortcutManager::addShortcut(this, CTRL + SHIFT + Keys::A, [this] { + ShortcutManager::addShortcut(this, CTRLCMD + SHIFT + Keys::A, [this] { if (ImHexApi::Provider::isValid()) this->openPopup(); }); @@ -812,49 +815,49 @@ namespace hex::plugin::builtin { this->m_hexEditor.jumpIfOffScreen(); }); - ShortcutManager::addShortcut(this, CTRL + Keys::G, [this] { + ShortcutManager::addShortcut(this, CTRLCMD + Keys::G, [this] { if (!ImHexApi::Provider::isValid()) return; this->openPopup(); }); - ShortcutManager::addShortcut(this, CTRL + Keys::F, [this] { + ShortcutManager::addShortcut(this, CTRLCMD + Keys::F, [this] { if (!ImHexApi::Provider::isValid()) return; this->openPopup(); }); // Copy - ShortcutManager::addShortcut(this, CTRL + Keys::C, [this] { + ShortcutManager::addShortcut(this, CTRLCMD + Keys::C, [this] { const auto selection = getSelection(); copyBytes(selection); }); - ShortcutManager::addShortcut(this, CTRL + SHIFT + Keys::C, [this] { + ShortcutManager::addShortcut(this, CTRLCMD + SHIFT + Keys::C, [this] { const auto selection = getSelection(); copyString(selection); }); // Paste - ShortcutManager::addShortcut(this, CTRL + Keys::V, [this] { + ShortcutManager::addShortcut(this, CTRLCMD + Keys::V, [this] { const auto selection = getSelection(); pasteBytes(selection, true); }); // Paste and resize - ShortcutManager::addShortcut(this, CTRL + SHIFT + Keys::V, [this] { + ShortcutManager::addShortcut(this, CTRLCMD + SHIFT + Keys::V, [this] { const auto selection = getSelection(); pasteBytes(selection, false); }); // Undo / Redo - ShortcutManager::addShortcut(this, CTRL + Keys::Z, [] { + ShortcutManager::addShortcut(this, CTRLCMD + Keys::Z, [] { if (ImHexApi::Provider::isValid()) ImHexApi::Provider::get()->undo(); }); - ShortcutManager::addShortcut(this, CTRL + Keys::Y, [] { + ShortcutManager::addShortcut(this, CTRLCMD + Keys::Y, [] { if (ImHexApi::Provider::isValid()) ImHexApi::Provider::get()->redo(); }); - ShortcutManager::addShortcut(this, CTRL + SHIFT + Keys::Z, [] { + ShortcutManager::addShortcut(this, CTRLCMD + SHIFT + Keys::Z, [] { if (ImHexApi::Provider::isValid()) ImHexApi::Provider::get()->redo(); }); @@ -916,11 +919,11 @@ namespace hex::plugin::builtin { auto provider = ImHexApi::Provider::get(); bool providerValid = ImHexApi::Provider::isValid(); - if (ImGui::MenuItem("hex.builtin.view.hex_editor.menu.file.save"_lang, "CTRL + S", false, providerValid && provider->isWritable())) { + if (ImGui::MenuItem("hex.builtin.view.hex_editor.menu.file.save"_lang, (CTRLCMD_NAME + " + S"s).c_str(), false, providerValid && provider->isWritable())) { save(); } - if (ImGui::MenuItem("hex.builtin.view.hex_editor.menu.file.save_as"_lang, "CTRL + SHIFT + S", false, providerValid && provider->isWritable())) { + if (ImGui::MenuItem("hex.builtin.view.hex_editor.menu.file.save_as"_lang, (CTRLCMD_NAME + " + "s + SHIFT_NAME + " + S"s).c_str(), false, providerValid && provider->isWritable())) { saveAs(); } }); @@ -953,15 +956,15 @@ namespace hex::plugin::builtin { ContentRegistry::Interface::addMenuItem("hex.builtin.menu.file", 1400, [&, this] { bool providerValid = ImHexApi::Provider::isValid(); - if (ImGui::MenuItem("hex.builtin.view.hex_editor.menu.file.search"_lang, "CTRL + F", false, providerValid)) { + if (ImGui::MenuItem("hex.builtin.view.hex_editor.menu.file.search"_lang, (CTRLCMD_NAME + " + F"s).c_str(), false, providerValid)) { this->openPopup(); } - if (ImGui::MenuItem("hex.builtin.view.hex_editor.menu.file.goto"_lang, "CTRL + G", false, providerValid)) { + if (ImGui::MenuItem("hex.builtin.view.hex_editor.menu.file.goto"_lang, (CTRLCMD_NAME + " + G"s).c_str(), false, providerValid)) { this->openPopup(); } - if (ImGui::MenuItem("hex.builtin.view.hex_editor.menu.file.select"_lang, "CTRL + SHIFT + A", false, providerValid)) { + if (ImGui::MenuItem("hex.builtin.view.hex_editor.menu.file.select"_lang, (CTRLCMD_NAME + " + "s + SHIFT_NAME + " + A"s).c_str(), false, providerValid)) { this->openPopup(); } }); @@ -973,11 +976,11 @@ namespace hex::plugin::builtin { bool providerValid = ImHexApi::Provider::isValid(); auto selection = ImHexApi::HexEditor::getSelection(); - if (ImGui::MenuItem("hex.builtin.view.hex_editor.menu.edit.copy"_lang, "CTRL + C", false, selection.has_value())) + if (ImGui::MenuItem("hex.builtin.view.hex_editor.menu.edit.copy"_lang, (CTRLCMD_NAME + " + C"s).c_str(), false, selection.has_value())) copyBytes(*selection); if (ImGui::BeginMenu("hex.builtin.view.hex_editor.menu.edit.copy_as"_lang, selection.has_value() && providerValid)) { - if (ImGui::MenuItem("hex.builtin.view.hex_editor.copy.hex"_lang, "CTRL + SHIFT + C")) + if (ImGui::MenuItem("hex.builtin.view.hex_editor.copy.hex"_lang, (CTRLCMD_NAME + " + "s + SHIFT_NAME + " + C"s).c_str())) copyString(*selection); if (ImGui::MenuItem("hex.builtin.view.hex_editor.copy.address"_lang)) ImGui::SetClipboardText(hex::format("0x{:08X}", selection->getStartAddress()).c_str()); @@ -999,12 +1002,12 @@ namespace hex::plugin::builtin { ImGui::EndMenu(); } - if (ImGui::MenuItem("hex.builtin.view.hex_editor.menu.edit.paste"_lang, "CTRL + V", false, selection.has_value())) + if (ImGui::MenuItem("hex.builtin.view.hex_editor.menu.edit.paste"_lang, (CTRLCMD_NAME + " + V"s).c_str(), false, selection.has_value())) pasteBytes(*selection, true); - if (ImGui::MenuItem("hex.builtin.view.hex_editor.menu.edit.paste_all"_lang, "CTRL + SHIFT + V", false, selection.has_value())) + if (ImGui::MenuItem("hex.builtin.view.hex_editor.menu.edit.paste_all"_lang, (CTRLCMD_NAME + " + "s + SHIFT_NAME + " + V"s).c_str(), false, selection.has_value())) pasteBytes(*selection, false); - if (ImGui::MenuItem("hex.builtin.view.hex_editor.menu.edit.select_all"_lang, "CTRL + A", false, selection.has_value() && providerValid)) + if (ImGui::MenuItem("hex.builtin.view.hex_editor.menu.edit.select_all"_lang, (CTRLCMD_NAME + " + A"s).c_str(), false, selection.has_value() && providerValid)) ImHexApi::HexEditor::setSelection(provider->getBaseAddress(), provider->getActualSize()); });