prep watch windows for floating query stacks; fix member/array-index generated-expression visualization

This commit is contained in:
Ryan Fleury
2025-04-24 13:39:26 -07:00
parent a9685e6b9d
commit d0cbaee344
5 changed files with 102 additions and 81 deletions
+1 -1
View File
@@ -1295,7 +1295,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden,
e_expr_push_child(call, first_arg);
for(E_Expr *arg = lhs->next; arg != &e_expr_nil; arg = arg->next)
{
e_expr_push_child(call, e_expr_ref(arena, arg));
e_expr_push_child(call, e_expr_copy(arena, arg));
}
result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, call);
E_MsgList new_msgs = {0};
+24 -10
View File
@@ -2348,6 +2348,15 @@ rd_view_ui(Rng2F32 rect)
RD_ViewState *vs = rd_view_state_from_cfg(view);
String8 view_name = view->string;
String8 expr_string = rd_expr_from_cfg(view);
B32 view_is_floating = 0;
for(RD_Cfg *p = view->parent; p != &rd_nil_cfg; p = p->parent)
{
if(str8_match(p->string, str8_lit("immediate"), 0))
{
view_is_floating = 1;
break;
}
}
//////////////////////////////
//- rjf: query extension
@@ -2987,14 +2996,13 @@ rd_view_ui(Rng2F32 rect)
B32 taken = 0;
//////////////////////////////
//- rjf: consume query-completion events, if this view is being used as a query
//- rjf: consume query-completion events, if this view is being used as a lister
//
{
RD_Cfg *lister = rd_cfg_child_from_string(view, str8_lit("lister"));
if(lister != &rd_nil_cfg &&
evt->kind == UI_EventKind_Press &&
if(evt->kind == UI_EventKind_Press &&
evt->slot == UI_EventActionSlot_Accept &&
selection_tbl.min.y == selection_tbl.max.y)
selection_tbl.min.y == selection_tbl.max.y &&
(rd_cfg_child_from_string(view, str8_lit("lister")) != &rd_nil_cfg || view_is_floating))
{
RD_Cfg *query = rd_cfg_child_from_string(view, str8_lit("query"));
RD_Cfg *cmd = rd_cfg_child_from_string(query, str8_lit("cmd"));
@@ -4642,8 +4650,7 @@ rd_view_ui(Rng2F32 rect)
}
// rjf: this watch window is a lister? -> move cursor & accept
RD_Cfg *lister = rd_cfg_child_from_string(view, str8_lit("lister"));
if(lister != &rd_nil_cfg)
if(rd_cfg_child_from_string(view, str8_lit("lister")) != &rd_nil_cfg)
{
ewv->next_cursor = ewv->next_mark = cell_pt;
rd_cmd(RD_CmdKind_Accept);
@@ -4745,6 +4752,13 @@ rd_view_ui(Rng2F32 rect)
{
rd_cmd(RD_CmdKind_SelectThread, .thread = cell_info.entity->handle);
}
// rjf: other cases, but this watch window is floating? -> move cursor & accept
else
{
ewv->next_cursor = ewv->next_mark = cell_pt;
rd_cmd(RD_CmdKind_Accept);
}
}
// rjf: hovering with inheritance string -> show tooltip
@@ -6841,8 +6855,8 @@ rd_window_frame(void)
}
// rjf: view menu
UI_Key view_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_view_menu_key_"));
UI_CtxMenu(view_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) UI_TagF("implicit")
UI_Key tab_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_tab_menu_key_"));
UI_CtxMenu(tab_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) UI_TagF("implicit")
{
String8 cmds[] =
{
@@ -7003,7 +7017,7 @@ rd_window_frame(void)
{str8_lit("File"), 'f', OS_Key_F, file_menu_key},
{str8_lit("Window"), 'w', OS_Key_W, window_menu_key},
{str8_lit("Panel"), 'p', OS_Key_P, panel_menu_key},
{str8_lit("View"), 'v', OS_Key_V, view_menu_key},
{str8_lit("Tab"), 'b', OS_Key_V, tab_menu_key},
{str8_lit("Targets"), 't', OS_Key_T, targets_menu_key},
{str8_lit("Control"), 'c', OS_Key_C, ctrl_menu_key},
{str8_lit("Help"), 'h', OS_Key_H, help_menu_key},
+1
View File
@@ -526,6 +526,7 @@ struct RD_WindowState
B32 query_is_active;
Arena *query_arena;
RD_Regs *query_regs;
RD_CfgID query_view_id;
RD_CfgID query_last_view_id;
// rjf: hover eval state
+75 -69
View File
@@ -1440,6 +1440,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla
//////////////////////////////
//- rjf: unpack evaluation
//
E_Type *block_type = e_type_from_key__cached(row->block->eval.irtree.type_key);
E_Type *cell_type = e_type_from_key__cached(cell->eval.irtree.type_key);
MD_NodePtrList cell_schemas = rd_schemas_from_name(cell_type->name);
if(cell->eval.space.u64s[1] == 0 && cell_schemas.count != 0)
@@ -1612,84 +1613,89 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla
// rjf: if this cell has no string specified, then we need to synthesize one from the evaluation
if(expr_string.size == 0)
{
// rjf: first, locate a notable expression - we special-case things like member accesses
// or array indices, so we should grab those if possible
E_Expr *notable_expr = cell->eval.expr;
for(B32 good = 0; !good;)
// rjf: defaultly fill the cell's expression string, before trying other things
expr_string = cell->eval.string;
// rjf: try to form a simpler expression string out of the expression tree itself, *if* this
// is not an editable expression
if(!(block_type->flags & E_TypeFlag_EditableChildren))
{
// rjf: first, locate a notable expression - we special-case things like member accesses
// or array indices, so we should grab those if possible
E_Expr *notable_expr = cell->eval.expr;
for(B32 good = 0; !good;)
{
switch(notable_expr->kind)
{
default:{good = 1;}break;
case E_ExprKind_Address:
case E_ExprKind_Deref:
case E_ExprKind_Cast:
{
notable_expr = notable_expr->last;
}break;
case E_ExprKind_Ref:
{
notable_expr = notable_expr->ref;
}break;
}
}
// rjf: generate expression string based on our notable expression
switch(notable_expr->kind)
{
default:{good = 1;}break;
case E_ExprKind_Address:
case E_ExprKind_Deref:
case E_ExprKind_Cast:
// rjf: default case -> just take whatever string was directly passed via the evaluation
default:{}break;
// rjf: array indices -> fast path to [index]
case E_ExprKind_ArrayIndex:
{
notable_expr = notable_expr->last;
expr_string = push_str8f(arena, "[%S]", e_string_from_expr(arena, notable_expr->last, str8_zero()));
}break;
case E_ExprKind_Ref:
// rjf: member accesses -> fast-path to .name
case E_ExprKind_MemberAccess:
{
notable_expr = notable_expr->ref;
Temp scratch = scratch_begin(&arena, 1);
// TODO(rjf): @cfg need to build inheritance tooltips
#if 0
if(member.inheritance_key_chain.count != 0)
{
String8List strings = {0};
for(E_TypeKeyNode *n = member.inheritance_key_chain.first; n != 0; n = n->next)
{
String8 base_class_name = e_type_string_from_key(scratch.arena, n->v);
str8_list_push(scratch.arena, &strings, base_class_name);
}
result.inheritance_tooltip = str8_list_join(arena, &strings, &(StringJoin){.sep = str8_lit_comp("::")});
}
#endif
// rjf: in meta-evaluation spaces, we will try to look up into our vocabulary map
// to see if we have a fancy display string for this member. otherwise, we will just
// do a code-string of ".member_name"
String8 member_name = notable_expr->first->next->string;
if(cell->eval.space.kind == RD_EvalSpaceKind_MetaCfg ||
cell->eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity ||
cell->eval.space.kind == E_SpaceKind_File ||
cell->eval.space.kind == E_SpaceKind_FileSystem)
{
String8 fancy_name = rd_display_from_code_name(member_name);
if(fancy_name.size != 0)
{
member_name = fancy_name;
is_non_code = 1;
}
}
if(member_name.size != 0)
{
expr_string = push_str8f(arena, ".%S", member_name);
}
scratch_end(scratch);
}break;
}
}
// rjf: generate expression string based on our notable expression
switch(notable_expr->kind)
{
// rjf: default case -> just take whatever string was directly passed via the evaluation
default:
{
expr_string = cell->eval.string;
}break;
// rjf: array indices -> fast path to [index]
case E_ExprKind_ArrayIndex:
{
expr_string = push_str8f(arena, "[%S]", e_string_from_expr(arena, notable_expr->last, str8_zero()));
}break;
// rjf: member accesses -> fast-path to .name
case E_ExprKind_MemberAccess:
{
Temp scratch = scratch_begin(&arena, 1);
// TODO(rjf): @cfg need to build inheritance tooltips
#if 0
if(member.inheritance_key_chain.count != 0)
{
String8List strings = {0};
for(E_TypeKeyNode *n = member.inheritance_key_chain.first; n != 0; n = n->next)
{
String8 base_class_name = e_type_string_from_key(scratch.arena, n->v);
str8_list_push(scratch.arena, &strings, base_class_name);
}
result.inheritance_tooltip = str8_list_join(arena, &strings, &(StringJoin){.sep = str8_lit_comp("::")});
}
#endif
// rjf: in meta-evaluation spaces, we will try to look up into our vocabulary map
// to see if we have a fancy display string for this member. otherwise, we will just
// do a code-string of ".member_name"
String8 member_name = notable_expr->first->next->string;
if(cell->eval.space.kind == RD_EvalSpaceKind_MetaCfg ||
cell->eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity ||
cell->eval.space.kind == E_SpaceKind_File ||
cell->eval.space.kind == E_SpaceKind_FileSystem)
{
String8 fancy_name = rd_display_from_code_name(member_name);
if(fancy_name.size != 0)
{
expr_string = fancy_name;
is_non_code = 1;
}
}
if(expr_string.size == 0)
{
expr_string = push_str8f(arena, ".%S", member_name);
}
scratch_end(scratch);
}break;
}
}
// rjf: use expression string / params to generate fancy strings
+1 -1
View File
@@ -3454,7 +3454,7 @@ rd_cell(RD_CellParams *params, String8 string)
//////////////////////////////
//- rjf: build bindings
//
if(build_bindings) UI_Parent(box) RD_Font(RD_FontSlot_Main)
if(build_bindings) UI_Parent(box) RD_Font(RD_FontSlot_Main) UI_PermissionFlags(UI_PermissionFlag_Clicks)
{
UI_PrefWidth(ui_children_sum(1)) UI_Column UI_Padding(ui_px(ui_top_px_height()*0.2f, 1.f)) UI_HeightFill
{