From 339541a56fa8365bfffd8dcc9a769da4f0cb959f Mon Sep 17 00:00:00 2001 From: Nik Date: Sun, 28 Jan 2024 22:14:59 +0100 Subject: [PATCH] impr: Restructure various components much better (#1520) --- lib/external/libwolv | 2 +- .../include/hex/api/event_manager.hpp | 1 + lib/libimhex/include/hex/api/imhex_api.hpp | 93 +++- lib/libimhex/include/hex/ui/view.hpp | 2 - lib/libimhex/source/api/content_registry.cpp | 2 +- lib/libimhex/source/api/imhex_api.cpp | 18 + .../source/ui/imgui_imhex_extensions.cpp | 7 +- lib/third_party/imgui/CMakeLists.txt | 3 +- lib/third_party/imgui/fonts/CMakeLists.txt | 14 - main/gui/source/init/tasks.cpp | 1 + main/gui/source/window/window.cpp | 418 +-------------- plugins/builtin/CMakeLists.txt | 3 +- .../undo_operations/operation_write.hpp | 2 + plugins/builtin/romfs/assets/common/icon.png | Bin 0 -> 672 bytes plugins/builtin/source/content/events.cpp | 20 + plugins/builtin/source/content/init_tasks.cpp | 22 + .../hex_editor/popup_hex_editor_find.cpp | 2 + .../source/content/views/view_about.cpp | 2 + .../content/views/view_achievements.cpp | 4 +- .../source/content/views/view_bookmarks.cpp | 4 +- .../source/content/views/view_constants.cpp | 2 + .../content/views/view_data_inspector.cpp | 2 + .../source/content/views/view_find.cpp | 2 + .../source/content/views/view_hex_editor.cpp | 8 +- .../content/views/view_highlight_rules.cpp | 2 + .../source/content/views/view_logs.cpp | 2 + .../content/views/view_pattern_data.cpp | 3 +- .../source/content/views/view_settings.cpp | 1 + .../content/views/view_theme_manager.cpp | 1 + .../source/content/views/view_tools.cpp | 2 + .../source/content/views/view_tutorials.cpp | 2 + .../source/content/window_decoration.cpp | 438 +++++++++++++++ plugins/builtin/source/plugin_builtin.cpp | 7 +- plugins/decompress/CMakeLists.txt | 1 + plugins/diffing/CMakeLists.txt | 1 + .../source/content/views/view_diff.cpp | 2 + plugins/disassembler/CMakeLists.txt | 3 +- .../content/views/view_disassembler.cpp | 2 + plugins/fonts/CMakeLists.txt | 14 + plugins/fonts/LICENSE | 502 ++++++++++++++++++ .../fonts/include/fonts/blendericons_font.h | 0 .../fonts/include/fonts/codicons_font.h | 0 .../fonts/include/fonts/unifont_font.h | 0 .../fonts/romfs}/UNIFONT_LICENSE.txt | 0 .../fonts/romfs}/VSCODICONS_LICENSE.txt | 0 .../romfs/fonts/blendericons.ttf | Bin .../romfs/fonts/codicons.ttf | Bin .../romfs/fonts/unifont.otf | Bin .../source/content => fonts/source}/fonts.cpp | 2 +- plugins/fonts/source/library_fonts.cpp | 16 + plugins/hashes/CMakeLists.txt | 2 +- .../source/content/views/view_hashes.cpp | 4 +- plugins/script_loader/CMakeLists.txt | 1 + plugins/ui/CMakeLists.txt | 1 + plugins/ui/source/ui/hex_editor.cpp | 3 + plugins/visualizers/CMakeLists.txt | 2 + plugins/windows/CMakeLists.txt | 1 + plugins/yara_rules/CMakeLists.txt | 1 + resources/projects/icon.xcf | Bin 0 -> 1453 bytes 59 files changed, 1179 insertions(+), 471 deletions(-) delete mode 100644 lib/third_party/imgui/fonts/CMakeLists.txt create mode 100644 plugins/builtin/romfs/assets/common/icon.png create mode 100644 plugins/builtin/source/content/window_decoration.cpp create mode 100644 plugins/fonts/CMakeLists.txt create mode 100644 plugins/fonts/LICENSE rename {lib/third_party/imgui => plugins}/fonts/include/fonts/blendericons_font.h (100%) rename {lib/third_party/imgui => plugins}/fonts/include/fonts/codicons_font.h (100%) rename {lib/third_party/imgui => plugins}/fonts/include/fonts/unifont_font.h (100%) rename {lib/third_party/imgui/fonts => plugins/fonts/romfs}/UNIFONT_LICENSE.txt (100%) rename {lib/third_party/imgui/fonts => plugins/fonts/romfs}/VSCODICONS_LICENSE.txt (100%) rename plugins/{builtin => fonts}/romfs/fonts/blendericons.ttf (100%) rename plugins/{builtin => fonts}/romfs/fonts/codicons.ttf (100%) rename plugins/{builtin => fonts}/romfs/fonts/unifont.otf (100%) rename plugins/{builtin/source/content => fonts/source}/fonts.cpp (96%) create mode 100644 plugins/fonts/source/library_fonts.cpp create mode 100644 resources/projects/icon.xcf diff --git a/lib/external/libwolv b/lib/external/libwolv index 7e90fc85e..a21d39b75 160000 --- a/lib/external/libwolv +++ b/lib/external/libwolv @@ -1 +1 @@ -Subproject commit 7e90fc85edad5c59eb82ce1d2727e1070fe4229b +Subproject commit a21d39b75dd1347ac82609112b831dd5092d6b45 diff --git a/lib/libimhex/include/hex/api/event_manager.hpp b/lib/libimhex/include/hex/api/event_manager.hpp index 00cfefe2b..9689c7996 100644 --- a/lib/libimhex/include/hex/api/event_manager.hpp +++ b/lib/libimhex/include/hex/api/event_manager.hpp @@ -241,6 +241,7 @@ namespace hex { EVENT_DEF(EventProviderDeleted, prv::Provider *); EVENT_DEF(EventProviderSaved, prv::Provider *); EVENT_DEF(EventWindowInitialized); + EVENT_DEF(EventWindowDeinitializing, GLFWwindow *); EVENT_DEF(EventBookmarkCreated, ImHexApi::Bookmarks::Entry&); EVENT_DEF(EventPatchCreated, u64, u8, u8); EVENT_DEF(EventPatternEvaluating); diff --git a/lib/libimhex/include/hex/api/imhex_api.hpp b/lib/libimhex/include/hex/api/imhex_api.hpp index 380bc680f..d85e52363 100644 --- a/lib/libimhex/include/hex/api/imhex_api.hpp +++ b/lib/libimhex/include/hex/api/imhex_api.hpp @@ -359,38 +359,18 @@ namespace hex { /* Functions to interact with various ImHex system settings */ namespace System { - bool isMainInstance(); - - namespace impl { - void setMainInstanceStatus(bool status); - - void setMainWindowPosition(i32 x, i32 y); - void setMainWindowSize(u32 width, u32 height); - void setMainDockSpaceId(ImGuiID id); - void setMainWindowHandle(GLFWwindow *window); - - void setGlobalScale(float scale); - void setNativeScale(float scale); - - void setBorderlessWindowMode(bool enabled); - - void setGPUVendor(const std::string &vendor); - - void setPortableVersion(bool enabled); - - void addInitArgument(const std::string &key, const std::string &value = { }); - - void setLastFrameTime(double time); - - bool isWindowResizable(); - } - struct ProgramArguments { int argc; char **argv; char **envp; }; + struct InitialWindowProperties { + i32 x, y; + u32 width, height; + bool maximized; + }; + enum class TaskProgressState { Reset, Progress, @@ -403,6 +383,34 @@ namespace hex { Error }; + namespace impl { + + void setMainInstanceStatus(bool status); + + void setMainWindowPosition(i32 x, i32 y); + void setMainWindowSize(u32 width, u32 height); + void setMainDockSpaceId(ImGuiID id); + void setMainWindowHandle(GLFWwindow *window); + + void setGlobalScale(float scale); + void setNativeScale(float scale); + + void setBorderlessWindowMode(bool enabled); + void setMultiWindowMode(bool enabled); + void setInitialWindowProperties(InitialWindowProperties properties); + + void setGPUVendor(const std::string &vendor); + + void setPortableVersion(bool enabled); + + void addInitArgument(const std::string &key, const std::string &value = { }); + + void setLastFrameTime(double time); + + bool isWindowResizable(); + + } + /** * @brief Closes ImHex * @param noQuestions Whether to skip asking the user for confirmation @@ -479,6 +487,12 @@ namespace hex { */ bool isBorderlessWindowModeEnabled(); + /** + * @brief Checks if multi-window mode is enabled currently + * @return Whether multi-window mode is enabled + */ + bool isMutliWindowModeEnabled(); + /** * @brief Gets the init arguments passed to ImHex from the splash screen * @return Init arguments @@ -578,11 +592,38 @@ namespace hex { */ bool updateImHex(UpdateType updateType); + /** + * @brief Add a new startup task that will be run while ImHex's splash screen is shown + * @param name Name to be shown in the UI + * @param async Whether to run the task asynchronously + * @param function The function to run + */ void addStartupTask(const std::string &name, bool async, const std::function &function); + /** + * @brief Gets the time the previous frame took + * @return Previous frame time + */ double getLastFrameTime(); + /** + * @brief Sets the window resizable + * @param resizable Whether the window should be resizable + */ void setWindowResizable(bool resizable); + + /** + * @brief Checks if this window is the main instance of ImHex + * @return True if this is the main instance, false if another instance is already running + */ + bool isMainInstance(); + + /** + * @brief Gets the initial window properties + * @return Initial window properties + */ + std::optional getInitialWindowProperties(); + } /** diff --git a/lib/libimhex/include/hex/ui/view.hpp b/lib/libimhex/include/hex/ui/view.hpp index 9dad0394c..a6794ac31 100644 --- a/lib/libimhex/include/hex/ui/view.hpp +++ b/lib/libimhex/include/hex/ui/view.hpp @@ -6,8 +6,6 @@ #include #include -#include - #include #include #include diff --git a/lib/libimhex/source/api/content_registry.cpp b/lib/libimhex/source/api/content_registry.cpp index 062ba04b1..e9025997a 100644 --- a/lib/libimhex/source/api/content_registry.cpp +++ b/lib/libimhex/source/api/content_registry.cpp @@ -352,7 +352,7 @@ namespace hex { ImGui::SameLine(); - if (ImGuiExt::IconButton(ICON_VS_FOLDER_OPENED, ImGui::GetStyleColorVec4(ImGuiCol_Text))) { + if (ImGuiExt::IconButton("...", ImGui::GetStyleColorVec4(ImGuiCol_Text))) { return fs::openFileBrowser(fs::DialogMode::Open, { { "TTF Font", "ttf" }, { "OTF Font", "otf" } }, [&](const std::fs::path &path) { m_value = wolv::util::toUTF8String(path); diff --git a/lib/libimhex/source/api/imhex_api.cpp b/lib/libimhex/source/api/imhex_api.cpp index 50d5058ad..6c5fe192f 100644 --- a/lib/libimhex/source/api/imhex_api.cpp +++ b/lib/libimhex/source/api/imhex_api.cpp @@ -426,6 +426,16 @@ namespace hex { s_borderlessWindowMode = enabled; } + static bool s_multiWindowMode = false; + void setMultiWindowMode(bool enabled) { + s_multiWindowMode = enabled; + } + + static std::optional s_initialWindowProperties; + void setInitialWindowProperties(InitialWindowProperties properties) { + s_initialWindowProperties = properties; + } + static std::string s_gpuVendor; void setGPUVendor(const std::string &vendor) { @@ -518,6 +528,14 @@ namespace hex { return impl::s_borderlessWindowMode; } + bool isMutliWindowModeEnabled() { + return impl::s_multiWindowMode; + } + + std::optional getInitialWindowProperties() { + return impl::s_initialWindowProperties; + } + std::map &getInitArguments() { static std::map initArgs; diff --git a/lib/libimhex/source/ui/imgui_imhex_extensions.cpp b/lib/libimhex/source/ui/imgui_imhex_extensions.cpp index 63d50cd06..7817d1433 100644 --- a/lib/libimhex/source/ui/imgui_imhex_extensions.cpp +++ b/lib/libimhex/source/ui/imgui_imhex_extensions.cpp @@ -17,7 +17,6 @@ #include -#include #include #include @@ -366,7 +365,7 @@ namespace ImGuiExt { PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, GetStyle().FramePadding.y)); PushStyleColor(ImGuiCol_Text, iconColor); - Button(ICON_VS_INFO); + Button("(?)"); PopStyleColor(); if (IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) { @@ -1010,7 +1009,7 @@ namespace ImGuiExt { ImGui::PushID(label); - const auto buttonSize = ImGui::CalcTextSize(ICON_VS_FOLDER) + ImGui::GetStyle().FramePadding * 2; + const auto buttonSize = ImGui::CalcTextSize("...") + ImGui::GetStyle().FramePadding * 2; ImGui::PushItemWidth(ImGui::CalcItemWidth() - buttonSize.x - ImGui::GetStyle().FramePadding.x); std::string string = wolv::util::toUTF8String(path); if (ImGui::InputText("##pathInput", string, ImGuiInputTextFlags_AutoSelectAll)) { @@ -1021,7 +1020,7 @@ namespace ImGuiExt { ImGui::SameLine(); - if (ImGui::Button(ICON_VS_FOLDER, buttonSize)) { + if (ImGui::Button("...", buttonSize)) { hex::fs::openFileBrowser(hex::fs::DialogMode::Open, validExtensions, [&](const std::fs::path &pickedPath) { path = pickedPath; picked = true; diff --git a/lib/third_party/imgui/CMakeLists.txt b/lib/third_party/imgui/CMakeLists.txt index 8323aff11..41bdf960f 100644 --- a/lib/third_party/imgui/CMakeLists.txt +++ b/lib/third_party/imgui/CMakeLists.txt @@ -9,7 +9,6 @@ add_subdirectory(imgui) add_subdirectory(implot) add_subdirectory(imnodes) add_subdirectory(custom) -add_subdirectory(fonts) add_subdirectory(ColorTextEditor) -set(IMGUI_LIBRARIES imgui_imgui imgui_implot imgui_imnodes imgui_custom imgui_fonts imgui_color_text_editor PARENT_SCOPE) \ No newline at end of file +set(IMGUI_LIBRARIES imgui_imgui imgui_implot imgui_imnodes imgui_custom imgui_color_text_editor PARENT_SCOPE) \ No newline at end of file diff --git a/lib/third_party/imgui/fonts/CMakeLists.txt b/lib/third_party/imgui/fonts/CMakeLists.txt deleted file mode 100644 index 6058eb46b..000000000 --- a/lib/third_party/imgui/fonts/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ -cmake_minimum_required(VERSION 3.16) -# https://unifoundry.com/unifont/index.html -# https://github.com/microsoft/vscode-codicons -project(imgui_fonts) - -set(CMAKE_CXX_STANDARD 17) - -add_library(imgui_fonts INTERFACE) - -target_include_directories(imgui_fonts INTERFACE - include -) - -target_include_directories(imgui_all_includes INTERFACE include) diff --git a/main/gui/source/init/tasks.cpp b/main/gui/source/init/tasks.cpp index f2b31176e..a6567286b 100644 --- a/main/gui/source/init/tasks.cpp +++ b/main/gui/source/init/tasks.cpp @@ -126,6 +126,7 @@ namespace hex::init { ContentRegistry::FileHandler::impl::getEntries().clear(); ContentRegistry::Hashes::impl::getHashes().clear(); ContentRegistry::HexEditor::impl::getVisualizers().clear(); + ContentRegistry::HexEditor::impl::getMiniMapVisualizers().clear(); ContentRegistry::BackgroundServices::impl::stopServices(); diff --git a/main/gui/source/window/window.cpp b/main/gui/source/window/window.cpp index eced02063..dc453216d 100644 --- a/main/gui/source/window/window.cpp +++ b/main/gui/source/window/window.cpp @@ -8,7 +8,6 @@ #include #include #include -#include #include #include @@ -35,8 +34,6 @@ #include -#include - #include #include #include @@ -72,8 +69,6 @@ namespace hex { this->setupNativeWindow(); this->registerEventHandlers(); - m_logoTexture = ImGuiExt::Texture(romfs::get("logo.png").span(), ImGuiExt::Texture::Filter::Linear); - ContentRegistry::Settings::impl::store(); EventSettingsChanged::post(); EventWindowInitialized::post(); @@ -87,10 +82,7 @@ namespace hex { EventAbnormalTermination::unsubscribe(this); RequestOpenPopup::unsubscribe(this); - WorkspaceManager::exportToFile(); - - if (auto workspace = WorkspaceManager::getCurrentWorkspace(); workspace != WorkspaceManager::getWorkspaces().end()) - ContentRegistry::Settings::write("hex.builtin.setting.general", "hex.builtin.setting.general.curr_workspace", workspace->first); + EventWindowDeinitializing::post(m_window); this->exitImGui(); this->exitGLFW(); @@ -108,44 +100,6 @@ namespace hex { EventWindowClosing::post(m_window); }); - // Handle updating the window title - RequestUpdateWindowTitle::subscribe(this, [this] { - std::string prefix, postfix; - std::string title = "ImHex"; - - if (ProjectFile::hasPath()) { - // If a project is open, show the project name instead of the file name - - prefix = "Project "; - title = ProjectFile::getPath().stem().string(); - - if (ImHexApi::Provider::isDirty()) - postfix += " (*)"; - - } else if (ImHexApi::Provider::isValid()) { - auto provider = ImHexApi::Provider::get(); - if (provider != nullptr) { - title = provider->getName(); - - if (provider->isDirty()) - postfix += " (*)"; - - if (!provider->isWritable() && provider->getActualSize() != 0) - postfix += " (Read Only)"; - } - } - - m_windowTitle = prefix + hex::limitStringLength(title, 32) + postfix; - m_windowTitleFull = prefix + title + postfix; - - if (m_window != nullptr) { - if (title != "ImHex") - title = "ImHex - " + title; - - glfwSetWindowTitle(m_window, title.c_str()); - } - }); - // Handle opening popups RequestOpenPopup::subscribe(this, [this](auto name) { std::scoped_lock lock(m_popupMutex); @@ -238,126 +192,6 @@ namespace hex { } } - static void createNestedMenu(std::span menuItems, const char *icon, const Shortcut &shortcut, const ContentRegistry::Interface::impl::MenuCallback &callback, const ContentRegistry::Interface::impl::EnabledCallback &enabledCallback, const ContentRegistry::Interface::impl::SelectedCallback &selectedCallback) { - const auto &name = menuItems.front(); - - if (name.get() == ContentRegistry::Interface::impl::SeparatorValue) { - ImGui::Separator(); - return; - } - - if (name.get() == ContentRegistry::Interface::impl::SubMenuValue) { - callback(); - } else if (menuItems.size() == 1) { - if (ImGui::MenuItemEx(Lang(name), icon, shortcut.toString().c_str(), selectedCallback(), enabledCallback())) - callback(); - } else { - bool isSubmenu = (menuItems.begin() + 1)->get() == ContentRegistry::Interface::impl::SubMenuValue; - - if (ImGui::BeginMenuEx(Lang(name), std::next(menuItems.begin())->get() == ContentRegistry::Interface::impl::SubMenuValue ? icon : nullptr, isSubmenu ? enabledCallback() : true)) { - createNestedMenu({ std::next(menuItems.begin()), menuItems.end() }, icon, shortcut, callback, enabledCallback, selectedCallback); - ImGui::EndMenu(); - } - } - } - - void Window::drawTitleBar() { - auto titleBarHeight = ImGui::GetCurrentWindowRead()->MenuBarHeight(); - auto buttonSize = ImVec2(titleBarHeight * 1.5F, titleBarHeight - 1); - - ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0)); - ImGui::PushStyleColor(ImGuiCol_Button, ImGui::GetColorU32(ImGuiCol_MenuBarBg)); - ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImGui::GetColorU32(ImGuiCol_ScrollbarGrabActive)); - ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImGui::GetColorU32(ImGuiCol_ScrollbarGrabHovered)); - - const auto windowSize = ImHexApi::System::getMainWindowSize(); - const auto searchBoxSize = ImVec2(windowSize.x / 2.5, titleBarHeight - 3_scaled); - const auto searchBoxPos = ImVec2((windowSize / 2 - searchBoxSize / 2).x, 3_scaled); - - m_searchBarPosition = searchBoxPos.x; - - // Custom titlebar buttons implementation for borderless window mode - auto &titleBarButtons = ContentRegistry::Interface::impl::getTitleBarButtons(); - - // Draw custom title bar buttons - if (!titleBarButtons.empty()) { - ImGui::SetCursorPosX(ImGui::GetWindowWidth() - buttonSize.x * float(4 + titleBarButtons.size())); - - if (ImGui::GetCursorPosX() > (searchBoxPos.x + searchBoxSize.x)) { - for (const auto &[icon, tooltip, callback]: titleBarButtons) { - if (ImGuiExt::TitleBarButton(icon.c_str(), buttonSize)) { - callback(); - } - ImGuiExt::InfoTooltip(Lang(tooltip)); - } - } - } - - if (ImHexApi::System::isBorderlessWindowModeEnabled() && glfwGetWindowMonitor(m_window) == nullptr) { - // Draw minimize, restore and maximize buttons - ImGui::SetCursorPosX(ImGui::GetWindowWidth() - buttonSize.x * 3); - if (ImGuiExt::TitleBarButton(ICON_VS_CHROME_MINIMIZE, buttonSize)) - glfwIconifyWindow(m_window); - if (glfwGetWindowAttrib(m_window, GLFW_MAXIMIZED)) { - if (ImGuiExt::TitleBarButton(ICON_VS_CHROME_RESTORE, buttonSize)) - glfwRestoreWindow(m_window); - } else { - if (ImGuiExt::TitleBarButton(ICON_VS_CHROME_MAXIMIZE, buttonSize)) - glfwMaximizeWindow(m_window); - } - - ImGui::PushStyleColor(ImGuiCol_ButtonActive, 0xFF7A70F1); - ImGui::PushStyleColor(ImGuiCol_ButtonHovered, 0xFF2311E8); - - // Draw close button - if (ImGuiExt::TitleBarButton(ICON_VS_CHROME_CLOSE, buttonSize)) { - ImHexApi::System::closeImHex(); - } - - ImGui::PopStyleColor(2); - } - - ImGui::PopStyleColor(3); - ImGui::PopStyleVar(); - - { - const auto buttonColor = [](float alpha) { - return ImU32(ImColor(ImGui::GetStyleColorVec4(ImGuiCol_DockingEmptyBg) * ImVec4(1, 1, 1, alpha))); - }; - - ImGui::PushStyleColor(ImGuiCol_Button, buttonColor(0.5F)); - ImGui::PushStyleColor(ImGuiCol_ButtonHovered, buttonColor(0.7F)); - ImGui::PushStyleColor(ImGuiCol_ButtonActive, buttonColor(0.9F)); - ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0_scaled); - ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 4_scaled); - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, scaled({ 1, 1 })); - - ImGui::SetCursorPos(searchBoxPos); - if (ImGui::Button(m_windowTitle.c_str(), searchBoxSize)) { - EventSearchBoxClicked::post(ImGuiMouseButton_Left); - } - - if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) - EventSearchBoxClicked::post(ImGuiMouseButton_Right); - - ImGui::PushTextWrapPos(300_scaled); - if (!m_windowTitleFull.empty()) - ImGui::SetItemTooltip("%s", m_windowTitleFull.c_str()); - ImGui::PopTextWrapPos(); - - ImGui::PopStyleVar(3); - ImGui::PopStyleColor(3); - } - } - - static bool isAnyViewOpen() { - const auto &views = ContentRegistry::Views::impl::getEntries(); - return std::any_of(views.begin(), views.end(), - [](const auto &entry) { - return entry.second->getWindowOpenState(); - }); - } - void Window::frameBegin() { // Start new ImGui Frame ImGui_ImplOpenGL3_NewFrame(); @@ -375,216 +209,19 @@ namespace hex { ImGuiWindowFlags windowFlags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoNavFocus | ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse; - ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; - // Render main dock space if (ImGui::Begin("ImHexDockSpace", nullptr, windowFlags)) { - auto drawList = ImGui::GetWindowDrawList(); ImGui::PopStyleVar(); - bool shouldDrawSidebar = [] { - if (const auto &items = ContentRegistry::Interface::impl::getSidebarItems(); items.empty()) { - return false; - } else { - return std::any_of(items.begin(), items.end(), [](const auto &item) { - return item.enabledCallback(); - }); - } - }(); - - const auto menuBarHeight = ImGui::GetCurrentWindowRead()->MenuBarHeight(); - auto sidebarPos = ImGui::GetCursorPos(); - auto sidebarWidth = shouldDrawSidebar ? 20_scaled : 0; - - ImGui::SetCursorPosX(sidebarWidth); - - auto footerHeight = ImGui::GetTextLineHeightWithSpacing() + ImGui::GetStyle().FramePadding.y * 2 + 1_scaled; - auto dockSpaceSize = ImVec2(ImHexApi::System::getMainWindowSize().x - sidebarWidth, ImGui::GetContentRegionAvail().y - footerHeight); - - // Render footer - { - - auto dockId = ImGui::DockSpace(ImGui::GetID("ImHexMainDock"), dockSpaceSize); - ImHexApi::System::impl::setMainDockSpaceId(dockId); - - drawList->AddRectFilled(ImGui::GetWindowPos(), ImGui::GetWindowPos() + ImGui::GetWindowSize() - ImVec2(dockSpaceSize.x, footerHeight - ImGui::GetStyle().FramePadding.y - 1_scaled), ImGui::GetColorU32(ImGuiCol_MenuBarBg)); - - ImGui::Separator(); - ImGui::SetCursorPosX(8); - for (const auto &callback : ContentRegistry::Interface::impl::getFooterItems()) { - auto prevIdx = drawList->_VtxCurrentIdx; - callback(); - auto currIdx = drawList->_VtxCurrentIdx; - - // Only draw separator if something was actually drawn - if (prevIdx != currIdx) { - ImGui::SameLine(); - ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical); - ImGui::SameLine(); - } - } - } - - // Render sidebar - if (shouldDrawSidebar) { - ImGui::SetCursorPos(sidebarPos); - - static i32 openWindow = -1; - u32 index = 0; - ImGui::PushID("SideBarWindows"); - for (const auto &[icon, callback, enabledCallback] : ContentRegistry::Interface::impl::getSidebarItems()) { - ImGui::SetCursorPosY(sidebarPos.y + sidebarWidth * index); - - ImGui::PushStyleColor(ImGuiCol_Button, ImGui::GetColorU32(ImGuiCol_MenuBarBg)); - ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImGui::GetColorU32(ImGuiCol_ScrollbarGrabActive)); - ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImGui::GetColorU32(ImGuiCol_ScrollbarGrabHovered)); - - ImGui::BeginDisabled(!(ImHexApi::Provider::isValid() && enabledCallback())); - { - if (ImGui::Button(icon.c_str(), ImVec2(sidebarWidth, sidebarWidth))) { - if (static_cast(openWindow) == index) - openWindow = -1; - else - openWindow = index; - } - } - ImGui::EndDisabled(); - - ImGui::PopStyleColor(3); - - auto sideBarFocused = ImGui::IsWindowFocused(); - - bool open = static_cast(openWindow) == index; - if (open) { - - ImGui::SetNextWindowPos(ImGui::GetWindowPos() + sidebarPos + ImVec2(sidebarWidth - 1_scaled, -1_scaled)); - ImGui::SetNextWindowSize(ImVec2(0, dockSpaceSize.y + 5_scaled)); - - ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 1); - ImGui::PushStyleColor(ImGuiCol_WindowShadow, 0x00000000); - if (ImGui::Begin("SideBarWindow", &open, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse)) { - if (ImGui::BeginChild("##Content", ImVec2(), ImGuiChildFlags_ResizeX)) { - callback(); - } - ImGui::EndChild(); - - if (!ImGui::IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows) && !sideBarFocused) { - openWindow = -1; - } - } - ImGui::End(); - ImGui::PopStyleVar(); - ImGui::PopStyleColor(); - } - - ImGui::NewLine(); - index++; - } - ImGui::PopID(); - } - - // Render main menu - ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0F); - ImGui::SetNextWindowScroll(ImVec2(0, 0)); - if (ImGui::BeginMainMenuBar()) { - - if (ImHexApi::System::isBorderlessWindowModeEnabled()) { - ImGui::SetCursorPosX(5); - - ImGui::Image(m_logoTexture, ImVec2(menuBarHeight, menuBarHeight)); - ImGui::SetCursorPosX(5); - ImGui::InvisibleButton("##logo", ImVec2(menuBarHeight, menuBarHeight)); - ImGui::OpenPopupOnItemClick("WindowingMenu", ImGuiPopupFlags_MouseButtonLeft); - } - - if (ImGui::BeginPopup("WindowingMenu")) { - bool maximized = glfwGetWindowAttrib(m_window, GLFW_MAXIMIZED); - - ImGui::BeginDisabled(!maximized); - if (ImGui::MenuItem(ICON_VS_CHROME_RESTORE " Restore")) glfwRestoreWindow(m_window); - ImGui::EndDisabled(); - - if (ImGui::MenuItem(ICON_VS_CHROME_MINIMIZE " Minimize")) glfwIconifyWindow(m_window); - - ImGui::BeginDisabled(maximized); - if (ImGui::MenuItem(ICON_VS_CHROME_MAXIMIZE " Maximize")) glfwMaximizeWindow(m_window); - ImGui::EndDisabled(); - - ImGui::Separator(); - - if (ImGui::MenuItem(ICON_VS_CHROME_CLOSE " Close")) ImHexApi::System::closeImHex(); - - ImGui::EndPopup(); - } - - const static auto drawMenu = [] { - for (const auto &[priority, menuItem] : ContentRegistry::Interface::impl::getMainMenuItems()) { - ImGui::GetStyle().TouchExtraPadding = scaled(ImVec2(0, 2)); - if (ImGui::BeginMenu(Lang(menuItem.unlocalizedName))) { - ImGui::EndMenu(); - } - ImGui::GetStyle().TouchExtraPadding = ImVec2(0, 0); - } - - for (auto &[priority, menuItem] : ContentRegistry::Interface::impl::getMenuItems()) { - const auto &[unlocalizedNames, icon, shortcut, view, callback, enabledCallback, selectedCallack, toolbarIndex] = menuItem; - - createNestedMenu(unlocalizedNames, icon.glyph.c_str(), *shortcut, callback, enabledCallback, selectedCallack); - } - }; - - if (m_lastStartFrameTime > 0) { - static u32 menuEndPos = 0; - if (menuEndPos < m_searchBarPosition) { - drawMenu(); - menuEndPos = ImGui::GetCursorPosX(); - } else { - if (ImGui::BeginMenu(ICON_VS_MENU)) { - drawMenu(); - ImGui::EndMenu(); - } - } - } - - this->drawTitleBar(); - - ImGui::EndMainMenuBar(); - } - ImGui::PopStyleVar(); - - // Render toolbar - if (ImGui::BeginMenuBar()) { - - for (const auto &callback : ContentRegistry::Interface::impl::getToolbarItems()) { - callback(); - ImGui::SameLine(); - } - - if (auto provider = ImHexApi::Provider::get(); provider != nullptr) { - ImGui::BeginDisabled(TaskManager::getRunningTaskCount() > 0); - if (ImGui::CloseButton(ImGui::GetID("ProviderCloseButton"), ImGui::GetCursorScreenPos() + ImVec2(ImGui::GetContentRegionAvail().x - 17_scaled, 3_scaled))) { - ImHexApi::Provider::remove(provider); - } - ImGui::EndDisabled(); - } - - ImGui::EndMenuBar(); - } - this->beginNativeWindowFrame(); - - if (ImHexApi::Provider::isValid() && isAnyViewOpen()) { - drawList->AddLine( - ImGui::GetWindowPos() + sidebarPos + ImVec2(sidebarWidth - 1_scaled, -2_scaled), - ImGui::GetWindowPos() + sidebarPos + ImGui::GetWindowSize() - ImVec2(dockSpaceSize.x + 1_scaled, footerHeight - ImGui::GetStyle().FramePadding.y - 1_scaled + menuBarHeight), - ImGui::GetColorU32(ImGuiCol_Separator)); - } } else { ImGui::PopStyleVar(); } ImGui::End(); ImGui::PopStyleVar(2); + EventFrameBegin::post(); + // Plugin load error popups. These are not translated because they should always be readable, no matter if any localization could be loaded or not { auto drawPluginFolderTable = [] { @@ -797,18 +434,6 @@ namespace hex { // Run all deferred calls TaskManager::runDeferredCalls(); - - // Draw main menu popups - for (auto &[priority, menuItem] : ContentRegistry::Interface::impl::getMenuItems()) { - const auto &[unlocalizedNames, icon, shortcut, view, callback, enabledCallback, selectedCallback, toolbarIndex] = menuItem; - - if (ImGui::BeginPopup(unlocalizedNames.front().get().c_str())) { - createNestedMenu({ unlocalizedNames.begin() + 1, unlocalizedNames.end() }, icon.glyph.c_str(), *shortcut, callback, enabledCallback, selectedCallback); - ImGui::EndPopup(); - } - } - - EventFrameBegin::post(); } void Window::frame() { @@ -942,8 +567,7 @@ namespace hex { } void Window::initGLFW() { - bool restoreWindowPos = ContentRegistry::Settings::read("hex.builtin.setting.interface", "hex.builtin.setting.interface.restore_window_pos", false); - + auto initialWindowProperties = ImHexApi::System::getInitialWindowProperties(); glfwSetErrorCallback([](int error, const char *desc) { if (error == GLFW_PLATFORM_ERROR) { // Ignore error spam caused by Wayland not supporting moving or resizing @@ -982,9 +606,8 @@ namespace hex { glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API); - if (restoreWindowPos) { - int maximized = ContentRegistry::Settings::read("hex.builtin.setting.interface", "hex.builtin.setting.interface.window.maximized", GLFW_FALSE); - glfwWindowHint(GLFW_MAXIMIZED, maximized); + if (initialWindowProperties.has_value()) { + glfwWindowHint(GLFW_MAXIMIZED, initialWindowProperties->maximized); } // Create window @@ -1026,9 +649,9 @@ namespace hex { int x = 0, y = 0; glfwGetWindowPos(m_window, &x, &y); - if (restoreWindowPos) { - x = ContentRegistry::Settings::read("hex.builtin.setting.interface", "hex.builtin.setting.interface.window.x", x); - y = ContentRegistry::Settings::read("hex.builtin.setting.interface", "hex.builtin.setting.interface.window.y", y); + if (initialWindowProperties.has_value()) { + x = initialWindowProperties->x; + y = initialWindowProperties->y; } ImHexApi::System::impl::setMainWindowPosition(x, y); @@ -1041,9 +664,9 @@ namespace hex { glfwGetWindowSize(m_window, &width, &height); glfwSetWindowSize(m_window, width, height); - if (restoreWindowPos) { - width = ContentRegistry::Settings::read("hex.builtin.setting.interface", "hex.builtin.setting.interface.window.width", width); - height = ContentRegistry::Settings::read("hex.builtin.setting.interface", "hex.builtin.setting.interface.window.height", height); + if (initialWindowProperties.has_value()) { + width = initialWindowProperties->width; + height = initialWindowProperties->height; } ImHexApi::System::impl::setMainWindowSize(width, height); @@ -1175,9 +798,7 @@ namespace hex { io.FontGlobalScale = 1.0F; if (glfwGetPrimaryMonitor() != nullptr) { - bool multiWindowEnabled = ContentRegistry::Settings::read("hex.builtin.setting.interface", "hex.builtin.setting.interface.multi_windows", false); - - if (multiWindowEnabled) + if (ImHexApi::System::isMutliWindowModeEnabled()) io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; } @@ -1273,19 +894,6 @@ namespace hex { } void Window::exitGLFW() { - { - int x = 0, y = 0, width = 0, height = 0, maximized = 0; - glfwGetWindowPos(m_window, &x, &y); - glfwGetWindowSize(m_window, &width, &height); - maximized = glfwGetWindowAttrib(m_window, GLFW_MAXIMIZED); - - ContentRegistry::Settings::write("hex.builtin.setting.interface", "hex.builtin.setting.interface.window.x", x); - ContentRegistry::Settings::write("hex.builtin.setting.interface", "hex.builtin.setting.interface.window.y", y); - ContentRegistry::Settings::write("hex.builtin.setting.interface", "hex.builtin.setting.interface.window.width", width); - ContentRegistry::Settings::write("hex.builtin.setting.interface", "hex.builtin.setting.interface.window.height", height); - ContentRegistry::Settings::write("hex.builtin.setting.interface", "hex.builtin.setting.interface.window.maximized", maximized); - } - glfwDestroyWindow(m_window); glfwTerminate(); diff --git a/plugins/builtin/CMakeLists.txt b/plugins/builtin/CMakeLists.txt index 2937818d7..b998cba50 100644 --- a/plugins/builtin/CMakeLists.txt +++ b/plugins/builtin/CMakeLists.txt @@ -41,11 +41,11 @@ add_imhex_plugin( source/content/file_extraction.cpp source/content/report_generators.cpp source/content/init_tasks.cpp - source/content/fonts.cpp source/content/workspaces.cpp source/content/pl_visualizers.cpp source/content/out_of_box_experience.cpp source/content/minimap_visualizers.cpp + source/content/window_decoration.cpp source/content/data_processor_nodes/basic_nodes.cpp source/content/data_processor_nodes/control_nodes.cpp @@ -120,6 +120,7 @@ add_imhex_plugin( LIBRARIES ui + fonts ${JTHREAD_LIBRARIES} plcli libpl-gen diff --git a/plugins/builtin/include/content/providers/undo_operations/operation_write.hpp b/plugins/builtin/include/content/providers/undo_operations/operation_write.hpp index 6dafa4a96..370a7869d 100644 --- a/plugins/builtin/include/content/providers/undo_operations/operation_write.hpp +++ b/plugins/builtin/include/content/providers/undo_operations/operation_write.hpp @@ -6,6 +6,8 @@ #include #include +#include + namespace hex::plugin::builtin::undo { class OperationWrite : public prv::undo::Operation { diff --git a/plugins/builtin/romfs/assets/common/icon.png b/plugins/builtin/romfs/assets/common/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..f86a0a2cfda17dd9439e563f78300bdde91a93a9 GIT binary patch literal 672 zcmV;R0$=@!P)EX>4Tx04R}tkv&MmP!xqvQ>7vmhjviukfAzR2NiLYDi*;)X)CnqVDi#GXws0R zxHt-~1qXi?s}3&Cx;nTDg5VE`vxAeOiHOd!q zE-Re3IIGnK>|xiA_WmL>ZqU!3o+U?QcR@jJnrEiar`NA$>gel zkz)ZhsE`~#_#gb9ty!F!bd!Q{p!dbLKSqJTF3@V&_V=-Ew@v{6GjOGK{Iw=9`$>AE zqeYK^!ENB;x}(W^z~v4w^rTCM@~24YJ`L;w!}4*(C~@OA_CX>@2HM@dakSAh-}0001YNkl1K8BEV9PF~WGxKCLEqnlccx+0000 #include #include +#include #include #include @@ -202,6 +203,25 @@ namespace hex::plugin::builtin { ContentRegistry::Settings::write("hex.builtin.setting.general", "hex.builtin.setting.general.prev_launch_version", ImHexApi::System::getImHexVersion()); }); + EventWindowDeinitializing::subscribe([](GLFWwindow *window) { + WorkspaceManager::exportToFile(); + if (auto workspace = WorkspaceManager::getCurrentWorkspace(); workspace != WorkspaceManager::getWorkspaces().end()) + ContentRegistry::Settings::write("hex.builtin.setting.general", "hex.builtin.setting.general.curr_workspace", workspace->first); + + { + int x = 0, y = 0, width = 0, height = 0, maximized = 0; + glfwGetWindowPos(window, &x, &y); + glfwGetWindowSize(window, &width, &height); + maximized = glfwGetWindowAttrib(window, GLFW_MAXIMIZED); + + ContentRegistry::Settings::write("hex.builtin.setting.interface", "hex.builtin.setting.interface.window.x", x); + ContentRegistry::Settings::write("hex.builtin.setting.interface", "hex.builtin.setting.interface.window.y", y); + ContentRegistry::Settings::write("hex.builtin.setting.interface", "hex.builtin.setting.interface.window.width", width); + ContentRegistry::Settings::write("hex.builtin.setting.interface", "hex.builtin.setting.interface.window.height", height); + ContentRegistry::Settings::write("hex.builtin.setting.interface", "hex.builtin.setting.interface.window.maximized", maximized); + } + }); + fs::setFileBrowserErrorCallback([](const std::string& errMsg){ #if defined(NFD_PORTAL) ui::PopupError::open(hex::format("hex.builtin.popup.error.file_dialog.portal"_lang, errMsg)); diff --git a/plugins/builtin/source/content/init_tasks.cpp b/plugins/builtin/source/content/init_tasks.cpp index 09c4c1db9..3c5d823ff 100644 --- a/plugins/builtin/source/content/init_tasks.cpp +++ b/plugins/builtin/source/content/init_tasks.cpp @@ -348,9 +348,31 @@ namespace hex::plugin::builtin { return loadFontsImpl(shouldLoadUnicode); } + bool loadWindowSettings() { + bool multiWindowEnabled = ContentRegistry::Settings::read("hex.builtin.setting.interface", "hex.builtin.setting.interface.multi_windows", false); + ImHexApi::System::impl::setMultiWindowMode(multiWindowEnabled); + + bool restoreWindowPos = ContentRegistry::Settings::read("hex.builtin.setting.interface", "hex.builtin.setting.interface.restore_window_pos", false); + + if (restoreWindowPos) { + ImHexApi::System::InitialWindowProperties properties = {}; + + properties.maximized = ContentRegistry::Settings::read("hex.builtin.setting.interface", "hex.builtin.setting.interface.window.maximized", 0).get(); + properties.x = ContentRegistry::Settings::read("hex.builtin.setting.interface", "hex.builtin.setting.interface.window.x", 0); + properties.y = ContentRegistry::Settings::read("hex.builtin.setting.interface", "hex.builtin.setting.interface.window.y", 0); + properties.width = ContentRegistry::Settings::read("hex.builtin.setting.interface", "hex.builtin.setting.interface.window.width", 0); + properties.height = ContentRegistry::Settings::read("hex.builtin.setting.interface", "hex.builtin.setting.interface.window.height", 0); + + ImHexApi::System::impl::setInitialWindowProperties(properties); + } + + return true; + } + } void addInitTasks() { + ImHexApi::System::addStartupTask("Load Window Settings", false, loadWindowSettings); ImHexApi::System::addStartupTask("Configuring UI scale", true, configureUIScale); ImHexApi::System::addStartupTask("Loading fonts", true, loadFonts); ImHexApi::System::addStartupTask("Checking for updates", true, checkForUpdates); diff --git a/plugins/builtin/source/content/popups/hex_editor/popup_hex_editor_find.cpp b/plugins/builtin/source/content/popups/hex_editor/popup_hex_editor_find.cpp index 93a110314..58e14e844 100644 --- a/plugins/builtin/source/content/popups/hex_editor/popup_hex_editor_find.cpp +++ b/plugins/builtin/source/content/popups/hex_editor/popup_hex_editor_find.cpp @@ -6,6 +6,8 @@ #include #include +#include + #include #include diff --git a/plugins/builtin/source/content/views/view_about.cpp b/plugins/builtin/source/content/views/view_about.cpp index 0be9e6c6a..9526a6da6 100644 --- a/plugins/builtin/source/content/views/view_about.cpp +++ b/plugins/builtin/source/content/views/view_about.cpp @@ -12,6 +12,8 @@ #include +#include + #include #include diff --git a/plugins/builtin/source/content/views/view_achievements.cpp b/plugins/builtin/source/content/views/view_achievements.cpp index f86163785..4edf59e24 100644 --- a/plugins/builtin/source/content/views/view_achievements.cpp +++ b/plugins/builtin/source/content/views/view_achievements.cpp @@ -3,9 +3,9 @@ #include #include -#include +#include -#include +#include namespace hex::plugin::builtin { diff --git a/plugins/builtin/source/content/views/view_bookmarks.cpp b/plugins/builtin/source/content/views/view_bookmarks.cpp index b769002ae..12363bc1e 100644 --- a/plugins/builtin/source/content/views/view_bookmarks.cpp +++ b/plugins/builtin/source/content/views/view_bookmarks.cpp @@ -6,10 +6,12 @@ #include #include #include - #include + #include +#include + #include #include diff --git a/plugins/builtin/source/content/views/view_constants.cpp b/plugins/builtin/source/content/views/view_constants.cpp index 26e4baffe..ea176fa88 100644 --- a/plugins/builtin/source/content/views/view_constants.cpp +++ b/plugins/builtin/source/content/views/view_constants.cpp @@ -10,6 +10,8 @@ #include #include +#include + namespace hex::plugin::builtin { ViewConstants::ViewConstants() : View::Window("hex.builtin.view.constants.name", ICON_VS_SYMBOL_CONSTANT) { diff --git a/plugins/builtin/source/content/views/view_data_inspector.cpp b/plugins/builtin/source/content/views/view_data_inspector.cpp index c7fc04726..994937e9a 100644 --- a/plugins/builtin/source/content/views/view_data_inspector.cpp +++ b/plugins/builtin/source/content/views/view_data_inspector.cpp @@ -7,6 +7,8 @@ #include #include +#include + #include #include diff --git a/plugins/builtin/source/content/views/view_find.cpp b/plugins/builtin/source/content/views/view_find.cpp index db7db1f4c..7e75cfee2 100644 --- a/plugins/builtin/source/content/views/view_find.cpp +++ b/plugins/builtin/source/content/views/view_find.cpp @@ -5,6 +5,8 @@ #include +#include + #include #include #include diff --git a/plugins/builtin/source/content/views/view_hex_editor.cpp b/plugins/builtin/source/content/views/view_hex_editor.cpp index d3e11003a..bbaff8248 100644 --- a/plugins/builtin/source/content/views/view_hex_editor.cpp +++ b/plugins/builtin/source/content/views/view_hex_editor.cpp @@ -13,12 +13,12 @@ #include #include + +#include + #include - -#include #include - -#include "content/popups/hex_editor/popup_hex_editor_find.hpp" +#include using namespace std::literals::string_literals; diff --git a/plugins/builtin/source/content/views/view_highlight_rules.cpp b/plugins/builtin/source/content/views/view_highlight_rules.cpp index 3e21472f0..7fe27f9a4 100644 --- a/plugins/builtin/source/content/views/view_highlight_rules.cpp +++ b/plugins/builtin/source/content/views/view_highlight_rules.cpp @@ -4,6 +4,8 @@ #include #include +#include + namespace hex::plugin::builtin { wolv::math_eval::MathEvaluator ViewHighlightRules::Rule::Expression::s_evaluator; diff --git a/plugins/builtin/source/content/views/view_logs.cpp b/plugins/builtin/source/content/views/view_logs.cpp index 2842c978f..9794083d3 100644 --- a/plugins/builtin/source/content/views/view_logs.cpp +++ b/plugins/builtin/source/content/views/view_logs.cpp @@ -3,6 +3,8 @@ #include #include +#include + namespace hex::plugin::builtin { ViewLogs::ViewLogs() : View::Floating("hex.builtin.view.logs.name") { diff --git a/plugins/builtin/source/content/views/view_pattern_data.cpp b/plugins/builtin/source/content/views/view_pattern_data.cpp index 25f3709cd..4d9010d57 100644 --- a/plugins/builtin/source/content/views/view_pattern_data.cpp +++ b/plugins/builtin/source/content/views/view_pattern_data.cpp @@ -1,9 +1,10 @@ #include #include - #include +#include + #include #include diff --git a/plugins/builtin/source/content/views/view_settings.cpp b/plugins/builtin/source/content/views/view_settings.cpp index c5a7dded1..723579de7 100644 --- a/plugins/builtin/source/content/views/view_settings.cpp +++ b/plugins/builtin/source/content/views/view_settings.cpp @@ -6,6 +6,7 @@ #include #include +#include namespace hex::plugin::builtin { diff --git a/plugins/builtin/source/content/views/view_theme_manager.cpp b/plugins/builtin/source/content/views/view_theme_manager.cpp index caa2d604d..cf349437c 100644 --- a/plugins/builtin/source/content/views/view_theme_manager.cpp +++ b/plugins/builtin/source/content/views/view_theme_manager.cpp @@ -4,6 +4,7 @@ #include #include +#include namespace hex::plugin::builtin { diff --git a/plugins/builtin/source/content/views/view_tools.cpp b/plugins/builtin/source/content/views/view_tools.cpp index 4e90f2caf..d26318224 100644 --- a/plugins/builtin/source/content/views/view_tools.cpp +++ b/plugins/builtin/source/content/views/view_tools.cpp @@ -3,6 +3,8 @@ #include +#include + namespace hex::plugin::builtin { ViewTools::ViewTools() : View::Window("hex.builtin.view.tools.name", ICON_VS_TOOLS) { diff --git a/plugins/builtin/source/content/views/view_tutorials.cpp b/plugins/builtin/source/content/views/view_tutorials.cpp index e16ecac6d..85c753088 100644 --- a/plugins/builtin/source/content/views/view_tutorials.cpp +++ b/plugins/builtin/source/content/views/view_tutorials.cpp @@ -3,6 +3,8 @@ #include #include +#include + #include namespace hex::plugin::builtin { diff --git a/plugins/builtin/source/content/window_decoration.cpp b/plugins/builtin/source/content/window_decoration.cpp new file mode 100644 index 000000000..8983783bb --- /dev/null +++ b/plugins/builtin/source/content/window_decoration.cpp @@ -0,0 +1,438 @@ +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include + +namespace hex::plugin::builtin { + + namespace { + + std::string s_windowTitle, s_windowTitleFull; + u32 s_searchBarPosition = 0; + ImGuiExt::Texture s_logoTexture; + + void createNestedMenu(std::span menuItems, const char *icon, const Shortcut &shortcut, const ContentRegistry::Interface::impl::MenuCallback &callback, const ContentRegistry::Interface::impl::EnabledCallback &enabledCallback, const ContentRegistry::Interface::impl::SelectedCallback &selectedCallback) { + const auto &name = menuItems.front(); + + if (name.get() == ContentRegistry::Interface::impl::SeparatorValue) { + ImGui::Separator(); + return; + } + + if (name.get() == ContentRegistry::Interface::impl::SubMenuValue) { + callback(); + } else if (menuItems.size() == 1) { + if (ImGui::MenuItemEx(Lang(name), icon, shortcut.toString().c_str(), selectedCallback(), enabledCallback())) + callback(); + } else { + bool isSubmenu = (menuItems.begin() + 1)->get() == ContentRegistry::Interface::impl::SubMenuValue; + + if (ImGui::BeginMenuEx(Lang(name), std::next(menuItems.begin())->get() == ContentRegistry::Interface::impl::SubMenuValue ? icon : nullptr, isSubmenu ? enabledCallback() : true)) { + createNestedMenu({ std::next(menuItems.begin()), menuItems.end() }, icon, shortcut, callback, enabledCallback, selectedCallback); + ImGui::EndMenu(); + } + } + } + + void drawFooter(ImDrawList *drawList, ImVec2 dockSpaceSize, float footerHeight) { + auto dockId = ImGui::DockSpace(ImGui::GetID("ImHexMainDock"), dockSpaceSize); + ImHexApi::System::impl::setMainDockSpaceId(dockId); + + drawList->AddRectFilled(ImGui::GetWindowPos(), ImGui::GetWindowPos() + ImGui::GetWindowSize() - ImVec2(dockSpaceSize.x, footerHeight - ImGui::GetStyle().FramePadding.y - 1_scaled), ImGui::GetColorU32(ImGuiCol_MenuBarBg)); + + ImGui::Separator(); + ImGui::SetCursorPosX(8); + for (const auto &callback : ContentRegistry::Interface::impl::getFooterItems()) { + auto prevIdx = drawList->_VtxCurrentIdx; + callback(); + auto currIdx = drawList->_VtxCurrentIdx; + + // Only draw separator if something was actually drawn + if (prevIdx != currIdx) { + ImGui::SameLine(); + ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical); + ImGui::SameLine(); + } + } + } + + void drawSidebar(ImVec2 dockSpaceSize, ImVec2 sidebarPos, float sidebarWidth) { + static i32 openWindow = -1; + u32 index = 0; + ImGui::PushID("SideBarWindows"); + for (const auto &[icon, callback, enabledCallback] : ContentRegistry::Interface::impl::getSidebarItems()) { + ImGui::SetCursorPosY(sidebarPos.y + sidebarWidth * index); + + ImGui::PushStyleColor(ImGuiCol_Button, ImGui::GetColorU32(ImGuiCol_MenuBarBg)); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImGui::GetColorU32(ImGuiCol_ScrollbarGrabActive)); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImGui::GetColorU32(ImGuiCol_ScrollbarGrabHovered)); + + ImGui::BeginDisabled(!(ImHexApi::Provider::isValid() && enabledCallback())); + { + if (ImGui::Button(icon.c_str(), ImVec2(sidebarWidth, sidebarWidth))) { + if (static_cast(openWindow) == index) + openWindow = -1; + else + openWindow = index; + } + } + ImGui::EndDisabled(); + + ImGui::PopStyleColor(3); + + auto sideBarFocused = ImGui::IsWindowFocused(); + + bool open = static_cast(openWindow) == index; + if (open) { + + ImGui::SetNextWindowPos(ImGui::GetWindowPos() + sidebarPos + ImVec2(sidebarWidth - 1_scaled, -1_scaled)); + ImGui::SetNextWindowSize(ImVec2(0, dockSpaceSize.y + 5_scaled)); + + ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 1); + ImGui::PushStyleColor(ImGuiCol_WindowShadow, 0x00000000); + if (ImGui::Begin("SideBarWindow", &open, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse)) { + if (ImGui::BeginChild("##Content", ImVec2(), ImGuiChildFlags_ResizeX)) { + callback(); + } + ImGui::EndChild(); + + if (!ImGui::IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows) && !sideBarFocused) { + openWindow = -1; + } + } + ImGui::End(); + ImGui::PopStyleVar(); + ImGui::PopStyleColor(); + } + + ImGui::NewLine(); + index++; + } + ImGui::PopID(); + } + + void drawTitleBar() { + auto titleBarHeight = ImGui::GetCurrentWindowRead()->MenuBarHeight(); + auto buttonSize = ImVec2(titleBarHeight * 1.5F, titleBarHeight - 1); + + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0)); + ImGui::PushStyleColor(ImGuiCol_Button, ImGui::GetColorU32(ImGuiCol_MenuBarBg)); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImGui::GetColorU32(ImGuiCol_ScrollbarGrabActive)); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImGui::GetColorU32(ImGuiCol_ScrollbarGrabHovered)); + + const auto windowSize = ImHexApi::System::getMainWindowSize(); + const auto searchBoxSize = ImVec2(windowSize.x / 2.5, titleBarHeight - 3_scaled); + const auto searchBoxPos = ImVec2((windowSize / 2 - searchBoxSize / 2).x, 3_scaled); + + s_searchBarPosition = searchBoxPos.x; + + // Custom titlebar buttons implementation for borderless window mode + auto &titleBarButtons = ContentRegistry::Interface::impl::getTitleBarButtons(); + + // Draw custom title bar buttons + if (!titleBarButtons.empty()) { + ImGui::SetCursorPosX(ImGui::GetWindowWidth() - buttonSize.x * float(4 + titleBarButtons.size())); + + if (ImGui::GetCursorPosX() > (searchBoxPos.x + searchBoxSize.x)) { + for (const auto &[icon, tooltip, callback]: titleBarButtons) { + if (ImGuiExt::TitleBarButton(icon.c_str(), buttonSize)) { + callback(); + } + ImGuiExt::InfoTooltip(Lang(tooltip)); + } + } + } + + auto window = ImHexApi::System::getMainWindowHandle(); + if (ImHexApi::System::isBorderlessWindowModeEnabled() && glfwGetWindowMonitor(window) == nullptr) { + // Draw minimize, restore and maximize buttons + ImGui::SetCursorPosX(ImGui::GetWindowWidth() - buttonSize.x * 3); + if (ImGuiExt::TitleBarButton(ICON_VS_CHROME_MINIMIZE, buttonSize)) + glfwIconifyWindow(window); + if (glfwGetWindowAttrib(window, GLFW_MAXIMIZED)) { + if (ImGuiExt::TitleBarButton(ICON_VS_CHROME_RESTORE, buttonSize)) + glfwRestoreWindow(window); + } else { + if (ImGuiExt::TitleBarButton(ICON_VS_CHROME_MAXIMIZE, buttonSize)) + glfwMaximizeWindow(window); + } + + ImGui::PushStyleColor(ImGuiCol_ButtonActive, 0xFF7A70F1); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, 0xFF2311E8); + + // Draw close button + if (ImGuiExt::TitleBarButton(ICON_VS_CHROME_CLOSE, buttonSize)) { + ImHexApi::System::closeImHex(); + } + + ImGui::PopStyleColor(2); + } + + ImGui::PopStyleColor(3); + ImGui::PopStyleVar(); + + { + const auto buttonColor = [](float alpha) { + return ImU32(ImColor(ImGui::GetStyleColorVec4(ImGuiCol_DockingEmptyBg) * ImVec4(1, 1, 1, alpha))); + }; + + ImGui::PushStyleColor(ImGuiCol_Button, buttonColor(0.5F)); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, buttonColor(0.7F)); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, buttonColor(0.9F)); + ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0_scaled); + ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 4_scaled); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, scaled({ 1, 1 })); + + ImGui::SetCursorPos(searchBoxPos); + if (ImGui::Button(s_windowTitle.c_str(), searchBoxSize)) { + EventSearchBoxClicked::post(ImGuiMouseButton_Left); + } + + if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) + EventSearchBoxClicked::post(ImGuiMouseButton_Right); + + ImGui::PushTextWrapPos(300_scaled); + if (!s_windowTitleFull.empty()) + ImGui::SetItemTooltip("%s", s_windowTitleFull.c_str()); + ImGui::PopTextWrapPos(); + + ImGui::PopStyleVar(3); + ImGui::PopStyleColor(3); + } + } + + void drawMainMenu(float menuBarHeight) { + ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0F); + ImGui::SetNextWindowScroll(ImVec2(0, 0)); + if (ImGui::BeginMainMenuBar()) { + + if (ImHexApi::System::isBorderlessWindowModeEnabled()) { + ImGui::SetCursorPosX(5); + + ImGui::Image(s_logoTexture, ImVec2(menuBarHeight, menuBarHeight)); + ImGui::SetCursorPosX(5); + ImGui::InvisibleButton("##logo", ImVec2(menuBarHeight, menuBarHeight)); + ImGui::OpenPopupOnItemClick("WindowingMenu", ImGuiPopupFlags_MouseButtonLeft); + } + + if (ImGui::BeginPopup("WindowingMenu")) { + auto window = ImHexApi::System::getMainWindowHandle(); + bool maximized = glfwGetWindowAttrib(window, GLFW_MAXIMIZED); + + ImGui::BeginDisabled(!maximized); + if (ImGui::MenuItem(ICON_VS_CHROME_RESTORE " Restore")) glfwRestoreWindow(window); + ImGui::EndDisabled(); + + if (ImGui::MenuItem(ICON_VS_CHROME_MINIMIZE " Minimize")) glfwIconifyWindow(window); + + ImGui::BeginDisabled(maximized); + if (ImGui::MenuItem(ICON_VS_CHROME_MAXIMIZE " Maximize")) glfwMaximizeWindow(window); + ImGui::EndDisabled(); + + ImGui::Separator(); + + if (ImGui::MenuItem(ICON_VS_CHROME_CLOSE " Close")) ImHexApi::System::closeImHex(); + + ImGui::EndPopup(); + } + + const static auto drawMenu = [] { + for (const auto &[priority, menuItem] : ContentRegistry::Interface::impl::getMainMenuItems()) { + ImGui::GetStyle().TouchExtraPadding = scaled(ImVec2(0, 2)); + if (ImGui::BeginMenu(Lang(menuItem.unlocalizedName))) { + ImGui::EndMenu(); + } + ImGui::GetStyle().TouchExtraPadding = ImVec2(0, 0); + } + + for (auto &[priority, menuItem] : ContentRegistry::Interface::impl::getMenuItems()) { + const auto &[unlocalizedNames, icon, shortcut, view, callback, enabledCallback, selectedCallack, toolbarIndex] = menuItem; + + createNestedMenu(unlocalizedNames, icon.glyph.c_str(), *shortcut, callback, enabledCallback, selectedCallack); + } + }; + + if (ImHexApi::System::getLastFrameTime() > 0) { + static u32 menuEndPos = 0; + if (menuEndPos < s_searchBarPosition) { + drawMenu(); + menuEndPos = ImGui::GetCursorPosX(); + } else { + if (ImGui::BeginMenu(ICON_VS_MENU)) { + drawMenu(); + ImGui::EndMenu(); + } + } + } + + drawTitleBar(); + + ImGui::EndMainMenuBar(); + } + ImGui::PopStyleVar(); + } + + void drawToolbar() { + if (ImGui::BeginMenuBar()) { + for (const auto &callback : ContentRegistry::Interface::impl::getToolbarItems()) { + callback(); + ImGui::SameLine(); + } + + if (auto provider = ImHexApi::Provider::get(); provider != nullptr) { + ImGui::BeginDisabled(TaskManager::getRunningTaskCount() > 0); + if (ImGui::CloseButton(ImGui::GetID("ProviderCloseButton"), ImGui::GetCursorScreenPos() + ImVec2(ImGui::GetContentRegionAvail().x - 17_scaled, 3_scaled))) { + ImHexApi::Provider::remove(provider); + } + ImGui::EndDisabled(); + } + + ImGui::EndMenuBar(); + } + } + + bool anySidebarItemsAvailable() { + if (const auto &items = ContentRegistry::Interface::impl::getSidebarItems(); items.empty()) { + return false; + } else { + return std::any_of(items.begin(), items.end(), [](const auto &item) { + return item.enabledCallback(); + }); + } + } + + bool isAnyViewOpen() { + const auto &views = ContentRegistry::Views::impl::getEntries(); + return std::any_of(views.begin(), views.end(), + [](const auto &entry) { + return entry.second->getWindowOpenState(); + }); + } + + } + + void addWindowDecoration() { + EventFrameBegin::subscribe([]{ + AT_FIRST_TIME { + s_logoTexture = ImGuiExt::Texture(romfs::get("assets/common/icon.png").span(), ImGuiExt::Texture::Filter::Nearest); + }; + + constexpr static ImGuiWindowFlags windowFlags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoNavFocus | ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse; + + // Handle all undocked floating windows + ImGuiViewport *viewport = ImGui::GetMainViewport(); + ImGui::SetNextWindowPos(viewport->WorkPos); + ImGui::SetNextWindowSize(ImHexApi::System::getMainWindowSize() - ImVec2(0, ImGui::GetTextLineHeightWithSpacing())); + ImGui::SetNextWindowViewport(viewport->ID); + ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0F); + ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0F); + ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0)); + + // Draw main window decoration + if (ImGui::Begin("ImHexDockSpace", nullptr, windowFlags)) { + ImGui::PopStyleVar(); + + const auto drawList = ImGui::GetWindowDrawList(); + const auto shouldDrawSidebar = anySidebarItemsAvailable(); + + const auto menuBarHeight = ImGui::GetCurrentWindowRead()->MenuBarHeight(); + const auto sidebarPos = ImGui::GetCursorPos(); + const auto sidebarWidth = shouldDrawSidebar ? 20_scaled : 0; + + const auto footerHeight = ImGui::GetTextLineHeightWithSpacing() + ImGui::GetStyle().FramePadding.y * 2 + 1_scaled; + const auto dockSpaceSize = ImVec2(ImHexApi::System::getMainWindowSize().x - sidebarWidth, ImGui::GetContentRegionAvail().y - footerHeight); + + ImGui::SetCursorPosX(sidebarWidth); + drawFooter(drawList, dockSpaceSize, footerHeight); + + if (shouldDrawSidebar) { + ImGui::SetCursorPos(sidebarPos); + drawSidebar(dockSpaceSize, sidebarPos, sidebarWidth); + } + + drawMainMenu(menuBarHeight); + drawToolbar(); + + if (ImHexApi::Provider::isValid() && isAnyViewOpen()) { + drawList->AddLine( + ImGui::GetWindowPos() + sidebarPos + ImVec2(sidebarWidth - 1_scaled, -2_scaled), + ImGui::GetWindowPos() + sidebarPos + ImGui::GetWindowSize() - ImVec2(dockSpaceSize.x + 1_scaled, footerHeight - ImGui::GetStyle().FramePadding.y - 1_scaled + menuBarHeight), + ImGui::GetColorU32(ImGuiCol_Separator)); + } + } else { + ImGui::PopStyleVar(); + } + ImGui::End(); + + ImGui::PopStyleVar(2); + + // Draw main menu popups + for (auto &[priority, menuItem] : ContentRegistry::Interface::impl::getMenuItems()) { + const auto &[unlocalizedNames, icon, shortcut, view, callback, enabledCallback, selectedCallback, toolbarIndex] = menuItem; + + if (ImGui::BeginPopup(unlocalizedNames.front().get().c_str())) { + createNestedMenu({ unlocalizedNames.begin() + 1, unlocalizedNames.end() }, icon.glyph.c_str(), *shortcut, callback, enabledCallback, selectedCallback); + ImGui::EndPopup(); + } + } + }); + + + constexpr static auto ImHexTitle = "ImHex"; + + s_windowTitle = ImHexTitle; + + // Handle updating the window title + RequestUpdateWindowTitle::subscribe([] { + std::string prefix, postfix; + std::string title = ImHexTitle; + + if (ProjectFile::hasPath()) { + // If a project is open, show the project name instead of the file name + + prefix = "Project "; + title = ProjectFile::getPath().stem().string(); + + if (ImHexApi::Provider::isDirty()) + postfix += " (*)"; + + } else if (ImHexApi::Provider::isValid()) { + auto provider = ImHexApi::Provider::get(); + if (provider != nullptr) { + title = provider->getName(); + + if (provider->isDirty()) + postfix += " (*)"; + + if (!provider->isWritable() && provider->getActualSize() != 0) + postfix += " (Read Only)"; + } + } + + s_windowTitle = prefix + hex::limitStringLength(title, 32) + postfix; + s_windowTitleFull = prefix + title + postfix; + + auto window = ImHexApi::System::getMainWindowHandle(); + if (window != nullptr) { + if (title != ImHexTitle) + title = std::string(ImHexTitle) + " - " + title; + + glfwSetWindowTitle(window, title.c_str()); + } + }); + } + + +} diff --git a/plugins/builtin/source/plugin_builtin.cpp b/plugins/builtin/source/plugin_builtin.cpp index d0ce1f678..02b7305a1 100644 --- a/plugins/builtin/source/plugin_builtin.cpp +++ b/plugins/builtin/source/plugin_builtin.cpp @@ -1,6 +1,7 @@ #include #include +#include #include #include @@ -41,12 +42,12 @@ namespace hex::plugin::builtin { void registerTutorials(); void loadWorkspaces(); + void addWindowDecoration(); void addFooterItems(); void addTitleBarButtons(); void addToolbarItems(); void addGlobalUIItems(); void addInitTasks(); - void loadFonts(); void handleBorderlessWindowMode(); void setupOutOfBoxExperience(); @@ -80,7 +81,6 @@ IMHEX_PLUGIN_SETUP("Built-in", "WerWolv", "Default ImHex functionality") { hex::ContentRegistry::Language::addLocalization(nlohmann::json::parse(romfs::get(path).string())); addInitTasks(); - loadFonts(); extractBundledFiles(); registerMainMenuEntries(); @@ -100,7 +100,6 @@ IMHEX_PLUGIN_SETUP("Built-in", "WerWolv", "Default ImHex functionality") { registerDataProcessorNodes(); registerProviders(); registerDataFormatters(); - createWelcomeScreen(); registerViews(); registerThemeHandlers(); registerStyleHandlers(); @@ -113,6 +112,8 @@ IMHEX_PLUGIN_SETUP("Built-in", "WerWolv", "Default ImHex functionality") { registerReportGenerators(); registerTutorials(); loadWorkspaces(); + addWindowDecoration(); + createWelcomeScreen(); addFooterItems(); addTitleBarButtons(); diff --git a/plugins/decompress/CMakeLists.txt b/plugins/decompress/CMakeLists.txt index b0a5d2975..23372426c 100644 --- a/plugins/decompress/CMakeLists.txt +++ b/plugins/decompress/CMakeLists.txt @@ -25,6 +25,7 @@ add_imhex_plugin( include LIBRARIES ui + fonts FEATURES ZLIB BZIP2 diff --git a/plugins/diffing/CMakeLists.txt b/plugins/diffing/CMakeLists.txt index d03e06200..f228fe0d5 100644 --- a/plugins/diffing/CMakeLists.txt +++ b/plugins/diffing/CMakeLists.txt @@ -24,5 +24,6 @@ add_imhex_plugin( include LIBRARIES ui + fonts edlib ) \ No newline at end of file diff --git a/plugins/diffing/source/content/views/view_diff.cpp b/plugins/diffing/source/content/views/view_diff.cpp index e86bb7051..d84b61025 100644 --- a/plugins/diffing/source/content/views/view_diff.cpp +++ b/plugins/diffing/source/content/views/view_diff.cpp @@ -4,6 +4,8 @@ #include #include + +#include #include namespace hex::plugin::diffing { diff --git a/plugins/disassembler/CMakeLists.txt b/plugins/disassembler/CMakeLists.txt index 996d282bf..2347186e6 100644 --- a/plugins/disassembler/CMakeLists.txt +++ b/plugins/disassembler/CMakeLists.txt @@ -28,6 +28,7 @@ add_imhex_plugin( include ${CAPSTONE_INCLUDE_DIR} LIBRARIES - ${CAPSTONE_LIBRARY} ui + fonts + ${CAPSTONE_LIBRARY} ) diff --git a/plugins/disassembler/source/content/views/view_disassembler.cpp b/plugins/disassembler/source/content/views/view_disassembler.cpp index c2308de46..c63b75931 100644 --- a/plugins/disassembler/source/content/views/view_disassembler.cpp +++ b/plugins/disassembler/source/content/views/view_disassembler.cpp @@ -3,6 +3,8 @@ #include #include +#include + #include using namespace std::literals::string_literals; diff --git a/plugins/fonts/CMakeLists.txt b/plugins/fonts/CMakeLists.txt new file mode 100644 index 000000000..cb76d2a11 --- /dev/null +++ b/plugins/fonts/CMakeLists.txt @@ -0,0 +1,14 @@ +cmake_minimum_required(VERSION 3.16) + +include(ImHexPlugin) + +add_imhex_plugin( + NAME + fonts + SOURCES + source/library_fonts.cpp + source/fonts.cpp + INCLUDES + include + LIBRARY_PLUGIN +) diff --git a/plugins/fonts/LICENSE b/plugins/fonts/LICENSE new file mode 100644 index 000000000..4362b4915 --- /dev/null +++ b/plugins/fonts/LICENSE @@ -0,0 +1,502 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/lib/third_party/imgui/fonts/include/fonts/blendericons_font.h b/plugins/fonts/include/fonts/blendericons_font.h similarity index 100% rename from lib/third_party/imgui/fonts/include/fonts/blendericons_font.h rename to plugins/fonts/include/fonts/blendericons_font.h diff --git a/lib/third_party/imgui/fonts/include/fonts/codicons_font.h b/plugins/fonts/include/fonts/codicons_font.h similarity index 100% rename from lib/third_party/imgui/fonts/include/fonts/codicons_font.h rename to plugins/fonts/include/fonts/codicons_font.h diff --git a/lib/third_party/imgui/fonts/include/fonts/unifont_font.h b/plugins/fonts/include/fonts/unifont_font.h similarity index 100% rename from lib/third_party/imgui/fonts/include/fonts/unifont_font.h rename to plugins/fonts/include/fonts/unifont_font.h diff --git a/lib/third_party/imgui/fonts/UNIFONT_LICENSE.txt b/plugins/fonts/romfs/UNIFONT_LICENSE.txt similarity index 100% rename from lib/third_party/imgui/fonts/UNIFONT_LICENSE.txt rename to plugins/fonts/romfs/UNIFONT_LICENSE.txt diff --git a/lib/third_party/imgui/fonts/VSCODICONS_LICENSE.txt b/plugins/fonts/romfs/VSCODICONS_LICENSE.txt similarity index 100% rename from lib/third_party/imgui/fonts/VSCODICONS_LICENSE.txt rename to plugins/fonts/romfs/VSCODICONS_LICENSE.txt diff --git a/plugins/builtin/romfs/fonts/blendericons.ttf b/plugins/fonts/romfs/fonts/blendericons.ttf similarity index 100% rename from plugins/builtin/romfs/fonts/blendericons.ttf rename to plugins/fonts/romfs/fonts/blendericons.ttf diff --git a/plugins/builtin/romfs/fonts/codicons.ttf b/plugins/fonts/romfs/fonts/codicons.ttf similarity index 100% rename from plugins/builtin/romfs/fonts/codicons.ttf rename to plugins/fonts/romfs/fonts/codicons.ttf diff --git a/plugins/builtin/romfs/fonts/unifont.otf b/plugins/fonts/romfs/fonts/unifont.otf similarity index 100% rename from plugins/builtin/romfs/fonts/unifont.otf rename to plugins/fonts/romfs/fonts/unifont.otf diff --git a/plugins/builtin/source/content/fonts.cpp b/plugins/fonts/source/fonts.cpp similarity index 96% rename from plugins/builtin/source/content/fonts.cpp rename to plugins/fonts/source/fonts.cpp index 97e3961da..8c7af8ec9 100644 --- a/plugins/builtin/source/content/fonts.cpp +++ b/plugins/fonts/source/fonts.cpp @@ -7,7 +7,7 @@ #include #include -namespace hex::plugin::builtin { +namespace hex::fonts { void loadFonts() { using namespace ImHexApi::Fonts; diff --git a/plugins/fonts/source/library_fonts.cpp b/plugins/fonts/source/library_fonts.cpp new file mode 100644 index 000000000..ceee11f02 --- /dev/null +++ b/plugins/fonts/source/library_fonts.cpp @@ -0,0 +1,16 @@ +#include + +#include +#include + +#include + +namespace hex::fonts { + void loadFonts(); +} + +IMHEX_LIBRARY_SETUP("Fonts") { + hex::log::debug("Using romfs: '{}'", romfs::name()); + + hex::fonts::loadFonts(); +} \ No newline at end of file diff --git a/plugins/hashes/CMakeLists.txt b/plugins/hashes/CMakeLists.txt index d4044a0f5..7bad19fdb 100644 --- a/plugins/hashes/CMakeLists.txt +++ b/plugins/hashes/CMakeLists.txt @@ -16,7 +16,7 @@ add_imhex_plugin( source/content/views/view_hashes.cpp INCLUDES include - LIBRARIES + fonts hashplus ) diff --git a/plugins/hashes/source/content/views/view_hashes.cpp b/plugins/hashes/source/content/views/view_hashes.cpp index 4f27f0569..150ebaea5 100644 --- a/plugins/hashes/source/content/views/view_hashes.cpp +++ b/plugins/hashes/source/content/views/view_hashes.cpp @@ -4,9 +4,11 @@ #include #include -#include #include +#include +#include + #include namespace hex::plugin::hashes { diff --git a/plugins/script_loader/CMakeLists.txt b/plugins/script_loader/CMakeLists.txt index 521cc86b7..af0f6c79c 100644 --- a/plugins/script_loader/CMakeLists.txt +++ b/plugins/script_loader/CMakeLists.txt @@ -14,6 +14,7 @@ add_imhex_plugin( include LIBRARIES + fonts ui ) diff --git a/plugins/ui/CMakeLists.txt b/plugins/ui/CMakeLists.txt index 3cf1345e8..cad681bc6 100644 --- a/plugins/ui/CMakeLists.txt +++ b/plugins/ui/CMakeLists.txt @@ -14,5 +14,6 @@ add_imhex_plugin( include LIBRARIES libpl-gen + fonts LIBRARY_PLUGIN ) diff --git a/plugins/ui/source/ui/hex_editor.cpp b/plugins/ui/source/ui/hex_editor.cpp index 4f1d0f4a3..01d803d80 100644 --- a/plugins/ui/source/ui/hex_editor.cpp +++ b/plugins/ui/source/ui/hex_editor.cpp @@ -5,8 +5,11 @@ #include #include + #include +#include + namespace hex::ui { /* Data Visualizer */ diff --git a/plugins/visualizers/CMakeLists.txt b/plugins/visualizers/CMakeLists.txt index c7b4b4468..b64ef7bcb 100644 --- a/plugins/visualizers/CMakeLists.txt +++ b/plugins/visualizers/CMakeLists.txt @@ -33,4 +33,6 @@ add_imhex_plugin( LIBRARIES ${JTHREAD_LIBRARIES} ${MINIAUDIO_LIBRARIES} + LIBRARIES + fonts ) diff --git a/plugins/windows/CMakeLists.txt b/plugins/windows/CMakeLists.txt index bac86b895..306c22515 100644 --- a/plugins/windows/CMakeLists.txt +++ b/plugins/windows/CMakeLists.txt @@ -17,6 +17,7 @@ if (WIN32) include LIBRARIES ui + fonts ${JTHREAD_LIBRARIES} ) diff --git a/plugins/yara_rules/CMakeLists.txt b/plugins/yara_rules/CMakeLists.txt index 092b9b16b..8e7801578 100644 --- a/plugins/yara_rules/CMakeLists.txt +++ b/plugins/yara_rules/CMakeLists.txt @@ -22,6 +22,7 @@ add_imhex_plugin( ${YARA_INCLUDE_DIRS} LIBRARIES ui + fonts ${JTHREAD_LIBRARIES} ${YARA_LIBRARIES} ) diff --git a/resources/projects/icon.xcf b/resources/projects/icon.xcf new file mode 100644 index 0000000000000000000000000000000000000000..b749c7d2039839066eda7310339fa481dc2ff06a GIT binary patch literal 1453 zcmc&yO>Wab7>)BopruT}z{V_wKPg>U%ACLwT_6@nT)}l5*O1ti?LfVPD|FL4AaN6K zde zO)v7tPKW)LQhuSyswe9$U z$HfRLy{8&s&I3Q;e&AfWF})E^Cb66FYQ4g1dVevUSt;$SA|#b}OW968*v>aE3gSOp_VCtOPcO zB9^ttGQ-HSuAyZM)iB!ZFZ`ohtNkG;LYp1xwe0uN>=-))95CI~E#$Y5pKqCEG2Y8d zV8a!$tVN!4p66Yz-r=9m8f0aAV9 literal 0 HcmV?d00001