From 655a16fa674b1d5c2a588907806eed03a6e000ea Mon Sep 17 00:00:00 2001 From: ruchirguitar <113586074+ruchirguitar@users.noreply.github.com> Date: Sun, 8 Nov 2026 17:02:29 +0530 Subject: [PATCH] #5925: add collapse arrows to floating panels and rail flyouts --- crates/ui-egui/src/panel_docking.rs | 50 +++++++- .../ui-egui/src/panel_docking/native_tests.rs | 28 +++++ crates/ui-egui/src/panel_docking/tests.rs | 115 ++++++++++++++++++ docs/gaps.md | 5 +- docs/roadmap.md | 5 +- docs/target-app-parity.md | 7 +- docs/ui-parity.md | 5 +- 7 files changed, 204 insertions(+), 11 deletions(-) diff --git a/crates/ui-egui/src/panel_docking.rs b/crates/ui-egui/src/panel_docking.rs index ff39d90cf..a479b227f 100644 --- a/crates/ui-egui/src/panel_docking.rs +++ b/crates/ui-egui/src/panel_docking.rs @@ -1414,13 +1414,53 @@ impl craft_ui::docking::DockContent for PanelContent<'_> { crate::panels::panel_menu_items(self.app, ui, id); } - fn group_header_width(&self, _panels: &[String], _active: &String, _floating: bool, _strip_width: f32) -> f32 { - 28.0 + fn group_header_width(&self, panels: &[String], _active: &String, floating: bool, _strip_width: f32) -> f32 { + let flyout = self.app.ui.open_panel.as_ref().is_some_and(|panel| panels.contains(panel)); + if floating || flyout { 52.0 } else { 28.0 } } - fn group_header(&mut self, ui: &mut egui::Ui, _panels: &[String], active: &String, _floating: bool) { - let rect = egui::Rect::from_center_size(ui.max_rect().center(), egui::vec2(16.0, 16.0)); - crate::panels::panel_menu(self.app, ui, active, rect); + fn group_header(&mut self, ui: &mut egui::Ui, panels: &[String], active: &String, floating: bool) { + let header = ui.max_rect(); + let flyout = self.app.ui.open_panel.clone().filter(|panel| panels.contains(panel)); + let menu_cell = if floating || flyout.is_some() { + let split = (header.right() - 28.0).max(header.left()); + let cell = egui::Rect::from_min_max(header.min, egui::pos2(split, header.bottom())); + if cell.is_positive() { + let rect = egui::Rect::from_center_size(cell.center(), egui::vec2(24.0_f32.min(cell.width()), 24.0_f32.min(cell.height()))); + let tokens = crate::theme::Tokens::get(ui.ctx()); + let response = ui.interact(rect, ui.scope_id().with(("collapse-to-icons", active)), egui::Sense::click()); + response.widget_info(|| egui::WidgetInfo::labeled(egui::Role::Button, ui.is_enabled(), tl!("Collapse to Icons"))); + let color = if response.hovered() || response.has_focus() { tokens.text_strong } else { tokens.text_dim }; + ui.painter().with_clip_rect(rect.intersect(ui.clip_rect())).text( + rect.center(), + egui::Align2::CENTER_CENTER, + "»", + egui::TextStyle::Button.resolve(ui.style()), + color, + ); + if response.on_hover_text(tl!("Collapse to Icons")).clicked() { + let result = if let Some(panel) = flyout { + // The opening icon can differ from the currently active tab. + self.app.run("window.panel", json!({"panel": panel})) + } else { + self.app.run("window.panel.dock", json!({"panel": active, "icon": true, "group": true})) + }; + match result { + // Dock commands reveal their destination. This control leaves the group collapsed. + Ok(_) => self.app.ui.open_panel = None, + Err(error) => self.app.ui.status = error, + } + } + } + egui::Rect::from_min_max(egui::pos2(split, header.top()), header.max) + } else { + header + }; + if menu_cell.is_positive() { + let rect = + egui::Rect::from_center_size(menu_cell.center(), egui::vec2(16.0_f32.min(menu_cell.width()), 16.0_f32.min(menu_cell.height()))); + crate::panels::panel_menu(self.app, ui, active, rect); + } } } diff --git a/crates/ui-egui/src/panel_docking/native_tests.rs b/crates/ui-egui/src/panel_docking/native_tests.rs index a7c661404..60130db74 100644 --- a/crates/ui-egui/src/panel_docking/native_tests.rs +++ b/crates/ui-egui/src/panel_docking/native_tests.rs @@ -1163,3 +1163,31 @@ fn wheel_without_a_move_uses_the_floating_viewports_pointer() { h.frame(vec![]); assert_ne!(h.app.run("text.fonts", json!({})).unwrap(), before); } + +#[test] +fn floating_collapse_arrow_in_a_native_window_moves_the_group_to_the_rail() { + let mut h = Harness::new(); + h.app.run("window.panel.float", json!({"panel": "layers", "group": true})).unwrap(); + h.app.run("window.panel.activate", json!({"panel": "layers"})).unwrap(); + h.frames(3); + let viewport = h.viewport("layers"); + h.host.borrow_mut().focus = viewport; + let arrow = h.host.borrow().windows[&viewport] + .texts + .iter() + .find(|(text, _)| text == "»") + .map(|(_, rect)| rect.center()) + .expect("the native floating header paints a collapse arrow"); + for pressed in [true, false] { + h.host.borrow_mut().windows.get_mut(&viewport).unwrap().events.extend([Event::PointerMoved(arrow), button(arrow, pressed)]); + h.frames(1); + } + h.frames(3); + let layout = layout_of(&h.app.ui); + assert!(floating_window(&layout, "layers").is_none()); + assert_eq!(group_of(&layout, &"layers".into()), ["properties", "layers", "libraries"]); + assert!(["properties", "layers", "libraries"].iter().all(|p| in_iconic_column(&layout, p))); + let frames = h.host.borrow().windows[&viewport].frames; + h.frames(3); + assert_eq!(h.host.borrow().windows[&viewport].frames, frames, "the emptied palette is no longer rendered"); +} diff --git a/crates/ui-egui/src/panel_docking/tests.rs b/crates/ui-egui/src/panel_docking/tests.rs index 60b59a2a8..7543beaca 100644 --- a/crates/ui-egui/src/panel_docking/tests.rs +++ b/crates/ui-egui/src/panel_docking/tests.rs @@ -759,3 +759,118 @@ fn other_function_keys_and_keyboard_guards_keep_their_routes() { assert_eq!(saved.session.doc().unwrap().doc.node_count(), 2, "F12 reloads the saved document"); std::fs::remove_dir_all(dir).unwrap(); } + +fn collapse_to_icons_button(h: &Harness, panel: &str) -> Option { + let panel = panel.to_string(); + h.ctx.read_response(area_id().with(("header", &panel)).with(("collapse-to-icons", &panel))).map(|r| r.rect) +} + +#[test] +fn floating_collapse_arrow_moves_the_whole_group_into_the_icon_rail() { + let mut h = Harness::new(); + assert!(collapse_to_icons_button(&h, "properties").is_none(), "docked headers have no extra button"); + h.app.run("window.panel.float", json!({"panel": "layers", "group": true})).unwrap(); + h.app.run("window.panel.activate", json!({"panel": "layers"})).unwrap(); + for _ in 0..3 { + h.frame(vec![]); + } + let before = h.layout(); + let members = group_of(&before, &"layers".into()); + let columns = end_columns(&before).len(); + let arrow = collapse_to_icons_button(&h, "layers").expect("floating header offers collapse to icons"); + assert!(arrow.width() <= 24.0 && arrow.height() <= 24.0, "a compact header control: {arrow:?}"); + h.click(arrow.center()); + let layout = h.layout(); + assert!(floating_window(&layout, "layers").is_none(), "the old floating window is removed"); + assert_eq!(group_of(&layout, &"layers".into()), members, "all tabs move together"); + assert!(members.iter().all(|p| in_iconic_column(&layout, p))); + assert_eq!(end_columns(&layout).len(), columns, "reuse the existing icon rail"); + assert!(h.app.ui.open_panel.is_none(), "the group stays collapsed until its icon is clicked"); + let icon = h.hit(&Hit::Icon("layers".into())).expect("Layers now has a rail icon"); + h.click(icon.center()); + assert_eq!(h.app.ui.open_panel.as_deref(), Some("layers")); + assert!(h.tab("layers").is_some(), "the collapsed group can reopen as a flyout"); + assert!(collapse_to_icons_button(&h, "layers").is_some(), "the reopened flyout also offers collapse to icons"); +} + +#[test] +fn floating_collapse_arrow_leaves_other_floating_groups_alone() { + let mut h = Harness::new(); + h.app.run("window.panel.float", json!({"panel": "layers"})).unwrap(); + h.app.run("window.panel.float", json!({"panel": "color", "below": "layers"})).unwrap(); + for _ in 0..3 { + h.frame(vec![]); + } + let arrow = collapse_to_icons_button(&h, "layers").expect("floating group has its own arrow"); + h.click(arrow.center()); + let layout = h.layout(); + assert!(in_iconic_column(&layout, "layers")); + assert!(floating_window(&layout, "color").is_some(), "another group in the same window stays floating"); + assert!(!in_iconic_column(&layout, "color")); + assert_eq!(main_panels(&layout), ["properties", "libraries"]); +} + +#[test] +fn floating_collapse_arrow_creates_a_rail_when_none_exists_and_keeps_the_menu() { + let mut h = Harness::new(); + h.app.run("window.panel.float", json!({"panel": "layers"})).unwrap(); + let mut layout = h.layout(); + if let Some(Node::Split { second, .. }) = layout.root.as_mut() + && let Node::Dock { columns, .. } = second.as_mut() + { + columns.retain(|column| !column.iconic); + } + assert!(icon_column(&end_columns(&layout)).is_none()); + h.app.ui.docking = Some(layout); + for _ in 0..3 { + h.frame(vec![]); + } + let panel = "layers".to_string(); + let menu = + h.ctx.read_response(area_id().with(("header", &panel)).with(("panel-menu", &panel))).expect("the existing panel menu remains available").rect; + let arrow = collapse_to_icons_button(&h, "layers").expect("floating group offers collapse"); + assert!(!menu.intersects(arrow), "menu and arrow have separate hit targets"); + h.click(menu.center()); + assert!(egui::Popup::is_any_open(&h.ctx), "the existing menu still opens"); + h.press(egui::Key::Escape, egui::Modifiers::NONE); + h.click(arrow.center()); + let layout = h.layout(); + assert!(in_iconic_column(&layout, "layers")); + assert!(floating_window(&layout, "layers").is_none()); + assert!(h.app.ui.open_panel.is_none(), "collapse does not immediately open a flyout"); + assert_eq!(main_panels(&layout), ["properties", "libraries"]); +} + +#[test] +fn rail_flyout_collapse_arrow_folds_the_panel_back_without_moving_it() { + let mut h = Harness::new(); + let icon = h.hit(&Hit::Icon("swatches".into())).unwrap(); + h.click(icon.center()); + let before = h.layout(); + let arrow = collapse_to_icons_button(&h, "swatches").expect("opened rail panels offer collapse to icons"); + h.click(arrow.center()); + assert!(h.app.ui.open_panel.is_none()); + assert!(craft_ui::docking::flyout::(&h.ctx, area_id()).is_none()); + assert_eq!(h.layout(), before, "folding a flyout leaves the dock layout intact"); + let icon = h.hit(&Hit::Icon("swatches".into())).expect("the rail icon stays available"); + h.click(icon.center()); + assert_eq!(h.app.ui.open_panel.as_deref(), Some("swatches")); + assert!(h.tab("swatches").is_some()); +} + +#[test] +fn rail_flyout_collapse_arrow_closes_the_opening_icon_after_switching_tabs() { + let mut h = Harness::new(); + h.app.ui.docking = Some(h.layout()); + let icon = h.hit(&Hit::Icon("swatches".into())).unwrap(); + h.click(icon.center()); + let brushes = h.tab("brushes").unwrap(); + h.click(brushes.center()); + assert_eq!(h.app.ui.open_panel.as_deref(), Some("swatches")); + let before = h.layout(); + let arrow = collapse_to_icons_button(&h, "brushes").expect("the active tab has a collapse arrow"); + h.click(arrow.center()); + assert!(h.app.ui.open_panel.is_none()); + assert!(craft_ui::docking::flyout::(&h.ctx, area_id()).is_none()); + assert_eq!(h.layout(), before, "all tabs and their active state stay in the rail"); +} diff --git a/docs/gaps.md b/docs/gaps.md index 6780782ab..176607212 100644 --- a/docs/gaps.md +++ b/docs/gaps.md @@ -1,6 +1,6 @@ # Gaps -> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-07 · **Change:** minor (Indian-language hyphenation review and license allowlist, #4947; opening a slow file shows a progress window, part of #5930; Hindi catalog and contributor loanword preferences; agent wording pass complete; wider native proofreading welcome; an image zoomed in on is separated, colorized or proofed only where it shows (#4155); scores and estimates unchanged; a document's first frame renders on the render worker, so opening a heavy file no longer freezes the window; scores and estimates unchanged; large images in CMYK documents are shrunk before they are separated into ink planes (#4155); scores and estimates unchanged; `.ai` paths with a Calligraphic brush open brushed, with the 6D Art Pen's channels, and Windows reads the pen's tilt and barrel rotation, #372; scores and estimates unchanged; Compound Shapes add-on, beyond Illustrator; scores and estimates unchanged; Contour add-on, beyond Illustrator; scores and estimates unchanged; a slow first frame is waited for instead of restarting without the graphics adapter, and the menu bar no longer waits for the installed fonts' scan; scores and estimates unchanged) · **Target:** Adobe Illustrator 2026 (30.x) +> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-08 · **Change:** minor (floating tab groups collapse into the side icon rail and opened rail panels fold back into it, #5925 in part; Indian-language hyphenation review and license allowlist, #4947; opening a slow file shows a progress window, part of #5930; Hindi catalog and contributor loanword preferences; agent wording pass complete; wider native proofreading welcome; an image zoomed in on is separated, colorized or proofed only where it shows (#4155); scores and estimates unchanged; a document's first frame renders on the render worker, so opening a heavy file no longer freezes the window; scores and estimates unchanged; large images in CMYK documents are shrunk before they are separated into ink planes (#4155); scores and estimates unchanged; `.ai` paths with a Calligraphic brush open brushed, with the 6D Art Pen's channels, and Windows reads the pen's tilt and barrel rotation, #372; scores and estimates unchanged; Compound Shapes add-on, beyond Illustrator; scores and estimates unchanged; Contour add-on, beyond Illustrator; scores and estimates unchanged; a slow first frame is waited for instead of restarting without the graphics adapter, and the menu bar no longer waits for the installed fonts' scan; scores and estimates unchanged) · **Target:** Adobe Illustrator 2026 (30.x) ## Feature submission evidence @@ -106,6 +106,8 @@ from G14 and the budget run of G15: **~170–270 h** one agent, ~50–80 h wall ## G1 Interaction fidelity +- **Panel collapse controls (#5925, in part):** The small » in a floating tab-group header moves that group into the side icon rail, reusing the existing rail or creating one. An opened rail panel has the same control to fold its flyout back into the rail, including after a tab switch. Both controls preserve the tab group and its menu; other floating groups and full-width docked headers stay as they were. Pointer regressions in `crates/ui-egui/src/panel_docking/tests.rs` cover grouped tabs, reopening, separate groups, a missing rail, the menu and flyout closure after switching tabs; `native_tests.rs` covers the native-window click and removal of the empty palette. Scores and estimates unchanged. + - **Done:** Distance Guides ([public page](https://helpx.adobe.com/illustrator/desktop/measure-and-align/grids-and-guides/use-distance-guides-for-accurate-placement.html)): with Smart Guides on and something selected, the Selection tool with Alt/Option held over another object shows the horizontal and vertical distances between them, and over an empty part of an artboard the selection's distances from its four edges, labelled in the General unit; Preferences › Smart Guides › Invoke Distance Guides turns them off. Hover only, as documented: not while moving or nudging. No entry closed; estimates unchanged. - **Done (part of #4028):** Recolor Artwork › Assign: double-clicking a row's new color opens the Color Picker, as the [public page](https://helpx.adobe.com/illustrator/desktop/manage-colors/modify-colors/assign-new-colors-to-selected-artwork.html) describes. OK sets the row's new color in the model it was picked in, so a CMYK mix is no longer a hex value converted back; Cancel leaves the row. A Lab new color is kept, but can't be typed yet: the picker's Lab fields work in RGB, as for fill and stroke. **Missing:** Lab entry in the picker, swatch libraries in the picker and the row's right-click menu (Pick from Swatches, Limit to Library). @@ -817,6 +819,7 @@ trap, and the defaults (0.25 pt, 100%, 40%) are VectorCraft's own, the pages giv | Date | Change | Summary | |---|---|---| +| 2026-11-08 | minor | Floating tab groups collapse into the side icon rail and opened rail panels fold back into it (#5925, in part); tab groups remain intact. Scores and estimates unchanged. | | 2026-11-06 | minor | Hindi (`hi`): 7,877-row machine-assisted catalog, zero/one singular plurals, desktop font fallback and optional Devanagari craft-fonts fallback; all 55 translation tests pass; native review and a web font remain; scores and estimates unchanged | | 2026-11-05 | minor | G15: nearby hits on plain long strokes and outlines check their candidate segments directly; a 200,000-anchor middle hit took about 11–13 ms before and 1.0–1.4 ms after in paired runs. An inside-bounds miss fell from 18.7 ms to 1.6 ms. Estimate unchanged; idle budget run still open. | | 2026-11-05 | minor | G15: an image zoomed in on is separated, colorized or proofed only for the tiles in view (#4155); 100% zoom on that file 8.6 s → 0.05 s. Estimate unchanged. | diff --git a/docs/roadmap.md b/docs/roadmap.md index c4246c711..944925518 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -1,6 +1,6 @@ # Roadmap: milestones and what's next -> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-07 · **Change:** minor (Indian-language hyphenation review and license allowlist, #4947; Hindi catalog and contributor loanword preferences; full wording review in progress; Effect dialogs: a colour swatch beside a hex colour opens the Color Picker, #5365; shape tools move the selection from its centre point and turn it from the zone outside a box corner, #5477; scores and estimates unchanged) · **Target:** Adobe Illustrator 2026 (30.x) +> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-08 · **Change:** minor (floating tab groups collapse into the side icon rail and opened rail panels fold back into it, #5925 in part; Indian-language hyphenation review and license allowlist, #4947; Hindi catalog and contributor loanword preferences; full wording review in progress; Effect dialogs: a colour swatch beside a hex colour opens the Color Picker, #5365; shape tools move the selection from its centre point and turn it from the zone outside a box corner, #5477; scores and estimates unchanged) · **Target:** Adobe Illustrator 2026 (30.x) ## Feature submission evidence @@ -143,7 +143,7 @@ native wording review, layout checks and a web Devanagari font remain. [Notes](l | M12 | Advanced color & art (CMYK/ICC, separations, Gradient Mesh, Live Paint, Image Trace, Graphs) | 🟡 Gradient Mesh, Live Paint, Image Trace (junction-returning pieces retain their positioned boundaries; a simpler contour walk with identical output; an edge's sub-pixel shift is the same from either side; notches read only their own piece; collapsed loops keep few segments; large images trace with a warning; Auto Color keeps rare distinct colours; quick presets trace at once and the Image Trace button opens the adjustment controls; Properties reopens them; tiny fitted contours retain islands and holes; Create Strokes: exact crop EDT, Guo–Hall thinning and maximal-disc graph simplification; 15 presets, the 14 documented ones each with an enhanced version; Ignore Color, Shapes, Auto Grouping and Gradients options; measured in `image-trace-quality.md`; closed outlines retain their interior after straightening; the Flat Logo mode places edges to a fraction of a pixel, restores sharp corners, snaps lines and circles, and refuses gradients; live trace result bounds and selection highlights exclude the retained bitmap except in source-image views), Recolor Artwork, colour management (ICC, soft proofing, separations preview), Graphs (all 9 tools, Graph Data/Type, group-selected series colours persist through regenerate/save/open) done; Graph Design and Marker designs, Transpose and Switch x/y, `\|` label line breaks, the pie options, drop shadows, the legend across the top, overlapping widths, First Row/Column in Front, filled lines, kept label formatting and the Graph Data worksheet done; graph Column designs pending | 6–10 | | M13 | Automation (Actions ✅ record/playback, persisted; variables, scripting, batch) | 🟡 MCP `add_text` exposes existing vertical point, area and path type; broader scripting and batch work remains | 18–27 | | M13 | Automation (Actions ✅ record/playback, persisted; variables, scripting, batch) | 🟡 | 18–27 | -| M14 | 1.0 polish (preferences, shortcut editor, workspaces, accessibility, packaging for all OSes) (status messages and readouts use stable responsive allocations sized for localized labels and ordinary coordinates; sample widths cached by language/unit/DPI; regression-tested and contributor-confirmed 2026-10-19; estimates unchanged) | 🟡 Dock groups collapse to their tabs by a double-click on a tab (UI.8); Preferences › General › Constrain Angle acts for the arrow keys, Shift drags and new objects (#394, 2026-10-21); numeric-field pointer selection and focus regression-tested (#1326, in part; short movements still select all); RPM runtime capabilities and glibc floor checked (#1275; real-distro install/start-up pending), Eyedropper cursor with precise-setting checks (#1269), Preferences, shortcut editor (chords with Shift and a punctuation key fire as typed; other apps' text shortcut sets imported), workspaces (each keeps its layout changes until Reset , UI.7), panels docked by dragging into any dock group (as tabs or a top/bottom split) or into the icon column, and closed from a dock tab's context menu (UI.6), a custom title bar on Windows/Linux with a Home button, content-sized dialogs, menus that scroll when longer than the window and macOS native menu dismissal done (M14.8), and native macOS save sheets with a Format menu (#866); titled PDF exports set `DisplayDocTitle` for viewers and accessibility checkers (#3646); accessibility and broader Windows/Linux packaging/QA pending | 18–28 | +| M14 | 1.0 polish (preferences, shortcut editor, workspaces, accessibility, packaging for all OSes) (status messages and readouts use stable responsive allocations sized for localized labels and ordinary coordinates; sample widths cached by language/unit/DPI; regression-tested and contributor-confirmed 2026-10-19; estimates unchanged) | 🟡 Dock groups collapse to their tabs by a double-click on a tab (UI.8); Preferences › General › Constrain Angle acts for the arrow keys, Shift drags and new objects (#394, 2026-10-21); numeric-field pointer selection and focus regression-tested (#1326, in part; short movements still select all); RPM runtime capabilities and glibc floor checked (#1275; real-distro install/start-up pending), Eyedropper cursor with precise-setting checks (#1269), Preferences, shortcut editor (chords with Shift and a punctuation key fire as typed; other apps' text shortcut sets imported), workspaces (each keeps its layout changes until Reset , UI.7), panels docked by dragging into any dock group (as tabs or a top/bottom split) or into the icon column, and closed from a dock tab's context menu (UI.6), a custom title bar on Windows/Linux with a Home button, content-sized dialogs, menus that scroll when longer than the window and macOS native menu dismissal done (M14.8), and native macOS save sheets with a Format menu (#866); titled PDF exports set `DisplayDocTitle` for viewers and accessibility checkers (#3646); accessibility and broader Windows/Linux packaging/QA pending ; floating tab groups collapse into the side icon rail and opened rail panels fold back into it (#5925, in part), with pointer and native-window regression coverage; estimates unchanged | 18–28 | | — | Interaction fidelity pass (every tool's modifiers, Properties panel per context, isolation, nuance; width-point creation and adjoining adjustment regression-tested; dialog layout reviewed) | ⬜ (new ruler-guide Alt orientation implemented; existing-guide Escape cancellation regression-tested; broader pass remains) | 60–90 | | — | Hardening at scale (big-file corpus, fuzzing, cross-platform + browser QA) | 🟡 PngSuite integrity and bounded fetching verified (#1729); real-world corpus/manual QA remain | 50–80 | | M14 follow-up | Color Picker layout (#2008) | ✅ Compact controls, centered header, stacked actions, aligned fields and screen sampling; narrow windows scroll vertically | Included above | @@ -180,6 +180,7 @@ separate. Scores and hours unchanged. [Behavior and command details](development | Date | Change | Summary | |---|---|---| +| 2026-11-08 | minor | Floating tab groups collapse into the side icon rail and opened rail panels fold back into it (#5925, in part); tab groups remain intact. Scores and estimates unchanged. | | 2026-11-06 | minor | M2: a shape just drawn moves by its centre point (Show Center) and turns from the rotate zone just outside a bounding-box corner with its tool still active, as the Selection tool's gestures do (#5477); estimates unchanged. | | 2026-11-06 | minor | Hindi (`hi`): 7,877-row machine-assisted catalog, zero/one singular plurals, desktop font fallback and optional Devanagari craft-fonts fallback; all 55 translation tests pass; native review and a web font remain; scores and estimates unchanged | | 2026-11-04 | minor | New Document: the units chosen in Preset Details belong to the chosen preset; Recent and Saved cards keep their own units; scores and estimates unchanged. | diff --git a/docs/target-app-parity.md b/docs/target-app-parity.md index 1aef04833..7a07ff4bd 100644 --- a/docs/target-app-parity.md +++ b/docs/target-app-parity.md @@ -1,6 +1,6 @@ # Parity with Adobe Illustrator -> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-07 · **Change:** minor (the canvas keeps selection outlines and anchors between frames; Indian-language hyphenation review and license allowlist, #4947; Stroke gradients: an arrowhead aligned to the tip is painted to the corners of its base, #5964; Drop Shadow and glow dialogs: spinner arrows, #5367, #5368; Stroke Weight Up and Down shortcuts, #5797; Hindi catalog and contributor loanword preferences; full wording review in progress; Properties in Edit Artboards: a Transform section with the reference point above the Artboards section, #5219; the Control bar's Stroke: and Opacity: links scrub their fields, #4088; an image zoomed in on is separated, colorized or proofed only where it shows (#4155); a document's first frame renders on the render worker, so opening a heavy file no longer freezes the window, #4155; Control bar Paragraph section with type selected, #5372; translating unchanged type reuses its glyph and character-stroke outlines; scores and estimates unchanged) · **Target:** Adobe Illustrator 2026 (30.x; public release notes through 30.7, August 2026) +> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-08 · **Change:** minor (floating tab groups collapse into the side icon rail and opened rail panels fold back into it, #5925 in part; the canvas keeps selection outlines and anchors between frames; Indian-language hyphenation review and license allowlist, #4947; Stroke gradients: an arrowhead aligned to the tip is painted to the corners of its base, #5964; Drop Shadow and glow dialogs: spinner arrows, #5367, #5368; Stroke Weight Up and Down shortcuts, #5797; Hindi catalog and contributor loanword preferences; full wording review in progress; Properties in Edit Artboards: a Transform section with the reference point above the Artboards section, #5219; the Control bar's Stroke: and Opacity: links scrub their fields, #4088; an image zoomed in on is separated, colorized or proofed only where it shows (#4155); a document's first frame renders on the render worker, so opening a heavy file no longer freezes the window, #4155; Control bar Paragraph section with type selected, #5372; translating unchanged type reuses its glyph and character-stroke outlines; scores and estimates unchanged) · **Target:** Adobe Illustrator 2026 (30.x; public release notes through 30.7, August 2026) ## Feature submission evidence @@ -212,7 +212,7 @@ dominate; 3D, graphs and automation are specialist). They sum to 105. Feature de | Export for Screens, Asset Export, slices, Save for Web | 3 | 85% | anti-aliasing ghost borders (#983); TIFF choices and settings are implemented | 2–4 | estimated | | Print, colour management, separations, flattener | 3 | 80% | print preview fidelity | 2–4 | estimated | | Automation (Actions, Variables, scripting, batch) | 3 | 60% | a scripting surface (Illustrator: JavaScript/ExtendScript), Batch, image and graph variables, dataset import/export | 8–14 | estimated; MCP `add_text` exposes existing vertical type; score and hours unchanged | -| UI chrome (panels, Properties, workspaces, preferences) | 6 | 80% | Properties per context, 3 Preferences options stored but unused (#394, audited 2026-10-30: Open Documents As Tabs, Scratch Disks, legacy vector clipboard), SVG Interactivity, context menus beyond the canvas, accessibility | 13–20 | estimated; floating panels in OS windows of their own on the desktop (#4135), score and hours unchanged; macOS save Format menu implemented (#866), score and hours unchanged; Eyedropper cursor and precise setting checked (#1269), OS visual QA unverified; numeric-field focus and normal text drags regression-tested (#1326, in part); movements below the click threshold still select all; artboard navigation synchronizes the tool selection before destructive actions; status messages and readouts use stable responsive allocations sized for localized labels and ordinary coordinates (sample widths cached by language/unit/DPI; regression and contributor original-file evidence below; scores/hours unchanged); effect dialogs' colour fields show a swatch that opens the Color Picker (#5365), score and hours unchanged | +| UI chrome (panels, Properties, workspaces, preferences) | 6 | 80% | Properties per context, 3 Preferences options stored but unused (#394, audited 2026-10-30: Open Documents As Tabs, Scratch Disks, legacy vector clipboard), SVG Interactivity, context menus beyond the canvas, accessibility | 13–20 | estimated; floating panels in OS windows of their own on the desktop (#4135), score and hours unchanged; macOS save Format menu implemented (#866), score and hours unchanged; Eyedropper cursor and precise setting checked (#1269), OS visual QA unverified; numeric-field focus and normal text drags regression-tested (#1326, in part); movements below the click threshold still select all; artboard navigation synchronizes the tool selection before destructive actions; status messages and readouts use stable responsive allocations sized for localized labels and ordinary coordinates (sample widths cached by language/unit/DPI; regression and contributor original-file evidence below; scores/hours unchanged); effect dialogs' colour fields show a swatch that opens the Color Picker (#5365), score and hours unchanged; floating tab groups collapse into the side icon rail and opened rail panels fold back into it (#5925, in part), scores and hours unchanged | | Libraries, Links, Package | 2 | 82% | shared libraries, linked graphics, gradients and patterns as library items (no cloud by design) | 2–3 | estimated | | Generative AI (Text to Vector, Generative Recolor, Shape Fill, Concept to Vector, Prompt to Edit, Rewrite Text) | 2 | 0% | a pluggable provider and the panels; needs an owner decision on models | 30–60 | measured (absent) | | **Feature depth** | **105** | **~75%** | | **~250–420** | | @@ -517,6 +517,8 @@ since 2026-10-01. ## Evidence: what ships today, by area +- **Panel collapse controls (#5925, in part):** The small » in a floating tab-group header moves that group into the side icon rail, reusing the existing rail or creating one. An opened rail panel has the same control to fold its flyout back into the rail, including after a tab switch. Both controls preserve the tab group and its menu; other floating groups and full-width docked headers stay as they were. Pointer regressions in `crates/ui-egui/src/panel_docking/tests.rs` cover grouped tabs, reopening, separate groups, a missing rail, the menu and flyout closure after switching tabs; `native_tests.rs` covers the native-window click and removal of the empty palette. Scores and estimates unchanged. + - 3D lighting presets: `crates/effects/src/lighting_presets.rs`, `crates/engine/src/cmd/effectcmd/lighting_presets_tests.rs` and the pointer tests in `crates/ui-egui/src/dialogs/revolve/tests.rs` cover recognition, atomic targeting, native round trips, preview, Cancel, reset and Undo. - **Status-bar pointer readout (2026-10-18):** uses the same effective ruler origin as the position fields, then formats the relative X/Y in General units. The absolute pointer position, document, selection, Undo/Redo and saved state are preserved. Three `chrome::tests::status_coordinates_*` painted-text regressions cover zero/positive/negative origins, unit conversion, global/artboard mode, active artboard, reset and missing pointer/document. Original headless status-bar captures were reviewed before and after the change. Scores and hours are unchanged. @@ -1729,6 +1731,7 @@ Edit › Copy and Cut put the selected ruler guides on the clipboard, with the s | Date | Change | Summary | |---|---|---| +| 2026-11-08 | minor | Floating tab groups collapse into the side icon rail and opened rail panels fold back into it (#5925, in part); tab groups remain intact. Scores and estimates unchanged. | | 2026-11-06 | minor | Direct Selection: with Snap to Grid, a dragged straight segment lands its anchors on the grid (#3835); evidence added; scores unchanged. | | 2026-11-06 | minor | Snap to Glyph › Glyph Bounds: the corners of each glyph's box are points a drawn point lands on, also on a curved side (`B`), and the box turns with rotated type, its edges then Angular Guides (#5112; [Snap to Glyph options](https://helpx.adobe.com/illustrator/desktop/design-with-text/special-characters-glyphs/snap-to-glyph-options.html)); scores and estimates unchanged. | | 2026-11-06 | minor | Drop Shadow: a swatch beside Color opens the Color Picker over the dialog, as the other effect colour fields do (#5364); correction: the #5365 entry listed Drop Shadow, whose Color is drawn outside the shared grid and had no swatch; scores unchanged. | diff --git a/docs/ui-parity.md b/docs/ui-parity.md index 4efbee4aa..85ea0a2f3 100644 --- a/docs/ui-parity.md +++ b/docs/ui-parity.md @@ -1,6 +1,6 @@ # UI and interaction parity -> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-06 · **Change:** minor (Drop Shadow and glow dialogs: spinner arrows, #5367, #5368; Stroke Weight Up and Down shortcuts, #5797; Layers: Rename (`ui.rename`) opens the name field of the selected layer, group or object, #5324; Properties in Edit Artboards: Transform section above the Artboards section, #5219; scrubby labels: the Control bar's Stroke: and Opacity: links and the Properties panel's Stroke link scrub their fields, #4088; Properties: Quick Actions has Repeat Options for one selected repeat, #5181; Direct Selection: Shift-click picks several blend spine points, which drag together, #5285; Direct Selection: Cmd/Ctrl held lends the Selection tool and shows its bounding box, #3901; Join tool trims two crossing open paths and joins them at the crossing, #5844; Control bar: Paragraph: link and Align left/center/right while type is selected, #5372; shape tools: a press on the selection's centre point moves it and one in the rotate zone outside a box corner turns it, #5477; scores and estimates unchanged) · **Target:** Adobe Illustrator 2026 (30.x; Units › East Asian Type acts, with Q and Ha units; scores unchanged) +> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-08 · **Change:** minor (floating tab groups collapse into the side icon rail and opened rail panels fold back into it, #5925 in part; Drop Shadow and glow dialogs: spinner arrows, #5367, #5368; Stroke Weight Up and Down shortcuts, #5797; Layers: Rename (`ui.rename`) opens the name field of the selected layer, group or object, #5324; Properties in Edit Artboards: Transform section above the Artboards section, #5219; scrubby labels: the Control bar's Stroke: and Opacity: links and the Properties panel's Stroke link scrub their fields, #4088; Properties: Quick Actions has Repeat Options for one selected repeat, #5181; Direct Selection: Shift-click picks several blend spine points, which drag together, #5285; Direct Selection: Cmd/Ctrl held lends the Selection tool and shows its bounding box, #3901; Join tool trims two crossing open paths and joins them at the crossing, #5844; Control bar: Paragraph: link and Align left/center/right while type is selected, #5372; shape tools: a press on the selection's centre point moves it and one in the rotate zone outside a box corner turns it, #5477; scores and estimates unchanged) · **Target:** Adobe Illustrator 2026 (30.x; Units › East Asian Type acts, with Q and Ha units; scores unchanged) ## Feature submission evidence @@ -334,6 +334,8 @@ next unit in the order a right-click on a ruler lists them, from Feet back to Po ## Panels, Control bar, Properties, context menus +- **Panel collapse controls (#5925, in part):** The small » in a floating tab-group header moves that group into the side icon rail, reusing the existing rail or creating one. An opened rail panel has the same control to fold its flyout back into the rail, including after a tab switch. Both controls preserve the tab group and its menu; other floating groups and full-width docked headers stay as they were. Pointer regressions in `crates/ui-egui/src/panel_docking/tests.rs` cover grouped tabs, reopening, separate groups, a missing rail, the menu and flyout closure after switching tabs; `native_tests.rs` covers the native-window click and removal of the empty palette. Scores and estimates unchanged. + | Interaction | Status | Evidence | |---|---|---| | Selection artwork drag hovers a visible document tab to activate it, then drops editable artwork on its canvas | done | `tests_document_drag`, `edit.dropSelection`, lossless resource and one-step Undo regressions; overflow and cross-window drag remain separate | @@ -478,6 +480,7 @@ separate. Scores and hours unchanged. [Behavior and command details](development | Date | Change | Summary | |---|---|---| +| 2026-11-08 | minor | Floating tab groups collapse into the side icon rail and opened rail panels fold back into it (#5925, in part); tab groups remain intact. Scores and estimates unchanged. | | 2026-11-06 | minor | Keyboard shortcuts: Cmd/Ctrl+Alt+. and Cmd/Ctrl+Alt+, (Stroke Weight Up and Down) step each selected stroke's weight, or the next object drawn's (#5797); scores and estimates unchanged | | 2026-11-06 | minor | Properties: Quick Actions has Repeat Options for one selected radial, grid or mirror repeat, opening Object › Repeat › Options with its values (#5181); scores and estimates unchanged | | 2026-11-06 | minor | Control bar: with type selected, a Paragraph: link (the Paragraph panel in a popover) and the Align left, Align center and Align right buttons follow the Character controls; the bar leaves them out from its right end when short of room, after X/Y/W/H and the Align buttons (#5372); scores and estimates unchanged |