The check after the last file returned the cancelled error for every
export. A folder export without a ZIP has written each file by then, so
a cancel that came during a final step that writes nothing (a row whose
file repeats the one before it) reported a finished export as
cancelled. The check now runs only for exports that still hold their
files: those without a folder and those that make a ZIP.
A cancel that came after the last file's check was not seen: an export
without a folder returned its files or its archive anyway. The export now
checks once more after the last file and again after deflating the
archive, so a cancel returns the cancelled error and nothing is written
or returned.
zip::deflate takes a `stop` callback that it calls before each 1 MiB of
a file. Export for Screens passes the cancel state, so deflating stops
at the next MiB. file.package passes one that never stops, so its
behavior does not change.
With `zip: true`, document.exportForScreens deflated nothing: every file
went into the archive stored. Each file is now deflated, or stored when
deflating does not make it smaller, as file.package's archive does. The
file list, the names and the reply's fields stay the same; `bytes` and
the archive's contents change. Entries keep the fixed 1980-01-01 date, so
the same files still give the same archive.
The deflating writer moves from package.rs into fileio/zip.rs as
`zip::deflate`, beside `zip::store`, and file.package calls it there with
its own date and error text. The test reader `zip::entries` reads
deflated entries too. The `zip` option's text in docs/mcp.md,
docs/control-protocol.md and the command's params says the files are
deflated.
An Alt-click right of a short layer name, inside the wider rename
target, no longer replaces the selection. The isolated layer's own row
now selects the art inside it (layer.selectAll), where it cleared the
selection before. The doc line says the click selects visible, unlocked
art and clears the selection on a hidden or locked layer.
The reference app selects all objects on a layer with an Alt-click
(Option-click) on the layer's name in the Layers panel. In VectorCraft
an Alt-click on a name did what a plain click does: it highlighted the
row and made the layer current, and the art stayed unselected.
An Alt-click on the name of a layer or sublayer now also selects its
visible, unlocked art, as the row's selection square does
(layer.selectAll), and the layer still becomes current
(layer.setCurrent). On a locked or hidden layer the click clears the
selection, as that row's selection square does. On a group or object
row, beside the name, and with Shift or Ctrl/Cmd held as well, the
click does what it did before.
Docs: docs/mcp.md, docs/target-app-parity.md.
The reset ran paint.editGradient, which changes every run of a type
object and leaves a stroke without paint at weight 0. It now runs
paint.setFill or paint.setStroke with the linear White, Black gradient:
characters selected with the Type tool take it and the rest keep their
paint, and a stroke without paint gets the 1 pt weight, as a plain click
on the Gradient button already does.
The reference app resets a gradient to black and white when the
gradient button in the Tools panel is Cmd/Ctrl-clicked, and to the
default black and white linear gradient when the Gradient Fill box in
the Gradient panel is Cmd/Ctrl-clicked. In VectorCraft a Cmd/Ctrl-click
on either did what a plain click does, and the reset was only in the
Gradient panel menu.
A Cmd/Ctrl-click on the Gradient panel's thumbnail or on the Tools
panel's Gradient button now makes the gradient of the active Fill or
Stroke a linear gradient with the White, Black stops, through
paint.editGradient, as one undo step. A solid or no paint becomes that
gradient, and with nothing selected the default paint changes. A plain
click keeps its behavior, and the panel menu's Reset to White, Black
is unchanged.
Docs: docs/target-app-parity.md.
The reference app selects the complement of the current fill or stroke
on a Cmd/Ctrl-click of the Color panel's color bar and the inverse on a
Cmd/Ctrl+Shift-click, and with Alt (Option) also held it changes the
nonactive one. In VectorCraft these clicks picked the spectrum's color,
and a Cmd/Ctrl+Shift-click cycled the color modes.
A Cmd/Ctrl-click on the spectrum now applies Complement and a
Cmd/Ctrl+Shift-click applies Invert to the active Fill or Stroke, as
the panel menu's items do: a selected gradient stop or freeform point
is recolored in place, and a solid color goes through paint.complement
or paint.invert. With Alt also held, the click runs the command on the
inactive proxy, which stays behind. A Cmd/Ctrl drag still picks colors,
and plain, Alt and Shift clicks keep their behavior. The panel menu's
Invert and Complement use the same code.
Docs: docs/target-app-parity.md.
The released buttons go after the frame's last pointer movement, at its
position. Before, they went first, at the press position, so a press that
moved past the click distance in the same frame ended as a click on the
widget under the press.
egui ends a drag only on a button release or Escape. When the window
never receives the mouse-up, a drag such as a dock column's resize keeps
following the pointer with no button held.
On macOS, each frame's input now gets a release for every button egui
still holds when NSEvent.pressedMouseButtons reports no button down, at
the pointer's last position. Frames that carry a button event, and
control-channel input that holds a button between steps, are left as
they are.
A click with the Scissors tool cut the path whether or not Alt was
held, and the cursor stayed the Scissors cursor. The reference app's
shortcut list has "Switch Scissors tool to Add Anchor Point tool" on
Alt (Option).
While Alt is held, a click with the Scissors tool now does what a click
with the Add Anchor Point tool does: on a segment it adds an anchor
point with path.insertAnchor in one undo step, and the path is not cut.
The cursor is the Add Anchor Point tool's while Alt is held. When Alt
is let go, the cursor is the Scissors again and a click cuts.
Docs: docs/target-app-parity.md, crates/tools/src/cursors.toml.
The reference app's shortcut list switches between its Type tools with
Shift and with Alt (Option). VectorCraft's Type tools had no such switch.
While no type is being edited, a press with Shift held makes new type
with the chosen tool's horizontal or vertical counterpart: Type and
Vertical Type, Area Type and Vertical Area Type, Type on a Path and
Vertical Type on a Path. A press with Alt held makes it with Type on a
Path in place of Area Type, or the reverse, in the same writing
direction. With both keys held, both switch. The keys held when the
press starts are the ones that count. The pointer shows the tool the
press acts as, and the chosen tool stays selected. While type is being
edited, Shift and Alt work as they did.
Docs: docs/target-app-parity.md.
The reference app switches the units of measurement with
Ctrl+Alt+Shift+U on Windows and Option+Shift+Command+U on macOS.
VectorCraft could set the document's units with document.setUnits or
a right-click on a ruler, but no command stepped through them and no
key did it.
document.switchUnits (Switch Units, default Cmd+Alt+Shift+U) sets the
document's units to the next one in the order a right-click on a
ruler lists them: Points, Picas, Inches, Millimeters, Centimeters,
Pixels, Feet & Inches, Meters, Yards, Feet, and from Feet back to
Points. Each press is one undo step, and the reply names the new
units. Keyboard Shortcuts lists it under Document.
The precise cursors shortcut-editor test used Cmd+Alt+Shift+U as a
free key; it now uses Cmd+Alt+Shift+Q.
Docs: docs/mcp.md, docs/ui-parity.md, docs/target-app-parity.md.
With the Width tool, Escape did not deselect the selected width points:
they stayed selected, Delete still removed them, and in isolation mode
the same Escape left isolation mode. The reference app's shortcut list
gives Esc for deselecting a width point.
Escape now deselects the Width tool's selected width points. The path,
its widths and the undo history do not change, and no command is sent.
While width points are selected the tool takes Escape, so that Escape
does not also leave isolation mode. With no width point selected, and
during a drag, Escape does what it did before.
Docs: docs/mcp.md, docs/target-app-parity.md.
The reference app switches an arc between open and closed with C,
flips it with F and changes its angle with Up/Down while it is dragged
out. VectorCraft's Arc tool ignored these keys during a drag.
While an arc is dragged out, C now switches it between an open and a
closed path, F switches its base between the X and Y axes in the same
box, and Up/Down raise and lower its slope by 10 within -100 to 100.
Each press switches once. The arc drawn on release uses the new values,
and they stay as the Arc tool's options. With nothing dragged, C and F
are shortcuts as before.
Docs: docs/mcp.md, docs/target-app-parity.md.
A release that arrives at a new position with no drag before it now counts
as movement, so Alt pressed at that moment no longer switches the stroke
to the Smooth tool.