Main's #11383 renamed an arrow-key run's History step to "Nudge", as the reference
application names it; #10438's new zoomed-out test still expected "Move".
Co-Authored-By: hectorviov <hectorviov@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review fix-ups on #11249 after merging main:
- A midpoint outside 5..95 %, transparency stops out of range or out of
order, and a Gradient Fill Set without transparency stops stay
reference-application steps instead of playing clamped or keeping the
layer's own transparency.
- An inverted Blend If range stays a reference-application step; the
command rejects it at play.
- The Layer Style dialog's OK records `Lefx` = {Scl} beside Blend If on a
layer without effects (measured). That Set is still the dialog's one
step and saves back with the `Lefx` it was recorded with.
Co-Authored-By: NaufalDzz <90562913+NaufalDzz@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Main added Effect, Attribute, Color, Smart Object and Artboard to the Layers
panel filter. Group is now the last type in the list, and works like Artboard:
`Filter::with_selection` fills the listed rows once per frame from
`group::listed`, so the panel, the deselect-on-apply step (#10879) and the
control channel all see the same rows; `shows_in`/`group_ids` and the
layers.rs change are gone. This also removes the duplicate `mod group;` and
`mod tests;` lines (E0428) and the rustfmt issues from the review.
- `group::listed` walks the tree with a stack instead of recursion and
returns `LayerId`s.
- `Filter::show_all` is documented: Group keeps each group open or closed.
- Tests go through `Filter::of_app` and `panel_rows`, as the panel does,
plus a deselect-on-apply case and a document without groups.
- control-protocol.md: `group` added to main's `layerFilter` entry.
Co-Authored-By: Nurana100 <Nurana100@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Single Row / Column Marquee: a drag from inside the selection moves it (#11392)
`selection_drag_kind` lists the Single Row and Single Column Marquee with the
other marquees, so a plain drag that starts inside the selection moves the
outline (one step, as the Rectangular Marquee's move) instead of replacing it
with one new line. A click inside without moving still selects a line
(`finish_gesture`), never deselects, and snaps it as a click outside the
selection does (`snap_ui::snap_click`: guides, grid, layers and document bounds,
not the selection's own edges, which would pick the line beside a 1 px one). A
click on a floating piece drops it where it is first, then selects the line.
⇧ / ⌥ and drags from outside are unchanged.
A selection drag is a click only when the pointer, before snapping, never left
the press by half a pixel or more (`Drag::left_press`, `selection_release`); a
click ends where it was pressed, unsnapped, as with snapping off. With View ›
Snap on, a click inside a selection whose edge sat within reach of a guide or
the canvas edge moved it onto that edge instead of selecting the line (or, with
the Rectangular and Elliptical Marquee, deselecting). `tool_input` passes the
classification on (`finish_release`), so a drag that snapping pulls back to
where it started, or that comes back there, leaves the selection as it was
instead of taking the click's path.
Fixes#11392
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Selection drags: judge a press inside the selection before snapping (#11392)
The press handler asked `selection_drag_kind` about the snapped press point. With
View › Snap on, a press just outside a selected row snapped onto the row's edge
and counted as inside, so a Single Row / Column Marquee drag from there moved the
selection instead of selecting a new line. It now asks about the press as it
was, as `snap_ui::begin` does when it picks the drag's snapping.
The Move tool's click shortcut also needs the pointer never to have left the
press (`Drag::left_press`): a drag that snapping held at the press point and that
came back there dropped a floating piece. A drag that ends unmoved without being
a click now clears the floating piece's move preview, which nothing else
releases on that path.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: FredApps <153173854+FredApps@users.noreply.github.com>
The new `"stepName":"Transform Path"` parameter made the registry probe in
registry_filesystem_path_params_are_classified count edit.transform as a
command that takes a host filesystem path. Add it to the vector-path list.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- #11458: the straight-crop rows also check that the active layer's pixels
inside the old canvas are the plain crop's, so a fill that recolours them
fails.
- #11295: the Esc case sends the key through shortcuts::handle instead of
calling cancel directly.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The test accepted an added Nudge step; layer.translate records nothing for
a zero offset, so require unchanged entries.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- #11500: a filter that matches no layer draws no row, so the empty-area
right-click was never created; the whole empty list now takes it.
- #11532: flipping the pen to its eraser end is a tool switch, so Add New
Artboard's placing mode ends as with any other switch.
Tests for both (the Layers one fails without the fix).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- menus/parity.rs: #11503 lowered FLOOR to 658 (two Warp rows went);
with #11497's two entries the batch has 660 live again.
- #11443: a nudge that changed nothing (zero offset) no longer renames
the state on top to "Nudge".
- #11295: a handle drag remembers its tool and ends on any tool switch,
also to another tool that shows the box; the release of a drag that was
just dropped is consumed instead of reaching the new tool; the box is
drawn only over the active document's view.
Tests for each (both new UI tests fail without their fix).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
In the app (background jobs on) edit.transform runs as a job and lands
after app.run returns, so renaming the top History step to "Transform
Path" right away renamed the step before it (the second shape's "New
Shape Layer") and left the scale as "Free Transform". Found in the batch
smoke run; the PR's tests run with background jobs off.
edit.transform now takes stepName "Transform Path" (any other name is
refused, as select.transformSelection's stepName from #11444), and the box
passes it instead of renaming afterwards. New tests: the box with
background jobs on (fails without the fix), and the parameter.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Channels: the panel menu has the channel commands, New Spot Channel among them (#11451)
The Channels panel's menu had no channel items, so New Spot Channel... and
the rest could only be reached from a row's right-click menu. It now lists
New Channel..., Duplicate Channel, Delete Channel, New Spot Channel...,
Merge Spot Channel, Channel Options..., Split Channels and Merge
Channels..., each acting on the targeted channel and greyed where it can't:
Duplicate takes a single colour, alpha or spot channel, the composite of a
one-channel image, the Quick Mask or a targeted layer mask. Channel
Options... in Quick Mask mode now opens the targeted alpha or spot
channel's options, not Quick Mask Options. The panel menus run their
commands through the menu bar's enabled rules, so the Layers panel menu
greys its dialog items the same way too. The labels are in every catalog.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Channels: New Channel... and Merge Channels... ask first, from the panel and row menus (#11451)
The panel menu's Merge Channels... ran channel.merge with no parameters, and
the engine merged the first grayscale documents into RGB and closed them with
no choice; New Channel... added a channel straight away. Both now open a
dialog when called without parameters, as New Spot Channel... and Channel
Options... already did: New Channel... reuses the Channel Options dialog
(name, colour indicates, colour and opacity), and a new Merge Channels
dialog picks the mode and the open grayscale document for each channel. The
channel rows' menu had the same two items and goes through the same path.
With parameters (scripts, the New button) both still run at once.
The Merge Spot Channel test now checks pixels, so a delete couldn't pass it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Channels: Merge Channels waits for three grayscale documents and the dialog offers only modes they fill (#11451)
With two grayscale documents open, Merge Channels... was enabled and its
dialog repeated a document for the third channel; OK then failed in the
engine and the dialog closed. The engine's rule now needs three documents
of one size (no mode merges fewer), so the menus grey the item below that.
The dialog offers only the modes the open documents can fill (RGB and Lab
from three, CMYK from four), greys OK with the reason while the picks
repeat, keeps itself open when OK is refused, and comes back with the
engine's message if the merge itself fails.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Channels: the Merge Channels dialog keeps its picks by document id (#11451)
The dialog kept the picked source documents by tab index, and background
work can still run while it is open, so a document moved or closed in the
meantime could leave another one at a picked index; OK would then merge,
and close, the wrong document. The picks are now document ids, resolved to
the current tabs when OK is pressed: a closed pick, or one that is no
longer a grayscale document of the same size, is refused with the reason
and the dialog stays open.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Export to files: a Custom JPEG quality in Artboards, Layers and Layer Comps to Files (#11481)
The engine commands already took `quality` (0..12), but their dialogs
offered no way to set it. Each dialog now has a Quality row with a Custom
checkbox, shared with Batch: quality is sent only for JPEG with Custom on,
so an export left alone writes exactly what it wrote before (the source
JPEG's own quality, else the encoder default), and PNG, WebP (still
lossless), PSD, TIFF and BMP never get one. Alt+Reset restores the Custom
state too. The fields follow the reference dialog's order.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Tests: the export quality tests go through the dialog's own controls (#11481)
Custom and Quality are now ticked and typed through their widgets, a new
test switches one dialog from JPEG to PNG and WebP and back and checks the
Custom quality survives, and Alt+Reset is clicked through the same path the
app uses instead of calling reset_form.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Since #10867 the non-deleting crop turns a 2000 px layer to 2001 px bounds, so
the budget refusal names 200100 x 200100 px.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Restore main's comment that Distort moves corners and edges (#10085), which the
merge with main had reverted. on_other_layer now checks the frontmost hit under
the click (skipping the moved and fully locked layers, as Auto-Select does), so a
grouped layer covering a top-level layer keeps the box open instead of
committing through the covered layer.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
nesting_depth now returns a Result; main's parse_image_bounded_with gets the
same entity-markup rejection as the other callers.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Merge main (0f15223e18) and rebuild #5532 on main's craft_ui::ComboBox:
#5501's hand-written combo_list and its call-site migrations (gradient
map, crop ratio, kerning, press_menu, the wheel and height tests) are
dropped in favour of main's versions; the list height stays #7622's.
The group lines are drawn inside ComboBox::show_ui: a 1 pt line that
takes no width during egui's sizing pass, above Darken, Lighten,
Overlay, Difference and Hue, never above the first row. Used by the
Layers panel's Blend Mode box (also the greyed one with no layer), the
Brush/Pencil Mode list (Clear starts no group), the retouch and Paint
Bucket Mode lists when they hold every blend mode (the Healing Brush's
short list draws none) and the Gradient's Mode list. The Brush Mode
right-click menu shares the same rule (starts_blend_group).
Tests: the Layers kittest at 1440x900 finds exactly the five group
boundaries; a widget test checks the first row gets no line and the list
keeps its width; a 1440x900 click released in place on the Blend Mode box
opens the list beside the box and changes nothing.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>