Commit Graph
888 Commits
Author SHA1 Message Date
dotCooCoo 67fd1cd127 Merge main into feat/live-paint-bucket-multi-click 2026-11-14 15:48:45 -08:00
BFlat a92993daf9 Merge pull request #7582 from dotCooCoo/fix/clip-effects-hit-test
Selection: clicks in a clip group follow the region its clipping path's effects give it
2026-11-15 06:16:57 +07:00
BFlat c0ce77a912 Merge pull request #7663 from dotCooCoo/feat/perspective-auto-plane-positioning
Perspective: Perspective Grid Options has Automatic Plane Positioning
2026-11-15 05:30:40 +07:00
BFlat 35bf3a7412 Merge pull request #7625 from dotCooCoo/fix/shape-builder-open-path-drawn-fill
Shape Builder: an open path counts as filled by the fill rows that draw
2026-11-15 05:29:46 +07:00
dotCooCoo 0e6e7df695 Merge main into feat/live-paint-bucket-multi-click 2026-11-14 13:02:52 -08:00
ncic d3213cf5b2 Merge remote-tracking branch 'upstream/main' into pencil-no-guides 2026-11-14 22:02:14 +01:00
dotCooCoo cf8b88b0ea Merge main into fix/clip-effects-hit-test 2026-11-14 12:59:50 -08:00
dotCooCoo ec5472f726 Merge main into fix/shape-builder-open-path-drawn-fill 2026-11-14 12:38:20 -08:00
dotCooCoo c0d9c76ecd Live Paint: a triple-click matches what its double-click reached
When the third click of a triple-click landed on a face or edge that
the double-click before it had painted (a neighbor the flood or the edge
walk reached), the triple-click sent that part's new paint as match,
since only the clicked part's paint was recorded. The bucket now records
the fill or drawn stroke paint of every other part a double-click
reaches, and a triple-click on one of them matches the paint it had
before the double-click. docs/mcp.md says so.
2026-11-14 12:32:02 -08:00
BFlat 85ce363b93 Merge pull request #7548 from dotCooCoo/fix/objects-on-path-widgets-flatten-once
Objects on Path: the widgets flatten the group's path once per lookup
2026-11-15 03:22:27 +07:00
dotCooCoo f46e0ad809 Live Paint: the bucket paints the stroke an edge shows
livePaint.strokeEdge wrote the paint and weight into an edge's topmost
stroke even when that stroke was hidden. An edge whose hidden top stroke
sat over a drawn one kept drawing its old paint, and since the edge
scopes now match the paint an edge draws, a samePaint or connected
stroke reached such edges and changed nothing on screen. The command now
paints the topmost stroke that is shown, and adds a stroke above the
others when every stroke is hidden or there is none. The "nothing
changes" check reads the same stroke.

The doc comments of the scopes and of the press record describe the
drawn stroke paint, and the engine names Paint through its parent module
instead of in the import list. Live Paint Selection's comment on a
triple-click states that the tool takes no action on it.

New tests cover the edge the tool matches on a multi-click over a hidden
or fully transparent edge, the connected edge scope through transparent
and hidden edges, and painting the shown stroke.
2026-11-14 12:20:03 -08:00
dotCooCoo b7678494a2 Merge main into fix/clip-effects-hit-test 2026-11-14 12:18:53 -08:00
dotCooCoo 163f256418 Perspective: Perspective Grid Options has Automatic Plane Positioning
Perspective Grid Options gets the two Automatic Plane Positioning
checkboxes, Anchor Point of Perspective Artwork and Intersection of
Gridlines. With the Perspective Selection tool, Shift held over an
anchor point of art in perspective, or over a gridline intersection,
with no button down, moves the active plane through that point and
hides the other planes. A plane made active then passes through the
same point. The plane goes back to its place once an object is drawn
on it or attached to it, when the grid hides or no plane is active,
when the file is opened again, and with Escape.

- perspective.plane.infer {at?, tolerance?, clear?} positions, reads
  and clears the held point, which is view state, not an undo step.
- perspective.widget.options takes anchorPoint and gridlineIntersection,
  both on by default and kept with the preferences.
