Commit Graph
282 Commits
Author SHA1 Message Date
Brandon Thomas c5643529af Merge PR #599 2026-10-14 22:05:10 -04:00
Brandon Thomas a9038cf262 Merge PR #497 2026-10-14 22:05:10 -04:00
aiongg 3acd29bef2 Merge upstream main d07cbbe9 2026-10-14 21:11:46 +00:00
moppeeer 9327a55100 Merge origin/main into #468 (layout-parent-guides-units)
Main restructured the dialog dispatch; #468's Create Guides and Margins and Columns arms moved into it unchanged.
2026-10-14 19:24:45 +02:00
moppeeerandClaude Opus 5.5 11b1566c09 Type tool: a press over a locked empty frame draws a new text frame instead of converting it
Adobe's "Set up a modern magazine layout" (Brian Wood, 2:12–4:23) locks a
page frame drawn round the spread (Cmd+L), then draws the text frames on
top of it with the Type tool. In DesignCraft the press landed in the
locked frame, which the Type tool turned into a text frame, putting the
caret in it; no new frame was drawn.

- The Type tool takes a hit only on text frames (locked or not, as
  InDesign lets you edit their text) and unlocked empty frames; over a
  locked empty frame, the press starts a new text frame.
- text.placeCaret refuses to convert a locked empty frame (or one on a
  locked layer).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 19:22:54 +02:00
aiongg d72307ec02 Merge remote-tracking branch 'upstream/main' into place-loads-cursor
# Conflicts:
#	crates/engine/src/cmd/file.rs
2026-10-14 17:01:12 +00:00
moppeeerandClaude Opus 5.5 cbba1fe7e1 Tools panel as InDesign's: Gradient Feather a tool of its own; two-column layout; View Options; Apply Color and Apply Gradient
Chris Nielsen's "The Adobe InDesign Toolbox" (InDesign 2020) walks the
Tools panel in one and two columns. Compared with it:

- Gradient Swatch and Gradient Feather are separate tools (one flyout
  here before).
- In two columns InDesign lays out Content Collector and Content Placer,
  Apply Color / Apply Gradient / Apply None and Normal / Preview (with
  Bleed, Slug, Presentation in its flyout) side by side
  (SPLIT_IN_TWO_COLUMNS). One column keeps one well with a flyout, which
  now names what is in front (Apply Color, Apply Gradient or Apply None).
- The utility button is View Options: Frame Edges, Rulers, Guides, Smart
  Guides, Baseline Grid and Hidden Characters, checked when shown, with
  their shortcuts (17:40). It was Text Frame Options (Object › Text Frame
  Options…, ⌘B, still opens it).
