diff --git a/external/ImGui/source/imgui_imhex_extensions.cpp b/external/ImGui/source/imgui_imhex_extensions.cpp index 0cbf15715..968889ff9 100644 --- a/external/ImGui/source/imgui_imhex_extensions.cpp +++ b/external/ImGui/source/imgui_imhex_extensions.cpp @@ -36,7 +36,7 @@ namespace ImGui { const ImU32 col = hovered ? GetColorU32(ImGuiCol_ButtonHovered) : GetColorU32(ImGuiCol_ButtonActive); PushStyleColor(ImGuiCol_Text, ImU32(col)); TextEx(label, NULL, ImGuiTextFlags_NoWidthForLargeClippedText); // Skip formatting - GetOverlayDrawList()->AddLine(ImVec2(pos.x, pos.y + size.y), pos + size, ImU32(col)); + GetWindowDrawList()->AddLine(ImVec2(pos.x, pos.y + size.y), pos + size, ImU32(col)); PopStyleColor(); IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.LastItemStatusFlags); @@ -70,7 +70,7 @@ namespace ImGui { PushStyleColor(ImGuiCol_Text, ImU32(col)); RenderBullet(window->DrawList, bb.Min + ImVec2(style.FramePadding.x + g.FontSize * 0.5f, g.FontSize * 0.5f), col); RenderText(bb.Min + ImVec2(g.FontSize + style.FramePadding.x * 2, 0.0f), label, nullptr, false); - GetOverlayDrawList()->AddLine(bb.Min + ImVec2(style.FramePadding.x, size.y), pos + size + ImVec2(g.FontSize * 2, 0), ImU32(col)); + GetWindowDrawList()->AddLine(bb.Min + ImVec2(style.FramePadding.x, size.y), pos + size + ImVec2(g.FontSize * 2, 0), ImU32(col)); ImGui::NewLine(); PopStyleColor(); @@ -137,7 +137,7 @@ namespace ImGui { PushStyleColor(ImGuiCol_Text, ImU32(color)); TextEx(label, NULL, ImGuiTextFlags_NoWidthForLargeClippedText); // Skip formatting - GetOverlayDrawList()->AddLine(ImVec2(pos.x, pos.y + size.y), pos + size, ImU32(color)); + GetWindowDrawList()->AddLine(ImVec2(pos.x, pos.y + size.y), pos + size, ImU32(color)); PopStyleColor(); } diff --git a/include/views/view_command_palette.hpp b/include/views/view_command_palette.hpp index 2f568eacc..71fab0e79 100644 --- a/include/views/view_command_palette.hpp +++ b/include/views/view_command_palette.hpp @@ -21,6 +21,7 @@ namespace hex { void drawContent() override; void drawMenu() override; + bool isAvailable() override { return true; } bool handleShortcut(int key, int mods) override; diff --git a/include/views/view_help.hpp b/include/views/view_help.hpp index 85a2db4a2..37f76c695 100644 --- a/include/views/view_help.hpp +++ b/include/views/view_help.hpp @@ -21,6 +21,7 @@ namespace hex { void drawContent() override; void drawMenu() override; + bool isAvailable() override { return true; } bool hasViewMenuItemEntry() override { return false; } diff --git a/include/views/view_settings.hpp b/include/views/view_settings.hpp index ca5ae3634..00f2fc9e1 100644 --- a/include/views/view_settings.hpp +++ b/include/views/view_settings.hpp @@ -14,10 +14,9 @@ namespace hex { void drawContent() override; void drawMenu() override; + bool isAvailable() override { return true; } bool hasViewMenuItemEntry() override { return false; } - private: - bool m_settingsWindowOpen = false; }; } \ No newline at end of file diff --git a/include/window.hpp b/include/window.hpp index 6d80f90e7..c8a3bfed7 100644 --- a/include/window.hpp +++ b/include/window.hpp @@ -39,7 +39,7 @@ namespace hex { void deinitGLFW(); void deinitImGui(); - GLFWwindow* m_window; + GLFWwindow* m_window = nullptr; float m_globalScale = 1.0f, m_fontScale = 1.0f; bool m_fpsVisible = false; diff --git a/plugins/libimhex/include/hex/api/event.hpp b/plugins/libimhex/include/hex/api/event.hpp index 37991af00..98853b9be 100644 --- a/plugins/libimhex/include/hex/api/event.hpp +++ b/plugins/libimhex/include/hex/api/event.hpp @@ -26,6 +26,7 @@ namespace hex { SettingsChanged, + OpenWindow, /* This is not a real event but a flag to show all events after this one are plugin ones */ Events_BuiltinEnd diff --git a/plugins/libimhex/include/hex/helpers/shared_data.hpp b/plugins/libimhex/include/hex/helpers/shared_data.hpp index 737477af1..3b4bd1e79 100644 --- a/plugins/libimhex/include/hex/helpers/shared_data.hpp +++ b/plugins/libimhex/include/hex/helpers/shared_data.hpp @@ -9,7 +9,6 @@ #include #include #include -#include #include #include @@ -25,6 +24,7 @@ namespace hex::plugin::internal { namespace hex { namespace prv { class Provider; } + class View; class SharedData { SharedData() = default; diff --git a/plugins/libimhex/include/hex/views/view.hpp b/plugins/libimhex/include/hex/views/view.hpp index 619c3af74..a531c8cd8 100644 --- a/plugins/libimhex/include/hex/views/view.hpp +++ b/plugins/libimhex/include/hex/views/view.hpp @@ -6,6 +6,8 @@ #include #include +#include +#include #include #include @@ -22,6 +24,7 @@ namespace hex { virtual void drawContent() = 0; virtual void drawMenu(); virtual bool handleShortcut(int key, int mods); + virtual bool isAvailable() { return SharedData::currentProvider != nullptr && SharedData::currentProvider->isAvailable(); } static void openFileBrowser(std::string title, imgui_addons::ImGuiFileBrowser::DialogMode mode, std::string validExtensions, const std::function &callback); static void doLater(std::function &&function); diff --git a/source/views/view_command_palette.cpp b/source/views/view_command_palette.cpp index 1c546f051..4e2a1c9a3 100644 --- a/source/views/view_command_palette.cpp +++ b/source/views/view_command_palette.cpp @@ -5,8 +5,6 @@ namespace hex { ViewCommandPalette::ViewCommandPalette() : View("Command Palette") { - this->getWindowOpenState() = true; - this->m_commandBuffer.resize(1024, 0x00); this->m_lastResults = this->getCommandResults(""); } @@ -17,6 +15,8 @@ namespace hex { void ViewCommandPalette::drawContent() { + if (!this->getWindowOpenState()) return; + auto windowPos = SharedData::windowPos; auto windowSize = SharedData::windowSize; auto paletteSize = this->getMinSize(); @@ -49,7 +49,10 @@ namespace hex { } ImGui::EndPopup(); + } else { + this->getWindowOpenState() = false; } + } void ViewCommandPalette::drawMenu() { @@ -61,6 +64,7 @@ namespace hex { View::doLater([this] { this->m_justOpened = true; ImGui::OpenPopup("Command Palette"); + this->getWindowOpenState() = true; }); return true; } diff --git a/source/views/view_help.cpp b/source/views/view_help.cpp index 2a1f35480..5f4141a46 100644 --- a/source/views/view_help.cpp +++ b/source/views/view_help.cpp @@ -5,7 +5,6 @@ namespace hex { ViewHelp::ViewHelp() : View("Help") { - this->getWindowOpenState() = true; } ViewHelp::~ViewHelp() { @@ -303,6 +302,9 @@ namespace hex { } void ViewHelp::drawContent() { + if (!this->m_aboutWindowOpen && !this->m_mathHelpWindowOpen && !this->m_patternHelpWindowOpen) + this->getWindowOpenState() = false; + this->drawAboutPopup(); this->drawPatternHelpPopup(); this->drawMathEvaluatorHelp(); @@ -313,13 +315,16 @@ namespace hex { if (ImGui::MenuItem("About", "")) { View::doLater([] { ImGui::OpenPopup("About"); }); this->m_aboutWindowOpen = true; + this->getWindowOpenState() = true; } ImGui::Separator(); if (ImGui::MenuItem("Pattern Language Cheat Sheet", "")) { this->m_patternHelpWindowOpen = true; + this->getWindowOpenState() = true; } if (ImGui::MenuItem("Calculator Cheat Sheet", "")) { this->m_mathHelpWindowOpen = true; + this->getWindowOpenState() = true; } ImGui::EndMenu(); } diff --git a/source/views/view_hexeditor.cpp b/source/views/view_hexeditor.cpp index 86af06aa2..7dde1e475 100644 --- a/source/views/view_hexeditor.cpp +++ b/source/views/view_hexeditor.cpp @@ -129,10 +129,19 @@ namespace hex { }); View::subscribeEvent(Events::PatternChanged, [this](auto) { - this->m_highlightedBytes.clear(); + this->m_highlightedBytes.clear(); - for (const auto &pattern : this->m_patternData) - this->m_highlightedBytes.merge(pattern->getHighlightedAddresses()); + for (const auto &pattern : this->m_patternData) + this->m_highlightedBytes.merge(pattern->getHighlightedAddresses()); + }); + + View::subscribeEvent(Events::OpenWindow, [this](auto name) { + if (std::any_cast(name) == std::string("Open File")) { + View::openFileBrowser("Open File", imgui_addons::ImGuiFileBrowser::DialogMode::OPEN, "*.*", [this](auto path) { + this->openFile(path); + this->getWindowOpenState() = true; + }); + } }); } diff --git a/source/views/view_settings.cpp b/source/views/view_settings.cpp index dcb4caa9a..91a1cd0a1 100644 --- a/source/views/view_settings.cpp +++ b/source/views/view_settings.cpp @@ -5,18 +5,23 @@ namespace hex { ViewSettings::ViewSettings() : View("Settings") { - this->getWindowOpenState() = true; + View::subscribeEvent(Events::OpenWindow, [this](auto name) { + if (std::any_cast(name) == std::string("Preferences")) { + View::doLater([]{ ImGui::OpenPopup("Preferences"); }); + this->getWindowOpenState() = true; + } + }); } ViewSettings::~ViewSettings() { - + View::unsubscribeEvent(Events::OpenWindow); } void ViewSettings::drawContent() { ImGui::SetNextWindowSizeConstraints(ImVec2(0, 0), ImVec2(FLT_MAX, FLT_MAX)); - if (ImGui::BeginPopupModal("Preferences", &this->m_settingsWindowOpen, ImGuiWindowFlags_AlwaysAutoResize)) { + if (ImGui::BeginPopupModal("Preferences", &this->getWindowOpenState(), ImGuiWindowFlags_AlwaysAutoResize)) { for (auto &[category, entries] : ContentRegistry::Settings::getEntries()) { ImGui::TextUnformatted(category.c_str()); ImGui::Separator(); @@ -30,7 +35,8 @@ namespace hex { ImGui::NewLine(); } ImGui::EndPopup(); - } + } else + this->getWindowOpenState() = false; } @@ -38,7 +44,7 @@ namespace hex { if (ImGui::BeginMenu("Help")) { if (ImGui::MenuItem("Preferences")) { View::doLater([]{ ImGui::OpenPopup("Preferences"); }); - this->m_settingsWindowOpen = true; + this->getWindowOpenState() = true; } ImGui::EndMenu(); } diff --git a/source/window.cpp b/source/window.cpp index d17984366..0b61a711f 100644 --- a/source/window.cpp +++ b/source/window.cpp @@ -93,18 +93,16 @@ namespace hex { call(); View::getDeferedCalls().clear(); - if (SharedData::currentProvider != nullptr) { - for (auto &view : ContentRegistry::Views::getEntries()) { - if (!view->getWindowOpenState()) - continue; + for (auto &view : ContentRegistry::Views::getEntries()) { + if (!view->isAvailable() || !view->getWindowOpenState()) + continue; - auto minSize = view->getMinSize(); - minSize.x *= this->m_globalScale; - minSize.y *= this->m_globalScale; + auto minSize = view->getMinSize(); + minSize.x *= this->m_globalScale; + minSize.y *= this->m_globalScale; - ImGui::SetNextWindowSizeConstraints(minSize, view->getMaxSize()); - view->drawContent(); - } + ImGui::SetNextWindowSizeConstraints(minSize, view->getMaxSize()); + view->drawContent(); } View::drawCommonInterfaces(); @@ -178,7 +176,7 @@ namespace hex { if (ImGui::BeginMenu("View")) { for (auto &view : ContentRegistry::Views::getEntries()) { - if (view->hasViewMenuItemEntry()) + if (view->isAvailable() && view->hasViewMenuItemEntry()) ImGui::MenuItem((std::string(view->getName()) + " View").c_str(), "", &view->getWindowOpenState()); } ImGui::EndMenu(); @@ -219,12 +217,16 @@ namespace hex { Window::s_currShortcut = { -1, -1 }; } - if (SharedData::currentProvider == nullptr) { + bool anyViewOpen = false; + for (auto &view : ContentRegistry::Views::getEntries()) + anyViewOpen = anyViewOpen || (view->getWindowOpenState() && view->isAvailable()); + + if (!anyViewOpen) { char title[256]; ImFormatString(title, IM_ARRAYSIZE(title), "%s/DockSpace_%08X", ImGui::GetCurrentWindow()->Name, ImGui::GetID("MainDock")); if (ImGui::Begin(title)) { ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(10 * this->m_globalScale, 10 * this->m_globalScale)); - if (ImGui::BeginChild("Welcome Screen", ImVec2(0, 0), ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_NoDecoration)) { + if (ImGui::BeginChild("Welcome Screen", ImVec2(0, 0), false, ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_NoDecoration)) { this->drawWelcomeScreen(); } ImGui::EndChild(); @@ -268,7 +270,8 @@ namespace hex { ImGui::TableNextColumn(); ImGui::Text("Start"); { - ImGui::BulletHyperlink("Open file"); + if (ImGui::BulletHyperlink("Open File")) + EventManager::post(Events::OpenWindow, "Open File"); } ImGui::TableNextRow(ImGuiTableRowFlags_None, 100); ImGui::TableNextColumn(); @@ -292,7 +295,8 @@ namespace hex { ImGui::TableNextColumn(); ImGui::Text("Customize"); { - ImGui::DescriptionButton("Settings", "Change preferences of ImHex", ImVec2(ImGui::GetContentRegionAvail().x * 0.8, 0)); + if (ImGui::DescriptionButton("Settings", "Change preferences of ImHex", ImVec2(ImGui::GetContentRegionAvail().x * 0.8f, 0))) + EventManager::post(Events::OpenWindow, "Preferences"); } ImGui::TableNextRow(ImGuiTableRowFlags_None, 100); ImGui::TableNextColumn();