From 2636f296cc6c58fed7cba2f08f4e6590590bbd47 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 17 Feb 2025 09:48:26 -0800 Subject: [PATCH] simplify stylized watch row building rules; allow buttons to be editable, maintain expr key stability even in different watch row styles --- src/eval/eval.mdesk | 1 + src/eval/eval_ir.c | 27 +++++++++-- src/eval/eval_types.c | 13 +++++ src/eval/eval_types.h | 14 +++--- src/eval/generated/eval.meta.c | 6 ++- src/eval/generated/eval.meta.h | 5 +- src/raddbg/raddbg_core.c | 13 +++-- src/raddbg/raddbg_views.c | 89 ++++++++++++++++++++++------------ src/raddbg/raddbg_views.h | 1 + 9 files changed, 120 insertions(+), 49 deletions(-) diff --git a/src/eval/eval.mdesk b/src/eval/eval.mdesk index a80bcb2d..4f281812 100644 --- a/src/eval/eval.mdesk +++ b/src/eval/eval.mdesk @@ -127,6 +127,7 @@ E_ExprKindTable: { LeafF32 Null 0 "F32" "" "" "" } { LeafIdent Null 0 "leaf_ident" "" "" "" } { LeafOffset Null 0 "leaf_offset" "" "" "" } + { LeafValue Null 0 "leaf_value" "" "" "" } { LeafFilePath Null 0 "leaf_filepath" "" "" "" } { TypeIdent Null 0 "type_ident" "" "" "" } diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index c5b90c48..68eaf957 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -170,7 +170,7 @@ E_LOOKUP_RANGE_FUNCTION_DEF(folder) { String8 folder_name = accel->folders.v[idx - 0]; String8 folder_path = push_str8f(scratch.arena, "%S/%S", accel->folder_path, folder_name); - expr = e_push_expr(arena, E_ExprKind_LeafOffset, 0); + expr = e_push_expr(arena, E_ExprKind_LeafValue, 0); expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("folder")); expr->space = e_space_make(E_SpaceKind_FileSystem); expr->value.u64 = e_id_from_string(folder_path); @@ -180,7 +180,7 @@ E_LOOKUP_RANGE_FUNCTION_DEF(folder) { String8 file_name = accel->files.v[idx - accel->folders.count]; String8 file_path = push_str8f(scratch.arena, "%S/%S", accel->folder_path, file_name); - expr = e_push_expr(arena, E_ExprKind_LeafOffset, 0); + expr = e_push_expr(arena, E_ExprKind_LeafValue, 0); expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("file")); expr->space = e_space_make(E_SpaceKind_FileSystem); expr->value.u64 = e_id_from_string(file_path); @@ -305,6 +305,7 @@ E_LOOKUP_RANGE_FUNCTION_DEF(file) typedef struct E_SliceAccel E_SliceAccel; struct E_SliceAccel { + Arch arch; U64 count; U64 base_ptr_vaddr; E_TypeKey element_type_key; @@ -343,6 +344,14 @@ E_LOOKUP_INFO_FUNCTION_DEF(slice) } } + // rjf: determine architecture + Arch arch = e_type_state->ctx->primary_module->arch; + if(base_ptr_member != 0) + { + E_Type *type = e_type_from_key__cached(base_ptr_member->type_key); + arch = type->arch; + } + // rjf: evaluate count member, determine count U64 count = 0; if(count_member != 0) @@ -372,6 +381,7 @@ E_LOOKUP_INFO_FUNCTION_DEF(slice) if(count_member && base_ptr_member) { E_SliceAccel *accel = push_array(arena, E_SliceAccel, 1); + accel->arch = arch; accel->count = count; accel->base_ptr_vaddr = base_ptr_vaddr; accel->element_type_key = element_type_key; @@ -2219,13 +2229,24 @@ E_IRGEN_FUNCTION_DEF(default) case E_ExprKind_LeafOffset: { E_IRNode *new_tree = e_push_irnode(arena, RDI_EvalOp_ConstU64); - new_tree->value.u64 = expr->value.u64; + new_tree->value = expr->value; new_tree->space = expr->space; result.root = new_tree; result.type_key = expr->type_key; result.mode = E_Mode_Offset; }break; + //- rjf: leaf values + case E_ExprKind_LeafValue: + { + E_IRNode *new_tree = e_push_irnode(arena, RDI_EvalOp_ConstU64); + new_tree->value = expr->value; + new_tree->space = expr->space; + result.root = new_tree; + result.type_key = expr->type_key; + result.mode = E_Mode_Value; + }break; + //- rjf: leaf file paths case E_ExprKind_LeafFilePath: { diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index 4e800955..6a4195e0 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -628,6 +628,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) type->direct_type_key = node->params.direct_key; type->count = node->params.count; type->depth = node->params.depth; + type->arch = node->params.arch; type->byte_size = node->byte_size; switch(type->kind) { @@ -706,6 +707,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) type->name = push_str8_copy(arena, name); type->byte_size = (U64)rdi_type->byte_size; type->count = members_count; + type->arch = e_type_state->ctx->modules[rdi_idx].arch; type->members = members; } @@ -750,6 +752,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) type->name = push_str8_copy(arena, name); type->byte_size = (U64)rdi_type->byte_size; type->count = enum_vals_count; + type->arch = e_type_state->ctx->modules[rdi_idx].arch; type->enum_vals = enum_vals; type->direct_type_key = direct_type_key; } @@ -789,6 +792,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) type->direct_type_key = direct_type_key; type->byte_size = direct_type_byte_size; type->flags = flags; + type->arch = e_type_state->ctx->modules[rdi_idx].arch; }break; case RDI_TypeKind_Ptr: case RDI_TypeKind_LRef: @@ -799,6 +803,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) type->direct_type_key = direct_type_key; type->byte_size = bit_size_from_arch(e_type_state->ctx->modules[rdi_idx].arch)/8; type->count = 1; + type->arch = e_type_state->ctx->modules[rdi_idx].arch; }break; case RDI_TypeKind_Array: @@ -808,6 +813,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) type->direct_type_key = direct_type_key; type->count = rdi_type->constructed.count; type->byte_size = direct_type_byte_size * type->count; + type->arch = e_type_state->ctx->modules[rdi_idx].arch; }break; case RDI_TypeKind_Function: { @@ -823,6 +829,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) type->direct_type_key = direct_type_key; type->count = count; type->param_type_keys = push_array_no_zero(arena, E_TypeKey, type->count); + type->arch = e_type_state->ctx->modules[rdi_idx].arch; for(U32 idx = 0; idx < type->count; idx += 1) { U32 param_type_idx = idx_run[idx]; @@ -856,6 +863,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) type->owner_type_key = direct_type_key; type->count = count; type->param_type_keys = push_array_no_zero(arena, E_TypeKey, type->count); + type->arch = e_type_state->ctx->modules[rdi_idx].arch; for(U32 idx = 0; idx < type->count; idx += 1) { U32 param_type_idx = idx_run[idx]; @@ -893,6 +901,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) type->byte_size = bit_size_from_arch(e_type_state->ctx->modules[rdi_idx].arch)/8; type->owner_type_key = owner_type_key; type->direct_type_key = direct_type_key; + type->arch = e_type_state->ctx->modules[rdi_idx].arch; }break; } } @@ -921,6 +930,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) type->name = push_str8_copy(arena, name); type->byte_size = direct_type_byte_size; type->direct_type_key = direct_type_key; + type->arch = e_type_state->ctx->modules[rdi_idx].arch; } //- rjf: bitfields @@ -944,6 +954,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) type->direct_type_key = direct_type_key; type->off = (U32)rdi_type->bitfield.off; type->count = (U64)rdi_type->bitfield.size; + type->arch = e_type_state->ctx->modules[rdi_idx].arch; } //- rjf: incomplete types @@ -957,6 +968,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) type = push_array(arena, E_Type, 1); type->kind = kind; type->name = push_str8_copy(arena, name); + type->arch = e_type_state->ctx->modules[rdi_idx].arch; } } @@ -984,6 +996,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) type->kind = E_TypeKind_Union; type->name = push_str8f(arena, "reg_%I64u_bit", reg_byte_count*8); type->byte_size = (U64)reg_byte_count; + type->arch = (Arch)key.u32[0]; // rjf: build register type members E_MemberList members = {0}; diff --git a/src/eval/eval_types.h b/src/eval/eval_types.h index 8dae9878..e59c09c4 100644 --- a/src/eval/eval_types.h +++ b/src/eval/eval_types.h @@ -67,12 +67,13 @@ E_MemberKind; typedef U32 E_TypeFlags; enum { - E_TypeFlag_Const = (1<<0), - E_TypeFlag_Volatile = (1<<1), - E_TypeFlag_External = (1<<2), - E_TypeFlag_IsPlainText= (1<<3), - E_TypeFlag_IsCodeText = (1<<4), - E_TypeFlag_IsPathText = (1<<5), + E_TypeFlag_Const = (1<<0), + E_TypeFlag_Volatile = (1<<1), + E_TypeFlag_External = (1<<2), + E_TypeFlag_IsPlainText = (1<<3), + E_TypeFlag_IsCodeText = (1<<4), + E_TypeFlag_IsPathText = (1<<5), + E_TypeFlag_EditableChildren = (1<<6), }; typedef struct E_Member E_Member; @@ -131,6 +132,7 @@ struct E_Type U64 count; U64 depth; U32 off; + Arch arch; E_TypeKey direct_type_key; E_TypeKey owner_type_key; E_TypeKey *param_type_keys; diff --git a/src/eval/generated/eval.meta.c b/src/eval/generated/eval.meta.c index 25e429c6..770eb9c2 100644 --- a/src/eval/generated/eval.meta.c +++ b/src/eval/generated/eval.meta.c @@ -14,7 +14,7 @@ str8_lit_comp("CharLiteral"), str8_lit_comp("Symbol"), }; -String8 e_expr_kind_strings[50] = +String8 e_expr_kind_strings[51] = { str8_lit_comp("Nil"), str8_lit_comp("Ref"), @@ -59,6 +59,7 @@ str8_lit_comp("LeafF64"), str8_lit_comp("LeafF32"), str8_lit_comp("LeafIdent"), str8_lit_comp("LeafOffset"), +str8_lit_comp("LeafValue"), str8_lit_comp("LeafFilePath"), str8_lit_comp("TypeIdent"), str8_lit_comp("Ptr"), @@ -83,7 +84,7 @@ str8_lit_comp("Insufficient evaluation machine stack space."), str8_lit_comp("Malformed bytecode."), }; -E_OpInfo e_expr_kind_op_info_table[50] = +E_OpInfo e_expr_kind_op_info_table[51] = { { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, @@ -133,6 +134,7 @@ E_OpInfo e_expr_kind_op_info_table[50] = { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, { E_OpKind_Binary, 13, str8_lit_comp(""), str8_lit_comp("="), str8_lit_comp("") }, { E_OpKind_Null, 0, str8_lit_comp("=>"), str8_lit_comp(","), str8_lit_comp("") }, }; diff --git a/src/eval/generated/eval.meta.h b/src/eval/generated/eval.meta.h index ad31221e..3288fa6c 100644 --- a/src/eval/generated/eval.meta.h +++ b/src/eval/generated/eval.meta.h @@ -134,6 +134,7 @@ E_ExprKind_LeafF64, E_ExprKind_LeafF32, E_ExprKind_LeafIdent, E_ExprKind_LeafOffset, +E_ExprKind_LeafValue, E_ExprKind_LeafFilePath, E_ExprKind_TypeIdent, E_ExprKind_Ptr, @@ -162,9 +163,9 @@ E_InterpretationCode_COUNT, C_LINKAGE_BEGIN extern String8 e_token_kind_strings[6]; -extern String8 e_expr_kind_strings[50]; +extern String8 e_expr_kind_strings[51]; extern String8 e_interpretation_code_display_strings[11]; -extern E_OpInfo e_expr_kind_op_info_table[50]; +extern E_OpInfo e_expr_kind_op_info_table[51]; extern U8 e_kind_basic_byte_size_table[56]; extern String8 e_kind_basic_string_table[56]; diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 6b82b9a9..272bf9d8 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -3996,12 +3996,15 @@ rd_lang_kind_from_eval_tag(E_Eval eval, E_Expr *tag) { lang_kind = txt_lang_kind_from_extension(str8_skip_last_dot(file_path)); } - else for(E_Expr *param = tag->first->next; param != &e_expr_nil; param = param->next) + if(lang_kind == TXT_LangKind_Null) { - if(param->kind == E_ExprKind_Define && str8_match(param->first->string, str8_lit("lang"), 0)) + for(E_Expr *param = tag->first->next; param != &e_expr_nil; param = param->next) { - lang_kind = txt_lang_kind_from_extension(param->first->next->string); - break; + if(param->kind == E_ExprKind_Define && str8_match(param->first->string, str8_lit("lang"), 0)) + { + lang_kind = txt_lang_kind_from_extension(param->first->next->string); + break; + } } } scratch_end(scratch); @@ -12382,7 +12385,7 @@ rd_frame(void) { String8 collection_name = str8_lit("watches"); E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); - expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name); + expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name, .flags = E_TypeFlag_EditableChildren); expr->space = e_space_make(RD_EvalSpaceKind_MetaCfg); e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, collection_name, diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index a655fd05..8df9729e 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -794,9 +794,12 @@ rd_id_from_watch_cell(RD_WatchCell *cell) { U64 result = 5381; result = e_hash_from_string(result, str8_struct(&cell->kind)); - result = e_hash_from_string(result, str8_struct(&cell->eval.mode)); - result = e_hash_from_string(result, str8_struct(&cell->index)); - result = e_hash_from_string(result, str8_struct(&cell->default_pct)); + if(cell->kind != RD_WatchCellKind_Expr) + { + result = e_hash_from_string(result, str8_struct(&cell->eval.mode)); + result = e_hash_from_string(result, str8_struct(&cell->index)); + result = e_hash_from_string(result, str8_struct(&cell->default_pct)); + } return result; } @@ -921,6 +924,12 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) // rjf: fill row's eval info.eval = e_eval_from_expr(arena, row->expr); + // rjf: determine if row's expression is editable + if(block_type->flags & E_TypeFlag_EditableChildren || row->expr == &e_expr_nil) + { + info.expr_is_editable = 1; + } + // rjf: determine row's module CTRL_Entity *row_ctrl_entity = rd_ctrl_entity_from_eval_space(info.eval.space); CTRL_Entity *row_module = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->module); @@ -984,25 +993,30 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) } } - // rjf: determine row's cfg + // rjf: determine row's group cfg if(info.group_cfg_name.size != 0) { RD_CfgID id = row->key.child_id; info.group_cfg_child = rd_cfg_from_id(id); } - // rjf: determine if the row's evaluation matches the group configuration - // this distinguishes between e.g. "watches", which uses the group of watch cfgs, - // but does not evaluate them, from e.g. "targets", which uses the group of target - // cfgs, and the evaluations are of the targets themselves. - // - B32 row_cfg_eval_matches_group = 0; + // rjf: determine cfgs/entities that this row is evaluating RD_Cfg *evalled_cfg = rd_cfg_from_eval_space(info.eval.space); - B32 row_entity_eval_matches_group = 0; CTRL_Entity *evalled_entity = (info.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity ? rd_ctrl_entity_from_eval_space(info.eval.space) : &ctrl_entity_nil); + + // rjf: determine if this cfg/entity evaluation is top-level - e.g. if we + // are evaluating a cfg tree, or some descendant of it + B32 is_top_level = 0; + if(evalled_cfg != &rd_nil_cfg) { - row_cfg_eval_matches_group = (evalled_cfg == info.group_cfg_child); - row_entity_eval_matches_group = (evalled_entity == info.group_entity); + E_TypeKey top_level_type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, evalled_cfg->string); + is_top_level = (info.eval.value.u64 == 0 && e_type_key_match(top_level_type_key, info.eval.type_key)); + } + if(evalled_entity != &ctrl_entity_nil) + { + String8 top_level_name = ctrl_entity_kind_code_name_table[evalled_entity->kind]; + E_TypeKey top_level_type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, top_level_name); + is_top_level = (info.eval.value.u64 == 0 && e_type_key_match(top_level_type_key, info.eval.type_key)); } // rjf: determine view ui rule @@ -1016,9 +1030,8 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) { if(0){} - // rjf: cfg rows - else if((info.eval.space.kind == RD_EvalSpaceKind_MetaCfg && row_cfg_eval_matches_group && info.group_cfg_parent == &rd_nil_cfg) || - (row->block->parent == &ev_nil_block && evalled_cfg != &rd_nil_cfg)) + // rjf: top-level cfg rows + else if(is_top_level && evalled_cfg != &rd_nil_cfg) { RD_Cfg *cfg = evalled_cfg; rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button, .pct = 1.f, .fstrs = rd_title_fstrs_from_cfg(arena, cfg, ui_top_palette()->text_weak, ui_top_font_size())); @@ -1071,9 +1084,8 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) } } - // rjf: entity rows - else if((info.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity && row_entity_eval_matches_group && info.group_entity != &ctrl_entity_nil) || - (row->block->parent == &ev_nil_block && evalled_entity != &ctrl_entity_nil)) + // rjf: top-level entity rows + else if(is_top_level && evalled_entity != &ctrl_entity_nil) { CTRL_Entity *entity = evalled_entity; rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button, .pct = 1.f, .fstrs = rd_title_fstrs_from_ctrl_entity(arena, entity, ui_top_palette()->text_weak, ui_top_font_size(), 1)); @@ -1091,17 +1103,14 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) } // rjf: singular button for commands - else if((block_eval.space.kind == RD_EvalSpaceKind_MetaCmd || - block_eval.space.kind == RD_EvalSpaceKind_MetaCfg) && - info.eval.space.kind == RD_EvalSpaceKind_MetaCmd && - row_cfg_eval_matches_group) + else if(info.eval.space.kind == RD_EvalSpaceKind_MetaCmd) { RD_CmdKind cmd_kind = e_value_eval_from_eval(info.eval).value.u64; RD_CmdKindInfo *cmd_kind_info = &rd_cmd_kind_info_table[cmd_kind]; rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_ActivateWithSingleClick, .pct = 1.f, .fstrs = rd_title_fstrs_from_code_name(arena, cmd_kind_info->string, ui_top_palette()->text_weak, ui_top_font_size())); } - // rjf: singular button for folders & files + // rjf: folder / file rows else if(info.eval.space.kind == E_SpaceKind_FileSystem) { DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Main), rd_raster_flags_from_slot(RD_FontSlot_Main), ui_top_palette()->text, ui_top_font_size()}; @@ -1111,7 +1120,12 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) if(str8_match(type->name, str8_lit("folder"), 0)) { DR_FStrList fstrs = {0}; - dr_fstrs_push_new(arena, &fstrs, ¶ms, file_name); + if(file_name.size) + { + dr_fstrs_push_new(arena, &fstrs, ¶ms, rd_icon_kind_text_table[RD_IconKind_FolderClosedFilled], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = ui_top_palette()->text_weak); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, file_name); + } rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_IsNonCode, .pct = 1.f, @@ -1126,7 +1140,12 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) F32 next_pct = 0; #define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) DR_FStrList fstrs = {0}; - dr_fstrs_push_new(arena, &fstrs, ¶ms, file_name); + if(file_name.size) + { + dr_fstrs_push_new(arena, &fstrs, ¶ms, rd_icon_kind_text_table[RD_IconKind_FileOutline], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = ui_top_palette()->text_weak); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, file_name); + } rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_IsNonCode, .default_pct = 0.35f, @@ -1236,7 +1255,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla // expression tree. case RD_WatchCellKind_Expr: { - if(!ev_key_match(ev_key_root(), row->block->key) && (row->string.size != 0 || row->expr == &e_expr_nil)) + if(row_info->expr_is_editable) { result.flags |= RD_WatchCellFlag_CanEdit; } @@ -2965,6 +2984,8 @@ RD_VIEW_UI_FUNCTION_DEF(watch) else { // rjf: compute visual params + B32 is_button = !!(cell_info.flags & RD_WatchCellFlag_Button); + B32 is_activated_on_single_click = !!(cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick); B32 is_non_code = !!(cell_info.flags & RD_WatchCellFlag_IsNonCode); String8 ghost_text = {0}; if(cell->kind == RD_WatchCellKind_Expr && cell_info.string.size == 0) @@ -2977,17 +2998,23 @@ RD_VIEW_UI_FUNCTION_DEF(watch) ghost_text = str8_lit("View Rules"); is_non_code = !cell_selected || !ewv->text_editing; } + if(cell_selected && ewv->text_editing && cell->kind == RD_WatchCellKind_Expr) + { + is_non_code = 0; + is_button = 0; + is_activated_on_single_click = 0; + } // rjf: build RD_LineEditParams line_edit_params = {0}; { line_edit_params.flags = (RD_LineEditFlag_CodeContents*!is_non_code| - RD_LineEditFlag_NoBackground*!(cell_info.flags & RD_WatchCellFlag_Button)| - RD_LineEditFlag_Button*!!(cell_info.flags & RD_WatchCellFlag_Button)| - RD_LineEditFlag_SingleClickActivate*!!(cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick)| + RD_LineEditFlag_NoBackground*!is_button| + RD_LineEditFlag_Button*is_button| + RD_LineEditFlag_SingleClickActivate*is_activated_on_single_click| RD_LineEditFlag_KeyboardClickable| RD_LineEditFlag_Expander*!!(row_is_expandable && cell == row_info->cells.first)| - RD_LineEditFlag_ExpanderPlaceholder*(row_depth==0 && cell == row_info->cells.first && !(cell_info.flags & RD_WatchCellFlag_Button))| + RD_LineEditFlag_ExpanderPlaceholder*(row_depth==0 && cell == row_info->cells.first && !is_button)| RD_LineEditFlag_ExpanderSpace*((row_depth!=0 && cell == row_info->cells.first))); line_edit_params.depth = (cell_x == 0 ? row_depth : 0); line_edit_params.cursor = &cell_edit_state->cursor; diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index 68e84df8..9524d108 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -89,6 +89,7 @@ struct RD_WatchRowInfo { E_Eval eval; CTRL_Entity *module; + B32 expr_is_editable; String8 group_cfg_name; RD_Cfg *group_cfg_parent; RD_Cfg *group_cfg_child;