diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index cf898964..bd34c0f7 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -113,6 +113,7 @@ struct_members(CTRL_BreakpointMetaEval) member_lit_comp(CTRL_MetaEval, type(U32), color, .pretty_name = str8_lit_comp("Color")), member_lit_comp(CTRL_MetaEval, type(U64), hit_count, .pretty_name = str8_lit_comp("Hit Count")), member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), label, .pretty_name = str8_lit_comp("Label")), + member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), condition, .pretty_name = str8_lit_comp("Condition")), member_lit_comp(CTRL_MetaEval, type(CTRL_PlainString8),location, .pretty_name = str8_lit_comp("Location")), }; diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index b8b737ab..2d9e71b1 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -560,6 +560,13 @@ rd_rgba_from_entity(RD_Entity *entity) Vec3F32 rgb = rgb_from_hsv(hsv); result = v4f32(rgb.x, rgb.y, rgb.z, entity->color_hsva.w); } + else switch(entity->kind) + { + case RD_EntityKind_Breakpoint: + { + result = rd_rgba_from_theme_color(RD_ThemeColor_Breakpoint); + }break; + } return result; } @@ -8086,9 +8093,9 @@ EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(targets) { return rd_ev_vie EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(targets) { return rd_ev_view_rule_expr_id_from_num__meta_entities(num, user_data, RD_EntityKind_Target, 1); } EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(targets) { return rd_ev_view_rule_expr_num_from_id__meta_entities(id, user_data, RD_EntityKind_Target, 1); } EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(breakpoints) { return rd_ev_view_rule_expr_expand_info__meta_entities(arena, view, filter, expr, params, RD_EntityKind_Breakpoint); } -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(breakpoints) { return rd_ev_view_rule_expr_expand_range_info__meta_entities(arena, view, filter, expr, params, idx_range, user_data, RD_EntityKind_Breakpoint, 0); } -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(breakpoints){ return rd_ev_view_rule_expr_id_from_num__meta_entities(num, user_data, RD_EntityKind_Breakpoint, 0); } -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(breakpoints){ return rd_ev_view_rule_expr_num_from_id__meta_entities(id, user_data, RD_EntityKind_Breakpoint, 0); } +EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(breakpoints) { return rd_ev_view_rule_expr_expand_range_info__meta_entities(arena, view, filter, expr, params, idx_range, user_data, RD_EntityKind_Breakpoint, 1); } +EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(breakpoints){ return rd_ev_view_rule_expr_id_from_num__meta_entities(num, user_data, RD_EntityKind_Breakpoint, 1); } +EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(breakpoints){ return rd_ev_view_rule_expr_num_from_id__meta_entities(id, user_data, RD_EntityKind_Breakpoint, 1); } EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(watch_pins) { return rd_ev_view_rule_expr_expand_info__meta_entities(arena, view, filter, expr, params, RD_EntityKind_WatchPin); } EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(watch_pins) { return rd_ev_view_rule_expr_expand_range_info__meta_entities(arena, view, filter, expr, params, idx_range, user_data, RD_EntityKind_WatchPin, 0); } EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(watch_pins) { return rd_ev_view_rule_expr_id_from_num__meta_entities(num, user_data, RD_EntityKind_WatchPin, 0); } diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 4db97cf5..68ae1234 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1795,51 +1795,41 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo Vec2S64 tbl = v2s64(x, y); RD_WatchViewPoint pt = rd_watch_view_point_from_tbl(&block_ranges, tbl); RD_WatchViewColumn *col = rd_watch_view_column_from_x(ewv, x); - switch(col->kind) + if(tbl.y != 0 && (col->kind == RD_WatchViewColumnKind_Expr || row_kind == RD_WatchViewRowKind_PrettyEntityControls) && + row_info.collection_entity_kind != RD_EntityKind_Nil) { - case RD_WatchViewColumnKind_Value: - case RD_WatchViewColumnKind_Type: - {}break; - default: - case RD_WatchViewColumnKind_Expr: - if(tbl.y != 0) + RD_Entity *entity = row_info.collection_entity; + if(!rd_entity_is_nil(entity)) { - if(row_info.collection_entity_kind != RD_EntityKind_Nil) + rd_entity_list_push(scratch.arena, &entities_to_remove, entity); + U64 deleted_id = row->key.child_id; + U64 deleted_num = row->block->expand_view_rule_info->expr_expand_num_from_id(deleted_id, row->block->expand_view_rule_info_user_data); + if(deleted_num != 0) { - RD_Entity *entity = row_info.collection_entity; - if(!rd_entity_is_nil(entity)) + U64 fallback_id_next = row->block->expand_view_rule_info->expr_expand_id_from_num(deleted_num+1, row->block->expand_view_rule_info_user_data); + U64 fallback_id_prev = row->block->expand_view_rule_info->expr_expand_id_from_num(deleted_num-1, row->block->expand_view_rule_info_user_data); + EV_Key parent_key = row->block->key; + EV_Key key = ev_key_make(row->key.parent_hash, fallback_id_next ? fallback_id_next : fallback_id_prev); + if(key.child_id == 0) { - rd_entity_list_push(scratch.arena, &entities_to_remove, entity); - U64 deleted_id = row->key.child_id; - U64 deleted_num = row->block->expand_view_rule_info->expr_expand_num_from_id(deleted_id, row->block->expand_view_rule_info_user_data); - if(deleted_num != 0) - { - U64 fallback_id_next = row->block->expand_view_rule_info->expr_expand_id_from_num(deleted_num+1, row->block->expand_view_rule_info_user_data); - U64 fallback_id_prev = row->block->expand_view_rule_info->expr_expand_id_from_num(deleted_num-1, row->block->expand_view_rule_info_user_data); - EV_Key parent_key = row->block->key; - EV_Key key = ev_key_make(row->key.parent_hash, fallback_id_next ? fallback_id_next : fallback_id_prev); - if(key.child_id == 0) - { - key = row->block->key; - parent_key = row->block->parent->key; - } - RD_WatchViewPoint new_pt = {0, parent_key, key}; - next_cursor_pt = new_pt; - next_cursor_set = 1; - } + key = row->block->key; + parent_key = row->block->parent->key; } + RD_WatchViewPoint new_pt = {0, parent_key, key}; + next_cursor_pt = new_pt; + next_cursor_set = 1; } - }break; - case RD_WatchViewColumnKind_ViewRule: + } + } + else if(tbl.y != 0 && col->kind == RD_WatchViewColumnKind_ViewRule && row_kind == RD_WatchViewRowKind_Normal) + { + if(row_info.collection_entity_kind != RD_EntityKind_Nil) { - if(row_info.collection_entity_kind != RD_EntityKind_Nil) - { - RD_Entity *entity = row_info.collection_entity; - RD_Entity *view_rule = rd_entity_child_from_kind(entity, RD_EntityKind_ViewRule); - rd_entity_mark_for_deletion(view_rule); - } - ev_key_set_view_rule(eval_view, row->key, str8_zero()); - }break; + RD_Entity *entity = row_info.collection_entity; + RD_Entity *view_rule = rd_entity_child_from_kind(entity, RD_EntityKind_ViewRule); + rd_entity_mark_for_deletion(view_rule); + } + ev_key_set_view_rule(eval_view, row->key, str8_zero()); } } } @@ -2491,6 +2481,20 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo rd_cmd(RD_CmdKind_RunCommand, .string = rd_cmd_kind_info_table[RD_CmdKind_AddTarget].string); } } + if(rd_entity_is_nil(entity) && collection_entity_kind == RD_EntityKind_Breakpoint) + UI_Palette(palette) + { + ui_set_next_focus_hot(row_selected && selection_tbl.min.x == 1 ? UI_FocusKind_On : UI_FocusKind_Off); + if(ui_clicked(rd_cmd_spec_button(rd_cmd_kind_info_table[RD_CmdKind_AddAddressBreakpoint].string))) + { + rd_cmd(RD_CmdKind_RunCommand, .string = rd_cmd_kind_info_table[RD_CmdKind_AddAddressBreakpoint].string); + } + ui_set_next_focus_hot(row_selected && selection_tbl.min.x == 2 ? UI_FocusKind_On : UI_FocusKind_Off); + if(ui_clicked(rd_cmd_spec_button(rd_cmd_kind_info_table[RD_CmdKind_AddFunctionBreakpoint].string))) + { + rd_cmd(RD_CmdKind_RunCommand, .string = rd_cmd_kind_info_table[RD_CmdKind_AddFunctionBreakpoint].string); + } + } //- rjf: build entity box if(!rd_entity_is_nil(entity) || ctrl_entity != &ctrl_entity_nil) @@ -2510,12 +2514,18 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo if(!rd_entity_is_nil(entity)) { palette->overlay = rd_rgba_from_entity(entity); + palette->overlay.w *= 0.3f; } else if(ctrl_entity != &ctrl_entity_nil) { palette->overlay = rd_rgba_from_ctrl_entity(ctrl_entity); + palette->overlay.w *= 0.3f; } - palette->overlay.w *= 0.3f*hover_t; + if(palette->overlay.x == 0 && palette->overlay.y == 0 && palette->overlay.z == 0 && palette->overlay.w == 0) + { + palette->overlay = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlay); + } + palette->overlay.w *= hover_t; //- rjf: build ui_set_next_hover_cursor(OS_Cursor_HandPoint); @@ -5347,13 +5357,11 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(breakpoints) if(!wv->initialized) { rd_watch_view_init(wv); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Member, 0.25f, .string = str8_lit("label.str"), .display_string = str8_lit("Label"), .dequote_string = 1); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Member, 0.35f, .string = str8_lit("location.str"), .display_string = str8_lit("Location"), .dequote_string = 1, .is_non_code = 1); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Member, 0.20f, .string = str8_lit("condition.str"),.display_string = str8_lit("Condition"), .dequote_string = 1); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Member, 0.10f, .string = str8_lit("enabled"), .display_string = str8_lit("Enabled"), .view_rule = str8_lit("checkbox")); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Member, 0.10f, .string = str8_lit("hit_count"), .display_string = str8_lit("Hit Count")); + rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Expr, 0.25f); + rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Value, 0.75f, .dequote_string = 1); } - rd_watch_view_build(wv, 0, str8_lit("breakpoints"), str8_lit(""), 0, 10, rect); + rd_watch_view_build(wv, RD_WatchViewFlag_NoHeader|RD_WatchViewFlag_PrettyNameMembers|RD_WatchViewFlag_PrettyEntityRows|RD_WatchViewFlag_DisableCacheLines, + str8_lit("breakpoints"), str8_lit("only: label condition str hit_count location"), 0, 10, rect); ProfEnd(); } @@ -5367,10 +5375,11 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(watch_pins) if(!wv->initialized) { rd_watch_view_init(wv); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Member, 0.5f, .string = str8_lit("Label"), .dequote_string = 1); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Member, 0.5f, .string = str8_lit("Location"), .dequote_string = 1, .is_non_code = 1); + rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Expr, 0.25f); + rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Value, 0.75f, .dequote_string = 1); } - rd_watch_view_build(wv, 0, str8_lit("watch_pins"), str8_lit(""), 0, 10, rect); + rd_watch_view_build(wv, RD_WatchViewFlag_NoHeader|RD_WatchViewFlag_PrettyNameMembers|RD_WatchViewFlag_PrettyEntityRows|RD_WatchViewFlag_DisableCacheLines, + str8_lit("watch_pins"), str8_lit("only: label location str"), 0, 10, rect); ProfEnd(); } diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 9f93e39a..f998482e 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -899,6 +899,7 @@ struct RD_BreakpointBoxDrawExtData { Vec4F32 color; F32 alive_t; + F32 hover_t; F32 remap_px_delta; B32 do_lines; B32 do_glow; @@ -920,6 +921,20 @@ internal UI_BOX_CUSTOM_DRAW(rd_bp_box_draw_extensions) inst->colors[Corner_00] = inst->colors[Corner_01] = u->color; } + // rjf: draw rich hover fill + if(u->hover_t > 0.001f) + { + Vec4F32 weak_color = u->color; + weak_color.w *= 0.5f*u->hover_t; + R_Rect2DInst *inst = dr_rect(r2f32p(box->parent->parent->parent->rect.x0, + box->parent->rect.y0, + box->parent->parent->parent->rect.x0 + ui_top_font_size()*22.f*u->hover_t, + box->parent->rect.y1), + v4f32(0, 0, 0, 0), + 0, 0, 1); + inst->colors[Corner_00] = inst->colors[Corner_01] = weak_color; + } + // rjf: draw slight fill if(u->do_glow) { @@ -1117,7 +1132,8 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe UI_Signal thread_sig = ui_signal_from_box(thread_box); // rjf: custom draw - {RD_Regs *hover_regs = rd_get_hover_regs(); + { + RD_Regs *hover_regs = rd_get_hover_regs(); B32 is_hovering = (ctrl_handle_match(hover_regs->thread, thread->handle) && rd_state->hover_regs_slot == RD_RegSlot_Thread); RD_ThreadBoxDrawExtData *u = push_array(ui_build_arena(), RD_ThreadBoxDrawExtData, 1); @@ -1339,8 +1355,11 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe // rjf: prep custom rendering data RD_BreakpointBoxDrawExtData *bp_draw = push_array(ui_build_arena(), RD_BreakpointBoxDrawExtData, 1); { + RD_Regs *hover_regs = rd_get_hover_regs(); + B32 is_hovering = (rd_entity_from_handle(hover_regs->entity) == bp && rd_state->hover_regs_slot == RD_RegSlot_Entity); bp_draw->color = bp_color; bp_draw->alive_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "bp_alive_t_%p", bp), 1.f, .rate = entity_alive_t_rate); + bp_draw->hover_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "bp_hover_t_%p", bp), (F32)!!is_hovering, .rate = entity_hover_t_rate); bp_draw->do_lines = rd_setting_val_from_code(RD_SettingCode_BreakpointLines).s32; bp_draw->do_glow = rd_setting_val_from_code(RD_SettingCode_BreakpointGlow).s32; if(rd_regs()->file_path.size != 0) @@ -1366,9 +1385,6 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe ui_set_next_palette(ui_build_palette(ui_top_palette(), .text = bp_color)); ui_set_next_text_alignment(UI_TextAlign_Center); UI_Box *bp_box = ui_build_box_from_stringf(UI_BoxFlag_DrawText| - UI_BoxFlag_DrawActiveEffects| - UI_BoxFlag_DrawHotEffects| - UI_BoxFlag_DrawBorder| UI_BoxFlag_Clickable*!!(params->flags & RD_CodeSliceFlag_Clickable)| UI_BoxFlag_DisableTextTrunc, "%S##bp_%p",