diff --git a/plugins/builtin/include/content/helpers/diagrams.hpp b/plugins/builtin/include/content/helpers/diagrams.hpp index 58eea2357..70587efe1 100644 --- a/plugins/builtin/include/content/helpers/diagrams.hpp +++ b/plugins/builtin/include/content/helpers/diagrams.hpp @@ -17,6 +17,11 @@ namespace hex { namespace { + int IntegerAxisFormatter(double value, char* buffer, int size, void *userData) { + u64 integer = static_cast(value); + return snprintf(buffer, size, static_cast(userData), integer); + } + std::vector getSampleSelection(prv::Provider *provider, u64 address, size_t size, size_t sampleSize) { const size_t sequenceCount = std::ceil(std::sqrt(sampleSize)); @@ -290,7 +295,11 @@ namespace hex { void draw(ImVec2 size, ImPlotFlags flags, bool updateHandle = false) { if (!this->m_processing && ImPlot::BeginPlot("##ChunkBasedAnalysis", size, flags)) { - ImPlot::SetupAxes("hex.builtin.common.address"_lang, "hex.builtin.view.information.entropy"_lang, ImPlotAxisFlags_Lock, ImPlotAxisFlags_Lock); + ImPlot::SetupAxes("hex.builtin.common.address"_lang, "hex.builtin.view.information.entropy"_lang, + ImPlotAxisFlags_Lock | ImPlotAxisFlags_NoHighlight | ImPlotAxisFlags_NoSideSwitch, + ImPlotAxisFlags_Lock | ImPlotAxisFlags_NoHighlight | ImPlotAxisFlags_NoSideSwitch); + ImPlot::SetupAxisFormat(ImAxis_X1, IntegerAxisFormatter, (void*)"0x%04llX"); + ImPlot::SetupMouseText(ImPlotLocation_NorthEast); // Set the axis limit to [first block : last block] ImPlot::SetupAxesLimits( @@ -453,16 +462,16 @@ namespace hex { // Return the highest entropy value among all of the blocks double getLowestEntropyBlockValue() { double result = 0.0f; - if (!this->m_yBlockEntropy.empty()) - result = *std::min_element(this->m_yBlockEntropy.begin(), this->m_yBlockEntropy.end()); + if (this->m_yBlockEntropy.size() > 1) + result = *std::min_element(this->m_yBlockEntropy.begin(), this->m_yBlockEntropy.end() - 1); return result; } // Return the highest entropy value among all of the blocks u64 getLowestEntropyBlockAddress() { u64 address = 0x00; - if (!this->m_yBlockEntropy.empty()) - address = (std::min_element(this->m_yBlockEntropy.begin(), this->m_yBlockEntropy.end()) - this->m_yBlockEntropy.begin()) * this->m_blockSize; + if (this->m_yBlockEntropy.size() > 1) + address = (std::min_element(this->m_yBlockEntropy.begin(), this->m_yBlockEntropy.end() - 1) - this->m_yBlockEntropy.begin()) * this->m_blockSize; return address; } @@ -575,9 +584,14 @@ namespace hex { void draw(ImVec2 size, ImPlotFlags flags) { if (!this->m_processing && ImPlot::BeginPlot("##distribution", size, flags)) { - ImPlot::SetupAxes("hex.builtin.common.value"_lang, "hex.builtin.common.count"_lang, ImPlotAxisFlags_Lock, ImPlotAxisFlags_Lock); + ImPlot::SetupAxes("hex.builtin.common.value"_lang, "hex.builtin.common.count"_lang, + ImPlotAxisFlags_Lock | ImPlotAxisFlags_NoHighlight | ImPlotAxisFlags_NoSideSwitch, + ImPlotAxisFlags_Lock | ImPlotAxisFlags_NoHighlight | ImPlotAxisFlags_NoSideSwitch); ImPlot::SetupAxisScale(ImAxis_Y1, ImPlotScale_Log10); - ImPlot::SetupAxesLimits(0, 256, 1, double(*std::max_element(this->m_valueCounts.begin(), this->m_valueCounts.end())) * 1.1F, ImGuiCond_Always); + ImPlot::SetupAxesLimits(-1, 256, 1, double(*std::max_element(this->m_valueCounts.begin(), this->m_valueCounts.end())) * 1.1F, ImGuiCond_Always); + ImPlot::SetupAxisFormat(ImAxis_X1, IntegerAxisFormatter, (void*)"0x%02llX"); + ImPlot::SetupAxisTicks(ImAxis_X1, 0, 255, 17); + ImPlot::SetupMouseText(ImPlotLocation_NorthEast); constexpr static auto x = [] { std::array result { 0 }; @@ -585,7 +599,7 @@ namespace hex { return result; }(); - ImPlot::PlotBars("##bytes", x.data(), this->m_valueCounts.data(), x.size(), 1.0); + ImPlot::PlotBars("##bytes", x.data(), this->m_valueCounts.data(), x.size(), 1); ImPlot::EndPlot(); } } @@ -665,7 +679,9 @@ namespace hex { void draw(ImVec2 size, ImPlotFlags flags, bool updateHandle = false) { // Draw the result of the analysis if (!this->m_processing && ImPlot::BeginPlot("##byte_types", size, flags)) { - ImPlot::SetupAxes("hex.builtin.common.address"_lang, "hex.builtin.common.percentage"_lang, ImPlotAxisFlags_Lock, ImPlotAxisFlags_Lock); + ImPlot::SetupAxes("hex.builtin.common.address"_lang, "hex.builtin.common.percentage"_lang, + ImPlotAxisFlags_Lock | ImPlotAxisFlags_NoHighlight | ImPlotAxisFlags_NoSideSwitch, + ImPlotAxisFlags_Lock | ImPlotAxisFlags_NoHighlight | ImPlotAxisFlags_NoSideSwitch); ImPlot::SetupAxesLimits( this->m_xBlockTypeDistributions.empty() ? 0 : this->m_xBlockTypeDistributions.front(), this->m_xBlockTypeDistributions.empty() ? 0 : this->m_xBlockTypeDistributions.back(), @@ -673,6 +689,8 @@ namespace hex { 100.1F, ImGuiCond_Always); ImPlot::SetupLegend(ImPlotLocation_South, ImPlotLegendFlags_Horizontal | ImPlotLegendFlags_Outside); + ImPlot::SetupAxisFormat(ImAxis_X1, IntegerAxisFormatter, (void*)"0x%04llX"); + ImPlot::SetupMouseText(ImPlotLocation_NorthEast); constexpr static std::array Names = { "iscntrl", "isprint", "isspace", "isblank", "isgraph", "ispunct", "isalnum", "isalpha", diff --git a/plugins/builtin/source/content/views/view_information.cpp b/plugins/builtin/source/content/views/view_information.cpp index 200f477ad..cd9fef193 100644 --- a/plugins/builtin/source/content/views/view_information.cpp +++ b/plugins/builtin/source/content/views/view_information.cpp @@ -240,7 +240,7 @@ namespace hex::plugin::builtin { ImGui::TextUnformatted("hex.builtin.view.information.entropy"_lang); this->m_chunkBasedEntropy.draw( ImVec2(-1, 0), - ImPlotFlags_NoChild | ImPlotFlags_CanvasOnly, + ImPlotFlags_NoChild | ImPlotFlags_NoLegend | ImPlotFlags_NoMenus | ImPlotFlags_NoBoxSelect, true ); @@ -271,12 +271,28 @@ namespace hex::plugin::builtin { ImGui::TableNextColumn(); ImGui::TextFormatted("{}", "hex.builtin.view.information.highest_entropy"_lang); ImGui::TableNextColumn(); - ImGui::TextFormatted("{:.5f} @ 0x{:02X}", this->m_highestBlockEntropy, this->m_highestBlockEntropyAddress); + ImGui::TextFormatted("{:.5f} @", this->m_highestBlockEntropy); + ImGui::SameLine(); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0)); + ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0)); + if (ImGui::Button(hex::format("0x{:06X}", this->m_highestBlockEntropyAddress).c_str())) { + ImHexApi::HexEditor::setSelection(this->m_highestBlockEntropyAddress, this->m_inputChunkSize); + } + ImGui::PopStyleColor(); + ImGui::PopStyleVar(); ImGui::TableNextColumn(); ImGui::TextFormatted("{}", "hex.builtin.view.information.lowest_entropy"_lang); ImGui::TableNextColumn(); - ImGui::TextFormatted("{:.5f} @ 0x{:02X}", this->m_lowestBlockEntropy, this->m_lowestBlockEntropyAddress); + ImGui::TextFormatted("{:.5f} @", this->m_lowestBlockEntropy); + ImGui::SameLine(); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0)); + ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0)); + if (ImGui::Button(hex::format("0x{:06X}", this->m_lowestBlockEntropyAddress).c_str())) { + ImHexApi::HexEditor::setSelection(this->m_lowestBlockEntropyAddress, this->m_inputChunkSize); + } + ImGui::PopStyleColor(); + ImGui::PopStyleVar(); ImGui::TableNextColumn(); ImGui::TextFormatted("{}", "hex.builtin.view.information.plain_text_percentage"_lang);