From d978f56250cbdb1a9c0fd601be9970d498ae4791 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 1 Oct 2024 13:48:11 -0700 Subject: [PATCH] thread rich hover --- src/raddbg/raddbg_core.c | 10 ++++++++-- src/raddbg/raddbg_main.c | 2 ++ src/raddbg/raddbg_views.c | 36 ++++++++++++++++++++++++++++++++++-- src/raddbg/raddbg_widgets.c | 25 ++++++++++++++++++++++++- 4 files changed, 68 insertions(+), 5 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index bc283431..11343dcc 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -6855,8 +6855,7 @@ rd_window_frame(RD_Window *ws) UI_BoxFlag_Clip| UI_BoxFlag_DrawBorder| UI_BoxFlag_DisableFocusOverlay| - ((ws->focused_panel != panel)*UI_BoxFlag_DisableFocusBorder)| - ((ws->focused_panel != panel)*UI_BoxFlag_DrawOverlay), + ((ws->focused_panel != panel)*UI_BoxFlag_DisableFocusBorder), panel_key); } @@ -7829,6 +7828,13 @@ rd_window_frame(RD_Window *ws) dr_pop_clip(); } + // rjf: draw overlay + if(b->flags & UI_BoxFlag_DrawOverlay) + { + R_Rect2DInst *inst = dr_rect(b->rect, b->palette->colors[UI_ColorCode_Overlay], 0, 0, 1.f); + MemoryCopyArray(inst->corner_radii, b->corner_radii); + } + // rjf: draw border if(b->flags & UI_BoxFlag_DrawBorder) { diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index 791de7e1..78aed49d 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -47,6 +47,8 @@ //////////////////////////////// //~ rjf: post-0.9.12 TODO notes // +// [ ] (reported by forrest) 'set-next-statement' -> prioritize current +// module/symbol, in cases where one line maps to many voffs // [ ] collapse upstream state for theme/bindings/settings into entities; use cache accelerators if needed to make up difference // [ ] collapse upstream state for windows/panels/tabs into entities; use downstream window/view resource cache to make up the difference // [ ] entity <-> mdesk paths diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 65e56053..f180af9d 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1195,6 +1195,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo FZY_Scope *fzy_scope = fzy_scope_open(); Temp scratch = scratch_begin(0, 0); UI_ScrollPt2 scroll_pos = rd_view_scroll_pos(); + F32 entity_hover_t_rate = 1 - pow_f32(2, (-20.f * rd_state->frame_dt)); ////////////////////////////// //- rjf: unpack arguments @@ -2463,6 +2464,11 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo RD_Entity *entity = row_info.collection_entity; CTRL_Entity *ctrl_entity = row_info.collection_ctrl_entity; B32 entity_box_selected = (row_selected && selection_tbl.min.x <= 1 && 1 <= selection_tbl.max.x); + B32 is_hovering = ((rd_handle_match(rd_state->hover_regs->entity, rd_handle_from_entity(entity)) && + rd_state->hover_regs_slot == RD_RegSlot_Entity) || + (ctrl_handle_match(rd_state->hover_regs->thread, ctrl_entity->handle) && rd_state->hover_regs_slot == RD_RegSlot_Thread) || + (ctrl_handle_match(rd_state->hover_regs->module, ctrl_entity->handle) && rd_state->hover_regs_slot == RD_RegSlot_Module) || + (ctrl_handle_match(rd_state->hover_regs->process, ctrl_entity->handle) && rd_state->hover_regs_slot == RD_RegSlot_Process)); //- rjf: pick palette UI_Palette *palette = ui_top_palette(); @@ -2499,6 +2505,16 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo { fstrs = rd_title_fstrs_from_ctrl_entity(scratch.arena, ctrl_entity, ui_top_palette()->text_weak, ui_top_font_size(), 1); } + F32 hover_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "###entity_hover_t_%p_%p", entity, ctrl_entity), (F32)!!is_hovering, .rate = entity_hover_t_rate); + if(!rd_entity_is_nil(entity)) + { + palette->overlay = rd_rgba_from_entity(entity); + } + else if(ctrl_entity != &ctrl_entity_nil) + { + palette->overlay = rd_rgba_from_ctrl_entity(ctrl_entity); + } + palette->overlay.w *= 0.3f*hover_t; //- rjf: build ui_set_next_hover_cursor(OS_Cursor_HandPoint); @@ -2507,21 +2523,37 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo { entity_box = ui_build_box_from_stringf(UI_BoxFlag_Clickable| UI_BoxFlag_DrawBorder| + UI_BoxFlag_DrawOverlay| UI_BoxFlag_DrawBackground| UI_BoxFlag_DrawHotEffects| UI_BoxFlag_DrawActiveEffects, "###entity_%p_%p", entity, ctrl_entity); } { - UI_Parent(entity_box) + UI_Parent(entity_box) RD_RegsScope(.entity = rd_handle_from_entity(entity)) { + RD_RegSlot slot = RD_RegSlot_Entity; + switch(ctrl_entity->kind) + { + case CTRL_EntityKind_Thread:{slot = RD_RegSlot_Thread; rd_regs()->thread = ctrl_entity->handle;}break; + case CTRL_EntityKind_Process:{slot = RD_RegSlot_Process; rd_regs()->process = ctrl_entity->handle;}break; + case CTRL_EntityKind_Module:{slot = RD_RegSlot_Module; rd_regs()->module = ctrl_entity->handle;}break; + } UI_PrefWidth(ui_em(2.f, 1.f)) if(ui_pressed(ui_expander(row_expanded, str8_lit("###expanded")))) { next_row_expanded = !row_expanded; } - UI_Box *title_box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); + UI_Box *title_box = ui_build_box_from_key(UI_BoxFlag_DrawText|UI_BoxFlag_DisableTruncatedHover, ui_key_zero()); ui_box_equip_display_fancy_strings(title_box, &fstrs); UI_Signal sig = ui_signal_from_box(entity_box); + if(ui_hovering(sig)) + { + rd_set_hover_regs(slot); + } + if(ui_dragging(sig) && !contains_2f32(sig.box->rect, ui_mouse())) + { + rd_drag_begin(slot); + } if(ui_clicked(sig)) { if(entity->kind == RD_EntityKind_Target) diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 1a633dc4..299c7149 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -816,6 +816,7 @@ struct RD_ThreadBoxDrawExtData Vec4F32 thread_color; F32 progress_t; F32 alive_t; + F32 hover_t; B32 is_selected; B32 is_frozen; B32 do_lines; @@ -851,6 +852,20 @@ internal UI_BOX_CUSTOM_DRAW(rd_thread_box_draw_extensions) 0, 0, 1); } + // rjf: draw rich hover fill + if(u->hover_t > 0.001f) + { + Vec4F32 weak_thread_color = u->thread_color; + weak_thread_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_thread_color; + } + // rjf: draw slight fill on selected thread if(u->is_selected && u->do_glow) { @@ -971,6 +986,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe margin_contents_palette->background = v4f32(0, 0, 0, 0); F32 line_num_padding_px = ui_top_font_size()*1.f; F32 entity_alive_t_rate = 1 - pow_f32(2, (-30.f * rd_state->frame_dt)); + F32 entity_hover_t_rate = 1 - pow_f32(2, (-20.f * rd_state->frame_dt)); ////////////////////////////// //- rjf: build top-level container @@ -1101,10 +1117,13 @@ 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(); + 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); u->thread_color = color; u->alive_t = ui_anim(ui_key_from_stringf(top_container_box->key, "###thread_alive_t_%p", thread), 1.f, .rate = entity_alive_t_rate); + u->hover_t = ui_anim(ui_key_from_stringf(top_container_box->key, "###thread_hover_t_%p", thread), (F32)!!is_hovering, .rate = entity_hover_t_rate); u->is_selected = (thread == selected_thread); u->is_frozen = !!thread->is_frozen; u->do_lines = rd_setting_val_from_code(RD_SettingCode_ThreadLines).s32; @@ -1246,9 +1265,13 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe // rjf: custom draw { + 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); u->thread_color = color; u->alive_t = ui_anim(ui_key_from_stringf(top_container_box->key, "###thread_alive_t_%p", thread), 1.f, .rate = entity_alive_t_rate); + u->hover_t = ui_anim(ui_key_from_stringf(top_container_box->key, "###thread_hover_t_%p", thread), (F32)!!is_hovering, .rate = entity_hover_t_rate); u->is_selected = (thread == selected_thread); u->is_frozen = !!thread->is_frozen; ui_box_equip_custom_draw(thread_box, rd_thread_box_draw_extensions, u);