diff --git a/src/hover.cpp b/src/hover.cpp index 8811157..67a30b3 100644 --- a/src/hover.cpp +++ b/src/hover.cpp @@ -2,6 +2,7 @@ struct Sec_Hover_Info { Byte_Range rng; // A string tree where children are more indented than parents String8_Node *desc; + String8_Node *highlighted_desc; }; template T bswap_if_needed(T x) { return x; } @@ -133,8 +134,10 @@ struct Sec_Hover_Fn { u64 sec_len = cur_field_off - sec_start; info.rng = { start + sec_start, sec_len }; // In case of nested sections, only highlight the innermost - // FIXME! - info.desc->selected = innermost_section_highlighted < cur_section_nesting; + // FIXME: sometimes no section ends up highlighted! + if (innermost_section_highlighted <= cur_section_nesting) { + info.highlighted_desc = info.desc; + } innermost_section_highlighted = max(cur_section_nesting, innermost_section_highlighted); // ended = true; } @@ -159,7 +162,8 @@ struct Sec_Hover_Fn { T val; memcpy(&val, (u8 *)data + start + cur_field_off, field_len); String8_Node *desc = display_val(arena, info.desc, desc_fmt, val); - desc->selected = hovered && !display_grouped; + if (hovered && !display_grouped) + info.highlighted_desc = desc; if (val_read) *val_read = val; @@ -195,7 +199,8 @@ struct Sec_Hover_Fn { buf[str_size] = 0; String8 s = { buf, str_size }; String8_Node *desc = display_val(arena, info.desc, desc_fmt, s); - desc->selected = hovered && !display_grouped; + if (hovered && !display_grouped) + info.highlighted_desc = desc; if (display_grouped || hovered) { info.rng = { start + cur_field_off, field_len }; @@ -224,7 +229,9 @@ struct Sec_Hover_Fn { b8 hovered = cur_field_off <= roff && roff < cur_field_off + range_len; String8_Node *dsc = display_val(arena, info.desc, desc, data + start + cur_field_off); - dsc->selected = hovered && !display_grouped; + if (hovered && !display_grouped) + info.highlighted_desc = dsc; + if (display_grouped || hovered) { info.rng = { start + cur_field_off, range_len }; // ended = !display_grouped; @@ -246,7 +253,8 @@ struct Sec_Hover_Fn { if (was_zipped) *was_zipped = true; info.rng = { start + cur_field_off, range_len }; - info.desc->selected = hovered; + if (hovered) + info.highlighted_desc = info.desc; // ended = !display_grouped; } cur_field_off += range_len; @@ -297,7 +305,7 @@ struct Sec_Hover_Fn { field_str8("Obj Name: %s"); field_str8("Obj Title: %s"); } - }); + }, HoverSec_HideIfNotHovered); } void envelope_preamble() @@ -329,7 +337,6 @@ struct Sec_Hover_Fn { titled_section(titlestr.c(), [this, &frame_type, &frame_size = size, n_items, titlestr] { i64 size; memcpy(&size, data + start + cur_field_off, sizeof(size)); - printf("frame header %s read size %ld at 0x%lX\n", titlestr.c(), size, start + cur_field_off); if (size >= 0) { frame_type = Frame_Record; field("Record frame size: %" PRIi64 " B", hover_display_val_le_abs); @@ -414,7 +421,6 @@ struct Sec_Hover_Fn { return; } - field_le("Size: %" PRIi64 " B"); field("Column type: %s", [](Arena *arena, String8_Node *prev, const char *fmt, u16 val) { const char *readable_col_type = get_column_type_name(val); return push_str8_node_child(arena, prev, fmt, readable_col_type); @@ -535,7 +541,7 @@ struct Sec_Hover_Fn { field_be("Len Footer: %u"); field_be("Max Key Size: %u"); field_le("Checksum: 0x%" PRIX64); - }); + }, HoverSec_HideIfNotHovered); }); } @@ -543,25 +549,27 @@ struct Sec_Hover_Fn { { titled_section("RNTuple Header", [this] { tkey(); - b8 zipped; - if (!maybe_rootzip(&zipped)) - return; + titled_section("Data", [this] { + b8 zipped; + if (!maybe_rootzip(&zipped)) + return; - if (zipped) { - // XXX: why -1? - range("Compressed payload", section.range.len - section.post_size - sizeof(u64) - 1); - field_le("Checksum: 0x%" PRIX64); - } else { - envelope_preamble(); - // NOTE: flags in principle require a more complex handling, but for now they are unused, - // so they're always occupying only 8 bytes. - field_le("Flags: 0x%" PRIX64); - field_str8("Name: %s"); - field_str8("Description: %s"); - field_str8("ROOT version: %s"); - schema_description("Schema Description"); - field_le("Checksum: 0x%" PRIX64); - } + if (zipped) { + // XXX: why -1? + range("Compressed payload", section.range.len - section.post_size - sizeof(u64) - 1); + field_le("Checksum: 0x%" PRIX64); + } else { + envelope_preamble(); + // NOTE: flags in principle require a more complex handling, but for now they are unused, + // so they're always occupying only 8 bytes. + field_le("Flags: 0x%" PRIX64); + field_str8("Name: %s"); + field_str8("Description: %s"); + field_str8("ROOT version: %s"); + schema_description("Schema Description"); + field_le("Checksum: 0x%" PRIX64); + } + }, HoverSec_HideIfNotHovered); }); } @@ -569,31 +577,52 @@ struct Sec_Hover_Fn { { titled_section("RNTuple Footer", [this] { tkey(); - b8 zipped; - if (!maybe_rootzip(&zipped)) - return; + titled_section("Data", [this] { + b8 zipped; + if (!maybe_rootzip(&zipped)) + return; - if (zipped) { - // XXX: why -1? - range("Payload", section.range.len - section.post_size - sizeof(u64) - 1); - field_le("Checksum: 0x%" PRIX64); - } else { - envelope_preamble(); - // NOTE: flags in principle require a more complex handling, but for now they are unused, - // so they're always occupying only 8 bytes. - field_le("Flags: 0x%" PRIX64); - field_le("Header checksum: 0x%" PRIX64); - u64 size; - Frame_Type ftype = frame_header(size); - assert(ftype == Frame_Record); - schema_description("Schema Extension"); - // - list of column group record frames (TODO) - //frame_header("Column Groups"); - // - list of cluster group record frames (TODO) - //frame_header("Cluster Groups"); - range("Payload", section.range.len - cur_field_off); - field_le("Checksum: 0x%" PRIX64); - } + if (zipped) { + // XXX: why -1? + range("Payload", section.range.len - section.post_size - sizeof(u64) - 1); + field_le("Checksum: 0x%" PRIX64); + } else { + envelope_preamble(); + // NOTE: flags in principle require a more complex handling, but for now they are unused, + // so they're always occupying only 8 bytes. + field_le("Flags: 0x%" PRIX64); + field_le("Header checksum: 0x%" PRIX64); + u64 size; + Frame_Type ftype = frame_header(size); + assert(ftype == Frame_Record); + schema_description("Schema Extension"); + // - list of column group record frames (TODO) + //frame_header("Column Groups"); + // - list of cluster group record frames (TODO) + //frame_header("Cluster Groups"); + range("Payload", section.range.len - cur_field_off); + field_le("Checksum: 0x%" PRIX64); + } + }, HoverSec_HideIfNotHovered); + }); + } + + void page_list() + { + titled_section("Page List", [this] { + tkey(); + titled_section("Data", [this] { + b8 zipped; + if (!maybe_rootzip(&zipped)) + return; + if (zipped) { + // XXX: why -1? + range("Payload", section.range.len - section.post_size - sizeof(u64) - 1); + field_le("Checksum: 0x%" PRIX64); + } else { + // TODO + } + }, HoverSec_HideIfNotHovered); }); } @@ -734,15 +763,11 @@ Sec_Hover_Info get_section_hover_info(Arena *arena, Section section, u64 off, co hover.rntuple_footer(); } break; - #if 0 case Sec_Page_List: { - hover.tkey() - || hover.maybe_rootzip() - || hover.range("Payload", section.range.len - section.post_size) // TODO: improve - || hover.field_le("Checksum: 0x%" PRIX64) - ; + hover.page_list(); } break; + #if 0 case Sec_Page: { // only try hovering a key if this is the first page of the cluster (<=> pre_size != 0) b8 ok = section.pre_size && hover.tkey(); diff --git a/src/render.cpp b/src/render.cpp index bd296b5..433d5ec 100644 --- a/src/render.cpp +++ b/src/render.cpp @@ -213,7 +213,7 @@ void viewer_jump_to_cluster(App_State &app, u64 cluster_idx) } internal -void imgui_render_string_tree(Arena *arena, String8_Node *root, u16 indent = 0) +void imgui_render_string_tree(Arena *arena, String8_Node *root, String8_Node *highlighted, u16 indent = 0) { String8 indent_str; if (indent) { @@ -225,13 +225,13 @@ void imgui_render_string_tree(Arena *arena, String8_Node *root, u16 indent = 0) } for (String8_Node *node = root; node; node = node->next) { - if (node->selected) + if (node == highlighted) ImGui::TextColored(ImColor(1.0f, 1.0f, 0.0f), "%s%s", indent_str.c(), node->str.c()); else ImGui::Text("%s%s", indent_str.c(), node->str.c()); if (node->first_child) - imgui_render_string_tree(arena, node->first_child, indent + 2); + imgui_render_string_tree(arena, node->first_child, highlighted, indent + 2); } } @@ -400,7 +400,7 @@ void update_and_render(Arena *arena, App_State &app, f32 delta_time_ms) ImGui::TextColored(ImColor(0.5f, 0.5f, 0.5f), "(Hint: press Alt for single-field hover information)"); if (hovered_section.id == Sec_Page) ImGui::TextColored(ImColor(0.5f, 0.5f, 0.5f), "(Hint: Shift-Click to jump to the start of this page)"); - imgui_render_string_tree(scratch.arena, hover_info.desc->head); + imgui_render_string_tree(scratch.arena, hover_info.desc->head, hover_info.highlighted_desc); app.viewer.hovered_range = hover_info.rng; // Shift-clicking on a page section will update the current page in the legend diff --git a/src/str.h b/src/str.h index 25e9a0c..e2cdaba 100644 --- a/src/str.h +++ b/src/str.h @@ -15,6 +15,4 @@ struct String8_Node { String8_Node *next, *prev, *head; String8_Node *first_child, *last_child; String8 str; - // @Cleanup: only used by hover.cpp, it should not belong in here... - b8 selected; };