From 8b39c8f2195ac5927b11261d1681043b4e5306c9 Mon Sep 17 00:00:00 2001 From: WerWolv Date: Thu, 13 Oct 2022 10:47:35 +0200 Subject: [PATCH] feat: Make all tool windows be detachable --- .../include/hex/api/content_registry.hpp | 1 + lib/libimhex/source/api/content_registry.cpp | 2 +- main/source/window/window.cpp | 11 +++-- .../include/content/views/view_tools.hpp | 5 ++- .../source/content/views/view_tools.cpp | 40 ++++++++++++++++++- 5 files changed, 53 insertions(+), 6 deletions(-) diff --git a/lib/libimhex/include/hex/api/content_registry.hpp b/lib/libimhex/include/hex/api/content_registry.hpp index 3f527b93d..a718ee367 100644 --- a/lib/libimhex/include/hex/api/content_registry.hpp +++ b/lib/libimhex/include/hex/api/content_registry.hpp @@ -174,6 +174,7 @@ namespace hex { struct Entry { std::string name; Callback function; + bool detached; }; } diff --git a/lib/libimhex/source/api/content_registry.cpp b/lib/libimhex/source/api/content_registry.cpp index 59174fbe5..e0757bab0 100644 --- a/lib/libimhex/source/api/content_registry.cpp +++ b/lib/libimhex/source/api/content_registry.cpp @@ -338,7 +338,7 @@ namespace hex { void add(const std::string &unlocalizedName, const impl::Callback &function) { log::debug("Registered new tool: {}", unlocalizedName); - getEntries().emplace_back(impl::Entry { unlocalizedName, function }); + getEntries().emplace_back(impl::Entry { unlocalizedName, function, false }); } std::vector &getEntries() { diff --git a/main/source/window/window.cpp b/main/source/window/window.cpp index d12c524c6..60e046319 100644 --- a/main/source/window/window.cpp +++ b/main/source/window/window.cpp @@ -47,19 +47,24 @@ namespace hex { void ImHexSettingsHandler_ReadLine(ImGuiContext *, ImGuiSettingsHandler *, void *, const char *line) { for (auto &[name, view] : ContentRegistry::Views::getEntries()) { - std::string format = std::string(view->getUnlocalizedName()) + "=%d"; + std::string format = view->getUnlocalizedName() + "=%d"; sscanf(line, format.c_str(), &view->getWindowOpenState()); } + for (auto &[name, function, detached] : ContentRegistry::Tools::getEntries()) { + std::string format = name + "=%d"; + sscanf(line, format.c_str(), &detached); + } } void ImHexSettingsHandler_WriteAll(ImGuiContext *, ImGuiSettingsHandler *handler, ImGuiTextBuffer *buf) { - buf->reserve(buf->size() + 0x20); // Ballpark reserve - buf->appendf("[%s][General]\n", handler->TypeName); for (auto &[name, view] : ContentRegistry::Views::getEntries()) { buf->appendf("%s=%d\n", name.c_str(), view->getWindowOpenState()); } + for (auto &[name, function, detached] : ContentRegistry::Tools::getEntries()) { + buf->appendf("%s=%d\n", name.c_str(), detached); + } buf->append("\n"); } diff --git a/plugins/builtin/include/content/views/view_tools.hpp b/plugins/builtin/include/content/views/view_tools.hpp index cb3dea9b4..96e80569c 100644 --- a/plugins/builtin/include/content/views/view_tools.hpp +++ b/plugins/builtin/include/content/views/view_tools.hpp @@ -2,7 +2,7 @@ #include -#include +#include #include #include @@ -16,6 +16,9 @@ namespace hex::plugin::builtin { ~ViewTools() override = default; void drawContent() override; + + private: + std::vector::iterator m_dragStartIterator; }; } \ No newline at end of file diff --git a/plugins/builtin/source/content/views/view_tools.cpp b/plugins/builtin/source/content/views/view_tools.cpp index a78006db4..ca2be96af 100644 --- a/plugins/builtin/source/content/views/view_tools.cpp +++ b/plugins/builtin/source/content/views/view_tools.cpp @@ -1,4 +1,5 @@ #include "content/views/view_tools.hpp" +#include #include @@ -7,14 +8,51 @@ namespace hex::plugin::builtin { ViewTools::ViewTools() : View("hex.builtin.view.tools.name") { } void ViewTools::drawContent() { + auto &tools = ContentRegistry::Tools::getEntries(); + if (ImGui::Begin(View::toWindowName("hex.builtin.view.tools.name").c_str(), &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse)) { - for (const auto &[name, function] : ContentRegistry::Tools::getEntries()) { + for (auto iter = tools.begin(); iter != tools.end(); iter++) { + auto &[name, function, detached] = *iter; + + if (detached) continue; + if (ImGui::CollapsingHeader(LangEntry(name))) { function(); + } else { + if (ImGui::IsMouseClicked(0) && ImGui::IsItemActivated() && this->m_dragStartIterator == tools.end()) + this->m_dragStartIterator = iter; + + if (!ImGui::IsItemHovered() && this->m_dragStartIterator == iter) { + detached = true; + } + + if (!ImGui::IsMouseDown(0)) + this->m_dragStartIterator = tools.end(); } } } ImGui::End(); + + for (auto iter = tools.begin(); iter != tools.end(); iter++) { + auto &[name, function, detached] = *iter; + + if (!detached) continue; + + ImGui::SetNextWindowSize(scaled(ImVec2(600, 0)), ImGuiCond_Appearing); + if (ImGui::Begin(View::toWindowName(name).c_str(), &detached, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize)) { + function(); + + if (ImGui::IsWindowAppearing() && this->m_dragStartIterator == iter) { + this->m_dragStartIterator = tools.end(); + + // Attach the newly created window to the cursor, so it gets dragged around + GImGui->MovingWindow = ImGui::GetCurrentWindow(); + GImGui->ActiveId = GImGui->MovingWindow->MoveId; + ImGui::DockContextQueueUndockWindow(GImGui, GImGui->MovingWindow); + } + } + ImGui::End(); + } } } \ No newline at end of file