more stuff
This commit is contained in:
parent
c83d457738
commit
cdcf1db83a
3 changed files with 81 additions and 53 deletions
113
src/hover.cpp
113
src/hover.cpp
|
@ -55,6 +55,7 @@ String8_Node *hover_display_datetime_str(Arena *arena, String8_Node *prev, const
|
||||||
return push_str8_node_child(arena, prev, "%s%u/%02u/%02u %02u:%02u:%02u", fmt_pre, year, month, day, hour, min, sec);
|
return push_str8_node_child(arena, prev, "%s%u/%02u/%02u %02u:%02u:%02u", fmt_pre, year, month, day, hour, min, sec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns null is `src` doesn't point to a zipped block
|
||||||
internal
|
internal
|
||||||
String8_Node *display_val_rootzip(Arena *arena, String8_Node *prev, const char *fmt, const u8 *src)
|
String8_Node *display_val_rootzip(Arena *arena, String8_Node *prev, const char *fmt, const u8 *src)
|
||||||
{
|
{
|
||||||
|
@ -89,6 +90,11 @@ String8_Node *display_val_rootzip(Arena *arena, String8_Node *prev, const char *
|
||||||
template <typename T>
|
template <typename T>
|
||||||
using Display_Fn = String8_Node *(*)(Arena *, String8_Node *, const char *, T);
|
using Display_Fn = String8_Node *(*)(Arena *, String8_Node *, const char *, T);
|
||||||
|
|
||||||
|
enum Hover_Section_Flags {
|
||||||
|
HoverSec_None = 0,
|
||||||
|
HoverSec_HideIfNotHovered = 1,
|
||||||
|
};
|
||||||
|
|
||||||
// Functor used by get_section_hover_info to describe the structure of a section and print data about it.
|
// Functor used by get_section_hover_info to describe the structure of a section and print data about it.
|
||||||
struct Sec_Hover_Fn {
|
struct Sec_Hover_Fn {
|
||||||
u64 start; // the start of the section (including the pre_size, e.g. the TKey)
|
u64 start; // the start of the section (including the pre_size, e.g. the TKey)
|
||||||
|
@ -99,34 +105,42 @@ struct Sec_Hover_Fn {
|
||||||
Sec_Hover_Info &info;
|
Sec_Hover_Info &info;
|
||||||
u64 &cur_field_off;
|
u64 &cur_field_off;
|
||||||
b8 display_grouped;
|
b8 display_grouped;
|
||||||
b8 hovered = false;
|
|
||||||
b8 ended = false;
|
b8 ended = false;
|
||||||
|
u8 cur_section_nesting = 0;
|
||||||
|
u8 innermost_section_highlighted = 0;
|
||||||
|
|
||||||
template <typename F>
|
template <typename F>
|
||||||
void titled_section(const char *title, F &&fn)
|
void titled_section(const char *title, F &&sec_body_fn, u64 flags = 0)
|
||||||
{
|
{
|
||||||
if (ended)
|
// if (ended)
|
||||||
return;
|
// return;
|
||||||
|
|
||||||
|
++cur_section_nesting;
|
||||||
String8_Node *prev_desc = info.desc;
|
String8_Node *prev_desc = info.desc;
|
||||||
info.desc = push_str8_node_child(arena, prev_desc, title);
|
info.desc = push_str8_node_child(arena, prev_desc, title);
|
||||||
|
|
||||||
u64 sec_start = cur_field_off;
|
u64 sec_start = cur_field_off;
|
||||||
fn();
|
|
||||||
|
|
||||||
if (!hovered) {
|
sec_body_fn();
|
||||||
// the entire section was not hovered: don't display its description.
|
|
||||||
|
assert(cur_field_off >= sec_start);
|
||||||
|
b8 hovered = roff >= sec_start && roff <= cur_field_off;
|
||||||
|
|
||||||
|
if (!hovered & (flags & HoverSec_HideIfNotHovered)) {
|
||||||
pop_str8_node_child(prev_desc, info.desc);
|
pop_str8_node_child(prev_desc, info.desc);
|
||||||
} else if (display_grouped) {
|
} else if (display_grouped) {
|
||||||
// if we're in display_grouped mode, we want to highlight the entire range of the section;
|
// if we're in display_grouped mode, we want to highlight the entire range of the section;
|
||||||
assert(sec_start <= cur_field_off);
|
|
||||||
u64 sec_len = cur_field_off - sec_start;
|
u64 sec_len = cur_field_off - sec_start;
|
||||||
hovered = roff >= sec_start && roff < sec_start + sec_len;
|
|
||||||
if (hovered) {
|
|
||||||
info.rng = { start + sec_start, sec_len };
|
info.rng = { start + sec_start, sec_len };
|
||||||
ended = true;
|
// In case of nested sections, only highlight the innermost
|
||||||
}
|
// FIXME!
|
||||||
|
info.desc->selected = innermost_section_highlighted < cur_section_nesting;
|
||||||
|
innermost_section_highlighted = max(cur_section_nesting, innermost_section_highlighted);
|
||||||
|
// ended = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
--cur_section_nesting;
|
||||||
|
|
||||||
info.desc = prev_desc;
|
info.desc = prev_desc;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -136,30 +150,33 @@ struct Sec_Hover_Fn {
|
||||||
b8 field(const char *desc_fmt, Display_Fn<T> display_val, T *val_read = nullptr)
|
b8 field(const char *desc_fmt, Display_Fn<T> display_val, T *val_read = nullptr)
|
||||||
{
|
{
|
||||||
static_assert(!std::is_same_v<T, String8>, "use field_str8 instead.");
|
static_assert(!std::is_same_v<T, String8>, "use field_str8 instead.");
|
||||||
if (ended)
|
// if (ended)
|
||||||
return false;
|
// return false;
|
||||||
|
|
||||||
u64 field_len = sizeof(T);
|
u64 field_len = sizeof(T);
|
||||||
if (display_grouped || roff < cur_field_off + field_len) {
|
b8 hovered = cur_field_off <= roff && roff < cur_field_off + field_len;
|
||||||
info.rng = { start + cur_field_off, field_len };
|
|
||||||
T val;
|
T val;
|
||||||
memcpy(&val, (u8 *)data + start + cur_field_off, field_len);
|
memcpy(&val, (u8 *)data + start + cur_field_off, field_len);
|
||||||
display_val(arena, info.desc, desc_fmt, val);
|
String8_Node *desc = display_val(arena, info.desc, desc_fmt, val);
|
||||||
|
desc->selected = hovered && !display_grouped;
|
||||||
if (val_read)
|
if (val_read)
|
||||||
*val_read = val;
|
*val_read = val;
|
||||||
hovered = true;
|
|
||||||
|
if (display_grouped || hovered) {
|
||||||
|
info.rng = { start + cur_field_off, field_len };
|
||||||
// truncate the hovered section here if we're not in display_grouped mode.
|
// truncate the hovered section here if we're not in display_grouped mode.
|
||||||
ended = !display_grouped;
|
// ended = !display_grouped;
|
||||||
}
|
}
|
||||||
cur_field_off += field_len;
|
cur_field_off += field_len;
|
||||||
return hovered;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TStrSize>
|
template <typename TStrSize>
|
||||||
void field_str8(const char *desc_fmt, Display_Fn<String8> display_val = hover_display_val_str8)
|
void field_str8(const char *desc_fmt, Display_Fn<String8> display_val = hover_display_val_str8)
|
||||||
{
|
{
|
||||||
if (ended)
|
// if (ended)
|
||||||
return;
|
// return;
|
||||||
|
|
||||||
// String size can be stored as different types, like u8 (by ROOT I/O) or u32 (by RNTuple).
|
// String size can be stored as different types, like u8 (by ROOT I/O) or u32 (by RNTuple).
|
||||||
TStrSize str_size;
|
TStrSize str_size;
|
||||||
|
@ -167,19 +184,22 @@ struct Sec_Hover_Fn {
|
||||||
// DEBUG
|
// DEBUG
|
||||||
if (str_size > 1000) {
|
if (str_size > 1000) {
|
||||||
printf("read str_size = %u at offset 0x%lX!\n", str_size, start + cur_field_off);
|
printf("read str_size = %u at offset 0x%lX!\n", str_size, start + cur_field_off);
|
||||||
ended = true;
|
// ended = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
u64 field_len = sizeof(TStrSize) + (u64)str_size;
|
u64 field_len = sizeof(TStrSize) + (u64)str_size;
|
||||||
if (display_grouped || roff < cur_field_off + field_len) {
|
b8 hovered = cur_field_off <= roff && roff < cur_field_off + field_len;
|
||||||
info.rng = { start + cur_field_off, field_len };
|
|
||||||
u8 *buf = arena_push_array_nozero<u8>(arena, str_size + 1);
|
u8 *buf = arena_push_array_nozero<u8>(arena, str_size + 1);
|
||||||
memcpy(buf, data + start + cur_field_off + sizeof(TStrSize), str_size);
|
memcpy(buf, data + start + cur_field_off + sizeof(TStrSize), str_size);
|
||||||
buf[str_size] = 0;
|
buf[str_size] = 0;
|
||||||
String8 s = { buf, str_size };
|
String8 s = { buf, str_size };
|
||||||
display_val(arena, info.desc, desc_fmt, s);
|
String8_Node *desc = display_val(arena, info.desc, desc_fmt, s);
|
||||||
hovered = true;
|
desc->selected = hovered && !display_grouped;
|
||||||
ended = !display_grouped;
|
|
||||||
|
if (display_grouped || hovered) {
|
||||||
|
info.rng = { start + cur_field_off, field_len };
|
||||||
|
// ended = !display_grouped;
|
||||||
}
|
}
|
||||||
cur_field_off += field_len;
|
cur_field_off += field_len;
|
||||||
}
|
}
|
||||||
|
@ -199,14 +219,15 @@ struct Sec_Hover_Fn {
|
||||||
// An unspecified range of bytes
|
// An unspecified range of bytes
|
||||||
void range(const char *desc, u64 range_len, Display_Fn<const u8 *> display_val = hover_display_generic_range)
|
void range(const char *desc, u64 range_len, Display_Fn<const u8 *> display_val = hover_display_generic_range)
|
||||||
{
|
{
|
||||||
if (ended)
|
// if (ended)
|
||||||
return;
|
// return;
|
||||||
|
|
||||||
if (display_grouped || roff < cur_field_off + range_len) {
|
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 (display_grouped || hovered) {
|
||||||
info.rng = { start + cur_field_off, range_len };
|
info.rng = { start + cur_field_off, range_len };
|
||||||
display_val(arena, info.desc, desc, data + start + cur_field_off);
|
// ended = !display_grouped;
|
||||||
hovered = true;
|
|
||||||
ended = !display_grouped;
|
|
||||||
}
|
}
|
||||||
cur_field_off += range_len;
|
cur_field_off += range_len;
|
||||||
}
|
}
|
||||||
|
@ -214,17 +235,19 @@ struct Sec_Hover_Fn {
|
||||||
// Returns true if `was_zipped` was read.
|
// Returns true if `was_zipped` was read.
|
||||||
b8 maybe_rootzip(b8 *was_zipped = nullptr)
|
b8 maybe_rootzip(b8 *was_zipped = nullptr)
|
||||||
{
|
{
|
||||||
if (ended)
|
// if (ended)
|
||||||
return false;
|
// return false;
|
||||||
|
|
||||||
// TODO boundary checks
|
// TODO boundary checks
|
||||||
const u64 range_len = 9;
|
const u64 range_len = 9;
|
||||||
|
b8 hovered = cur_field_off <= roff && roff < cur_field_off + range_len;
|
||||||
if (display_val_rootzip(arena, info.desc, "Zipped Block", data + start + cur_field_off)) {
|
if (display_val_rootzip(arena, info.desc, "Zipped Block", data + start + cur_field_off)) {
|
||||||
if (was_zipped) *was_zipped = true;
|
if (display_grouped || hovered) {
|
||||||
if (display_grouped || roff < cur_field_off + range_len) {
|
if (was_zipped)
|
||||||
|
*was_zipped = true;
|
||||||
info.rng = { start + cur_field_off, range_len };
|
info.rng = { start + cur_field_off, range_len };
|
||||||
hovered = true;
|
info.desc->selected = hovered;
|
||||||
ended = !display_grouped;
|
// ended = !display_grouped;
|
||||||
}
|
}
|
||||||
cur_field_off += range_len;
|
cur_field_off += range_len;
|
||||||
} else if (was_zipped) {
|
} else if (was_zipped) {
|
||||||
|
@ -342,7 +365,7 @@ struct Sec_Hover_Fn {
|
||||||
// DEBUG
|
// DEBUG
|
||||||
if (size > 100000) {
|
if (size > 100000) {
|
||||||
printf("read field_frame_size = %lu at offset 0x%lX!\n", size, start + cur_field_off);
|
printf("read field_frame_size = %lu at offset 0x%lX!\n", size, start + cur_field_off);
|
||||||
ended = true;
|
// ended = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
field_le<u32>("Field version: %u");
|
field_le<u32>("Field version: %u");
|
||||||
|
@ -372,7 +395,7 @@ struct Sec_Hover_Fn {
|
||||||
u64 extra_size = size - (cur_field_off - start_off);
|
u64 extra_size = size - (cur_field_off - start_off);
|
||||||
if (extra_size > 0)
|
if (extra_size > 0)
|
||||||
range("Unknown", extra_size);
|
range("Unknown", extra_size);
|
||||||
});
|
}, HoverSec_HideIfNotHovered);
|
||||||
}
|
}
|
||||||
|
|
||||||
void column_desc(const char *title)
|
void column_desc(const char *title)
|
||||||
|
@ -387,7 +410,7 @@ struct Sec_Hover_Fn {
|
||||||
// DEBUG
|
// DEBUG
|
||||||
if (size > 100000) {
|
if (size > 100000) {
|
||||||
printf("read column_desc_size = %lu at offset 0x%lX!\n", size, start + cur_field_off);
|
printf("read column_desc_size = %lu at offset 0x%lX!\n", size, start + cur_field_off);
|
||||||
ended = true;
|
// ended = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -421,7 +444,7 @@ struct Sec_Hover_Fn {
|
||||||
printf("extra size: %lu - %lu = %lu\n", size, cur_field_off - start_off, extra_size);
|
printf("extra size: %lu - %lu = %lu\n", size, cur_field_off - start_off, extra_size);
|
||||||
if (extra_size > 0)
|
if (extra_size > 0)
|
||||||
range("Unknown", extra_size);
|
range("Unknown", extra_size);
|
||||||
});
|
}, HoverSec_HideIfNotHovered);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename F>
|
template <typename F>
|
||||||
|
@ -439,7 +462,7 @@ struct Sec_Hover_Fn {
|
||||||
// DEBUG
|
// DEBUG
|
||||||
if (n_elems > 100000) {
|
if (n_elems > 100000) {
|
||||||
printf("read n_elems = %u at offset 0x%lX!\n", n_elems, start + cur_field_off);
|
printf("read n_elems = %u at offset 0x%lX!\n", n_elems, start + cur_field_off);
|
||||||
ended = true;
|
// ended = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (u32 i = 0; i < n_elems; ++i) {
|
for (u32 i = 0; i < n_elems; ++i) {
|
||||||
|
|
|
@ -225,6 +225,9 @@ void imgui_render_string_tree(Arena *arena, String8_Node *root, u16 indent = 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (String8_Node *node = root; node; node = node->next) {
|
for (String8_Node *node = root; node; node = node->next) {
|
||||||
|
if (node->selected)
|
||||||
|
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());
|
ImGui::Text("%s%s", indent_str.c(), node->str.c());
|
||||||
|
|
||||||
if (node->first_child)
|
if (node->first_child)
|
||||||
|
|
|
@ -15,4 +15,6 @@ struct String8_Node {
|
||||||
String8_Node *next, *prev, *head;
|
String8_Node *next, *prev, *head;
|
||||||
String8_Node *first_child, *last_child;
|
String8_Node *first_child, *last_child;
|
||||||
String8 str;
|
String8 str;
|
||||||
|
// @Cleanup: only used by hover.cpp, it should not belong in here...
|
||||||
|
b8 selected;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue