diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index 12aafc78..869f02c7 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -297,16 +297,16 @@ E_MemberKind; typedef U32 E_TypeFlags; enum { - E_TypeFlag_Const = (1<<0), - E_TypeFlag_Volatile = (1<<1), - E_TypeFlag_IsPlainText = (1<<2), - E_TypeFlag_IsCodeText = (1<<3), - E_TypeFlag_IsPathText = (1<<4), - E_TypeFlag_IsNotText = (1<<5), - E_TypeFlag_EditableChildren = (1<<6), - E_TypeFlag_InheritedByMembers = (1<<7), - E_TypeFlag_InheritedByElements = (1<<8), - E_TypeFlag_ArrayLikeExpansion = (1<<9), + E_TypeFlag_Const = (1<<0), + E_TypeFlag_Volatile = (1<<1), + E_TypeFlag_IsPlainText = (1<<2), + E_TypeFlag_IsCodeText = (1<<3), + E_TypeFlag_IsPathText = (1<<4), + E_TypeFlag_IsNotText = (1<<5), + E_TypeFlag_EditableChildren = (1<<6), + E_TypeFlag_InheritedByMembers = (1<<7), + E_TypeFlag_InheritedByElements = (1<<8), + E_TypeFlag_ArrayLikeExpansion = (1<<9), }; typedef struct E_Member E_Member; diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 5277f70a..35e6a7f3 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -1597,42 +1597,52 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) new_task.eval = eval; new_task.redirect_to_sets_and_structs = 1; } - else switch(task_idx) + else { - default:{}break; - - // rjf: step 0 -> generate lens description, then descend to same evaluation w/ direct type - case 0: + need_new_task = 1; + need_pop = 1; + new_task.params = lens_params; + new_task.eval = eval; + new_task.eval.irtree.type_key = e_type_direct_from_key(eval.irtree.type_key); +#if 0 // NOTE(rjf): will explicitly visualize lenses in value strings. does not seem useful for now? + switch(task_idx) { - Temp scratch = scratch_begin(&arena, 1); - String8List strings = {0}; + default:{}break; + + // rjf: step 0 -> generate lens description, then descend to same evaluation w/ direct type + case 0: { - str8_list_pushf(scratch.arena, &strings, "%S(", type->name); - for EachIndex(idx, type->count) + Temp scratch = scratch_begin(&arena, 1); + String8List strings = {0}; { - String8 string = e_string_from_expr(scratch.arena, type->args[idx]); - str8_list_push(scratch.arena, &strings, string); - if(idx+1 < type->count) + str8_list_pushf(scratch.arena, &strings, "%S(", type->name); + for EachIndex(idx, type->count) { - str8_list_pushf(scratch.arena, &strings, ", "); + String8 string = e_string_from_expr(scratch.arena, type->args[idx]); + str8_list_push(scratch.arena, &strings, string); + if(idx+1 < type->count) + { + str8_list_pushf(scratch.arena, &strings, ", "); + } } + str8_list_pushf(scratch.arena, &strings, ") <- ("); } - str8_list_pushf(scratch.arena, &strings, ") <- ("); - } - *out_string = str8_list_join(arena, &strings, 0); - need_new_task = 1; - need_pop = 0; - new_task.params = *params; - new_task.eval = eval; - new_task.eval.irtree.type_key = e_type_direct_from_key(eval.irtree.type_key); - scratch_end(scratch); - }break; - - // rjf: step 1 -> close - case 1: - { - *out_string = str8_lit(")"); - }break; + *out_string = str8_list_join(arena, &strings, 0); + need_new_task = 1; + need_pop = 0; + new_task.params = *params; + new_task.eval = eval; + new_task.eval.irtree.type_key = e_type_direct_from_key(eval.irtree.type_key); + scratch_end(scratch); + }break; + + // rjf: step 1 -> close + case 1: + { + *out_string = str8_lit(")"); + }break; + } +#endif } }break; diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index bf9c0745..b1a3d113 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -3927,11 +3927,54 @@ rd_view_ui(Rng2F32 rect) RD_WatchViewTextEditState *cell_edit_state = rd_watch_view_text_edit_state_from_pt(ewv, cell_pt); B32 cell_selected = (row_selected && selection_tbl.min.x <= cell_x && cell_x <= selection_tbl.max.x); 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); + E_Type *cell_type = e_type_from_key__cached(cell_info.eval.irtree.type_key); + E_Eval cell_value_eval = e_value_eval_from_eval(cell_info.eval); 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 cell_toggled = (cell_value_eval.value.u64 != 0); B32 next_cell_toggled = cell_toggled; + //////////// + //- rjf: compute slider parameters + // + E_Value cell_slider_min = zero_struct; + E_Value cell_slider_max = zero_struct; + E_TypeKind slider_value_type_kind = E_TypeKind_Null; + F32 cell_slider_value = 0.f; + if(str8_match(cell_type->name, str8_lit("range1"), 0) && cell_type->args != 0 && cell_type->count >= 2) + { + E_Expr *min_expr = cell_type->args[0]; + E_Expr *max_expr = cell_type->args[1]; + E_IRTreeAndType *prev_overridden_irtree = e_ir_state->overridden_irtree; + e_ir_state->overridden_irtree = &cell_info.eval.irtree; + { + E_TypeKey slider_value_type = e_type_unwrap(cell_type->direct_type_key); + slider_value_type_kind = e_type_kind_from_key(slider_value_type); + E_Expr *min_casted = e_expr_ref_cast(scratch.arena, slider_value_type, min_expr); + E_Expr *max_casted = e_expr_ref_cast(scratch.arena, slider_value_type, max_expr); + cell_slider_min = e_value_from_expr(min_casted); + cell_slider_max = e_value_from_expr(max_casted); + } + e_ir_state->overridden_irtree = prev_overridden_irtree; + } + switch(slider_value_type_kind) + { + default: + if(e_type_kind_is_integer(slider_value_type_kind)) + { + cell_slider_value = ((F32)(cell_value_eval.value.s64 - cell_slider_min.s64)) / (cell_slider_max.s64 - cell_slider_min.s64); + }break; + case E_TypeKind_F32: + { + cell_slider_value = (cell_value_eval.value.f32 - cell_slider_min.f32) / (cell_slider_max.f32 - cell_slider_min.f32); + }break; + case E_TypeKind_F64: + { + cell_slider_value = (F32)((cell_value_eval.value.f64 - cell_slider_min.f64) / (cell_slider_max.f64 - cell_slider_min.f64)); + }break; + } + F32 next_cell_slider_value = cell_slider_value; + //////////// //- rjf: determine cell's palette // @@ -4097,9 +4140,12 @@ rd_view_ui(Rng2F32 rect) else { // rjf: compute visual params + B32 fancy_editors_in_expr = (row_info->cells.count == 1); + B32 cell_has_fancy_editors = (cell->kind != RD_WatchCellKind_Expr || fancy_editors_in_expr); B32 is_button = !!(cell_info.flags & RD_WatchCellFlag_Button); B32 has_background = !!(cell_info.flags & RD_WatchCellFlag_Background); - B32 is_toggle_switch = (cell_info.eval.irtree.mode != E_Mode_Null && e_type_kind_from_key(cell_info.eval.irtree.type_key) == E_TypeKind_Bool); + B32 is_toggle_switch = (cell_has_fancy_editors && cell_info.eval.irtree.mode != E_Mode_Null && cell_type->kind == E_TypeKind_Bool); + B32 is_slider = (cell_has_fancy_editors && cell_info.eval.irtree.mode != E_Mode_Null && cell_type->kind == E_TypeKind_Lens && str8_match(cell_type->name, str8_lit("range1"), 0)); 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}; @@ -4200,6 +4246,13 @@ rd_view_ui(Rng2F32 rect) cell_params.flags |= RD_CellFlag_ToggleSwitch; cell_params.toggled_out = &next_cell_toggled; } + + // rjf: apply slider + if(is_slider) + { + cell_params.flags |= RD_CellFlag_Slider; + cell_params.slider_value_out = &next_cell_slider_value; + } } // rjf: build @@ -4435,6 +4488,37 @@ rd_view_ui(Rng2F32 rect) rd_commit_eval_value_string(cell_info.eval, next_cell_toggled ? str8_lit("1") : str8_lit("0")); } + //////////// + //- rjf: commit slider changes + // + if(next_cell_slider_value != cell_slider_value) + { + String8 new_value_string = {0}; + switch(slider_value_type_kind) + { + default: + if(e_type_kind_is_integer(slider_value_type_kind)) + { + S64 new_value = (S64)((next_cell_slider_value * (cell_slider_max.s64 - cell_slider_min.s64)) + cell_slider_min.s64); + new_value = Clamp(cell_slider_min.s64, new_value, cell_slider_max.s64); + new_value_string = push_str8f(scratch.arena, "%I64d", new_value); + }break; + case E_TypeKind_F32: + { + F32 new_value = (next_cell_slider_value * (cell_slider_max.f32 - cell_slider_min.f32)) + cell_slider_min.f32; + new_value = Clamp(cell_slider_min.f32, new_value, cell_slider_max.f32); + new_value_string = push_str8f(scratch.arena, "%f", new_value); + }break; + case E_TypeKind_F64: + { + F64 new_value = (F64)((next_cell_slider_value * (cell_slider_max.f64 - cell_slider_min.f64)) + cell_slider_min.f64); + new_value = Clamp(cell_slider_min.f64, new_value, cell_slider_max.f64); + new_value_string = push_str8f(scratch.arena, "%f", new_value); + }break; + } + rd_commit_eval_value_string(cell_info.eval, new_value_string); + } + //////////// //- rjf: bump x pixel coordinate // diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index faa44ddb..ba89a4d7 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -3278,6 +3278,62 @@ rd_cell(RD_CellParams *params, String8 string) } } + ////////////////////////////// + //- rjf: build slider + // + if(params->flags & RD_CellFlag_Slider && !is_focus_active) + UI_Parent(box) + { + F32 padding_px = floor_f32(ui_top_font_size()*0.65f); + 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_pct(0.5f, 0.f)) + UI_PrefHeight(ui_px(height_px, 1.f)) + UI_CornerRadius(floor_f32(height_px/2.f - 1.f)) + { + ui_set_next_hover_cursor(OS_Cursor_LeftRight); + UI_Box *slider_box = ui_build_box_from_stringf(UI_BoxFlag_DrawHotEffects|UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_Clickable, "slider"); + UI_Parent(slider_box) UI_TagF("good_pop") + { + UI_Signal sig = ui_signal_from_box(slider_box); + if(ui_dragging(sig)) + { + if(ui_pressed(sig)) + { + ui_store_drag_struct(params->slider_value_out); + } + F32 initial_pct = *ui_get_drag_struct(F32); + F32 current_pct = initial_pct + (ui_drag_delta().x / dim_2f32(slider_box->rect).x); + params->slider_value_out[0] = current_pct; + } + UI_Box *fill_box = &ui_nil_box; + UI_PrefWidth(ui_pct(Clamp(0, params->slider_value_out[0], 1), 0.f)) + fill_box = ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBorder, ui_key_zero()); + UI_Parent(fill_box) + { + UI_BackgroundColor(ui_color_from_name(str8_lit("text"))) + UI_PrefWidth(ui_px(height_px, 1.f)) + { + ui_spacer(ui_pct(1.f, 0.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 *nub = ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawDropShadow, ui_key_zero()); + } + } + } + } + } + } + ////////////////////////////// //- rjf: do non-textual edits (delete, copy, cut) // diff --git a/src/raddbg/raddbg_widgets.h b/src/raddbg/raddbg_widgets.h index 66d14bf3..f4004990 100644 --- a/src/raddbg/raddbg_widgets.h +++ b/src/raddbg/raddbg_widgets.h @@ -54,8 +54,7 @@ struct RD_CellParams B32 *toggled_out; //- rjf: slider info r/w info - Rng1U64 slider_value_range; - U64 *slider_value_out; + F32 *slider_value_out; //- rjf: text editing r/w info TxtPt *cursor;