Merge pull request #239 from theironchef/fix/dialog-width

Dialogs: the button row is as wide as the fields, not the window
This commit is contained in:
BFlat 2026-10-07 07:24:06 +07:00 committed by GitHub
commit e50f02e638
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 31 additions and 3 deletions

View File

@ -328,9 +328,10 @@ pub fn show(app: &mut VectorcraftApp, ctx: &egui::Context) {
ui.add_space(12.0); ui.add_space(12.0);
cancel = (spec.body)(app, ui, &mut d); cancel = (spec.body)(app, ui, &mut d);
ui.add_space(16.0); ui.add_space(16.0);
// The button row is as tall as the buttons: a right-to-left layout would otherwise take // The button row is as wide as the fields above it and as tall as the buttons: a
// all the height left in the window, so the window could never shrink to its content. // right-to-left layout would otherwise take all the room left in the window, so the
let row = egui::vec2(ui.available_width(), ui.spacing().interact_size.y); // 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| { 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))) if let Some(label) = spec.ok.map(|ok| spec.ok_label.map_or(ok, |f| f(app)))
&& widgets::primary_button(ui, label).clicked() && widgets::primary_button(ui, label).clicked()

View File

@ -246,3 +246,30 @@ fn dialogs_do_not_stretch_to_the_screen() {
} }
assert!(checked >= 10, "only {checked} dialogs drew in the shared frame"); 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());
}