diff --git a/ASSETS.md b/ASSETS.md index bf15723ac..1003a0e02 100644 --- a/ASSETS.md +++ b/ASSETS.md @@ -83,6 +83,7 @@ Generated-in-code art is original and has no file to list. This covers the defau | `assets/icons/copy.svg` | Lucide Icons and Contributors | https://lucide.dev (lucide-static v1.49.0; header kept in file) | ISC (`assets/icons/LICENSE-lucide.txt`) | | | `assets/icons/dc-actions.svg` | VectorCraft contributors | Original work, drawn for VectorCraft | MIT OR Apache-2.0 | | | `assets/icons/dc-al-bottom.svg` | VectorCraft contributors | Original work, drawn for VectorCraft | MIT OR Apache-2.0 | | +| `assets/icons/dc-al-center.svg` | VectorCraft contributors | Original work, drawn for VectorCraft | MIT OR Apache-2.0 | | | `assets/icons/dc-al-hcenter.svg` | VectorCraft contributors | Original work, drawn for VectorCraft | MIT OR Apache-2.0 | | | `assets/icons/dc-al-left.svg` | VectorCraft contributors | Original work, drawn for VectorCraft | MIT OR Apache-2.0 | | | `assets/icons/dc-al-right.svg` | VectorCraft contributors | Original work, drawn for VectorCraft | MIT OR Apache-2.0 | | diff --git a/assets/icons/dc-al-center.svg b/assets/icons/dc-al-center.svg new file mode 100644 index 000000000..2e8e9e978 --- /dev/null +++ b/assets/icons/dc-al-center.svg @@ -0,0 +1 @@ + diff --git a/crates/engine/src/tests.rs b/crates/engine/src/tests.rs index 8071a7edd..6a66ad1ab 100644 --- a/crates/engine/src/tests.rs +++ b/crates/engine/src/tests.rs @@ -506,6 +506,19 @@ fn align_to_artboard_uses_the_artboard_named() { assert_eq!(x0(&s, c), boards[0].x0, "off every artboard: the first"); } +#[test] +fn align_both_centers() { + let mut s = session(); + let a = rect(&mut s, 0.0, 0.0, 100.0, 100.0); + let b = rect(&mut s, 20.0, 40.0, 20.0, 20.0); + s.execute("select.set", &json!({"ids": [a.0, b.0]})).unwrap(); + s.execute("object.align", &json!({"horizontal": "center", "vertical": "center"})).unwrap(); + let gb_a = s.doc().unwrap().doc.node(a).unwrap().geometric_bounds().unwrap(); + let gb_b = s.doc().unwrap().doc.node(b).unwrap().geometric_bounds().unwrap(); + assert!((gb_a.center().x - gb_b.center().x).abs() < 1e-6); + assert!((gb_a.center().y - gb_b.center().y).abs() < 1e-6); +} + /// #541: with the Selection tool, a click on one object of the selection makes it the key object: /// aligning to the key moves the others to it, Distribute Spacing spaces them from it, and a click /// on the key again lets it go. diff --git a/crates/ui-egui/src/i18n/cs.tsv b/crates/ui-egui/src/i18n/cs.tsv index 4b081573a..0028e1b96 100644 --- a/crates/ui-egui/src/i18n/cs.tsv +++ b/crates/ui-egui/src/i18n/cs.tsv @@ -133,6 +133,7 @@ Horizontal Align Right Vodorovně zarovnat doprava Vertical Align Top Svisle zarovnat nahoru Vertical Align Center Svisle zarovnat na střed + Horizontal & Vertical Align Center Vodorovně a svisle zarovnat na střed Vertical Align Bottom Svisle zarovnat dolů Group Seskupit Ungroup Oddělit diff --git a/crates/ui-egui/src/i18n/de.tsv b/crates/ui-egui/src/i18n/de.tsv index b5eff51c8..ed0e6e6b7 100644 --- a/crates/ui-egui/src/i18n/de.tsv +++ b/crates/ui-egui/src/i18n/de.tsv @@ -3037,6 +3037,7 @@ effect Points Punkte Vertical % Vertikal % Vertical Align Bottom Vertikal unten ausrichten Vertical Align Center Vertikal zentriert ausrichten + Horizontal & Vertical Align Center Horizontal und vertikal zentriert ausrichten Vertical Align Top Vertikal oben ausrichten Vertical Area Type Tool Vertikaler-Flächentext-Werkzeug Vertical Distribute Bottom Vertikal unten verteilen diff --git a/crates/ui-egui/src/i18n/es.tsv b/crates/ui-egui/src/i18n/es.tsv index 709155b3a..ef53c9455 100644 --- a/crates/ui-egui/src/i18n/es.tsv +++ b/crates/ui-egui/src/i18n/es.tsv @@ -3137,6 +3137,7 @@ Vertical % % vertical Vertical Align Bottom Alinear abajo verticalmente Vertical Align Center Alinear centros verticalmente + Horizontal & Vertical Align Center Alinear centros horizontal y verticalmente Vertical Align Top Alinear arriba verticalmente Vertical Area Type Tool Herramienta Texto de área vertical Vertical Distribute Bottom Distribuir abajo verticalmente diff --git a/crates/ui-egui/src/i18n/fr.tsv b/crates/ui-egui/src/i18n/fr.tsv index 304db7db5..facbc9465 100644 --- a/crates/ui-egui/src/i18n/fr.tsv +++ b/crates/ui-egui/src/i18n/fr.tsv @@ -3134,6 +3134,7 @@ Vertical % % vertical Vertical Align Bottom Alignement vertical en bas Vertical Align Center Alignement vertical au centre + Horizontal & Vertical Align Center Alignement centré horizontal et vertical Vertical Align Top Alignement vertical en haut Vertical Area Type Tool Outil Texte captif vertical Vertical Distribute Bottom Répartition verticale en bas diff --git a/crates/ui-egui/src/i18n/it.tsv b/crates/ui-egui/src/i18n/it.tsv index d897e5446..2b9111282 100644 --- a/crates/ui-egui/src/i18n/it.tsv +++ b/crates/ui-egui/src/i18n/it.tsv @@ -3137,6 +3137,7 @@ Vertical % % verticale Vertical Align Bottom Allinea verticalmente in basso Vertical Align Center Allinea verticalmente al centro + Horizontal & Vertical Align Center Allinea centri orizzontalmente e verticalmente Vertical Align Top Allinea verticalmente in alto Vertical Area Type Tool Strumento Testo in area verticale Vertical Distribute Bottom Distribuisci verticalmente i bordi inferiori diff --git a/crates/ui-egui/src/i18n/ja.tsv b/crates/ui-egui/src/i18n/ja.tsv index 601504ce5..7657db854 100644 --- a/crates/ui-egui/src/i18n/ja.tsv +++ b/crates/ui-egui/src/i18n/ja.tsv @@ -173,6 +173,7 @@ Horizontal Align Right 水平方向右に整列 Vertical Align Top 垂直方向上に整列 Vertical Align Center 垂直方向中央に整列 + Horizontal & Vertical Align Center 水平方向および垂直方向中央に整列 Vertical Align Bottom 垂直方向下に整列 Group グループ Ungroup グループ解除 diff --git a/crates/ui-egui/src/i18n/pt-br.tsv b/crates/ui-egui/src/i18n/pt-br.tsv index 40eb16d53..1312a8ea4 100644 --- a/crates/ui-egui/src/i18n/pt-br.tsv +++ b/crates/ui-egui/src/i18n/pt-br.tsv @@ -2566,6 +2566,7 @@ Vertical Vertical Vertical Align Bottom Alinhar Inferior Verticalmente Vertical Align Center Alinhar Centro Verticalmente + Horizontal & Vertical Align Center Alinhar Centro Horizontal e Verticalmente Vertical Align Top Alinhar Superior Verticalmente Vertical Area Type Tool Ferramenta Texto Vertical de Área Vertical Distribute Space Distribuir Espaço Verticalmente diff --git a/crates/ui-egui/src/i18n/ru.tsv b/crates/ui-egui/src/i18n/ru.tsv index 1c39b1954..db352d378 100644 --- a/crates/ui-egui/src/i18n/ru.tsv +++ b/crates/ui-egui/src/i18n/ru.tsv @@ -3133,6 +3133,7 @@ Vertical % По вертикали, % Vertical Align Bottom Выровнять по нижнему краю по вертикали Vertical Align Center Выровнять по центру по вертикали + Horizontal & Vertical Align Center Выровнять по центру по горизонтали и вертикали Vertical Align Top Выровнять по верхнему краю по вертикали Vertical Area Type Tool Инструмент «Вертикальный текст в области» Vertical Distribute Bottom Распределить по нижнему краю по вертикали diff --git a/crates/ui-egui/src/i18n/uk.tsv b/crates/ui-egui/src/i18n/uk.tsv index 1cc41bcbc..ff91b1c00 100644 --- a/crates/ui-egui/src/i18n/uk.tsv +++ b/crates/ui-egui/src/i18n/uk.tsv @@ -3130,6 +3130,7 @@ effect Points Точки Vertical % По вертикалі, % Vertical Align Bottom Вирівняти по нижньому краю по вертикалі Vertical Align Center Вирівняти по центру по вертикалі + Horizontal & Vertical Align Center Вирівняти по центру по горизонталі й вертикалі Vertical Align Top Вирівняти по верхньому краю по вертикалі Vertical Area Type Tool Інструмент «Вертикальний текст в області» Vertical Distribute Bottom Розподілити по нижньому краю по вертикалі diff --git a/crates/ui-egui/src/i18n/zh-hans.tsv b/crates/ui-egui/src/i18n/zh-hans.tsv index 84bbf15ba..13f8093fd 100644 --- a/crates/ui-egui/src/i18n/zh-hans.tsv +++ b/crates/ui-egui/src/i18n/zh-hans.tsv @@ -3028,6 +3028,7 @@ Vertical % 垂直 % Vertical Align Bottom 垂直底对齐 Vertical Align Center 垂直居中对齐 + Horizontal & Vertical Align Center 水平和垂直居中对齐 Vertical Align Top 垂直顶对齐 Vertical Area Type Tool 直排区域文字工具 Vertical Distribute Bottom 垂直分布下缘 diff --git a/crates/ui-egui/src/i18n/zh-hant.tsv b/crates/ui-egui/src/i18n/zh-hant.tsv index adf8089ba..bde581475 100644 --- a/crates/ui-egui/src/i18n/zh-hant.tsv +++ b/crates/ui-egui/src/i18n/zh-hant.tsv @@ -3121,6 +3121,7 @@ Vertical % 垂直 % Vertical Align Bottom 垂直靠下對齊 Vertical Align Center 垂直置中對齊 + Horizontal & Vertical Align Center 水平和垂直置中對齊 Vertical Align Top 垂直靠上對齊 Vertical Area Type Tool 垂直區域文字工具 Vertical Distribute Bottom 垂直均分下緣 diff --git a/crates/ui-egui/src/icon_data.rs b/crates/ui-egui/src/icon_data.rs index f2a97a7c2..016b47227 100644 --- a/crates/ui-egui/src/icon_data.rs +++ b/crates/ui-egui/src/icon_data.rs @@ -31,6 +31,7 @@ pub static ICONS: &[(&str, &[u8])] = &[ ("copy", include_bytes!("../../../assets/icons/copy.svg")), ("dc-actions", include_bytes!("../../../assets/icons/dc-actions.svg")), ("dc-al-bottom", include_bytes!("../../../assets/icons/dc-al-bottom.svg")), + ("dc-al-center", include_bytes!("../../../assets/icons/dc-al-center.svg")), ("dc-al-hcenter", include_bytes!("../../../assets/icons/dc-al-hcenter.svg")), ("dc-al-left", include_bytes!("../../../assets/icons/dc-al-left.svg")), ("dc-al-right", include_bytes!("../../../assets/icons/dc-al-right.svg")), diff --git a/crates/ui-egui/src/menus.rs b/crates/ui-egui/src/menus.rs index 6bf171aec..2072d292b 100644 --- a/crates/ui-egui/src/menus.rs +++ b/crates/ui-egui/src/menus.rs @@ -2151,6 +2151,9 @@ pub fn menu_tree_named(english_names: bool) -> Vec<(&'static str, Vec)> { cp("Horizontal Align Left", "object.align", json!({"horizontal": "left"})), cp("Horizontal Align Center", "object.align", json!({"horizontal": "center"})), cp("Horizontal Align Right", "object.align", json!({"horizontal": "right"})), + Sep, + cp("Horizontal & Vertical Align Center", "object.align", json!({"horizontal": "center", "vertical": "center"})), + Sep, cp("Vertical Align Top", "object.align", json!({"vertical": "top"})), cp("Vertical Align Center", "object.align", json!({"vertical": "center"})), cp("Vertical Align Bottom", "object.align", json!({"vertical": "bottom"})), diff --git a/crates/ui-egui/src/panels/align.rs b/crates/ui-egui/src/panels/align.rs index 40b9d23a4..a24f191f1 100644 --- a/crates/ui-egui/src/panels/align.rs +++ b/crates/ui-egui/src/panels/align.rs @@ -58,14 +58,20 @@ pub const DISTRIBUTE: [(&str, &str, &str, &str); 6] = [ 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 [ + for (i, (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"), - ] { + ] + .into_iter() + .enumerate() + { + if i == 3 && widgets::icon_button(ui, "dc-al-center", tl!("Horizontal & Vertical Align Center"), false, size).clicked() { + app.run("object.align", align_params(json!({"horizontal": "center", "vertical": "center"}), to, n)).ok(); + } if widgets::icon_button(ui, icon, tl!(tip), false, size).clicked() { app.run("object.align", align_params(json!({axis: v}), to, n)).ok(); } @@ -98,6 +104,10 @@ pub fn show(app: &mut VectorcraftApp, ui: &mut Ui) { for (i, (icon, tip, axis, v)) in ALIGN.iter().enumerate() { if i == 3 { ui.add_space(6.0); + if widgets::icon_button_enabled(ui, "dc-al-center", tl!("Horizontal & Vertical Align Center"), false, n >= 1, 32.0).clicked() { + app.run("object.align", align_params(json!({"horizontal": "center", "vertical": "center"}), to, n)).ok(); + } + ui.add_space(6.0); } if widgets::icon_button_enabled(ui, icon, tl!(tip), false, n >= 1, 32.0).clicked() { app.run("object.align", align_params(json!({*axis: v}), to, n)).ok(); @@ -247,6 +257,14 @@ mod tests { assert_eq!(bounds(&app).x0, 0.0, "the artboard's left edge"); } + #[test] + fn align_both_centers_params() { + let p = align_params(json!({"horizontal": "center", "vertical": "center"}), AlignTo::Selection, 2); + assert_eq!(p["horizontal"], "center"); + assert_eq!(p["vertical"], "center"); + assert_eq!(p["to"], "selection"); + } + /// #541: while the selection has a key object Align aligns to it, whatever Align To says; /// choosing Align to Selection lets the key go. #[test]