diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index b57c8947..d4426e1e 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -322,7 +322,7 @@ RD_NameSchemaInfo rd_name_schema_info_table[16] = {str8_lit_comp("disasm"), str8_lit_comp("x:\n{\n 'arch': arch,\n 'syntax': dasm_syntax,\n 'size': code_string,\n @default(1) 'show_addresses': bool,\n @default(0) 'show_code_bytes': bool,\n @default(1) 'show_source_lines': bool,\n @default(1) 'show_symbol_names': bool,\n @default(1) 'show_line_numbers': bool,\n}\n")}, {str8_lit_comp("memory"), str8_lit_comp("x:\n{\n 'size': code_string,\n @default(16) 'num_columns': @range[1, 64] u64,\n}\n")}, {str8_lit_comp("bitmap"), str8_lit_comp("x:\n{\n 'w': code_string,\n 'h': code_string,\n 'fmt': tex2dformat,\n}\n")}, -{str8_lit_comp("target"), str8_lit_comp("@commands(launch_and_run, launch_and_step_into, enable_cfg, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'debug_subprocesses': bool,\n 'environment': query,\n}\n")}, +{str8_lit_comp("target"), str8_lit_comp("@commands(launch_and_run, launch_and_step_into, enable_cfg, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'environment': query,\n 'debug_subprocesses': bool,\n}\n")}, {str8_lit_comp("breakpoint"), str8_lit_comp("@commands(enable_cfg, remove_cfg)\n@collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint, add_function_breakpoint)\nx:\n{\n 'label': code_string,\n 'condition': code_string,\n 'source_location': path_pt,\n 'address_location': code_string,\n 'hit_count': u64,\n 'disabled': bool,\n}\n")}, {str8_lit_comp("watch_pin"), str8_lit_comp("@commands(remove_cfg)\n@collection_commands(add_watch_pin)\nx:\n{\n 'expression': code_string,\n 'view_rule': code_string,\n 'source_location': path_pt,\n 'address_location': code_string,\n}\n")}, {str8_lit_comp("file_path_map"), str8_lit_comp("@collection_commands(add_file_path_map) @commands(remove_cfg) x:{'source':path, 'dest':path}")}, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 4812a18e..8346f2db 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -228,8 +228,8 @@ RD_VocabTable: 'stdout_path': path, 'stderr_path': path, 'stdin_path': path, - 'debug_subprocesses': bool, 'environment': query, + 'debug_subprocesses': bool, } ```, } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index c8c87233..deca3596 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -3449,10 +3449,10 @@ rd_view_ui(Rng2F32 rect) RD_Font(RD_FontSlot_Main) UI_PrefWidth(ui_text_dim(1, 1)) ui_label(rd_display_from_code_name(cmd_name)); ui_spacer(ui_em(0.5f, 1.f)); - RD_LineEditParams params = {0}; + RD_CellParams params = {0}; { - params.flags |= !!(cmd_kind_info->query.flags & RD_QueryFlag_CodeInput) * RD_LineEditFlag_CodeContents; - params.flags |= RD_LineEditFlag_Border; + params.flags |= !!(cmd_kind_info->query.flags & RD_QueryFlag_CodeInput) * RD_CellFlag_CodeContents; + params.flags |= RD_CellFlag_Border; params.cursor = &vs->query_cursor; params.mark = &vs->query_mark; params.edit_buffer = vs->query_buffer; @@ -3462,7 +3462,7 @@ rd_view_ui(Rng2F32 rect) } UI_Transparency(1-search_row_open_t) { - UI_Signal sig = rd_line_editf(¶ms, "###search"); + UI_Signal sig = rd_cellf(¶ms, "###search"); if(ui_pressed(sig)) { vs->query_is_selected = 1; @@ -4747,12 +4747,14 @@ rd_view_ui(Rng2F32 rect) B32 pressed = 0; ProfScope("build ui") { + Vec2F32 rect_dim = dim_2f32(rect); + F32 contents_width_px = (rect_dim.x - floor_f32(ui_top_font_size()*1.5f)); Rng1S64 visible_row_rng = {0}; UI_ScrollListParams scroll_list_params = {0}; { scroll_list_params.flags = UI_ScrollListFlag_All; scroll_list_params.row_height_px = row_height_px; - scroll_list_params.dim_px = dim_2f32(rect); + scroll_list_params.dim_px = rect_dim; scroll_list_params.cursor_range = r2s64(v2s64(0, 0), v2s64(0, 0)); scroll_list_params.item_range = r1s64(0, block_tree.total_row_count - !!implicit_root); scroll_list_params.cursor_min_is_empty_selection[Axis2_Y] = 1; @@ -4843,7 +4845,7 @@ rd_view_ui(Rng2F32 rect) { EV_Row *row = last_row; RD_WatchRowInfo *row_info = last_row_info; - F32 row_width_px = (dim_2f32(rect).x - floor_f32(ui_top_font_size()*1.5f)); + F32 row_width_px = contents_width_px; if(row_info != 0) { U64 row_hash = ev_hash_from_key(row->key); @@ -5088,7 +5090,7 @@ rd_view_ui(Rng2F32 rect) //- rjf: build row box // ui_set_next_flags(disabled_flags); - ui_set_next_pref_width(ui_pct(1, 0)); + ui_set_next_pref_width(ui_px(contents_width_px, 1.f)); ui_set_next_pref_height(ui_px(row_height_px*row->visual_size, 1.f)); ui_set_next_focus_hot(row_selected ? UI_FocusKind_On : UI_FocusKind_Off); UI_Box *row_box = ui_build_box_from_stringf(row_flags|((!row_node->next)*UI_BoxFlag_DrawSideBottom)|UI_BoxFlag_Clickable, "row_%I64x", row_hash); @@ -5115,7 +5117,7 @@ rd_view_ui(Rng2F32 rect) } } - //////////////////// + ////////////// //- rjf: draw mid-row cache line boundaries in expansions // if(row_info->eval.space.kind == RD_EvalSpaceKind_CtrlEntity && row_info->view_ui_rule == &rd_nil_view_ui_rule) @@ -5138,14 +5140,16 @@ rd_view_ui(Rng2F32 rect) } } - //////////////////// + ////////////// //- rjf: build all cells // S64 cell_x = 0; F32 cell_x_px = 0; for(RD_WatchCell *cell = row_info->cells.first; cell != 0; cell = cell->next, cell_x += 1) { + //////////// //- rjf: unpack cell info + // U64 cell_id = rd_id_from_watch_cell(cell); RD_WatchPt cell_pt = {row->block->key, row->key, cell_id}; RD_WatchViewTextEditState *cell_edit_state = rd_watch_view_text_edit_state_from_pt(ewv, cell_pt); @@ -5153,9 +5157,12 @@ rd_view_ui(Rng2F32 rect) RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, string_flags, row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); F32 cell_width_px = cell->px + cell->pct * (dim_2f32(rect).x - floor_f32(ui_top_font_size()*1.5f)); F32 next_cell_x_px = cell_x_px + cell_width_px; + B32 cell_toggled = (e_value_eval_from_eval(cell_info.eval).value.u64 != 0); + B32 next_cell_toggled = cell_toggled; + //////////// //- rjf: determine cell's palette - ProfBegin("determine cell's palette"); + // UI_BoxFlags cell_flags = 0; Vec4F32 cell_background_color_override = {0}; String8 cell_tag = {0}; @@ -5164,16 +5171,13 @@ rd_view_ui(Rng2F32 rect) rd_state->hover_regs_slot == RD_RegSlot_Cfg) { RD_Cfg *cfg = cell_info.cfg; - Vec4F32 rgba = linear_from_srgba(rd_color_from_cfg(cfg)); + Vec4F32 rgba = rd_color_from_cfg(cfg); + rgba.w *= 0.05f; if(rgba.w == 0) { rgba = pop_background_rgba; rgba.w *= 0.5f; } - else - { - rgba.w *= 0.05f; - } rgba.w *= ui_anim(ui_key_from_stringf(ui_key_zero(), "###cfg_hover_t_%p", cfg), 1.f, .rate = entity_hover_t_rate); cell_background_color_override = rgba; cell_flags |= UI_BoxFlag_DrawBackground; @@ -5183,23 +5187,21 @@ rd_view_ui(Rng2F32 rect) { CTRL_Entity *entity = cell_info.entity; Vec4F32 rgba = rd_color_from_ctrl_entity(entity); + rgba.w *= 0.05f; if(rgba.w == 0) { rgba = pop_background_rgba; rgba.w *= 0.5f; } - else - { - rgba.w *= 0.05f; - } rgba.w *= ui_anim(ui_key_from_stringf(ui_key_zero(), "###entity_hover_t_%p", entity), 1.f, .rate = entity_hover_t_rate); cell_background_color_override = rgba; cell_flags |= UI_BoxFlag_DrawBackground; } } - ProfEnd(); - //- rjf: build cell + //////////// + //- rjf: build cell container + // UI_Box *cell_box = &ui_nil_box; UI_PrefWidth(ui_px(cell_width_px, 0.f)) { @@ -5207,7 +5209,9 @@ rd_view_ui(Rng2F32 rect) cell_box = ui_build_box_from_stringf(UI_BoxFlag_DrawSideLeft|cell_flags, "cell_%I64x_%I64x", row_hash, cell_id); } + //////////// //- rjf: build cell contents + // UI_Signal sig = {0}; ProfScope("build cell contents") UI_Parent(cell_box) @@ -5217,7 +5221,7 @@ rd_view_ui(Rng2F32 rect) UI_TagF("weak") UI_Tag(cell_tag) { - // rjf: cell has errors? -> build error box + //- rjf: cell has errors? -> build error box if(cell_info.flags & RD_WatchCellFlag_IsErrored) RD_Font(RD_FontSlot_Main) { UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clip|UI_BoxFlag_Clickable, "###%I64x_%I64x", cell_id, row_hash); @@ -5228,7 +5232,7 @@ rd_view_ui(Rng2F32 rect) } } - // rjf: cell has hook? -> build ui by calling hook + //- rjf: cell has hook? -> build ui by calling hook else if(cell_info.view_ui_rule != &rd_nil_view_ui_rule) { Rng2F32 cell_rect = r2f32p(cell_x_px, 0, next_cell_x_px, row_height_px*(row_node->visual_size_skipped + row->visual_size + row_node->visual_size_chopped)); @@ -5295,7 +5299,7 @@ rd_view_ui(Rng2F32 rect) sig = ui_signal_from_box(box); } - // rjf: cell is call stack frame? -> build arrow if this is the selected frame, otherwise leave empty + //- rjf: cell is call stack frame? -> build arrow if this is the selected frame, otherwise leave empty else if(cell->kind == RD_WatchCellKind_CallStackFrame) { UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clickable, "###%I64x_%I64x", cell_id, row_hash); @@ -5315,11 +5319,12 @@ rd_view_ui(Rng2F32 rect) } } - // rjf: build cell line edit + //- rjf: build general cell else { // rjf: compute visual params B32 is_button = !!(cell_info.flags & RD_WatchCellFlag_Button); + B32 is_toggle_switch = (cell_info.eval.irtree.mode == E_Mode_Offset && e_type_kind_from_key(cell_info.eval.irtree.type_key) == E_TypeKind_Bool); 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}; @@ -5355,17 +5360,11 @@ rd_view_ui(Rng2F32 rect) } } - // rjf: build - RD_LineEditParams line_edit_params = {0}; + // rjf: form cell build parameters + RD_CellParams line_edit_params = {0}; { - line_edit_params.flags = (RD_LineEditFlag_CodeContents*!is_non_code| - 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_ExpanderSpace*(row_depth==!implicit_root && cell == row_info->cells.first && !is_button)| - RD_LineEditFlag_ExpanderSpace*((row_depth!=0 && cell == row_info->cells.first))); + // rjf: set up base parameters + line_edit_params.flags = (RD_CellFlag_KeyboardClickable|RD_CellFlag_NoBackground|RD_CellFlag_CodeContents); line_edit_params.depth = (cell_x == 0 ? row_depth : 0); line_edit_params.cursor = &cell_edit_state->cursor; line_edit_params.mark = &cell_edit_state->mark; @@ -5376,7 +5375,50 @@ rd_view_ui(Rng2F32 rect) line_edit_params.pre_edit_value = cell_info.string; line_edit_params.fstrs = cell_info.fstrs; line_edit_params.fuzzy_matches = &fuzzy_matches; + + // rjf: apply expander (or substitute space) + if(row_is_expandable && cell == row_info->cells.first) + { + line_edit_params.flags |= RD_CellFlag_Expander; + } + else if(row_depth == !implicit_root && cell == row_info->cells.first) + { + line_edit_params.flags |= RD_CellFlag_ExpanderSpace; + } + else if(row_depth != 0 && cell == row_info->cells.first) + { + line_edit_params.flags |= RD_CellFlag_ExpanderSpace; + } + + // rjf: apply single-click-activation + if(is_activated_on_single_click) + { + line_edit_params.flags |= RD_CellFlag_SingleClickActivate; + } + + // rjf: apply code styles + if(is_non_code) + { + line_edit_params.flags &= ~RD_CellFlag_CodeContents; + } + + // rjf: apply button styles + if(is_button) + { + line_edit_params.flags |= RD_CellFlag_Button; + line_edit_params.flags &= ~RD_CellFlag_NoBackground; + line_edit_params.flags &= ~RD_CellFlag_ExpanderSpace; + } + + // rjf: apply toggle-switch + if(is_toggle_switch) + { + line_edit_params.flags |= RD_CellFlag_ToggleSwitch; + line_edit_params.toggled_out = &next_cell_toggled; + } } + + // rjf: build if(cell_background_color_override.w != 0) { ui_push_background_color(cell_background_color_override); @@ -5384,7 +5426,7 @@ rd_view_ui(Rng2F32 rect) UI_TextAlignment(cell->px != 0 ? UI_TextAlign_Center : UI_TextAlign_Left) RD_Font(is_non_code ? RD_FontSlot_Main : RD_FontSlot_Code) { - sig = rd_line_editf(&line_edit_params, "%S###%I64x_row_%I64x", ghost_text, cell_x, row_hash); + sig = rd_cellf(&line_edit_params, "%S###%I64x_row_%I64x", ghost_text, cell_x, row_hash); } if(cell_background_color_override.w != 0) { @@ -5406,7 +5448,9 @@ rd_view_ui(Rng2F32 rect) } } + //////////// //- rjf: handle interactions + // { // rjf: hover -> rich hover cfgs if(ui_hovering(sig) && cell_info.cfg != &rd_nil_cfg) @@ -5589,7 +5633,17 @@ rd_view_ui(Rng2F32 rect) } } + //////////// + //- rjf: commit toggle changes + // + if(next_cell_toggled != cell_toggled) + { + rd_commit_eval_value_string(cell_info.eval, next_cell_toggled ? str8_lit("1") : str8_lit("0"), 0); + } + + //////////// //- rjf: bump x pixel coordinate + // cell_x_px = next_cell_x_px; } } @@ -7155,7 +7209,7 @@ rd_window_frame(void) MD_Node *param_tree = md_child_from_string(params, key->string, 0); String8 pre_edit_value = md_string_from_children(scratch.arena, param_tree); UI_PrefWidth(ui_em(10.f, 1.f)) ui_label(key->string); - UI_Signal sig = rd_line_editf(RD_LineEditFlag_Border|RD_LineEditFlag_CodeContents, 0, 0, &ws->ctx_menu_input_cursor, &ws->ctx_menu_input_mark, ws->ctx_menu_input_buffer, ws->ctx_menu_input_buffer_size, &ws->ctx_menu_input_string_size, 0, pre_edit_value, "%S##view_param", key->string); + UI_Signal sig = rd_cellf(RD_CellFlag_Border|RD_CellFlag_CodeContents, 0, 0, &ws->ctx_menu_input_cursor, &ws->ctx_menu_input_mark, ws->ctx_menu_input_buffer, ws->ctx_menu_input_buffer_size, &ws->ctx_menu_input_string_size, 0, pre_edit_value, "%S##view_param", key->string); if(ui_committed(sig)) { String8 new_string = str8(ws->ctx_menu_input_buffer, ws->ctx_menu_input_string_size); @@ -9882,7 +9936,8 @@ rd_window_frame(void) if(box->flags & UI_BoxFlag_DrawDropShadow) { Rng2F32 drop_shadow_rect = shift_2f32(pad_2f32(box->rect, 8), v2f32(4, 4)); - dr_rect(drop_shadow_rect, drop_shadow_color, 0.8f, 0, 8.f); + R_Rect2DInst *inst = dr_rect(drop_shadow_rect, drop_shadow_color, 0.8f, 0, 8.f); + MemoryCopyArray(inst->corner_radii, box->corner_radii); } // rjf: blur background @@ -10133,9 +10188,9 @@ rd_window_frame(void) } // rjf: debug border rendering - if(0) + if(b->flags & UI_BoxFlag_Debug) { - R_Rect2DInst *inst = dr_rect(b->rect, v4f32(1, 0, 1, 0.25f), 0, 1.f, 1.f); + R_Rect2DInst *inst = dr_rect(b->rect, v4f32(1*box->pref_size[Axis2_X].strictness, 0, 1, 0.25f), 0, 1.f, 1.f); MemoryCopyArray(inst->corner_radii, b->corner_radii); } diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 0f7f2557..96574df5 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1248,6 +1248,15 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .pct = 1.f); } + // rjf: for meta-evaluation space booleans, only do expr + else if(e_type_kind_from_key(info.eval.irtree.type_key) == E_TypeKind_Bool && + (info.eval.space.kind == RD_EvalSpaceKind_MetaCfg || + info.eval.space.kind == RD_EvalSpaceKind_MetaCmd || + info.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity)) + { + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .pct = 1.f); + } + // rjf: for meta-cfg evaluation spaces, only do expr/value else if(info.eval.space.kind == RD_EvalSpaceKind_MetaCfg || info.eval.space.kind == RD_EvalSpaceKind_MetaCmd || diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 796b499c..48a7e518 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -3066,17 +3066,23 @@ rd_code_label(F32 alpha, B32 indirection_size_change, Vec4F32 base_color, String //~ rjf: UI Widgets: Line Edit internal UI_Signal -rd_line_edit(RD_LineEditParams *params, String8 string) +rd_cell(RD_CellParams *params, String8 string) { ProfBeginFunction(); + ////////////////////////////// //- rjf: unpack visual metrics + // F32 expander_size_px = ui_top_font_size()*2.f; + ////////////////////////////// //- rjf: make key + // UI_Key key = ui_key_from_string(ui_active_seed_key(), string); + ////////////////////////////// //- rjf: calculate & push focus + // B32 is_auto_focus_hot = ui_is_key_auto_focus_hot(key); B32 is_auto_focus_active = ui_is_key_auto_focus_active(key); if(is_auto_focus_hot) { ui_push_focus_hot(UI_FocusKind_On); } @@ -3086,69 +3092,137 @@ rd_line_edit(RD_LineEditParams *params, String8 string) B32 is_focus_hot_disabled = (!is_focus_hot && ui_top_focus_hot() == UI_FocusKind_On); B32 is_focus_active_disabled = (!is_focus_active && ui_top_focus_active() == UI_FocusKind_On); + ////////////////////////////// //- rjf: build top-level box + // if(is_focus_active || is_focus_active_disabled) { ui_set_next_hover_cursor(OS_Cursor_IBar); } - if(params->flags & RD_LineEditFlag_Button) + if(params->flags & RD_CellFlag_Button) { ui_set_next_hover_cursor(OS_Cursor_HandPoint); } UI_Box *box = ui_build_box_from_key(UI_BoxFlag_MouseClickable| - (!!(params->flags & RD_LineEditFlag_KeyboardClickable)*UI_BoxFlag_KeyboardClickable)| + (!!(params->flags & RD_CellFlag_KeyboardClickable)*UI_BoxFlag_KeyboardClickable)| UI_BoxFlag_ClickToFocus| UI_BoxFlag_DrawHotEffects| - (!!(params->flags & RD_LineEditFlag_SingleClickActivate)*UI_BoxFlag_DrawActiveEffects)| - (!(params->flags & RD_LineEditFlag_NoBackground)*UI_BoxFlag_DrawBackground)| - (!!(params->flags & RD_LineEditFlag_Border)*UI_BoxFlag_DrawBorder)| + (!!(params->flags & RD_CellFlag_SingleClickActivate)*UI_BoxFlag_DrawActiveEffects)| + (!(params->flags & RD_CellFlag_NoBackground)*UI_BoxFlag_DrawBackground)| + (!!(params->flags & RD_CellFlag_Border)*UI_BoxFlag_DrawBorder)| ((is_auto_focus_hot || is_auto_focus_active)*UI_BoxFlag_KeyboardClickable)| (is_focus_active || is_focus_active_disabled)*(UI_BoxFlag_Clip), key); + ////////////////////////////// //- rjf: build indent + // UI_Parent(box) for(S32 idx = 0; idx < params->depth; idx += 1) { ui_set_next_flags(UI_BoxFlag_DrawSideLeft); ui_spacer(ui_em(1.f, 1.f)); } - //- rjf: build expander - if(params->flags & RD_LineEditFlag_Expander) UI_PrefWidth(ui_px(expander_size_px, 1.f)) UI_Parent(box) - UI_Flags(UI_BoxFlag_DrawSideLeft) - UI_Focus(UI_FocusKind_Off) + ////////////////////////////// + //- rjf: build expander (or placeholder, or space) + // { - UI_Signal expander_sig = ui_expanderf(params->expanded_out[0], "expander"); - if(ui_pressed(expander_sig)) + //- rjf: build expander + if(params->flags & RD_CellFlag_Expander) UI_PrefWidth(ui_px(expander_size_px, 1.f)) UI_Parent(box) + UI_Flags(UI_BoxFlag_DrawSideLeft) + UI_Focus(UI_FocusKind_Off) { - params->expanded_out[0] ^= 1; + UI_Signal expander_sig = ui_expanderf(params->expanded_out[0], "expander"); + if(ui_pressed(expander_sig)) + { + params->expanded_out[0] ^= 1; + } + } + + //- rjf: build expander placeholder + else if(params->flags & RD_CellFlag_ExpanderPlaceholder) UI_Parent(box) UI_PrefWidth(ui_px(expander_size_px, 1.f)) UI_Focus(UI_FocusKind_Off) + { + UI_TagF("weak") + UI_Flags(UI_BoxFlag_DrawSideLeft) + RD_Font(RD_FontSlot_Icons) + UI_TextAlignment(UI_TextAlign_Center) + ui_label(rd_icon_kind_text_table[RD_IconKind_Dot]); + } + + //- rjf: build expander space + else if(params->flags & RD_CellFlag_ExpanderSpace) UI_Parent(box) UI_Focus(UI_FocusKind_Off) + { + UI_Flags(UI_BoxFlag_DrawSideLeft) ui_spacer(ui_px(expander_size_px, 1.f)); } } - //- rjf: build expander placeholder - else if(params->flags & RD_LineEditFlag_ExpanderPlaceholder) UI_Parent(box) UI_PrefWidth(ui_px(expander_size_px, 1.f)) UI_Focus(UI_FocusKind_Off) - { - UI_TagF("weak") - UI_Flags(UI_BoxFlag_DrawSideLeft) - RD_Font(RD_FontSlot_Icons) - UI_TextAlignment(UI_TextAlign_Center) - ui_label(rd_icon_kind_text_table[RD_IconKind_Dot]); - } - - //- rjf: build expander space - else if(params->flags & RD_LineEditFlag_ExpanderSpace) UI_Parent(box) UI_Focus(UI_FocusKind_Off) - { - UI_Flags(UI_BoxFlag_DrawSideLeft) ui_spacer(ui_px(expander_size_px, 1.f)); - } - + ////////////////////////////// //- rjf: build scrollable container box + // UI_Box *scrollable_box = &ui_nil_box; - UI_Parent(box) UI_PrefWidth(ui_children_sum(0)) + UI_Parent(box) UI_WidthFill { scrollable_box = ui_build_box_from_stringf(is_focus_active*(UI_BoxFlag_AllowOverflowX), "scroll_box_%p", params->edit_buffer); } + ////////////////////////////// + //- rjf: build toggle-switch + // + if(params->flags & RD_CellFlag_ToggleSwitch && !is_focus_active) + UI_Parent(box) + { + B32 is_toggled = !!params->toggled_out[0]; + F32 toggle_t = ui_anim(ui_key_from_stringf(key, "toggled"), (F32)is_toggled, .initial = (F32)is_toggled); + Vec4F32 untoggled_bg_color = {0}; + Vec4F32 toggled_bg_color = {0}; + UI_TagF("pop") + { + toggled_bg_color = ui_color_from_name(str8_lit("background")); + } + Vec4F32 bg_color = mix_4f32(untoggled_bg_color, toggled_bg_color, toggle_t); + F32 padding_px = floor_f32(ui_top_font_size()*0.4f); + F32 height_px = ui_top_px_height() - padding_px*2.f; + UI_PrefWidth(ui_children_sum(1.f)) + UI_HeightFill + UI_Column UI_Padding(ui_px(padding_px, 1.f)) + UI_Row UI_Padding(ui_px(padding_px, 1.f)) + UI_PrefWidth(ui_em(4.f, 1.f)) + UI_PrefHeight(ui_px(height_px, 1.f)) + UI_CornerRadius(floor_f32(height_px/2.f - 1.f)) + { + ui_set_next_background_color(bg_color); + ui_set_next_hover_cursor(OS_Cursor_HandPoint); + UI_Box *switch_box = ui_build_box_from_stringf(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_Clickable, "toggle_switch"); + UI_Parent(switch_box) + { + ui_spacer(ui_pct(toggle_t, 0)); + UI_BackgroundColor(ui_color_from_name(str8_lit("text"))) + UI_PrefWidth(ui_px(height_px, 1.f)) + { + F32 extratoggler_padding_px = floor_f32(ui_top_font_size()*0.35f); + F32 toggler_size_px = height_px - extratoggler_padding_px*2.f; + UI_Column UI_Padding(ui_px(extratoggler_padding_px, 1.f)) + UI_Row UI_Padding(ui_px(extratoggler_padding_px, 1.f)) + UI_PrefWidth(ui_px(toggler_size_px, 1.f)) + UI_PrefHeight(ui_px(toggler_size_px, 1.f)) + UI_CornerRadius(floor_f32(toggler_size_px/2.f - 1.f)) + { + UI_Box *toggler = ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawDropShadow, ui_key_zero()); + } + } + ui_spacer(ui_pct(1.f-toggle_t, 0)); + } + UI_Signal switch_sig = ui_signal_from_box(switch_box); + if(ui_pressed(switch_sig)) + { + params->toggled_out[0] ^= 1; + } + } + } + + ////////////////////////////// //- rjf: do non-textual edits (delete, copy, cut) + // B32 commit = 0; if(!is_focus_active && is_focus_hot) { @@ -3166,14 +3240,18 @@ rd_line_edit(RD_LineEditParams *params, String8 string) } } + ////////////////////////////// //- rjf: get signal + // UI_Signal sig = ui_signal_from_box(box); if(commit) { sig.f |= UI_SignalFlag_Commit; } + ////////////////////////////// //- rjf: do start/end editing interaction + // B32 focus_started = 0; if(!is_focus_active) { @@ -3201,7 +3279,7 @@ rd_line_edit(RD_LineEditParams *params, String8 string) MemoryCopy(params->edit_buffer, edit_string.str, edit_string.size); params->edit_string_size_out[0] = edit_string.size; ui_set_auto_focus_active_key(key); - if(!(params->flags & RD_LineEditFlag_Button)) + if(!(params->flags & RD_CellFlag_Button)) { ui_kill_action(); } @@ -3216,7 +3294,9 @@ rd_line_edit(RD_LineEditParams *params, String8 string) sig.f |= UI_SignalFlag_Commit; } + ////////////////////////////// //- rjf: determine autocompletion string + // String8 autocomplete_hint_string = {0}; { for(UI_Event *evt = 0; ui_next_event(&evt);) @@ -3228,9 +3308,11 @@ rd_line_edit(RD_LineEditParams *params, String8 string) } } + ////////////////////////////// //- rjf: take navigation actions for editing + // B32 changes_made = 0; - if(!(params->flags & RD_LineEditFlag_DisableEdit) && (is_focus_active || focus_started)) + if(!(params->flags & RD_CellFlag_DisableEdit) && (is_focus_active || focus_started)) { Temp scratch = scratch_begin(0, 0); rd_state->text_edit_mode = 1; @@ -3290,12 +3372,14 @@ rd_line_edit(RD_LineEditParams *params, String8 string) scratch_end(scratch); } + ////////////////////////////// //- rjf: build scrolled contents + // TxtPt mouse_pt = {0}; F32 cursor_off = 0; UI_Parent(scrollable_box) { - if(ui_top_text_alignment() == UI_TextAlign_Left && (params->flags & (RD_LineEditFlag_Expander|RD_LineEditFlag_ExpanderSpace|RD_LineEditFlag_ExpanderPlaceholder)) == 0) + if(ui_top_text_alignment() == UI_TextAlign_Left && (params->flags & (RD_CellFlag_Expander|RD_CellFlag_ExpanderSpace|RD_CellFlag_ExpanderPlaceholder)) == 0) { ui_spacer(ui_em(0.5f, 1.f)); } @@ -3308,10 +3392,10 @@ rd_line_edit(RD_LineEditParams *params, String8 string) ui_box_equip_fuzzy_match_ranges(label, params->fuzzy_matches); } } - else if(!is_focus_active && !is_focus_active_disabled && params->flags & RD_LineEditFlag_CodeContents) + else if(!is_focus_active && !is_focus_active_disabled && params->flags & RD_CellFlag_CodeContents) { String8 display_string = ui_display_part_from_key_string(string); - if(!(params->flags & RD_LineEditFlag_PreferDisplayString) && params->pre_edit_value.size != 0) + if(!(params->flags & RD_CellFlag_PreferDisplayString) && params->pre_edit_value.size != 0) { display_string = params->pre_edit_value; UI_Box *box = rd_code_label(1.f, 1, ui_color_from_name(str8_lit("text")), display_string); @@ -3320,7 +3404,7 @@ rd_line_edit(RD_LineEditParams *params, String8 string) ui_box_equip_fuzzy_match_ranges(box, params->fuzzy_matches); } } - else if(params->flags & RD_LineEditFlag_DisplayStringIsCode) + else if(params->flags & RD_CellFlag_DisplayStringIsCode) { UI_Box *box = rd_code_label(1.f, 1, ui_color_from_name(str8_lit("text")), display_string); if(params->fuzzy_matches != 0) @@ -3337,10 +3421,10 @@ rd_line_edit(RD_LineEditParams *params, String8 string) } } } - else if(!is_focus_active && !is_focus_active_disabled && !(params->flags & RD_LineEditFlag_CodeContents)) + else if(!is_focus_active && !is_focus_active_disabled && !(params->flags & RD_CellFlag_CodeContents)) { String8 display_string = ui_display_part_from_key_string(string); - if(!(params->flags & RD_LineEditFlag_PreferDisplayString) && params->pre_edit_value.size != 0) + if(!(params->flags & RD_CellFlag_PreferDisplayString) && params->pre_edit_value.size != 0) { display_string = params->pre_edit_value; } @@ -3354,12 +3438,12 @@ rd_line_edit(RD_LineEditParams *params, String8 string) ui_box_equip_fuzzy_match_ranges(box, params->fuzzy_matches); } } - else if((is_focus_active || is_focus_active_disabled) && params->flags & RD_LineEditFlag_CodeContents) + else if((is_focus_active || is_focus_active_disabled) && params->flags & RD_CellFlag_CodeContents) { String8 edit_string = str8(params->edit_buffer, params->edit_string_size_out[0]); Temp scratch = scratch_begin(0, 0); F32 total_text_width = fnt_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, ui_top_tab_size(), edit_string).x; - F32 total_editstr_width = total_text_width - !!(params->flags & (RD_LineEditFlag_Expander|RD_LineEditFlag_ExpanderSpace|RD_LineEditFlag_ExpanderPlaceholder)) * expander_size_px; + F32 total_editstr_width = total_text_width - !!(params->flags & (RD_CellFlag_Expander|RD_CellFlag_ExpanderSpace|RD_CellFlag_ExpanderPlaceholder)) * expander_size_px; ui_set_next_pref_width(ui_px(total_editstr_width+ui_top_font_size()*2, 0.f)); UI_Box *editstr_box = ui_build_box_from_stringf(UI_BoxFlag_DrawText|UI_BoxFlag_DisableTextTrunc, "###editstr"); DR_FStrList code_fstrs = rd_fstrs_from_code_string(scratch.arena, 1.f, 0, ui_color_from_name(str8_lit("text")), edit_string); @@ -3437,11 +3521,11 @@ rd_line_edit(RD_LineEditParams *params, String8 string) cursor_off = fnt_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, ui_top_tab_size(), str8_prefix(edit_string, params->cursor->column-1)).x; scratch_end(scratch); } - else if((is_focus_active || is_focus_active_disabled) && !(params->flags & RD_LineEditFlag_CodeContents)) + else if((is_focus_active || is_focus_active_disabled) && !(params->flags & RD_CellFlag_CodeContents)) { String8 edit_string = str8(params->edit_buffer, params->edit_string_size_out[0]); F32 total_text_width = fnt_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, ui_top_tab_size(), edit_string).x; - F32 total_editstr_width = total_text_width - !!(params->flags & (RD_LineEditFlag_Expander|RD_LineEditFlag_ExpanderSpace|RD_LineEditFlag_ExpanderPlaceholder)) * expander_size_px; + F32 total_editstr_width = total_text_width - !!(params->flags & (RD_CellFlag_Expander|RD_CellFlag_ExpanderSpace|RD_CellFlag_ExpanderPlaceholder)) * expander_size_px; ui_set_next_pref_width(ui_px(total_editstr_width+ui_top_font_size()*2, 0.f)); UI_Box *editstr_box = ui_build_box_from_stringf(UI_BoxFlag_DrawText|UI_BoxFlag_DisableTextTrunc, "###editstr"); UI_LineEditDrawData *draw_data = push_array(ui_build_arena(), UI_LineEditDrawData, 1); @@ -3455,7 +3539,9 @@ rd_line_edit(RD_LineEditParams *params, String8 string) } } + ////////////////////////////// //- rjf: click+drag + // if(is_focus_active && ui_dragging(sig)) { if(ui_pressed(sig)) @@ -3469,7 +3555,9 @@ rd_line_edit(RD_LineEditParams *params, String8 string) params->cursor[0] = params->mark[0] = mouse_pt; } + ////////////////////////////// //- rjf: focus cursor + // { F32 visible_dim_px = dim_2f32(box->rect).x - expander_size_px - ui_top_font_size()*params->depth; if(visible_dim_px > 0) @@ -3491,7 +3579,9 @@ rd_line_edit(RD_LineEditParams *params, String8 string) } } + ////////////////////////////// //- rjf: pop focus + // if(is_auto_focus_hot) { ui_pop_focus_hot(); } if(is_auto_focus_active) { ui_pop_focus_active(); } @@ -3500,14 +3590,14 @@ rd_line_edit(RD_LineEditParams *params, String8 string) } internal UI_Signal -rd_line_editf(RD_LineEditParams *params, char *fmt, ...) +rd_cellf(RD_CellParams *params, 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 sig = rd_line_edit(params, string); + UI_Signal sig = rd_cell(params, string); scratch_end(scratch); return sig; } diff --git a/src/raddbg/raddbg_widgets.h b/src/raddbg/raddbg_widgets.h index dfd3691c..66d14bf3 100644 --- a/src/raddbg/raddbg_widgets.h +++ b/src/raddbg/raddbg_widgets.h @@ -5,39 +5,64 @@ #define RADDBG_WIDGETS_H //////////////////////////////// -//~ rjf: Line Edit Types +//~ rjf: Cell Types -typedef U32 RD_LineEditFlags; +typedef U32 RD_CellFlags; enum { - RD_LineEditFlag_Expander = (1<<0), - RD_LineEditFlag_ExpanderSpace = (1<<1), - RD_LineEditFlag_ExpanderPlaceholder = (1<<2), - RD_LineEditFlag_DisableEdit = (1<<3), - RD_LineEditFlag_CodeContents = (1<<4), - RD_LineEditFlag_KeyboardClickable = (1<<5), - RD_LineEditFlag_Border = (1<<6), - RD_LineEditFlag_NoBackground = (1<<7), - RD_LineEditFlag_Button = (1<<8), - RD_LineEditFlag_SingleClickActivate = (1<<9), - RD_LineEditFlag_PreferDisplayString = (1<<10), - RD_LineEditFlag_DisplayStringIsCode = (1<<11), + //- rjf: expander + RD_CellFlag_Expander = (1<<0), + RD_CellFlag_ExpanderSpace = (1<<1), + RD_CellFlag_ExpanderPlaceholder = (1<<2), + + //- rjf: toggle switch extension + RD_CellFlag_ToggleSwitch = (1<<3), + + //- rjf: slider extension + RD_CellFlag_Slider = (1<<4), + + //- rjf: behavior + RD_CellFlag_DisableEdit = (1<<5), + RD_CellFlag_KeyboardClickable = (1<<6), + RD_CellFlag_SingleClickActivate = (1<<7), + + //- rjf: contents description + RD_CellFlag_CodeContents = (1<<8), + + //- rjf: appearance + RD_CellFlag_Border = (1<<9), + RD_CellFlag_NoBackground = (1<<10), + RD_CellFlag_Button = (1<<11), + RD_CellFlag_PreferDisplayString = (1<<12), + RD_CellFlag_DisplayStringIsCode = (1<<13), }; -typedef struct RD_LineEditParams RD_LineEditParams; -struct RD_LineEditParams +typedef struct RD_CellParams RD_CellParams; +struct RD_CellParams { - RD_LineEditFlags flags; + //- rjf: catachall parameters + RD_CellFlags flags; S32 depth; FuzzyMatchRangeList *fuzzy_matches; + String8 pre_edit_value; + DR_FStrList fstrs; + + //- rjf: expander r/w info + B32 *expanded_out; + + //- rjf: toggle-switch r/w info + B32 *toggled_out; + + //- rjf: slider info r/w info + Rng1U64 slider_value_range; + U64 *slider_value_out; + + //- rjf: text editing r/w info TxtPt *cursor; TxtPt *mark; U8 *edit_buffer; U64 edit_buffer_size; U64 *edit_string_size_out; - B32 *expanded_out; - String8 pre_edit_value; - DR_FStrList fstrs; }; //////////////////////////////// @@ -140,7 +165,7 @@ internal UI_Box *rd_code_label(F32 alpha, B32 indirection_size_change, Vec4F32 b //////////////////////////////// //~ rjf: UI Widgets: Line Edit -internal UI_Signal rd_line_edit(RD_LineEditParams *params, String8 string); -internal UI_Signal rd_line_editf(RD_LineEditParams *params, char *fmt, ...); +internal UI_Signal rd_cell(RD_CellParams *params, String8 string); +internal UI_Signal rd_cellf(RD_CellParams *params, char *fmt, ...); #endif // RADDBG_WIDGETS_H diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index 5968c4fc..579c8051 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -352,6 +352,9 @@ typedef U64 UI_BoxFlags; # define UI_BoxFlag_RoundChildrenByParent (UI_BoxFlags)(1ull<<51) # define UI_BoxFlag_SquishAnchored (UI_BoxFlags)(1ull<<52) +//- rjf: debug +# define UI_BoxFlag_Debug (UI_BoxFlags)(1ull<<53) + //- rjf: bundles # define UI_BoxFlag_Clickable (UI_BoxFlag_MouseClickable|UI_BoxFlag_KeyboardClickable) # define UI_BoxFlag_DefaultFocusNav (UI_BoxFlag_DefaultFocusNavX|UI_BoxFlag_DefaultFocusNavY|UI_BoxFlag_DefaultFocusEdit)