From 82251c8e8b226dbafb327a173c287388c6fbfeea Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 5 Nov 2026 14:46:42 +0300 Subject: [PATCH] Layers: a layer that does not print shows its name italic (#5739) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Layer Options › Print off means the layer's art does not print. The Layers panel now paints that layer's name italic, as Illustrator shows non-printing layers, and the ghost of a row being dragged keeps the italic. A printing layer's name stays upright, and ticking Print again restores it. Row names are painted rather than widgets, so the italics come from a layout job's text format (egui slants the glyphs itself; no italic face is needed). Tests: panels::layers::tests::a_layer_that_does_not_print_has_its_name_italic covers Print off, Print on again, and a plain printing layer; the layers suite (64 tests) passes. Docs: roadmap, target-app-parity and ui-parity carry the change. --- crates/ui-egui/src/panels/layers/rows.rs | 23 +++++++++++++-- crates/ui-egui/src/panels/layers/tests.rs | 35 +++++++++++++++++++++++ docs/roadmap.md | 3 +- docs/target-app-parity.md | 4 ++- docs/ui-parity.md | 4 ++- 5 files changed, 64 insertions(+), 5 deletions(-) diff --git a/crates/ui-egui/src/panels/layers/rows.rs b/crates/ui-egui/src/panels/layers/rows.rs index f7abe7aa3..310d7a1cd 100644 --- a/crates/ui-egui/src/panels/layers/rows.rs +++ b/crates/ui-egui/src/panels/layers/rows.rs @@ -16,6 +16,25 @@ pub(super) fn rename_id() -> egui::Id { egui::Id::unique("layers-rename") } +/// Whether a row's name is italic: a layer whose Layer Options в†’ Print is off does not print, and +/// the panel shows that in its name, as the reference application does (a template layer's Print is +/// off too). +fn prints_italic(n: &Node) -> bool { + matches!(n.kind, NodeKind::Layer { printable: false, .. }) +} + +/// Paints the row name `name` at `pos` (left, vertically centred), italic when `italic`, and +/// returns its rect. Row names are painted rather than widgets, so italics come from a layout job's +/// text format: egui slants the glyphs itself, no italic face is needed. +fn paint_name(painter: &egui::Painter, pos: egui::Pos2, name: &str, font: egui::FontId, color: Color32, italic: bool) -> egui::Rect { + let mut job = egui::text::LayoutJob::default(); + job.append(name, 0.0, egui::TextFormat { font_id: font, color, italics: italic, ..Default::default() }); + let galley = painter.layout_job(job); + let rect = egui::Align2::LEFT_CENTER.anchor_size(pos, galley.size()); + painter.galley(rect.min, galley, color); + rect +} + /// The colour of the layer holding `id`. fn layer_colour(doc: &Document, id: NodeId) -> Color32 { let [r, g, b] = doc.layer_color(id); @@ -57,7 +76,7 @@ pub(super) fn drag_ghost(ui: &Ui, view: &View, src: NodeId, pos: egui::Pos2) { } let label = n.identify_label(view.identify_xml_id); let name = if view.identify_xml_id { label } else { painted_name(n, &label, crate::i18n::current()) }; - ui.painter().text(egui::pos2(x, r.center().y), egui::Align2::LEFT_CENTER, name, egui::FontId::proportional(13.0), t.text); + paint_name(ui.painter(), egui::pos2(x, r.center().y), &name, egui::FontId::proportional(13.0), t.text, prints_italic(n)); }); } @@ -316,7 +335,7 @@ pub(super) fn row(ui: &mut Ui, view: &View, item: &Row, out: &mut Out) { } else { painted_name(n, &n.display_name(), crate::i18n::current()) }; - let text = painter.text(egui::pos2(x, r.center().y), egui::Align2::LEFT_CENTER, shown, font, if item.dim { t.text_dim } else { t.text }); + let text = paint_name(&painter, egui::pos2(x, r.center().y), &shown, font, if item.dim { t.text_dim } else { t.text }, prints_italic(n)); name_end = text.right(); // A clipping path's name is underlined, a masked object's with a dashed line. if clip_path { diff --git a/crates/ui-egui/src/panels/layers/tests.rs b/crates/ui-egui/src/panels/layers/tests.rs index 6f65e5d8c..03862ad52 100644 --- a/crates/ui-egui/src/panels/layers/tests.rs +++ b/crates/ui-egui/src/panels/layers/tests.rs @@ -211,6 +211,41 @@ fn two_rects() -> (VectorcraftApp, NodeId, [NodeId; 2]) { (app, layer, [NodeId(a), NodeId(b)]) } +/// The painted names one headless frame of the panel draws italic. +fn italic_names(app: &mut VectorcraftApp, ctx: &egui::Context) -> Vec { + let mut out = ctx.run_ui(egui::RawInput::default(), |ui| show(app, ui)); + out.textures_delta.clear(); + fn collect(shape: &egui::Shape, names: &mut Vec) { + match shape { + egui::Shape::Text(t) => { + if t.galley.job.sections.iter().any(|s| s.format.italics) { + names.push(t.galley.text().to_string()); + } + } + egui::Shape::Vec(shapes) => shapes.iter().for_each(|s| collect(s, names)), + _ => {} + } + } + let mut names = Vec::new(); + out.shapes.iter().for_each(|c| collect(&c.shape, &mut names)); + names +} + +/// A layer whose Layer Options в†’ Print is off has its name italic in the panel (#5739), as the +/// reference application shows it; a printing layer's name stays upright, and unticking Print again +/// makes it upright. +#[test] +fn a_layer_that_does_not_print_has_its_name_italic() { + let (mut app, layer, _) = two_rects(); + let ctx = egui::Context::default(); + crate::theme::install_fonts(&ctx); + assert!(!italic_names(&mut app, &ctx).iter().any(|n| n == "Layer 1"), "a printing layer's name is upright"); + app.session.execute("layer.setProps", &json!({"ids": [layer.0], "printable": false})).unwrap(); + assert!(italic_names(&mut app, &ctx).iter().any(|n| n == "Layer 1"), "Print off: its name is italic"); + app.session.execute("layer.setProps", &json!({"ids": [layer.0], "printable": true})).unwrap(); + assert!(!italic_names(&mut app, &ctx).iter().any(|n| n == "Layer 1"), "Print on again: upright again"); +} + #[test] fn row_thumbnails_wait_for_the_end_of_a_drag() { let (mut app, _, _) = two_rects(); diff --git a/docs/roadmap.md b/docs/roadmap.md index b91a963e8..5c3103ef5 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-05 · **Change:** minor (Selection Tools add-on: Select by Link Status selects images and placed documents that are linked, embedded, missing or modified, #5526; scores and estimates unchanged) · **Target:** Adobe Illustrator 2026 (30.x) +> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-05 · **Change:** minor (Layers panel: a layer whose Layer Options › Print is off shows its name italic, #5739; scores and estimates unchanged) · **Target:** Adobe Illustrator 2026 (30.x) ## Feature submission evidence @@ -29,6 +29,7 @@ M7 type: Touch Type moves a right-to-left character along its line and up from i | Date | Change | Summary | |---|---|---| | 2026-11-05 | minor | Selection Tools add-on: Select Linked, Embedded, Missing and Modified select the images and placed documents with that link status (Object › Plug-ins › Selection Tools and the Links panel menu; Shift adds), and Select by Link Status… lists them by name, status and format to pick from, optionally zooming to them; what is hidden, locked, on a template layer or outside the isolated group is left out and the status bar says how many (#5526, a VectorCraft addition); scores and estimates unchanged (estimated). | +| 2026-11-05 | minor | Layers panel: a layer whose Layer Options › Print is off shows its name italic, as the reference application shows non-printing layers, and keeps it while the row is dragged (#5739); scores and estimates unchanged. | | 2026-11-04 | minor | M7: Find Font's Replace With Font lists family and style rows with a search, and the list and the document's font list scroll on their own (#4972); scores and estimates unchanged. | | 2026-11-04 | minor | Selection Tools add-on: Select by Artboards selects the objects overlapping, fully inside or fully outside several chosen artboards, from a dialog that lists, searches and multi-selects the artboards and fits one in the window on double-click (#5525, #5548, #5549, a VectorCraft addition); scores and estimates unchanged. | | 2026-11-05 | minor | Panels: a floating panel window hides under a modal dialog and drops out of the top level under an open menu, so neither the Colour Picker or Recolor Artwork nor the menu bar is covered, and it comes back at its palette level after (#5238); scores and estimates unchanged. | diff --git a/docs/target-app-parity.md b/docs/target-app-parity.md index 584a83d3a..cbf855fe1 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-05 · **Change:** minor (Selection Tools add-on: Select by Link Status selects images and placed documents that are linked, embedded, missing or modified, #5526; 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-05 · **Change:** minor (Layers panel: a layer whose Layer Options › Print is off shows its name italic, #5739; scores and estimates unchanged) · **Target:** Adobe Illustrator 2026 (30.x; public release notes through 30.7, August 2026) ## Feature submission evidence @@ -24,6 +24,7 @@ Artboard Options forwards the active Artboard tool's Scale Artwork with Artboard | Date | Change | Summary | |---|---|---| | 2026-11-05 | minor | Selection Tools add-on: Select Linked, Embedded, Missing and Modified select the images and placed documents with that link status (Object › Plug-ins › Selection Tools and the Links panel menu; Shift adds), and Select by Link Status… lists them by name, status and format to pick from, optionally zooming to them; what is hidden, locked, on a template layer or outside the isolated group is left out and the status bar says how many (#5526, a VectorCraft addition); scores and estimates unchanged (estimated). | +| 2026-11-05 | minor | Layers panel: a layer whose Layer Options › Print is off shows its name italic, as the reference application shows non-printing layers, and keeps it while the row is dragged (#5739); a printing layer's name is upright, and Print on again makes it upright again; scores and estimates unchanged. | | 2026-11-05 | minor | G12: Hyphenation › Default Language sets the language of new type unless Document Setup chose one, stored as a tag; each run hyphenates in its own language, English only so far, so 2 Preferences options stay unused (#394) | | 2026-11-05 | minor | Type Tools add-on: Release Type on a Path (a VectorCraft addition, #5532): evidence added; scores unchanged. | | 2026-11-04 | minor | Path Precision Tools add-on (a VectorCraft addition): Set Corners… and `addon.pathtools.cornerSet` `minAngle`/`maxAngle` round only the corners whose angle is in a range (#5545); evidence added; scores unchanged. | @@ -643,6 +644,7 @@ Moved from the ROADMAP's "Shipped so far" on 2026-10-10. Update it when a featur - Tab does not stop on the regions that only the pointer uses: the custom title bar's background and the window's resize zones, the band at the top of a dialog that moves it, the Tools panel's grip, a flyout's and a floating strip's tear-off bar, the isolation bar's background, and the rulers and the box where they meet. - These dialog sliders, each beside a number field, respond to the keyboard: those of the effect, tool option, brush and transform dialogs, the Perspective Grid, the 3D dialogs, and the flattener options, which the Flattener Preview panel also shows. A click, or Tab, gives a slider the keyboard focus, and an outline shows it. Then → and ↑ step the field's number up to the next whole number and ← and ↓ step it down to the next whole number, Shift with an arrow and Page Up and Page Down step it by ten, and Home and End set the slider's first and last value; no step goes past either end. Screen readers' increment and decrement actions step the slider as → and ← do. The Color panel's, Swatch Options', the Navigator's and the Character panel's sliders, and the Color Picker's channel slider, respond only to the pointer. The keys follow the WAI-ARIA slider pattern (); the reference app's help does not describe keys on a dialog's slider, so the step sizes are VectorCraft's own. - Screen readers get the value of the color and channel sliders that panels and dialogs draw (the Color panel, the Color Picker, Swatch Options, the Navigator's Zoom, the Character panel's variable font axes, the Perspective Grid and flattener options, and the sliders of the effect, tool option and transform dialogs): the number and text of the field beside each one, such as 128 for G or 50% for an opacity, with the slider's range, which extends to include a number past the slider's end. The harmony wheel's Brightness slider, which has no field, reports its brightness in percent. + - A layer whose Layer Options › Print is off shows its name italic in the Layers panel, and while its row is dragged, as the reference application shows non-printing layers (#5739); a printing layer stays upright and ticking Print again restores the upright name (`panels::layers` test `a_layer_that_does_not_print_has_its_name_italic`). - Panels undock (#495): a dock tab, a panel icon or a popped-out panel's title dragged out of the dock floats that panel (in an OS window of its own on the desktop, #4135), and the strip right of the dock's tabs floats the whole tabbed group. A floating group moves by its title bar, a tab dragged out of it floats on its own, and dropped on another group's title bar or tabs it stacks with that group; dropped on a dock group's tabs, which light up under the pointer, its panels join that group, and on the group's upper or lower half they make a new group above or below it (`window.panel.dock {anchor, zone}`); dropped on the icon column they become icons there, the tabbed group's panels too (`window.panel.dock {icon: true}`); dropped anywhere else on the dock, which lights up, they go back where they live (the tabbed group or the icon column), as its × and the panel menus' Float Panel / Dock Panel do (`window.panel.float`, `window.panel.dock`). The Tools panel floats by its title bar and docks again on the window's left edge. Floating groups stack into sets: dropped on the upper or lower half of another group (a line shows where), a group joins it right above or below it, and the set's groups stack top to bottom, each showing one panel, moving together by the top group's title bar, whose × docks them all; a group dragged by its tab strip leaves the set (`window.panel.float {below, above}`). A double-click on a tab collapses a floating group to its tabs (`collapsed`), and a dock group too, a group below it moving up into the room; a second double-click, or a click on another of its tabs, expands it (`window.panel.collapse`, kept with the preferences and in saved workspaces). Sets dropped on the left edge of the icon column or of another dock column dock as dock columns (a multi-column dock, `window.panel.dock {column}`), whose groups stack, tab and tear out as a floating set's do, and whose top strip floats the column again. Floating panels, their sets and the Tools panel's position are kept with the preferences and in user workspaces, and clamped into a smaller window. Not done: panels in separate OS windows, reordering tabs by dragging, collapsing a set or dock column to icons, dock columns right of the default dock, resizing floating panels and the groups of a set. - The dock's double arrow collapses Properties, Layers and Libraries to icons at the top of the icon column, popping out like the other icon panels, and expands them again (`window.collapseDock`, kept with the preferences and in saved workspaces). The icon column's own arrow (expanding the icon panels into a full column) is not done. - Window › Toolbars › New Toolbar… and New Toolbar… in the All Tools drawer's menu ask for a name and make a blank toolbar that floats on its own, moved by its title bar and listed under Window › Toolbars, whose item shows or hides it. The title bar's × hides it, and its double arrow shows its tools in one column or two. Its ••• button opens the All Tools drawer beside it, and tools dragged from the drawer fill it. The toolbars are kept with the workspace they were made in: switching workspaces shows that workspace's toolbars, Reset Workspace keeps them, and New Workspace starts the new workspace with a copy of them (; `window.toolbar.new`, `window.toolbar.custom`, the `toolbar` param of `window.editToolbar` and `toolbar.addTool`/`removeTool`/`reset`; `tools_added_to_a_new_toolbar_survive_a_workspace_reload`). diff --git a/docs/ui-parity.md b/docs/ui-parity.md index 560fc3edb..4812ef238 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-05 · **Change:** minor (Selection Tools add-on: Select by Link Status selects images and placed documents that are linked, embedded, missing or modified, #5526; 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-05 · **Change:** minor (Layers panel: a layer whose Layer Options › Print is off shows its name italic, #5739; 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 @@ -31,6 +31,7 @@ Artboard Options forwards the active Artboard tool's Scale Artwork with Artboard | Date | Change | Summary | |---|---|---| | 2026-11-05 | minor | Selection Tools add-on: Select Linked, Embedded, Missing and Modified select the images and placed documents with that link status (Object › Plug-ins › Selection Tools and the Links panel menu; Shift adds), and Select by Link Status… lists them by name, status and format to pick from, optionally zooming to them; what is hidden, locked, on a template layer or outside the isolated group is left out and the status bar says how many (#5526, a VectorCraft addition); scores and estimates unchanged (estimated). | +| 2026-11-05 | minor | Layers panel: a layer whose Layer Options › Print is off shows its name italic, as the reference application shows non-printing layers, and keeps it while the row is dragged (#5739); scores and estimates unchanged | | 2026-11-05 | minor | G12: Hyphenation › Default Language sets the language of new type unless Document Setup chose one, stored as a tag; each run hyphenates in its own language, English only so far, so 2 Preferences options stay unused (#394) | | 2026-11-05 | minor | Gradient panel: Delete Stop sits at the right end of the ramp, so it shows whenever the ramp does instead of under the stop fields, where a short panel hid it (#5403); scores and estimates unchanged | | 2026-11-04 | minor | Artboards panel: a Shift- or Ctrl/Cmd-click on a row selects several artboards with any tool, switching to the Artboard tool first, so a preset, orientation, size or Fill set in Properties or the Control bar goes to every selected artboard; Fill used to set the active artboard only (#5698); scores and estimates unchanged | @@ -117,6 +118,7 @@ tools, never checked side by side) isn't captured row by row. | Each anchor snaps to Smart Guides and construction angles | done | `DrawSnap` | | Curvature tool: click/drag points, double-click or Alt-click for a corner, temporary Direct Selection, point conversion | partial | circular point markers without direction handles or duplicate markers, Anchor Size and Hide Edges regression-tested (#1236, in part); curve geometry: each stretch of three points follows the circle through them (handles along its tangent, chord/(3·cos²(α/2)) long, shorter in a turn tighter than 30°), open ends curving in, the same rule for the rubber band, dragged, inserted and converted points (#1236, in part); neighbours of a point dragged on an existing path keep their tangents, and modifiers requested in #975 remain | | Layers panel lists a blend's spine (#4820) | done | an open blend shows a `` row below its key objects, where Release leaves the spine; a click selects the blend (Shift/Cmd toggles it) so Direct Selection edits the spine; a locked blend's row selects nothing; no row while searching or filtering (`a_blends_spine_is_a_row_below_its_keys_that_selects_the_blend`) | +| Layers panel: a layer whose Layer Options › Print is off shows its name italic (#5739) | done | the panel row and its drag ghost; a printing layer stays upright, and Print on again restores it; `panels::layers` test `a_layer_that_does_not_print_has_its_name_italic` | | Blend spine Anchor Point conversion and handle editing (#2544) | implemented | symmetric handles, independent drag/retraction, visible-handle policy and selection/stacking covered by tool and engine regressions; Windows native canvas checks and screenshots reviewed in PR #2643 | | Add/Delete/Anchor Point tools; Anchor Point tool drags segments to reshape | done | #2267: a click on a handle end retracts that handle and leaves the anchor a corner with the other one; Shift held at the press on an anchor moves it, handles and all (Shift kept down: at 45° steps) instead of pulling out handles | | Pencil: Fidelity, Keep selected, Alt to Smooth, edit selected paths, close by proximity | done | Fidelity goes down to 0.01 pt in the dialog, the tool and `path.freehand` (the Smooth tool keeps 0.05); its slider runs across the Tool Options row on a logarithmic rail from 0.01 to 20 pt, the field shows hundredths, and the slider's and the field's arrow keys step hundredths up to 0.1 pt, tenths up to 1 pt and whole points above (Shift ×10) (#3328); Alt key toggles to Smooth Tool (#2001); Shift held at the press draws a straight line at 45° steps from the Constrain Angle, and Alt held at the press (with Alt key toggles to Smooth Tool off) a straight line at any angle (#3799), with a straight-line cursor while Shift or Alt is held before the press, and a path-continuation cursor over an end of a selected open path, where the line continues the path; Edit Selected Paths continues a selected path from an end and, from a stroke that starts and ends on a selected path, redraws the section between (the shorter way round a closed path, #2850); with Keep selected (Pencil and Paintbrush, on by default) off, the path a stroke draws or continues is not selected afterwards; a filled Pencil path keeps a stroke of None (#1804, part of #1679); while a freehand stroke is drawn back to within Close Paths When Ends Are Within of its start, the Pencil and the Paintbrush show the closing cursor, and a release there closes the path |