From 48af5eb10a61b5d84dddaa1ec1dfbe7935990c82 Mon Sep 17 00:00:00 2001 From: WerWolv Date: Sat, 16 Aug 2025 11:49:35 +0200 Subject: [PATCH] impr: Modernize disassembler view --- .../content/views/view_disassembler.hpp | 1 + .../content/views/view_disassembler.cpp | 118 +++++++++++------- 2 files changed, 72 insertions(+), 47 deletions(-) diff --git a/plugins/disassembler/include/content/views/view_disassembler.hpp b/plugins/disassembler/include/content/views/view_disassembler.hpp index ebc611d0e..60c0328d7 100644 --- a/plugins/disassembler/include/content/views/view_disassembler.hpp +++ b/plugins/disassembler/include/content/views/view_disassembler.hpp @@ -31,6 +31,7 @@ namespace hex::plugin::disasm { PerProvider> m_currArchitecture; PerProvider> m_disassembly; + PerProvider m_settingsCollapsed; void disassemble(); void exportToFile(); diff --git a/plugins/disassembler/source/content/views/view_disassembler.cpp b/plugins/disassembler/source/content/views/view_disassembler.cpp index b65809492..26a03515d 100644 --- a/plugins/disassembler/source/content/views/view_disassembler.cpp +++ b/plugins/disassembler/source/content/views/view_disassembler.cpp @@ -7,6 +7,7 @@ #include #include +#include #include @@ -33,6 +34,8 @@ namespace hex::plugin::disasm { }, [this]{ return ImHexApi::HexEditor::isSelectionValid() && !m_disassemblerTask.isRunning() && *m_currArchitecture != nullptr; }, ContentRegistry::Views::getViewByName("hex.builtin.view.hex_editor.name")); + + m_settingsCollapsed.setOnCreateCallback([](auto *, bool &value) { value = false; }); } ViewDisassembler::~ViewDisassembler() { @@ -59,6 +62,10 @@ namespace hex::plugin::disasm { if (currArchitecture->start()) { ON_SCOPE_EXIT { currArchitecture->end(); + + if (!disassembly.empty()) { + TaskManager::doLater([this, provider]{ m_settingsCollapsed.get(provider) = true; }); + } }; std::vector buffer(1_MiB, 0x00); @@ -138,69 +145,82 @@ namespace hex::plugin::disasm { } void ViewDisassembler::drawContent() { - auto provider = ImHexApi::Provider::get(); + auto *provider = ImHexApi::Provider::get(); + if (ImHexApi::Provider::isValid() && provider->isReadable()) { auto ®ion = m_regionToDisassemble.get(provider); auto &range = m_range.get(provider); - ImGui::BeginDisabled(m_disassemblerTask.isRunning()); - { - // Draw region selection picker - ui::regionSelectionPicker(®ion, provider, &range, true, true); - - ImGuiExt::Header("hex.disassembler.view.disassembler.position"_lang); - - // Draw base address input + auto &collapsed = m_settingsCollapsed.get(provider); + ImGui::SetNextWindowScroll(ImVec2(0, 0)); + if (ImGuiExt::BeginSubWindow("hex.ui.common.settings"_lang, &collapsed, collapsed ? ImVec2(0, 1) : ImVec2(0, 0))) { + ImGui::BeginDisabled(m_disassemblerTask.isRunning()); { - auto &address = m_imageLoadAddress.get(provider); - ImGuiExt::InputHexadecimal("hex.disassembler.view.disassembler.image_load_address"_lang, &address, ImGuiInputTextFlags_CharsHexadecimal); + // Draw region selection picker + ui::regionSelectionPicker(®ion, provider, &range, false, true); + ImGui::SameLine(); - ImGuiExt::HelpHover("hex.disassembler.view.disassembler.image_load_address.hint"_lang, ICON_VS_INFO); - } - - // Draw code region start address input - ImGui::BeginDisabled(m_range == ui::RegionType::EntireData); - { - auto &address = m_imageBaseAddress.get(provider); - ImGuiExt::InputHexadecimal("hex.disassembler.view.disassembler.image_base_address"_lang, &address, ImGuiInputTextFlags_CharsHexadecimal); + ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical); ImGui::SameLine(); - ImGuiExt::HelpHover("hex.disassembler.view.disassembler.image_base_address.hint"_lang, ICON_VS_INFO); - } - ImGui::EndDisabled(); - // Draw settings - { - ImGuiExt::Header("hex.ui.common.settings"_lang); + // Draw base address input + ImGui::BeginGroup(); + { + auto &address = m_imageLoadAddress.get(provider); + ImGuiExt::InputHexadecimal("hex.disassembler.view.disassembler.image_load_address"_lang, &address, ImGuiInputTextFlags_CharsHexadecimal); + ImGui::SameLine(); + ImGuiExt::HelpHover("hex.disassembler.view.disassembler.image_load_address.hint"_lang, ICON_VS_INFO); + } - // Draw architecture selector - const auto &architectures = ContentRegistry::Disassemblers::impl::getArchitectures(); - if (architectures.empty()) { - ImGuiExt::TextSpinner("hex.disassembler.view.disassembler.arch"_lang); - } else { - const auto &currArchitecture = m_currArchitecture.get(provider); - if (currArchitecture == nullptr) { - m_currArchitecture = architectures.begin()->second(); - } + // Draw code region start address input + ImGui::BeginDisabled(m_range == ui::RegionType::EntireData); + { + auto &address = m_imageBaseAddress.get(provider); + ImGuiExt::InputHexadecimal("hex.disassembler.view.disassembler.image_base_address"_lang, &address, ImGuiInputTextFlags_CharsHexadecimal); + ImGui::SameLine(); + ImGuiExt::HelpHover("hex.disassembler.view.disassembler.image_base_address.hint"_lang, ICON_VS_INFO); + } + ImGui::EndDisabled(); + ImGui::EndGroup(); - if (ImGui::BeginCombo("hex.disassembler.view.disassembler.arch"_lang, currArchitecture->getName().c_str())) { - for (const auto &[name, creator] : architectures) { - if (ImGui::Selectable(name.c_str(), name == currArchitecture->getName())) { - m_currArchitecture = creator(); - } + // Draw settings + { + ImGui::Separator(); + + // Draw architecture selector + const auto &architectures = ContentRegistry::Disassemblers::impl::getArchitectures(); + if (architectures.empty()) { + ImGuiExt::TextSpinner("hex.disassembler.view.disassembler.arch"_lang); + } else { + const auto &currArchitecture = m_currArchitecture.get(provider); + if (currArchitecture == nullptr) { + m_currArchitecture = architectures.begin()->second(); } - ImGui::EndCombo(); - } - // Draw sub-settings for each architecture - if (ImGuiExt::BeginBox()) { - currArchitecture->drawSettings(); + if (ImGui::BeginTabBar("Architecture", ImGuiTabBarFlags_FittingPolicyScroll | ImGuiTabBarFlags_DrawSelectedOverline)) { + for (const auto &[name, creator] : architectures) { + if (ImGui::BeginTabItem(name.c_str())) { + if (m_currArchitecture->get()->getName() != name) { + m_currArchitecture = creator(); + } + + ImGui::EndTabItem(); + } + } + ImGui::EndTabBar(); + } + + // Draw sub-settings for each architecture + if (ImGuiExt::BeginBox()) { + currArchitecture->drawSettings(); + } + ImGuiExt::EndBox(); } - ImGuiExt::EndBox(); } } + ImGui::EndDisabled(); } - ImGui::EndDisabled(); - + ImGuiExt::EndSubWindow(); // Draw disassemble button ImGui::BeginDisabled(m_disassemblerTask.isRunning() || region.getStartAddress() < m_imageBaseAddress); @@ -224,6 +244,10 @@ namespace hex::plugin::disasm { // Draw a spinner if the disassembler is running if (m_disassemblerTask.isRunning()) { + ImGui::SameLine(); + ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical); + ImGui::SameLine(); + ImGuiExt::TextSpinner("hex.disassembler.view.disassembler.disassembling"_lang); }