Commit: 7138a16a9bb12a7e30953d2faf55619be0060038
Parent: f5b33a0debee11db5bbb9c71bcce29c417d5d3a6
Author: Randy Palamar
Date: Fri, 7 Aug 2026 06:31:03 -0700
ui: make live control panel launching more user friendly
* if the user opened a live control panel don't launch another
* if the user moves the auto panel don't auto close it
Diffstat:
4 files changed, 49 insertions(+), 22 deletions(-)
diff --git a/beamformer_core.c b/beamformer_core.c
@@ -1905,20 +1905,26 @@ beamformer_frame_step(void *memory, BeamformerInput *input)
u32 live_imaging_active = atomic_load_u32(&sm->live_imaging_parameters.active);
if (live_imaging_active != ctx->live_imaging_active) {
if (ctx->live_imaging_active) {
- BeamformerUIPanel *parent = ctx->auto_live_control_panel->parent;
- beamformer_command(beamformer_command_infos[BeamformerCommandKind_CloseTab].string, .tree_node = (u64)ctx->auto_live_control_panel);
- if (parent->child_count == 1)
- beamformer_command(beamformer_command_infos[BeamformerCommandKind_CloseTab].string, .tree_node = (u64)parent);
- ctx->auto_live_control_panel = 0;
+ if (ctx->auto_live_control_panel) {
+ BeamformerUIPanel *parent = ctx->auto_live_control_panel->parent;
+ beamformer_command(beamformer_command_infos[BeamformerCommandKind_CloseTab].string, .tree_node = (u64)ctx->auto_live_control_panel);
+ if (parent->child_count == 1)
+ beamformer_command(beamformer_command_infos[BeamformerCommandKind_CloseTab].string, .tree_node = (u64)parent);
+ }
} else {
+ if (beamformer_registers()->live_controls) {
+ beamformer_command(beamformer_command_infos[BeamformerCommandKind_FocusTab].string,
+ .tree_node = beamformer_registers()->live_controls);
+ } else {
+ ctx->auto_live_control_panel = beamformer_ui_push_panel(0, BeamformerPanelKind_LiveImagingControls);
+ beamformer_command(beamformer_command_infos[BeamformerCommandKind_SplitTree].string,
+ .tree_node = (u64)ctx->auto_live_control_panel,
+ .split_axis = Axis2_X,
+ .split_left_tree = (u64)ui_context->tree,
+ .split_right_tree = 0,
+ .drop_target_tree = (u64)ui_context->tree);
+ }
ctx->live_imaging_active_frame = ctx->frame_index;
- ctx->auto_live_control_panel = beamformer_ui_push_panel(0, BeamformerPanelKind_LiveImagingControls);
- beamformer_command(beamformer_command_infos[BeamformerCommandKind_SplitTree].string,
- .tree_node = (u64)ctx->auto_live_control_panel,
- .split_axis = Axis2_X,
- .split_left_tree = (u64)ui_context->tree,
- .split_right_tree = 0,
- .drop_target_tree = (u64)ui_context->tree);
}
ctx->live_imaging_active = live_imaging_active;
}
@@ -1959,6 +1965,12 @@ beamformer_frame_step(void *memory, BeamformerInput *input)
BeamformerUIPanel *group = (BeamformerUIPanel *)beamformer_registers()->drop_target_tree;
u64 new_child_index = beamformer_registers()->drop_child_index;
beamformer_panel_group_insert_at(group, move, new_child_index);
+
+ if (move->kind == BeamformerPanelKind_LiveImagingControls) {
+ beamformer_context->base_registers.v.live_controls = (u64)move;
+ if (move == ctx->auto_live_control_panel)
+ ctx->auto_live_control_panel = 0;
+ }
}break;
case BeamformerCommandKind_OpenTab:{
diff --git a/beamformer_core.meta b/beamformer_core.meta
@@ -44,6 +44,7 @@
[U64 frame Frame ]
[U64 frame_view FrameView ]
+ [U64 live_controls LiveControls ]
// NOTE(rnp): Panel Movement and Splitting
[U64 split_axis SplitAxis ]
diff --git a/generated/beamformer_core.c b/generated/beamformer_core.c
@@ -22,11 +22,12 @@ typedef enum {
BeamformerRegisterSlot_Window = 2,
BeamformerRegisterSlot_Frame = 3,
BeamformerRegisterSlot_FrameView = 4,
- BeamformerRegisterSlot_SplitAxis = 5,
- BeamformerRegisterSlot_SplitLeftTree = 6,
- BeamformerRegisterSlot_SplitRightTree = 7,
- BeamformerRegisterSlot_DropTargetTree = 8,
- BeamformerRegisterSlot_DropChildIndex = 9,
+ BeamformerRegisterSlot_LiveControls = 5,
+ BeamformerRegisterSlot_SplitAxis = 6,
+ BeamformerRegisterSlot_SplitLeftTree = 7,
+ BeamformerRegisterSlot_SplitRightTree = 8,
+ BeamformerRegisterSlot_DropTargetTree = 9,
+ BeamformerRegisterSlot_DropChildIndex = 10,
BeamformerRegisterSlot_Count,
} BeamformerRegisterSlot;
@@ -59,6 +60,7 @@ typedef struct {
u64 window;
u64 frame;
u64 frame_view;
+ u64 live_controls;
u64 split_axis;
u64 split_left_tree;
u64 split_right_tree;
@@ -91,6 +93,7 @@ read_only global BeamformerPanelInfo beamformer_panel_infos[] = {
.window = beamformer_registers()->window, \
.frame = beamformer_registers()->frame, \
.frame_view = beamformer_registers()->frame_view, \
+ .live_controls = beamformer_registers()->live_controls, \
.split_axis = beamformer_registers()->split_axis, \
.split_left_tree = beamformer_registers()->split_left_tree, \
.split_right_tree = beamformer_registers()->split_right_tree, \
diff --git a/ui.c b/ui.c
@@ -2,9 +2,6 @@
/* TODO(rnp):
* [ ]: track active panel
* - when beamformer gets command to open tab it goes to this location by default
- * [ ]: track last active live control panel
- * - when live imaging starts make this panel the focus
- * - if this exists do not auto open a panel
* [ ]: word scan for text input
* [ ]: when dragging only tab from group close old group on release
* - only keep layout when closing tabs
@@ -3625,6 +3622,7 @@ ui_build_live_imaging_controls(BeamformerUIPanel *panel)
{
ui_top_parent()->child_layout_axis = Axis2_Y;
ui_top_parent()->semantic_width = ui_px(4.f * UI_NODE_PAD + 200.f, 1.f);
+ ui_top_parent()->parent->alignment[Axis2_X] = UIAlign_Center;
if (popcount_u64(lip->acquisition_kind_enabled_flags) > 1)
UIPrefWidth(ui_children_sum(1.f))
@@ -4792,8 +4790,10 @@ ui_layout_nodes(UINode *root)
for (UINode *child = node->first_child; !ui_node_is_nil(child); child = child->next_sibling) {
for EachElement(node->alignment, axis) {
- f32 size_delta = node->computed_size[axis] - child->computed_size[axis];
- child->computed_position[axis] += ui_alignment_correction(node->alignment[axis], size_delta);
+ UIAlign align = node->alignment[axis];
+ f32 size_delta = node->computed_size[axis] - child->computed_size[axis];
+ if (size_delta < 0) align = UIAlign_Left;
+ child->computed_position[axis] += ui_alignment_correction(align, size_delta);
}
}
@@ -4973,6 +4973,14 @@ ui_kill_panel(BeamformerUIPanel *node)
SLLStackPush(ui->view_freelist, bv, next);
}
+ if (node->kind == BeamformerPanelKind_LiveImagingControls && (u64)node == beamformer_context->base_registers.v.live_controls) {
+ beamformer_context->base_registers.v.live_controls = 0;
+ // TODO(rnp): find first live control panel and update this with it
+ }
+
+ if (node->kind == BeamformerPanelKind_LiveImagingControls && node == beamformer_context->auto_live_control_panel)
+ beamformer_context->auto_live_control_panel = 0;
+
beamformer_ui_panel_unlink(node);
if (node->kind == BeamformerPanelKind_TabGroup) {
@@ -5032,6 +5040,9 @@ beamformer_ui_push_panel(BeamformerUIPanel *parent, BeamformerPanelKind kind)
result->u.frame_view = beamformer_ui_frame_view_new(view_kind);
}
+ if (kind == BeamformerPanelKind_LiveImagingControls)
+ beamformer_context->base_registers.v.live_controls = (u64)result;
+
return result;
}