diff --git a/crates/ui-egui/src/dialogs.rs b/crates/ui-egui/src/dialogs.rs index fb899c702..3f070008f 100644 --- a/crates/ui-egui/src/dialogs.rs +++ b/crates/ui-egui/src/dialogs.rs @@ -1367,18 +1367,22 @@ fn paste_special_shortcuts(d: &mut Dialog, ctx: &egui::Context) { fn ok_cancel(ui: &mut egui::Ui, confirm: &mut bool, open: &mut bool) { ui.add_space(8.0); - ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| { - let lang = crate::i18n::current(ui.ctx()); - let ok = ui.add( - egui::Button::new(egui::RichText::new(format!(" {} ", lang.tr("OK"))).color(Color32::WHITE)) - .fill(crate::theme::Tokens::get(ui.ctx()).accent), - ); - if ok.clicked() || ui.input(|i| i.key_pressed(Key::Enter)) { - *confirm = true; - } - if ui.button(format!(" {} ", lang.tr("Cancel"))).clicked() { - *open = false; - } + // A row as tall as the buttons: a right-to-left layout straight in the window takes all the + // height it is offered, which stretched every form dialog to the screen's height. + ui.horizontal(|ui| { + ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| { + let lang = crate::i18n::current(ui.ctx()); + let ok = ui.add( + egui::Button::new(egui::RichText::new(format!(" {} ", lang.tr("OK"))).color(Color32::WHITE)) + .fill(crate::theme::Tokens::get(ui.ctx()).accent), + ); + if ok.clicked() || ui.input(|i| i.key_pressed(Key::Enter)) { + *confirm = true; + } + if ui.button(format!(" {} ", lang.tr("Cancel"))).clicked() { + *open = false; + } + }) }); } diff --git a/crates/ui-egui/tests/dialog_button_row.rs b/crates/ui-egui/tests/dialog_button_row.rs new file mode 100644 index 000000000..7a7520484 --- /dev/null +++ b/crates/ui-egui/tests/dialog_button_row.rs @@ -0,0 +1,27 @@ +//! Form dialogs fit their content: OK and Cancel sit right under the last field, not halfway down +//! a window stretched to the screen's height. + +use egui_kittest::kittest::Queryable as _; +use gridcraft_engine::Session; +use gridcraft_ui_egui::SheetApp; +use serde_json::json; + +#[test] +fn ok_and_cancel_sit_under_the_last_field() { + let mut s = Session::new(); + s.new_workbook(); + let mut h = egui_kittest::Harness::builder().with_size(egui::vec2(1200.0, 1000.0)).build_ui_state( + |ui, app: &mut SheetApp| { + let ctx = ui.ctx().clone(); + app.logic(&ctx); + app.ui(ui); + }, + SheetApp::new(s, Default::default()), + ); + h.state_mut().open_dialog("cfQuick", json!({"type": "cellIs", "operator": "greaterThan", "title": "Greater Than…"})); + h.run_steps(4); + let last = h.get_by_label("Red Border").rect(); + let ok = h.get_by_label_contains("OK").rect(); + let gap = ok.top() - last.bottom(); + assert!((0.0..40.0).contains(&gap), "OK is {gap} points under the last option"); +} diff --git a/docs/ui-parity.md b/docs/ui-parity.md index 34cb502f5..16e1d608a 100644 --- a/docs/ui-parity.md +++ b/docs/ui-parity.md @@ -1,6 +1,6 @@ # UI parity -> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-19 · **Change:** minor (Ctrl+Enter fill gives each cell the automatic number format typing gives it; keytip letters typed with Alt held, #1846) · **Target:** Microsoft Excel (Microsoft 365), Excel for Mac 16.113.4 +> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-21 · **Change:** minor (form dialogs fit their content) · **Target:** Microsoft Excel (Microsoft 365), Excel for Mac 16.113.4 Interaction, controls and feel, against Excel. Part of [target-app-parity.md](target-app-parity.md). **UI/UX fidelity: ~55% ready, 50–80 h** (estimated). Ribbon command coverage is measured @@ -161,6 +161,7 @@ scrollbar bugs 2–4 · pixel/feel pass against observed Excel 7–12. | Date | Change | Summary | |---|---|---| +| 2026-10-21 | minor | Form dialogs (conditional-format quick rules, New Name, Remove Duplicates, Text to Columns and every other `Dialog::form`) fit their content: OK and Cancel sit in a row under the last field instead of a right-to-left layout that took the screen's whole height and left the buttons floating halfway down | | 2026-10-19 | minor | Ctrl+Enter (`range.fill`) gives each cell what typing the input there gives: a General cell gets the automatic number format (`5%`, `$5`, `3/4/2026`, `=TODAY()`) even when it already held a value, and a cell with its own format, a formatted row or column, or Text keeps it. Cells that held a value used to keep General (`5%` showed 0.05), and empty cells took the active cell's format | | 2026-10-18 | minor | Keytip letters typed with left Alt held continue the sequence (Alt+H, O, A / Alt+H, O, I ran nothing before: Alt+letter cancelled keytips); other Alt combinations, AltGr and macOS Option are unchanged (#1846) | | 2026-10-12 | minor | The File view's recent list tells when each workbook was last changed, read off the UI thread |