start adding hover info
This commit is contained in:
parent
1ae3d6b82b
commit
8af9fddf73
6 changed files with 112 additions and 5 deletions
|
@ -33,6 +33,9 @@ u32 mem_edit_bg_color_fn(const u8 *, u64 off, void *user_data)
|
||||||
App_State *app = reinterpret_cast<App_State *>(user_data);
|
App_State *app = reinterpret_cast<App_State *>(user_data);
|
||||||
off += app->base_display_addr;
|
off += app->base_display_addr;
|
||||||
|
|
||||||
|
if (app->viewer.hovered_range.start <= off && off < app->viewer.hovered_range.end())
|
||||||
|
return imcol(app->viewer.col_highlight);
|
||||||
|
|
||||||
i64 hilite_cluster = app->viewer.highlight_cluster ? app->viewer.highlighted_cluster : -1;
|
i64 hilite_cluster = app->viewer.highlight_cluster ? app->viewer.highlighted_cluster : -1;
|
||||||
Section section = find_section(*app, off, hilite_cluster);
|
Section section = find_section(*app, off, hilite_cluster);
|
||||||
|
|
||||||
|
@ -46,6 +49,9 @@ u32 mem_edit_bg_color_fn(const u8 *, u64 off, void *user_data)
|
||||||
internal
|
internal
|
||||||
void mem_edit_interact_fn(const u8 *, u64 off, void *user_data)
|
void mem_edit_interact_fn(const u8 *, u64 off, void *user_data)
|
||||||
{
|
{
|
||||||
|
App_State *app = reinterpret_cast<App_State *>(user_data);
|
||||||
|
off += app->base_display_addr;
|
||||||
|
app->viewer.hovered_off = off;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal
|
internal
|
||||||
|
@ -219,6 +225,10 @@ void update_and_render(Arena *arena, App_State &app, f32 delta_time_ms)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Repeated sections: allow jumping to the N-th
|
// Repeated sections: allow jumping to the N-th
|
||||||
|
ImGui::ColorEdit3("_TKey Header", app.viewer.col_key, flags);
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Button("TKey Header")) {} // TODO: jump to next key
|
||||||
|
|
||||||
ImGui::ColorEdit3("_Page Start", app.viewer.col_page_start, flags);
|
ImGui::ColorEdit3("_Page Start", app.viewer.col_page_start, flags);
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::Button("Page Start"))
|
if (ImGui::Button("Page Start"))
|
||||||
|
@ -282,6 +292,26 @@ void update_and_render(Arena *arena, App_State &app, f32 delta_time_ms)
|
||||||
ImGui::Checkbox("Highlight cluster", &app.viewer.highlight_cluster);
|
ImGui::Checkbox("Highlight cluster", &app.viewer.highlight_cluster);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------
|
||||||
|
ImGui::Separator();
|
||||||
|
|
||||||
|
{
|
||||||
|
Section hovered_section = find_section(app, app.viewer.hovered_off);
|
||||||
|
Sec_Hover_Info hover_info = get_section_hover_info(scratch.arena, hovered_section, app.viewer.hovered_off, app.inspected_file.mem);
|
||||||
|
u8 indent = 0;
|
||||||
|
for (String8_Node *node = hover_info.desc; node; node = node->next) {
|
||||||
|
String8 fmt = str8("%s");
|
||||||
|
if (indent) {
|
||||||
|
// create indent
|
||||||
|
fmt = push_str8f(scratch.arena, "%%%ds", indent + node->str.size);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::Text(fmt.c(), node->str.c());
|
||||||
|
indent += 2;
|
||||||
|
}
|
||||||
|
app.viewer.hovered_range = hover_info.rng;
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::EndTable();
|
ImGui::EndTable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,10 @@ struct Viewer {
|
||||||
u64 latest_key_gone_to;
|
u64 latest_key_gone_to;
|
||||||
u64 latest_checksum_gone_to;
|
u64 latest_checksum_gone_to;
|
||||||
u64 latest_page_list_gone_to;
|
u64 latest_page_list_gone_to;
|
||||||
|
|
||||||
|
// Absolute byte offset into inspected_file.mem that has been hovered last.
|
||||||
|
u64 hovered_off;
|
||||||
|
Byte_Range hovered_range;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Edit_Bg_Color_Data {
|
struct Edit_Bg_Color_Data {
|
||||||
|
|
|
@ -39,11 +39,7 @@ String8 render_legend_to_string(Arena *arena, const Term_Viewer &viewer, const A
|
||||||
Temp scratch = scratch_begin(&arena, 1);
|
Temp scratch = scratch_begin(&arena, 1);
|
||||||
defer { scratch_end(scratch); };
|
defer { scratch_end(scratch); };
|
||||||
|
|
||||||
struct String8_Node {
|
String8_Node *head = nullptr, *tail = nullptr;
|
||||||
String8_Node *next;
|
|
||||||
String8 str;
|
|
||||||
} *head = nullptr, *tail = nullptr;
|
|
||||||
|
|
||||||
String8 color_none = ansi_color_table[ACol_None];
|
String8 color_none = ansi_color_table[ACol_None];
|
||||||
u64 tot_len = 0;
|
u64 tot_len = 0;
|
||||||
for (u64 section = 1; section < Sec_COUNT; ++section) {
|
for (u64 section = 1; section < Sec_COUNT; ++section) {
|
||||||
|
|
|
@ -439,3 +439,57 @@ Section find_section(App_State &app, u64 off, i64 hilite_cluster = -1)
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Sec_Hover_Info {
|
||||||
|
Byte_Range rng;
|
||||||
|
String8_Node *desc;
|
||||||
|
};
|
||||||
|
|
||||||
|
// `off` is the absolute offset into `data`.
|
||||||
|
internal
|
||||||
|
Sec_Hover_Info get_section_hover_info(Arena *arena, Section section, u64 off, const u8 *data)
|
||||||
|
{
|
||||||
|
Sec_Hover_Info info {};
|
||||||
|
|
||||||
|
printf("off: 0x%lX, sec start: 0x%lX\n", off, section.range.start);
|
||||||
|
// assert(off >= section.range.start);
|
||||||
|
if (off < section.range.start) {
|
||||||
|
printf("WRONG\n"); // TODO: fix TKey Header case
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 start = section.range.start;
|
||||||
|
u64 roff = off - start; // offset relative to `section`
|
||||||
|
|
||||||
|
if (section.id == Sec_RNTuple_Anchor) {
|
||||||
|
info.desc = push_str8_node(arena, nullptr, "RNTuple Anchor");
|
||||||
|
// TODO: dry
|
||||||
|
if (roff < sizeof(u32)) {
|
||||||
|
info.rng = { start, sizeof(u32) };
|
||||||
|
u32 val;
|
||||||
|
memcpy(&val, data + info.rng.start, info.rng.len);
|
||||||
|
val = bswap_32(val);
|
||||||
|
val -= 0x40000000;
|
||||||
|
push_str8_node(arena, info.desc, "Object len: %u", val);
|
||||||
|
} else if (roff < sizeof(u32) + sizeof(u16)) {
|
||||||
|
info.rng = { start + sizeof(u32), sizeof(u16) };
|
||||||
|
u32 val;
|
||||||
|
memcpy(&val, data + info.rng.start, info.rng.len);
|
||||||
|
val = bswap_16(val);
|
||||||
|
push_str8_node(arena, info.desc, "Class version: %u", val);
|
||||||
|
} else if (roff < sizeof(u32) + sizeof(u16) + sizeof(u16)) {
|
||||||
|
info.rng = { start + sizeof(u32) + sizeof(u16), sizeof(u16) };
|
||||||
|
u16 val;
|
||||||
|
memcpy(&val, data + info.rng.start, info.rng.len);
|
||||||
|
val = bswap_16(val);
|
||||||
|
push_str8_node(arena, info.desc, "Version Epoch: %u", val);
|
||||||
|
} else if (roff < sizeof(u32) + sizeof(u16) + sizeof(u16) + sizeof(u16)) {
|
||||||
|
info.rng = { start + sizeof(u32) + sizeof(u16) + sizeof(u16), sizeof(u16) };
|
||||||
|
u16 val;
|
||||||
|
memcpy(&val, data + info.rng.start, info.rng.len);
|
||||||
|
val = bswap_16(val);
|
||||||
|
push_str8_node(arena, info.desc, "Version Major: %u", val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
16
src/str.cpp
16
src/str.cpp
|
@ -36,3 +36,19 @@ String8 to_pretty_size(Arena *arena, u64 bytes)
|
||||||
return push_str8f(arena, "%zu B", bytes);
|
return push_str8f(arena, "%zu B", bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
internal
|
||||||
|
String8_Node *push_str8_node(Arena *arena, String8_Node *prev, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
String8_Node *snode = arena_push<String8_Node>(arena);
|
||||||
|
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
snode->str = push_str8fv(arena, fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
if (prev)
|
||||||
|
prev->next = snode;
|
||||||
|
|
||||||
|
return snode;
|
||||||
|
}
|
||||||
|
|
|
@ -10,3 +10,10 @@ struct String8 {
|
||||||
|
|
||||||
String8 str8_from_c(const char *str);
|
String8 str8_from_c(const char *str);
|
||||||
String8 push_str8f(Arena *arena, char *fmt, ...);
|
String8 push_str8f(Arena *arena, char *fmt, ...);
|
||||||
|
|
||||||
|
|
||||||
|
struct String8_Node {
|
||||||
|
String8_Node *next;
|
||||||
|
String8 str;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue