diff --git a/crates/ui-egui/src/dialogs/mod.rs b/crates/ui-egui/src/dialogs/mod.rs index 94c5e53d..468c40ce 100644 --- a/crates/ui-egui/src/dialogs/mod.rs +++ b/crates/ui-egui/src/dialogs/mod.rs @@ -328,9 +328,10 @@ pub fn show(app: &mut VectorcraftApp, ctx: &egui::Context) { ui.add_space(12.0); cancel = (spec.body)(app, ui, &mut d); ui.add_space(16.0); - // The button row is as tall as the buttons: a right-to-left layout would otherwise take - // all the height left in the window, so the window could never shrink to its content. - let row = egui::vec2(ui.available_width(), ui.spacing().interact_size.y); + // The button row is as wide as the fields above it and as tall as the buttons: a + // right-to-left layout would otherwise take all the room left in the window, so the + // window could never shrink to its content. + let row = egui::vec2(ui.min_rect().width(), ui.spacing().interact_size.y); ui.allocate_ui_with_layout(row, egui::Layout::right_to_left(egui::Align::Center), |ui| { if let Some(label) = spec.ok.map(|ok| spec.ok_label.map_or(ok, |f| f(app))) && widgets::primary_button(ui, label).clicked() diff --git a/crates/ui-egui/src/dialogs/tests.rs b/crates/ui-egui/src/dialogs/tests.rs index ecffbffb..94c89b45 100644 --- a/crates/ui-egui/src/dialogs/tests.rs +++ b/crates/ui-egui/src/dialogs/tests.rs @@ -246,3 +246,30 @@ fn dialogs_do_not_stretch_to_the_screen() { } assert!(checked >= 10, "only {checked} dialogs drew in the shared frame"); } + +/// The dialog window of `app`'s open dialog after a few frames in a `w` × 900 window. +fn dialog_rect(app: &mut VectorcraftApp, w: f32) -> egui::Rect { + let ctx = egui::Context::default(); + theme::install_fonts(&ctx); + theme::apply(&ctx, Default::default()); + let screen = egui::Rect::from_min_size(egui::Pos2::ZERO, egui::vec2(w, 900.0)); + let kind = app.ui.dialog.as_ref().unwrap().kind.clone(); + for _ in 0..3 { + let input = egui::RawInput { screen_rect: Some(screen), ..Default::default() }; + ctx.run_ui(input, |ui| show(app, ui.ctx())).textures_delta.clear(); + } + ctx.memory(|m| m.area_rect(egui::Id::new(("dialog", kind.as_str())))).unwrap() +} + +#[test] +fn a_form_dialog_is_as_wide_as_its_fields_not_the_window() { + let mut app = app(); + // Clean Up: three check boxes in the generic parameter dialog. + let params = json!({"emptyTextPaths": true, "strayPoints": true, "unpaintedObjects": true}); + app.run("ui.paramDialog", json!({"command": "object.path.cleanUp", "label": "Clean Up", "params": params})).unwrap(); + let wide = dialog_rect(&mut app, 1600.0); + assert!(wide.width() < 500.0, "Clean Up is {:.0} wide in a 1600-point window", wide.width()); + // The same dialog in a narrow window still fits it. + let narrow = dialog_rect(&mut app, 360.0); + assert!(narrow.width() <= 360.0, "{:.0} wide in a 360-point window", narrow.width()); +}