slider extension to built-in cell controls (similar to toggle-switch)

This commit is contained in:
Ryan Fleury
2025-04-11 16:21:47 -07:00
parent 72aa479724
commit 64187e75eb
5 changed files with 192 additions and 43 deletions
+10 -10
View File
@@ -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;
@@ -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;
+86 -2
View File
@@ -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
//
+56
View File
@@ -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)
//
+1 -2
View File
@@ -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;