Commit: d75294f88389f24df5ffab8485a09109a4701188
Parent: d8adafea9b9f9309744bed7b59c3e88bb45ea497
Author: Randy Palamar
Date: Tue, 21 Jul 2026 06:09:07 -0700
ui: move context menu building close to panel building
it easier to add a panel if all code is contained in one place
Diffstat:
| M | ui.c | | | 651 | ++++++++++++++++++++++++++++++++++++++----------------------------------------- |
1 file changed, 315 insertions(+), 336 deletions(-)
diff --git a/ui.c b/ui.c
@@ -1,6 +1,5 @@
/* See LICENSE for license details. */
/* TODO(rnp):
- * [ ]: bug: context_menu_close on live parameters acquisition jumps to left corner of beamformer
* [ ]: bug: flickering x-scroll bar on switch from ComputeBarGraph to other
* [ ]: word scan for text input
* [ ]: animation state
@@ -8,8 +7,6 @@
* [ ]: extra copy view settings
* [ ]: refactor: all drag overlay floating elements can be children of the drag_root.
* as long as we layout before chaining them on there won't be an issue.
- * [ ]: refactor: move context menu building code next to normal ui building.
- * keeping this localized makes it easier to add new panels.
* [ ]: refactor: can the scroll container just use the ViewScroll flags like the tab bar?
* [ ]: refactor: it would be nice to have some table building helpers
*
@@ -527,10 +524,12 @@ UI_STACK_LIST
#define ui_padh(v) UIPrefHeight(ui_px(v, 1.f)) ui_spacer(0)
#define ui_pads(v) UISize(ui_px(v, 1.f)) ui_spacer(0)
-#define ui_dragging(s) (!!(s.flags & UISignalFlag_Dragging))
-#define ui_released(s) (!!(s.flags & UISignalFlag_Released))
-#define ui_pressed(s) (!!(s.flags & UISignalFlag_Pressed))
-#define ui_scrolled(s) (!!(s.flags & UISignalFlag_Scrolled))
+#define ui_dragging(s) (!!((s).flags & UISignalFlag_Dragging))
+#define ui_released(s) (!!((s).flags & UISignalFlag_Released))
+#define ui_pressed(s) (!!((s).flags & UISignalFlag_Pressed))
+#define ui_scrolled(s) (!!((s).flags & UISignalFlag_Scrolled))
+
+#define ui_context_menu(p) ((p) == ui_context->context_menu_panel)
function UIAlign
ui_push_axis_alignment(Axis2 axis, UIAlign v)
@@ -1710,6 +1709,7 @@ ui_context_menu_close(void)
{
ui_context->context_menu_next_anchor_key = ui_node_key_zero();
ui_context->context_menu_state_changed = 1;
+ ui_context->context_menu_next_panel = 0;
}
function void
@@ -2674,6 +2674,90 @@ ui_build_frame_view_overlay(UINode *frame_view, BeamformerFrameView *view, v2 mi
}
function void
+ui_build_3d_xplane_context_menu(BeamformerFrameView *view)
+{
+ UINode *label_column, *button_column;
+ UIParent(ui_context->context_menu_root)
+ UIChildLayoutAxis(Axis2_X)
+ UIPrefHeight(ui_children_sum(1.f))
+ UIPrefWidth(ui_children_sum(1.f))
+ UIParent(ui_spacer(0))
+ UIChildLayoutAxis(Axis2_Y)
+ {
+ ui_padw(UI_NODE_PAD);
+ UIAxisAlign(Axis2_X, Left) label_column = ui_node_from_string(0, str8("###labels"));
+ ui_padw(UI_NODE_PAD * 2.f);
+ UIAxisAlign(Axis2_X, Center)
+ button_column = ui_node_from_string(0, str8("###buttons"));
+ ui_padw(UI_NODE_PAD);
+ }
+
+ UIPrefHeight(ui_text_dim(1.1f, 1.f))
+ UIPrefWidth(ui_text_dim(1.f, 1.f))
+ {
+ {
+ f32 row_height;
+ UIParent(label_column)
+ row_height = ui_label(str8("Log Scale")).node->computed_size[Axis2_Y];
+
+ UIParent(button_column)
+ // TODO(rnp): ui_em(1.f, 1.f) once font size matches directly
+ UIPrefHeight(ui_px(row_height, 1.f))
+ UIPrefWidth(ui_px(row_height, 1.f))
+ {
+ UISignal signal = ui_toggle_button(view->log_scale, str8("###log_scale"));
+ if ui_pressed(signal) {
+ view->log_scale = !view->log_scale;
+ view->dirty = 1;
+ }
+ }
+ }
+
+ {
+ f32 row_height;
+ UIParent(label_column)
+ row_height = ui_label(str8("Demo Mode")).node->computed_size[Axis2_Y];
+
+ UIParent(button_column)
+ // TODO(rnp): ui_em(1.f, 1.f) once font size matches directly
+ UIPrefHeight(ui_px(row_height, 1.f))
+ UIPrefWidth(ui_px(row_height, 1.f))
+ {
+ UISignal signal = ui_toggle_button(view->demo, str8("###demo_mode"));
+ if ui_pressed(signal)
+ view->demo = !view->demo;
+ }
+ }
+
+ UIParent(label_column)
+ {
+ f32 row_height = ui_label(str8("Planes:")).node->computed_size[Axis2_Y];
+ // TODO(rnp): ui_em(1.f, 1.f) once font size matches directly
+ UIParent(button_column) ui_padh(row_height);
+ }
+ for EachElement(view->plane_active, plane) {
+ f32 row_height;
+ UIParent(label_column)
+ {
+ str8 label = push_str8_from_parts(ui_build_arena(), str8(""), str8(" "),
+ beamformer_view_plane_tag_strings[plane]);
+ row_height = ui_label(label).node->computed_size[Axis2_Y];
+ }
+
+ UIParent(button_column)
+ UIPrefHeight(ui_px(row_height, 1.f))
+ UIPrefWidth(ui_px(row_height, 1.f))
+ {
+ UISignal signal = ui_toggle_button(view->plane_active[plane],
+ beamformer_view_plane_tag_strings[plane]);
+ if ui_pressed(signal)
+ view->plane_active[plane] = !view->plane_active[plane];
+ }
+ }
+ }
+}
+
+function void
ui_build_3d_xplane_frame_view(UINode *container, BeamformerFrameView *view)
{
assert(view->kind == BeamformerFrameViewKind_3DXPlane);
@@ -2812,6 +2896,111 @@ ui_build_3d_xplane_frame_view(UINode *container, BeamformerFrameView *view)
}
function void
+ui_build_frame_view_context_menu(BeamformerUIPanel *panel, BeamformerFrameView *view)
+{
+ UINode *label_column, *button_column;
+ UIParent(ui_context->context_menu_root)
+ UIChildLayoutAxis(Axis2_X)
+ UIPrefHeight(ui_children_sum(1.f))
+ UIPrefWidth(ui_children_sum(1.f))
+ UIParent(ui_spacer(0))
+ UIChildLayoutAxis(Axis2_Y)
+ {
+ ui_padw(UI_NODE_PAD);
+ UIAxisAlign(Axis2_X, Left) label_column = ui_node_from_string(0, str8("###labels"));
+ ui_padw(UI_NODE_PAD * 2.f);
+ UIAxisAlign(Axis2_X, Center)
+ button_column = ui_node_from_string(0, str8("###buttons"));
+ ui_padw(UI_NODE_PAD);
+ }
+
+ UIPrefHeight(ui_text_dim(1.1f, 1.f))
+ UIPrefWidth(ui_text_dim(1.f, 1.f))
+ {
+ read_only local_persist str8 dimension_strings[2][2] = {
+ {str8_comp("Extent Scale Bar"), str8_comp("Magnitude Scale Bar")},
+ {str8_comp("Lateral Scale Bar"), str8_comp("Axial Scale Bar") },
+ };
+
+ UIParent(label_column) ui_label(str8("Plane Tag"));
+ UIParent(button_column)
+ UIFlags(UINodeFlag_Scroll)
+ {
+ str8 tag = str8("Any");
+ if (view->view_plane != BeamformerViewPlaneTag_Count)
+ tag = beamformer_view_plane_tag_strings[view->view_plane];
+ UISignal signal = ui_label_button(push_str8_from_parts(ui_build_arena(), str8(""),
+ tag, str8("###PlaneTagButton")));
+ i32 delta = signal.scroll.y + ui_pressed(signal);
+ view->view_plane = circular_add(view->view_plane, delta, BeamformerViewPlaneTag_Count + 1);
+ if (ui_pressed(signal) || ui_scrolled(signal))
+ view->dirty = 1;
+ }
+
+ i32 dimension = iv3_dimension(view->frame.points);
+ dimension = Min(dimension, 2);
+ if (dimension > 0) {
+ for EachEnumValue(Axis2, axis) {
+ f32 row_height;
+ UIParent(label_column)
+ row_height = ui_label(dimension_strings[dimension - 1][axis]).node->computed_size[Axis2_Y];
+
+ UIParent(button_column)
+ // TODO(rnp): ui_em(1.f, 1.f) once font size matches directly
+ UIPrefHeight(ui_px(row_height, 1.f))
+ UIPrefWidth(ui_px(row_height, 1.f))
+ {
+ UISignal signal = ui_toggle_buttonf(view->scale_bar_active[axis], "###axis_%u", axis);
+ if ui_pressed(signal)
+ view->scale_bar_active[axis] = !view->scale_bar_active[axis];
+ }
+ }
+ }
+
+ {
+ f32 row_height;
+ UIParent(label_column)
+ row_height = ui_label(str8("Log Scale")).node->computed_size[Axis2_Y];
+
+ UIParent(button_column)
+ // TODO(rnp): ui_em(1.f, 1.f) once font size matches directly
+ UIPrefHeight(ui_px(row_height, 1.f))
+ UIPrefWidth(ui_px(row_height, 1.f))
+ {
+ UISignal signal = ui_toggle_button(view->log_scale, str8("###log_scale"));
+ if ui_pressed(signal) {
+ view->log_scale = !view->log_scale;
+ view->dirty = 1;
+ }
+ }
+ }
+
+ if (dimension > 0 && panel->kind != BeamformerPanelKind_FrameViewCopy) {
+ f32 row_height;
+ UIParent(label_column)
+ {
+ UISignal signal = ui_label_button(str8("Copy Frame"));
+ row_height = signal.node->computed_size[Axis2_Y];
+ if ui_pressed(signal) {
+ ui_context_menu_close();
+ beamformer_command(beamformer_command_infos[BeamformerCommandKind_OpenTab].string,
+ .tree_node = (u64)panel->parent,
+ .frame_view = (u64)view,
+ .string = beamformer_panel_infos[BeamformerPanelKind_FrameViewCopy].string);
+ }
+ }
+
+ // TODO(rnp): ui_em(1.f, 1.f) once font size matches directly
+ UIParent(button_column) ui_padh(row_height);
+ }
+
+ // TODO(rnp): extra frame view copy settings
+ if (panel->kind == BeamformerPanelKind_FrameViewCopy) {
+ }
+ }
+}
+
+function void
ui_build_frame_view(UINode *container, BeamformerFrameView *view)
{
assert(view->kind != BeamformerFrameViewKind_3DXPlane);
@@ -3092,6 +3281,42 @@ ui_build_parameters_listing(BeamformerUIPanel *panel)
{
BeamformerUI *ui = ui_context;
+ if ui_context_menu(panel) {
+ UINode *label_column, *button_column;
+ UIParent(ui->context_menu_root)
+ UIChildLayoutAxis(Axis2_X)
+ UIPrefHeight(ui_children_sum(1.f))
+ UIPrefWidth(ui_children_sum(1.f))
+ UIParent(ui_spacer(0))
+ UIChildLayoutAxis(Axis2_Y)
+ {
+ ui_padw(UI_NODE_PAD);
+ UIAxisAlign(Axis2_X, Left) label_column = ui_node_from_string(0, str8("###labels"));
+ ui_padw(UI_NODE_PAD * 2.f);
+ UIAxisAlign(Axis2_X, Center)
+ button_column = ui_node_from_string(0, str8("###buttons"));
+ ui_padw(UI_NODE_PAD);
+ }
+
+ UIPrefHeight(ui_text_dim(1.1f, 1.f))
+ UIPrefWidth(ui_text_dim(1.f, 1.f))
+ {
+ UIParent(label_column) ui_label(str8("Block"));
+ UIParent(button_column)
+ {
+ UISignal signal;
+ u32 cycle = beamformer_context->shared_memory->reserved_parameter_blocks;
+ u32 block = panel->u.parameter_listing.parameter_block;
+ UIFlags(cycle <= 1 ? UINodeFlag_Disabled : 0)
+ signal = ui_label_buttonf("%u", block);
+ if (ui_pressed(signal) || ui_scrolled(signal)) {
+ i32 delta = signal.scroll.y + ui_pressed(signal);
+ panel->u.parameter_listing.parameter_block = circular_add(block, delta, cycle);
+ }
+ }
+ }
+ }
+
UIFontSize(30.f)
UIScroll(Axis2_Count)
{
@@ -3333,6 +3558,32 @@ ui_build_live_imaging_controls(BeamformerUIPanel *panel)
UISignal signal = ui_label_button(kind_string);
if ui_pressed(signal)
ui_context_menu_open(signal.node->key, panel);
+
+ if ui_context_menu(panel) {
+ u64 enabled_kinds = atomic_load_u64(&lip->acquisition_kind_enabled_flags);
+
+ UIParent(ui_context->context_menu_root)
+ UIFontSize(24.f)
+ UIChildLayoutAxis(Axis2_X)
+ UIPrefHeight(ui_children_sum(1.f))
+ UIPrefWidth(ui_children_sum(1.f))
+ for EachBit(enabled_kinds, kind)
+ UIParent(ui_spacer(0))
+ {
+ ui_padw(UI_NODE_PAD);
+ UIPrefHeight(ui_text_dim(1.1f, 1.f))
+ UIPrefWidth(ui_text_dim(1.f, 1.f))
+ signal = ui_label_button(beamformer_acquisition_kind_strings[kind]);
+ ui_padw(UI_NODE_PAD);
+
+ if ui_pressed(signal) {
+ ui_context_menu_close();
+ lip->acquisition_kind = kind;
+ atomic_or_u32(&beamformer_context->shared_memory->live_imaging_dirty_flags,
+ BeamformerLiveImagingDirtyFlags_AcquisitionKind);
+ }
+ }
+ }
}
UIPrefHeight(ui_text_dim(1.1f, 1.f))
@@ -3424,44 +3675,38 @@ ui_build_live_imaging_controls(BeamformerUIPanel *panel)
ui_padh(UI_NODE_PAD);
+ UIChildLayoutAxis(Axis2_Y)
UIAxisAlign(Axis2_X, Center)
+ UIPrefWidth(ui_children_sum(1.f))
+ UIPrefHeight(ui_children_sum(1.f))
+ spacer = ui_spacer(0);
+
+ UIParent(spacer)
UITextAlign(Center)
UIBGColour((v4){0})
UIPrefWidth(ui_text_dim(1.3f, 1.f))
UIPrefHeight(ui_text_dim(1.3f, 1.f))
{
- UIPrefWidth(ui_pct(1.f, 1.f)) UIPrefHeight(ui_children_sum(1.f))
- spacer = ui_spacer(0);
-
- UIParent(spacer)
- {
- b32 active = lip->save_active;
- str8 label = active ? str8("Saving...###save_button") : str8("Save Data###save_button");
- f32 save_t = beamformer_ui_blinker_update(&panel->u.live_imaging_save_button_blinker, BLINK_SPEED);
- v4 border_colour = (v4){.a = 0.6f};
- if (active) border_colour = v4_lerp(BORDER_COLOUR, FOCUSED_COLOUR, ease_in_out_cubic(save_t));
- UIBorderColour(border_colour)
- signal = ui_button(label);
- if ui_pressed(signal) {
- lip->save_active = !active;
- atomic_or_u32(&beamformer_context->shared_memory->live_imaging_dirty_flags,
- BeamformerLiveImagingDirtyFlags_SaveData);
- }
+ b32 active = lip->save_active;
+ str8 label = active ? str8("Saving...###save_button") : str8("Save Data###save_button");
+ f32 save_t = beamformer_ui_blinker_update(&panel->u.live_imaging_save_button_blinker, BLINK_SPEED);
+ v4 border_colour = (v4){.a = 0.6f};
+ if (active) border_colour = v4_lerp(BORDER_COLOUR, FOCUSED_COLOUR, ease_in_out_cubic(save_t));
+ UIBorderColour(border_colour)
+ signal = ui_button(label);
+ if ui_pressed(signal) {
+ lip->save_active = !active;
+ atomic_or_u32(&beamformer_context->shared_memory->live_imaging_dirty_flags,
+ BeamformerLiveImagingDirtyFlags_SaveData);
}
ui_padh(UI_NODE_PAD);
- UIPrefWidth(ui_pct(1.f, 1.f)) UIPrefHeight(ui_children_sum(1.f))
- spacer = ui_spacer(0);
-
- UIParent(spacer)
- {
- UIBorderColour((v4){.a = 0.6f})
- signal = ui_button(str8("Stop Imaging"));
- if ui_pressed(signal)
- atomic_or_u32(&beamformer_context->shared_memory->live_imaging_dirty_flags,
- BeamformerLiveImagingDirtyFlags_StopImaging);
- }
+ UIBorderColour((v4){.a = 0.6f})
+ signal = ui_button(str8("Stop Imaging"));
+ if ui_pressed(signal)
+ atomic_or_u32(&beamformer_context->shared_memory->live_imaging_dirty_flags,
+ BeamformerLiveImagingDirtyFlags_StopImaging);
}
}
}
@@ -3688,6 +3933,36 @@ ui_panel_group_equip(UINode *node, BeamformerUIPanel *group)
if ui_pressed(signal)
ui_context_menu_open(signal.node->key, group);
+ if ui_context_menu(group) {
+ UIParent(ui_context->context_menu_root)
+ UIChildLayoutAxis(Axis2_X)
+ UIPrefHeight(ui_children_sum(1.f))
+ UIPrefWidth(ui_children_sum(1.f))
+ for EachElement(beamformer_panel_infos, it)
+ {
+ BeamformerPanelInfo *info = beamformer_panel_infos + it;
+ b32 list = (info->flags & BeamformerPanelFlags_List) != 0;
+ b32 needs_frame = (info->flags & BeamformerPanelFlags_NeedsFrame) != 0;
+ if (list && (!needs_frame || beamformer_frame_valid(beamformer_registers()->frame))) {
+ UIParent(ui_spacer(0))
+ {
+ ui_padw(UI_NODE_PAD);
+ UIPrefHeight(ui_text_dim(1.1f, 1.f))
+ UIPrefWidth(ui_text_dim(1.f, 1.f))
+ signal = ui_label_button(info->display);
+ ui_padw(UI_NODE_PAD);
+
+ if ui_pressed(signal) {
+ ui_context_menu_close();
+ beamformer_command(beamformer_command_infos[BeamformerCommandKind_OpenTab].string,
+ .tree_node = (u64)group,
+ .string = info->string);
+ }
+ }
+ }
+ }
+ }
+
if (drop_site && !drop_site_handled && ui_context->drag_panel != group->last_child) {
drop_site_handled = 1;
ui_insert_drop_site_spacer_before(signal.node, tab_pad);
@@ -3876,6 +4151,7 @@ ui_build_regions(UINode *root_node, BeamformerUIPanel *tree_root)
container = ui_node_from_string(0, str8("###frame_view_container"));
ui_build_3d_xplane_frame_view(container, view);
}
+ if ui_context_menu(panel) ui_build_3d_xplane_context_menu(view);
}break;
case BeamformerPanelKind_FrameViewCopy:
@@ -3892,6 +4168,7 @@ ui_build_regions(UINode *root_node, BeamformerUIPanel *tree_root)
container = ui_node_from_string(0, str8("###frame_view_container"));
ui_build_frame_view(container, view);
}
+ if ui_context_menu(panel) ui_build_frame_view_context_menu(panel, view);
}break;
case BeamformerPanelKind_ParameterListing:{ ui_build_parameters_listing(panel); }break;
@@ -4239,303 +4516,6 @@ ui_build_drag_overlay(Rect window_rect)
}
function void
-ui_build_context_menu_for_panel(BeamformerUIPanel *panel)
-{
- if (!panel)
- {
- // TODO(rnp): command pallete
- }
-
- if (panel) {
- UIAxisSize(Axis2_X, ui_px(0.f, 0.5f)) ui_padh(0.8f * UI_NODE_PAD);
- switch(panel->kind) {
- InvalidDefaultCase;
-
- case BeamformerPanelKind_TabGroup:{
- for EachElement(beamformer_panel_infos, it) {
- BeamformerPanelInfo *info = beamformer_panel_infos + it;
- b32 list = (info->flags & BeamformerPanelFlags_List) != 0;
- b32 needs_frame = (info->flags & BeamformerPanelFlags_NeedsFrame) != 0;
- if (list && (!needs_frame || beamformer_frame_valid(beamformer_registers()->frame))) {
- UIChildLayoutAxis(Axis2_X)
- UIPrefHeight(ui_children_sum(1.f))
- UIPrefWidth(ui_children_sum(1.f))
- UIParent(ui_spacer(0))
- {
- UISignal signal;
- ui_padw(UI_NODE_PAD);
- UIPrefHeight(ui_text_dim(1.1f, 1.f))
- UIPrefWidth(ui_text_dim(1.f, 1.f))
- signal = ui_label_button(info->display);
- ui_padw(UI_NODE_PAD);
-
- if ui_pressed(signal) {
- ui_context_menu_close();
- beamformer_command(beamformer_command_infos[BeamformerCommandKind_OpenTab].string,
- .tree_node = (u64)panel,
- .string = info->string);
- }
- }
- }
- }
- }break;
-
- case BeamformerPanelKind_FrameViewCopy:
- case BeamformerPanelKind_FrameViewLive:
- {
- BeamformerFrameView *view = panel->u.frame_view;
-
- UINode *label_column, *button_column;
- UIChildLayoutAxis(Axis2_X)
- UIPrefHeight(ui_children_sum(1.f))
- UIPrefWidth(ui_children_sum(1.f))
- UIParent(ui_spacer(0))
- UIChildLayoutAxis(Axis2_Y)
- {
- ui_padw(UI_NODE_PAD);
- UIAxisAlign(Axis2_X, Left) label_column = ui_node_from_string(0, str8("###labels"));
- ui_padw(UI_NODE_PAD * 2.f);
- UIAxisAlign(Axis2_X, Center)
- button_column = ui_node_from_string(0, str8("###buttons"));
- ui_padw(UI_NODE_PAD);
- }
-
- UIPrefHeight(ui_text_dim(1.1f, 1.f))
- UIPrefWidth(ui_text_dim(1.f, 1.f))
- {
- read_only local_persist str8 dimension_strings[2][2] = {
- {str8_comp("Extent Scale Bar"), str8_comp("Magnitude Scale Bar")},
- {str8_comp("Lateral Scale Bar"), str8_comp("Axial Scale Bar") },
- };
-
- UIParent(label_column) ui_label(str8("Plane Tag"));
- UIParent(button_column)
- UIFlags(UINodeFlag_Scroll)
- {
- str8 tag = str8("Any");
- if (view->view_plane != BeamformerViewPlaneTag_Count)
- tag = beamformer_view_plane_tag_strings[view->view_plane];
- UISignal signal = ui_label_button(push_str8_from_parts(ui_build_arena(), str8(""),
- tag, str8("###PlaneTagButton")));
- i32 delta = signal.scroll.y + ui_pressed(signal);
- view->view_plane = circular_add(view->view_plane, delta, BeamformerViewPlaneTag_Count + 1);
- if (ui_pressed(signal) || ui_scrolled(signal))
- view->dirty = 1;
- }
-
- i32 dimension = iv3_dimension(view->frame.points);
- dimension = Min(dimension, 2);
- if (dimension > 0) {
- for EachEnumValue(Axis2, axis) {
- f32 row_height;
- UIParent(label_column)
- row_height = ui_label(dimension_strings[dimension - 1][axis]).node->computed_size[Axis2_Y];
-
- UIParent(button_column)
- // TODO(rnp): ui_em(1.f, 1.f) once font size matches directly
- UIPrefHeight(ui_px(row_height, 1.f))
- UIPrefWidth(ui_px(row_height, 1.f))
- {
- UISignal signal = ui_toggle_buttonf(view->scale_bar_active[axis], "###axis_%u", axis);
- if ui_pressed(signal)
- view->scale_bar_active[axis] = !view->scale_bar_active[axis];
- }
- }
- }
-
- {
- f32 row_height;
- UIParent(label_column)
- row_height = ui_label(str8("Log Scale")).node->computed_size[Axis2_Y];
-
- UIParent(button_column)
- // TODO(rnp): ui_em(1.f, 1.f) once font size matches directly
- UIPrefHeight(ui_px(row_height, 1.f))
- UIPrefWidth(ui_px(row_height, 1.f))
- {
- UISignal signal = ui_toggle_button(view->log_scale, str8("###log_scale"));
- if ui_pressed(signal) {
- view->log_scale = !view->log_scale;
- view->dirty = 1;
- }
- }
- }
-
- if (dimension > 0 && panel->kind != BeamformerPanelKind_FrameViewCopy) {
- f32 row_height;
- UIParent(label_column)
- {
- UISignal signal = ui_label_button(str8("Copy Frame"));
- row_height = signal.node->computed_size[Axis2_Y];
- if ui_pressed(signal) {
- ui_context_menu_close();
- beamformer_command(beamformer_command_infos[BeamformerCommandKind_OpenTab].string,
- .tree_node = (u64)panel->parent,
- .frame_view = (u64)view,
- .string = beamformer_panel_infos[BeamformerPanelKind_FrameViewCopy].string);
- }
- }
-
- // TODO(rnp): ui_em(1.f, 1.f) once font size matches directly
- UIParent(button_column) ui_padh(row_height);
- }
-
- // TODO(rnp): extra frame view copy settings
- if (panel->kind == BeamformerPanelKind_FrameViewCopy) {
- }
- }
- }break;
-
- case BeamformerPanelKind_FrameViewXPlane:{
- BeamformerFrameView *view = panel->u.frame_view;
-
- UINode *label_column, *button_column;
- UIChildLayoutAxis(Axis2_X)
- UIPrefHeight(ui_children_sum(1.f))
- UIPrefWidth(ui_children_sum(1.f))
- UIParent(ui_spacer(0))
- UIChildLayoutAxis(Axis2_Y)
- {
- ui_padw(UI_NODE_PAD);
- UIAxisAlign(Axis2_X, Left) label_column = ui_node_from_string(0, str8("###labels"));
- ui_padw(UI_NODE_PAD * 2.f);
- UIAxisAlign(Axis2_X, Center)
- button_column = ui_node_from_string(0, str8("###buttons"));
- ui_padw(UI_NODE_PAD);
- }
-
- UIPrefHeight(ui_text_dim(1.1f, 1.f))
- UIPrefWidth(ui_text_dim(1.f, 1.f))
- {
- {
- f32 row_height;
- UIParent(label_column)
- row_height = ui_label(str8("Log Scale")).node->computed_size[Axis2_Y];
-
- UIParent(button_column)
- // TODO(rnp): ui_em(1.f, 1.f) once font size matches directly
- UIPrefHeight(ui_px(row_height, 1.f))
- UIPrefWidth(ui_px(row_height, 1.f))
- {
- UISignal signal = ui_toggle_button(view->log_scale, str8("###log_scale"));
- if ui_pressed(signal) {
- view->log_scale = !view->log_scale;
- view->dirty = 1;
- }
- }
- }
-
- {
- f32 row_height;
- UIParent(label_column)
- row_height = ui_label(str8("Demo Mode")).node->computed_size[Axis2_Y];
-
- UIParent(button_column)
- // TODO(rnp): ui_em(1.f, 1.f) once font size matches directly
- UIPrefHeight(ui_px(row_height, 1.f))
- UIPrefWidth(ui_px(row_height, 1.f))
- {
- UISignal signal = ui_toggle_button(view->demo, str8("###demo_mode"));
- if ui_pressed(signal)
- view->demo = !view->demo;
- }
- }
-
- UIParent(label_column)
- {
- f32 row_height = ui_label(str8("Planes:")).node->computed_size[Axis2_Y];
- // TODO(rnp): ui_em(1.f, 1.f) once font size matches directly
- UIParent(button_column) ui_padh(row_height);
- }
- for EachElement(view->plane_active, plane) {
- f32 row_height;
- UIParent(label_column)
- {
- str8 label = push_str8_from_parts(ui_build_arena(), str8(""), str8(" "),
- beamformer_view_plane_tag_strings[plane]);
- row_height = ui_label(label).node->computed_size[Axis2_Y];
- }
-
- UIParent(button_column)
- UIPrefHeight(ui_px(row_height, 1.f))
- UIPrefWidth(ui_px(row_height, 1.f))
- {
- UISignal signal = ui_toggle_button(view->plane_active[plane],
- beamformer_view_plane_tag_strings[plane]);
- if ui_pressed(signal)
- view->plane_active[plane] = !view->plane_active[plane];
- }
- }
- }
- }break;
-
- case BeamformerPanelKind_ParameterListing:{
- UINode *label_column, *button_column;
- UIChildLayoutAxis(Axis2_X)
- UIPrefHeight(ui_children_sum(1.f))
- UIPrefWidth(ui_children_sum(1.f))
- UIParent(ui_spacer(0))
- UIChildLayoutAxis(Axis2_Y)
- {
- ui_padw(UI_NODE_PAD);
- UIAxisAlign(Axis2_X, Left) label_column = ui_node_from_string(0, str8("###labels"));
- ui_padw(UI_NODE_PAD * 2.f);
- UIAxisAlign(Axis2_X, Center)
- button_column = ui_node_from_string(0, str8("###buttons"));
- ui_padw(UI_NODE_PAD);
- }
-
- UIPrefHeight(ui_text_dim(1.1f, 1.f))
- UIPrefWidth(ui_text_dim(1.f, 1.f))
- {
- UIParent(label_column) ui_label(str8("Block"));
- UIParent(button_column)
- {
- UISignal signal;
- u32 cycle = beamformer_context->shared_memory->reserved_parameter_blocks;
- u32 block = panel->u.parameter_listing.parameter_block;
- UIFlags(cycle <= 1 ? UINodeFlag_Disabled : 0)
- signal = ui_label_buttonf("%u", block);
- if (ui_pressed(signal) || ui_scrolled(signal)) {
- i32 delta = signal.scroll.y + ui_pressed(signal);
- panel->u.parameter_listing.parameter_block = circular_add(block, delta, cycle);
- }
- }
- }
- }break;
-
- case BeamformerPanelKind_LiveImagingControls:{
- BeamformerLiveImagingParameters *lip = &beamformer_context->shared_memory->live_imaging_parameters;
- u64 enabled_kinds = atomic_load_u64(&lip->acquisition_kind_enabled_flags);
-
- UIChildLayoutAxis(Axis2_X)
- UIPrefHeight(ui_children_sum(1.f))
- UIPrefWidth(ui_children_sum(1.f))
- for EachBit(enabled_kinds, kind)
- UIParent(ui_spacer(0))
- {
- UISignal signal;
- ui_padw(UI_NODE_PAD);
- UIPrefHeight(ui_text_dim(1.1f, 1.f))
- UIPrefWidth(ui_text_dim(1.f, 1.f))
- signal = ui_label_button(beamformer_acquisition_kind_strings[kind]);
- ui_padw(UI_NODE_PAD);
-
- if ui_pressed(signal) {
- ui_context_menu_close();
- lip->acquisition_kind = kind;
- atomic_or_u32(&beamformer_context->shared_memory->live_imaging_dirty_flags,
- BeamformerLiveImagingDirtyFlags_AcquisitionKind);
- }
- }
- }break;
-
- }
- UIAxisSize(Axis2_X, ui_px(0.f, 0.5f)) ui_padh(0.8f * UI_NODE_PAD);
- }
-}
-
-function void
ui_layout_constrain(UINode *root)
{
assert(!ui_node_is_nil(root->first_child));
@@ -5322,10 +5302,7 @@ beamformer_ui_frame(void)
ui->context_menu_root = ui_node_from_string(UINodeFlag_DrawBackground, str8("context_menu_root"));
}
- UIParent(ui->context_menu_root)
- {
- ui_build_context_menu_for_panel(ui->context_menu_panel);
- }
+ UIParent(ui->context_menu_root) UIAxisSize(Axis2_X, ui_px(0.f, 0.5f)) ui_padh(0.8f * UI_NODE_PAD);
}
// NOTE(rnp): drag panel
@@ -5406,6 +5383,8 @@ beamformer_ui_frame(void)
ui_layout_nodes(ui->root_node);
if (!ui_node_key_nil(ui->context_menu_anchor_key)) {
+ UIParent(ui->context_menu_root) UIAxisSize(Axis2_X, ui_px(0.f, 0.5f)) ui_padh(0.8f * UI_NODE_PAD);
+
UINode *anchor = ui_node_from_key(ui->context_menu_anchor_key);
v2 anchor_p = ui_node_final_position(anchor);
ui->context_menu_root->computed_position[Axis2_X] = anchor_p.x;