diff --git a/crates/ui-egui/src/chrome.rs b/crates/ui-egui/src/chrome.rs index 00467ab2d..0176f97ef 100644 --- a/crates/ui-egui/src/chrome.rs +++ b/crates/ui-egui/src/chrome.rs @@ -265,23 +265,7 @@ pub fn control_bar(app: &mut VectorcraftApp, ui: &mut Ui) { } return; } - // Align buttons. - for (icon, tip, p) in [ - ("align-start-vertical", "Horizontal Align Left", json!({"horizontal": "left"})), - ("align-center-vertical", "Horizontal Align Center", json!({"horizontal": "center"})), - ("align-end-vertical", "Horizontal Align Right", json!({"horizontal": "right"})), - ("align-start-horizontal", "Vertical Align Top", json!({"vertical": "top"})), - ("align-center-horizontal", "Vertical Align Center", json!({"vertical": "center"})), - ("align-end-horizontal", "Vertical Align Bottom", json!({"vertical": "bottom"})), - ] { - if widgets::icon_button(ui, icon, tl!(tip), false, 24.0).clicked() { - let mut p = p; - if sel.len() == 1 { - p["to"] = json!("artboard"); - } - app.run("object.align", p).ok(); - } - } + crate::panels::align::align_buttons(app, ui, 24.0); ui.separator(); // The Transform link opens the whole Transform panel (reference point, rotate, // shear, options) in a popover; X/Y/W/H follow inline while the bar has room. diff --git a/crates/ui-egui/src/i18n/es.tsv b/crates/ui-egui/src/i18n/es.tsv index 8476f913b..209992946 100644 --- a/crates/ui-egui/src/i18n/es.tsv +++ b/crates/ui-egui/src/i18n/es.tsv @@ -1497,6 +1497,7 @@ Monospaced Monoespaciada More Más More Pathfinder options Más opciones de Buscatrazos + More Align options Más opciones de alineación More Settings Más ajustes Move Mover Move All Objects Mover todos los objetos diff --git a/crates/ui-egui/src/i18n/fr.tsv b/crates/ui-egui/src/i18n/fr.tsv index b82601222..ab47b7f47 100644 --- a/crates/ui-egui/src/i18n/fr.tsv +++ b/crates/ui-egui/src/i18n/fr.tsv @@ -1496,6 +1496,7 @@ Monospaced À chasse fixe More Plus More Pathfinder options Plus d’options Pathfinder + More Align options Plus d’options d’alignement More Settings Plus de réglages Move Déplacer Move All Objects Déplacer tous les objets diff --git a/crates/ui-egui/src/i18n/it.tsv b/crates/ui-egui/src/i18n/it.tsv index aa5edeb5a..e23a10f54 100644 --- a/crates/ui-egui/src/i18n/it.tsv +++ b/crates/ui-egui/src/i18n/it.tsv @@ -1497,6 +1497,7 @@ Monospaced Monospaziato More Altro More Pathfinder options Altre opzioni di Elaborazione tracciati + More Align options Altre opzioni di allineamento More Settings Altre impostazioni Move Sposta Move All Objects Sposta tutti gli oggetti diff --git a/crates/ui-egui/src/i18n/ja.tsv b/crates/ui-egui/src/i18n/ja.tsv index 80e8c16bc..75df70579 100644 --- a/crates/ui-egui/src/i18n/ja.tsv +++ b/crates/ui-egui/src/i18n/ja.tsv @@ -1639,6 +1639,7 @@ Monochrome images モノクロイメージ More 多く More Pathfinder options その他のパスファインダーオプション + More Align options その他の整列オプション More Settings その他の設定 Move 移動 Move Anchors アンカーポイントを移動 diff --git a/crates/ui-egui/src/i18n/pt-br.tsv b/crates/ui-egui/src/i18n/pt-br.tsv index e2e03f23e..09b12d794 100644 --- a/crates/ui-egui/src/i18n/pt-br.tsv +++ b/crates/ui-egui/src/i18n/pt-br.tsv @@ -1313,6 +1313,7 @@ Monochrome images Imagens monocromáticas More Mais More Pathfinder options Mais opções de Localizador de Caminhos + More Align options Mais opções de alinhamento More Settings Mais Configurações Move Mover Move Anchors Mover Âncoras diff --git a/crates/ui-egui/src/i18n/ru.tsv b/crates/ui-egui/src/i18n/ru.tsv index a3ebf7d47..504b52a97 100644 --- a/crates/ui-egui/src/i18n/ru.tsv +++ b/crates/ui-egui/src/i18n/ru.tsv @@ -1495,6 +1495,7 @@ Monospaced Моноширинный More Больше More Pathfinder options Дополнительные параметры обработки контуров + More Align options Дополнительные параметры выравнивания More Settings Дополнительные настройки Move Переместить Move All Objects Переместить все объекты diff --git a/crates/ui-egui/src/i18n/uk.tsv b/crates/ui-egui/src/i18n/uk.tsv index cb6f3a116..0f19a210c 100644 --- a/crates/ui-egui/src/i18n/uk.tsv +++ b/crates/ui-egui/src/i18n/uk.tsv @@ -1491,6 +1491,7 @@ Monospaced Моноширинний More Більше More Pathfinder options Додаткові параметри обробки контурів + More Align options Додаткові параметри вирівнювання More Settings Додаткові налаштування Move Перемістити Move All Objects Перемістити всі об’єкти diff --git a/crates/ui-egui/src/i18n/zh-hans.tsv b/crates/ui-egui/src/i18n/zh-hans.tsv index de889f02f..03119810c 100644 --- a/crates/ui-egui/src/i18n/zh-hans.tsv +++ b/crates/ui-egui/src/i18n/zh-hans.tsv @@ -1455,6 +1455,7 @@ Monochrome images 单色图像 More 较多 More Pathfinder options 更多路径查找器选项 + More Align options 更多对齐选项 More Settings 更多设置 Move 移动 Move All Objects 移动所有对象 diff --git a/crates/ui-egui/src/i18n/zh-hant.tsv b/crates/ui-egui/src/i18n/zh-hant.tsv index f4dc6efc3..7aabf1416 100644 --- a/crates/ui-egui/src/i18n/zh-hant.tsv +++ b/crates/ui-egui/src/i18n/zh-hant.tsv @@ -1497,6 +1497,7 @@ Monospaced 等寬 More 更多 More Pathfinder options 更多路徑管理員選項 + More Align options 更多對齊選項 More Settings 更多設定 Move 移動 Move All Objects 移動所有物件 diff --git a/crates/ui-egui/src/panels/align.rs b/crates/ui-egui/src/panels/align.rs index 5aa6619ad..6c9c9e767 100644 --- a/crates/ui-egui/src/panels/align.rs +++ b/crates/ui-egui/src/panels/align.rs @@ -52,6 +52,26 @@ pub const DISTRIBUTE: [(&str, &str, &str, &str); 6] = [ ("dc-dist-right", "Horizontal Distribute Right", "horizontal", "right"), ]; +/// The six align buttons of the Control bar and the Properties panel, `size` points square. +/// They align to what the Align panel's Align To says (the key object while there is one), as +/// its own buttons do (#789). +pub fn align_buttons(app: &mut VectorcraftApp, ui: &mut Ui, size: f32) { + let n = selection_len(app); + let to = align_to(app, ui.ctx()); + for (icon, tip, axis, v) in [ + ("align-start-vertical", "Horizontal Align Left", "horizontal", "left"), + ("align-center-vertical", "Horizontal Align Center", "horizontal", "center"), + ("align-end-vertical", "Horizontal Align Right", "horizontal", "right"), + ("align-start-horizontal", "Vertical Align Top", "vertical", "top"), + ("align-center-horizontal", "Vertical Align Center", "vertical", "center"), + ("align-end-horizontal", "Vertical Align Bottom", "vertical", "bottom"), + ] { + if widgets::icon_button(ui, icon, tl!(tip), false, size).clicked() { + app.run("object.align", align_params(json!({axis: v}), to, n)).ok(); + } + } +} + /// Whether the selection has a key object. fn has_key(app: &VectorcraftApp) -> bool { app.session.active().is_some_and(|st| st.selection.key.is_some()) @@ -183,4 +203,35 @@ mod tests { app.run("select.key", json!({})).unwrap(); assert_eq!(align_to(&app, &ctx), AlignTo::Selection, "no key: the choice again"); } + + /// #789: the Control bar's and the Properties panel's align buttons follow Align To too. + #[test] + fn the_other_align_buttons_align_to_the_align_to_choice() { + let mut app = VectorcraftApp::new(vectorcraft_engine::Session::new(), Default::default()); + app.run("file.new", json!({"width": 200, "height": 200})).unwrap(); + let a = app.run("shape.rectangle", json!({"x": 10, "y": 10, "width": 10, "height": 10})).unwrap()["id"].clone(); + let b = app.run("shape.rectangle", json!({"x": 80, "y": 50, "width": 30, "height": 30})).unwrap()["id"].clone(); + app.run("select.set", json!({"ids": [a, b]})).unwrap(); + let ctx = egui::Context::default(); + set_pstate(&ctx, "align-to", AlignTo::Artboard); + // One frame finds the first button (Horizontal Align Right is third); the next clicks it. + let at = std::cell::Cell::new(egui::Pos2::ZERO); + let frame = |app: &mut VectorcraftApp, events: Vec| { + let mut out = ctx.run_ui(egui::RawInput { events, ..Default::default() }, |ui| { + ui.horizontal(|ui| { + at.set(ui.cursor().min); + align_buttons(app, ui, 24.0); + }); + }); + out.textures_delta.clear(); + }; + frame(&mut app, vec![]); + let right = at.get() + egui::vec2(2.0 * (24.0 + ctx.global_style().spacing.item_spacing.x) + 12.0, 12.0); + let press = |pressed| egui::Event::PointerButton { pos: right, button: egui::PointerButton::Primary, pressed, modifiers: Default::default() }; + frame(&mut app, vec![egui::Event::PointerMoved(right), press(true)]); + frame(&mut app, vec![press(false)]); + let st = app.session.active().unwrap(); + let x1 = |id: &serde_json::Value| st.doc.bounds_of(&[vectorcraft_doc::NodeId(id.as_u64().unwrap())], false).unwrap().x1; + assert_eq!((x1(&a), x1(&b)), (200.0, 200.0), "both to the artboard's right edge"); + } } diff --git a/crates/ui-egui/src/panels/properties.rs b/crates/ui-egui/src/panels/properties.rs index ea27ebc80..88a636ae7 100644 --- a/crates/ui-egui/src/panels/properties.rs +++ b/crates/ui-egui/src/panels/properties.rs @@ -57,21 +57,10 @@ pub fn show(app: &mut VectorcraftApp, ui: &mut Ui) { divider(ui); section_header(ui, tl!("Align")); ui.horizontal(|ui| { - for (icon, tip, p) in [ - ("align-start-vertical", tl!("Horizontal Align Left"), json!({"horizontal": "left"})), - ("align-center-vertical", tl!("Horizontal Align Center"), json!({"horizontal": "center"})), - ("align-end-vertical", tl!("Horizontal Align Right"), json!({"horizontal": "right"})), - ("align-start-horizontal", tl!("Vertical Align Top"), json!({"vertical": "top"})), - ("align-center-horizontal", tl!("Vertical Align Center"), json!({"vertical": "center"})), - ("align-end-horizontal", tl!("Vertical Align Bottom"), json!({"vertical": "bottom"})), - ] { - if widgets::icon_button(ui, icon, tip, false, 26.0).clicked() { - let mut p = p; - if n_sel == 1 { - p["to"] = json!("artboard"); - } - app.run("object.align", p).ok(); - } + super::align::align_buttons(app, ui, 26.0); + // The rest (Distribute Objects, Distribute Spacing, Align To) is the Align panel's. + if widgets::icon_button(ui, "ellipsis", tl!("More Align options"), false, 26.0).clicked() { + app.ui.open_panel = Some("align".into()); } }); if n_sel > 1 {