Merge PR #8186: fix(paths): the Work Path is drawn only while selected or a path tool is active (#6551)

This commit is contained in:
aiongg
2026-10-22 15:37:32 +00:00
2 changed files with 48 additions and 4 deletions
+3 -1
View File
@@ -248,7 +248,8 @@ fn clicking_shape_with_path_selection_selects_its_layer() {
assert_eq!(h.state().session.active().unwrap().active_layer.unwrap().0, rect_layer);
}
/// Work paths remain visible (outline) regardless of the active tool. Before the fix,
/// A work path selected in the Paths panel remains visible (outline) regardless of the active tool
/// (one that is not selected is hidden, #6551). Before the fix,
/// `draw_overlay` was gated on `vector_tool` so paths disappeared when switching to Brush, Move,
/// etc. This test renders the canvas with a Brush tool active and a work path present, then
/// confirms the path's outline pixels are painted in the accent colour, proving the path is drawn.
@@ -259,6 +260,7 @@ fn path_overlay_drawn_for_non_vector_tools() {
app.sync_views();
// Place a work path whose top edge runs exactly along y=10 in document space.
app.run("path.set", json!({"name": "work", "path": rect_path(50.0, 10.0, 100.0, 80.0)})).unwrap();
app.ui.selected_path = Some("work".into());
// Switch to a non-vector tool — before the fix this hid the path outline.
app.ui.tool = Tool::Brush;
+45 -3
View File
@@ -1173,10 +1173,15 @@ pub fn draw_overlay(app: &PhotocraftApp, painter: &egui::Painter, xf: &ViewXform
crate::anchor_tools::draw_hover(app, painter, &to_scr, accent, painter.ctx().input(|i| i.modifiers));
}
} else if paths {
// Paths remain visible as outlines with any tool. Path Selection and the Pen tools add
// anchor squares; Direct Selection has its own overlay above.
// The shape's or vector mask's path stays visible as an outline with any tool. Path
// Selection and the Pen tools add anchor squares; Direct Selection has its own overlay
// above. The Work Path is drawn only while it is the path selected in the Paths panel or
// a path tool is active, as in Photoshop: a Work Path left unselected (one a PSD arrived
// with, or after Ctrl-click Load as Selection) would otherwise cover the marching ants (#6551).
let anchors = shows_anchors(tool);
if let Some(wp) = &doc.work_path {
if let Some(wp) = &doc.work_path
&& (anchors || app.ui.selected_path.as_deref() == Some("work"))
{
draw_path(wp, anchors);
}
// The saved path selected in the Paths panel is the target path (#6550).
@@ -2491,6 +2496,43 @@ mod tests {
assert!(!shows_anchors(Tool::Brush) && !shows_anchors(Tool::Move));
}
#[test]
fn an_unselected_work_path_is_not_drawn_over_the_canvas() {
// #6551: Ctrl-click Load as Selection leaves the Paths panel's selection alone, yet the Work
// Path stayed drawn over the new selection's edge. Photoshop draws it only while selected
// in the Paths panel (or a path tool is active).
let ctx = egui::Context::default();
let mut app = app();
let path = json!({"subpaths": [{"closed": true, "knots": [
{"anchor": [20, 20], "in": [20, 20], "out": [20, 20]},
{"anchor": [90, 20], "in": [90, 20], "out": [90, 20]},
{"anchor": [90, 90], "in": [90, 90], "out": [90, 90]}
]}]});
app.run("path.set", json!({"name": "work", "path": path})).unwrap();
app.run("path.toSelection", json!({"name": "work", "mode": "replace"})).unwrap();
assert!(app.ui.selected_path.is_none());
for tool in [Tool::Move, Tool::Brush, Tool::Rectangle, Tool::Zoom] {
app.ui.tool = tool;
assert_eq!(overlay_shapes(&app, &ctx), 0, "{tool:?}: an unselected Work Path stays off the canvas");
}
// Selected in the Paths panel: drawn with any tool.
app.ui.selected_path = Some("work".into());
for tool in [Tool::Move, Tool::Brush] {
app.ui.tool = tool;
assert!(overlay_shapes(&app, &ctx) > 0, "{tool:?}: the selected Work Path is drawn");
}
// Another path selected: the Work Path is not the target path.
app.ui.selected_path = Some("Saved".into());
app.ui.tool = Tool::Move;
assert_eq!(overlay_shapes(&app, &ctx), 0);
// A path tool shows the Work Path it edits even when the panel selection was cleared.
app.ui.selected_path = None;
for tool in [Tool::Pen, Tool::PathSelection] {
app.ui.tool = tool;
assert!(overlay_shapes(&app, &ctx) > 0, "{tool:?}: path tools draw the Work Path");
}
}
#[test]
fn show_target_path_and_extras_hide_the_path_outlines() {
// #1119: View › Show › Target Path only flipped its checkmark; the canvas kept drawing the