- Apply Color (,) applies the colour applied last ([Black] at first) and
  Apply Gradient (.) the gradient applied last, else the document's first,
  else white to black (InDesign's default), to the fill or stroke in front.
  The flyout had Apply Color as [Black] and no Apply Gradient.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 18:15:14 +02:00
aiongg 78340e6588 Canvas: tools show their own cursors (Direct Selection, Pen states)
Tool cursors are glyphs drawn in code (black ink, white halo): the filled
arrow for Selection, the hollow arrow for Direct Selection, the pen nib
with an add, delete, close or convert badge, and a curved double arrow
for rotating. Linux and Windows show them as OS cursor bitmaps,
rasterized per pixels-per-point and cached; macOS paints them at the
pointer, since it sizes cursor bitmaps in points; the web build keeps
the system cursors. Text, hand, zoom and resize cursors stay system
cursors.

The Pen tool reports what a click does: over the first anchor of the
path being drawn it closes the path, and between paths a click on a
selected path's anchor deletes it and a click on its outline adds one.
The Add, Delete and Convert Direction Point tools show the matching pen
badges.

The glyph geometry and the rasterizer are adapted from VectorCraft's
code-drawn tool cursors (same organisation, original work).

Fixes #438
2026-10-14 18:11:06 +02:00
moppeeerandClaude Opus 5.5 bf2cf8842b Direct Selection: pressing on a corner of an unselected object pulls just that corner
Chris Nielsen's "The Adobe InDesign Toolbox" (10:10): with the White
Arrow he clicks outside, then presses on a frame's corner and pulls it up,
turning the rectangle into a lopsided triangle. DesignCraft only looked for
anchors on objects already selected, so the press fell through to moving
the whole frame.

The Direct Selection tool now also looks at the anchors of the object
under the pointer: on one, it selects the object and drags that point, in
one undo step. Elsewhere on the object it still drags it whole; Shift-
click still toggles the selection.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 14:53:40 +02:00
moppeeer 2a9e29f6ff Merge branch 'codex/page-tool-control-panel' into codex/liquid-object-pins
# Conflicts:
#	crates/engine/src/tests.rs
2026-10-14 09:39:24 +02:00
moppeeer 3f1eb00bb3 Merge branch 'codex/page-tool' into codex/page-tool-control-panel
# Conflicts:
#	crates/engine/src/tests.rs
2026-10-14 09:38:16 +02:00
moppeeer 65dbf3c3a2 Merge remote-tracking branch 'origin/main' into codex/page-tool
# Conflicts:
#	crates/engine/src/tests.rs
2026-10-14 09:37:32 +02:00
0f4f382b0e feat(text): improve editing, snapping, and threading
Add multi-click text selection, pending caret formatting and clipboard support, text-aware colour controls, guide/grid snapping, and frame threading with loaded-port interactions.

Include the layout, drop-cap and IDML updates carried from #83, with safeguards for generated and linked stories, external text references, local IDs, locked frames and atomic colour edits.

Fixes #23.

Co-authored-by: Sean Hammond <sean.hammond@und.edu>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 21:41:46 -06:00
aiongg a4b8ee994f Merge #866: Page tool: liquid pins and resize locks on the canvas for object-based pages
# Conflicts:
#	ROADMAP.md
#	crates/ui-egui/src/canvas.rs
#	crates/ui-egui/src/i18n.rs
#	docs/target-app-parity.md
2026-10-14 01:40:21 +00:00
aiongg d0035c0722 Merge #864: Control panel for the Page tool (W/H, preset, orientation, Liquid Page Rule); Controlled by Parent; Show Parent Page Overlay
# Conflicts:
#	crates/idml/src/import.rs
#	crates/ui-egui/src/chrome.rs
#	crates/ui-egui/src/i18n.rs
2026-10-14 01:37:34 +00:00
aiongg f1f8aaa9f7 Merge #862: Page tool: click selects a page; its handles preview the liquid rule, Alt-drag resizes, Shift keeps proportions
# Conflicts:
#	ROADMAP.md
#	crates/engine/src/tests.rs
#	crates/tools/src/lib.rs
#	crates/ui-egui/src/canvas.rs
#	crates/ui-egui/src/i18n.rs
2026-10-14 01:36:53 +00:00
moppeeerandClaude Opus 5.5 8f71219533 feat(tools): Page tool pins and locks objects on object-based pages, on the canvas
Chris Cicchino's "Adobe InDesign – Page Tool and Liquid Layout" (6:32–
9:58) clicks an object with the Page tool on an object-based page and
gets InDesign's on-canvas liquid controls: a pin outside each edge
("Object is pinned relative to the page edge. Click to release.") and a
padlock on the width and height lines ("The object's width is locked.
Click to let the object change width as the page changes width."). The
pins and resize settings existed (liquid.object, the Liquid Layout
panel) but the canvas showed none of it.

- tools: on an object-based page a Page tool click selects the object
  with its page (layout.selectPage takes `ids`); its pins (14 px outside
  each edge's middle) and width/height locks (beside the centre) toggle
  liquid.object on click, show InDesign's tooltips on hover and a hand
  cursor.
- canvas: LiquidPins (orange dashed width/height lines with padlocks,
  open when the object follows the page; hollow pins, or a line to the
  page edge when pinned) and Tip overlays; tooltip translations.

Builds on the Page tool PR (#862).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 01:21:51 +02:00
moppeeerandClaude Opus 5.5 59b6125af1 feat(ui): Control panel for the Page tool; Controlled by Parent; Show Parent Page Overlay
Chris Cicchino's "Adobe InDesign – Page Tool and Liquid Layout" (1:02–
2:06, 13:47) sizes pages from the Control panel with the Page tool
selected: X/Y, W/H, the page-size preset ("US Business Card"),
orientation, Liquid Page Rule ("Controlled by Parent"), Objects Move with
Page and Show Parent Page Overlay. DesignCraft's Control panel showed the
(empty) object controls.

- ui: with the Page tool, the Control panel shows the selected page (or
  the page in view): the reference point (W/H, preset and orientation
  keep it in place via layout.pageSize's anchor), X/Y (read-only),
  W/H, the preset dropdown, portrait/landscape, Liquid Page Rule, Objects
  Move with Page (always on: pages don't move within spreads yet) and
  Show Parent Page Overlay.
- doc: LiquidRule::ControlledByParent (the parent page's rule, Off
  without one; resolved by liquid::effective_rule); Page.show_parent_overlay.
- engine: layout.pageOptions {pages, showParentOverlay}; liquid.pageRule
  takes controlledByParent.
- canvas: the parent page's size over a page with the overlay on.
- Liquid Layout panel and Control panel share InDesign's rule list
  (Off, Scale, Re-center, Object-based, Guide-based, Controlled by
  Parent); "US Business Card" preset; translations.

Builds on the Page tool PR (#862) for the selected page.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 00:51:47 +02:00
moppeeerandClaude Opus 5.5 cc13e80c9d feat(tools): Page tool selects pages; handles preview the liquid rule, Alt-drag resizes
Chris Cicchino's "Adobe InDesign – Page Tool and Liquid Layout" (0:42–
2:06) selects a page with the Page tool, gets its bounding box with
handles, drags a handle (the page springs back: a liquid-rule preview),
holds Option to really resize it, Shift for proportions, and reads the
size in a tooltip by the cursor. DesignCraft's Page tool only opened a
generic Page Size dialog on click.

- tools: the Page tool selects the page under a click (none on the
  pasteboard); the selected page shows its outline, eight handles and
  its liquid page rule ("Scale", "Object-Based"…) above it. Dragging a
  handle previews layout.pageSize (the liquid rule re-flows the
  objects) and springs back on release; Alt resizes, Shift keeps the
  proportions; a W/H readout follows the pointer; resize cursors on the
  handles. Double-click a page for the Page Size dialog.
- doc: Selection.page (the Page tool's page); engine: layout.selectPage
  (no undo step).
- layout.pageSize `anchor` (0-8): the page grows away from the
  reference point and its objects and guides keep their place relative
  to it (a handle drag anchors the opposite edge); liquid rules work
  from that.
- canvas: PageHandles and Tag overlays; translations for the tags and
  the Resize Page undo label.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 00:29:55 +02:00
aiongg b9060d0350 Merge #803: Refuse command params the description doesn't name
# Conflicts:
#	ROADMAP.md
#	crates/engine/src/cmd/file.rs
#	crates/engine/src/cmd/mod.rs
#	crates/engine/src/cmd/object.rs
#	crates/engine/src/cmd/prefs.rs
#	crates/engine/src/cmd/table.rs
#	crates/engine/src/lib.rs
2026-10-13 20:13:51 +00:00
aiongg a8e0af254f Integration: #816's test checks for color.sample by name (the tool also passes matchFrom) 2026-10-13 19:16:49 +00:00
aiongg 891e29ea92 Integration: #816's test (eyedropper ignores inactive states of a multi-state object) 2026-10-13 19:07:03 +00:00
MarekSpodBiedry cab9200975 fix: eyedropper ignores inactive states of a multi-state object (#737) 2026-10-13 18:43:09 +02:00
Gert Pellin 68596ea696 Refuse command params the description doesn't name
Callers from outside the app now get a parameter error for a key a
command's params description doesn't name, instead of the command
running with its defaults: `text.select {story, start, end}` and
`style.list {bogus: 1}` are refused with "unknown parameter `…`" and the
nearest or the accepted keys.

- engine: `cmd::params` (ported from VectorCraft #1442) reads the keys
  from each params description; `check_params` / `check_keys`.
  `Session::execute` itself stays lenient so old journals replay; in the
  engine's own tests it checks too, as the audit of the descriptions.
- MCP: tools/call answers -32602 for an argument a tool doesn't take and
  for params a command doesn't take (`execute`, every `batch` step before
  the first runs); the headless backend checks as well.
- Control channel (`engine.execute`) and `designcraft-cli run --cmd`.
- Descriptions now name every key their commands read (table target
  cells, anchored objects, gap.move, file.place, data merge, prefs.set,
  …); type.char / type.para stay unchecked (their attributes may be the
  params object itself; the setters refuse unknown attributes).
- Tests that passed keys the commands never read are fixed, and the pen
  tool no longer sends the unread `notifyPen`.

Fixes #776
2026-10-13 17:25:27 +02:00
moppeeer a255dc99b5 feat(tools): resize a selected placed graphic by its own handles (#699)
With a placed graphic selected (Direct Selection, or the content
grabber), the graphic's own brown bounding box has eight handles:
dragging one resizes the image inside its frame (Shift keeps its
proportions, Alt from its centre) and leaves the frame as it is.

- tools: a content-handle hit test on the selected graphic's bounds
  (after the frame's anchors under Direct Selection), a ContentResize
  drag previewing `transform.set {content, bounds}`, the handle cursors,
  and the content ghost while dragging. The frame's handles don't resize
  the frame while its graphic is selected.
- engine: `transform.set` takes `bounds` for content: the graphic's new
  bounding box on the spread (normalized, never empty).
- canvas: the brown content box gets its handles; the frame's handles
  are hidden while the graphic is selected.

(cherry picked from commit 8e0e6c2f2e)
2026-10-13 12:29:32 +00:00
moppeeerandClaude Opus 5.5 7192c2e136 feat(eyedropper): A sampled colour goes to the stroke when the Stroke box is in front
As in InDesign, the Eyedropper applies a colour sampled from a placed image
to the fill or the stroke, whichever is in front in the toolbox: with the
Stroke box in front a selected line takes it on its stroke (it has no
fill to show it). The toolbox's state reaches tools through
ViewInfo/ToolContext::stroke_in_front.

Depends on #572.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 09:56:25 +02:00
Brandon Thomas 777d8c3251 Merge branch 'pr/572' into batch1
# Conflicts:
#	crates/tools/src/tests.rs
#	crates/ui-egui/src/i18n.rs
#	crates/ui-egui/src/i18n/ar.rs
#	crates/ui-egui/src/i18n/it.rs
#	crates/ui-egui/src/i18n/ja.rs
#	crates/ui-egui/src/i18n/pt_br.rs
#	crates/ui-egui/src/i18n/uk.rs
2026-10-13 02:24:24 -04:00
Brandon Thomas a390905beb Merge branch 'pr/647' into batch1
# Conflicts:
#	crates/tools/src/lib.rs
#	crates/tools/src/tests.rs
#	crates/ui-egui/src/canvas.rs
2026-10-13 02:23:33 -04:00
Brandon Thomas b758c6180a Merge branch 'pr/649' into batch1 2026-10-13 02:23:11 -04:00
aiongg ebae0c7805 Merge parent-based-on: Parents: a parent can be based on another parent (#652)
# Conflicts:
#	ROADMAP.md
#	crates/compose/src/cache.rs
#	crates/doc/src/build.rs
#	crates/engine/src/cmd/file.rs
#	crates/engine/src/cmd/layout.rs
#	crates/idml/src/import.rs
#	crates/idml/src/tests.rs
#	crates/pdf/src/tests.rs
#	crates/render/src/lib.rs
#	crates/render/src/text.rs
#	crates/tools/src/snap.rs
#	docs/gaps.md
#	docs/target-app-parity.md
2026-10-13 01:00:08 +00:00
aiongg 182db943c2 fix(parents): bound every based-on walk; base items follow the parent showing them (#652)
Cycle checks walk based_on with a seen-set over all parents, so a cycle
longer than the drawing depth cap is still found. Snapping lists parent
items through shown_parent_pages instead of recursing, and offers base
items on a parent spread. A base parent's text on a parent spread is
composed for that spread, so page-number markers show its prefix.
Cmd+Shift-click hits what is drawn: it honours Show Parent Items, hidden
and locked layers, the facing-page filter and layer order. IDML import
warns when a parent spread's pages name different bases or their own
spread.
2026-10-13 00:51:41 +00:00
aiongg f74664df8d Integration (#636): the Direct Selection end-anchor test checks only Direct Selection (with the default brackets the Selection tool's thread ports sit there too) 2026-10-13 00:33:00 +00:00
aiongg 5b81bfa9b6 Integration: format 2026-10-13 00:23:24 +00:00
aiongg 80803e3ae3 feat(parents): a parent can be based on another parent (#652)
Pages draw the base parent's items, then the parent's, then their own,
on the canvas, in PDF and image export, and on the parent spread itself.
Chains are followed base first with a depth bound. Overrides, parent hit
testing and the flattener's transparency check include base items.

layout.parents.options {parent, basedOn} sets or clears the base and
refuses cycles; document.inspect reports basedOn per parent. Opening a
.designcraft or IDML file clears a cyclic or dangling base with a warning.
IDML already carried the base as the parent pages' AppliedMaster; a test
covers the round trip.
2026-10-13 00:21:48 +00:00
aiongg 2732f8c2e6 Integration (#636): with Direct Selection an anchor under the pointer wins over a type-on-a-path bracket, so the end anchors (where the default brackets sit) can be dragged again 2026-10-13 00:09:13 +00:00
aiongg 99e6922981 Merge pr/636: Tools: drag type-on-a-path start and end brackets (#636)
# Conflicts:
#	ROADMAP.md
#	crates/idml/src/tests.rs
#	crates/tools/src/lib.rs
#	crates/tools/src/select.rs
#	crates/tools/src/tests.rs
#	crates/ui-egui/src/canvas.rs
2026-10-13 00:08:12 +00:00
aiongg 1cf1477183 Integration (#630): the Pen continuing from a path's first anchor adds anchors before it (path.appendAnchor at: start) instead of reversing the path, so arrowheads stay on their ends and a press then Esc leaves no undo step 2026-10-13 00:06:15 +00:00
aiongg 575839cc4f Merge pr/630: Tools: the Pen continues an open path from either end point (#630)
# Conflicts:
#	ROADMAP.md
#	crates/engine/src/cmd/object.rs
#	crates/tools/src/lib.rs
#	crates/tools/src/pen.rs
#	crates/tools/src/tests.rs
#	crates/ui-egui/src/canvas.rs
#	crates/ui-egui/src/i18n.rs
#	crates/ui-egui/src/i18n/ar.rs
#	crates/ui-egui/src/i18n/it.rs
#	crates/ui-egui/src/i18n/ja.rs
#	crates/ui-egui/src/i18n/pt_br.rs
#	crates/ui-egui/src/i18n/uk.rs
2026-10-13 00:02:51 +00:00
aiongg 8ad77980ac Merge pr/648: Eyedropper: a sampled colour goes to the stroke when the Stroke box is in front (#648)
# Conflicts:
#	ROADMAP.md
#	crates/tools/src/xform.rs
#	crates/ui-egui/src/toolbar.rs
2026-10-13 00:01:26 +00:00
aiongg 8811669ee0 Merge alt-arrow-kerning: Type: Alt+Left/Right kerns at the caret and tracks a selection (#621)
Conflict: crates/engine/src/cmd/prefs.rs: next's document.preferences params doc + kerningIncrement
Conflict: crates/engine/src/tests.rs: tests both
Conflict: docs/target-app-parity.md: next's UI and Pen lines + the branch's Tools line
Conflict: ROADMAP.md: logs both
2026-10-12 21:58:22 +00:00
Marco Arnulfo fc01666ac2 feat(text): select sentence, paragraph and story on 3, 4 and 5 clicks (fixes #622) 2026-10-12 23:58:11 +02:00
moppeeerandClaude Opus 5.5 142e5d91e0 feat(eyedropper): A sampled colour goes to the stroke when the Stroke box is in front
As in InDesign, the Eyedropper applies a colour sampled from a placed image
to the fill or the stroke, whichever is in front in the toolbox: with the
Stroke box in front a selected line takes it on its stroke (it has no
fill to show it). The toolbox's state reaches tools through
ViewInfo/ToolContext::stroke_in_front.

Depends on #572.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 23:48:11 +02:00
aiongg 86a0ce2cf7 Type: Alt+Left/Right kerns at the caret and tracks a selection
With the Type tool, Option/Alt+Left/Right with a caret changes the manual kerning of the pair at the caret by the Kerning/Tracking increment (a new document preference, 20/1000 em by default, in Preferences > Units & Increments); with a selection it changes the tracking of the selected text. Cmd (Ctrl on Windows and Linux) multiplies the step by five. A pair without manual kerning starts from 0. The new type.kernStep command does the work, one undo step per press.

Moving by words is Cmd+Left/Right on macOS and Ctrl+Left/Right on Windows and Linux; Option/Alt+Shift+Left/Right still extends the selection by words. Fixes #621.
2026-10-12 20:48:14 +00:00
moppeeerandClaude Opus 5.5 cded7d997e feat(tools): Drag type-on-a-path start and end brackets
Selected type on a path shows its start and end brackets across the path,
as in InDesign, and the Selection and Direct Selection tools drag them
along it (Move Bracket, one undo step): the text starts and ends where
they are, and text past the end bracket is overset.

- doc: PathType.end (None: the path's end)
- geom: PathWarp::nearest, the arc length of the nearest point
- engine: type.pathOptions {end}; brackets stay on the path and can't cross
- compose: the line runs from the start to the end bracket
- idml: EndBracket read and written
- tools: Cursor::PathBracket

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 22:32:56 +02:00
moppeeerandClaude Opus 5.5 c35515c54d feat(tools): The Pen continues an open path from either end point
As in InDesign, the Pen over an end point of an open path (selected, or
under the pointer) shows a continue cursor; clicking it carries on drawing
that path, new anchors going on its subpath, and clicking its other end
closes it. Dragging from the end point first reshapes its direction
lines. From the first anchor the subpath is reversed first.

- engine: path.reverse (Object > Paths > Reverse Path), path.setAnchor;
  path.appendAnchor and path.close take a subpath, and appendAnchor
  refuses a closed subpath
- tools: Cursor::PenContinue

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 22:18:14 +02:00
aiongg 203870ed64 Merge #591: Double-click a frame handle to fit the frame to its content; Fit Frame to Content fits text frames
Conflict: crates/engine/src/cmd/object.rs: object.fit's doc keeps next's text and adds the `axis` clause; test modules from both sides
Conflict: crates/ui-egui/src/canvas.rs: kept next's input code (it sends the second press as Down with clicks: 2) and dropped the PR's release-time DoubleClick; the PR's UI test stays
Conflict: crates/tools/src/select.rs: the handle double-click joins next's second-press preamble, after the port checks and before editing text and the frame/content toggle (Down or DoubleClick with click_count 2 on a handle runs object.fit along fitting_axis); the DoubleClick arm stays empty; module doc from both
Conflict: crates/tools/src/tests.rs, ROADMAP.md: both sides
2026-10-12 18:56:35 +00:00
aiongg 796e9d713d Integration: the Eyedropper matches the clicked frame where no image pixel shows; sampling skips clipped-out pixels and hidden states (#572, #561)
color.sample takes `matchFrom`: with no opaque image pixel under the point (an empty part of an image frame, a transparent pixel), it applies that object's attributes as object.matchAttributes does, in the same command; the tool passes the object under the pointer. sample_item and the tool walk shown_children(), so only a multi-state object's active state is sampled, and sample_item skips points outside the graphic's clipping path. object.matchAttributes's body is a function both commands share.
2026-10-12 18:47:51 +00:00
aiongg 20a14d95f0 Merge #572: Eyedropper: sample a placed image's colour into the selected text or objects
Conflict: crates/engine/src/cmd/style.rs: object.color keeps next's apply_color, spec and enabled check (#84); takes the PR's color.sample (with next's enabled check), image_color_at and sample_item; drops the PR's color_swatch, color_items and has_text_or_selection; explicit `id`/`ids` win over a text selection in apply_color; the PR's tests follow next's caret behaviour (a caret takes the sampled colour for the next typing)
Conflict: crates/tools/src/tests.rs: both sides; the eyedropper test's Asset and Graphic literals gain next's pdf_crop, pdf_box, clip and wrap fields
Conflict: crates/ui-egui/src/i18n.rs, i18n/{ar,it,ja,pt_br,uk}.rs, ROADMAP.md: both sides
2026-10-12 18:43:58 +00:00
aiongg f11097c3f8 Merge #608: UI: spring-loaded zoom (Cmd+Space / Cmd+Alt+Space)
Conflict: crates/engine/src/tooling.rs: every with_ctx caller (IME preedit, commit, end, caret) takes the PR's `|s, cx| s.tool.…` form; pointer keeps next's end_composition before dispatch and tool_key its composing() early return
Conflict: crates/ui-egui/src/canvas.rs: the cursor block takes `space` from navigation_space, then the zoom branch, then `(space && !cmd) || alt_text`; the spring-zoom pointer events carry next's `clicks`; the PR's tests name their button helper `press` (next's tests have a `primary`) and compare cursors with what cursors::show sets for the engine cursor (next paints or rasterizes cursors per platform)
Conflict: ROADMAP.md, docs/target-app-parity.md, docs/ui-parity.md: status lines list both sides; progress and change-log rows keep both
2026-10-12 18:36:04 +00:00
moppeeerandClaude Opus 5.5 9ab226d741 fix(eyedropper): Sample rasters only; colour text through object.color
A placed PDF, EPS or SVG under the Eyedropper matches attributes again,
as before, instead of failing with "no placed image under the point"
(Asset::is_raster, shared by the tool and color.sample). color.sample
hands its colour to object.color, which now colours selected text, the
text of selected frames ({text: true}), or the typing colour of an empty
story; a caret in existing text is refused before a swatch or undo step.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 17:56:17 +02:00