diff --git a/lib/libimhex/include/hex/providers/provider.hpp b/lib/libimhex/include/hex/providers/provider.hpp index f7e1dfefa..ff9650d42 100644 --- a/lib/libimhex/include/hex/providers/provider.hpp +++ b/lib/libimhex/include/hex/providers/provider.hpp @@ -139,8 +139,8 @@ namespace hex::prv { u32 m_currPage = 0; u64 m_baseAddress = 0; - u32 m_patchTreeOffset = 0; std::list> m_patches; + decltype(m_patches)::iterator m_currPatches; std::list m_overlays; u32 m_id; diff --git a/lib/libimhex/source/providers/provider.cpp b/lib/libimhex/source/providers/provider.cpp index af21f7a3a..1d038b58a 100644 --- a/lib/libimhex/source/providers/provider.cpp +++ b/lib/libimhex/source/providers/provider.cpp @@ -17,6 +17,7 @@ namespace hex::prv { Provider::Provider() : m_id(s_idCounter++) { this->m_patches.emplace_back(); + this->m_currPatches = this->m_patches.begin(); } Provider::~Provider() { @@ -120,19 +121,11 @@ namespace hex::prv { std::map &Provider::getPatches() { - auto iter = this->m_patches.end(); - for (u32 i = 0; i < this->m_patchTreeOffset + 1; i++) - iter--; - - return *(iter); + return *this->m_currPatches; } const std::map &Provider::getPatches() const { - auto iter = this->m_patches.end(); - for (u32 i = 0; i < this->m_patchTreeOffset + 1; i++) - iter--; - - return *(iter); + return *this->m_currPatches; } void Provider::applyPatches() { @@ -204,15 +197,6 @@ namespace hex::prv { } void Provider::addPatch(u64 offset, const void *buffer, size_t size, bool createUndo) { - if (this->m_patchTreeOffset > 0) { - auto iter = this->m_patches.end(); - for (u32 i = 0; i < this->m_patchTreeOffset; i++) - iter--; - - this->m_patches.erase(iter, this->m_patches.end()); - this->m_patchTreeOffset = 0; - } - if (createUndo) createUndoPoint(); @@ -235,24 +219,25 @@ namespace hex::prv { void Provider::createUndoPoint() { this->m_patches.push_back(getPatches()); + this->m_currPatches = std::prev(this->m_patches.end()); } void Provider::undo() { if (canUndo()) - this->m_patchTreeOffset++; + this->m_currPatches--; } void Provider::redo() { if (canRedo()) - this->m_patchTreeOffset--; + this->m_currPatches++; } bool Provider::canUndo() const { - return this->m_patchTreeOffset < this->m_patches.size() - 1; + return this->m_currPatches != this->m_patches.begin(); } bool Provider::canRedo() const { - return this->m_patchTreeOffset > 0; + return std::next(this->m_currPatches) != this->m_patches.end(); } bool Provider::hasFilePicker() const { diff --git a/plugins/builtin/include/ui/widgets.hpp b/plugins/builtin/include/ui/widgets.hpp index a356c0d86..584dc0d4c 100644 --- a/plugins/builtin/include/ui/widgets.hpp +++ b/plugins/builtin/include/ui/widgets.hpp @@ -19,35 +19,38 @@ namespace hex::plugin::builtin::ui { if (showHeader) ImGui::Header("hex.builtin.common.range"_lang, firstEntry); - if (ImGui::RadioButton("hex.builtin.common.range.entire_data"_lang, *type == RegionType::EntireData)) { - *region = { provider->getBaseAddress(), provider->getActualSize() }; + if (ImGui::RadioButton("hex.builtin.common.range.entire_data"_lang, *type == RegionType::EntireData)) *type = RegionType::EntireData; - } - if (ImGui::RadioButton("hex.builtin.common.range.selection"_lang, *type == RegionType::Selection)) { - *region = ImHexApi::HexEditor::getSelection().value_or(ImHexApi::HexEditor::ProviderRegion { { 0, 1 }, provider }); + if (ImGui::RadioButton("hex.builtin.common.range.selection"_lang, *type == RegionType::Selection)) *type = RegionType::Selection; - } - if (ImGui::RadioButton("hex.builtin.common.region"_lang, *type == RegionType::Region)) { + if (ImGui::RadioButton("hex.builtin.common.region"_lang, *type == RegionType::Region)) *type = RegionType::Region; - } - if (*type == RegionType::Region) { - ImGui::SameLine(); + switch (*type) { + case RegionType::EntireData: + *region = { provider->getBaseAddress(), provider->getActualSize() }; + break; + case RegionType::Selection: + *region = ImHexApi::HexEditor::getSelection().value_or(ImHexApi::HexEditor::ProviderRegion { { 0, 1 }, provider }); + break; + case RegionType::Region: + ImGui::SameLine(); - const auto width = ImGui::GetContentRegionAvail().x / 2 - ImGui::CalcTextSize(" - ").x / 2 - ImGui::GetStyle().FramePadding.x * 4; - u64 start = region->getStartAddress(), end = region->getEndAddress(); + const auto width = ImGui::GetContentRegionAvail().x / 2 - ImGui::CalcTextSize(" - ").x / 2 - ImGui::GetStyle().FramePadding.x * 4; + u64 start = region->getStartAddress(), end = region->getEndAddress(); - ImGui::PushItemWidth(width); - ImGui::InputHexadecimal("##start", &start); - ImGui::PopItemWidth(); - ImGui::SameLine(); - ImGui::TextUnformatted(" - "); - ImGui::SameLine(); - ImGui::PushItemWidth(width); - ImGui::InputHexadecimal("##end", &end); - ImGui::PopItemWidth(); + ImGui::PushItemWidth(width); + ImGui::InputHexadecimal("##start", &start); + ImGui::PopItemWidth(); + ImGui::SameLine(); + ImGui::TextUnformatted(" - "); + ImGui::SameLine(); + ImGui::PushItemWidth(width); + ImGui::InputHexadecimal("##end", &end); + ImGui::PopItemWidth(); - *region = { start, (end - start) + 1 }; + *region = { start, (end - start) + 1 }; + break; } } diff --git a/plugins/builtin/source/content/providers/file_provider.cpp b/plugins/builtin/source/content/providers/file_provider.cpp index b99175f20..99b6fd8ce 100644 --- a/plugins/builtin/source/content/providers/file_provider.cpp +++ b/plugins/builtin/source/content/providers/file_provider.cpp @@ -41,9 +41,10 @@ namespace hex::plugin::builtin { if (overlays) { if (auto &patches = this->getPatches(); !patches.empty()) { - for (u64 i = 0; i < size; i++) - if (patches.contains(offset + i)) - reinterpret_cast(buffer)[i] = patches[offset + i]; + for (const auto&[patchOffset, patchData] : patches) { + if (patchOffset >= offset && patchOffset <= (offset + size)) + reinterpret_cast(buffer)[patchOffset] = patchData; + } } this->applyOverlays(offset, buffer, size);