From a67b6ed5ca69638a070e11cb8c36e8d6366f8fc4 Mon Sep 17 00:00:00 2001 From: David Mann Date: Wed, 21 Oct 2026 12:24:49 +0200 Subject: [PATCH] Address CodeRabbit review: narrow two coverage claims, cite evidence as file:line BUG-207-5: only eight retouch tools are tested to follow the Channels panel target (Healing, Spot Healing, Sponge and Remove are skipped by changes_gray). BUG-208-4: the Polygonal Lasso test keeps the selection for Shift or Alt and commits a Shift polygon; no test commits an Alt one. The notes this branch changes now cite file:line, as docs/development.md asks; ui-parity.md gets a dated row for the marquee Shift+Alt test instead of rewriting the 2026-10-11 one. Regenerated docs/scorecard.md. Co-Authored-By: Claude Opus 5.5 --- docs/scorecard.md | 20 ++++++++++---------- docs/ui-parity.md | 3 ++- scorecard/bugs.toml | 4 ++-- scorecard/tools.toml | 4 ++-- scorecard/type.toml | 2 +- scorecard/ui.toml | 2 +- 6 files changed, 18 insertions(+), 17 deletions(-) diff --git a/docs/scorecard.md b/docs/scorecard.md index 42ae824b4d..e6ac874b1c 100644 --- a/docs/scorecard.md +++ b/docs/scorecard.md @@ -8,13 +8,13 @@ Generated by `cargo xtask scorecard` from `perf/budgets.toml`, `perf/baseline.js |---|---:|---:|---:|---| | [Performance](#performance) | 3 | 22 | 25 | 59 scenarios: 3 within budget, 22 over budget or failing, 9 tracked only, 20 not run, 5 not measurable yet (baseline 2026-10-05) | | [File compatibility](#file-compatibility) | 7 | 14 | 6 | io corpus: oracle ≥ 148/170, round trip ≥ 169/170; psd-tools corpus: oracle ≥ 249/309, round trip ≥ 308/309; photoshop oracles: oracle ≥ 188/256, round trip ≥ 258/256 | -| [Tools](#tools) | 33 | 11 | 0 | | -| [Workspace and UI](#workspace-and-ui) | 13 | 6 | 4 | settings that do nothing: 26 of 170 (target 0) | -| [Type](#type) | 4 | 3 | 2 | | +| [Tools](#tools) | 34 | 10 | 0 | | +| [Workspace and UI](#workspace-and-ui) | 13 | 7 | 3 | settings that do nothing: 26 of 170 (target 0) | +| [Type](#type) | 5 | 3 | 1 | | | [Automation](#automation) | 5 | 2 | 4 | 631 of 631 menu items live (100.0%) | | [Reliability](#reliability) | 5 | 2 | 0 | never-crash lints on 30 of 30 crates; panic_hunt present | | [Distribution](#distribution) | 5 | 4 | 2 | | -| [Open bugs](#open-bugs) | 29 | 2 | 1 | | +| [Open bugs](#open-bugs) | 31 | 1 | 0 | | ## Performance @@ -151,7 +151,7 @@ Corpus floors (`crates/io/tests/corpus.rs`): the enforced minimums; the corpus t | TOOL-214-1 | Select and Mask workspace: view modes, Refine Edge brush, 6 outputs | partial | [#214](https://github.com/storytold/photocraft/issues/214) | select.refineEdge dialog with a live preview in Photoshop's view modes: Onion Skin, Marching Ants, Overlay, On Black, On White, Black & White, On Layers, per-view Opacity, Show Edge (J), Show Original (P), F cycles, X shows the image (select_mask_view.rs, #1754); Refine Edge Brush (R, size, Expand Detection Area / Restore Original Edge, Alt swaps) paints select.refineEdge refineStrokes, estimated by colour-line matting (matting/brush.rs, #2972); outputs Selection, Layer Mask, New Layer, New Layer with Mask, New Document, New Document with Mask (#2998); no workspace layout | | TOOL-214-2 | Marquee: Shift square, Alt from centre, live W x H readout | done | [#214](https://github.com/storytold/photocraft/issues/214) | canvas.rs marquee_corners: Shift square or circle, Alt from the centre, live W x H readout beside the cursor (marquee_readout); marquee_tests.rs | | TOOL-214-3 | Color Range test: Sampled Colors at Fuzziness 0 selects the exact match only | done | [#214](https://github.com/storytold/photocraft/issues/214) | color_range_fuzziness_zero_selects_exact_match_only in selection_cmds.rs asserts exact match is selected and 1-level-off pixels are rejected at fuzziness 0; tonal presets covered in color_range_presets | -| TOOL-214-4 | Move tool: box-select layers, Auto-Select hover outline, double-click fit, drag to a tab | partial | [#214](https://github.com/storytold/photocraft/issues/214) | Auto-Select hover outline (Preferences › Tools › Show Highlight on Rollover, #2834) and box-select layers from an empty spot (move_box.rs, layer.selectInRect, #2844) done; double-click fit and drag to a tab open | +| TOOL-214-4 | Move tool: box-select layers, Auto-Select hover outline, double-click fit, drag to a tab | partial | [#214](https://github.com/storytold/photocraft/issues/214) | Auto-Select hover outline (Preferences › Tools › Show Highlight on Rollover, #2834) and box-select layers from an empty spot (move_box.rs:59, layer.selectInRect, #2844) done; dragging layers with the Move tool (or from the Layers panel) onto another document's tab copies them there (layer_transfer.rs:162, layer.copyToDocument, #589/#851); double-click fit and dragging a selection's pixels to another document open | | TOOL-214-5 | Right-click menu during Free Transform (scale, rotate, skew, warp, flip, rotate 90/180) | done | [#214](https://github.com/storytold/photocraft/issues/214) | canvas_tool_menu.rs TRANSFORM_MENU: modes, Content-Aware Scale / Puppet Warp greyed, Rotate 180 / 90 CW / 90 CCW and Flip turn the open box (transform_tool::intercept, #2832) | | TOOL-214-6 | Puppet Warp mesh follows the object outline (constrained triangulation) | done | [#214](https://github.com/storytold/photocraft/issues/214) | algo/puppet.rs build_mesh: traced outline of the opaque region grown by Expansion, triangulated with a Density-spaced lattice (conforming Delaunay); separate shapes get separate meshes (#3105) | | TOOL-214-7 | Content-Aware Scale through the Free Transform box with a live proxy preview | done | [#214](https://github.com/storytold/photocraft/issues/214) | Edit > Content-Aware Scale opens a scale-only Free Transform box (cas_transform.rs) with Amount, Protect and Protect Skin Tones in the options bar; edit.contentAwareScale carves a 384 px copy in the background for the live preview, and Enter runs it with the box's size and x/y as one step (#3096) | @@ -160,7 +160,7 @@ Corpus floors (`crates/io/tests/corpus.rs`): the enforced minimums; the corpus t | TOOL-214-10 | Pen: Alt breaks a handle, Shift 45 deg, Ctrl direct-selects, Backspace, close-drag handle | done | [#214](https://github.com/storytold/photocraft/issues/214) | Ctrl/Cmd = Direct Selection and Alt = Convert Point on existing paths (direct_select.rs, #790); Backspace/Delete retracts the last point while drawing (#1466); Alt during a drag breaks the handle pair, Alt-drag turns the last anchor's outgoing handle alone, and dragging on the first anchor closes with that anchor's handles (vector_ui.rs, #3306); Shift-click puts the next anchor on the nearest 45 deg ray from the previous one and Shift-drag turns the handles to 45 deg steps, live (vector_ui.rs pen_shift_click_puts_the_next_anchor_on_a_45_degree_ray, pen_shift_drag_turns_handles_to_45_degrees_live, #3751) | | TOOL-214-11 | Stroke Path dialog: pick any brush-based tool, Simulate Pressure | done | [#214](https://github.com/storytold/photocraft/issues/214) | path.stroke tool: Brush, Pencil, Eraser and every other brush-based tool (Background Eraser, Clone/Pattern Stamp, Healing/Spot Healing Brush, History Brush, Blur, Sharpen, Smudge, Dodge, Burn, Sponge, Color Replacement, Mixer Brush: their paint.* command along the path, one step) plus simulatePressure (taper both ends); Stroke Path dialog from the Pen menu, the Paths panel menu and Alt-click on its Stroke button (#2978) | | TOOL-214-12 | Shapes: on-canvas corner radius handles, shape feather, selection to shape with tolerance | partial | [#214](https://github.com/storytold/photocraft/issues/214) | On-canvas corner radius widgets on every selected live rectangle with Path Selection, the Rectangle tool and Move + Show Transform Controls: drag rounds every corner of every selected rectangle alike, Alt that corner on each, corner radius cursor and R: readout, one history step (corner_radius.rs, 2026-10-13); select.convertToShape with tolerance (vector_cmds.rs:1256). Missing: shape feather | -| TOOL-214-13 | Mask Properties: Density and Feather controls | partial | [#214](https://github.com/storytold/photocraft/issues/214) | Vector-mask density/feather in the engine (vector_cmds.rs:948); no UI controls | +| TOOL-214-13 | Mask Properties: Density and Feather controls | done | [#214](https://github.com/storytold/photocraft/issues/214) | Properties panel shows Density (%) and Feather (px) sliders for a targeted pixel mask (layer.layerMask.edit) and a targeted vector mask (layer.vectorMask.edit), non-destructive and one undo step per drag, with Photoshop's Refine row (mask_props_ui.rs:34 pixel mask, :48 vector mask, :52 the sliders; mask_props_ui_tests.rs:39 pixel_mask_properties_follow_target_for_raster_and_adjustment_in_both_themes, :81 mask_slider_drags_preview_live_and_undo_as_separate_gestures, :147 vector_mask_properties_edit_density_and_feather) | | TOOL-214-14 | Vanishing Point window: draw and edit planes, paste, clone in perspective | partial | [#214](https://github.com/storytold/photocraft/issues/214) | filter.vanishingPoint (vp_cmds.rs:15); on-canvas plane editor (vp_ui.rs: Create/Edit Plane, edge nodes, valid/doubtful/invalid grid colours, Grid Size, clipboard pasted onto the plane on OK); clone stamp, marquee and tear-off planes in the window still missing | | TOOL-214-15 | Content-Aware Fill workspace: paint the sampling area, preview, rotate/scale/mirror, new layer | partial | [#214](https://github.com/storytold/photocraft/issues/214) | Engine sampling auto, rect, custom (edit_menu_cmds.rs:324); generic dialog | | TOOL-214-16 | Liquify: redo (Cmd+Shift+Z) | done | [#214](https://github.com/storytold/photocraft/issues/214) | liquify_ui.rs supports bounded redo through Cmd+Shift+Z and the control channel; new strokes clear redo | @@ -203,7 +203,7 @@ Unread: `general.color_picker`, `general.animated_zoom`, `general.zoom_resizes_w | UI-217-15 | Curves: smoothing / pencil mode, black/grey/white eyedroppers, tooltips | done | [#217](https://github.com/storytold/photocraft/issues/217) | Curves editor (adjust_editors.rs, dialog and Properties): Edit points / Draw (pencil) buttons and Smooth, all with tooltips; pencil curves are 256-level maps (Adjustment::Curves pencil, params pencil/smooth, PSD curv map form and smart-filter Mpng; #3088). Set Black/Neutral Gray/White Point eyedroppers in the Image > Adjustments > Curves dialog (adjust_dialog.rs, #873) and in a Curves adjustment layer's Properties panel (layer_picker.rs: a click on the image is one layer.setAdjustment with the eyedropper param, sampling below the layer; Esc or another tool disarms; #3110) | | UI-217-16 | Hue/Saturation: Saturation and Lightness sliders get hue-following colour tracks | done | [#217](https://github.com/storytold/photocraft/issues/217) | saturation_track/lightness_track (adjust_editors.rs): grey -> the hue and black -> the hue -> white, recolouring as the Hue slider moves; saturation_and_lightness_tracks_follow_the_hue | | UI-217-17 | Color panel: wheel plus RGB/HSB/CMYK/Lab/Gray/Web slider modes; resizes with its group | missing | [#217](https://github.com/storytold/photocraft/issues/217) | panels.rs:1837 single field + hex/RGB readout | -| UI-217-18 | Alt+wheel zooms in gentle ~5 % steps; zoom controls uncramped | missing | [#217](https://github.com/storytold/photocraft/issues/217) | canvas.rs:1107-1125 no Alt handling | +| UI-217-18 | Alt+wheel zooms in gentle ~5 % steps; zoom controls uncramped | partial | [#217](https://github.com/storytold/photocraft/issues/217) | Alt+wheel zooms around the pointer, one step per notch applied the frame it arrives (wheel_nav.rs:94; input_tests.rs:443 alt_scroll_zooms_in_steps_around_the_pointer, wheel_nav.rs:448 alt_scroll_zooms_ten_percent_per_notch), but the step is x1.1 (10 %), not the ~5 % this row asks for: #1718 changed it from x1.05 after measuring Photoshop, so the row's target is in question. Status bar zoom field and Fit button fit inside the bar in every theme (status_bar_tests.rs:39 status_bar_controls_sit_inside_the_bar_with_even_margins, #2823); the Navigator zoom controls are not checked | | UI-217-19 | Shortcut hints rendered per platform; Reveal label per OS | done | [#217](https://github.com/storytold/photocraft/issues/217) | hints and tooltips go through shortcuts::pretty (6266b7a9, #262; pretty_uses_the_platform_notation); menus::reveal_label names Reveal in Finder per OS (Show in Explorer / Show in Folder) in the Smart Objects menu and the tab menu; reveal_label_names_the_platform_file_manager + smart_objects_reveal_item_names_the_platform_file_manager | | UI-217-20 | 'Show rulers in new documents' preference; guides stored as f64 | done | [#217](https://github.com/storytold/photocraft/issues/217) | View › Rulers is remembered in unitsAndRulers.showRulers and applied at launch and on change (#2918; rulers_open_as_last_set_after_a_restart); doc Guides are Vec through New Guide, .pcraft and PSD 1032 (guides_keep_sub_pixel_positions_through_pcraft_and_psd) | | UI-217-21 | One Preset Manager for every preset kind with folders, search, reorder, load/save sets | partial | [#217](https://github.com/storytold/photocraft/issues/217) | edit_menu_cmds.rs:714 covers brushes, custom shapes, patterns with reorder | @@ -220,7 +220,7 @@ Unread: `general.color_picker`, `general.animated_zoom`, `general.zoom_resizes_w | TYPE-218-4 | Variable font axis sliders from the font's axes; opsz follows the point size | done | [#218](https://github.com/storytold/photocraft/issues/218) | One slider per axis of the style's font in the Character section (Properties and Window > Character), setting type.setStyle variations; opsz follows the type size unless set (layout.rs variation_list); a style or weight resets the wght axis (#2985). PSD does not round-trip axis values yet | | TYPE-218-5 | OpenType UI: Character panel buttons, Numerals and Stylistic Sets submenus | partial | [#218](https://github.com/storytold/photocraft/issues/218) | Type > OpenType toggles (type_extra_cmds.rs:512). Character panel (and the Properties Character section) has Photoshop's eight OpenType buttons: Standard Ligatures, Contextual Alternates, Discretionary Ligatures, Swash, Stylistic Alternates, Titling Alternates, Ordinals, Fractions, pressed while the feature is on at the selection and dispatching the type.openType.* commands (type_tool.rs opentype_row; character_panel_opentype_buttons_toggle_and_show_the_feature, #3752). Still missing: the Numerals and Stylistic Sets submenus, and greying out features the font lacks | | TYPE-218-6 | Manual pair kerning (Alt+arrows), optical kerning rendered, both round-trip PSD (#206) | done | [#218](https://github.com/storytold/photocraft/issues/218) | Alt+Left/Right at a collapsed caret kerns the pair (type_tool.rs kern_pair, 20 per step and 100 with Cmd; type_tool_alt_arrows_kern_the_pair). Optical kerning is computed from the glyph outlines in text/src/optical.rs and applied by layout.rs when the run's mode is Optical (optical_matches_photoshop, optical_kerning_tightens_open_pairs). Both modes and manual values round-trip through PSD (io/tests/psd_kerning.rs; the optical mode travels in Txt2, txt2_carries_optical_kerning) | -| TYPE-218-7 | Warp Text dialog previews live and opens with the layer's current warp | missing | [#218](https://github.com/storytold/photocraft/issues/218) | view_cmds.rs:834 always seeds arc, bend 50 | +| TYPE-218-7 | Warp Text dialog previews live and opens with the layer's current warp | done | [#218](https://github.com/storytold/photocraft/issues/218) | Type > Warp Text opens with the shown layer's warp, or None, never remembered values (filter_dialog.rs:503 warp_defaults; warp_text_dialog_tests.rs:80 warp_text_opens_with_the_type_layers_current_warp, :99 warp_text_opens_at_none_for_a_layer_without_warp, :108 remembered_warp_values_never_override_the_layers_warp). The dialog previews live without editing the document, Cancel leaves no step and OK is one undoable step (:138 warp_text_dialog_previews_the_warp_without_editing_the_document, :160 cancelling_warp_text_leaves_the_document_and_history_untouched, :179 confirming_warp_text_is_one_undoable_step); the reduced-proxy preview matches the full-size result (filter_dialog.rs:2150 warp_text_preview_matches_the_full_size_result_on_a_reduced_proxy) | | TYPE-218-8 | Text editing: select all, double/triple/quadruple-click selection, paste, with tests | done | [#218](https://github.com/storytold/photocraft/issues/218) | Like Photoshop, 2 clicks select the word, 3 the laid-out line (a column in vertical type), 4 the paragraph up to the hard return, 5 all text, and the next quick click starts over (#3493; type_tool.rs next_click_count, click_selection, multi_click). Tested through real canvas clicks in point, paragraph and vertical type, with paste replacing the selection and Cmd+A selecting all (type_tool_tests.rs multi_click_selects_word_line_paragraph_and_all_in_point_text, multi_click_separates_wrapped_lines_from_paragraphs, click_counts_cycle_and_restart, click_selection_without_layout_and_on_hostile_input, multi_click_without_a_session_does_nothing) | | TYPE-218-9 | Distort/Perspective/Warp on live type as in Photoshop (was: offer 'Rasterize and continue?'; Photoshop doesn't prompt) | done | [#218](https://github.com/storytold/photocraft/issues/218) | Photoshop 2026 prompts for none of these: Edit › Transform › Warp on live type stays enabled with no rasterize prompt and offers only the warp styles (the mesh can't be dragged), so the type stays editable; Distort, Perspective and the split warps are greyed. PhotoCraft does the same: Warp on type commits the layer's Warp Text in one step (transform_tool.rs enter_type_warp, warp_cmds.rs warp_type_layer, #3004; warp_on_type_takes_a_style_and_keeps_the_type_editable), Distort/Perspective greyed (enable_rules.rs, #2701) | @@ -302,9 +302,9 @@ Never-crash attribute on 30 of 30 crate roots. | BUG-207-2 | Sample All Layers applies to Blur, Sharpen and Smudge | done | [#207](https://github.com/storytold/photocraft/issues/207) | retouch_ui.rs passes sampleAllLayers to paint.blur/sharpen/smudge; sample_all_layers_reaches_the_command (e2444ce, #234) | | BUG-207-3 | Smudge mixes premultiplied RGBA (no dark fringe at transparent edges) | done | [#207](https://github.com/storytold/photocraft/issues/207) | paint/src/retouch.rs premultiplies; smudge_into_transparency_leaves_no_dark_fringe (e2444ce, #234) | | BUG-207-4 | edit.transform transforms a targeted alpha channel | done | [#207](https://github.com/storytold/photocraft/issues/207) | edit.transform follows a targeted alpha channel or Quick Mask (explicit target since #242, Channels panel target with no target/layer param since #2835); Edit > Transform > Rotate/Flip are routed to the target too; transforms_follow_the_targeted_alpha_channel | -| BUG-207-5 | Tests: per-tool mask/channel targeting, Sample All Layers, no smudge fringe | missing | [#207](https://github.com/storytold/photocraft/issues/207) | Only smudge_drags_colour_along_the_stroke (retouch.rs:407) | +| BUG-207-5 | Tests: per-tool mask/channel targeting, Sample All Layers, no smudge fringe | done | [#207](https://github.com/storytold/photocraft/issues/207) | Every retouch tool (Clone Stamp, Pattern Stamp, Healing, Spot Healing, Dodge, Burn, Sponge, Blur, Sharpen, Smudge, History Brush, Remove) is tested to paint only a targeted mask and only a targeted alpha channel (engine retouch_cmds/tests.rs:786 retouch_tools_paint_only_the_targeted_mask, :805 retouch_tools_paint_only_the_targeted_alpha_channel; Healing, Spot Healing, Sponge and Remove are checked to leave the rest untouched, not to change the target, since they may leave grey noise as it was); the other eight follow the Channels panel target (:822 retouch_tools_follow_the_channels_panel_target); Quick Mask and bad targets: :840 retouch_tools_paint_the_quick_mask, :853 retouch_targets_fail_gracefully. Sample All Layers changes the result over two layers (:879 sample_all_layers_blur_and_sharpen_work_on_an_empty_layer, :907 sample_all_layers_smudge_drags_colour_from_below, :923 sample_all_layers_spot_healing_heals_onto_an_empty_layer, :313 clone_stamp_sample_all_layers_onto_empty_layer_and_opacity; ui retouch_ui.rs:818 sample_all_layers_reaches_the_command); no smudge fringe (:942 smudge_across_a_transparent_edge_has_no_dark_fringe). Brush/Eraser/Gradient/Bucket targets: engine tests.rs:1263 painting_can_target_the_layer_mask, channel_cmds/tests.rs:301 painting_filtering_and_adjusting_into_an_alpha_channel. Not covered: Pencil and Mixer Brush into a mask or channel; the Channels panel target for Healing, Spot Healing, Sponge and Remove | | BUG-208-1 | Shift while dragging a Rect/Elliptical Marquee constrains to a square/circle | done | [#208](https://github.com/storytold/photocraft/issues/208) | canvas.rs marquee_corners applies Shift via Drag::marquee_mods; marquee_tests.rs::shift_during_the_drag_draws_a_square_and_the_readout_follows covers the drag | | BUG-208-2 | Alt while dragging a marquee draws from the centre | done | [#208](https://github.com/storytold/photocraft/issues/208) | canvas.rs marquee_corners centres Alt drags; marquee_tests.rs::alt_draws_from_the_centre_and_shift_alt_a_centred_circle verifies rectangles and ellipses | | BUG-208-3 | W x H px readout beside the cursor while dragging a marquee | done | [#208](https://github.com/storytold/photocraft/issues/208) | canvas.rs marquee_readout draws the readout; marquee_tests.rs asserts dimensions while dragging and its removal after release | -| BUG-208-4 | Add/subtract/intersect from modifiers pressed before the drag, kept by a test | partial | [#208](https://github.com/storytold/photocraft/issues/208) | Mods captured at press (canvas.rs:1679, used :1779); only a badge test (tool_feedback.rs:195) | +| BUG-208-4 | Add/subtract/intersect from modifiers pressed before the drag, kept by a test | done | [#208](https://github.com/storytold/photocraft/issues/208) | Mods captured at press. Marquee: Shift at the press adds and Alt subtracts, with no square or centring (ui-egui marquee_tests.rs:361 modifiers_held_before_the_drag_pick_the_mode_not_the_shape), and Shift+Alt held at the press intersects (marquee_tests.rs:410 shift_alt_before_the_drag_intersects_the_selection). Lasso: Alt, Shift and Shift+Alt at the start subtract, add and intersect (lasso_ui/tests.rs:96 initial_alt_still_subtracts_and_initial_shift_still_adds). Polygonal Lasso: Shift or Alt at the first click keeps the selection in view, and a Shift polygon adds to it (polygon_lasso_tests.rs:209 modifiers_at_the_first_click_keep_and_combine_the_selection); no test commits an Alt (subtract) polygon | | BUG-208-5 | Kittest: Shift drag gives a square, Alt drag is centred, readout matches the size | done | [#208](https://github.com/storytold/photocraft/issues/208) | crates/ui-egui/src/marquee_tests.rs covers Shift, Alt, selection bounds, W/H readout and drag completion | diff --git a/docs/ui-parity.md b/docs/ui-parity.md index 45a4750f6a..d7275bc691 100644 --- a/docs/ui-parity.md +++ b/docs/ui-parity.md @@ -1,6 +1,6 @@ # UI parity: tools, handles, modifiers and feel -> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-15 · **Change:** minor (Pen Auto Add/Delete on the path being drawn, #6140; Show Transform Controls frames every selected layer; guide keys and clicks; menu bar from the keyboard, #4988; Crop tool Content-Aware Fill; on-canvas corner radius widgets, TOOL-214-12; Curvature Pen edits the active path; Clip Thumbnails to Layer Bounds; Pen ⇧ 45°; last selected tool restored at launch; Layers panel filter-type dropdown with Kind, Name and Mode, #5048; Free Transform box and marching ants follow the selection, #5297; History: the trash deletes the selected snapshot, rows drag onto the trash, #5324; smart filter reordering by drag; smart object perspective row corrected to done, #426; Free Transform H/V skew fields; toolbar tool shortcuts can be reassigned; ⇧-dragged guides land on ruler ticks; layer and selection keys; tool keys; spring-loaded tool letters; type formatting keys; Pen Auto Add/Delete, #4144; smart filter rows; stale missing-tool rows corrected: Color Replacement, Red Eye and the Add/Delete Anchor Point pair are live toolbar tools, Frame landed; no percentage changed; selection-modifier and ⌥-wheel rows match their tests) · **Target:** Adobe Photoshop 2026 +> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-21 · **Change:** minor (Pen Auto Add/Delete on the path being drawn, #6140; Show Transform Controls frames every selected layer; guide keys and clicks; menu bar from the keyboard, #4988; Crop tool Content-Aware Fill; on-canvas corner radius widgets, TOOL-214-12; Curvature Pen edits the active path; Clip Thumbnails to Layer Bounds; Pen ⇧ 45°; last selected tool restored at launch; Layers panel filter-type dropdown with Kind, Name and Mode, #5048; Free Transform box and marching ants follow the selection, #5297; History: the trash deletes the selected snapshot, rows drag onto the trash, #5324; smart filter reordering by drag; smart object perspective row corrected to done, #426; Free Transform H/V skew fields; toolbar tool shortcuts can be reassigned; ⇧-dragged guides land on ruler ticks; layer and selection keys; tool keys; spring-loaded tool letters; type formatting keys; Pen Auto Add/Delete, #4144; smart filter rows; stale missing-tool rows corrected: Color Replacement, Red Eye and the Add/Delete Anchor Point pair are live toolbar tools, Frame landed; no percentage changed; selection-modifier and ⌥-wheel rows match their tests) · **Target:** Adobe Photoshop 2026 How PhotoCraft's direct manipulation compares with Photoshop 2026 (27.11.0): the toolbox, the handles and modifier keys of each gesture, nudging, snapping, numeric precision, navigation, @@ -243,6 +243,7 @@ Paragraph; the rest open as in-app floating windows. | 2026-10-11 | minor | Spring-loaded tool letters done (#2672): holding any tool letter (Z included) past 300 ms, or using the canvas while it is down, makes the tool temporary until release | | 2026-10-11 | minor | Type formatting keys done: ⇧⌘K, U, B, I and /, ⌥↑/↓, ⇧⌥↑/↓, ⌥←/→ over a selection and ⌥⇧⌘H format the selected type while editing, and no longer reach Color Settings, Desaturate, Auto Color or Inverse | | 2026-10-11 | minor | Selection modifiers at press: evidence now names the marquee, Lasso and Polygonal Lasso tests (still partial: no marquee ⇧⌥ intersect test). ⌥-wheel zoom: missing → partial (works at ×1.1 a notch; #217 asked for ~5 %) | +| 2026-10-21 | minor | Selection modifiers at press: partial → done; the marquee ⇧⌥ intersect test (`marquee_tests.rs` `shift_alt_before_the_drag_intersects_the_selection`) closed the gap the 2026-10-11 row names (BUG-208-4) | | 2026-10-12 | minor | Pen Auto Add/Delete on the active path, with its options-bar checkbox, hover feedback and + / − cursor badge (#4144) | | 2026-10-15 | minor | Pen Auto Add/Delete works on the path being drawn: a click on its segment adds an anchor, on a middle anchor deletes it, and drawing carries on (#6140) | | 2026-10-12 | minor | Toolbar tool shortcuts can be reassigned, removed and reset in Keyboard Shortcuts (#4086); capture, restart, group cycling, conflict and text-focus regressions | diff --git a/scorecard/bugs.toml b/scorecard/bugs.toml index eb1bb58e55..a8d0358b55 100644 --- a/scorecard/bugs.toml +++ b/scorecard/bugs.toml @@ -193,7 +193,7 @@ id = "BUG-207-5" target = "Tests: per-tool mask/channel targeting, Sample All Layers, no smudge fringe" status = "done" issue = 207 -note = "Every retouch tool (Clone Stamp, Pattern Stamp, Healing, Spot Healing, Dodge, Burn, Sponge, Blur, Sharpen, Smudge, History Brush, Remove) is tested to paint only a targeted mask, only a targeted alpha channel, and to follow the Channels panel target (engine retouch_cmds/tests.rs retouch_tools_paint_only_the_targeted_mask, retouch_tools_paint_only_the_targeted_alpha_channel, retouch_tools_follow_the_channels_panel_target, retouch_tools_paint_the_quick_mask, retouch_targets_fail_gracefully). Sample All Layers changes the result over two layers (sample_all_layers_blur_and_sharpen_work_on_an_empty_layer, sample_all_layers_smudge_drags_colour_from_below, sample_all_layers_spot_healing_heals_onto_an_empty_layer, clone_stamp_sample_all_layers_onto_empty_layer_and_opacity; ui retouch_ui.rs sample_all_layers_reaches_the_command); no smudge fringe (smudge_across_a_transparent_edge_has_no_dark_fringe). Brush/Eraser/Gradient/Bucket targets: tests.rs painting_can_target_the_layer_mask, channel_cmds/tests.rs painting_filtering_and_adjusting_into_an_alpha_channel. Not covered: Pencil and Mixer Brush into a mask or channel" +note = "Every retouch tool (Clone Stamp, Pattern Stamp, Healing, Spot Healing, Dodge, Burn, Sponge, Blur, Sharpen, Smudge, History Brush, Remove) is tested to paint only a targeted mask and only a targeted alpha channel (engine retouch_cmds/tests.rs:786 retouch_tools_paint_only_the_targeted_mask, :805 retouch_tools_paint_only_the_targeted_alpha_channel; Healing, Spot Healing, Sponge and Remove are checked to leave the rest untouched, not to change the target, since they may leave grey noise as it was); the other eight follow the Channels panel target (:822 retouch_tools_follow_the_channels_panel_target); Quick Mask and bad targets: :840 retouch_tools_paint_the_quick_mask, :853 retouch_targets_fail_gracefully. Sample All Layers changes the result over two layers (:879 sample_all_layers_blur_and_sharpen_work_on_an_empty_layer, :907 sample_all_layers_smudge_drags_colour_from_below, :923 sample_all_layers_spot_healing_heals_onto_an_empty_layer, :313 clone_stamp_sample_all_layers_onto_empty_layer_and_opacity; ui retouch_ui.rs:818 sample_all_layers_reaches_the_command); no smudge fringe (:942 smudge_across_a_transparent_edge_has_no_dark_fringe). Brush/Eraser/Gradient/Bucket targets: engine tests.rs:1263 painting_can_target_the_layer_mask, channel_cmds/tests.rs:301 painting_filtering_and_adjusting_into_an_alpha_channel. Not covered: Pencil and Mixer Brush into a mask or channel; the Channels panel target for Healing, Spot Healing, Sponge and Remove" [[item]] id = "BUG-208-1" @@ -221,7 +221,7 @@ id = "BUG-208-4" target = "Add/subtract/intersect from modifiers pressed before the drag, kept by a test" status = "done" issue = 208 -note = "Mods captured at press. Marquee: Shift at the press adds and Alt subtracts, with no square or centring (marquee_tests.rs modifiers_held_before_the_drag_pick_the_mode_not_the_shape). Lasso: Alt, Shift and Shift+Alt at the start subtract, add and intersect (lasso_ui/tests.rs initial_alt_still_subtracts_and_initial_shift_still_adds). Polygonal Lasso: Shift/Alt at the first click keep the selection and combine (polygon_lasso_tests.rs modifiers_at_the_first_click_keep_and_combine_the_selection). Marquee Shift+Alt held at the press intersects (marquee_tests.rs shift_alt_before_the_drag_intersects_the_selection)" +note = "Mods captured at press. Marquee: Shift at the press adds and Alt subtracts, with no square or centring (ui-egui marquee_tests.rs:361 modifiers_held_before_the_drag_pick_the_mode_not_the_shape), and Shift+Alt held at the press intersects (marquee_tests.rs:410 shift_alt_before_the_drag_intersects_the_selection). Lasso: Alt, Shift and Shift+Alt at the start subtract, add and intersect (lasso_ui/tests.rs:96 initial_alt_still_subtracts_and_initial_shift_still_adds). Polygonal Lasso: Shift or Alt at the first click keeps the selection in view, and a Shift polygon adds to it (polygon_lasso_tests.rs:209 modifiers_at_the_first_click_keep_and_combine_the_selection); no test commits an Alt (subtract) polygon" [[item]] id = "BUG-208-5" diff --git a/scorecard/tools.toml b/scorecard/tools.toml index aaf7514d2e..146fac05ae 100644 --- a/scorecard/tools.toml +++ b/scorecard/tools.toml @@ -136,7 +136,7 @@ id = "TOOL-214-4" target = "Move tool: box-select layers, Auto-Select hover outline, double-click fit, drag to a tab" status = "partial" issue = 214 -note = "Auto-Select hover outline (Preferences › Tools › Show Highlight on Rollover, #2834) and box-select layers from an empty spot (move_box.rs, layer.selectInRect, #2844) done; dragging layers with the Move tool (or from the Layers panel) onto another document's tab copies them there (layer_transfer.rs, layer.copyToDocument, #589/#851); double-click fit and dragging a selection's pixels to another document open" +note = "Auto-Select hover outline (Preferences › Tools › Show Highlight on Rollover, #2834) and box-select layers from an empty spot (move_box.rs:59, layer.selectInRect, #2844) done; dragging layers with the Move tool (or from the Layers panel) onto another document's tab copies them there (layer_transfer.rs:162, layer.copyToDocument, #589/#851); double-click fit and dragging a selection's pixels to another document open" [[item]] id = "TOOL-214-5" @@ -199,7 +199,7 @@ id = "TOOL-214-13" target = "Mask Properties: Density and Feather controls" status = "done" issue = 214 -note = "Properties panel shows Density (%) and Feather (px) sliders for a targeted pixel mask (layer.layerMask.edit) and a targeted vector mask (layer.vectorMask.edit), non-destructive and one undo step per drag, with Photoshop's Refine row (mask_props_ui.rs; mask_props_ui_tests.rs pixel_mask_properties_follow_target_for_raster_and_adjustment_in_both_themes, mask_slider_drags_preview_live_and_undo_as_separate_gestures, vector_mask_properties_edit_density_and_feather)" +note = "Properties panel shows Density (%) and Feather (px) sliders for a targeted pixel mask (layer.layerMask.edit) and a targeted vector mask (layer.vectorMask.edit), non-destructive and one undo step per drag, with Photoshop's Refine row (mask_props_ui.rs:34 pixel mask, :48 vector mask, :52 the sliders; mask_props_ui_tests.rs:39 pixel_mask_properties_follow_target_for_raster_and_adjustment_in_both_themes, :81 mask_slider_drags_preview_live_and_undo_as_separate_gestures, :147 vector_mask_properties_edit_density_and_feather)" [[item]] id = "TOOL-214-14" diff --git a/scorecard/type.toml b/scorecard/type.toml index 1cf4adaba3..88aab270bb 100644 --- a/scorecard/type.toml +++ b/scorecard/type.toml @@ -51,7 +51,7 @@ id = "TYPE-218-7" target = "Warp Text dialog previews live and opens with the layer's current warp" status = "done" issue = 218 -note = "Type > Warp Text opens with the shown layer's warp, or None, never remembered values (filter_dialog.rs warp_defaults; warp_text_dialog_tests.rs warp_text_opens_with_the_type_layers_current_warp, warp_text_opens_at_none_for_a_layer_without_warp, remembered_warp_values_never_override_the_layers_warp). The dialog previews live without editing the document, Cancel leaves no step and OK is one undoable step (warp_text_dialog_previews_the_warp_without_editing_the_document, cancelling_warp_text_leaves_the_document_and_history_untouched, confirming_warp_text_is_one_undoable_step); the reduced-proxy preview matches the full-size result (filter_dialog.rs warp_text_preview_matches_the_full_size_result_on_a_reduced_proxy)" +note = "Type > Warp Text opens with the shown layer's warp, or None, never remembered values (filter_dialog.rs:503 warp_defaults; warp_text_dialog_tests.rs:80 warp_text_opens_with_the_type_layers_current_warp, :99 warp_text_opens_at_none_for_a_layer_without_warp, :108 remembered_warp_values_never_override_the_layers_warp). The dialog previews live without editing the document, Cancel leaves no step and OK is one undoable step (:138 warp_text_dialog_previews_the_warp_without_editing_the_document, :160 cancelling_warp_text_leaves_the_document_and_history_untouched, :179 confirming_warp_text_is_one_undoable_step); the reduced-proxy preview matches the full-size result (filter_dialog.rs:2150 warp_text_preview_matches_the_full_size_result_on_a_reduced_proxy)" [[item]] id = "TYPE-218-8" diff --git a/scorecard/ui.toml b/scorecard/ui.toml index 783ed9b9bf..53c6bedbaa 100644 --- a/scorecard/ui.toml +++ b/scorecard/ui.toml @@ -129,7 +129,7 @@ id = "UI-217-18" target = "Alt+wheel zooms in gentle ~5 % steps; zoom controls uncramped" status = "partial" issue = 217 -note = "Alt+wheel zooms around the pointer, one step per notch applied the frame it arrives (wheel_nav.rs; input_tests.rs alt_scroll_zooms_in_steps_around_the_pointer, wheel_nav.rs alt_scroll_zooms_ten_percent_per_notch), but the step is x1.1 (10 %), not the ~5 % this row asks for: #1718 changed it from x1.05 after measuring Photoshop, so the row's target is in question. Status bar zoom field and Fit button fit inside the bar in every theme (status_bar_tests.rs status_bar_controls_sit_inside_the_bar_with_even_margins, #2823); the Navigator zoom controls are not checked" +note = "Alt+wheel zooms around the pointer, one step per notch applied the frame it arrives (wheel_nav.rs:94; input_tests.rs:443 alt_scroll_zooms_in_steps_around_the_pointer, wheel_nav.rs:448 alt_scroll_zooms_ten_percent_per_notch), but the step is x1.1 (10 %), not the ~5 % this row asks for: #1718 changed it from x1.05 after measuring Photoshop, so the row's target is in question. Status bar zoom field and Fit button fit inside the bar in every theme (status_bar_tests.rs:39 status_bar_controls_sit_inside_the_bar_with_even_margins, #2823); the Navigator zoom controls are not checked" [[item]] id = "UI-217-19"