diff --git a/src/df/gfx/df_gfx.c b/src/df/gfx/df_gfx.c index 47f33a30..9bca1876 100644 --- a/src/df/gfx/df_gfx.c +++ b/src/df/gfx/df_gfx.c @@ -781,7 +781,7 @@ df_view_release(DF_View *view) } internal void -df_view_equip_spec(DF_View *view, DF_ViewSpec *spec, DF_Entity *entity, String8 default_query, DF_CfgNode *cfg_root) +df_view_equip_spec(DF_Window *window, DF_View *view, DF_ViewSpec *spec, DF_Entity *entity, String8 default_query, DF_CfgNode *cfg_root) { // rjf: fill arguments buffer view->query_string_size = Min(sizeof(view->query_buffer), default_query.size); @@ -798,7 +798,7 @@ df_view_equip_spec(DF_View *view, DF_ViewSpec *spec, DF_Entity *entity, String8 view->entity = df_handle_from_entity(entity); view->is_filtering = 0; view->is_filtering_t = 0; - view_setup(view, cfg_root); + view_setup(window, view, cfg_root); } } @@ -1337,82 +1337,82 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D if(df_view_is_nil(watch)) { watch = df_view_alloc(); - df_view_equip_spec(watch, df_view_spec_from_gfx_view_kind(DF_GfxViewKind_Watch), &df_g_nil_entity, str8_lit(""), &df_g_nil_cfg_node); + df_view_equip_spec(ws, watch, df_view_spec_from_gfx_view_kind(DF_GfxViewKind_Watch), &df_g_nil_entity, str8_lit(""), &df_g_nil_cfg_node); } if(df_view_is_nil(locals)) { locals = df_view_alloc(); - df_view_equip_spec(locals, df_view_spec_from_gfx_view_kind(DF_GfxViewKind_Locals), &df_g_nil_entity, str8_lit(""), &df_g_nil_cfg_node); + df_view_equip_spec(ws, locals, df_view_spec_from_gfx_view_kind(DF_GfxViewKind_Locals), &df_g_nil_entity, str8_lit(""), &df_g_nil_cfg_node); } if(df_view_is_nil(regs)) { regs = df_view_alloc(); - df_view_equip_spec(regs, df_view_spec_from_gfx_view_kind(DF_GfxViewKind_Registers), &df_g_nil_entity, str8_lit(""), &df_g_nil_cfg_node); + df_view_equip_spec(ws, regs, df_view_spec_from_gfx_view_kind(DF_GfxViewKind_Registers), &df_g_nil_entity, str8_lit(""), &df_g_nil_cfg_node); } if(df_view_is_nil(globals)) { globals = df_view_alloc(); - df_view_equip_spec(globals, df_view_spec_from_gfx_view_kind(DF_GfxViewKind_Globals), &df_g_nil_entity, str8_lit(""), &df_g_nil_cfg_node); + df_view_equip_spec(ws, globals, df_view_spec_from_gfx_view_kind(DF_GfxViewKind_Globals), &df_g_nil_entity, str8_lit(""), &df_g_nil_cfg_node); } if(df_view_is_nil(tlocals)) { tlocals = df_view_alloc(); - df_view_equip_spec(tlocals, df_view_spec_from_gfx_view_kind(DF_GfxViewKind_ThreadLocals), &df_g_nil_entity, str8_lit(""), &df_g_nil_cfg_node); + df_view_equip_spec(ws, tlocals, df_view_spec_from_gfx_view_kind(DF_GfxViewKind_ThreadLocals), &df_g_nil_entity, str8_lit(""), &df_g_nil_cfg_node); } if(df_view_is_nil(types)) { types = df_view_alloc(); - df_view_equip_spec(types, df_view_spec_from_gfx_view_kind(DF_GfxViewKind_Types), &df_g_nil_entity, str8_lit(""), &df_g_nil_cfg_node); + df_view_equip_spec(ws, types, df_view_spec_from_gfx_view_kind(DF_GfxViewKind_Types), &df_g_nil_entity, str8_lit(""), &df_g_nil_cfg_node); } if(df_view_is_nil(procs)) { procs = df_view_alloc(); - df_view_equip_spec(procs, df_view_spec_from_gfx_view_kind(DF_GfxViewKind_Procedures), &df_g_nil_entity, str8_lit(""), &df_g_nil_cfg_node); + df_view_equip_spec(ws, procs, df_view_spec_from_gfx_view_kind(DF_GfxViewKind_Procedures), &df_g_nil_entity, str8_lit(""), &df_g_nil_cfg_node); } if(df_view_is_nil(callstack)) { callstack = df_view_alloc(); - df_view_equip_spec(callstack, df_view_spec_from_gfx_view_kind(DF_GfxViewKind_CallStack), &df_g_nil_entity, str8_lit(""), &df_g_nil_cfg_node); + df_view_equip_spec(ws, callstack, df_view_spec_from_gfx_view_kind(DF_GfxViewKind_CallStack), &df_g_nil_entity, str8_lit(""), &df_g_nil_cfg_node); } if(df_view_is_nil(breakpoints)) { breakpoints = df_view_alloc(); - df_view_equip_spec(breakpoints, df_view_spec_from_gfx_view_kind(DF_GfxViewKind_Breakpoints), &df_g_nil_entity, str8_lit(""), &df_g_nil_cfg_node); + df_view_equip_spec(ws, breakpoints, df_view_spec_from_gfx_view_kind(DF_GfxViewKind_Breakpoints), &df_g_nil_entity, str8_lit(""), &df_g_nil_cfg_node); } if(df_view_is_nil(watch_pins)) { watch_pins = df_view_alloc(); - df_view_equip_spec(watch_pins, df_view_spec_from_gfx_view_kind(DF_GfxViewKind_WatchPins), &df_g_nil_entity, str8_lit(""), &df_g_nil_cfg_node); + df_view_equip_spec(ws, watch_pins, df_view_spec_from_gfx_view_kind(DF_GfxViewKind_WatchPins), &df_g_nil_entity, str8_lit(""), &df_g_nil_cfg_node); } if(df_view_is_nil(output)) { output = df_view_alloc(); - df_view_equip_spec(output, df_view_spec_from_gfx_view_kind(DF_GfxViewKind_Output), &df_g_nil_entity, str8_lit(""), &df_g_nil_cfg_node); + df_view_equip_spec(ws, output, df_view_spec_from_gfx_view_kind(DF_GfxViewKind_Output), &df_g_nil_entity, str8_lit(""), &df_g_nil_cfg_node); } if(df_view_is_nil(targets)) { targets = df_view_alloc(); - df_view_equip_spec(targets, df_view_spec_from_gfx_view_kind(DF_GfxViewKind_Targets), &df_g_nil_entity, str8_lit(""), &df_g_nil_cfg_node); + df_view_equip_spec(ws, targets, df_view_spec_from_gfx_view_kind(DF_GfxViewKind_Targets), &df_g_nil_entity, str8_lit(""), &df_g_nil_cfg_node); } if(df_view_is_nil(scheduler)) { scheduler = df_view_alloc(); - df_view_equip_spec(scheduler, df_view_spec_from_gfx_view_kind(DF_GfxViewKind_Scheduler), &df_g_nil_entity, str8_lit(""), &df_g_nil_cfg_node); + df_view_equip_spec(ws, scheduler, df_view_spec_from_gfx_view_kind(DF_GfxViewKind_Scheduler), &df_g_nil_entity, str8_lit(""), &df_g_nil_cfg_node); } if(df_view_is_nil(modules)) { modules = df_view_alloc(); - df_view_equip_spec(modules, df_view_spec_from_gfx_view_kind(DF_GfxViewKind_Modules), &df_g_nil_entity, str8_lit(""), &df_g_nil_cfg_node); + df_view_equip_spec(ws, modules, df_view_spec_from_gfx_view_kind(DF_GfxViewKind_Modules), &df_g_nil_entity, str8_lit(""), &df_g_nil_cfg_node); } if(df_view_is_nil(disasm)) { disasm = df_view_alloc(); - df_view_equip_spec(disasm, df_view_spec_from_gfx_view_kind(DF_GfxViewKind_Disassembly), &df_g_nil_entity, str8_lit(""), &df_g_nil_cfg_node); + df_view_equip_spec(ws, disasm, df_view_spec_from_gfx_view_kind(DF_GfxViewKind_Disassembly), &df_g_nil_entity, str8_lit(""), &df_g_nil_cfg_node); } if(df_view_is_nil(memory)) { memory = df_view_alloc(); - df_view_equip_spec(memory, df_view_spec_from_gfx_view_kind(DF_GfxViewKind_Memory), &df_g_nil_entity, str8_lit(""), &df_g_nil_cfg_node); + df_view_equip_spec(ws, memory, df_view_spec_from_gfx_view_kind(DF_GfxViewKind_Memory), &df_g_nil_entity, str8_lit(""), &df_g_nil_cfg_node); } // rjf: root split @@ -1779,7 +1779,7 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D if(!df_panel_is_nil(panel) && spec != &df_g_nil_view_spec) { DF_View *view = df_view_alloc(); - df_view_equip_spec(view, spec, entity, params.string, params.cfg_node); + df_view_equip_spec(ws, view, spec, entity, params.string, params.cfg_node); df_panel_insert_tab_view(panel, panel->last_tab_view, view); df_panel_notify_mutation(ws, panel); } @@ -2702,7 +2702,7 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D if(!df_panel_is_nil(dst_panel) && df_view_is_nil(view_w_this_src_code)) { DF_View *view = df_view_alloc(); - df_view_equip_spec(view, df_view_spec_from_gfx_view_kind(DF_GfxViewKind_Code), src_code, str8_lit(""), &df_g_nil_cfg_node); + df_view_equip_spec(ws, view, df_view_spec_from_gfx_view_kind(DF_GfxViewKind_Code), src_code, str8_lit(""), &df_g_nil_cfg_node); df_panel_insert_tab_view(dst_panel, dst_panel->last_tab_view, view); dst_view = view; } @@ -2750,7 +2750,7 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D if(!df_panel_is_nil(dst_panel) && df_view_is_nil(view_w_disasm)) { DF_View *view = df_view_alloc(); - df_view_equip_spec(view, df_view_spec_from_gfx_view_kind(DF_GfxViewKind_Disassembly), &df_g_nil_entity, str8_lit(""), &df_g_nil_cfg_node); + df_view_equip_spec(ws, view, df_view_spec_from_gfx_view_kind(DF_GfxViewKind_Disassembly), &df_g_nil_entity, str8_lit(""), &df_g_nil_cfg_node); df_panel_insert_tab_view(dst_panel, dst_panel->last_tab_view, view); dst_view = view; } @@ -4797,7 +4797,7 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D // rjf: construct & push new view DF_View *view = df_view_alloc(); - df_view_equip_spec(view, view_spec, &df_g_nil_entity, default_query, &df_g_nil_cfg_node); + df_view_equip_spec(ws, view, view_spec, &df_g_nil_entity, default_query, &df_g_nil_cfg_node); if(cmd_spec->info.query.flags & DF_CmdQueryFlag_SelectOldInput) { view->query_mark = txt_pt(1, 1); @@ -7988,7 +7988,7 @@ df_cfg_strings_from_gfx(Arena *arena, String8 root_path, DF_CfgSrc source) Temp scratch = scratch_begin(&arena, 1); String8 query_raw = str8(view->query_buffer, view->query_string_size); String8 query_sanitized = df_cfg_escaped_from_raw_string(scratch.arena, query_raw); - str8_list_pushf(arena, &strs, "query:\"%S\" ", query_sanitized); + str8_list_pushf(arena, &strs, "query:{\"%S\"} ", query_sanitized); scratch_end(scratch); } if(view->spec->info.flags & DF_ViewSpecFlag_CanSerializeEntityPath) @@ -11843,7 +11843,7 @@ df_gfx_begin_frame(Arena *arena, DF_CmdList *cmds) } // rjf: set up view - df_view_equip_spec(view, view_spec, entity, view_query, op); + df_view_equip_spec(ws, view, view_spec, entity, view_query, op); } // rjf: insert diff --git a/src/df/gfx/df_gfx.h b/src/df/gfx/df_gfx.h index 5c700ca8..a6c0d110 100644 --- a/src/df/gfx/df_gfx.h +++ b/src/df/gfx/df_gfx.h @@ -73,7 +73,7 @@ struct DF_View; struct DF_Panel; struct DF_Window; -#define DF_VIEW_SETUP_FUNCTION_SIG(name) void name(struct DF_View *view, DF_CfgNode *cfg_root) +#define DF_VIEW_SETUP_FUNCTION_SIG(name) void name(DF_Window *ws, struct DF_View *view, DF_CfgNode *cfg_root) #define DF_VIEW_SETUP_FUNCTION_NAME(name) df_view_setup_##name #define DF_VIEW_SETUP_FUNCTION_DEF(name) internal DF_VIEW_SETUP_FUNCTION_SIG(DF_VIEW_SETUP_FUNCTION_NAME(name)) typedef DF_VIEW_SETUP_FUNCTION_SIG(DF_ViewSetupFunctionType); @@ -866,7 +866,7 @@ internal DF_ViewSpec *df_tab_view_spec_from_gfx_view_rule_spec(DF_GfxViewRuleSpe internal DF_View *df_view_alloc(void); internal void df_view_release(DF_View *view); -internal void df_view_equip_spec(DF_View *view, DF_ViewSpec *spec, DF_Entity *entity, String8 default_query, DF_CfgNode *cfg_root); +internal void df_view_equip_spec(DF_Window *window, DF_View *view, DF_ViewSpec *spec, DF_Entity *entity, String8 default_query, DF_CfgNode *cfg_root); internal void df_view_equip_loading_info(DF_View *view, B32 is_loading, U64 progress_v, U64 progress_target); internal void df_view_clear_user_state(DF_View *view); internal void *df_view_get_or_push_user_state(DF_View *view, U64 size); diff --git a/src/df/gfx/df_view_rule_hooks.c b/src/df/gfx/df_view_rule_hooks.c index 7f8290d4..991965bd 100644 --- a/src/df/gfx/df_view_rule_hooks.c +++ b/src/df/gfx/df_view_rule_hooks.c @@ -1150,11 +1150,218 @@ DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(bitmap) scratch_end(scratch); } -DF_VIEW_SETUP_FUNCTION_DEF(bitmap) {} -DF_VIEW_STRING_FROM_STATE_FUNCTION_DEF(bitmap) { return str8_lit(""); } -DF_VIEW_CMD_FUNCTION_DEF(bitmap) {} +typedef struct DF_BitmapViewState DF_BitmapViewState; +struct DF_BitmapViewState +{ + Vec2F32 view_center_pos; + F32 zoom; + DF_BitmapTopologyInfo top; +}; + +internal Vec2F32 +df_bitmap_view_state__screen_from_canvas_pos(DF_BitmapViewState *bvs, Rng2F32 rect, Vec2F32 cvs) +{ + Vec2F32 scr = + { + (rect.x0+rect.x1)/2 + (cvs.x - bvs->view_center_pos.x) * bvs->zoom, + (rect.y0+rect.y1)/2 + (cvs.y - bvs->view_center_pos.y) * bvs->zoom, + }; + return scr; +} + +internal Rng2F32 +df_bitmap_view_state__screen_from_canvas_rect(DF_BitmapViewState *bvs, Rng2F32 rect, Rng2F32 cvs) +{ + Rng2F32 scr = r2f32(df_bitmap_view_state__screen_from_canvas_pos(bvs, rect, cvs.p0), df_bitmap_view_state__screen_from_canvas_pos(bvs, rect, cvs.p1)); + return scr; +} + +internal Vec2F32 +df_bitmap_view_state__canvas_from_screen_pos(DF_BitmapViewState *bvs, Rng2F32 rect, Vec2F32 scr) +{ + Vec2F32 cvs = + { + (scr.x - (rect.x0+rect.x1)/2) / bvs->zoom + bvs->view_center_pos.x, + (scr.y - (rect.y0+rect.y1)/2) / bvs->zoom + bvs->view_center_pos.y, + }; + return cvs; +} + +internal Rng2F32 +df_bitmap_view_state__canvas_from_screen_rect(DF_BitmapViewState *bvs, Rng2F32 rect, Rng2F32 scr) +{ + Rng2F32 cvs = r2f32(df_bitmap_view_state__canvas_from_screen_pos(bvs, rect, scr.p0), df_bitmap_view_state__canvas_from_screen_pos(bvs, rect, scr.p1)); + return cvs; +} + +DF_VIEW_SETUP_FUNCTION_DEF(bitmap) +{ + DF_BitmapViewState *bvs = df_view_user_state(view, DF_BitmapViewState); + DBGI_Scope *dbgi_scope = dbgi_scope_open(); + DF_CfgNode *view_center_cfg = df_cfg_node_child_from_string(cfg_root, str8_lit("view_center"), StringMatchFlag_CaseInsensitive); + DF_CfgNode *zoom_cfg = df_cfg_node_child_from_string(cfg_root, str8_lit("zoom"), StringMatchFlag_CaseInsensitive); + DF_CfgNode *bitmap_cfg = df_cfg_node_child_from_string(cfg_root, str8_lit("bitmap"), StringMatchFlag_CaseInsensitive); + DF_CtrlCtx ctrl_ctx = df_ctrl_ctx_from_view(ws, view); + 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(dbgi_scope, process, thread_unwind_rip_vaddr); + bvs->view_center_pos.x = (F32)f64_from_str8(bitmap_cfg->first->string); + bvs->view_center_pos.y = (F32)f64_from_str8(bitmap_cfg->first->next->string); + bvs->zoom = (F32)f64_from_str8(zoom_cfg->first->string); + bvs->top = df_view_rule_hooks__bitmap_topology_info_from_cfg(dbgi_scope, &ctrl_ctx, &parse_ctx, &eval_string2expr_map_nil, bitmap_cfg); + if(bvs->zoom == 0) + { + bvs->zoom = 1.f; + } + dbgi_scope_close(dbgi_scope); +} + +DF_VIEW_STRING_FROM_STATE_FUNCTION_DEF(bitmap) +{ + DF_BitmapViewState *bvs = df_view_user_state(view, DF_BitmapViewState); + String8 result = push_str8f(arena, "view_center:(%.2f %.2f) zoom:(%.2f) bitmap:(w:%I64u, h:%I64u, fmt:%S)", + bvs->view_center_pos.x, + bvs->view_center_pos.y, + bvs->zoom, + bvs->top.width, + bvs->top.height, + r_tex2d_format_display_string_table[bvs->top.fmt]); + return result; +} + +DF_VIEW_CMD_FUNCTION_DEF(bitmap) +{ +} + +internal UI_BOX_CUSTOM_DRAW(df_bitmap_view_canvas_box_draw) +{ + DF_BitmapViewState *bvs = (DF_BitmapViewState *)user_data; + Rng2F32 rect_scrn = box->rect; + Rng2F32 rect_cvs = df_bitmap_view_state__canvas_from_screen_rect(bvs, rect_scrn, rect_scrn); + F32 grid_cell_size_cvs = box->font_size*10.f; + F32 grid_line_thickness_px = Max(2.f, box->font_size*0.1f); + Vec4F32 grid_line_color = df_rgba_from_theme_color(DF_ThemeColor_WeakText); + for(EachEnumVal(Axis2, axis)) + { + for(F32 v = rect_cvs.p0.v[axis] - mod_f32(rect_cvs.p0.v[axis], grid_cell_size_cvs); + v < rect_cvs.p1.v[axis]; + v += grid_cell_size_cvs) + { + Vec2F32 p_cvs = {0}; + p_cvs.v[axis] = v; + Vec2F32 p_scr = df_bitmap_view_state__screen_from_canvas_pos(bvs, rect_scrn, p_cvs); + Rng2F32 rect = {0}; + rect.p0.v[axis] = p_scr.v[axis] - grid_line_thickness_px/2; + rect.p1.v[axis] = p_scr.v[axis] + grid_line_thickness_px/2; + rect.p0.v[axis2_flip(axis)] = box->rect.p0.v[axis2_flip(axis)]; + rect.p1.v[axis2_flip(axis)] = box->rect.p1.v[axis2_flip(axis)]; + d_rect(rect, grid_line_color, 0, 0, 1.f); + } + } +} + DF_VIEW_UI_FUNCTION_DEF(bitmap) { + DF_BitmapViewState *bvs = df_view_user_state(view, DF_BitmapViewState); + Temp scratch = scratch_begin(0, 0); + DBGI_Scope *dbgi_scope = dbgi_scope_open(); + HS_Scope *hs_scope = hs_scope_open(); + TEX_Scope *tex_scope = tex_scope_open(); + + ////////////////////////////// + //- rjf: unpack context + // + DF_CtrlCtx ctrl_ctx = df_ctrl_ctx_from_view(ws, view); + 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(dbgi_scope, process, thread_unwind_rip_vaddr); + + ////////////////////////////// + //- rjf: evaluate expression + // + String8 expr = str8(view->query_buffer, view->query_string_size); + DF_Eval eval = df_eval_from_string(scratch.arena, dbgi_scope, &ctrl_ctx, &parse_ctx, &eval_string2expr_map_nil, expr); + DF_Eval value_eval = df_value_mode_eval_from_eval(parse_ctx.type_graph, parse_ctx.rdi, &ctrl_ctx, eval); + U64 base_vaddr = value_eval.imm_u64 ? value_eval.imm_u64 : value_eval.offset; + U64 expected_size = bvs->top.width*bvs->top.height*r_tex2d_format_bytes_per_pixel_table[bvs->top.fmt]; + Rng1U64 vaddr_range = r1u64(base_vaddr, base_vaddr+expected_size); + + ////////////////////////////// + //- rjf: map expression artifacts -> texture + // + U128 texture_key = ctrl_hash_store_key_from_process_vaddr_range(process->ctrl_machine_id, process->ctrl_handle, vaddr_range, 0); + TEX_Topology topology = tex_topology_make(v2s32((S32)bvs->top.width, (S32)bvs->top.height), bvs->top.fmt); + R_Handle texture = tex_texture_from_key_topology(tex_scope, texture_key, topology); + + ////////////////////////////// + //- rjf: build canvas box + // + UI_Box *canvas_box = &ui_g_nil_box; + Vec2F32 canvas_dim = dim_2f32(rect); + Rng2F32 canvas_rect = r2f32p(0, 0, canvas_dim.x, canvas_dim.y); + UI_Rect(canvas_rect) + { + canvas_box = ui_build_box_from_stringf(UI_BoxFlag_Clip|UI_BoxFlag_Clickable|UI_BoxFlag_Scroll, "bmp_canvas_%p", view); + ui_box_equip_custom_draw(canvas_box, df_bitmap_view_canvas_box_draw, bvs); + } + + ////////////////////////////// + //- rjf: canvas box interaction + // + { + UI_Signal canvas_sig = ui_signal_from_box(canvas_box); + if(ui_dragging(canvas_sig)) + { + if(ui_pressed(canvas_sig)) + { + DF_CmdParams p = df_cmd_params_from_view(ws, panel, view); + df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_FocusPanel)); + ui_store_drag_struct(&bvs->view_center_pos); + } + Vec2F32 start_view_center_pos = *ui_get_drag_struct(Vec2F32); + Vec2F32 drag_delta_scr = ui_drag_delta(); + Vec2F32 drag_delta_cvs = scale_2f32(drag_delta_scr, 1.f/bvs->zoom); + Vec2F32 new_view_center_pos = sub_2f32(start_view_center_pos, drag_delta_cvs); + bvs->view_center_pos = new_view_center_pos; + } + if(canvas_sig.scroll.y != 0) + { + F32 new_zoom = bvs->zoom - bvs->zoom*canvas_sig.scroll.y/10.f; + new_zoom = Clamp(1.f/256.f, new_zoom, 256.f); + Vec2F32 mouse_scr_pre = sub_2f32(ui_mouse(), rect.p0); + Vec2F32 mouse_cvs = df_bitmap_view_state__canvas_from_screen_pos(bvs, canvas_rect, mouse_scr_pre); + bvs->zoom = new_zoom; + Vec2F32 mouse_scr_pst = df_bitmap_view_state__screen_from_canvas_pos(bvs, canvas_rect, mouse_cvs); + Vec2F32 drift_scr = sub_2f32(mouse_scr_pst, mouse_scr_pre); + bvs->view_center_pos = add_2f32(bvs->view_center_pos, scale_2f32(drift_scr, 1.f/new_zoom)); + } + if(ui_double_clicked(canvas_sig)) + { + ui_kill_action(); + MemoryZeroStruct(&bvs->view_center_pos); + bvs->zoom = 1.f; + } + } + + ////////////////////////////// + //- rjf: build image + // + UI_Parent(canvas_box) + { + Rng2F32 img_rect_cvs = r2f32p(-topology.dim.x/2, -topology.dim.y/2, +topology.dim.x/2, +topology.dim.y/2); + Rng2F32 img_rect_scr = df_bitmap_view_state__screen_from_canvas_rect(bvs, canvas_rect, img_rect_cvs); + UI_Rect(img_rect_scr) UI_Flags(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawDropShadow|UI_BoxFlag_Floating) + { + ui_image(texture, r2f32p(0, 0, (F32)bvs->top.width, (F32)bvs->top.height), v4f32(1, 1, 1, 1), 0, str8_lit("bmp_image")); + } + } + + hs_scope_close(hs_scope); + tex_scope_close(tex_scope); + dbgi_scope_close(dbgi_scope); + scratch_end(scratch); } //////////////////////////////// diff --git a/src/df/gfx/df_view_rule_hooks.h b/src/df/gfx/df_view_rule_hooks.h index 4ac8729e..2066827e 100644 --- a/src/df/gfx/df_view_rule_hooks.h +++ b/src/df/gfx/df_view_rule_hooks.h @@ -46,4 +46,4 @@ internal DF_GeoTopologyInfo df_view_rule_hooks__geo_topology_info_from_cfg(DBGI_ internal DF_TxtTopologyInfo df_view_rule_hooks__txt_topology_info_from_cfg(DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_CfgNode *cfg); internal DF_DisasmTopologyInfo df_view_rule_hooks__disasm_topology_info_from_cfg(DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_CfgNode *cfg); -#endif //DF_VIEW_RULE_HOOKS_H +#endif // DF_VIEW_RULE_HOOKS_H diff --git a/src/df/gfx/df_views.c b/src/df/gfx/df_views.c index 0eb281b6..e8d59ccf 100644 --- a/src/df/gfx/df_views.c +++ b/src/df/gfx/df_views.c @@ -1073,10 +1073,15 @@ df_eval_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_EvalW //- rjf: double clicked or keyboard clicked -> open dedicated tab if(ui_double_clicked(sig) || sig.f & UI_SignalFlag_KeyboardPressed) { + DF_CfgNode *cfg = df_cfg_tree_copy(scratch.arena, row->expand_ui_rule_node); + DF_CfgNode *cfg_root = push_array(scratch.arena, DF_CfgNode, 1); + cfg_root->first = cfg_root->last = cfg; + cfg_root->next = cfg_root->parent = &df_g_nil_cfg_node; + cfg->parent = cfg_root; DF_CmdParams p = df_cmd_params_from_view(ws, panel, view); p.string = row->edit_expr; p.view_spec = df_tab_view_spec_from_gfx_view_rule_spec(row->expand_ui_rule_spec); - p.cfg_node = row->expand_ui_rule_node; + p.cfg_node = cfg_root; df_cmd_params_mark_slot(&p, DF_CmdParamSlot_String); df_cmd_params_mark_slot(&p, DF_CmdParamSlot_ViewSpec); df_cmd_params_mark_slot(&p, DF_CmdParamSlot_CfgNode); @@ -2147,7 +2152,7 @@ DF_VIEW_UI_FUNCTION_DEF(FileSystem) if(query_normalized_with_opt_slash_props.flags & FilePropertyFlag_IsFolder) { String8 new_path = push_str8f(scratch.arena, "%S%S/", path_query.path, path_query.search); - df_view_equip_spec(view, view->spec, df_entity_from_handle(view->entity), new_path, &df_g_nil_cfg_node); + df_view_equip_spec(ws, view, view->spec, df_entity_from_handle(view->entity), new_path, &df_g_nil_cfg_node); } // rjf: is a file -> complete view @@ -2177,7 +2182,7 @@ DF_VIEW_UI_FUNCTION_DEF(FileSystem) { String8 existing_path = str8_chop_last_slash(path_query.path); String8 new_path = push_str8f(scratch.arena, "%S/%S/", existing_path, files[0].filename); - df_view_equip_spec(view, view->spec, df_entity_from_handle(view->entity), new_path, &df_g_nil_cfg_node); + df_view_equip_spec(ws, view, view->spec, df_entity_from_handle(view->entity), new_path, &df_g_nil_cfg_node); } else { @@ -2309,7 +2314,7 @@ DF_VIEW_UI_FUNCTION_DEF(FileSystem) { new_path = path_normalized_from_string(scratch.arena, new_path); String8 new_cmd = push_str8f(scratch.arena, "%S/", new_path); - df_view_equip_spec(view, view->spec, df_entity_from_handle(view->entity), new_cmd, &df_g_nil_cfg_node); + df_view_equip_spec(ws, view, view->spec, df_entity_from_handle(view->entity), new_cmd, &df_g_nil_cfg_node); } } } @@ -2392,7 +2397,7 @@ DF_VIEW_UI_FUNCTION_DEF(FileSystem) if(file->props.flags & FilePropertyFlag_IsFolder) { String8 new_cmd = push_str8f(scratch.arena, "%S/", new_path); - df_view_equip_spec(view, view->spec, df_entity_from_handle(view->entity), new_cmd, &df_g_nil_cfg_node); + df_view_equip_spec(ws, view, view->spec, df_entity_from_handle(view->entity), new_cmd, &df_g_nil_cfg_node); } else { @@ -4894,7 +4899,7 @@ DF_VIEW_CMD_FUNCTION_DEF(PendingEntity) { view_spec = df_view_spec_from_gfx_view_kind(viewer_kind); } - df_view_equip_spec(view, view_spec, entity, str8_lit(""), cfg_root); + df_view_equip_spec(ws, view, view_spec, entity, str8_lit(""), cfg_root); df_panel_notify_mutation(ws, panel); } diff --git a/src/text_cache/text_cache.c b/src/text_cache/text_cache.c index a9a3ea43..51d8cd4d 100644 --- a/src/text_cache/text_cache.c +++ b/src/text_cache/text_cache.c @@ -33,6 +33,23 @@ txt_lang_kind_from_extension(String8 extension) return kind; } +internal String8 +txt_extension_from_lang_kind(TXT_LangKind kind) +{ + String8 result = {0}; + switch(kind) + { + TXT_LangKind_Null: + TXT_LangKind_COUNT: + TXT_LangKind_DisasmX64Intel: + {}break; + TXT_LangKind_C: {result = str8_lit("c");}break; + TXT_LangKind_CPlusPlus: {result = str8_lit("cpp");}break; + TXT_LangKind_Odin: {result = str8_lit("odin");}break; + } + return result; +} + internal TXT_LangKind txt_lang_kind_from_architecture(Architecture arch) { @@ -565,6 +582,7 @@ txt_token_array_from_string__odin(Arena *arena, U64 *bytes_processed_counter, St { read_only local_persist String8 odin_keywords[] = { + str8_lit_comp("align_of"), str8_lit_comp("asm"), str8_lit_comp("auto_cast"), str8_lit_comp("bit_set"), @@ -594,6 +612,7 @@ txt_token_array_from_string__odin(Arena *arena, U64 *bytes_processed_counter, St str8_lit_comp("package"), str8_lit_comp("proc"), str8_lit_comp("return"), + str8_lit_comp("size_of"), str8_lit_comp("struct"), str8_lit_comp("switch"), str8_lit_comp("transmute"), diff --git a/src/text_cache/text_cache.h b/src/text_cache/text_cache.h index 17b32ea9..9b4f5810 100644 --- a/src/text_cache/text_cache.h +++ b/src/text_cache/text_cache.h @@ -234,6 +234,7 @@ global TXT_Shared *txt_shared = 0; //~ rjf: Basic Helpers internal TXT_LangKind txt_lang_kind_from_extension(String8 extension); +internal String8 txt_extension_from_lang_kind(TXT_LangKind kind); internal TXT_LangKind txt_lang_kind_from_architecture(Architecture arch); internal TXT_LangLexFunctionType *txt_lex_function_from_lang_kind(TXT_LangKind kind); diff --git a/src/ui/ui_basic_widgets.c b/src/ui/ui_basic_widgets.c index 7edbfd2b..177e5fe6 100644 --- a/src/ui/ui_basic_widgets.c +++ b/src/ui/ui_basic_widgets.c @@ -330,6 +330,52 @@ ui_line_editf(TxtPt *cursor, TxtPt *mark, U8 *edit_buffer, U64 edit_buffer_size, return result; } +//////////////////////////////// +//~ rjf: Images + +typedef struct UI_ImageDrawData UI_ImageDrawData; +struct UI_ImageDrawData +{ + R_Handle texture; + Rng2F32 region; + Vec4F32 tint; + F32 blur; +}; + +internal UI_BOX_CUSTOM_DRAW(ui_image_draw) +{ + UI_ImageDrawData *draw_data = (UI_ImageDrawData *)user_data; + R_Rect2DInst *inst = d_img(box->rect, draw_data->region, draw_data->texture, draw_data->tint, 0, 0, 0); + MemoryCopyArray(inst->corner_radii, box->corner_radii); +} + +internal UI_Signal +ui_image(R_Handle texture, Rng2F32 region, Vec4F32 tint, F32 blur, String8 string) +{ + UI_Box *box = ui_build_box_from_string(UI_BoxFlag_Clickable, string); + UI_ImageDrawData *draw_data = push_array(ui_build_arena(), UI_ImageDrawData, 1); + draw_data->texture = texture; + draw_data->region = region; + draw_data->tint = tint; + draw_data->blur = blur; + ui_box_equip_custom_draw(box, ui_image_draw, draw_data); + UI_Signal sig = ui_signal_from_box(box); + return sig; +} + +internal UI_Signal +ui_imagef(R_Handle texture, Rng2F32 region, Vec4F32 tint, F32 blur, char *fmt, ...) +{ + Temp scratch = scratch_begin(0, 0); + va_list args; + va_start(args, fmt); + String8 string = push_str8fv(scratch.arena, fmt, args); + va_end(args); + UI_Signal result = ui_image(texture, region, tint, blur, string); + scratch_end(scratch); + return result; +} + //////////////////////////////// //~ rjf: Special Buttons diff --git a/src/ui/ui_basic_widgets.h b/src/ui/ui_basic_widgets.h index c6bd0f01..de1b48b9 100644 --- a/src/ui/ui_basic_widgets.h +++ b/src/ui/ui_basic_widgets.h @@ -80,6 +80,12 @@ internal UI_Signal ui_hover_labelf(char *fmt, ...); internal UI_Signal ui_line_edit(TxtPt *cursor, TxtPt *mark, U8 *edit_buffer, U64 edit_buffer_size, U64 *edit_string_size_out, String8 pre_edit_value, String8 string); internal UI_Signal ui_line_editf(TxtPt *cursor, TxtPt *mark, U8 *edit_buffer, U64 edit_buffer_size, U64 *edit_string_size_out, String8 pre_edit_value, char *fmt, ...); +//////////////////////////////// +//~ rjf: Images + +internal UI_Signal ui_image(R_Handle texture, Rng2F32 region, Vec4F32 tint, F32 blur, String8 string); +internal UI_Signal ui_imagef(R_Handle texture, Rng2F32 region, Vec4F32 tint, F32 blur, char *fmt, ...); + //////////////////////////////// //~ rjf: Special Buttons diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index be62687e..e9bccdab 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -527,6 +527,12 @@ ui_dt(void) //- rjf: drag data +internal Vec2F32 +ui_drag_start_mouse(void) +{ + return ui_state->drag_start_mouse; +} + internal Vec2F32 ui_drag_delta(void) { diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index 3b511a92..cebaa1d1 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -617,6 +617,7 @@ internal String8 ui_icon_string_from_kind(UI_IconKind icon_kind); internal F32 ui_dt(void); //- rjf: drag data +internal Vec2F32 ui_drag_start_mouse(void); internal Vec2F32 ui_drag_delta(void); internal void ui_store_drag_data(String8 string); internal String8 ui_get_drag_data(U64 min_required_size);