Effect › Color Effects › Vector Halftone… (addon.color.halftone, also in
Object › Plug-ins › Color Effects) draws its object as the halftone dots
Object › Vector Halftone makes, live: mono (one dot colour, or each dot in
the art's colour under it) or CMYK screens, the five dot shapes,
frequency, angle, invert and clip to the art's outline.
- The screens, dots and caps move to vectorcraft_effects::addons::halftone,
shared by the command (its behaviour and tests unchanged) and the effect.
- The renderer samples the art (vectorcraft_render::addons::halftone) and
keeps the dots by the object's content and what it reads from the
document, so unchanged art isn't sampled again; past 100000 cells per
screen the object draws as it is.
- Expand Appearance turns the object into its dots, and the SVG, PDF, EPS
and AI exporters write them as paths.
- Its dialog reuses the command's fields, without Keep Original.
Deferred: stochastic and radial patterns, a dot-gain curve, per-screen
separation settings, type or symbols as dots.
In effect dialogs (like Color Halftone), length fields with defined bounds
(e.g. Max Radius 4..127 pt) were previously checked only after num_field
returned, leaving the field's temporary buffer holding the un-clamped string
(e.g. '0.5 px'). Subsequently entering invalid text caused the field to
fall back to that sub-minimum buffer.
- Added num_field_within to pass effect parameter bounds directly to unit_field.
- When committed, clamp the parsed value within bounds and update the field
buffer to the formatted clamped value so the UI reflects what is applied.
- When invalid text is committed, clear the invalid buffer and trigger a
one-frame border highlight so invalid input is rejected visibly.
A built-in add-on in Effect › Color Effects and Object › Plug-ins › Color Effects:
- Exposure (stops of linear light, offset and gamma), Desaturate and
Invert Colors as live colour adjustments, evaluated in stack order with
those of Effect › Color Adjustments.
- addon.color.filter applies any colour adjustment to the colours
themselves, through the Edit Colors pass, as one undo step.
- A panel picks an adjustment and its values, then adds it as a live
effect or applies it as a filter.
The add-on lives in its own modules (effects, engine and ui-egui addons
folders) and leaves the existing effects, commands and menus as they
were.
Eraser Tool Options' Size takes Fixed or Pressure and a Variation as the
Blob Brush's does: the tool records the pen, and path.eraseRegion outlines
the squashed drag at the pen's widths, stretched back to the tip's angle
and roundness. The pressure parsing and outline move to draw2's common
helpers, shared by both commands.
Blob Brush Tool Options' Size takes Fixed or Pressure and a Variation, as
the brush options' Size does: with Pressure the brush is Size − Variation
wide where the pen presses lightest and Size + Variation where it presses
hardest. The tool records the pen pressure of each point and shows each
step of the drag as wide as the pen pressed there; path.blob takes
[x, y, pressure] points with sizeMode and sizeVariation and outlines the
stroke with that width profile. A stroke without pressure keeps the Size,
and Fixed with no variation stays the default.
https://helpx.adobe.com/illustrator/desktop/paint-and-fill/learn-painting-basics/blob-brush-options-and-best-practices.html
The Turkish catalog translated the bare "Open" as the adjective (Açık), so the Home screen's Open button and the History panel's first row read "open" rather than "open it". The Arc tool's Type choice, where Open is the adjective, now looks its labels up in a "shape" context (falling back to the plain row in the other languages), and Turkish gives it Açık there.
In single-line text and numeric inputs across panels and dialogs, egui
0.37 defaulted TextEdit alignment to Align2::LEFT_TOP, placing the text
galley at the very top of the allocated input box (e.g. 1pt top margin,
11pt bottom margin in 26pt rows).
Align single-line TextEdit instances to Align2::LEFT_CENTER across
recessed_text, opt_field_named (dash/gap cells), hex fields, search
fields, and dialog inputs, matching DesignCraft's vertical centering.
Add regression assertions in look_tests verifying balanced vertical
spacing.
The link applied its state only when its button was clicked, so turning
it off and on again through `ui.dialog.set` kept the old proportions,
and the next dialog didn't open with the state set that way. A link
turned on at a side of zero also took new proportions on the next frame
once that side was a size again.
The dialog now keeps the link state it last applied and applies any
change from it, however it was made: turned on, the link keeps the
sizes the dialog shows then; turned off, it forgets them; either way
the next dialog opens with the new state. Nothing else recalculates the
proportions, so a link turned on at a side of zero stays unconstrained
until it is turned off and on again.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EjfPR4a1jPek7r3nyFFNYv
A click with the Rectangle, Rounded Rectangle or Ellipse tool opens a
dialog with Width and Height. It now has a Constrain Width and Height
Proportions link beside the two rows, drawn like the Transform panel's:
while it is on, typing one side sets the other at the proportions the
shape had when the link was turned on. The next of these dialogs opens
with the link as the last one left it.
Width now comes before Height in these dialogs: the fields were listed
by name, so Height came first.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EjfPR4a1jPek7r3nyFFNYv
The Color Guide kept the base color it took when the panel first showed,
and only the base chip changed it. In a new document the current fill is
white, so every harmony and variation was white or gray until the base
chip was clicked with another current color.
A color chosen in the Color panel (spectrum, sliders, fields, chips and
Recent Colors), in the Swatches panel or a swatch library panel, or with
OK in the Color Picker for a fill or stroke now becomes the guide's base
color, and the guide shows its harmonies. A color applied from the guide
itself leaves the base as it is, and so does selecting artwork. The base
chip (Set base color to the current color) still makes the current color
the base. A new base clears the cells selected for Save Colors as
Swatches.
The base moves from egui's temporary memory to UiState::color_guide_base,
which is not saved, so the Color panel, the Swatches panels and the Color
Picker can set it.
OK used to save None for a corner tile the dialog showed as None because
the brush had no art or source for it, so that corner stopped drawing the
other kind of corner's art once the brush got some. It also copied the
art a corner borrows from the other kind of corner when that corner kept
its art. Now OK saves a corner tile's choice only when it was set from its
menu or with `ui.dialog.set`, or when the art it borrows goes away.
Pattern Brush Options has a menu below the Outer Corner Tile and the Inner
Corner Tile. Each can be the brush's own corner art (Original), None, or one
of four tiles made from the side tile at each corner of the path:
- Auto-Centered stretches one side tile around the corner, centered on it.
- Auto-Between bends a side tile on each side into the corner, the two
meeting on the corner's diagonal.
- Auto-Sliced lays a side tile on each side past the corner and masks it
at the diagonal, so the two meet like a mitered frame.
- Auto-Overlap lays a side tile on each side past the corner, overlapping.
The tiles are straight at the corner and follow the path towards the side
tiles, so they meet a curve that runs into the corner. A side tile taller
than the corner can reach is stretched along until the two sides meet. On a
short path, a corner's tile is squeezed along so that it covers at most the
path up to an open path's end and half way to the next corner, and its two sides still meet on the
corner's diagonal.
The definition stores the choice as `outer_source` and `inner_source`
(`none`, `autoCentered`, `autoBetween`, `autoSliced`, `autoOverlap`), which
`brush.options` sets. Corner art wins over a source. A brush saved without
a source draws as before: a kind of corner without art takes the other
kind's art. None leaves that kind of corner empty.
Docs: docs/mcp.md, docs/target-app-parity.md.
* chore(deps): pin craft-libs to 62bb0e1d (shared combo box)
* fix(ui-egui): dropdown menus grow back after their contents shrink
Every combo box is craft_ui::ComboBox, whose menu follows its contents'
height while it is open (egui#5225); clippy.toml bans egui::ComboBox.
The font family menu is a craft_ui::combo::Menu under its field, with the
search field and filters in its header and the family rows scrolling under
them, still laid out only in view. The menu keeps to the room on its side
of the field, so the list's minimum height and the popup's room are gone.
* fix(ui-egui): the shortcut import's target picker grows back after a search
Its search field, "No equivalent" and the row's choices are the header of
a craft_ui::combo::Menu, and Keyboard Shortcuts' entries scroll under
them. That was the last menu on the popup path that capped itself at the
room left, so that path and combo's `searchable` flag are gone.
* chore(deps): craft-libs 60d60d48 (dropdown fixes)
* chore(deps): craft-libs 4d7b82f7 (dropdown fixes)
* chore(deps): craft-libs 92d392cf (#387 merged)
* chore(xtask): pdf-deps expects craft-libs 92d392cf
Review follow-ups:
- items_per_target maps each requested row on its own. Rows deleted or
duplicated together, one shared and one not, fell back to the literal
indices in every object, so the other objects could lose the wrong
items. The first object takes its own rows; each other object takes
its copies of the shared ones only.
- effect.dialog takes `aligned` (the panel passes it on a mixed
selection's shared effect row), and its OK and preview run
effect.setParams with it, so the dialog edits each object's own copy
of the effect instead of the first object's index in every object.
Tests: removing a shared stroke with an unshared fill leaves the other
object's fills; an aligned dialog's command carries `aligned`.
OK in a new scatter, art or pattern brush's Brush Options ran brush.new
without the art the dialog had captured for its preview, so brush.new
read the selection again. A selection changed while the dialog was open
gave the brush other art than the preview showed, and a cleared
selection made OK fail. OK now passes the captured art (the side tile
for a pattern brush) to brush.new.