diff --git a/include/views/view_command_palette.hpp b/include/views/view_command_palette.hpp index e6f86cb39..49fed0411 100644 --- a/include/views/view_command_palette.hpp +++ b/include/views/view_command_palette.hpp @@ -24,7 +24,7 @@ namespace hex { bool isAvailable() override { return true; } bool shouldProcess() override { return true; } - bool handleShortcut(int key, int mods) override; + bool handleShortcut(bool keys[512], bool ctrl, bool shift, bool alt) override; bool hasViewMenuItemEntry() override { return false; } ImVec2 getMinSize() override { return ImVec2(400, 100); } diff --git a/include/views/view_hexeditor.hpp b/include/views/view_hexeditor.hpp index dcf2c14af..8067bf6d2 100644 --- a/include/views/view_hexeditor.hpp +++ b/include/views/view_hexeditor.hpp @@ -27,7 +27,7 @@ namespace hex { void drawContent() override; void drawAlwaysVisible() override; void drawMenu() override; - bool handleShortcut(int key, int mods) override; + bool handleShortcut(bool keys[512], bool ctrl, bool shift, bool alt) override; private: MemoryEditor m_memoryEditor; diff --git a/include/window.hpp b/include/window.hpp index 441408eb0..d47d9f62d 100644 --- a/include/window.hpp +++ b/include/window.hpp @@ -52,6 +52,8 @@ namespace hex { double m_lastFrameTime; + bool m_prevKeysDown[512]; + static inline std::tuple s_currShortcut = { -1, -1 }; }; diff --git a/plugins/libimhex/include/hex/views/view.hpp b/plugins/libimhex/include/hex/views/view.hpp index 93e96fb9e..5f268c634 100644 --- a/plugins/libimhex/include/hex/views/view.hpp +++ b/plugins/libimhex/include/hex/views/view.hpp @@ -26,7 +26,7 @@ namespace hex { virtual void drawContent() = 0; virtual void drawAlwaysVisible() { } virtual void drawMenu(); - virtual bool handleShortcut(int key, int mods); + virtual bool handleShortcut(bool keys[512], bool ctrl, bool shift, bool alt); virtual bool isAvailable(); virtual bool shouldProcess() { return this->isAvailable() && this->getWindowOpenState(); } diff --git a/plugins/libimhex/source/views/view.cpp b/plugins/libimhex/source/views/view.cpp index 7a961fa7d..4d9128191 100644 --- a/plugins/libimhex/source/views/view.cpp +++ b/plugins/libimhex/source/views/view.cpp @@ -14,7 +14,7 @@ namespace hex { View::View(std::string unlocalizedName) : m_unlocalizedViewName(unlocalizedName) { } void View::drawMenu() { } - bool View::handleShortcut(int key, int mods) { return false; } + bool View::handleShortcut(bool keys[512], bool ctrl, bool shift, bool alt) { return false; } bool View::isAvailable() { return SharedData::currentProvider != nullptr && SharedData::currentProvider->isAvailable(); diff --git a/source/views/view_command_palette.cpp b/source/views/view_command_palette.cpp index 3651110ad..da592f825 100644 --- a/source/views/view_command_palette.cpp +++ b/source/views/view_command_palette.cpp @@ -67,8 +67,8 @@ namespace hex { } - bool ViewCommandPalette::handleShortcut(int key, int mods) { - if (key == 'P' && mods == (GLFW_MOD_SHIFT | GLFW_MOD_CONTROL)) { + bool ViewCommandPalette::handleShortcut(bool keys[512], bool ctrl, bool shift, bool alt) { + if (ctrl && shift && keys['P']) { View::doLater([this] { ImGui::OpenPopup("hex.view.command_palette.name"_lang); this->m_commandPaletteOpen = true; diff --git a/source/views/view_hexeditor.cpp b/source/views/view_hexeditor.cpp index fcb489f8e..f42f60494 100644 --- a/source/views/view_hexeditor.cpp +++ b/source/views/view_hexeditor.cpp @@ -533,39 +533,50 @@ namespace hex { } } - bool ViewHexEditor::handleShortcut(int key, int mods) { - if (mods == GLFW_MOD_CONTROL && key == 'S') { + bool ViewHexEditor::handleShortcut(bool keys[512], bool ctrl, bool shift, bool alt) { + if (ctrl && keys['S']) { save(); return true; - } else if (mods == (GLFW_MOD_CONTROL | GLFW_MOD_SHIFT) && key == 'S') { + } else if (ctrl && shift && keys['S']) { saveAs(); return true; - } else if (mods == GLFW_MOD_CONTROL && key == 'Z') { - if (SharedData::currentProvider != nullptr) - SharedData::currentProvider->undo(); - } else if (mods == GLFW_MOD_CONTROL && key == 'Y') { - if (SharedData::currentProvider != nullptr) - SharedData::currentProvider->redo(); - } else if (mods == GLFW_MOD_CONTROL && key == 'F') { - View::doLater([]{ ImGui::OpenPopup("hex.view.hexeditor.menu.file.search"_lang); }); - return true; - } else if (mods == GLFW_MOD_CONTROL && key == 'G') { - View::doLater([]{ ImGui::OpenPopup("hex.view.hexeditor.menu.file.goto"_lang); }); - return true; - } else if (mods == GLFW_MOD_CONTROL && key == 'O') { - View::doLater([]{ ImGui::OpenPopup("hex.view.hexeditor.open_file"_lang); }); - return true; - } else if (mods == GLFW_MOD_CONTROL && key == 'C') { - this->copyBytes(); - return true; - } else if (mods == (GLFW_MOD_CONTROL | GLFW_MOD_SHIFT) && key == 'C') { - this->copyString(); - return true; - } else if (mods == GLFW_MOD_CONTROL && key == 'V') { - this->pasteBytes(); - return true; } + if (ImGui::Begin(View::toWindowName("hex.view.hexeditor.name").c_str())) { + ON_SCOPE_EXIT { ImGui::End(); }; + + if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows)) { + if (ctrl && keys['Z']) { + if (SharedData::currentProvider != nullptr) + SharedData::currentProvider->undo(); + return true; + } else if (ctrl && keys['Y']) { + if (SharedData::currentProvider != nullptr) + SharedData::currentProvider->redo(); + } else if (ctrl && keys['F']) { + View::doLater([]{ ImGui::OpenPopup("hex.view.hexeditor.menu.file.search"_lang); }); + return true; + } else if (ctrl && keys['G']) { + View::doLater([]{ ImGui::OpenPopup("hex.view.hexeditor.menu.file.goto"_lang); }); + return true; + } else if (ctrl && keys['O']) { + View::doLater([]{ ImGui::OpenPopup("hex.view.hexeditor.open_file"_lang); }); + return true; + } else if (ctrl && keys['C']) { + this->copyBytes(); + return true; + } else if (ctrl && shift && keys['C']) { + this->copyString(); + return true; + } else if (ctrl && keys['V']) { + this->pasteBytes(); + return true; + } + } + } + + + return false; } diff --git a/source/window.cpp b/source/window.cpp index ac4ab56ac..03e16a1d3 100644 --- a/source/window.cpp +++ b/source/window.cpp @@ -181,10 +181,17 @@ namespace hex { } void Window::loop() { + bool pressedKeys[512] = { 0 }; + this->m_lastFrameTime = glfwGetTime(); while (!glfwWindowShouldClose(this->m_window)) { + std::copy_n(ImGui::GetIO().KeysDown, 512, this->m_prevKeysDown); + this->frameBegin(); + for (u16 i = 0; i < 512; i++) + pressedKeys[i] = ImGui::GetIO().KeysDown[i] && !this->m_prevKeysDown[i]; + for (const auto &call : View::getDeferedCalls()) call(); View::getDeferedCalls().clear(); @@ -201,6 +208,7 @@ namespace hex { ImGui::SetNextWindowSizeConstraints(minSize, view->getMaxSize()); view->drawContent(); + view->handleShortcut(pressedKeys, ImGui::GetIO().KeyCtrl, ImGui::GetIO().KeyShift, ImGui::GetIO().KeyAlt); } View::drawCommonInterfaces(); @@ -352,17 +360,6 @@ namespace hex { ImGui::EndMenuBar(); } - if (auto &[key, mods] = Window::s_currShortcut; key != -1) { - for (auto &view : ContentRegistry::Views::getEntries()) { - if (view->shouldProcess()) { - if (view->handleShortcut(key, mods)) - break; - } - } - - Window::s_currShortcut = { -1, -1 }; - } - if (SharedData::currentProvider == nullptr) { char title[256]; ImFormatString(title, IM_ARRAYSIZE(title), "%s/DockSpace_%08X", ImGui::GetCurrentWindow()->Name, ImGui::GetID("MainDock"));