feat: Added option to highlight pattern parents in the hex editor when hovering

This commit is contained in:
WerWolv
2024-02-25 14:30:56 +01:00
parent dac45659c0
commit ea601a7d03
12 changed files with 141 additions and 25 deletions

View File

@@ -767,6 +767,7 @@ namespace hex::plugin::builtin {
ContentRegistry::Settings::add<Widgets::SliderInteger>("hex.builtin.setting.hex_editor", "", "hex.builtin.setting.hex_editor.byte_padding", 0, 0, 50);
ContentRegistry::Settings::add<Widgets::SliderInteger>("hex.builtin.setting.hex_editor", "", "hex.builtin.setting.hex_editor.char_padding", 0, 0, 50);
ContentRegistry::Settings::add<Widgets::Checkbox>("hex.builtin.setting.hex_editor", "", "hex.builtin.setting.hex_editor.pattern_parent_highlighting", true);
}

View File

@@ -19,6 +19,8 @@
#include <popups/popup_file_chooser.hpp>
#include <content/popups/popup_blocking_task.hpp>
#include <content/popups/hex_editor/popup_hex_editor_find.hpp>
#include <wolv/utils/lock.hpp>
#include <pl/patterns/pattern.hpp>
using namespace std::literals::string_literals;
@@ -404,8 +406,20 @@ namespace hex::plugin::builtin {
});
m_hexEditor.setBackgroundHighlightCallback([this](u64 address, const u8 *data, size_t size) -> std::optional<color_t> {
if (auto highlight = m_backgroundHighlights->find(address); highlight != m_backgroundHighlights->end())
return highlight->second;
bool hovered = false;
for (const auto &[id, hoverFunction] : ImHexApi::HexEditor::impl::getHoveringFunctions()) {
if (hoverFunction(m_hexEditor.getProvider(), address, data, size)) {
hovered = true;
break;
}
}
if (auto highlight = m_backgroundHighlights->find(address); highlight != m_backgroundHighlights->end()) {
if (hovered)
return ImAlphaBlendColors(highlight->second, 0xA0FFFFFF);
else
return highlight->second;
}
std::optional<color_t> result;
for (const auto &[id, callback] : ImHexApi::HexEditor::impl::getBackgroundHighlightingFunctions()) {

View File

@@ -15,7 +15,7 @@ namespace hex::plugin::builtin {
using namespace hex::literals;
ViewInformation::ViewInformation() : View::Window("hex.builtin.view.information.name", ICON_VS_GRAPH_LINE) {
m_analysisData.setOnCreateCallback([](prv::Provider *provider, AnalysisData &data) {
m_analysisData.setOnCreateCallback([](const prv::Provider *provider, AnalysisData &data) {
data.analyzedProvider = provider;
for (const auto &informationSectionConstructor : ContentRegistry::DataInformation::impl::getInformationSectionConstructors()) {

View File

@@ -37,7 +37,7 @@ namespace hex::plugin::builtin {
(*m_patternDrawer)->jumpToPattern(pattern);
});
m_patternDrawer.setOnCreateCallback([this](prv::Provider *provider, auto &drawer) {
m_patternDrawer.setOnCreateCallback([this](const prv::Provider *provider, auto &drawer) {
drawer = std::make_unique<ui::PatternDrawer>();
drawer->setSelectionCallback([](const pl::ptrn::Pattern *pattern) {

View File

@@ -278,24 +278,24 @@ namespace hex::plugin::builtin {
bool openFindPopup = false;
ImGui::PushID(&this->m_textEditor);
if (clickedMenuFind) {
replace = false;
m_replaceMode = false;
openFindPopup = true;
}
if (clickedMenuReplace) {
replace = true;
m_replaceMode = true;
openFindPopup = true;
}
// shortcuts to open the find/replace popup
if (ImGui::IsItemHovered()) {
if (ImGui::IsKeyPressed(ImGuiKey_F, false) && ImGui::GetIO().KeyCtrl) {
replace = false;
m_replaceMode = false;
openFindPopup = true;
}
if (ImGui::IsKeyPressed(ImGuiKey_H, false) && ImGui::GetIO().KeyCtrl) {
replace = true;
m_replaceMode = true;
openFindPopup = true;
}
}
@@ -350,7 +350,7 @@ namespace hex::plugin::builtin {
windowPosForPopup.x += windowSize.x - popupSize.x;
findReplaceHandler->SetFindWindowPos(windowPosForPopup);
if (replace) {
if (m_replaceMode) {
// Remove one window padding
popupSize.y -= style.WindowPadding.y;
// Add the replace window height
@@ -604,10 +604,10 @@ namespace hex::plugin::builtin {
ImGui::TableNextRow();
ImGui::TableNextColumn();
bool oldReplace = replace;
ImGuiExt::DimmedIconToggle(ICON_VS_TRIANGLE_DOWN, ICON_VS_TRIANGLE_RIGHT, &replace);
if (oldReplace != replace) {
if (replace)
bool oldReplace = m_replaceMode;
ImGuiExt::DimmedIconToggle(ICON_VS_TRIANGLE_DOWN, ICON_VS_TRIANGLE_RIGHT, &m_replaceMode);
if (oldReplace != m_replaceMode) {
if (m_replaceMode)
requestFocusReplace = true;
else
requestFocusFind = true;
@@ -644,7 +644,7 @@ namespace hex::plugin::builtin {
findReplaceHandler->SetFindWord(&m_textEditor,findWord);
}
if ((!replace && requestFocus) || requestFocusFind) {
if ((!m_replaceMode && requestFocus) || requestFocusFind) {
ImGui::SetKeyboardFocusHere(-1);
requestFocus = false;
requestFocusFind = false;
@@ -755,7 +755,7 @@ namespace hex::plugin::builtin {
if (ImGuiExt::IconButton(ICON_VS_ARROW_UP, ImVec4(1, 1, 1, 1)))
upArrowFind = true;
if (replace) {
if (m_replaceMode) {
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::TableNextColumn();
@@ -1837,6 +1837,10 @@ namespace hex::plugin::builtin {
}
});
ContentRegistry::Settings::onChange("hex.builtin.setting.interface", "hex.builtin.setting.interface.parent_highlighting", [this](const ContentRegistry::Settings::SettingsValue &value) {
m_parentHighlightingEnabled = bool(value.get<int>(false));
});
ImHexApi::HexEditor::addBackgroundHighlightingProvider([this](u64 address, const u8 *data, size_t size, bool) -> std::optional<color_t> {
hex::unused(data, size);
@@ -1859,6 +1863,26 @@ namespace hex::plugin::builtin {
return color;
});
ImHexApi::HexEditor::addHoverHighlightProvider([this](const prv::Provider *provider, u64 address, const u8 *, size_t) {
if (!m_parentHighlightingEnabled) return false;
const auto &runtime = ContentRegistry::PatternLanguage::getRuntime();
if (auto hoveredRegion = ImHexApi::HexEditor::getHoveredRegion(provider)) {
for (const auto &pattern : runtime.getPatternsAtAddress(hoveredRegion->getStartAddress())) {
const pl::ptrn::Pattern * checkPattern = pattern;
if (auto parent = checkPattern->getParent(); parent != nullptr)
checkPattern = parent;
if (checkPattern->getOffset() <= address && checkPattern->getOffset() + checkPattern->getSize() > address) {
return true;
}
}
}
return false;
});
ImHexApi::HexEditor::addTooltipProvider([this](u64 address, const u8 *data, size_t size) {
hex::unused(data, size);