Commit Graph
77 Commits
Author SHA1 Message Date
Brandon Thomas 742d46446f Merge PR #474 2026-10-15 00:35:27 -04:00
Brandon Thomas 94d0c57236 Merge PR #937
# Conflicts:
#	crates/ui-egui/src/dialogs.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-14 23:14:44 -04:00
Brandon Thomas d47e7a186c Merge PR #929
# Conflicts:
#	crates/tools/src/tests.rs
#	crates/ui-egui/src/icons.rs
2026-10-14 23:08:32 -04:00
Brandon Thomas 2dbf60be6f Merge PR #925
# Conflicts:
#	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-14 22:33:55 -04:00
Brandon Thomas 79a5c52e9d Merge PR #933 2026-10-14 22:05:12 -04:00
Brandon Thomas 69f61a2c4a Merge PR #816 2026-10-14 22:05:12 -04:00
Brandon Thomas 4cd3a8fa5e Merge PR #648 2026-10-14 22:05:11 -04:00
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
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
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
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
MarekSpodBiedry cab9200975 fix: eyedropper ignores inactive states of a multi-state object (#737) 2026-10-13 18:43:09 +02: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
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 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
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
moppeeerandClaude Opus 5.5 d7d6f27069 feat(eyedropper): Sample a placed image's colour into the selection
The Eyedropper on a placed image now does what InDesign does: with text
selected, clicking the photo colours the text with the image's colour under
the pointer; with objects selected, it fills them. The colour is an unnamed
colour (reused when the same colour is sampled again). Images on locked
layers can be sampled, and unfilled frames over the image let it show through.

- color.sample {at, spread?, target?: fill|stroke, ids?} samples the frontmost
  visible raster image at a spread point; one undo step; a caret or a point
  with no image is refused without an edit.
- object.color shares its swatch lookup with it.
- The Eyedropper tool sends color.sample over an image, matchAttributes
  elsewhere as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 17:56:17 +02:00
aiongg bb45f12b05 Place: with no frame selected, the graphic loads into the place cursor
File › Place (native picker, browser import, Place with Import Options
and the PDF page dialog) passes loadCursor to file.place. With no empty
or graphic frame selected and no x/y given, an image is added to the
document and loaded into the place cursor instead of landing in a new
frame on the first spread; a click places it at its natural size, a drag
draws its frame. The loaded graphic keeps the chosen PDF page and crop
box. Escape or choosing another tool unloads the cursor. Dropped files
and file.place without loadCursor behave as before.
2026-10-12 14:39:14 +00:00
aiongg cde814c0df Selection tool: Alt and Shift resize around the centre and keep side-handle drags centred 2026-10-11 12:24:00 +00:00
MarekSpodBiedry 5ab84500fe Show the first parent page behind single-sided pages (#429) 2026-10-11 11:40:56 +02:00
Middle DiscandClaude Haiku 5.5 2b55f2ed0d Layout: parent-page margins and guides, Create Guides on the current page, ruler-unit-aware Margins and Columns
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XWRYQ5eieuUrtxhdbh6goq
2026-10-11 12:16:18 +03:30
Brandon ThomasandClaude Opus 5.5 99b6228abd Snap: snap preferences as a command, overlay colours from tokens, tidy-up
- view.snapPreferences {alignEdges, alignCenters, smartDimensions,
  smartSpacing, zone} sets the smart guide options; the Preferences
  dialog goes through it, so the control channel and MCP reach them.
- Smart guide, gap and measurement colours come from theme::Tokens.
- Remove the unused closest-target helper (snap_rect and friends).
- Drop the agent planning docs (docs/superpowers) and the .worktrees
  ignore line; ROADMAP entry for smart guides and snapping.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 09:05:59 -04:00
Cameron Gilroy 78605f2944 Snap: visible bounds and constrained gestures 2026-10-06 09:05:59 -04:00
Cameron Gilroy 09c8dc3f06 Snap: pen and anchor points 2026-10-06 09:05:59 -04:00
Cameron Gilroy e76570c875 Snap: parent rotation is a target 2026-10-06 09:05:59 -04:00
Cameron Gilroy 343b0de552 Snap: rotation lands on the other angle 2026-10-06 09:05:59 -04:00
Cameron Gilroy 50e5355358 Snap: rotation matches another angle 2026-10-06 09:05:59 -04:00
Cameron Gilroy 5a74bf2d6e Snap: equal spacing on moves 2026-10-06 09:05:59 -04:00
Cameron Gilroy 8e7cff341f Snap: dimension guides follow the final edge
Shift plus Alt restores the aspect from the original center after the size snaps. A line keeps the runner delta on both axes. Dimension guides are redrawn on the committed side. Grouped own size decomposes the absolute transform once.
2026-10-06 09:05:59 -04:00
Cameron Gilroy 40f3b6454a Snap: dimensions on resize and create 2026-10-06 09:05:59 -04:00
Cameron Gilroy b0797f2b47 Snap: parent items use the stroked edge 2026-10-06 09:05:59 -04:00
Cameron Gilroy 7032587238 Snap: document grid and baseline passes 2026-10-06 09:05:59 -04:00
Cameron Gilroy 253f1a7a10 Snap: Alt-drag skips preview copies and Shift follows the turned view 2026-10-06 09:05:59 -04:00
Cameron Gilroy a2451243ad Snap: Shift and Command on a move 2026-10-06 09:05:59 -04:00
Cameron Gilroy 55ec575521 Snap: guides beat object alignment 2026-10-06 09:05:59 -04:00
Cameron Gilroy 4de93d1345 Snap: carry SnapView on the tool context 2026-10-06 09:05:59 -04:00