Merge pull request #4985 from dotCooCoo/feat/properties-objects-on-path-options

Properties: an Objects on Path group shows Objects on Path Options with Pivot and Rotate
This commit is contained in:
BFlat
2026-11-01 05:29:15 +07:00
committed by GitHub
29 changed files with 177 additions and 34 deletions
+1 -1
View File
@@ -1425,9 +1425,9 @@ font-technology Variable Променливи
Objects on Path Обекти по пътя
Attach Прикрепяне
Objects on Path Options Опции за обекти по пътя
Objects on Path Tool Инструмент „Обекти по пътя“
Pivot: Опорна точка:
Rotate: Завъртане:
Objects on Path Tool Инструмент „Обекти по пътя“
Attach Objects on Path Прикрепяне на обекти към пътя
Expand Objects on Path Разширяване на обекти по пътя
Release Live Paint Освобождаване на динамично оцветяване
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2 -2
View File
@@ -1609,9 +1609,9 @@ digits Malayalam Malajalam
Objects on Path Objekti na putanji
Attach Priloži
Objects on Path Options Opcije objekata na putanji
Objects on Path Tool Alat objekti na putanji
Pivot: Tačka okretanja:
Pivot: Tačka oslonca:
Rotate: Rotacija:
Objects on Path Tool Alat objekti na putanji
Attach Objects on Path Priloži objekte na putanju
Expand Objects on Path Proširi objekte na putanji
Release Live Paint Oslobodi živo bojenje
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1 -1
View File
@@ -2639,9 +2639,9 @@ digits Malayalam Malaiàlam
Objects Objectes
Objects on Path Objectes sobre el traçat
Objects on Path Options Opcions dels objectes sobre el traçat
Objects on Path Tool Eina d’objectes sobre el traçat
Pivot: Punt de pivot:
Rotate: Rotació:
Objects on Path Tool Eina d’objectes sobre el traçat
Objects using them keep their look but are no longer linked. Els objectes que les utilitzen conserven l’aspecte, però ja no estan enllaçats.
Ocean Ripple Onada oceànica
Ocean Ripple… Onada oceànica…
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1 -1
View File
@@ -1635,9 +1635,9 @@ digits Malayalam Malajálamské
Objects on Path Objekty na cestě
Attach Připojit
Objects on Path Options Možnosti objektů na cestě
Objects on Path Tool Nástroj Objekty na cestě
Pivot: Otočný bod:
Rotate: Otočení:
Objects on Path Tool Nástroj Objekty na cestě
Attach Objects on Path Připojit objekty na cestu
Expand Objects on Path Rozložit objekty na cestě
Release Live Paint Uvolnit živou malbu
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1 -1
View File
@@ -5395,9 +5395,9 @@ swatch Bright Violet Kraftig violet
Objects on Path Objekter på kurve
Attach Tilknyt
Objects on Path Options Indstillinger for objekter på kurve
Objects on Path Tool Objekter på kurve-værktøj
Pivot: Omdrejningspunkt:
Rotate: Rotation:
Objects on Path Tool Objekter på kurve-værktøj
Attach Objects on Path Tilknyt objekter til kurve
Expand Objects on Path Udvid objekter på kurve
Release Live Paint Frigør live-maling
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1 -1
View File
@@ -1459,9 +1459,9 @@ file-filter Templates Vorlagen
Objects on Path Objekte auf Pfad
Attach Anhängen
Objects on Path Options Optionen für Objekte auf Pfad
Objects on Path Tool Objekte-auf-Pfad-Werkzeug
Pivot: Drehpunkt:
Rotate: Drehung:
Objects on Path Tool Objekte-auf-Pfad-Werkzeug
Attach Objects on Path Objekte an Pfad anhängen
Expand Objects on Path Objekte auf Pfad umwandeln
Release Live Paint „Interaktiv malen“ zurückwandeln
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1 -1
View File
@@ -1389,9 +1389,9 @@ font-technology Variable Μεταβλητές
Objects on Path Αντικείμενα σε διαδρομή
Attach Προσάρτηση
Objects on Path Options Επιλογές αντικειμένων σε διαδρομή
Objects on Path Tool Αντικείμενα σε διαδρομή (Objects on Path Tool)
Pivot: Σημείο περιστροφής:
Rotate: Περιστροφή:
Objects on Path Tool Αντικείμενα σε διαδρομή (Objects on Path Tool)
Attach Objects on Path Προσάρτηση αντικειμένων σε διαδρομή
Expand Objects on Path Επέκταση αντικειμένων σε διαδρομή
Release Live Paint Αποδέσμευση δυναμικής βαφής
Can't render this file because it contains an unexpected character in line 164 and column 5.
+1 -1
View File
@@ -1463,9 +1463,9 @@ font-technology Variable Variables
Objects on Path Objetos en trazado
Attach Adjuntar
Objects on Path Options Opciones de objetos en trazado
Objects on Path Tool Herramienta Objetos en trazado
Pivot: Pivote:
Rotate: Rotación:
Objects on Path Tool Herramienta Objetos en trazado
Attach Objects on Path Adjuntar objetos al trazado
Expand Objects on Path Expandir objetos en trazado
Release Live Paint Soltar pintura interactiva
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2 -2
View File
@@ -1608,9 +1608,9 @@ digits Malayalam Malajalam
Objects on Path Objektit polulla
Attach Kiinnitä
Objects on Path Options Objektit polulla -asetukset
Objects on Path Tool Objektit polulla -työkalu
Pivot: Kiertopiste:
Pivot: Kiintopiste:
Rotate: Kierto:
Objects on Path Tool Objektit polulla -työkalu
Attach Objects on Path Kiinnitä objektit polulle
Expand Objects on Path Laajenna objektit polulla
Release Live Paint Vapauta elävä maalaus
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1 -1
View File
@@ -1463,9 +1463,9 @@ font-technology Variable Variables
Objects on Path Objets sur tracé
Attach Attacher
Objects on Path Options Options d’objets sur tracé
Objects on Path Tool Outil Objets sur tracé
Pivot: Pivot :
Rotate: Rotation :
Objects on Path Tool Outil Objets sur tracé
Attach Objects on Path Attacher des objets au tracé
Expand Objects on Path Décomposer les objets sur tracé
Release Live Paint Annuler la peinture dynamique
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1 -1
View File
@@ -1860,9 +1860,9 @@ file-filter Templates Sablonok
Objects on Path Objektumok útvonalon
Attach Csatolás
Objects on Path Options Objektumok útvonalon beállításai
Objects on Path Tool Objektumok útvonalon
Pivot: Forgáspont:
Rotate: Elforgatás:
Objects on Path Tool Objektumok útvonalon
Attach Objects on Path Objektumok csatolása útvonalhoz
Expand Objects on Path Objektumok útvonalon kibontása
Release Live Paint Élő festés megszüntetése
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2 -2
View File
@@ -5395,9 +5395,9 @@ swatch Bright Violet Violet cerah
Objects on Path Objek pada jalur
Attach Tempelkan
Objects on Path Options Opsi objek pada jalur
Objects on Path Tool Alat objek pada jalur
Pivot: Titik poros:
Pivot: Titik pivot:
Rotate: Rotasi:
Objects on Path Tool Alat objek pada jalur
Attach Objects on Path Tempelkan objek pada jalur
Expand Objects on Path Perluas objek pada jalur
Release Live Paint Lepaskan Live Paint
Can't render this file because it contains an unexpected character in line 2185 and column 5.
+1 -1
View File
@@ -1483,9 +1483,9 @@ file-filter Templates Modelli
Objects on Path Oggetti su tracciato
Attach Aggancia
Objects on Path Options Opzioni oggetti su tracciato
Objects on Path Tool Strumento Oggetti su tracciato
Pivot: Perno:
Rotate: Rotazione:
Objects on Path Tool Strumento Oggetti su tracciato
Attach Objects on Path Aggancia oggetti al tracciato
Expand Objects on Path Espandi oggetti su tracciato
Release Live Paint Rilascia pittura dinamica
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1 -1
View File
@@ -1773,9 +1773,9 @@ digits Malayalam マラヤーラム数字
Objects on Path パス上のオブジェクト
Attach アタッチ
Objects on Path Options パス上のオブジェクトオプション
Objects on Path Tool パス上のオブジェクトツール
Pivot: ピボット:
Rotate: 回転:
Objects on Path Tool パス上のオブジェクトツール
Attach Objects on Path パス上のオブジェクトをアタッチ
Expand Objects on Path パス上のオブジェクトを拡張
Release Live Paint ライブペイントを解除
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1 -1
View File
@@ -5301,9 +5301,9 @@ imageTrace Outline კონტური
Objects on Path ობიექტები ტრაექტორიაზე
Attach მიმაგრება
Objects on Path Options ტრაექტორიაზე ობიექტების პარამეტრები
Objects on Path Tool ტრაექტორიაზე ობიექტების ხელსაწყო
Pivot: საყრდენი წერტილი:
Rotate: შემობრუნება:
Objects on Path Tool ტრაექტორიაზე ობიექტების ხელსაწყო
Attach Objects on Path ობიექტების ტრაექტორიაზე მიმაგრება
Expand Objects on Path ტრაექტორიაზე ობიექტების გაშლა
Release Live Paint ცოცხალი შეღებვის მოხსნა
Can't render this file because it is too large.
+1 -1
View File
@@ -1763,9 +1763,9 @@ digits Malayalam 말라얄람어
Objects on Path 패스 위 개체
Attach 부착
Objects on Path Options 패스 위 개체 옵션
Objects on Path Tool 패스 위 개체 도구
Pivot: 피벗:
Rotate: 회전:
Objects on Path Tool 패스 위 개체 도구
Attach Objects on Path 패스 위 개체 부착
Expand Objects on Path 패스 위 개체 확장
Release Live Paint 라이브 페인트 해제
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1 -1
View File
@@ -5406,9 +5406,9 @@ swatch Bright Violet Felviolet
Objects on Path Objecten op pad
Attach Koppelen
Objects on Path Options Opties voor objecten op pad
Objects on Path Tool Objecten-op-pad-gereedschap
Pivot: Draaipunt:
Rotate: Rotatie:
Objects on Path Tool Objecten-op-pad-gereedschap
Attach Objects on Path Objecten aan pad koppelen
Expand Objects on Path Objecten op pad uitbreiden
Release Live Paint Live Paint vrijgeven
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1 -1
View File
@@ -1553,9 +1553,9 @@ digits Malayalam Malajalam
Objects on Path Obiekty na ścieżce
Attach Dołącz
Objects on Path Options Opcje obiektów na ścieżce
Objects on Path Tool Narzędzie Obiekty na ścieżce
Pivot: Punkt obrotu:
Rotate: Obrót:
Objects on Path Tool Narzędzie Obiekty na ścieżce
Attach Objects on Path Dołącz obiekty do ścieżki
Expand Objects on Path Rozszerz obiekty na ścieżce
Release Live Paint Uwolnij aktywne malowanie
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1 -1
View File
@@ -1269,9 +1269,9 @@
Objects on Path Objetos no Caminho
Attach Anexar
Objects on Path Options Opções de Objetos no Caminho
Objects on Path Tool Ferramenta Objetos no Caminho
Pivot: Pivô:
Rotate: Rotação:
Objects on Path Tool Ferramenta Objetos no Caminho
Attach Objects on Path Anexar Objetos ao Caminho
Expand Objects on Path Expandir Objetos no Caminho
Release Live Paint Liberar Pintura ao Vivo
Can't render this file because it contains an unexpected character in line 6 and column 47.
+2 -2
View File
@@ -1481,9 +1481,9 @@ file-filter Templates Шаблоны
Objects on Path Объекты на контуре
Attach Прикрепить
Objects on Path Options Параметры объектов на контуре
Objects on Path Tool Инструмент «Объекты на контуре»
Pivot: Опорная точка:
Pivot: Точка опоры:
Rotate: Поворот:
Objects on Path Tool Инструмент «Объекты на контуре»
Attach Objects on Path Прикрепить объекты к контуру
Expand Objects on Path Разобрать объекты на контуре
Release Live Paint Освободить быструю заливку
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1 -1
View File
@@ -1427,9 +1427,9 @@ font-technology Variable Variabla
Objects on Path Objekt på bana
Attach Fäst
Objects on Path Options Alternativ för objekt på bana
Objects on Path Tool Verktyg för objekt på bana
Pivot: Pivotpunkt:
Rotate: Rotation:
Objects on Path Tool Verktyg för objekt på bana
Attach Objects on Path Fäst objekt på bana
Expand Objects on Path Expandera objekt på bana
Release Live Paint Släpp direktmålning
Can't render this file because it contains an unexpected character in line 5 and column 25.
+2 -2
View File
@@ -5374,9 +5374,9 @@ theme Appearance Görünüm
Note Paper… Not Kâğıdı…
Objects on Path Yol Üzerindeki Nesneler
Objects on Path Options Yol Üzerindeki Nesneler Seçenekleri
Objects on Path Tool Yol Üzerindeki Nesneler Aracı
Pivot: Pivot noktası:
Rotate: Döndürme:
Rotate: Rotasyon:
Objects on Path Tool Yol Üzerindeki Nesneler Aracı
Photocopy Fotokopi
Photocopy… Fotokopi…
Plaster Alçı
Can't render this file because it contains an unexpected character in line 5 and column 25.
+2 -2
View File
@@ -1477,9 +1477,9 @@ file-filter Templates Шаблони
Objects on Path Об’єкти на контурі
Attach Прикріпити
Objects on Path Options Параметри об’єктів на контурі
Objects on Path Tool Інструмент «Об’єкти на контурі»
Pivot: Опорна точка:
Pivot: Точка опори:
Rotate: Поворот:
Objects on Path Tool Інструмент «Об’єкти на контурі»
Attach Objects on Path Прикріпити об’єкти до контуру
Expand Objects on Path Розібрати об’єкти на контурі
Release Live Paint Звільнити швидку заливку
Can't render this file because it contains an unexpected character in line 178 and column 5.
+2 -2
View File
@@ -1700,9 +1700,9 @@ digits Hindi Hindi
Objects on Path Đối tượng trên đường dẫn
Attach Gắn
Objects on Path Options Tùy chọn đối tượng trên đường dẫn
Objects on Path Tool Công cụ Đối tượng trên đường dẫn
Pivot: Điểm trục:
Pivot: Điểm xoay:
Rotate: Xoay:
Objects on Path Tool Công cụ Đối tượng trên đường dẫn
Attach Objects on Path Gắn đối tượng lên đường dẫn
Expand Objects on Path Mở rộng đối tượng trên đường dẫn
Release Live Paint Giải phóng tô trực tiếp
Can't render this file because it contains an unexpected character in line 200 and column 5.
+1 -1
View File
@@ -1411,9 +1411,9 @@ file-filter Templates 模板
Objects on Path 路径上的对象
Attach 附加
Objects on Path Options 路径上的对象选项
Objects on Path Tool 路径上的对象工具
Pivot: 枢轴:
Rotate: 旋转:
Objects on Path Tool 路径上的对象工具
Attach Objects on Path 附加路径上的对象
Expand Objects on Path 扩展路径上的对象
Release Live Paint 释放实时上色
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1 -1
View File
@@ -1448,9 +1448,9 @@ file-filter Templates 範本
Objects on Path 路徑上的物件
Attach 附加
Objects on Path Options 路徑上的物件選項
Objects on Path Tool 路徑上的物件工具
Pivot: 樞軸:
Rotate: 旋轉:
Objects on Path Tool 路徑上的物件工具
Attach Objects on Path 附加路徑上的物件
Expand Objects on Path 展開路徑上的物件
Release Live Paint 釋放即時上色
Can't render this file because it contains an unexpected character in line 6 and column 47.
+69
View File
@@ -65,6 +65,10 @@ pub fn show(app: &mut VectorcraftApp, ui: &mut Ui) {
trace_section(app, ui, &preset, view);
divider(ui);
}
if let Some(oop) = selected_objects_on_path(app) {
objects_on_path_section(app, ui, &oop);
divider(ui);
}
if matches!(first.as_ref().map(|n| &n.kind), Some(NodeKind::Text(_))) {
type_sections(app, ui);
divider(ui);
@@ -359,6 +363,71 @@ fn trace_section(app: &mut VectorcraftApp, ui: &mut Ui, preset: &str, view: vect
});
}
/// The Objects on Path groups selected with nothing else: their ids, and the Pivot and Rotate they
/// share (`None` where they differ).
struct ObjectsOnPathSelection {
ids: Vec<u64>,
pivot: Option<u8>,
rotate: Option<f64>,
}
/// The selection as Objects on Path groups ([`ObjectsOnPathSelection`]), when every selected
/// object is one.
fn selected_objects_on_path(app: &VectorcraftApp) -> Option<ObjectsOnPathSelection> {
let st = app.session.active()?;
let mut out: Option<ObjectsOnPathSelection> = None;
for id in &st.selection.objects {
let rec = st.doc.node(*id)?.extras().objects_on_path.as_deref()?;
match &mut out {
None => out = Some(ObjectsOnPathSelection { ids: vec![id.0], pivot: Some(rec.pivot), rotate: Some(rec.rotate) }),
Some(s) => {
s.ids.push(id.0);
if s.pivot != Some(rec.pivot) {
s.pivot = None;
}
if s.rotate != Some(rec.rotate) {
s.rotate = None;
}
}
}
}
out
}
/// The Objects on Path Options of the selected Objects on Path groups: Pivot, the point of each
/// object that attaches to the path, and Rotate, the angle each object tilts by from upright on the
/// path, as the help page places them in the Properties panel
/// (<https://helpx.adobe.com/illustrator/using/objects-on-path.html>). A change goes to every
/// selected group in one undo step (`object.objectsOnPath.options`). Where the groups differ, no
/// Pivot square is chosen and Rotate is blank.
fn objects_on_path_section(app: &mut VectorcraftApp, ui: &mut Ui, oop: &ObjectsOnPathSelection) {
section_header(ui, tl!("Objects on Path Options"));
let fw = super::field_width(ui);
let set = |app: &mut VectorcraftApp, mut p: serde_json::Value| {
p["ids"] = json!(oop.ids);
if let Err(e) = app.run("object.objectsOnPath.options", p) {
app.status(e);
}
};
egui::Grid::new("props-objects-on-path").num_columns(2).spacing([6.0, 6.0]).show(ui, |ui| {
dim_label(ui, tl!("Pivot:"));
// 9 is no square: the groups' pivots differ.
if let Some(i) = widgets::reference_point(ui, oop.pivot.map_or(9, usize::from))
&& oop.pivot.is_none_or(|p| usize::from(p) != i)
{
set(app, json!({ "pivot": i }));
}
ui.end_row();
dim_label(ui, tl!("Rotate:"));
if let Some(a) = widgets::spin_plain(ui, "props-oop-rotate", oop.rotate, "°", 2, fw, 15.0, -360.0, &super::transform::ANGLE_PRESETS)
&& oop.rotate != Some(a)
{
set(app, json!({ "rotate": a }));
}
ui.end_row();
});
}
/// Whether the selection uses more than one colour (`recolor.colors`), which offers the Recolor
/// quick action; cached per document revision.
fn multi_color(app: &mut VectorcraftApp, ctx: &egui::Context) -> bool {
@@ -1684,3 +1684,77 @@ fn reset_is_a_quick_action_for_a_changed_dynamic_instance() {
assert!(app.session.doc().unwrap().doc.node(id).unwrap().extras().symbol_overrides.is_empty());
assert!(!shows(&tall(&mut app, &ctx, vec![]), "Reset"));
}
/// Two 20 pt squares attached to a horizontal line in an Objects on Path group (`rotate` degrees),
/// with the group selected → the group.
fn objects_on_path(app: &mut VectorcraftApp, y: f64, rotate: f64) -> Value {
let line = app.run("shape.line", json!({"x1": 20, "y1": y, "x2": 380, "y2": y})).unwrap()["id"].clone();
let a = rect(app, 40.0, y - 60.0, 20.0, 20.0);
let b = rect(app, 80.0, y - 60.0, 20.0, 20.0);
app.run("select.set", json!({"ids": [a, b]})).unwrap();
let group = app.run("object.objectsOnPath.attach", json!({"path": line, "rotate": rotate})).unwrap()["id"].clone();
app.run("select.set", json!({"ids": [group]})).unwrap();
group
}
/// The Pivot and Rotate of the Objects on Path group `id`.
fn pivot_rotate(app: &VectorcraftApp, id: &Value) -> (u8, f64) {
let d = &app.session.active().unwrap().doc;
let rec = d.node(vectorcraft_doc::NodeId(id.as_u64().unwrap())).unwrap().extras().objects_on_path.as_deref().unwrap();
(rec.pivot, rec.rotate)
}
/// The Objects on Path Options section alone.
fn objects_on_path_options(app: &mut VectorcraftApp, ui: &mut Ui) {
if let Some(oop) = selected_objects_on_path(app) {
objects_on_path_section(app, ui, &oop);
}
}
/// The help page's Objects on Path Options section of the Properties panel shows for an Objects on
/// Path group selected on its own or with other such groups, and not for a plain group, an object
/// or an Objects on Path group selected with another object.
#[test]
fn objects_on_path_groups_show_objects_on_path_options() {
let mut app = new_app();
let ctx = egui::Context::default();
let group = objects_on_path(&mut app, 150.0, 0.0);
let texts = tall(&mut app, &ctx, vec![]);
assert!(shows(&texts, "Objects on Path Options") && shows(&texts, "Pivot:") && shows(&texts, "Rotate:"), "one group: {texts:?}");
let other = objects_on_path(&mut app, 250.0, 0.0);
app.run("select.set", json!({"ids": [group, other]})).unwrap();
assert!(shows(&tall(&mut app, &ctx, vec![]), "Objects on Path Options"), "two groups");
let r = rect(&mut app, 300.0, 20.0, 40.0, 40.0);
app.run("select.set", json!({"ids": [group, r]})).unwrap();
assert!(!shows(&tall(&mut app, &ctx, vec![]), "Objects on Path Options"), "a group and a rectangle");
app.run("select.set", json!({"ids": [r]})).unwrap();
assert!(!shows(&tall(&mut app, &ctx, vec![]), "Objects on Path Options"), "a rectangle");
let s = rect(&mut app, 340.0, 20.0, 20.0, 20.0);
app.run("select.set", json!({"ids": [r, s]})).unwrap();
app.run("object.group", json!({})).unwrap();
assert!(!shows(&tall(&mut app, &ctx, vec![]), "Objects on Path Options"), "a plain group");
}
/// A click on a Pivot square and a typed Rotate each set the selected groups' Objects on Path
/// Options in one undo step: one group's, and two groups' at once, where Rotate starts blank as
/// the groups' angles differ.
#[test]
fn objects_on_path_options_set_pivot_and_rotate_in_one_undo_step() {
let (mut app, ctx) = reference_setup(&[]);
let group = objects_on_path(&mut app, 150.0, 0.0);
let depth = undo_depth(&app);
click_named(&mut app, &ctx, objects_on_path_options, "Top Left");
assert_eq!(pivot_rotate(&app, &group), (0, 0.0), "Pivot: top left");
assert_eq!(undo_depth(&app), depth + 1, "one undo step");
type_over(&mut app, &ctx, objects_on_path_options, "0°", "30");
assert_eq!(pivot_rotate(&app, &group), (0, 30.0), "Rotate: 30°");
assert_eq!(undo_depth(&app), depth + 2, "one undo step");
let other = objects_on_path(&mut app, 250.0, 45.0);
app.run("select.set", json!({"ids": [group, other]})).unwrap();
let texts = panel_frame(&mut app, &ctx, vec![], objects_on_path_options);
assert!(!shows(&texts, "30°") && !shows(&texts, "45°"), "Rotate is blank: {texts:?}");
let depth = undo_depth(&app);
click_named(&mut app, &ctx, objects_on_path_options, "Bottom Right");
assert_eq!((pivot_rotate(&app, &group), pivot_rotate(&app, &other)), ((8, 30.0), (8, 45.0)), "both groups' Pivot");
assert_eq!(undo_depth(&app), depth + 1, "one undo step for both groups");
}
+1 -1
View File
@@ -930,7 +930,7 @@ Moved from the ROADMAP's "Shipped so far" on 2026-10-10. Update it when a featur
When the object the Blend tool picked first is deleted or undone away before the second click, the next click on an object picks that object first instead of doing nothing. Regression tests: `blend_tool_picks_again_when_its_first_pick_is_gone` in `meshblend.rs` and `the_blend_tool_picks_again_when_its_first_pick_is_deleted` in `tests/blendopts.rs`.
Window › Blend opens the Blend panel: Make, the selected blend's Spacing and Orientation (with no blend selected, the options new blends start with), Reverse Front to Back, Reverse Spine, Replace Spine, Expand and Release, each running its Object › Blend command. Make is dimmed until two or more objects are selected. Spacing and Orientation are dimmed until a blend or two or more objects are selected, and the other buttons are dimmed until a blend is selected.
With the Blend tool, Escape drops the object clicked first and stops the next click adding to the blend just made, so the next click picks a new first object; the document and the selection stay as they are. Regression tests: `escape_drops_the_blend_tools_first_pick` in `meshblend.rs` and `tests/blendopts.rs`.
Objects on Path (#2545): a click with the Objects on Path tool (in Edit Toolbar's Modify section and the Blend tool's flyout; Object › Objects on Path › Attach and the context menu with two or more objects selected choose it) attaches the selected objects to the path clicked, open or closed, in an Objects on Path group with the path at its bottom. The objects go along the path column by column from left to right, spread evenly from its first anchor (the last one sits on the end of an open path), each turned to the path at its attachment point; Pivot and Rotate set where each one attaches and how far it tilts (`object.objectsOnPath.attach`, `object.objectsOnPath.options`). Editing the path moves the objects, an object moved on its own goes back, objects moved into or out of the group in the Layers panel join or leave the path, and Object › Objects on Path › Expand leaves a plain group. The group saves and reopens live and exports as plain art. The Space, Move All, Rotate All and Select/Move widgets, Detach and the Properties panel section are missing.
Objects on Path (#2545): a click with the Objects on Path tool (in Edit Toolbar's Modify section and the Blend tool's flyout; Object › Objects on Path › Attach and the context menu with two or more objects selected choose it) attaches the selected objects to the path clicked, open or closed, in an Objects on Path group with the path at its bottom. The objects go along the path column by column from left to right, spread evenly from its first anchor (the last one sits on the end of an open path), each turned to the path at its attachment point; Pivot and Rotate set where each one attaches and how far it tilts (`object.objectsOnPath.attach`, `object.objectsOnPath.options`), and with Objects on Path groups selected the Properties panel's Objects on Path Options section shows them as a nine-point Pivot grid and a Rotate field with common angles, each change one undo step for every selected group. Editing the path moves the objects, an object moved on its own goes back, objects moved into or out of the group in the Layers panel join or leave the path, and Object › Objects on Path › Expand leaves a plain group. The group saves and reopens live and exports as plain art. The Space, Move All, Rotate All and Select/Move widgets and Detach are missing.
Double-clicking the Objects on Path tool opens Objects on Path Tool Options ([Objects on Path](https://helpx.adobe.com/illustrator/using/objects-on-path.html)): the nine-point Pivot grid and the Rotate field set the attachment point and angle of the objects attached next, and groups already attached keep theirs; Reset puts the center and 0° back. Save keeps the options across tool switches and saves them with the preferences (`tool.setOption {tool: "objectsOnPath"}`).
- **Paint and appearance (M3):**
- **CSS swatch libraries:** fractional linear and radial gradient stop positions are preserved, so nearby stops such as 12.5% and 12.890625% remain distinct instead of collapsing to 13%. Reference: [CSS Images 3 color stops](https://www.w3.org/TR/css-images-3/#color-stop-syntax). The original synthetic regression is `palette_io::tests::css_preserves_fractional_gradient_stop_positions` in `crates/color/src/palette_io.rs`. Scores and hours are unchanged.