From 20422c47256b21338f05de5ead111166f01368bf Mon Sep 17 00:00:00 2001 From: Jan Hallvard Larsen Date: Thu, 8 Oct 2026 16:14:24 +0100 Subject: [PATCH] UI: the Control panel shows its second row In every workspace that shows the Control panel (Advanced, Typography, Printing and Proofing, Book), the second row of fields was cut off at the panel's lower edge: Y and H in object mode, leading, tracking and the indents in text mode. The panel lays its groups out in a row that centres each child vertically. The two-row grids were placed as if they were one row tall and then grew downward, so they started 13.5 pt below the panel's top instead of at it and ended 5.5 pt past the 59 pt panel. The row is now top-aligned, which is where the font menus, the separators and the reference-point proxy already sat. Co-Authored-By: Claude Opus 5.5 (1M context) --- crates/ui-egui/src/chrome.rs | 2 +- crates/ui-egui/src/lib.rs | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/crates/ui-egui/src/chrome.rs b/crates/ui-egui/src/chrome.rs index dfb5e699b..04f4c4fc3 100644 --- a/crates/ui-egui/src/chrome.rs +++ b/crates/ui-egui/src/chrome.rs @@ -142,7 +142,7 @@ pub fn control_bar(app: &mut DesignApp, ui: &mut egui::Ui) { egui::Frame::NONE.fill(t.panel).inner_margin(egui::Margin { left: 8, right: 8, top: 5, bottom: 3 }).stroke(Stroke::new(1.0, t.divider)), ) .show(ui, |ui| { - ui.horizontal(|ui| { + ui.horizontal_top(|ui| { let text_mode = matches!(app.session.tool_id(), "type" | "verticalType") || app.session.active().is_some_and(|d| d.selection.text.is_some()); if text_mode { diff --git a/crates/ui-egui/src/lib.rs b/crates/ui-egui/src/lib.rs index 7b474fa21..6f65a6aa6 100644 --- a/crates/ui-egui/src/lib.rs +++ b/crates/ui-egui/src/lib.rs @@ -872,6 +872,30 @@ pub fn now_ms() -> f64 { mod tests { use super::*; + /// The Control panel's two-row groups were centred as if they were one row tall, so the second + /// row hung below the panel and was cut off. + #[test] + fn control_bar_shows_its_second_row() { + use egui_kittest::kittest::Queryable as _; + let mut app = DesignApp::new(designcraft_engine::Session::new(), Services::default()); + app.run("file.newSample", json!({})).unwrap(); + app.ui.control_bar = true; + let mut h = egui_kittest::Harness::builder().with_size(egui::vec2(1440.0, 900.0)).build_ui_state( + |ui, app: &mut DesignApp| { + let ctx = ui.ctx().clone(); + app.logic(&ctx); + app.ui(ui); + }, + app, + ); + h.run_steps(4); + let bar = egui::containers::panel::PanelState::load(&h.ctx, egui::Id::new("control_bar")).unwrap().outer_rect; + assert!(bar.height() > 40.0, "{bar:?}"); + let rows: Vec = h.query_all_by_label("Y:").map(|n| n.rect()).filter(|r| bar.contains(r.left_top())).collect(); + assert_eq!(rows.len(), 1, "the Y: caption of the Control panel"); + assert!(rows[0].bottom() <= bar.bottom(), "Y: caption {:?} hangs below the Control panel {bar:?}", rows[0]); + } + #[test] fn snap_view_uses_the_saved_switches() { let mut ui = UiState::default();