u/var: Add nested headers

This commit is contained in:
Mateo de Mayo 2023-01-25 17:18:50 -03:00
parent 6f263dbda4
commit d22f58bee4
2 changed files with 42 additions and 6 deletions
src/xrt
auxiliary/util
state_trackers/gui

View file

@ -187,6 +187,8 @@ enum u_var_kind
U_VAR_KIND_RO_FF_F64,
U_VAR_KIND_RO_FF_VEC3_F32,
U_VAR_KIND_GUI_HEADER,
U_VAR_KIND_GUI_HEADER_BEGIN,
U_VAR_KIND_GUI_HEADER_END,
U_VAR_KIND_BUTTON,
U_VAR_KIND_COMBO,
U_VAR_KIND_HISTOGRAM_F32,
@ -298,6 +300,8 @@ u_var_force_on(void);
ADD_FUNC(ro_ff_f64, struct m_ff_f64, RO_FF_F64) \
ADD_FUNC(ro_ff_vec3_f32, struct m_ff_vec3_f32, RO_FF_VEC3_F32) \
ADD_FUNC(gui_header, bool, GUI_HEADER) \
ADD_FUNC(gui_header_begin, bool, GUI_HEADER_BEGIN) \
ADD_FUNC(gui_header_end, bool, GUI_HEADER_END) \
ADD_FUNC(button, struct u_var_button, BUTTON) \
ADD_FUNC(combo, struct u_var_combo, COMBO) \
ADD_FUNC(draggable_f32, struct u_var_draggable_f32, DRAGGABLE_F32) \

View file

@ -111,11 +111,13 @@ handle_draggable_quat(const char *name, struct xrt_quat *q)
math_quat_normalize(q);
}
#define MAX_HEADER_NESTING 256
struct draw_state
{
struct gui_program *p;
struct debug_scene *ds;
bool hidden;
bool vis_stack[MAX_HEADER_NESTING]; //!< Visibility stack for nested headers
int vis_i;
};
struct plot_state
@ -306,7 +308,8 @@ static void
on_root_enter(const char *name, void *priv)
{
struct draw_state *state = (struct draw_state *)priv;
state->hidden = false;
state->vis_i = 0;
state->vis_stack[0] = true;
igBegin(name, NULL, 0);
}
@ -326,7 +329,20 @@ on_elem(struct u_var_info *info, void *priv)
enum u_var_kind kind = info->kind;
struct draw_state *state = (struct draw_state *)priv;
if (state->hidden && kind != U_VAR_KIND_GUI_HEADER) {
bool visible = state->vis_stack[state->vis_i];
if (kind == U_VAR_KIND_GUI_HEADER_BEGIN) {
state->vis_i++;
state->vis_stack[state->vis_i] = visible;
} else if (kind == U_VAR_KIND_GUI_HEADER_END) {
state->vis_i--;
}
// Check balanced GUI_HEADER_BEGIN/END pairs
assert(state->vis_i >= 0 && state->vis_i < MAX_HEADER_NESTING);
if (!visible && kind != U_VAR_KIND_GUI_HEADER) {
return;
}
@ -429,7 +445,21 @@ on_elem(struct u_var_info *info, void *priv)
case U_VAR_KIND_RO_QUAT_F32: igInputFloat4(name, (float *)ptr, "%+f", ro_i_flags); break;
case U_VAR_KIND_RO_FF_VEC3_F32: on_ff_vec3_var(info, state->p); break;
case U_VAR_KIND_GUI_HEADER: {
state->hidden = !igCollapsingHeaderBoolPtr(name, NULL, 0);
assert(state->vis_i == 0 && "Do not mix GUI_HEADER with GUI_HEADER_BEGIN/END");
state->vis_stack[state->vis_i] = igCollapsingHeaderBoolPtr(name, NULL, 0);
break;
}
case U_VAR_KIND_GUI_HEADER_BEGIN: {
bool is_open = igCollapsingHeaderBoolPtr(name, NULL, 0);
state->vis_stack[state->vis_i] = is_open;
if (is_open) {
igIndent(8.0f);
}
break;
}
case U_VAR_KIND_GUI_HEADER_END: {
igDummy((ImVec2){0, 8.0f});
igUnindent(8.0f);
break;
}
case U_VAR_KIND_SINK_DEBUG: on_sink_debug_var(name, ptr, state->p, state->ds); break;
@ -448,7 +478,9 @@ static void
on_root_exit(const char *name, void *priv)
{
struct draw_state *state = (struct draw_state *)priv;
state->hidden = false;
assert(state->vis_i == 0 && "Unbalanced GUI_HEADER_BEGIN/END pairs");
state->vis_i = 0;
state->vis_stack[0] = false;
igEnd();
}
@ -513,7 +545,7 @@ static void
scene_render(struct gui_scene *scene, struct gui_program *p)
{
struct debug_scene *ds = (struct debug_scene *)scene;
struct draw_state state = {p, ds, false};
struct draw_state state = {p, ds, {0}, 0};
u_var_visit(on_root_enter, on_root_exit, on_elem, &state);
}