diff --git a/src/df/gfx/df_gfx.c b/src/df/gfx/df_gfx.c index 657c1a78..a2f76343 100644 --- a/src/df/gfx/df_gfx.c +++ b/src/df/gfx/df_gfx.c @@ -1028,7 +1028,6 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D B32 confirm_open = df_gfx_state->confirm_active; B32 query_is_open = !df_view_is_nil(ws->query_view_stack_top); B32 hover_eval_is_open = (!confirm_open && - !query_is_open && ws->hover_eval_string.size != 0 && ws->hover_eval_first_frame_idx+20 < ws->hover_eval_last_frame_idx && df_frame_index()-ws->hover_eval_last_frame_idx < 20); @@ -1123,6 +1122,7 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D arena_clear(ws->query_cmd_arena); ws->query_cmd_spec = df_cmd_spec_is_nil(spec) ? cmd->spec : spec; ws->query_cmd_params = df_cmd_params_copy(ws->query_cmd_arena, ¶ms); + ws->query_view_selected = 1; } }break; @@ -3998,312 +3998,6 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D } } - //////////////////////////// - //- rjf: build hover eval - // - ProfScope("build hover eval") - { - B32 build_hover_eval = hover_eval_is_open; - - // rjf: disable hover eval if queries are active - if(query_is_open) - { - build_hover_eval = 0; - } - - // rjf: disable hover eval if hovered view is actively scrolling - if(hover_eval_is_open) - { - for(DF_Panel *panel = ws->root_panel; - !df_panel_is_nil(panel); - panel = df_panel_rec_df_pre(panel).next) - { - if(!df_panel_is_nil(panel->first)) { continue; } - Rng2F32 panel_rect = df_rect_from_panel(content_rect, ws->root_panel, panel); - DF_View *view = df_view_from_handle(panel->selected_tab_view); - if(!df_view_is_nil(view) && - contains_2f32(panel_rect, ui_mouse()) && - (abs_f32(view->scroll_pos.x.off) > 0.01f || - abs_f32(view->scroll_pos.y.off) > 0.01f)) - { - build_hover_eval = 0; - ws->hover_eval_first_frame_idx = df_frame_index(); - } - } - } - - // rjf: reset open animation - if(ws->hover_eval_string.size == 0) - { - ws->hover_eval_open_t = 0; - ws->hover_eval_num_visible_rows_t = 0; - } - - // rjf: reset animation, but request frames if we're waiting to open - if(ws->hover_eval_string.size != 0 && !hover_eval_is_open && ws->hover_eval_last_frame_idx < ws->hover_eval_first_frame_idx+20 && df_frame_index()-ws->hover_eval_last_frame_idx < 50) - { - df_gfx_request_frame(); - ws->hover_eval_num_visible_rows_t = 0; - ws->hover_eval_open_t = 0; - } - - // rjf: build hover eval - if(build_hover_eval && ws->hover_eval_string.size != 0 && hover_eval_is_open) - UI_Font(df_font_from_slot(DF_FontSlot_Code)) - UI_FontSize(df_font_size_from_slot(ws, DF_FontSlot_Main)) - { - Temp scratch = scratch_begin(&arena, 1); - DBGI_Scope *scope = dbgi_scope_open(); - DF_CtrlCtx ctrl_ctx = ws->hover_eval_ctrl_ctx; - DF_Entity *thread = df_entity_from_handle(ctrl_ctx.thread); - DF_Entity *process = df_entity_ancestor_from_kind(thread, DF_EntityKind_Process); - U64 thread_unwind_rip_vaddr = df_query_cached_rip_from_thread_unwind(thread, ctrl_ctx.unwind_count); - EVAL_ParseCtx parse_ctx = df_eval_parse_ctx_from_process_vaddr(scope, process, thread_unwind_rip_vaddr); - String8 expr = ws->hover_eval_string; - DF_Eval eval = df_eval_from_string(scratch.arena, scope, &ctrl_ctx, &parse_ctx, expr); - - //- rjf: build if good - if(!tg_key_match(eval.type_key, tg_key_zero()) && !ui_any_ctx_menu_is_open()) - UI_Focus((hover_eval_is_open && !ui_any_ctx_menu_is_open() && !query_is_open) ? UI_FocusKind_Null : UI_FocusKind_Off) - { - //- rjf: eval -> viz artifacts - F32 row_height = ui_top_font_size()*2.25f; - DF_CfgTable cfg_table = {0}; - U64 expr_hash = df_hash_from_string(expr); - DF_EvalViewKey eval_view_key = df_eval_view_key_from_stringf("eval_hover_%I64x", expr_hash); - DF_EvalView *eval_view = df_eval_view_from_key(eval_view_key); - DF_EvalVizBlockList viz_blocks = df_eval_viz_block_list_from_eval_view_expr_num(scratch.arena, scope, &ctrl_ctx, &parse_ctx, eval_view, expr, 1); - DF_EvalVizWindowedRowList viz_rows = df_eval_viz_windowed_row_list_from_viz_block_list(scratch.arena, scope, &ctrl_ctx, &parse_ctx, eval_view, 10, ui_top_font(), ui_top_font_size(), r1s64(0, 50), &viz_blocks); - - //- rjf: animate - { - // rjf: animate height - { - F32 fish_rate = 1 - pow_f32(2, (-60.f * df_dt())); - F32 hover_eval_container_height_target = row_height * Min(30, viz_blocks.total_visual_row_count); - ws->hover_eval_num_visible_rows_t += (hover_eval_container_height_target - ws->hover_eval_num_visible_rows_t) * fish_rate; - if(abs_f32(hover_eval_container_height_target - ws->hover_eval_num_visible_rows_t) > 0.5f) - { - df_gfx_request_frame(); - } - else - { - ws->hover_eval_num_visible_rows_t = hover_eval_container_height_target; - } - } - - // rjf: animate open - { - F32 fish_rate = 1 - pow_f32(2, (-60.f * df_dt())); - F32 diff = 1.f - ws->hover_eval_open_t; - ws->hover_eval_open_t += diff*fish_rate; - if(abs_f32(diff) < 0.01f) - { - ws->hover_eval_open_t = 1.f; - } - else - { - df_gfx_request_frame(); - } - } - } - - //- rjf: build hover eval box - F32 hover_eval_container_height = ws->hover_eval_num_visible_rows_t; - F32 corner_radius = ui_top_font_size()*0.25f; - ui_set_next_fixed_x(ws->hover_eval_spawn_pos.x); - ui_set_next_fixed_y(ws->hover_eval_spawn_pos.y); - ui_set_next_pref_width(ui_em(70.f, 1.f)); - ui_set_next_pref_height(ui_px(hover_eval_container_height, 1.f)); - ui_set_next_background_color(df_rgba_from_theme_color(DF_ThemeColor_AltBackground)); - ui_set_next_corner_radius_00(0); - ui_set_next_corner_radius_01(corner_radius); - ui_set_next_corner_radius_10(corner_radius); - ui_set_next_corner_radius_11(corner_radius); - ui_set_next_child_layout_axis(Axis2_Y); - ui_set_next_squish(0.25f-0.25f*ws->hover_eval_open_t); - ui_set_next_transparency(1.f-ws->hover_eval_open_t); - UI_Focus(UI_FocusKind_On) - { - hover_eval_box = ui_build_box_from_stringf(UI_BoxFlag_DrawBorder| - UI_BoxFlag_DrawBackground| - UI_BoxFlag_DrawBackgroundBlur| - UI_BoxFlag_DrawDropShadow| - UI_BoxFlag_Clip| - UI_BoxFlag_AllowOverflowY| - UI_BoxFlag_ViewScroll| - UI_BoxFlag_ViewClamp| - UI_BoxFlag_Floating| - UI_BoxFlag_AnimatePos| - UI_BoxFlag_Clickable| - UI_BoxFlag_DefaultFocusNav, - "###hover_eval"); - } - - //- rjf: build contents - UI_Parent(hover_eval_box) UI_PrefHeight(ui_px(row_height, 1.f)) - { - //- rjf: build rows - for(DF_EvalVizRow *row = viz_rows.first; row != 0; row = row->next) - { - //- rjf: determine if row's data is fresh - B32 row_is_fresh = 0; - switch(row->eval.mode) - { - default:{}break; - case EVAL_EvalMode_Addr: - { - U64 size = tg_byte_size_from_graph_raddbg_key(parse_ctx.type_graph, parse_ctx.rdbg, row->eval.type_key); - size = Min(size, 64); - Rng1U64 vaddr_rng = r1u64(row->eval.offset, row->eval.offset+size); - CTRL_ProcessMemorySlice slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, process->ctrl_machine_id, process->ctrl_handle, vaddr_rng, 0); - for(U64 idx = 0; idx < (slice.data.size+63)/64; idx += 1) - { - if(slice.byte_changed_flags[idx] != 0) - { - row_is_fresh = 1; - break; - } - } - }break; - } - - //- rjf: build row - UI_WidthFill UI_Row - { - ui_spacer(ui_em(0.75f, 1.f)); - ui_spacer(ui_em(1.5f*row->depth, 1.f)); - U64 row_hash = df_hash_from_expand_key(row->key); - B32 row_is_expanded = df_expand_key_is_set(&eval_view->expand_tree_table, row->key); - if(row->flags & DF_EvalVizRowFlag_CanExpand) - UI_PrefWidth(ui_em(1.5f, 1)) - if(ui_expanderf(row_is_expanded, "###%I64x_%I64x_is_expanded", row->key.parent_hash, row->key.child_num).pressed) - { - df_expand_set_expansion(eval_view->arena, &eval_view->expand_tree_table, row->parent_key, row->key, !row_is_expanded); - } - UI_WidthFill - { - UI_PrefWidth(ui_em(15.f, 1.f)) df_code_label(1.f, 1, df_rgba_from_theme_color(DF_ThemeColor_CodeDefault), row->expr); - ui_spacer(ui_em(1.5f, 1.f)); - if(row->flags & DF_EvalVizRowFlag_CanEditValue) - { - if(row_is_fresh) - { - Vec4F32 rgba = df_rgba_from_theme_color(DF_ThemeColor_Highlight0); - rgba.w *= 0.2f; - ui_set_next_background_color(rgba); - } - UI_Signal sig = df_line_editf(DF_LineEditFlag_CodeContents| - DF_LineEditFlag_DisplayStringIsCode| - DF_LineEditFlag_PreferDisplayString| - DF_LineEditFlag_Border, - 0, 0, &ws->hover_eval_txt_cursor, &ws->hover_eval_txt_mark, ws->hover_eval_txt_buffer, sizeof(ws->hover_eval_txt_buffer), &ws->hover_eval_txt_size, 0, row->edit_value, "%S###val_%I64x", row->display_value, row_hash); - if(sig.commit) - { - String8 commit_string = str8(ws->hover_eval_txt_buffer, ws->hover_eval_txt_size); - DF_Eval write_eval = df_eval_from_string(scratch.arena, scope, &ctrl_ctx, &parse_ctx, commit_string); - B32 success = df_commit_eval_value(parse_ctx.type_graph, parse_ctx.rdbg, &ctrl_ctx, row->eval, write_eval); - if(success == 0) - { - DF_CmdParams params = df_cmd_params_from_window(ws); - params.string = str8_lit("Could not commit value successfully."); - df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_String); - df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_Error)); - } - } - } - else - { - if(row_is_fresh) - { - Vec4F32 rgba = df_rgba_from_theme_color(DF_ThemeColor_Highlight0); - rgba.w *= 0.2f; - ui_set_next_background_color(rgba); - ui_set_next_flags(UI_BoxFlag_DrawBackground); - } - df_code_label(1.f, 1, df_rgba_from_theme_color(DF_ThemeColor_CodeDefault), row->display_value); - } - } - if(row == viz_rows.first) - { - UI_TextAlignment(UI_TextAlign_Center) UI_PrefWidth(ui_em(3.f, 1.f)) - UI_CornerRadius00(0) - UI_CornerRadius01(0) - UI_CornerRadius10(0) - UI_CornerRadius11(0) - { - UI_Signal watch_sig = df_icon_buttonf(DF_IconKind_List, 0, "###watch_hover_eval"); - if(watch_sig.hovering) UI_Tooltip UI_Font(df_font_from_slot(DF_FontSlot_Main)) UI_FontSize(df_font_size_from_slot(ws, DF_FontSlot_Main)) - { - ui_labelf("Add the hovered expression to an opened watch view."); - } - if(watch_sig.clicked) - { - DF_CmdParams params = df_cmd_params_from_window(ws); - params.string = expr; - df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_String); - df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_ToggleWatchExpression)); - } - } - if(!df_entity_is_nil(df_entity_from_handle(ws->hover_eval_file))) - UI_TextAlignment(UI_TextAlign_Center) UI_PrefWidth(ui_em(3.f, 1.f)) - UI_CornerRadius10(corner_radius) - UI_CornerRadius11(corner_radius) - { - UI_Signal pin_sig = df_icon_buttonf(DF_IconKind_Pin, 0, "###pin_hover_eval"); - if(pin_sig.hovering) UI_Tooltip UI_Font(df_font_from_slot(DF_FontSlot_Main)) UI_FontSize(df_font_size_from_slot(ws, DF_FontSlot_Main)) - UI_CornerRadius00(0) - UI_CornerRadius01(0) - UI_CornerRadius10(0) - UI_CornerRadius11(0) - { - ui_labelf("Pin the hovered expression to this code location."); - } - if(pin_sig.clicked) - { - DF_CmdParams params = df_cmd_params_from_window(ws); - if(ws->hover_eval_vaddr != 0) - { - params.vaddr = ws->hover_eval_vaddr; - df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_VirtualAddr); - } - else - { - params.entity = ws->hover_eval_file; - params.text_point = ws->hover_eval_file_pt; - df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_Entity); - df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_TextPoint); - } - params.string = expr; - df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_String); - df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_ToggleWatchPin)); - } - } - } - } - } - UI_PrefWidth(ui_px(0, 0)) ui_spacer(ui_px(hover_eval_container_height-row_height, 1.f)); - } - - //- rjf: interact - { - UI_Signal hover_eval_sig = ui_signal_from_box(hover_eval_box); - if(hover_eval_sig.mouse_over) - { - ws->hover_eval_last_frame_idx = df_frame_index(); - } - else if(ws->hover_eval_last_frame_idx+2 < df_frame_index()) - { - df_gfx_request_frame(); - } - } - } - - dbgi_scope_close(scope); - scratch_end(scratch); - } - } - //////////////////////////// //- rjf: top bar // @@ -5337,6 +5031,306 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D } } + //////////////////////////// + //- rjf: build hover eval + // + ProfScope("build hover eval") + { + B32 build_hover_eval = hover_eval_is_open; + + // rjf: disable hover eval if hovered view is actively scrolling + if(hover_eval_is_open) + { + for(DF_Panel *panel = ws->root_panel; + !df_panel_is_nil(panel); + panel = df_panel_rec_df_pre(panel).next) + { + if(!df_panel_is_nil(panel->first)) { continue; } + Rng2F32 panel_rect = df_rect_from_panel(content_rect, ws->root_panel, panel); + DF_View *view = df_view_from_handle(panel->selected_tab_view); + if(!df_view_is_nil(view) && + contains_2f32(panel_rect, ui_mouse()) && + (abs_f32(view->scroll_pos.x.off) > 0.01f || + abs_f32(view->scroll_pos.y.off) > 0.01f)) + { + build_hover_eval = 0; + ws->hover_eval_first_frame_idx = df_frame_index(); + } + } + } + + // rjf: reset open animation + if(ws->hover_eval_string.size == 0) + { + ws->hover_eval_open_t = 0; + ws->hover_eval_num_visible_rows_t = 0; + } + + // rjf: reset animation, but request frames if we're waiting to open + if(ws->hover_eval_string.size != 0 && !hover_eval_is_open && ws->hover_eval_last_frame_idx < ws->hover_eval_first_frame_idx+20 && df_frame_index()-ws->hover_eval_last_frame_idx < 50) + { + df_gfx_request_frame(); + ws->hover_eval_num_visible_rows_t = 0; + ws->hover_eval_open_t = 0; + } + + // rjf: build hover eval + if(build_hover_eval && ws->hover_eval_string.size != 0 && hover_eval_is_open) + UI_Font(df_font_from_slot(DF_FontSlot_Code)) + UI_FontSize(df_font_size_from_slot(ws, DF_FontSlot_Main)) + { + Temp scratch = scratch_begin(&arena, 1); + DBGI_Scope *scope = dbgi_scope_open(); + DF_CtrlCtx ctrl_ctx = ws->hover_eval_ctrl_ctx; + DF_Entity *thread = df_entity_from_handle(ctrl_ctx.thread); + DF_Entity *process = df_entity_ancestor_from_kind(thread, DF_EntityKind_Process); + U64 thread_unwind_rip_vaddr = df_query_cached_rip_from_thread_unwind(thread, ctrl_ctx.unwind_count); + EVAL_ParseCtx parse_ctx = df_eval_parse_ctx_from_process_vaddr(scope, process, thread_unwind_rip_vaddr); + String8 expr = ws->hover_eval_string; + DF_Eval eval = df_eval_from_string(scratch.arena, scope, &ctrl_ctx, &parse_ctx, expr); + + //- rjf: build if good + if(!tg_key_match(eval.type_key, tg_key_zero()) && !ui_any_ctx_menu_is_open()) + UI_Focus((hover_eval_is_open && !ui_any_ctx_menu_is_open() && (!query_is_open || !ws->query_view_selected)) ? UI_FocusKind_Null : UI_FocusKind_Off) + { + //- rjf: eval -> viz artifacts + F32 row_height = ui_top_font_size()*2.25f; + DF_CfgTable cfg_table = {0}; + U64 expr_hash = df_hash_from_string(expr); + DF_EvalViewKey eval_view_key = df_eval_view_key_from_stringf("eval_hover_%I64x", expr_hash); + DF_EvalView *eval_view = df_eval_view_from_key(eval_view_key); + DF_EvalVizBlockList viz_blocks = df_eval_viz_block_list_from_eval_view_expr_num(scratch.arena, scope, &ctrl_ctx, &parse_ctx, eval_view, expr, 1); + DF_EvalVizWindowedRowList viz_rows = df_eval_viz_windowed_row_list_from_viz_block_list(scratch.arena, scope, &ctrl_ctx, &parse_ctx, eval_view, 10, ui_top_font(), ui_top_font_size(), r1s64(0, 50), &viz_blocks); + + //- rjf: animate + { + // rjf: animate height + { + F32 fish_rate = 1 - pow_f32(2, (-60.f * df_dt())); + F32 hover_eval_container_height_target = row_height * Min(30, viz_blocks.total_visual_row_count); + ws->hover_eval_num_visible_rows_t += (hover_eval_container_height_target - ws->hover_eval_num_visible_rows_t) * fish_rate; + if(abs_f32(hover_eval_container_height_target - ws->hover_eval_num_visible_rows_t) > 0.5f) + { + df_gfx_request_frame(); + } + else + { + ws->hover_eval_num_visible_rows_t = hover_eval_container_height_target; + } + } + + // rjf: animate open + { + F32 fish_rate = 1 - pow_f32(2, (-60.f * df_dt())); + F32 diff = 1.f - ws->hover_eval_open_t; + ws->hover_eval_open_t += diff*fish_rate; + if(abs_f32(diff) < 0.01f) + { + ws->hover_eval_open_t = 1.f; + } + else + { + df_gfx_request_frame(); + } + } + } + + //- rjf: build hover eval box + F32 hover_eval_container_height = ws->hover_eval_num_visible_rows_t; + F32 corner_radius = ui_top_font_size()*0.25f; + ui_set_next_fixed_x(ws->hover_eval_spawn_pos.x); + ui_set_next_fixed_y(ws->hover_eval_spawn_pos.y); + ui_set_next_pref_width(ui_em(70.f, 1.f)); + ui_set_next_pref_height(ui_px(hover_eval_container_height, 1.f)); + ui_set_next_background_color(df_rgba_from_theme_color(DF_ThemeColor_AltBackground)); + ui_set_next_corner_radius_00(0); + ui_set_next_corner_radius_01(corner_radius); + ui_set_next_corner_radius_10(corner_radius); + ui_set_next_corner_radius_11(corner_radius); + ui_set_next_child_layout_axis(Axis2_Y); + ui_set_next_squish(0.25f-0.25f*ws->hover_eval_open_t); + ui_set_next_transparency(1.f-ws->hover_eval_open_t); + UI_Focus(UI_FocusKind_On) + { + hover_eval_box = ui_build_box_from_stringf(UI_BoxFlag_DrawBorder| + UI_BoxFlag_DrawBackground| + UI_BoxFlag_DrawBackgroundBlur| + UI_BoxFlag_DrawDropShadow| + UI_BoxFlag_Clip| + UI_BoxFlag_AllowOverflowY| + UI_BoxFlag_ViewScroll| + UI_BoxFlag_ViewClamp| + UI_BoxFlag_Floating| + UI_BoxFlag_AnimatePos| + UI_BoxFlag_Clickable| + UI_BoxFlag_DefaultFocusNav, + "###hover_eval"); + } + + //- rjf: build contents + UI_Parent(hover_eval_box) UI_PrefHeight(ui_px(row_height, 1.f)) + { + //- rjf: build rows + for(DF_EvalVizRow *row = viz_rows.first; row != 0; row = row->next) + { + //- rjf: determine if row's data is fresh + B32 row_is_fresh = 0; + switch(row->eval.mode) + { + default:{}break; + case EVAL_EvalMode_Addr: + { + U64 size = tg_byte_size_from_graph_raddbg_key(parse_ctx.type_graph, parse_ctx.rdbg, row->eval.type_key); + size = Min(size, 64); + Rng1U64 vaddr_rng = r1u64(row->eval.offset, row->eval.offset+size); + CTRL_ProcessMemorySlice slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, process->ctrl_machine_id, process->ctrl_handle, vaddr_rng, 0); + for(U64 idx = 0; idx < (slice.data.size+63)/64; idx += 1) + { + if(slice.byte_changed_flags[idx] != 0) + { + row_is_fresh = 1; + break; + } + } + }break; + } + + //- rjf: build row + UI_WidthFill UI_Row + { + ui_spacer(ui_em(0.75f, 1.f)); + ui_spacer(ui_em(1.5f*row->depth, 1.f)); + U64 row_hash = df_hash_from_expand_key(row->key); + B32 row_is_expanded = df_expand_key_is_set(&eval_view->expand_tree_table, row->key); + if(row->flags & DF_EvalVizRowFlag_CanExpand) + UI_PrefWidth(ui_em(1.5f, 1)) + if(ui_expanderf(row_is_expanded, "###%I64x_%I64x_is_expanded", row->key.parent_hash, row->key.child_num).pressed) + { + df_expand_set_expansion(eval_view->arena, &eval_view->expand_tree_table, row->parent_key, row->key, !row_is_expanded); + } + UI_WidthFill + { + UI_PrefWidth(ui_em(15.f, 1.f)) df_code_label(1.f, 1, df_rgba_from_theme_color(DF_ThemeColor_CodeDefault), row->expr); + ui_spacer(ui_em(1.5f, 1.f)); + if(row->flags & DF_EvalVizRowFlag_CanEditValue) + { + if(row_is_fresh) + { + Vec4F32 rgba = df_rgba_from_theme_color(DF_ThemeColor_Highlight0); + rgba.w *= 0.2f; + ui_set_next_background_color(rgba); + } + UI_Signal sig = df_line_editf(DF_LineEditFlag_CodeContents| + DF_LineEditFlag_DisplayStringIsCode| + DF_LineEditFlag_PreferDisplayString| + DF_LineEditFlag_Border, + 0, 0, &ws->hover_eval_txt_cursor, &ws->hover_eval_txt_mark, ws->hover_eval_txt_buffer, sizeof(ws->hover_eval_txt_buffer), &ws->hover_eval_txt_size, 0, row->edit_value, "%S###val_%I64x", row->display_value, row_hash); + if(sig.commit) + { + String8 commit_string = str8(ws->hover_eval_txt_buffer, ws->hover_eval_txt_size); + DF_Eval write_eval = df_eval_from_string(scratch.arena, scope, &ctrl_ctx, &parse_ctx, commit_string); + B32 success = df_commit_eval_value(parse_ctx.type_graph, parse_ctx.rdbg, &ctrl_ctx, row->eval, write_eval); + if(success == 0) + { + DF_CmdParams params = df_cmd_params_from_window(ws); + params.string = str8_lit("Could not commit value successfully."); + df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_String); + df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_Error)); + } + } + } + else + { + if(row_is_fresh) + { + Vec4F32 rgba = df_rgba_from_theme_color(DF_ThemeColor_Highlight0); + rgba.w *= 0.2f; + ui_set_next_background_color(rgba); + ui_set_next_flags(UI_BoxFlag_DrawBackground); + } + df_code_label(1.f, 1, df_rgba_from_theme_color(DF_ThemeColor_CodeDefault), row->display_value); + } + } + if(row == viz_rows.first) + { + UI_TextAlignment(UI_TextAlign_Center) UI_PrefWidth(ui_em(3.f, 1.f)) + UI_CornerRadius00(0) + UI_CornerRadius01(0) + UI_CornerRadius10(0) + UI_CornerRadius11(0) + { + UI_Signal watch_sig = df_icon_buttonf(DF_IconKind_List, 0, "###watch_hover_eval"); + if(watch_sig.hovering) UI_Tooltip UI_Font(df_font_from_slot(DF_FontSlot_Main)) UI_FontSize(df_font_size_from_slot(ws, DF_FontSlot_Main)) + { + ui_labelf("Add the hovered expression to an opened watch view."); + } + if(watch_sig.clicked) + { + DF_CmdParams params = df_cmd_params_from_window(ws); + params.string = expr; + df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_String); + df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_ToggleWatchExpression)); + } + } + if(!df_entity_is_nil(df_entity_from_handle(ws->hover_eval_file))) + UI_TextAlignment(UI_TextAlign_Center) UI_PrefWidth(ui_em(3.f, 1.f)) + UI_CornerRadius10(corner_radius) + UI_CornerRadius11(corner_radius) + { + UI_Signal pin_sig = df_icon_buttonf(DF_IconKind_Pin, 0, "###pin_hover_eval"); + if(pin_sig.hovering) UI_Tooltip UI_Font(df_font_from_slot(DF_FontSlot_Main)) UI_FontSize(df_font_size_from_slot(ws, DF_FontSlot_Main)) + UI_CornerRadius00(0) + UI_CornerRadius01(0) + UI_CornerRadius10(0) + UI_CornerRadius11(0) + { + ui_labelf("Pin the hovered expression to this code location."); + } + if(pin_sig.clicked) + { + DF_CmdParams params = df_cmd_params_from_window(ws); + if(ws->hover_eval_vaddr != 0) + { + params.vaddr = ws->hover_eval_vaddr; + df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_VirtualAddr); + } + else + { + params.entity = ws->hover_eval_file; + params.text_point = ws->hover_eval_file_pt; + df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_Entity); + df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_TextPoint); + } + params.string = expr; + df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_String); + df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_ToggleWatchPin)); + } + } + } + } + } + UI_PrefWidth(ui_px(0, 0)) ui_spacer(ui_px(hover_eval_container_height-row_height, 1.f)); + } + + //- rjf: interact + { + UI_Signal hover_eval_sig = ui_signal_from_box(hover_eval_box); + if(hover_eval_sig.mouse_over) + { + ws->hover_eval_last_frame_idx = df_frame_index(); + } + else if(ws->hover_eval_last_frame_idx+2 < df_frame_index()) + { + df_gfx_request_frame(); + } + } + } + + dbgi_scope_close(scope); + scratch_end(scratch); + } + } + //////////////////////////// //- rjf: panel non-leaf UI (drag boundaries) // @@ -9830,7 +9824,7 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ ////////////////////////////// //- rjf: mouse -> expression range info // - if(text_container_sig.mouse_over && contains_1s64(params->line_num_range, mouse_pt.line)) ProfScope("mouse -> expression range") + if(text_container_sig.hovering && contains_1s64(params->line_num_range, mouse_pt.line)) ProfScope("mouse -> expression range") { TxtRng selected_rng = txt_rng(*cursor, *mark); if(!txt_pt_match(*cursor, *mark) && cursor->line == mark->line &&