mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-06-17 17:42:22 -07:00
eliminate old ctx menu paths
This commit is contained in:
@@ -2679,7 +2679,6 @@ rd_window_open(Vec2F32 size, OS_Handle preferred_monitor, RD_CfgSrc cfg_src)
|
||||
window->ctx_menu_regs = push_array(window->ctx_menu_arena, RD_Regs, 1);
|
||||
window->ctx_menu_input_buffer_size = KB(4);
|
||||
window->ctx_menu_input_buffer = push_array(window->arena, U8, window->ctx_menu_input_buffer_size);
|
||||
window->code_ctx_menu_arena = arena_alloc();
|
||||
window->hover_eval_arena = arena_alloc();
|
||||
window->autocomp_lister_params_arena = arena_alloc();
|
||||
window->free_panel = &rd_nil_panel;
|
||||
@@ -3880,713 +3879,6 @@ rd_window_frame(RD_Window *ws)
|
||||
scratch_end(scratch);
|
||||
}
|
||||
|
||||
////////////////////////////
|
||||
//- rjf: universal ctx menus
|
||||
//
|
||||
// TODO(rjf): @msgs to-be-gone:
|
||||
//
|
||||
RD_Palette(RD_PaletteCode_Floating)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
|
||||
//- rjf: auto-close entity ctx menu
|
||||
if(ui_ctx_menu_is_open(rd_state->entity_ctx_menu_key))
|
||||
{
|
||||
RD_Entity *entity = rd_entity_from_handle(ws->entity_ctx_menu_entity);
|
||||
if(rd_entity_is_nil(entity))
|
||||
{
|
||||
ui_ctx_menu_close();
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: code ctx menu
|
||||
UI_CtxMenu(rd_state->code_ctx_menu_key)
|
||||
UI_PrefWidth(ui_em(40.f, 1.f))
|
||||
RD_Palette(RD_PaletteCode_ImplicitButton)
|
||||
{
|
||||
TXT_Scope *txt_scope = txt_scope_open();
|
||||
HS_Scope *hs_scope = hs_scope_open();
|
||||
TxtRng range = ws->code_ctx_menu_range;
|
||||
D_LineList lines = ws->code_ctx_menu_lines;
|
||||
if(!txt_pt_match(range.min, range.max) && ui_clicked(rd_cmd_spec_button(rd_cmd_kind_info_table[RD_CmdKind_Copy].string)))
|
||||
{
|
||||
U128 hash = {0};
|
||||
TXT_TextInfo info = txt_text_info_from_key_lang(txt_scope, ws->code_ctx_menu_text_key, ws->code_ctx_menu_lang_kind, &hash);
|
||||
String8 data = hs_data_from_hash(hs_scope, hash);
|
||||
String8 copy_data = txt_string_from_info_data_txt_rng(&info, data, ws->code_ctx_menu_range);
|
||||
os_set_clipboard_text(copy_data);
|
||||
ui_ctx_menu_close();
|
||||
}
|
||||
if(range.min.line == range.max.line && ui_clicked(rd_icon_buttonf(RD_IconKind_RightArrow, 0, "Set Next Statement")))
|
||||
{
|
||||
CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread);
|
||||
U64 new_rip_vaddr = ws->code_ctx_menu_vaddr;
|
||||
if(ws->code_ctx_menu_file_path.size != 0)
|
||||
{
|
||||
for(D_LineNode *n = lines.first; n != 0; n = n->next)
|
||||
{
|
||||
CTRL_EntityList modules = ctrl_modules_from_dbgi_key(scratch.arena, d_state->ctrl_entity_store, &n->v.dbgi_key);
|
||||
CTRL_Entity *module = ctrl_module_from_thread_candidates(d_state->ctrl_entity_store, thread, &modules);
|
||||
if(module != &ctrl_entity_nil)
|
||||
{
|
||||
new_rip_vaddr = ctrl_vaddr_from_voff(module, n->v.voff_range.min);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
rd_cmd(RD_CmdKind_SetThreadIP, .vaddr = new_rip_vaddr);
|
||||
ui_ctx_menu_close();
|
||||
}
|
||||
if(range.min.line == range.max.line && ui_clicked(rd_icon_buttonf(RD_IconKind_Play, 0, "Run To Line")))
|
||||
{
|
||||
if(ws->code_ctx_menu_file_path.size != 0)
|
||||
{
|
||||
rd_cmd(RD_CmdKind_RunToLine, .file_path = ws->code_ctx_menu_file_path, .cursor = range.min);
|
||||
}
|
||||
else
|
||||
{
|
||||
rd_cmd(RD_CmdKind_RunToAddress, .vaddr = ws->code_ctx_menu_vaddr);
|
||||
}
|
||||
ui_ctx_menu_close();
|
||||
}
|
||||
if(range.min.line == range.max.line && ui_clicked(rd_icon_buttonf(RD_IconKind_Null, 0, "Go To Name")))
|
||||
{
|
||||
U128 hash = {0};
|
||||
TXT_TextInfo info = txt_text_info_from_key_lang(txt_scope, ws->code_ctx_menu_text_key, ws->code_ctx_menu_lang_kind, &hash);
|
||||
String8 data = hs_data_from_hash(hs_scope, hash);
|
||||
Rng1U64 expr_off_range = {0};
|
||||
if(range.min.column != range.max.column)
|
||||
{
|
||||
expr_off_range = r1u64(txt_off_from_info_pt(&info, range.min), txt_off_from_info_pt(&info, range.max));
|
||||
}
|
||||
else
|
||||
{
|
||||
expr_off_range = txt_expr_off_range_from_info_data_pt(&info, data, range.min);
|
||||
}
|
||||
String8 expr = str8_substr(data, expr_off_range);
|
||||
rd_cmd(RD_CmdKind_GoToName, .string = expr);
|
||||
ui_ctx_menu_close();
|
||||
}
|
||||
if(range.min.line == range.max.line && ui_clicked(rd_icon_buttonf(RD_IconKind_CircleFilled, 0, "Toggle Breakpoint")))
|
||||
{
|
||||
rd_cmd(RD_CmdKind_ToggleBreakpoint,
|
||||
.file_path = ws->code_ctx_menu_file_path,
|
||||
.cursor = range.min,
|
||||
.vaddr = ws->code_ctx_menu_vaddr);
|
||||
ui_ctx_menu_close();
|
||||
}
|
||||
if(range.min.line == range.max.line && ui_clicked(rd_icon_buttonf(RD_IconKind_Binoculars, 0, "Toggle Watch Expression")))
|
||||
{
|
||||
U128 hash = {0};
|
||||
TXT_TextInfo info = txt_text_info_from_key_lang(txt_scope, ws->code_ctx_menu_text_key, ws->code_ctx_menu_lang_kind, &hash);
|
||||
String8 data = hs_data_from_hash(hs_scope, hash);
|
||||
Rng1U64 expr_off_range = {0};
|
||||
if(range.min.column != range.max.column)
|
||||
{
|
||||
expr_off_range = r1u64(txt_off_from_info_pt(&info, range.min), txt_off_from_info_pt(&info, range.max));
|
||||
}
|
||||
else
|
||||
{
|
||||
expr_off_range = txt_expr_off_range_from_info_data_pt(&info, data, range.min);
|
||||
}
|
||||
String8 expr = str8_substr(data, expr_off_range);
|
||||
rd_cmd(RD_CmdKind_ToggleWatchExpression, .string = expr);
|
||||
ui_ctx_menu_close();
|
||||
}
|
||||
if(ws->code_ctx_menu_file_path.size == 0 && range.min.line == range.max.line && ui_clicked(rd_icon_buttonf(RD_IconKind_FileOutline, 0, "Go To Source")))
|
||||
{
|
||||
if(lines.first != 0)
|
||||
{
|
||||
rd_cmd(RD_CmdKind_FindCodeLocation,
|
||||
.file_path = lines.first->v.file_path,
|
||||
.cursor = lines.first->v.pt);
|
||||
}
|
||||
ui_ctx_menu_close();
|
||||
}
|
||||
if(ws->code_ctx_menu_file_path.size != 0 && range.min.line == range.max.line && ui_clicked(rd_icon_buttonf(RD_IconKind_FileOutline, 0, "Go To Disassembly")))
|
||||
{
|
||||
CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread);
|
||||
U64 vaddr = 0;
|
||||
for(D_LineNode *n = lines.first; n != 0; n = n->next)
|
||||
{
|
||||
CTRL_EntityList modules = ctrl_modules_from_dbgi_key(scratch.arena, d_state->ctrl_entity_store, &n->v.dbgi_key);
|
||||
CTRL_Entity *module = ctrl_module_from_thread_candidates(d_state->ctrl_entity_store, thread, &modules);
|
||||
if(module != &ctrl_entity_nil)
|
||||
{
|
||||
vaddr = ctrl_vaddr_from_voff(module, n->v.voff_range.min);
|
||||
break;
|
||||
}
|
||||
}
|
||||
rd_cmd(RD_CmdKind_FindCodeLocation, .vaddr = vaddr);
|
||||
ui_ctx_menu_close();
|
||||
}
|
||||
hs_scope_close(hs_scope);
|
||||
txt_scope_close(txt_scope);
|
||||
}
|
||||
|
||||
//- rjf: entity menu
|
||||
UI_CtxMenu(rd_state->entity_ctx_menu_key)
|
||||
UI_PrefWidth(ui_em(40.f, 1.f))
|
||||
RD_Palette(RD_PaletteCode_ImplicitButton)
|
||||
{
|
||||
RD_Entity *entity = rd_entity_from_handle(ws->entity_ctx_menu_entity);
|
||||
CTRL_Entity *entity_ctrl = ctrl_entity_from_handle(d_state->ctrl_entity_store, entity->ctrl_handle);
|
||||
RD_IconKind entity_icon = rd_entity_kind_icon_kind_table[entity->kind];
|
||||
RD_EntityKindFlags kind_flags = rd_entity_kind_flags_table[entity->kind];
|
||||
String8 display_name = rd_display_string_from_entity(scratch.arena, entity);
|
||||
|
||||
// rjf: title
|
||||
UI_Row
|
||||
{
|
||||
ui_spacer(ui_em(1.f, 1.f));
|
||||
RD_Font(RD_FontSlot_Icons)
|
||||
UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Icons))
|
||||
UI_PrefWidth(ui_em(2.f, 1.f))
|
||||
UI_PrefHeight(ui_pct(1, 0))
|
||||
UI_TextAlignment(UI_TextAlign_Center)
|
||||
UI_Flags(UI_BoxFlag_DrawTextWeak)
|
||||
ui_label(rd_icon_kind_text_table[entity_icon]);
|
||||
UI_PrefWidth(ui_text_dim(10, 1))
|
||||
UI_Flags(UI_BoxFlag_DrawTextWeak)
|
||||
ui_label(d_entity_kind_display_string_table[entity->kind]);
|
||||
{
|
||||
UI_Palette *palette = ui_top_palette();
|
||||
if(entity->flags & RD_EntityFlag_HasColor)
|
||||
{
|
||||
palette = ui_build_palette(ui_top_palette(), .text = rd_rgba_from_entity(entity));
|
||||
}
|
||||
UI_Palette(palette)
|
||||
UI_PrefWidth(ui_text_dim(10, 1))
|
||||
RD_Font((kind_flags & RD_EntityKindFlag_NameIsCode) ? RD_FontSlot_Code : RD_FontSlot_Main)
|
||||
ui_label(display_name);
|
||||
}
|
||||
}
|
||||
|
||||
RD_Palette(RD_PaletteCode_Floating) ui_divider(ui_em(1.f, 1.f));
|
||||
|
||||
// rjf: name editor
|
||||
if(kind_flags & RD_EntityKindFlag_CanRename) UI_TextPadding(ui_top_font_size()*1.5f)
|
||||
{
|
||||
UI_Signal sig = rd_line_editf(RD_LineEditFlag_Border, 0, 0, &ws->entity_ctx_menu_input_cursor, &ws->entity_ctx_menu_input_mark, ws->entity_ctx_menu_input_buffer, sizeof(ws->entity_ctx_menu_input_buffer), &ws->entity_ctx_menu_input_size, 0, entity->string, "%S###entity_name_edit_%p", d_entity_kind_name_label_table[entity->kind], entity);
|
||||
if(ui_committed(sig))
|
||||
{
|
||||
rd_cmd(RD_CmdKind_NameEntity,
|
||||
.entity = rd_handle_from_entity(entity),
|
||||
.string = str8(ws->entity_ctx_menu_input_buffer, ws->entity_ctx_menu_input_size));
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: condition editor
|
||||
if(kind_flags & RD_EntityKindFlag_CanCondition)
|
||||
RD_Font(RD_FontSlot_Code)
|
||||
UI_TextPadding(ui_top_font_size()*1.5f)
|
||||
{
|
||||
RD_Entity *condition = rd_entity_child_from_kind(entity, RD_EntityKind_Condition);
|
||||
UI_Signal sig = rd_line_editf(RD_LineEditFlag_Border|RD_LineEditFlag_CodeContents, 0, 0, &ws->entity_ctx_menu_input_cursor, &ws->entity_ctx_menu_input_mark, ws->entity_ctx_menu_input_buffer, sizeof(ws->entity_ctx_menu_input_buffer), &ws->entity_ctx_menu_input_size, 0, condition->string, "Condition###entity_cond_edit_%p", entity);
|
||||
if(ui_committed(sig))
|
||||
{
|
||||
String8 new_string = str8(ws->entity_ctx_menu_input_buffer, ws->entity_ctx_menu_input_size);
|
||||
if(new_string.size != 0)
|
||||
{
|
||||
if(rd_entity_is_nil(condition))
|
||||
{
|
||||
condition = rd_entity_alloc(entity, RD_EntityKind_Condition);
|
||||
}
|
||||
rd_cmd(RD_CmdKind_NameEntity, .entity = rd_handle_from_entity(condition), .string = new_string);
|
||||
}
|
||||
else if(!rd_entity_is_nil(condition))
|
||||
{
|
||||
rd_entity_mark_for_deletion(condition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: exe editor
|
||||
if(entity->kind == RD_EntityKind_Target) UI_TextPadding(ui_top_font_size()*1.5f)
|
||||
{
|
||||
RD_Entity *exe = rd_entity_child_from_kind(entity, RD_EntityKind_Executable);
|
||||
UI_Signal sig = rd_line_editf(RD_LineEditFlag_Border, 0, 0, &ws->entity_ctx_menu_input_cursor, &ws->entity_ctx_menu_input_mark, ws->entity_ctx_menu_input_buffer, sizeof(ws->entity_ctx_menu_input_buffer), &ws->entity_ctx_menu_input_size, 0, exe->string, "Executable###entity_exe_edit_%p", entity);
|
||||
if(ui_committed(sig))
|
||||
{
|
||||
String8 new_string = str8(ws->entity_ctx_menu_input_buffer, ws->entity_ctx_menu_input_size);
|
||||
if(new_string.size != 0)
|
||||
{
|
||||
if(rd_entity_is_nil(exe))
|
||||
{
|
||||
exe = rd_entity_alloc(entity, RD_EntityKind_Executable);
|
||||
}
|
||||
rd_cmd(RD_CmdKind_NameEntity, .entity = rd_handle_from_entity(exe), .string = new_string);
|
||||
}
|
||||
else if(!rd_entity_is_nil(exe))
|
||||
{
|
||||
rd_entity_mark_for_deletion(exe);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: arguments editors
|
||||
if(entity->kind == RD_EntityKind_Target) UI_TextPadding(ui_top_font_size()*1.5f)
|
||||
{
|
||||
RD_Entity *args = rd_entity_child_from_kind(entity, RD_EntityKind_Arguments);
|
||||
UI_Signal sig = rd_line_editf(RD_LineEditFlag_Border, 0, 0, &ws->entity_ctx_menu_input_cursor, &ws->entity_ctx_menu_input_mark, ws->entity_ctx_menu_input_buffer, sizeof(ws->entity_ctx_menu_input_buffer), &ws->entity_ctx_menu_input_size, 0, args->string, "Arguments###entity_args_edit_%p", entity);
|
||||
if(ui_committed(sig))
|
||||
{
|
||||
String8 new_string = str8(ws->entity_ctx_menu_input_buffer, ws->entity_ctx_menu_input_size);
|
||||
if(new_string.size != 0)
|
||||
{
|
||||
if(rd_entity_is_nil(args))
|
||||
{
|
||||
args = rd_entity_alloc(entity, RD_EntityKind_Arguments);
|
||||
}
|
||||
rd_cmd(RD_CmdKind_NameEntity, .entity = rd_handle_from_entity(args), .string = new_string);
|
||||
}
|
||||
else if(!rd_entity_is_nil(args))
|
||||
{
|
||||
rd_entity_mark_for_deletion(args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: copy name
|
||||
if(ui_clicked(rd_icon_buttonf(RD_IconKind_Clipboard, 0, "Copy Name")))
|
||||
{
|
||||
os_set_clipboard_text(display_name);
|
||||
ui_ctx_menu_close();
|
||||
}
|
||||
|
||||
// rjf: is command line only? -> make permanent
|
||||
if(entity->cfg_src == RD_CfgSrc_CommandLine && ui_clicked(rd_icon_buttonf(RD_IconKind_Save, 0, "Save To Project")))
|
||||
{
|
||||
rd_entity_equip_cfg_src(entity, RD_CfgSrc_Project);
|
||||
}
|
||||
|
||||
// rjf: duplicate
|
||||
if(kind_flags & RD_EntityKindFlag_CanDuplicate && ui_clicked(rd_icon_buttonf(RD_IconKind_XSplit, 0, "Duplicate")))
|
||||
{
|
||||
rd_cmd(RD_CmdKind_DuplicateEntity, .entity = rd_handle_from_entity(entity));
|
||||
ui_ctx_menu_close();
|
||||
}
|
||||
|
||||
// rjf: edit
|
||||
if(kind_flags & RD_EntityKindFlag_CanEdit && ui_clicked(rd_icon_buttonf(RD_IconKind_Pencil, 0, "Edit")))
|
||||
{
|
||||
rd_cmd(RD_CmdKind_EditEntity, .entity = rd_handle_from_entity(entity));
|
||||
ui_ctx_menu_close();
|
||||
}
|
||||
|
||||
// rjf: deletion
|
||||
if(kind_flags & RD_EntityKindFlag_CanDelete && ui_clicked(rd_icon_buttonf(RD_IconKind_Trash, 0, "Delete")))
|
||||
{
|
||||
rd_cmd(RD_CmdKind_RemoveEntity, .entity = rd_handle_from_entity(entity));
|
||||
ui_ctx_menu_close();
|
||||
}
|
||||
|
||||
// rjf: enabling
|
||||
if(kind_flags & RD_EntityKindFlag_CanEnable)
|
||||
{
|
||||
B32 is_enabled = !entity->disabled;
|
||||
if(!is_enabled && ui_clicked(rd_icon_buttonf(RD_IconKind_CheckHollow, 0, "Enable###enabler")))
|
||||
{
|
||||
rd_cmd(RD_CmdKind_EnableEntity, .entity = rd_handle_from_entity(entity));
|
||||
}
|
||||
if(is_enabled && ui_clicked(rd_icon_buttonf(RD_IconKind_CheckFilled, 0, "Disable###enabler")))
|
||||
{
|
||||
rd_cmd(RD_CmdKind_DisableEntity, .entity = rd_handle_from_entity(entity));
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: freezing
|
||||
if(kind_flags & RD_EntityKindFlag_CanFreeze)
|
||||
{
|
||||
B32 is_frozen = ctrl_entity_tree_is_frozen(entity_ctrl);
|
||||
ui_set_next_palette(rd_palette_from_code(is_frozen ? RD_PaletteCode_NegativePopButton : RD_PaletteCode_PositivePopButton));
|
||||
if(is_frozen && ui_clicked(rd_icon_buttonf(RD_IconKind_Locked, 0, "Thaw###freeze_thaw")))
|
||||
{
|
||||
rd_cmd(RD_CmdKind_ThawEntity, .entity = rd_handle_from_entity(entity));
|
||||
}
|
||||
if(!is_frozen && ui_clicked(rd_icon_buttonf(RD_IconKind_Unlocked, 0, "Freeze###freeze_thaw")))
|
||||
{
|
||||
rd_cmd(RD_CmdKind_FreezeEntity, .entity = rd_handle_from_entity(entity));
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: go-to-location
|
||||
{
|
||||
RD_Entity *loc = rd_entity_child_from_kind(entity, RD_EntityKind_Location);
|
||||
if(!rd_entity_is_nil(loc) && ui_clicked(rd_icon_buttonf(RD_IconKind_FileOutline, 0, "Go To Location")))
|
||||
{
|
||||
rd_cmd(RD_CmdKind_FindCodeLocation,
|
||||
.file_path = loc->string,
|
||||
.cursor = loc->text_point,
|
||||
.vaddr = loc->vaddr);
|
||||
ui_ctx_menu_close();
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: entity-kind-specific options
|
||||
switch(entity->kind)
|
||||
{
|
||||
default:
|
||||
{
|
||||
}break;
|
||||
|
||||
case RD_EntityKind_Process:
|
||||
case RD_EntityKind_Thread:
|
||||
{
|
||||
if(entity->kind == RD_EntityKind_Thread)
|
||||
{
|
||||
CTRL_Entity *entity_ctrl = ctrl_entity_from_handle(d_state->ctrl_entity_store, entity->ctrl_handle);
|
||||
B32 is_selected = ctrl_handle_match(rd_base_regs()->thread, entity_ctrl->handle);
|
||||
if(is_selected)
|
||||
{
|
||||
rd_icon_buttonf(RD_IconKind_Thread, 0, "[Selected]###select_entity");
|
||||
}
|
||||
else if(ui_clicked(rd_icon_buttonf(RD_IconKind_Thread, 0, "Select###select_entity")))
|
||||
{
|
||||
rd_cmd(RD_CmdKind_SelectThread, .thread = entity_ctrl->handle);
|
||||
ui_ctx_menu_close();
|
||||
}
|
||||
}
|
||||
|
||||
if(ui_clicked(rd_icon_buttonf(RD_IconKind_Clipboard, 0, "Copy ID")))
|
||||
{
|
||||
U32 ctrl_id = entity->ctrl_id;
|
||||
String8 string = push_str8f(scratch.arena, "%i", (int)ctrl_id);
|
||||
os_set_clipboard_text(string);
|
||||
ui_ctx_menu_close();
|
||||
}
|
||||
|
||||
if(entity->kind == RD_EntityKind_Thread)
|
||||
{
|
||||
if(ui_clicked(rd_icon_buttonf(RD_IconKind_Clipboard, 0, "Copy Instruction Pointer Address")))
|
||||
{
|
||||
CTRL_Entity *entity_ctrl = ctrl_entity_from_handle(d_state->ctrl_entity_store, entity->ctrl_handle);
|
||||
U64 rip = d_query_cached_rip_from_thread(entity_ctrl);
|
||||
String8 string = push_str8f(scratch.arena, "0x%I64x", rip);
|
||||
os_set_clipboard_text(string);
|
||||
ui_ctx_menu_close();
|
||||
}
|
||||
}
|
||||
|
||||
if(entity->kind == RD_EntityKind_Thread)
|
||||
{
|
||||
if(ui_clicked(rd_icon_buttonf(RD_IconKind_Clipboard, 0, "Copy Call Stack")))
|
||||
{
|
||||
DI_Scope *di_scope = di_scope_open();
|
||||
CTRL_Entity *entity_ctrl = ctrl_entity_from_handle(d_state->ctrl_entity_store, entity->ctrl_handle);
|
||||
CTRL_Entity *process = ctrl_entity_ancestor_from_kind(entity_ctrl, CTRL_EntityKind_Process);
|
||||
CTRL_Unwind base_unwind = d_query_cached_unwind_from_thread(entity_ctrl);
|
||||
D_Unwind rich_unwind = d_unwind_from_ctrl_unwind(scratch.arena, di_scope, process, &base_unwind);
|
||||
String8List lines = {0};
|
||||
for(U64 frame_idx = 0; frame_idx < rich_unwind.frames.concrete_frame_count; frame_idx += 1)
|
||||
{
|
||||
D_UnwindFrame *concrete_frame = &rich_unwind.frames.v[frame_idx];
|
||||
U64 rip_vaddr = regs_rip_from_arch_block(entity->arch, concrete_frame->regs);
|
||||
CTRL_Entity *module = ctrl_module_from_process_vaddr(process, rip_vaddr);
|
||||
RDI_Parsed *rdi = concrete_frame->rdi;
|
||||
RDI_Procedure *procedure = concrete_frame->procedure;
|
||||
for(D_UnwindInlineFrame *inline_frame = concrete_frame->last_inline_frame;
|
||||
inline_frame != 0;
|
||||
inline_frame = inline_frame->prev)
|
||||
{
|
||||
RDI_InlineSite *inline_site = inline_frame->inline_site;
|
||||
String8 name = {0};
|
||||
name.str = rdi_string_from_idx(rdi, inline_site->name_string_idx, &name.size);
|
||||
str8_list_pushf(scratch.arena, &lines, "0x%I64x: [inlined] \"%S\"%s%S", rip_vaddr, name, module == &ctrl_entity_nil ? "" : " in ", module->string);
|
||||
}
|
||||
if(procedure != 0)
|
||||
{
|
||||
String8 name = {0};
|
||||
name.str = rdi_name_from_procedure(rdi, procedure, &name.size);
|
||||
str8_list_pushf(scratch.arena, &lines, "0x%I64x: \"%S\"%s%S", rip_vaddr, name, module == &ctrl_entity_nil ? "" : " in ", module->string);
|
||||
}
|
||||
else if(module != &ctrl_entity_nil)
|
||||
{
|
||||
str8_list_pushf(scratch.arena, &lines, "0x%I64x: [??? in %S]", rip_vaddr, module->string);
|
||||
}
|
||||
else
|
||||
{
|
||||
str8_list_pushf(scratch.arena, &lines, "0x%I64x: [??? in ???]", rip_vaddr);
|
||||
}
|
||||
}
|
||||
StringJoin join = {0};
|
||||
join.sep = join.post = str8_lit("\n");
|
||||
String8 text = str8_list_join(scratch.arena, &lines, &join);
|
||||
os_set_clipboard_text(text);
|
||||
ui_ctx_menu_close();
|
||||
di_scope_close(di_scope);
|
||||
}
|
||||
}
|
||||
|
||||
if(entity->kind == RD_EntityKind_Thread)
|
||||
{
|
||||
if(ui_clicked(rd_icon_buttonf(RD_IconKind_FileOutline, 0, "Find")))
|
||||
{
|
||||
rd_cmd(RD_CmdKind_FindThread, .entity = rd_handle_from_entity(entity));
|
||||
ui_ctx_menu_close();
|
||||
}
|
||||
}
|
||||
}break;
|
||||
|
||||
case RD_EntityKind_Module:
|
||||
{
|
||||
UI_Signal copy_full_path_sig = rd_icon_buttonf(RD_IconKind_Clipboard, 0, "Copy Full Path");
|
||||
if(ui_clicked(copy_full_path_sig))
|
||||
{
|
||||
String8 string = entity->string;
|
||||
os_set_clipboard_text(string);
|
||||
ui_ctx_menu_close();
|
||||
}
|
||||
if(ui_hovering(copy_full_path_sig)) UI_Tooltip
|
||||
{
|
||||
String8 string = entity->string;
|
||||
ui_label(string);
|
||||
}
|
||||
if(ui_clicked(rd_icon_buttonf(RD_IconKind_Clipboard, 0, "Copy Base Address")))
|
||||
{
|
||||
Rng1U64 vaddr_rng = entity->vaddr_rng;
|
||||
String8 string = push_str8f(scratch.arena, "0x%I64x", vaddr_rng.min);
|
||||
os_set_clipboard_text(string);
|
||||
ui_ctx_menu_close();
|
||||
}
|
||||
if(ui_clicked(rd_icon_buttonf(RD_IconKind_Clipboard, 0, "Copy Address Range Size")))
|
||||
{
|
||||
Rng1U64 vaddr_rng = entity->vaddr_rng;
|
||||
String8 string = push_str8f(scratch.arena, "0x%I64x", dim_1u64(vaddr_rng));
|
||||
os_set_clipboard_text(string);
|
||||
ui_ctx_menu_close();
|
||||
}
|
||||
}break;
|
||||
|
||||
case RD_EntityKind_Target:
|
||||
{
|
||||
if(ui_clicked(rd_icon_buttonf(RD_IconKind_Play, 0, "Launch And Run")))
|
||||
{
|
||||
rd_cmd(RD_CmdKind_LaunchAndRun, .entity = rd_handle_from_entity(entity));
|
||||
ui_ctx_menu_close();
|
||||
}
|
||||
if(ui_clicked(rd_icon_buttonf(RD_IconKind_PlayStepForward, 0, "Launch And Initialize")))
|
||||
{
|
||||
rd_cmd(RD_CmdKind_LaunchAndInit, .entity = rd_handle_from_entity(entity));
|
||||
ui_ctx_menu_close();
|
||||
}
|
||||
}break;
|
||||
}
|
||||
|
||||
RD_Palette(RD_PaletteCode_Floating) ui_divider(ui_em(1.f, 1.f));
|
||||
|
||||
// rjf: color editor
|
||||
{
|
||||
B32 entity_has_color = entity->flags & RD_EntityFlag_HasColor;
|
||||
if(entity_has_color)
|
||||
{
|
||||
UI_Padding(ui_em(1.5f, 1.f))
|
||||
{
|
||||
ui_set_next_pref_height(ui_em(9.f, 1.f));
|
||||
UI_Row UI_Padding(ui_pct(1, 0))
|
||||
{
|
||||
UI_PrefWidth(ui_em(1.5f, 1.f)) UI_PrefHeight(ui_em(9.f, 1.f)) UI_Column UI_PrefHeight(ui_em(1.5f, 0.f))
|
||||
{
|
||||
Vec4F32 presets[] =
|
||||
{
|
||||
v4f32(1.0f, 0.2f, 0.1f, 1.0f),
|
||||
v4f32(1.0f, 0.8f, 0.2f, 1.0f),
|
||||
v4f32(0.3f, 0.8f, 0.2f, 1.0f),
|
||||
v4f32(0.1f, 0.8f, 0.4f, 1.0f),
|
||||
v4f32(0.1f, 0.6f, 0.8f, 1.0f),
|
||||
v4f32(0.5f, 0.3f, 0.8f, 1.0f),
|
||||
v4f32(0.8f, 0.3f, 0.5f, 1.0f),
|
||||
};
|
||||
UI_CornerRadius(ui_em(0.3f, 1.f).value)
|
||||
for(U64 preset_idx = 0; preset_idx < ArrayCount(presets); preset_idx += 1)
|
||||
{
|
||||
ui_set_next_hover_cursor(OS_Cursor_HandPoint);
|
||||
ui_set_next_palette(ui_build_palette(ui_top_palette(), .background = presets[preset_idx]));
|
||||
UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_DrawBackground|
|
||||
UI_BoxFlag_DrawBorder|
|
||||
UI_BoxFlag_Clickable|
|
||||
UI_BoxFlag_DrawHotEffects|
|
||||
UI_BoxFlag_DrawActiveEffects,
|
||||
"###color_preset_%i", (int)preset_idx);
|
||||
UI_Signal sig = ui_signal_from_box(box);
|
||||
if(ui_clicked(sig))
|
||||
{
|
||||
Vec3F32 hsv = hsv_from_rgb(v3f32(presets[preset_idx].x, presets[preset_idx].y, presets[preset_idx].z));
|
||||
Vec4F32 hsva = v4f32(hsv.x, hsv.y, hsv.z, 1);
|
||||
entity->color_hsva = hsva;
|
||||
}
|
||||
ui_spacer(ui_em(0.3f, 1.f));
|
||||
}
|
||||
}
|
||||
|
||||
ui_spacer(ui_em(0.75f, 1.f));
|
||||
|
||||
UI_PrefWidth(ui_em(9.f, 1.f)) UI_PrefHeight(ui_em(9.f, 1.f))
|
||||
{
|
||||
ui_sat_val_pickerf(entity->color_hsva.x, &entity->color_hsva.y, &entity->color_hsva.z, "###ent_satval_picker");
|
||||
}
|
||||
|
||||
ui_spacer(ui_em(0.75f, 1.f));
|
||||
|
||||
UI_PrefWidth(ui_em(1.5f, 1.f)) UI_PrefHeight(ui_em(9.f, 1.f))
|
||||
ui_hue_pickerf(&entity->color_hsva.x, entity->color_hsva.y, entity->color_hsva.z, "###ent_hue_picker");
|
||||
}
|
||||
}
|
||||
|
||||
UI_Row UI_Padding(ui_pct(1, 0)) UI_PrefWidth(ui_em(16.f, 1.f)) UI_CornerRadius(8.f) UI_TextAlignment(UI_TextAlign_Center)
|
||||
RD_Palette(RD_PaletteCode_Floating)
|
||||
{
|
||||
if(ui_clicked(rd_icon_buttonf(RD_IconKind_Trash, 0, "Remove Color###color_toggle")))
|
||||
{
|
||||
entity->flags &= ~RD_EntityFlag_HasColor;
|
||||
}
|
||||
}
|
||||
|
||||
ui_spacer(ui_em(1.5f, 1.f));
|
||||
}
|
||||
if(!entity_has_color && ui_clicked(rd_icon_buttonf(RD_IconKind_Palette, 0, "Apply Color###color_toggle")))
|
||||
{
|
||||
rd_entity_equip_color_rgba(entity, v4f32(1, 1, 1, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: auto-close tab ctx menu
|
||||
if(ui_ctx_menu_is_open(rd_state->tab_ctx_menu_key))
|
||||
{
|
||||
RD_View *tab = rd_view_from_handle(ws->tab_ctx_menu_view);
|
||||
if(rd_view_is_nil(tab))
|
||||
{
|
||||
ui_ctx_menu_close();
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: tab menu
|
||||
UI_CtxMenu(rd_state->tab_ctx_menu_key) UI_PrefWidth(ui_em(40.f, 1.f)) UI_CornerRadius(0)
|
||||
RD_Palette(RD_PaletteCode_ImplicitButton)
|
||||
{
|
||||
RD_Panel *panel = rd_panel_from_handle(ws->tab_ctx_menu_panel);
|
||||
RD_View *view = rd_view_from_handle(ws->tab_ctx_menu_view);
|
||||
RD_IconKind view_icon = rd_icon_kind_from_view(view);
|
||||
DR_FancyStringList fstrs = rd_title_fstrs_from_view(scratch.arena, view, ui_top_palette()->text, ui_top_palette()->text_weak, ui_top_font_size());
|
||||
String8 file_path = rd_file_path_from_eval_string(scratch.arena, str8(view->query_buffer, view->query_string_size));
|
||||
|
||||
// rjf: title
|
||||
UI_Row
|
||||
{
|
||||
ui_spacer(ui_em(1.f, 1.f));
|
||||
RD_Font(RD_FontSlot_Icons)
|
||||
UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Icons))
|
||||
UI_PrefWidth(ui_em(2.f, 1.f))
|
||||
UI_PrefHeight(ui_pct(1, 0))
|
||||
UI_TextAlignment(UI_TextAlign_Center)
|
||||
UI_FlagsAdd(UI_BoxFlag_DrawTextWeak)
|
||||
ui_label(rd_icon_kind_text_table[view_icon]);
|
||||
UI_PrefWidth(ui_text_dim(10, 1))
|
||||
{
|
||||
UI_Box *name_box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero());
|
||||
ui_box_equip_display_fancy_strings(name_box, &fstrs);
|
||||
}
|
||||
}
|
||||
|
||||
RD_Palette(RD_PaletteCode_Floating) ui_divider(ui_em(1.f, 1.f));
|
||||
|
||||
// rjf: copy name
|
||||
if(ui_clicked(rd_icon_buttonf(RD_IconKind_Clipboard, 0, "Copy Name")))
|
||||
{
|
||||
os_set_clipboard_text(dr_string_from_fancy_string_list(scratch.arena, &fstrs));
|
||||
ui_ctx_menu_close();
|
||||
}
|
||||
|
||||
// rjf: copy full path
|
||||
if(file_path.size != 0)
|
||||
{
|
||||
UI_Signal copy_full_path_sig = rd_icon_buttonf(RD_IconKind_Clipboard, 0, "Copy Full Path");
|
||||
String8 full_path = path_normalized_from_string(scratch.arena, file_path);
|
||||
if(ui_clicked(copy_full_path_sig))
|
||||
{
|
||||
os_set_clipboard_text(full_path);
|
||||
ui_ctx_menu_close();
|
||||
}
|
||||
if(ui_hovering(copy_full_path_sig)) UI_Tooltip
|
||||
{
|
||||
ui_label(full_path);
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: show in explorer
|
||||
if(file_path.size != 0)
|
||||
{
|
||||
UI_Signal sig = rd_icon_buttonf(RD_IconKind_FolderClosedFilled, 0, "Show In Explorer");
|
||||
if(ui_clicked(sig))
|
||||
{
|
||||
String8 full_path = path_normalized_from_string(scratch.arena, file_path);
|
||||
os_show_in_filesystem_ui(full_path);
|
||||
ui_ctx_menu_close();
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: filter controls
|
||||
if(view->spec->flags & RD_ViewRuleInfoFlag_CanFilter)
|
||||
{
|
||||
if(ui_clicked(rd_cmd_spec_button(rd_cmd_kind_info_table[RD_CmdKind_Filter].display_name)))
|
||||
{
|
||||
rd_cmd(RD_CmdKind_Filter, .view = rd_handle_from_view(view));
|
||||
ui_ctx_menu_close();
|
||||
}
|
||||
if(ui_clicked(rd_cmd_spec_button(rd_cmd_kind_info_table[RD_CmdKind_ClearFilter].display_name)))
|
||||
{
|
||||
rd_cmd(RD_CmdKind_ClearFilter, .view = rd_handle_from_view(view));
|
||||
ui_ctx_menu_close();
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: close tab
|
||||
if(ui_clicked(rd_icon_buttonf(RD_IconKind_X, 0, "Close Tab")))
|
||||
{
|
||||
rd_cmd(RD_CmdKind_CloseTab, .panel = rd_handle_from_panel(panel), .view = rd_handle_from_view(view));
|
||||
ui_ctx_menu_close();
|
||||
}
|
||||
|
||||
// rjf: param tree editing
|
||||
UI_TextPadding(ui_top_font_size()*1.5f) RD_Font(RD_FontSlot_Code)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
String8 schema_string = view->spec->params_schema;
|
||||
MD_TokenizeResult schema_tokenize = md_tokenize_from_text(scratch.arena, schema_string);
|
||||
MD_ParseResult schema_parse = md_parse_from_text_tokens(scratch.arena, str8_zero(), schema_string, schema_tokenize.tokens);
|
||||
MD_Node *schema_root = schema_parse.root->first;
|
||||
if(!md_node_is_nil(schema_root))
|
||||
{
|
||||
if(!md_node_is_nil(schema_root->first))
|
||||
{
|
||||
RD_Palette(RD_PaletteCode_Floating) ui_divider(ui_em(1.f, 1.f));
|
||||
}
|
||||
for MD_EachNode(key, schema_root->first)
|
||||
{
|
||||
UI_Row
|
||||
{
|
||||
MD_Node *params = view->params_roots[view->params_write_gen%ArrayCount(view->params_roots)];
|
||||
MD_Node *param_tree = md_child_from_string(params, key->string, 0);
|
||||
String8 pre_edit_value = md_string_from_children(scratch.arena, param_tree);
|
||||
UI_PrefWidth(ui_em(10.f, 1.f)) ui_label(key->string);
|
||||
UI_Signal sig = rd_line_editf(RD_LineEditFlag_Border|RD_LineEditFlag_CodeContents, 0, 0, &ws->tab_ctx_menu_input_cursor, &ws->tab_ctx_menu_input_mark, ws->tab_ctx_menu_input_buffer, sizeof(ws->tab_ctx_menu_input_buffer), &ws->tab_ctx_menu_input_size, 0, pre_edit_value, "%S##view_param", key->string);
|
||||
if(ui_committed(sig))
|
||||
{
|
||||
String8 new_string = str8(ws->tab_ctx_menu_input_buffer, ws->tab_ctx_menu_input_size);
|
||||
rd_view_store_param(view, key->string, new_string);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
scratch_end(scratch);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
scratch_end(scratch);
|
||||
}
|
||||
|
||||
////////////////////////////
|
||||
//- rjf: popup
|
||||
//
|
||||
@@ -10397,9 +9689,6 @@ rd_init(CmdLine *cmdln)
|
||||
rd_state->key_map_arena = arena_alloc();
|
||||
rd_state->popup_arena = arena_alloc();
|
||||
rd_state->ctx_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("top_level_ctx_menu"));
|
||||
rd_state->code_ctx_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_code_ctx_menu_"));
|
||||
rd_state->entity_ctx_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_entity_ctx_menu_"));
|
||||
rd_state->tab_ctx_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_tab_ctx_menu_"));
|
||||
rd_state->string_search_arena = arena_alloc();
|
||||
rd_state->eval_viz_view_cache_slots_count = 1024;
|
||||
rd_state->eval_viz_view_cache_slots = push_array(arena, RD_EvalVizViewCacheSlot, rd_state->eval_viz_view_cache_slots_count);
|
||||
@@ -11268,7 +10557,6 @@ rd_frame(void)
|
||||
os_window_close(ws->os);
|
||||
arena_release(ws->query_cmd_arena);
|
||||
arena_release(ws->ctx_menu_arena);
|
||||
arena_release(ws->code_ctx_menu_arena);
|
||||
arena_release(ws->hover_eval_arena);
|
||||
arena_release(ws->autocomp_lister_params_arena);
|
||||
arena_release(ws->arena);
|
||||
|
||||
@@ -663,30 +663,6 @@ struct RD_Window
|
||||
TxtPt ctx_menu_input_cursor;
|
||||
TxtPt ctx_menu_input_mark;
|
||||
|
||||
// rjf: code context menu state
|
||||
Arena *code_ctx_menu_arena;
|
||||
String8 code_ctx_menu_file_path;
|
||||
U128 code_ctx_menu_text_key;
|
||||
TXT_LangKind code_ctx_menu_lang_kind;
|
||||
TxtRng code_ctx_menu_range;
|
||||
U64 code_ctx_menu_vaddr;
|
||||
D_LineList code_ctx_menu_lines;
|
||||
|
||||
// rjf: entity context menu state
|
||||
RD_Handle entity_ctx_menu_entity;
|
||||
U8 entity_ctx_menu_input_buffer[1024];
|
||||
U64 entity_ctx_menu_input_size;
|
||||
TxtPt entity_ctx_menu_input_cursor;
|
||||
TxtPt entity_ctx_menu_input_mark;
|
||||
|
||||
// rjf: tab context menu state
|
||||
RD_Handle tab_ctx_menu_panel;
|
||||
RD_Handle tab_ctx_menu_view;
|
||||
U8 tab_ctx_menu_input_buffer[1024];
|
||||
U64 tab_ctx_menu_input_size;
|
||||
TxtPt tab_ctx_menu_input_cursor;
|
||||
TxtPt tab_ctx_menu_input_mark;
|
||||
|
||||
// rjf: autocomplete lister state
|
||||
U64 autocomp_last_frame_idx;
|
||||
B32 autocomp_force_closed;
|
||||
@@ -892,11 +868,6 @@ struct RD_State
|
||||
String8 bind_change_cmd_name;
|
||||
RD_Binding bind_change_binding;
|
||||
|
||||
// rjf: top-level context menu keys
|
||||
UI_Key code_ctx_menu_key;
|
||||
UI_Key entity_ctx_menu_key;
|
||||
UI_Key tab_ctx_menu_key;
|
||||
|
||||
// rjf: windows
|
||||
RD_Window *first_window;
|
||||
RD_Window *last_window;
|
||||
|
||||
@@ -747,10 +747,10 @@ rd_entity_desc_button(RD_Entity *entity, FuzzyMatchRangeList *name_matches, Stri
|
||||
// rjf: right-click => context menu for this entity
|
||||
else if(ui_right_clicked(sig))
|
||||
{
|
||||
RD_Handle handle = rd_handle_from_entity(entity);
|
||||
RD_Window *window = rd_window_from_handle(rd_regs()->window);
|
||||
ui_ctx_menu_open(rd_state->entity_ctx_menu_key, sig.box->key, v2f32(0, sig.box->rect.y1 - sig.box->rect.y0));
|
||||
window->entity_ctx_menu_entity = handle;
|
||||
// RD_Handle handle = rd_handle_from_entity(entity);
|
||||
// RD_Window *window = rd_window_from_handle(rd_regs()->window);
|
||||
// ui_ctx_menu_open(rd_state->entity_ctx_menu_key, sig.box->key, v2f32(0, sig.box->rect.y1 - sig.box->rect.y0));
|
||||
// window->entity_ctx_menu_entity = handle;
|
||||
}
|
||||
|
||||
// rjf: drag+drop
|
||||
@@ -1374,10 +1374,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe
|
||||
// rjf: bp right-click menu
|
||||
if(ui_right_clicked(bp_sig))
|
||||
{
|
||||
RD_Handle handle = rd_handle_from_entity(bp);
|
||||
ui_ctx_menu_open(rd_state->entity_ctx_menu_key, bp_box->key, v2f32(0, bp_box->rect.y1-bp_box->rect.y0));
|
||||
RD_Window *window = rd_window_from_handle(rd_regs()->window);
|
||||
window->entity_ctx_menu_entity = handle;
|
||||
RD_RegsScope(.entity = rd_handle_from_entity(bp)) rd_open_ctx_menu(bp_box->key, v2f32(0, bp_box->rect.y1-bp_box->rect.y0), RD_RegSlot_Entity);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1430,10 +1427,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe
|
||||
// rjf: watch right-click menu
|
||||
if(ui_right_clicked(pin_sig))
|
||||
{
|
||||
RD_Handle handle = rd_handle_from_entity(pin);
|
||||
ui_ctx_menu_open(rd_state->entity_ctx_menu_key, pin_box->key, v2f32(0, pin_box->rect.y1-pin_box->rect.y0));
|
||||
RD_Window *window = rd_window_from_handle(rd_regs()->window);
|
||||
window->entity_ctx_menu_entity = handle;
|
||||
RD_RegsScope(.entity = rd_handle_from_entity(pin)) rd_open_ctx_menu(pin_box->key, v2f32(0, pin_box->rect.y1-pin_box->rect.y0), RD_RegSlot_Entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1655,9 +1649,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe
|
||||
}
|
||||
if(ui_right_clicked(sig))
|
||||
{
|
||||
ui_ctx_menu_open(rd_state->entity_ctx_menu_key, sig.box->key, v2f32(0, sig.box->rect.y1-sig.box->rect.y0));
|
||||
RD_Window *window = rd_window_from_handle(rd_regs()->window);
|
||||
window->entity_ctx_menu_entity = rd_handle_from_entity(pin);
|
||||
RD_RegsScope(.entity = rd_handle_from_entity(pin)) rd_open_ctx_menu(sig.box->key, v2f32(0, sig.box->rect.y1-sig.box->rect.y0), RD_RegSlot_Entity);
|
||||
}
|
||||
}
|
||||
rd_code_label(0.8f, 1, rd_rgba_from_theme_color(RD_ThemeColor_CodeDefault), pin_expr);
|
||||
|
||||
Reference in New Issue
Block a user