watch expr drag/drop -> watch pin creation

This commit is contained in:
Ryan Fleury
2025-02-20 18:11:25 -08:00
parent e4de4dd52f
commit 2373af25ce
6 changed files with 78 additions and 51 deletions
+5 -3
View File
@@ -317,7 +317,7 @@ RD_NameSchemaInfo rd_name_schema_info_table[12] =
{str8_lit_comp("thread"), str8_lit_comp("x:{'label':code_string, 'id':u64, 'frozen':bool, 'call_stack':query}")},
};
Rng1U64 rd_reg_slot_range_table[38] =
Rng1U64 rd_reg_slot_range_table[40] =
{
{0},
{OffsetOf(RD_Regs, machine), OffsetOf(RD_Regs, machine) + sizeof(CTRL_Handle)},
@@ -345,6 +345,8 @@ Rng1U64 rd_reg_slot_range_table[38] =
{OffsetOf(RD_Regs, voff), OffsetOf(RD_Regs, voff) + sizeof(U64)},
{OffsetOf(RD_Regs, vaddr_range), OffsetOf(RD_Regs, vaddr_range) + sizeof(Rng1U64)},
{OffsetOf(RD_Regs, voff_range), OffsetOf(RD_Regs, voff_range) + sizeof(Rng1U64)},
{OffsetOf(RD_Regs, expr), OffsetOf(RD_Regs, expr) + sizeof(String8)},
{OffsetOf(RD_Regs, view_rule), OffsetOf(RD_Regs, view_rule) + sizeof(String8)},
{OffsetOf(RD_Regs, ui_key), OffsetOf(RD_Regs, ui_key) + sizeof(UI_Key)},
{OffsetOf(RD_Regs, off_px), OffsetOf(RD_Regs, off_px) + sizeof(Vec2F32)},
{OffsetOf(RD_Regs, lister_flags), OffsetOf(RD_Regs, lister_flags) + sizeof(RD_ListerFlags)},
@@ -531,8 +533,8 @@ RD_CmdKindInfo rd_cmd_kind_info_table[213] =
{ str8_lit_comp("toggle_breakpoint"), str8_lit_comp("Places or removes a breakpoint at a given location (file path and line number, address, or symbol name)."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}},
{ str8_lit_comp("enable_breakpoint"), str8_lit_comp("Enables a breakpoint."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:breakpoints"), str8_lit_comp(""), CTRL_EntityKind_Null}},
{ str8_lit_comp("disable_breakpoint"), str8_lit_comp("Disables a breakpoint."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:breakpoints"), str8_lit_comp(""), CTRL_EntityKind_Null}},
{ str8_lit_comp("add_watch_pin"), str8_lit_comp("Places a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp("$watch_pins,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}},
{ str8_lit_comp("toggle_watch_pin"), str8_lit_comp("Places or removes a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}},
{ str8_lit_comp("add_watch_pin"), str8_lit_comp("Places a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp("$watch_pins,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Expr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}},
{ str8_lit_comp("toggle_watch_pin"), str8_lit_comp("Places or removes a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Expr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}},
{ str8_lit_comp("add_auto_view_rule"), str8_lit_comp("Adds a new auto view rule."), str8_lit_comp(""), str8_lit_comp("$auto_view_rules,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}},
{ str8_lit_comp("set_next_statement"), str8_lit_comp("Sets the selected thread's instruction pointer to the cursor's position."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}},
{ str8_lit_comp("add_target"), str8_lit_comp("Adds a new target."), str8_lit_comp("application,executable,debug"), str8_lit_comp("$targets,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}},
+7 -1
View File
@@ -34,6 +34,8 @@ RD_RegSlot_Vaddr,
RD_RegSlot_Voff,
RD_RegSlot_VaddrRange,
RD_RegSlot_VoffRange,
RD_RegSlot_Expr,
RD_RegSlot_ViewRule,
RD_RegSlot_UIKey,
RD_RegSlot_OffPx,
RD_RegSlot_ListerFlags,
@@ -550,6 +552,8 @@ U64 vaddr;
U64 voff;
Rng1U64 vaddr_range;
Rng1U64 voff_range;
String8 expr;
String8 view_rule;
UI_Key ui_key;
Vec2F32 off_px;
RD_ListerFlags lister_flags;
@@ -611,6 +615,8 @@ RD_Query query;
.voff = rd_regs()->voff,\
.vaddr_range = rd_regs()->vaddr_range,\
.voff_range = rd_regs()->voff_range,\
.expr = rd_regs()->expr,\
.view_rule = rd_regs()->view_rule,\
.ui_key = rd_regs()->ui_key,\
.off_px = rd_regs()->off_px,\
.lister_flags = rd_regs()->lister_flags,\
@@ -627,7 +633,7 @@ RD_Query query;
C_LINKAGE_BEGIN
extern RD_VocabInfo rd_vocab_info_table[293];
extern RD_NameSchemaInfo rd_name_schema_info_table[12];
extern Rng1U64 rd_reg_slot_range_table[38];
extern Rng1U64 rd_reg_slot_range_table[40];
extern String8 rd_binding_version_remap_old_name_table[8];
extern String8 rd_binding_version_remap_new_name_table[8];
extern String8 rd_icon_kind_text_table[69];
+6 -2
View File
@@ -297,6 +297,10 @@ RD_RegTable:
{Rng1U64 vaddr_range VaddrRange }
{Rng1U64 voff_range VoffRange }
// rjf: evaluation
{String8 expr Expr }
{String8 view_rule ViewRule }
// rjf: ui context
{UI_Key ui_key UIKey }
{Vec2F32 off_px OffPx }
@@ -545,8 +549,8 @@ RD_CmdTable: // | | | |
{DisableBreakpoint 1 1 "query:breakpoints" Cfg null Breakpoint Null 0 0 0 0 0 0 1 CheckHollow "disable_breakpoint" "Disable Breakpoint" "Disables a breakpoint." "" "" }
//- rjf: watch pins
{AddWatchPin 1 1 "" String null Nil Null 0 0 0 0 1 1 1 Pin "add_watch_pin" "Add Watch Pin" "Places a watch pin at a given location (file path and line number or address)." "" "$watch_pins," }
{ToggleWatchPin 1 0 "" String null Nil Null 0 0 0 0 1 1 1 Binoculars "toggle_watch_pin" "Toggle Watch Pin" "Places or removes a watch pin at a given location (file path and line number or address)." "" "" }
{AddWatchPin 1 1 "" Expr null Nil Null 0 0 0 0 1 1 1 Pin "add_watch_pin" "Add Watch Pin" "Places a watch pin at a given location (file path and line number or address)." "" "$watch_pins," }
{ToggleWatchPin 1 0 "" Expr null Nil Null 0 0 0 0 1 1 1 Binoculars "toggle_watch_pin" "Toggle Watch Pin" "Places or removes a watch pin at a given location (file path and line number or address)." "" "" }
//- rjf: auto view rule
{AddAutoViewRule 1 1 "" String null Nil Null 0 0 0 0 0 0 0 Binoculars "add_auto_view_rule" "Add Auto View Rule" "Adds a new auto view rule." "" "$auto_view_rules," }
+36 -31
View File
@@ -1051,6 +1051,8 @@ rd_regs_copy_contents(Arena *arena, RD_Regs *dst, RD_Regs *src)
dst->file_path = push_str8_copy(arena, src->file_path);
dst->lines = d_line_list_copy(arena, &src->lines);
dst->dbgi_key = di_key_copy(arena, &src->dbgi_key);
dst->expr = push_str8_copy(arena, src->expr);
dst->view_rule = push_str8_copy(arena, src->view_rule);
dst->string = push_str8_copy(arena, src->string);
dst->cmd_name = push_str8_copy(arena, src->cmd_name);
dst->params_tree = md_tree_copy(arena, src->params_tree);
@@ -5259,6 +5261,12 @@ rd_view_ui(Rng2F32 rect)
case CTRL_EntityKind_Thread:{RD_RegsScope(.thread = cell_info.entity->handle) rd_drag_begin(RD_RegSlot_Thread);}break;
}
}
else
{
RD_RegsScope(.expr = e_string_from_expr(scratch.arena, row_info->eval.exprs.last),
.view_rule = ev_view_rule_from_key(rd_view_eval_view(), row->key))
rd_drag_begin(RD_RegSlot_Expr);
}
}
// rjf: (normally) single-click -> move selection here
@@ -6267,7 +6275,6 @@ rd_window_frame(void)
//- rjf: build UI
//
UI_Box *lister_box = &ui_nil_box;
UI_Box *hover_eval_box = &ui_nil_box;
ProfScope("build UI")
{
////////////////////////////
@@ -6500,6 +6507,26 @@ rd_window_frame(void)
di_scope_close(di_scope);
}break;
////////////////////////
//- rjf: expression tooltips
//
case RD_RegSlot_Expr:
UI_Tooltip RD_Font(RD_FontSlot_Code)
{
ui_set_next_pref_width(ui_children_sum(1));
UI_Row
{
rd_code_label(1.f, 0, ui_color_from_name(str8_lit("text")), rd_state->drag_drop_regs->expr);
ui_spacer(ui_em(2.f, 1.f));
E_Eval eval = e_eval_from_string(scratch.arena, rd_state->drag_drop_regs->expr);
if(eval.mode != E_Mode_Null)
{
String8 value_string = rd_value_string_from_eval(scratch.arena, str8_zero(), EV_StringFlag_ReadOnlyDisplayRules, 10, ui_top_font(), ui_top_font_size(), ui_top_font_size()*20.f, eval);
rd_code_label(1.f, 0, ui_color_from_name(str8_lit("text")), value_string);
}
}
}break;
}
scratch_end(scratch);
}
@@ -8031,6 +8058,8 @@ rd_window_frame(void)
}
U64 needed_row_count = Min(max_row_count, predicted_block_tree.total_row_count);
F32 num_rows_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "hover_eval_num_rows_t"), (F32)needed_row_count);
// rjf: build container
UI_Focus(ws->hover_eval_focused ? UI_FocusKind_On : UI_FocusKind_Off)
UI_PrefHeight(ui_px(row_height_px, 1.f))
{
@@ -9305,33 +9334,6 @@ rd_window_frame(void)
ui_end_build();
}
//////////////////////////////
//- rjf: ensure hover eval is in-bounds
//
if(!ui_box_is_nil(hover_eval_box))
{
UI_Box *root = hover_eval_box;
Rng2F32 window_rect = os_client_rect_from_window(ui_window());
Rng2F32 root_rect = root->rect;
Vec2F32 shift =
{
-ClampBot(0, root_rect.x1 - window_rect.x1),
-ClampBot(0, root_rect.y1 - window_rect.y1),
};
Rng2F32 new_root_rect = shift_2f32(root_rect, shift);
root->fixed_position = new_root_rect.p0;
root->fixed_size = dim_2f32(new_root_rect);
root->rect = new_root_rect;
for(Axis2 axis = (Axis2)0; axis < Axis2_COUNT; axis = (Axis2)(axis + 1))
{
ui_calc_sizes_standalone__in_place_rec(root, axis);
ui_calc_sizes_upwards_dependent__in_place_rec(root, axis);
ui_calc_sizes_downwards_dependent__in_place_rec(root, axis);
ui_layout_enforce_constraints__in_place_rec(root, axis);
ui_layout_position__in_place_rec(root, axis);
}
}
//////////////////////////////
//- rjf: attach lister boxes to root, or hide if it has not been renewed
//
@@ -15896,7 +15898,8 @@ Z(getting_started)
{
String8 file_path = rd_regs()->file_path;
TxtPt pt = rd_regs()->cursor;
String8 string = rd_regs()->string;
String8 expr_string = rd_regs()->expr;
String8 view_rule_string = rd_regs()->view_rule;
U64 vaddr = rd_regs()->vaddr;
B32 removed_already_existing = 0;
if(kind == RD_CmdKind_ToggleWatchPin)
@@ -15911,7 +15914,7 @@ Z(getting_started)
U64 loc_vaddr = 0;
B32 loc_matches_file_pt = (file_path.size != 0 && path_match_normalized(loc->first->string, file_path) && try_s64_from_str8_c_rules(loc->first->first->string, &loc_line) && loc_line == pt.line);
B32 loc_matches_vaddr = (vaddr != 0 && try_u64_from_str8_c_rules(loc->first->string, &loc_vaddr) && loc_vaddr == vaddr);
B32 loc_matches_expr = (string.size != 0 && str8_match(expr->first->string, string, 0));
B32 loc_matches_expr = (expr_string.size != 0 && str8_match(expr->first->string, expr_string, 0));
if(loc_matches_expr && (loc_matches_file_pt || loc_matches_vaddr))
{
rd_cfg_release(wp);
@@ -15925,8 +15928,10 @@ Z(getting_started)
RD_Cfg *project = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project"));
RD_Cfg *wp = rd_cfg_new(project, str8_lit("watch_pin"));
RD_Cfg *expr = rd_cfg_new(wp, str8_lit("expression"));
RD_Cfg *view_rule = rd_cfg_new(wp, str8_lit("view_rule"));
RD_Cfg *loc = rd_cfg_new(wp, str8_lit("location"));
rd_cfg_new(expr, string);
rd_cfg_new(expr, expr_string);
rd_cfg_new(view_rule, view_rule_string);
if(vaddr != 0)
{
rd_cfg_newf(loc, "0x%I64x", vaddr);
-10
View File
@@ -1543,16 +1543,6 @@ rd_watch_view_text_edit_state_from_pt(RD_WatchViewState *wv, RD_WatchPt pt)
return result;
}
//- rjf: watch view main hooks
internal void
rd_watch_view_build(RD_WatchViewState *ewv, Rng2F32 rect)
{
ProfBeginFunction();
ProfEnd();
}
////////////////////////////////
//~ rjf: null @view_hook_impl
+24 -4
View File
@@ -234,7 +234,7 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg)
}
//- rjf: cfg has expression attached -> use that
else if(expr_string.size != 0 && !str8_match(cfg->string, str8_lit("watch"), 0))
else if(expr_string.size != 0 && !is_within_window)
{
dr_fstrs_push_new(arena, &result, &params, expr_string, .font = rd_font_from_slot(RD_FontSlot_Code), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Code));
dr_fstrs_push_new(arena, &result, &params, str8_lit(" "));
@@ -1829,7 +1829,8 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe
RD_Cfg *pin = n->v;
String8 pin_expr = rd_expr_from_cfg(pin);
String8 pin_view_rule = rd_view_rule_from_cfg(pin);
E_Eval eval = e_eval_from_string(scratch.arena, pin_expr);
String8 full_pin_expr = push_str8f(scratch.arena, "%S => %S", pin_expr, pin_view_rule);
E_Eval eval = e_eval_from_string(scratch.arena, full_pin_expr);
String8 eval_string = {0};
if(!e_type_key_match(e_type_key_zero(), eval.type_key))
{
@@ -2042,6 +2043,12 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe
line_drag_drop_color = pop_color;
}
}
if(rd_state->drag_drop_regs_slot == RD_RegSlot_Expr)
{
line_drag_drop = 1;
line_drag_cfg = cfg;
line_drag_drop_color = pop_color;
}
if(rd_state->drag_drop_regs_slot == RD_RegSlot_Thread)
{
line_drag_drop = 1;
@@ -2055,8 +2062,21 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe
}
//- rjf: drop target is dropped -> process
if(contains_1s64(params->line_num_range, mouse_pt.line) && contains_2f32(clipped_top_container_rect, ui_mouse()))
{
if(line_drag_cfg != &rd_nil_cfg && rd_drag_drop() && contains_1s64(params->line_num_range, mouse_pt.line))
if(rd_state->drag_drop_regs_slot == RD_RegSlot_Expr && rd_drag_drop())
{
S64 line_num = mouse_pt.line;
U64 line_idx = line_num - params->line_num_range.min;
U64 line_vaddr = params->line_vaddrs[line_idx];
rd_cmd(RD_CmdKind_AddWatchPin,
.expr = rd_state->drag_drop_regs->expr,
.view_rule = rd_state->drag_drop_regs->view_rule,
.file_path = line_vaddr == 0 ? rd_regs()->file_path : str8_zero(),
.cursor = line_vaddr == 0 ? txt_pt(line_num, 1) : txt_pt(0, 0),
.vaddr = line_vaddr);
}
if(rd_state->drag_drop_regs_slot == RD_RegSlot_Cfg && line_drag_cfg != &rd_nil_cfg && rd_drag_drop())
{
RD_Cfg *dropped_cfg = line_drag_cfg;
S64 line_num = mouse_pt.line;
@@ -2068,7 +2088,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe
.cursor = line_vaddr == 0 ? txt_pt(line_num, 1) : txt_pt(0, 0),
.vaddr = line_vaddr);
}
if(line_drag_ctrl_entity != &ctrl_entity_nil && rd_drag_drop() && contains_1s64(params->line_num_range, mouse_pt.line))
if(line_drag_ctrl_entity != &ctrl_entity_nil && rd_drag_drop())
{
S64 line_num = mouse_pt.line;
U64 line_idx = line_num - params->line_num_range.min;