add interact fn to mem edit

This commit is contained in:
silverweed 2024-07-25 10:44:50 +02:00
parent d03da05b26
commit ca9b536a54
2 changed files with 41 additions and 1 deletions

View file

@ -124,6 +124,11 @@ u32 mem_edit_bg_color_fn(const u8 *, u64 off, void *user_data)
return IM_COL32(0, 0, 0, 0); return IM_COL32(0, 0, 0, 0);
} }
internal
void mem_edit_interact_fn(const u8 *, u64 off, void *user_data)
{
}
internal internal
MemoryEditor make_memory_editor(App_State &app) MemoryEditor make_memory_editor(App_State &app)
{ {
@ -135,6 +140,8 @@ MemoryEditor make_memory_editor(App_State &app)
mem_edit.WriteFn = [] (ImU8*, size_t, ImU8) {}; mem_edit.WriteFn = [] (ImU8*, size_t, ImU8) {};
mem_edit.BgColorFn = mem_edit_bg_color_fn; mem_edit.BgColorFn = mem_edit_bg_color_fn;
mem_edit.BgColorFnUserData = &app; mem_edit.BgColorFnUserData = &app;
mem_edit.InteractFn = mem_edit_interact_fn;
mem_edit.InteractFnUserData = &app;
return mem_edit; return mem_edit;
} }

View file

@ -96,6 +96,8 @@ struct MemoryEditor
bool (*HighlightFn)(const ImU8* data, size_t off);//= 0 // optional handler to return Highlight property (to support non-contiguous highlighting). bool (*HighlightFn)(const ImU8* data, size_t off);//= 0 // optional handler to return Highlight property (to support non-contiguous highlighting).
ImU32 (*BgColorFn)(const ImU8* data, size_t off, void *UserData); // = 0 // optional handler to return custom background color of individual bytes. ImU32 (*BgColorFn)(const ImU8* data, size_t off, void *UserData); // = 0 // optional handler to return custom background color of individual bytes.
void *BgColorFnUserData; void *BgColorFnUserData;
void (*InteractFn)(const ImU8* data, size_t off, void *UserData);// = 0 // optional handler to interact with individual bytes using ImGui::IsItemHovered, ImGui::IsItemClicked, etc.
void *InteractFnUserData;
// [Internal State] // [Internal State]
bool ContentsWidthChanged; bool ContentsWidthChanged;
@ -130,6 +132,8 @@ struct MemoryEditor
HighlightFn = NULL; HighlightFn = NULL;
BgColorFn = NULL; BgColorFn = NULL;
BgColorFnUserData = NULL; BgColorFnUserData = NULL;
InteractFn = NULL;
InteractFnUserData = NULL;
// State/Internals // State/Internals
ContentsWidthChanged = false; ContentsWidthChanged = false;
@ -275,6 +279,10 @@ struct MemoryEditor
const char* format_byte = OptUpperCaseHex ? "%02X" : "%02x"; const char* format_byte = OptUpperCaseHex ? "%02X" : "%02x";
const char* format_byte_space = OptUpperCaseHex ? "%02X " : "%02x "; const char* format_byte_space = OptUpperCaseHex ? "%02X " : "%02x ";
// Disallow interacting with multiple bytes simultaneously.
// This is needed because consecutive hex cells overlap each other by 1 pixel.
bool interact_invoked = false;
while (clipper.Step()) while (clipper.Step())
for (int line_i = clipper.DisplayStart; line_i < clipper.DisplayEnd; line_i++) // display only visible lines for (int line_i = clipper.DisplayStart; line_i < clipper.DisplayEnd; line_i++) // display only visible lines
{ {
@ -407,6 +415,18 @@ struct MemoryEditor
DataEditingTakeFocus = true; DataEditingTakeFocus = true;
data_editing_addr_next = addr; data_editing_addr_next = addr;
} }
else if (InteractFn && ImGui::IsItemHovered())
{
if (!interact_invoked)
{
// Revert padding/spacing to let users draw popups/windows without interference
ImGui::PopStyleVar(2);
InteractFn(mem_data, addr, InteractFnUserData);
interact_invoked = true;
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0));
}
}
} }
} }
@ -416,12 +436,25 @@ struct MemoryEditor
ImGui::SameLine(s.PosAsciiStart); ImGui::SameLine(s.PosAsciiStart);
ImVec2 pos = ImGui::GetCursorScreenPos(); ImVec2 pos = ImGui::GetCursorScreenPos();
addr = (size_t)line_i * Cols; addr = (size_t)line_i * Cols;
size_t mouseAddr = addr + (size_t)((ImGui::GetIO().MousePos.x - pos.x) / s.GlyphWidth);
ImGui::PushID(line_i); ImGui::PushID(line_i);
if (ImGui::InvisibleButton("ascii", ImVec2(s.PosAsciiEnd - s.PosAsciiStart, s.LineHeight))) if (ImGui::InvisibleButton("ascii", ImVec2(s.PosAsciiEnd - s.PosAsciiStart, s.LineHeight)))
{ {
DataEditingAddr = DataPreviewAddr = addr + (size_t)((ImGui::GetIO().MousePos.x - pos.x) / s.GlyphWidth); DataEditingAddr = DataPreviewAddr = mouseAddr;
DataEditingTakeFocus = true; DataEditingTakeFocus = true;
} }
if (InteractFn && ImGui::IsItemHovered())
{
if (!interact_invoked)
{
// Revert padding/spacing to let users draw popups/windows without interference
ImGui::PopStyleVar(2);
InteractFn(mem_data, mouseAddr, InteractFnUserData);
interact_invoked = true;
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0));
}
}
ImGui::PopID(); ImGui::PopID();
for (int n = 0; n < Cols && addr < mem_size; n++, addr++) for (int n = 0; n < Cols && addr < mem_size; n++, addr++)
{ {