diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 43b74c8d..8c8db833 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -661,7 +661,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I E_Type *lhs_type = e_type_from_key(lhs_irtree_try_chain->type_key); E_TypeAccessFunctionType *lhs_access = lhs_type->access; for(E_Type *lens_type = lhs_type; - lens_type->kind == E_TypeKind_Lens || lens_type->kind == E_TypeKind_Set; + lens_type->kind == E_TypeKind_Lens || lens_type->kind == E_TypeKind_Set || (E_TypeKind_FirstMeta <= lens_type->kind && lens_type->kind <= E_TypeKind_LastMeta); lens_type = e_type_from_key(lens_type->direct_type_key)) { if(lens_type->access != 0) @@ -2444,7 +2444,9 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I E_Type *type = e_type_from_key(result.type_key); { E_TypeIRExtFunctionType *irext = type->irext; - for(E_Type *t = type; t->kind == E_TypeKind_Lens || t->kind == E_TypeKind_Set; t = e_type_from_key(t->direct_type_key)) + for(E_Type *t = type; + t->kind == E_TypeKind_Lens || t->kind == E_TypeKind_Set || (E_TypeKind_FirstMeta <= t->kind && t->kind <= E_TypeKind_LastMeta); + t = e_type_from_key(t->direct_type_key)) { if(t->irext != 0) { diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 964762f0..34ed91f3 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -62,7 +62,7 @@ str8_lit_comp(""), str8_lit_comp(""), }; -RD_VocabInfo rd_vocab_info_table[358] = +RD_VocabInfo rd_vocab_info_table[359] = { {str8_lit_comp("type_view"), str8_lit_comp("type_views"), str8_lit_comp("Type View"), str8_lit_comp("Type Views"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -175,6 +175,7 @@ RD_VocabInfo rd_vocab_info_table[358] = {str8_lit_comp("rgba"), str8_lit_comp(""), str8_lit_comp("RGBA"), str8_lit_comp(""), RD_IconKind_Palette}, {str8_lit_comp("path"), str8_lit_comp(""), str8_lit_comp("Path"), str8_lit_comp(""), RD_IconKind_FileOutline}, {str8_lit_comp("guid"), str8_lit_comp(""), str8_lit_comp("GUID"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("peek_type"), str8_lit_comp("peek_types"), str8_lit_comp("Peek Type"), str8_lit_comp("Peek Types"), RD_IconKind_Null}, {str8_lit_comp("launch_and_run"), str8_lit_comp(""), str8_lit_comp("Launch and Run"), str8_lit_comp(""), RD_IconKind_Play}, {str8_lit_comp("launch_and_step_into"), str8_lit_comp(""), str8_lit_comp("Launch and Step Into"), str8_lit_comp(""), RD_IconKind_PlayStepForward}, {str8_lit_comp("kill"), str8_lit_comp(""), str8_lit_comp("Kill"), str8_lit_comp(""), RD_IconKind_X}, @@ -264,7 +265,7 @@ RD_VocabInfo rd_vocab_info_table[358] = {str8_lit_comp("move_view"), str8_lit_comp(""), str8_lit_comp("Move View"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("tab_bar_top"), str8_lit_comp(""), str8_lit_comp("Anchor Tab Bar To Top"), str8_lit_comp(""), RD_IconKind_UpArrow}, {str8_lit_comp("tab_bar_bottom"), str8_lit_comp(""), str8_lit_comp("Anchor Tab Bar To Bottom"), str8_lit_comp(""), RD_IconKind_DownArrow}, -{str8_lit_comp("tab_settings"), str8_lit_comp(""), str8_lit_comp("Tab Settings"), str8_lit_comp(""), RD_IconKind_Gear}, +{str8_lit_comp("tab_settings"), str8_lit_comp(""), str8_lit_comp("Selected Tab Settings"), str8_lit_comp(""), RD_IconKind_Gear}, {str8_lit_comp("set_current_path"), str8_lit_comp(""), str8_lit_comp("Set Current Path"), str8_lit_comp(""), RD_IconKind_FileOutline}, {str8_lit_comp("open"), str8_lit_comp(""), str8_lit_comp("Open"), str8_lit_comp(""), RD_IconKind_FileOutline}, {str8_lit_comp("switch"), str8_lit_comp(""), str8_lit_comp("Switch"), str8_lit_comp(""), RD_IconKind_FileOutline}, @@ -434,8 +435,8 @@ RD_NameSchemaInfo rd_name_schema_info_table[26] = {str8_lit_comp("watch"), str8_lit_comp("@inherit(tab) x:\n{\n @override @display_name('Tab Row Height') @description(\"Controls the tab's row height, in multiples of the font size.\")\n 'row_height': @range[1.75f, 5.f] f32,\n 'label': code_string,\n @description(\"The root expression which is evaluated to produce the watch window.\")\n 'expression': expr_string,\n @no_expand 'watches': query,\n}\n")}, {str8_lit_comp("list"), str8_lit_comp("x:\n{\n @description(\"An expression describing the first node in the list.\")\n 'expression': expr_string,\n @order(0) @description(\"The name of the member which encodes the link to the next node.\")\n 'member_name': code_string,\n}\n")}, {str8_lit_comp("text"), str8_lit_comp("@inherit(tab) @expand_commands(@output clear_output) x:\n{\n @description(\"An expression to describe data which should be viewed as text or code.\")\n 'expression': expr_string,\n @description(\"The language that the text should be interpreted as being within. Used for syntax highlighting and other parsing features.\")\n 'lang': code_string,\n @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers':bool,\n @no_callee_helper @default(1) @display_name('Line Wrapping') @description(\"Splits textual lines into multiple visual lines, so that all text is within the visible area.\")\n 'line_wrapping': bool,\n @no_callee_helper @default(0) @display_name('Scroll To Bottom On Change') @description(\"Scrolls to the bottom if the text is changed.\")\n 'scroll_to_bottom_on_change': bool,\n @no_callee_helper @no_revert @default(0) @display_name('Transient') @description(\"Controls whether or not this tab will be automatically replaced by the debugger when it snaps to new source code locations.\")\n 'auto': bool,\n}\n")}, -{str8_lit_comp("disasm"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe the base address or offset of the disassembly.\")\n 'expression': expr_string,\n 'arch': code_string,\n 'syntax': code_string,\n 'size': expr_string,\n @no_callee_helper @default(1) @description(\"Controls whether or not addresses are shown in the disassembly text.\")\n 'show_addresses': bool,\n @no_callee_helper @default(0) @description(\"Controls whether or not code bytes are shown in the disassembly text.\")\n 'show_code_bytes': bool,\n @no_callee_helper @default(1) @description(\"Controls whether or not source lines, corresponding to disassembly instruction ranges, are shown in the disassembly text.\")\n 'show_source_lines': bool,\n @no_callee_helper @default(1) @description(\"Controls whether or not disassembly text is decorated with symbol names.\")\n 'show_symbol_names': bool,\n @no_callee_helper @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers': bool,\n\n}\n")}, -{str8_lit_comp("memory"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression which refers to the base address of data which should be viewed as memory.\")\n 'expression': expr_string,\n @display_name(\"Address Range Size\") @description(\"The number of bytes of the viewed memory range.\")\n 'size': expr_string,\n @display_name(\"Cursor Address\") @description(\"The address of the cursor.\")\n 'cursor': expr_string,\n @default(1) @display_name(\"Cursor Size\") @description(\"The size, in bytes, of the cursor.\")\n 'cursor_size': @range[1, 16] u64,\n @default(16) @description(\"The number of columns to build before building new rows.\")\n 'num_columns': @range[1, 64] u64,\n @default(1) @display_name(\"Track Mark To Cursor\") @description(\"Ensures that the mark always follows the cursor, if the cursor value is updated.\")\n 'track_mark_to_cursor': bool,\n @default(0) @display_name(\"Edit Mode\") @description(\"Enables editing operations on memory contents.\")\n 'edit_mode': bool,\n}\n")}, +{str8_lit_comp("disasm"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe the base address or offset of the disassembly.\")\n 'expression': expr_string,\n 'arch': code_string,\n 'syntax': code_string,\n 'size': expr_string,\n @no_callee_helper @default(1) @description(\"Controls whether or not addresses are shown in the disassembly text.\")\n 'show_addresses': bool,\n @no_callee_helper @default(0) @description(\"Controls whether or not code bytes are shown in the disassembly text.\")\n 'show_code_bytes': bool,\n @no_callee_helper @default(1) @description(\"Controls whether or not source lines, corresponding to disassembly instruction ranges, are shown in the disassembly text.\")\n 'show_source_lines': bool,\n @no_callee_helper @default(1) @description(\"Controls whether or not disassembly text is decorated with symbol names.\")\n 'show_symbol_names': bool,\n @no_callee_helper @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers': bool,\n}\n")}, +{str8_lit_comp("memory"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Base Address\") @description(\"An expression which refers to the base address of data which should be viewed as memory.\")\n 'expression': expr_string,\n @display_name(\"Address Range Size\") @description(\"The number of bytes of the viewed memory range.\")\n 'size': expr_string,\n @display_name(\"Cursor Address\") @description(\"The address of the cursor.\")\n 'cursor': expr_string,\n @default(1) @display_name(\"Cursor Size\") @description(\"The size, in bytes, of the cursor.\")\n 'cursor_size': @range[1, 16] u64,\n @expand_if(\"!$.auto_columns\") @default(16) @description(\"The number of columns to build before building new rows.\")\n 'num_columns': @range[1, 64] u64,\n @default(1) @display_name(\"Track Mark To Cursor\") @description(\"Ensures that the mark always follows the cursor, if the cursor value is updated.\")\n 'track_mark_to_cursor': bool,\n @default(1) @display_name(\"Allow Mutation\") @description(\"Allows operations which mutate memory.\")\n 'allow_mutation': bool,\n @default(0) @display_name(\"Automatically Size Columns\") @description(\"Determines the number of columns based on the available space.\")\n 'auto_columns': bool,\n @display_name(\"Peek Types\") @description(\"A list of types to interpret selected and hovered memory as.\")\n 'peek_types': query,\n}\n")}, {str8_lit_comp("bitmap"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression which refers to the base address of data which should be viewed as a bitmap.\")\n 'expression': expr_string,\n @description(\"An expression describing the width of the bitmap, in pixels.\") @order(0) 'w': u64,\n @description(\"An expression describing the height of the bitmap, in pixels.\") @order(1) 'h': u64,\n @display_name(\"Bitmap Format\") @description(\"The pixel format that the bitmap data should be interpreted as being within.\")\n 'fmt': code_string,\n}\n")}, {str8_lit_comp("color"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Value\") @description(\"An expression to describe the value or location of the color.\")\n 'expression': expr_string,\n}\n")}, {str8_lit_comp("geo3d"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Expression\") @description(\"An expression to describe the base address of the index buffer.\")\n 'expression': expr_string,\n 'count': expr_string,\n 'vtx': expr_string,\n 'vtx_size': expr_string,\n 'yaw': @range[0, 1] f32,\n 'pitch': @range[-0.5, 0] f32,\n 'zoom': @range[0, 100] f32,\n}\n")}, @@ -652,7 +653,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[248] = { str8_lit_comp("move_view"), str8_lit_comp("Moves a view to a new panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(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("tab_bar_top"), str8_lit_comp("Anchors a panel's tab bar to the top of the panel."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(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("tab_bar_bottom"), str8_lit_comp("Anchors a panel's tab bar to the bottom of the panel."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(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("tab_settings"), str8_lit_comp("Opens settings for a tab."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(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("tab_settings"), str8_lit_comp("Opens settings for a tab."), str8_lit_comp("view,options"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(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("set_current_path"), str8_lit_comp("Sets the debugger's current path, which is used as a starting point when browsing for files."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(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("open"), str8_lit_comp("Opens a file."), str8_lit_comp("code,source,file"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(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}}, { str8_lit_comp("switch"), str8_lit_comp("Switches to a recent file."), str8_lit_comp("code,source,file"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(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_Cfg, str8_lit_comp("query:recent_files, query:source_files"), str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -812,7 +813,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[248] = { str8_lit_comp("geo3d"), str8_lit_comp("Opens a Geometry (3D) tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs|RD_CmdKindFlag_ListInTab}, }; -struct {String8 string; CFG_Binding binding;} rd_default_binding_table[116] = +struct {String8 string; CFG_Binding binding;} rd_default_binding_table[117] = { {str8_lit_comp("kill_all"), {OS_Key_F5, 0 |OS_Modifier_Shift }}, {str8_lit_comp("step_into_inst"), {OS_Key_F11, 0 |OS_Modifier_Alt}}, @@ -854,6 +855,7 @@ struct {String8 string; CFG_Binding binding;} rd_default_binding_table[116] = {str8_lit_comp("tab_bar_top"), {OS_Key_Up, 0 |OS_Modifier_Ctrl |OS_Modifier_Shift |OS_Modifier_Alt}}, {str8_lit_comp("tab_bar_bottom"), {OS_Key_Down, 0 |OS_Modifier_Ctrl |OS_Modifier_Shift |OS_Modifier_Alt}}, {str8_lit_comp("open_tab"), {OS_Key_T, 0 |OS_Modifier_Ctrl }}, +{str8_lit_comp("tab_settings"), {OS_Key_T, 0 |OS_Modifier_Ctrl |OS_Modifier_Alt}}, {str8_lit_comp("open"), {OS_Key_O, 0 |OS_Modifier_Ctrl }}, {str8_lit_comp("switch"), {OS_Key_I, 0 |OS_Modifier_Ctrl }}, {str8_lit_comp("switch_to_partner_file"), {OS_Key_O, 0 |OS_Modifier_Alt}}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index c82edd1c..dda99eec 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -601,7 +601,7 @@ Z(getting_started)\ C_LINKAGE_BEGIN extern String8 rd_tab_fast_path_view_name_table[25]; extern String8 rd_tab_fast_path_query_name_table[25]; -extern RD_VocabInfo rd_vocab_info_table[358]; +extern RD_VocabInfo rd_vocab_info_table[359]; extern RD_NameSchemaInfo rd_name_schema_info_table[26]; extern String8 rd_reg_slot_code_name_table[49]; extern Rng1U64 rd_reg_slot_range_table[49]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 052c445e..45e5f582 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -200,6 +200,7 @@ RD_VocabTable: {rgba "" "RGBA" "" Palette } {path "" "Path" "" FileOutline } {guid "" "GUID" "" Null } + {peek_type _ "Peek Type" _ Null } } @struct RD_VocabInfo: @@ -531,7 +532,6 @@ RD_VocabTable: 'show_symbol_names': bool, @no_callee_helper @default(1) @description("Controls whether or not line numbers are shown.") 'show_line_numbers': bool, - } ``` } @@ -540,7 +540,7 @@ RD_VocabTable: ``` @inherit(tab) x: { - @description("An expression which refers to the base address of data which should be viewed as memory.") + @display_name("Base Address") @description("An expression which refers to the base address of data which should be viewed as memory.") 'expression': expr_string, @display_name("Address Range Size") @description("The number of bytes of the viewed memory range.") 'size': expr_string, @@ -548,12 +548,16 @@ RD_VocabTable: 'cursor': expr_string, @default(1) @display_name("Cursor Size") @description("The size, in bytes, of the cursor.") 'cursor_size': @range[1, 16] u64, - @default(16) @description("The number of columns to build before building new rows.") + @expand_if("!$.auto_columns") @default(16) @description("The number of columns to build before building new rows.") 'num_columns': @range[1, 64] u64, @default(1) @display_name("Track Mark To Cursor") @description("Ensures that the mark always follows the cursor, if the cursor value is updated.") 'track_mark_to_cursor': bool, - @default(0) @display_name("Edit Mode") @description("Enables editing operations on memory contents.") - 'edit_mode': bool, + @default(1) @display_name("Allow Mutation") @description("Allows operations which mutate memory.") + 'allow_mutation': bool, + @default(0) @display_name("Automatically Size Columns") @description("Determines the number of columns based on the available space.") + 'auto_columns': bool, + @display_name("Peek Types") @description("A list of types to interpret selected and hovered memory as.") + 'peek_types': query, } ``` } @@ -935,7 +939,7 @@ RD_CmdTable: // | | | | {MoveView 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_view" "Move View" "Moves a view to a new panel." "" "" } {TabBarTop 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 UpArrow "tab_bar_top" "Anchor Tab Bar To Top" "Anchors a panel's tab bar to the top of the panel." "" "$tab," } {TabBarBottom 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 DownArrow "tab_bar_bottom" "Anchor Tab Bar To Bottom" "Anchors a panel's tab bar to the bottom of the panel." "" "$tab," } - {TabSettings 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Gear "tab_settings" "Tab Settings" "Opens settings for a tab." "" "" } + {TabSettings 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Gear "tab_settings" "Selected Tab Settings" "Opens settings for a tab." "view,options" "" } //- rjf: files {SetCurrentPath 0 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 FileOutline "set_current_path" "Set Current Path" "Sets the debugger's current path, which is used as a starting point when browsing for files." "" "" } @@ -1241,6 +1245,7 @@ RD_DefaultBindingTable: { "tab_bar_top" Up ctrl shift alt } { "tab_bar_bottom" Down ctrl shift alt } { "open_tab" T ctrl 0 0 } + { "tab_settings" T ctrl 0 alt } //- rjf: files { "open" O ctrl 0 0 } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 6640c9b1..be59c832 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -8095,6 +8095,11 @@ rd_window_frame(void) t->tab = tab; t->fstrs = rd_title_fstrs_from_cfg(scratch.arena, tab, 0); F32 tab_width_target = dr_dim_from_fstrs(ui_top_tab_size(), &t->fstrs).x + tab_close_width_px + ui_top_font_size()*1.f; + B32 tab_is_selected = (tab == panel->selected_tab); + if(tab_is_selected && panel_tree.focused == panel) + { + tab_width_target += tab_close_width_px; + } tab_width_target = Min(max_tab_width_px, tab_width_target); t->tab_width = floor_f32(ui_anim(ui_key_from_stringf(ui_key_zero(), "tab_width_%p", tab), tab_width_target, .initial = reset ? tab_width_target : 0, .rate = rd_state->menu_animation_rate)); SLLQueuePush(first_tab_task, last_tab_task, t); @@ -8238,6 +8243,38 @@ rd_window_frame(void) ui_box_equip_display_fstrs(name_box, &tab_fstrs); } } + if(tab_is_selected && panel_tree.focused == panel) + { + UI_PrefWidth(ui_px(tab_close_width_px, 1.f)) UI_TextAlignment(UI_TextAlign_Center) + RD_Font(RD_FontSlot_Icons) + UI_FontSize(ui_top_font_size()*0.75f) + UI_TagF(".") UI_TagF("tab") UI_TagF("weak") UI_TagF("implicit") + UI_CornerRadius(0) + { + UI_Box *edit_box = ui_build_box_from_stringf(UI_BoxFlag_Clickable| + UI_BoxFlag_DrawBorder| + UI_BoxFlag_DrawBackground| + UI_BoxFlag_DrawText| + UI_BoxFlag_DrawHotEffects| + UI_BoxFlag_DrawActiveEffects, + "%S###edit_view_%p", rd_icon_kind_text_table[RD_IconKind_Gear], tab); + UI_Signal sig = ui_signal_from_box(edit_box); + if(ui_pressed(sig)) + { + if(ws->query_is_active && + ui_key_match(sig.box->key, ws->query_regs->ui_key)) + { + rd_cmd(RD_CmdKind_CancelQuery); + } + else + { + rd_cmd(RD_CmdKind_PushQuery, + .ui_key = sig.box->key, + .expr = push_str8f(scratch.arena, "query:config.$%I64x", tab->id)); + } + } + } + } UI_PrefWidth(ui_px(tab_close_width_px, 1.f)) UI_TextAlignment(UI_TextAlign_Center) RD_Font(RD_FontSlot_Icons) UI_FontSize(ui_top_font_size()*0.75f) @@ -11577,6 +11614,19 @@ rd_frame(void) .id_from_num = E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(watches), .num_from_id = E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_NAME(watches), })); + e_string2typekey_map_insert(rd_frame_arena(), rd_state->meta_name2type_map, str8_lit("peek_types"), + e_type_key_cons(.kind = E_TypeKind_Set, + .flags = E_TypeFlag_EditableChildren, + .name = str8_lit("peek_types"), + .irext = E_TYPE_IREXT_FUNCTION_NAME(peek_types), + .access = E_TYPE_ACCESS_FUNCTION_NAME(peek_types), + .expand = + { + .info = E_TYPE_EXPAND_INFO_FUNCTION_NAME(peek_types), + .range = E_TYPE_EXPAND_RANGE_FUNCTION_NAME(peek_types), + .id_from_num = E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(peek_types), + .num_from_id = E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_NAME(peek_types), + })); e_string2typekey_map_insert(rd_frame_arena(), rd_state->meta_name2type_map, str8_lit("call_stack"), @@ -11601,18 +11651,6 @@ rd_frame(void) .id_from_num = E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(cfgs_slice), .num_from_id = E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_NAME(cfgs_slice), })); - e_string2typekey_map_insert(rd_frame_arena(), rd_state->meta_name2type_map, str8_lit("environment"), - e_type_key_cons(.kind = E_TypeKind_Set, - .name = str8_lit("environment"), - .irext = E_TYPE_IREXT_FUNCTION_NAME(environment), - .access = E_TYPE_ACCESS_FUNCTION_NAME(environment), - .expand = - { - .info = E_TYPE_EXPAND_INFO_FUNCTION_NAME(environment), - .range = E_TYPE_EXPAND_RANGE_FUNCTION_NAME(environment), - .id_from_num = E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(environment), - .num_from_id = E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_NAME(environment), - })); } //- rjf: add macro for collections with specific lookup rules (but no unique id rules) diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index 7d8237b0..e41320d2 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -1248,6 +1248,120 @@ E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(watches) return num; } +//////////////////////////////// +//~ rjf: `peek_types` Type Hooks + +typedef struct RD_PeekTypesAccel RD_PeekTypesAccel; +struct RD_PeekTypesAccel +{ + CFG_NodePtrArray cfgs; +}; + +E_TYPE_IREXT_FUNCTION_DEF(peek_types) +{ + RD_PeekTypesAccel *accel = push_array(arena, RD_PeekTypesAccel, 1); + { + Temp scratch = scratch_begin(&arena, 1); + E_OpList oplist = e_oplist_from_irtree(scratch.arena, irtree->root); + String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); + E_Interpretation interpret = e_interpret(bytecode); + E_Space space = interpret.space; + CFG_Node *target = rd_cfg_from_eval_space(space); + CFG_NodePtrList env_strings = {0}; + for(CFG_Node *child = target->first; child != &cfg_nil_node; child = child->next) + { + if(str8_match(child->string, str8_lit("peek_type"), 0)) + { + cfg_node_ptr_list_push(scratch.arena, &env_strings, child); + } + } + accel->cfgs = cfg_node_ptr_array_from_list(arena, &env_strings); + scratch_end(scratch); + } + E_IRExt result = {accel}; + return result; +} + +E_TYPE_ACCESS_FUNCTION_DEF(peek_types) +{ + E_IRTreeAndType result = {&e_irnode_nil}; + if(expr->kind == E_ExprKind_ArrayIndex) + { + RD_PeekTypesAccel *accel = (RD_PeekTypesAccel *)lhs_irtree->user_data; + CFG_NodePtrArray *cfgs = &accel->cfgs; + E_Value rhs_value = e_value_from_expr(expr->first->next); + if(0 <= rhs_value.u64 && rhs_value.u64 < cfgs->count) + { + CFG_Node *cfg = cfgs->v[rhs_value.u64]; + result.root = e_irtree_set_space(arena, rd_eval_space_from_cfg(cfg), e_irtree_const_u(arena, 0)); + result.type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), cfg->first->string.size, E_TypeFlag_IsCodeText); + result.mode = E_Mode_Offset; + } + } + return result; +} + +E_TYPE_EXPAND_INFO_FUNCTION_DEF(peek_types) +{ + RD_PeekTypesAccel *accel = (RD_PeekTypesAccel *)eval.irtree.user_data; + E_TypeExpandInfo result = {accel, accel->cfgs.count + 1}; + return result; +} + +E_TYPE_EXPAND_RANGE_FUNCTION_DEF(peek_types) +{ + RD_PeekTypesAccel *accel = (RD_PeekTypesAccel *)user_data; + Rng1U64 legal_idx_range = r1u64(0, accel->cfgs.count); + Rng1U64 read_range = intersect_1u64(idx_range, legal_idx_range); + U64 read_range_count = dim_1u64(read_range); + for(U64 idx = 0; idx < read_range_count; idx += 1) + { + U64 cfg_idx = read_range.min + idx; + if(cfg_idx < accel->cfgs.count) + { + evals_out[idx] = e_eval_wrapf(eval, "$[%I64u]", cfg_idx); + } + } +} + +E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_DEF(peek_types) +{ + U64 id = 0; + RD_PeekTypesAccel *accel = (RD_PeekTypesAccel *)user_data; + if(1 <= num && num <= accel->cfgs.count) + { + U64 idx = (num-1); + id = accel->cfgs.v[idx]->id; + } + else if(num == accel->cfgs.count+1) + { + id = max_U64; + } + return id; +} + +E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(peek_types) +{ + U64 num = 0; + RD_PeekTypesAccel *accel = (RD_PeekTypesAccel *)user_data; + if(id != 0 && id != max_U64) + { + for EachIndex(idx, accel->cfgs.count) + { + if(accel->cfgs.v[idx]->id == id) + { + num = idx+1; + break; + } + } + } + else if(id == max_U64) + { + num = accel->cfgs.count + 1; + } + return num; +} + //////////////////////////////// //~ rjf: `unattached_processes` Type Hooks diff --git a/src/raddbg/raddbg_eval.h b/src/raddbg/raddbg_eval.h index b2269be9..216f514b 100644 --- a/src/raddbg/raddbg_eval.h +++ b/src/raddbg/raddbg_eval.h @@ -86,6 +86,16 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(watches); E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_DEF(watches); E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(watches); +//////////////////////////////// +//~ rjf: `peek_types` Type Hooks + +E_TYPE_IREXT_FUNCTION_DEF(peek_types); +E_TYPE_ACCESS_FUNCTION_DEF(peek_types); +E_TYPE_EXPAND_INFO_FUNCTION_DEF(peek_types); +E_TYPE_EXPAND_RANGE_FUNCTION_DEF(peek_types); +E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_DEF(peek_types); +E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(peek_types); + //////////////////////////////// //~ rjf: `unattached_processes` Type Hooks diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index f55e02d8..a5dad0b5 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1085,9 +1085,11 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) // if(!block_is_root) { + // TODO(rjf): @hack special-casing these specific hook checks... not good if(info.group_cfg_name.size != 0 && (block_type->expand.id_from_num == E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(cfgs_slice) || block_type->expand.id_from_num == E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(watches) || - block_type->expand.id_from_num == E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(environment))) + block_type->expand.id_from_num == E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(environment) || + block_type->expand.id_from_num == E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(peek_types))) { CFG_ID id = row->key.child_id; info.group_cfg_child = cfg_node_from_id(id); @@ -2654,7 +2656,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) ProfBeginFunction(); Temp scratch = scratch_begin(0, 0); RD_MemoryViewState *mv = rd_view_state(RD_MemoryViewState); - B32 edit_mode = rd_view_setting_b32_from_name(str8_lit("edit_mode")); + B32 allow_edits = rd_view_setting_b32_from_name(str8_lit("allow_mutation")); ////////////////////////////// //- rjf: if memory views are parameterized by a register-space evaluation, @@ -2677,6 +2679,17 @@ RD_VIEW_UI_FUNCTION_DEF(memory) view_range = rd_whole_range_from_eval_space(eval.space); } + ////////////////////////////// + //- rjf: unpack visual params + // + FNT_Tag font = rd_font_from_slot(RD_FontSlot_Code); + FNT_RasterFlags font_raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Code); + F32 font_size = ui_top_font_size(); + F32 big_glyph_advance = fnt_dim_from_tag_size_string(font, font_size, 0, 0, str8_lit("H")).x; + F32 row_height_px = floor_f32(font_size*2.f); + F32 cell_width_px = floor_f32(font_size*2.f); + F32 address_margin_width_px = big_glyph_advance*20.f; + ////////////////////////////// //- rjf: unpack parameterization info // @@ -2693,10 +2706,15 @@ RD_VIEW_UI_FUNCTION_DEF(memory) U64 initial_mark_base_vaddr = mark_base_vaddr; U64 num_columns = rd_view_setting_u64_from_name(str8_lit("num_columns")); B32 track_mark_to_cursor = rd_view_setting_b32_from_name(str8_lit("track_mark_to_cursor")); + B32 auto_columns = rd_view_setting_b32_from_name(str8_lit("auto_columns")); if(num_columns == 0) { num_columns = 16; } + if(auto_columns) + { + num_columns = (U64)((dim_2f32(rect).x - address_margin_width_px - big_glyph_advance*4.f) / (cell_width_px + big_glyph_advance)); + } num_columns = ClampBot(1, num_columns); UI_ScrollPt2 scroll_pos = rd_view_scroll_pos(); Vec4F32 selection_color = ui_color_from_name(str8_lit("selection")); @@ -2739,16 +2757,6 @@ RD_VIEW_UI_FUNCTION_DEF(memory) } } - ////////////////////////////// - //- rjf: unpack visual params - // - FNT_Tag font = rd_font_from_slot(RD_FontSlot_Code); - FNT_RasterFlags font_raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Code); - F32 font_size = ui_top_font_size(); - F32 big_glyph_advance = fnt_dim_from_tag_size_string(font, font_size, 0, 0, str8_lit("H")).x; - F32 row_height_px = floor_f32(font_size*2.f); - F32 cell_width_px = floor_f32(font_size*2.f); - ////////////////////////////// //- rjf: calculate rectangles // @@ -2828,14 +2836,6 @@ RD_VIEW_UI_FUNCTION_DEF(memory) Vec2S64 cell_delta = {0}; B32 allow_cell_movement = 1; - // rjf: edit mode toggling - if(evt->slot == UI_EventActionSlot_Edit) - { - rd_store_view_param_s64(str8_lit("edit_mode"), !edit_mode); - edit_mode ^= 1; - good_action = 1; - } - // rjf: copies if(evt->flags & UI_EventFlag_Copy) { @@ -2872,7 +2872,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) } // rjf: pastes - if(edit_mode && evt->flags & UI_EventFlag_Paste) + if(allow_edits && evt->flags & UI_EventFlag_Paste) { String8 data_textified = evt->string; U8 split_chars[] = {' ', '\n', '\r'}; @@ -2903,7 +2903,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) } // rjf: cell-granularity deletions - if(edit_mode && !mv->cell_value_edit_in_progress && evt->flags & UI_EventFlag_Delete) + if(allow_edits && !mv->cell_value_edit_in_progress && evt->flags & UI_EventFlag_Delete) { Rng1U64 range = union_1u64(r1u64(cursor_base_vaddr, cursor_base_vaddr+cursor_size), r1u64(mark_base_vaddr, mark_base_vaddr+cursor_size)); @@ -2913,10 +2913,14 @@ RD_VIEW_UI_FUNCTION_DEF(memory) log_user_errorf("Could not successfully write to memory."); } good_action = 1; + if(cursor_base_vaddr != mark_base_vaddr) + { + allow_cell_movement = 0; + } } // rjf: in-progress cell value edit deletions -> delete existing cell half-byte - if(edit_mode && mv->cell_value_edit_in_progress && evt->flags & UI_EventFlag_Delete) + if(allow_edits && mv->cell_value_edit_in_progress && evt->flags & UI_EventFlag_Delete) { mv->cell_value_edit_in_progress = 0; allow_cell_movement = 0; @@ -2924,7 +2928,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) } // rjf: byte digit -> cell value insertion. if first digit, store, if 2nd, commit - if(edit_mode && evt->string.size != 0 && evt->kind == UI_EventKind_Text && !(evt->flags & UI_EventFlag_Paste)) + if(allow_edits && evt->string.size != 0 && evt->kind == UI_EventKind_Text && !(evt->flags & UI_EventFlag_Paste)) { good_action = 1; if(!mv->cell_value_edit_in_progress) @@ -3005,7 +3009,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) next_cursor_base_vaddr += cell_delta.x; next_cursor_base_vaddr += cell_delta.y*num_columns; } - if(good_action && evt->flags & UI_EventFlag_PickSelectSide && cursor_base_vaddr != mark_base_vaddr) + if(allow_cell_movement && good_action && evt->flags & UI_EventFlag_PickSelectSide && cursor_base_vaddr != mark_base_vaddr) { if(evt->delta_2s32.x < 0 || evt->delta_2s32.y < 0) { @@ -3016,7 +3020,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) next_cursor_base_vaddr = Max(cursor_base_vaddr, mark_base_vaddr); } } - if(good_action && !(evt->flags & UI_EventFlag_KeepMark)) + if(allow_cell_movement && good_action && !(evt->flags & UI_EventFlag_KeepMark)) { next_mark_base_vaddr = next_cursor_base_vaddr; } @@ -3149,7 +3153,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) DR_FStrList byte_fstrs_changed[256] = {0}; { Vec4F32 selected_color = ui_color_from_name(str8_lit("text")); - if(edit_mode) UI_TagF("bad") + if(!allow_edits) UI_TagF("weak") { selected_color = ui_color_from_name(str8_lit("text")); } @@ -3551,14 +3555,15 @@ RD_VIEW_UI_FUNCTION_DEF(memory) RD_Font(RD_FontSlot_Code) UI_FontSize(font_size) { - UI_PrefWidth(ui_px(big_glyph_advance*20.f, 1.f)) ui_labelf("Address"); + UI_PrefWidth(ui_px(address_margin_width_px, 1.f)) ui_labelf("Address"); UI_PrefWidth(ui_px(cell_width_px, 1.f)) UI_TextAlignment(UI_TextAlign_Center) { - Rng1U64 col_selection_rng = r1u64(cursor_base_vaddr%num_columns, mark_base_vaddr%num_columns); + Rng1U64 col_selection_rng = r1u64((cursor_base_vaddr - view_range.min) % num_columns, + (mark_base_vaddr - view_range.min) % num_columns); for(U64 row_off = 0; row_off < num_columns; row_off += 1) { - B32 column_is_selected = (selection.min%num_columns <= row_off && row_off <= selection.max%num_columns); + B32 column_is_selected = ((selection.min - view_range.min) % num_columns <= row_off && row_off <= (selection.max - view_range.min) % num_columns); UI_TagF(column_is_selected ? "" : "weak") ui_labelf("%I64X", row_off); } } @@ -3650,8 +3655,10 @@ RD_VIEW_UI_FUNCTION_DEF(memory) //- rjf: interact with row container // U64 mouse_hover_byte_num = 0; + B32 dragging_is_active = 0; { UI_Signal sig = ui_signal_from_box(row_container_box); + dragging_is_active = ui_dragging(sig); // rjf: calculate hovered byte if(ui_hovering(sig) || ui_dragging(sig)) @@ -3790,7 +3797,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) UI_BoxFlags cell_flags = 0; Vec4F32 cell_bg_rgba = {0}; Vec4F32 cell_bd_rgba = ui_color_from_name(str8_lit("text")); - if(edit_mode) UI_TagF("bad") + if(!allow_edits) UI_TagF("weak") { cell_bd_rgba = ui_color_from_name(str8_lit("text")); } @@ -3898,9 +3905,9 @@ RD_VIEW_UI_FUNCTION_DEF(memory) } } } - if(annotation_node != 0 && mouse_hover_byte_num == global_byte_num) + if(annotation_node != 0 && mouse_hover_byte_num == global_byte_num && !byte_is_selected && !dragging_is_active) { - UI_Tooltip UI_FontSize(ui_top_font_size()) UI_PrefHeight(ui_px(ui_top_font_size()*1.75f, 1.f)) + UI_Tooltip UI_PrefHeight(ui_px(ui_top_font_size()*1.75f, 1.f)) { for(AnnotationNode *a_n = annotation_node; a_n != 0; a_n = a_n->next) { @@ -3922,6 +3929,38 @@ RD_VIEW_UI_FUNCTION_DEF(memory) } } } + if(mouse_hover_byte_num == global_byte_num && byte_is_selected && !dragging_is_active) + { + UI_Tooltip + { + CFG_Node *view = cfg_node_from_id(rd_regs()->view); + CFG_NodePtrList peek_types = cfg_node_child_list_from_string(scratch.arena, view, str8_lit("peek_type")); + for EachNode(n, CFG_NodePtrNode, peek_types.first) + { + String8 type_string = n->v->first->string; + E_Eval type_size_eval = e_eval_from_stringf("sizeof(%S)", type_string); + if(type_size_eval.msgs.max_kind == E_MsgKind_Null && dim_1u64(selection)+1 >= type_size_eval.value.u64) + { + String8 casted_expr = str8f(scratch.arena, "*(((%S) *)((((uint8 *)(&(%S)) + 0x%I64x))))", + type_string, + eval.string.size ? eval.string : str8_lit("0"), + selection.min - view_range.min); + E_Eval peek_eval = e_eval_from_string(casted_expr); + UI_PrefWidth(ui_children_sum(1)) UI_Row + { + EV_StringParams params = + { + .flags = EV_StringFlag_ReadOnlyDisplayRules, + .radix = 10, + }; + String8 value_string = rd_value_string_from_eval(scratch.arena, str8_zero(), ¶ms, ui_top_font(), ui_top_font_size(), ui_top_font_size()*40.f, peek_eval); + UI_TextAlignment(UI_TextAlign_Left) UI_PrefWidth(ui_em(4.f, 1.f)) rd_code_label(1.f, 0, ui_color_from_name(str8_lit("text")), type_string); + UI_PrefWidth(ui_text_dim(10, 1)) rd_code_label(1.f, 0, ui_color_from_name(str8_lit("text")), value_string); + } + } + } + } + } } } }