- perspective.plane.move moves a held plane from where it is held.
2026-11-14 12:11:36 -08:00
dotCooCoo 9d0a4eb731 Shape Builder: rewrap the shape_builder_shapes doc comment 2026-11-14 11:47:28 -08:00
ncic badf89be39 Merge remote-tracking branch 'upstream/main' into pencil-no-guides
# Conflicts:
#	docs/mcp.md
#	docs/target-app-parity.md
2026-11-14 20:32:09 +01:00
dotCooCoo 7ef603db40 Live Paint: bucket scopes follow the stroke an edge draws
The Live Paint Bucket's connected and samePaint scopes kept their own
copies of the face flood and the edge walk. They read an edge's stored
stroke paint, so an edge that is fully transparent or whose stroke is
hidden stopped a face flood and matched as stroked. The face flood also
required outlines within 0.0001 pt of an edge, which a curved face that
the planar map refits can miss.

The engine now calls the shared flood_faces and connected_edges that
Live Paint Selection uses (#7342), and compares edges by lp_stroke_paint,
the paint of the topmost stroke that draws. The tool records that same
paint as the match for a double-click or triple-click on an edge. The
params text and docs/mcp.md describe the drawn stroke paint.
2026-11-14 11:24:56 -08:00
dotCooCoo f0c920fa8e Shape Builder: leave out Live Paint faces and edges with an opacity of 0
A visible, unlocked Live Paint face or edge whose own opacity is 0 draws
nothing, as Expand and the edge stroke check already treat it, but the
Shape Builder still took it as an input. It now leaves such faces and
edges out; hidden and locked parts keep their current handling.
2026-11-14 11:15:41 -08:00
dotCooCoo 69ce720e46 Live Paint: Live Paint Selection does nothing on a triple-click
main's Live Paint Selection double-click (#7342) replaced the tool's
catch-all pointer arm with an explicit DoubleClick arm, so the
TripleClick kind this branch adds left the match non-exhaustive. The
tool now takes no action on TripleClick: the third click's press and
release already select what a click selects, as before the merge.

The merge also took main's import list in the engine's Live Paint
commands, which no longer named Paint while this branch's Merge code
still uses it; Paint is imported again.
2026-11-14 10:44:26 -08:00
dotCooCoo 924aa258d0 Merge main into fix/shape-builder-open-path-drawn-fill 2026-11-14 10:29:06 -08:00
dotCooCoo 1c4cc88e90 Merge main into feat/live-paint-bucket-multi-click
# Conflicts:
#	crates/tools/src/builder/live_paint.rs
2026-11-14 10:19:24 -08:00
BFlat 8c5494bccc Merge pull request #7342 from dotCooCoo/feat/live-paint-selection-double-click
Live Paint: a Live Paint Selection double-click selects the connected faces or edges
2026-11-15 00:40:41 +07:00
BFlat 01e66f0a19 Merge pull request #7477 from dotCooCoo/fix/dimension-second-point-guides
Dimension tool: no construction guides through a first point off the anchors
2026-11-15 00:39:29 +07:00
BFlat d89f593bfa Merge pull request #7380 from ncic/pencil-cursors
Pencil: shows where a stroke continues, connects and closes
2026-11-15 00:38:01 +07:00
dotCooCoo 1d94c97425 Selection: symbol parts count the Preview of the instance's layers
Direct Selection on a dynamic symbol's instance below a layer whose
Preview is off tested and outlined the art in Preview, where the canvas
draws it in outline with the plain clipping paths. When a clipping
path's effects left no region, a selected object in its clip group kept
an outline cut to the plain clipping path.

- `hit::symbol_part_at` and `hit::symbol_part_outline_in_view` count the
  layers around the instance, the isolated container and the layers
  around it apart, as clicks outside symbols do.
  `symbol_part_outline_in_view` takes the click options in place of the
  outline flag.
- The outline of an object is empty when the effects of a clipping path
  around it leave no region.
2026-11-14 09:30:12 -08:00
dotCooCoo 11bd1659f5 Selection: symbol parts follow the region a clipping path's effects give it
Direct Selection on a dynamic symbol's instance picked an object in the
region its clipping path's effects give it, but cut the object's outline
to the plain clipping path, so the outline came out empty or cut short.
In a layer of the art whose Preview is off, it tested the effect-shaped
region and the fills, where the canvas draws the plain clipping path and
outlines.

- `hit::symbol_part_outline` cuts to the bounds of the effect-shaped
  region. The new `hit::symbol_part_outline_in_view` takes the view's
  outline state, and the Direct Selection overlay passes it.
- `hit::symbol_part_at` tests art in a layer whose Preview is off in
  outline.
2026-11-14 08:51:22 -08:00
dotCooCoo bbe9480656 Shape Builder: an open path counts as filled by the fill rows that draw
Consider Open Filled Paths as Closed decided whether an open path was
filled from its top fill row only. A path whose top fill is None over a
painted lower fill stayed open, and one whose only painted fill was
hidden or at 0% opacity closed. The region map, merge inputs and the
Clicking Stroke Splits the Path cut now use Appearance::has_drawn_fill,
so any shown, painted fill row above 0% opacity counts, as the canvas
paints it.

The Shape Builder's Live Paint face and edge filters had the same
top-row check; they now use has_drawn_fill and has_drawn_stroke, so a
face or edge is taken when one of its rows draws.
2026-11-14 08:00:35 -08:00
dotCooCoo c7cd768399 Merge main into fix/clip-effects-hit-test 2026-11-14 07:42:26 -08:00
FredApps 676f0524cc Merge pull request #1203 from FredApps/fix/spiral-decay-setting-20261011
Keep Spiral decay settings consistent with drawn geometry
2026-11-14 16:22:35 +01:00
BFlat 6e3ec907de Merge pull request #7592 from dotCooCoo/fix/brush-freehand-unknown-brush
Brushes: brush.freehand refuses a brush or style it cannot use
2026-11-14 21:52:42 +07:00
dotCooCoo f6ad3ecc01 Merge main into feat/live-paint-selection-double-click
# Conflicts:
#	docs/target-app-parity.md
2026-11-14 06:28:52 -08:00
ncic cd89999939 Merge remote-tracking branch 'upstream/main' into pencil-cursors
# Conflicts:
#	docs/target-app-parity.md
2026-11-14 14:42:23 +01:00
dotCooCoo e385d92b1b Merge main into feat/live-paint-bucket-multi-click 2026-11-14 05:25:24 -08:00
dotCooCoo f37c5c293e Brushes: brush.freehand refuses a brush or style it cannot use
brush.freehand drew the plain path when `brush` named no brush in the
document or was not a string, and drew a pencil stroke for any `style`
other than "brush". It now refuses an unknown name with "no brush named
`<name>`", as brush.apply and brush.setCurrent do, a `brush` that is not
a string, and a `style` other than "pencil" or "brush". The document does
not change and no undo step is recorded. A `brush` left out or null still
draws the plain path.

The Paintbrush skips a tool brush or current brush that has been deleted
and paints with the other, or draws the plain path when neither is in the
document, so a stroke after a brush is deleted is not refused.
2026-11-14 04:41:02 -08:00
ncic fc47e4782b Pencil: Use Precise Cursors shows the plain crosshair again; a far close is a straight segment 2026-11-14 13:23:22 +01:00
FredApps c9a199ff91 Merge branch 'main' into fix/spiral-decay-setting-20261011 2026-11-14 13:15:33 +01:00
dotCooCoo 8fa551e173 Selection: clicks in a clip group follow the region its clipping path's effects give it
The canvas clips a clip group by its clipping path with the path's live
geometry effects applied, but clicks, hovers and marquees still tested
the plain clipping path. A click where a Transform effect had moved the
clip selected nothing, and a click on the clipping path's own place
selected art that was not drawn there.

- The engine registers the effect-shaped region with the doc crate
  (`hit::set_clip_region`), as it does for image paint and live art. It
  gives a region only when the clipping path holds a visible geometry
  effect; otherwise clicks keep the plain shapes, and type keeps
  counting by its frame.
- Clicks, `objects_at`, the hidden art of a selected object, the Unlock
  submenu's list and marquees inside a clip group or a clipping layer
  use that region. Outline view and layers with Preview off draw no
  effects and keep the plain shapes; the Selection, Direct Selection
  and Enclosing Lasso marquees pass the view's outline state
  (`hit::marquee_in_view`). Each container around a selected object
  tests its clipping path in the outline state a click has there.
- A marquee touches the clipping path itself by its own geometry, as a
  click on its outline finds it, and also on the edge of the region, so
  a marquee around a clipping path that an effect moved into large art
  still selects it. `hit::marquee_in` keeps the plain shapes for the
  Color Theme Picker, which clips by them.
- The region is kept per thread until the clipping path or the live
  inputs change. A clip group's reach takes in the region's box, so
  culling does not skip art the region moved past the plain clipping
  path. Up to 4096 boxes are kept; when they are full, a new box
  replaces only as many others as it needs room for.

Docs: docs/target-app-parity.md.
2026-11-14 04:08:03 -08:00
dotCooCoo 5803d2da4a Fix #7411: a selection grabbed by an anchor snaps it onto other paths
With Smart Guides on, a selection the Selection tool grabbed by one of
its anchors only landed that anchor on other anchors and centers, or
lined its bounds up. The anchor now also lands on the other objects'
paths ("path"), and where a path crosses another path or a ruler guide
("intersect"), in the order Direct Selection uses for a dragged anchor.
When the anchor lands on a path, the bounds do not also line up with
other objects, and a ruler guide nearby does not pull it off the path.
A selection grabbed anywhere else keeps lining its bounds up.

- Targets::for_move_by_anchor gathers the other art's path segments as
  well, and Targets::snap_onto_path lands a point on them or on their
  crossings with each other and with the ruler guides.
- MoveSnap::by_anchor uses those targets; the Selection tool picks it
  when the press grabbed an anchor.

Reported by pivot-al.

Docs: docs/target-app-parity.md.
2026-11-14 03:42:08 -08:00
ncic bdaaff534c Merge remote-tracking branch 'upstream/main' into pencil-cursors
# Conflicts:
#	docs/ui-parity.md
2026-11-14 12:31:28 +01:00
dotCooCoo fc562960ec Merge main into fix/dimension-second-point-guides 2026-11-14 03:02:44 -08:00
dotCooCoo cde9a27b4f Objects on Path: the widgets flatten the group's path once per lookup
Finding where the Rotate All, Space, Move All and Select/Move widgets
go and testing whether the pointer is over one flattened the group's
path two to three times per widget. Starting a Space, Move All or
Select/Move drag flattened it five times, and one pointer move over the
group could flatten it eleven times. Each lookup now flattens the path
once and shares that measurement across the widgets:

- vectorcraft-doc makes `Measured` public with `stop` and `stops`, and
  adds `attachable`, which returns the path with its measurement.
- `Widgets::of` gives all four widgets for the canvas, `widget_at` gives
  the widget under the pointer, and `WidgetDrag::hit` gives the drag a
  press starts, each from one flattening. The Selection and Objects on
  Path tools and the canvas use them.
- A Space, Move All or Select/Move drag keeps its measurement and
  measures again only when the group's path changes.

Widget places, hits, cursors and drag results are unchanged. The new
`spine-count` feature of vectorcraft-doc exposes the flattening counter
to vectorcraft-tools' tests; it is enabled only as a dev-dependency and
leaves Cargo.lock unchanged.
2026-11-14 03:01:29 -08:00
FredApps 4552915aae Tests: spiral decay is per full wind on main, so four segments give the decay 2026-11-14 11:35:04 +01:00
BFlat 868a86ddff Merge pull request #7494 from dotCooCoo/fix/gradient-vector-snap-draw
Gradient tool: a vector drawn on the art snaps as other drawn points do
2026-11-14 16:51:12 +07:00
ncic 77070d29a7 Pencil: the continuation cursor follows the snapped release; Precise Cursors tests keep the badges 2026-11-14 09:22:18 +01:00
ncic cbd1c142dc Merge remote-tracking branch 'upstream/main' into pencil-cursors
# Conflicts:
#	docs/target-app-parity.md
2026-11-14 09:05:01 +01:00
ncic 3789bc27bc Merge remote-tracking branch 'upstream/main' into pencil-no-guides
# Conflicts:
#	docs/mcp.md
#	docs/target-app-parity.md
2026-11-14 08:54:32 +01:00
BFlat 6beeb9e2a4 Merge pull request #7262 from dotCooCoo/feat/smooth-cursor-without-path
Smooth: the cursor shows Not Allowed when no path is selected to smooth
2026-11-14 13:43:44 +07:00
BFlat 508ff987f5 Merge pull request #7374 from dotCooCoo/fix/shape-builder-hover-ended
Shape Builder, Live Paint Selection: hover highlights go when the pointer leaves the canvas
2026-11-14 13:43:20 +07:00
BFlat d3ac2434f5 Merge pull request #7397 from dotCooCoo/fix/dimension-first-preview
Dimension tool: the first preview of a drag-out is drawn at the pointer
2026-11-14 13:43:03 +07:00
BFlat aa5b635b32 Merge pull request #7388 from dotCooCoo/fix/snap-glyph-parametric-slice
Smart Guides: Parametric Shape and Slice tools snap as the drawing tools do
2026-11-14 13:42:31 +07:00
BFlat 7fd4564c0c Merge pull request #7390 from dotCooCoo/fix/hyphenation-exceptions-relayout
Type: hyphenated type lays out again when the hyphenation exceptions change
2026-11-14 13:41:57 +07:00