From d8c88cea1d7d31336934531beab2909235b1f6d3 Mon Sep 17 00:00:00 2001 From: Harrison Booth <73434116+Harrison-Booth@users.noreply.github.com> Date: Tue, 27 Oct 2026 20:57:04 -0500 Subject: [PATCH] Format Shape: Scale and a centre origin need a single selected shape --- crates/ui-egui/src/panels/format_shape.rs | 52 ++++++++++++++--------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/crates/ui-egui/src/panels/format_shape.rs b/crates/ui-egui/src/panels/format_shape.rs index 3ce92d26..b673a3ae 100644 --- a/crates/ui-egui/src/panels/format_shape.rs +++ b/crates/ui-egui/src/panels/format_shape.rs @@ -32,6 +32,8 @@ pub(super) fn format_shape(app: &mut SlideApp, ui: &mut Ui) { return; }; let x = deckcraft_engine::cmd::xfrm_of(&st.doc, &st.selection, &sh); + // Scale and a centre origin work from the shown shape's size, so they need a single shape. + let single = st.selected_shapes().len() == 1; let uid = st.uid; // Tabs as icons. ui.horizontal(|ui| { @@ -156,7 +158,7 @@ pub(super) fn format_shape(app: &mut SlideApp, ui: &mut Ui) { let (base_w, base_h): (f64, f64) = ui.data_mut(|d| d.get_temp(base_id).unwrap_or((x.w, x.h))); ui.data_mut(|d| d.insert_temp(base_id, (base_w, base_h))); let origin_id = ui.scope_id().with("fmt-origin-center"); - let mut center: bool = ui.data_mut(|d| d.get_temp(origin_id).unwrap_or(false)); + let mut center: bool = single && ui.data_mut(|d| d.get_temp(origin_id).unwrap_or(false)); let len = app.session.prefs.units; let mut fields = |ui: &mut Ui, label: &str, id: &str, v: f64, key: &str, cmd: &str, angle: bool| { let (unit, suffix) = if angle { (1.0, "°") } else { (len.points_per_unit(), len.suffix()) }; @@ -176,18 +178,20 @@ pub(super) fn format_shape(app: &mut SlideApp, ui: &mut Ui) { fields(ui, "Width", "fw", x.w, "w", "shape.resize", false); fields(ui, "Rotation", "fr", x.rot, "deg", "shape.rotate", true); for (label, id, cur, base, key) in [("Scale Height", "fsh", x.h, base_h, "h"), ("Scale Width", "fsw", x.w, base_w, "w")] { - ui.horizontal(|ui| { - ui.add_sized(vec2(90.0, 20.0), egui::Label::new(label)); - let pct = if base > 0.0 { cur / base * 100.0 } else { 100.0 }; - if let Some(nv) = widgets::spinner(ui, id, label, pct, 1.0, "%", 70.0) - && nv > 0.0 - { - let mut p = json!({key: base * nv / 100.0}); - if locked { - p["lockAspect"] = json!(true); + ui.add_enabled_ui(single, |ui| { + ui.horizontal(|ui| { + ui.add_sized(vec2(90.0, 20.0), egui::Label::new(label)); + let pct = if base > 0.0 { cur / base * 100.0 } else { 100.0 }; + if let Some(nv) = widgets::spinner(ui, id, label, pct, 1.0, "%", 70.0) + && nv > 0.0 + { + let mut p = json!({key: base * nv / 100.0}); + if locked { + p["lockAspect"] = json!(true); + } + run(app, "shape.sizePosition", p); } - run(app, "shape.sizePosition", p); - } + }) }); } if ui.checkbox(&mut lock, "Lock aspect ratio").changed() { @@ -195,16 +199,22 @@ pub(super) fn format_shape(app: &mut SlideApp, ui: &mut Ui) { } ui.add_space(6.0); ui.label(egui::RichText::new("Position").font(theme::bold(13.0))); - ui.horizontal(|ui| { - ui.add_sized(vec2(90.0, 20.0), egui::Label::new("From")); - let combo = - egui::ComboBox::from_id_salt("fmt-origin").selected_text(if center { "Center" } else { "Top Left Corner" }).show_ui(ui, |ui| { - ui.selectable_value(&mut center, false, "Top Left Corner"); - ui.selectable_value(&mut center, true, "Center"); - }); - combo.response.widget_info(|| egui::WidgetInfo::labeled(egui::Role::ComboBox, true, "From")); + ui.add_enabled_ui(single, |ui| { + ui.horizontal(|ui| { + ui.add_sized(vec2(90.0, 20.0), egui::Label::new("From")); + let combo = egui::ComboBox::from_id_salt("fmt-origin").selected_text(if center { "Center" } else { "Top Left Corner" }).show_ui( + ui, + |ui| { + ui.selectable_value(&mut center, false, "Top Left Corner"); + ui.selectable_value(&mut center, true, "Center"); + }, + ); + combo.response.widget_info(|| egui::WidgetInfo::labeled(egui::Role::ComboBox, true, "From")); + }) }); - ui.data_mut(|d| d.insert_temp(origin_id, center)); + if single { + ui.data_mut(|d| d.insert_temp(origin_id, center)); + } let (dx, dy) = if center { (x.w / 2.0, x.h / 2.0) } else { (0.0, 0.0) }; // The spinner shows `value / unit`; `shape.move` takes the top-left corner, so a centre // reading is shifted by half the size in both directions.