Commit Graph
558 Commits
Author SHA1 Message Date
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
moppeeer ed6bcae877 Merge remote-tracking branch 'origin/main' into codex/gradient-cmyk-blend 2026-10-14 09:12:51 +02:00
moppeeer f6cbcac5ed Merge remote-tracking branch 'origin/main' into codex/essentials-classic-workspace 2026-10-14 09:12:35 +02:00
moppeeer 1faaebef25 Merge remote-tracking branch 'origin/main' into codex/gradient-text 2026-10-14 09:12:03 +02:00
skylar taylor-barrick c68cb357e9 fix(pdf): preserve writer integration with main (PDFW)
Retain the PDF writer adoption and upstream text-threading changes. Keep both roadmap entries and use the accepted-socket fixture comment from main.
2026-10-14 00:18:33 -06:00
LabDennis ff5d866ff3 chore(sync): merge upstream main into PR #854 2026-10-14 06:51:45 +02:00
aiongg 8e2c62e08a Integration: #84 control-channel paste and IME use the control queue with keys and clicks; click count 1-255 checked inside the pending-event budget, which counts the control queue 2026-10-14 04:24:39 +00: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 47b51d6377 Integration: #864 drops the Controlled by Parent rule from the menus and the Objects Move with Page checkbox (neither has an effect yet) 2026-10-14 01:39:08 +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
aiongg 063856cc4c Merge t14-b: #836 #840 #846 #854, Find/Change first:true
# Conflicts:
#	ROADMAP.md
2026-10-14 00:09:13 +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 8864307d7c docs: the Page tool's Control panel in the parity notes
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 00:52:06 +02:00
aiongg 5ff7c4f956 Merge #854: index duplicate asset candidates by content (#727)
# Conflicts:
#	docs/file-format-parity.md
2026-10-13 22:41:06 +00:00
aiongg cd317a235a Merge #553: docs: add user docs in docs/user 2026-10-13 22:36:18 +00:00
aiongg 283d04e14f Integration: #859 drop the control-channel safety note from the editing gap, which lists missing features 2026-10-13 22:36:08 +00:00
aiongg 450bee203a Merge #859: Control: bound click and drag input before queuing events 2026-10-13 22:36:03 +00:00
aiongg dc2dda7717 Merge #836: gradients between process colours blend as inks
# Conflicts:
#	ROADMAP.md
2026-10-13 22:31:16 +00: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
Andreas Haraminac 5024ed8870 #732: bound control-channel click and drag event queues 2026-10-13 21:55:44 +00:00
LabDennis 0fd627aa44 perf(assets): index duplicate candidates by content (#727) 2026-10-13 23:12:09 +02:00
aiongg e19b6b1fd9 Merge toc-dialog: Table of Contents dialog, entry options and IDML TOC styles (#755)
# Conflicts:
#	ROADMAP.md
#	crates/engine/src/tests_idml.rs
#	crates/idml/src/import.rs
#	crates/ui-egui/src/dialogs.rs
2026-10-13 20:44:30 +00:00
aiongg 129adfa429 Layout: Table of Contents dialog with entry styles, page number position and IDML TOC styles (#755) 2026-10-13 20:41:56 +00:00
aiongg d5c26cc781 Merge t13-commands: #764 #757 #802 #803
# Conflicts:
#	crates/engine/src/cmd/object.rs
2026-10-13 20:28:49 +00: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 16c2ac46c6 Merge #829: Polish UI language
# Conflicts:
#	ROADMAP.md
#	crates/ui-egui/src/chrome.rs
#	crates/ui-egui/src/dialogs.rs
#	crates/ui-egui/src/i18n.rs
#	crates/ui-egui/src/menus.rs
#	docs/localization-parity.md
#	docs/target-app-parity.md
2026-10-13 20:06:53 +00:00
aiongg c6921a77cb Merge #802: File › Open Recent: recent documents in the menu and on the start screen
# Conflicts:
#	ROADMAP.md
#	apps/designcraft/src/native_menu.rs
#	crates/engine/src/cmd/file.rs
#	crates/engine/src/cmd/mod.rs
#	crates/engine/src/cmd/prefs.rs
#	crates/engine/src/lib.rs
#	crates/format/src/lib.rs
#	crates/ui-egui/src/dialogs.rs
#	crates/ui-egui/src/menus.rs
#	docs/target-app-parity.md
2026-10-13 20:06:29 +00:00
aiongg 7f0d7f1f32 Merge t13-moppeeer: #253 #832 #753 #754 (a3b97165) #588
# Conflicts:
#	ROADMAP.md
#	crates/idml/src/tests.rs
2026-10-13 19:57:37 +00:00
aiongg a4ec5b31d6 Merge t13-gradients: gradient PRs #765 #763 #826 #823 #825 2026-10-13 19:55:40 +00:00
aiongg 6039be0526 Merge #588: CMYK blend space: blend modes blend in CMYK on screen
# Conflicts:
#	ROADMAP.md
#	crates/render/src/fx.rs
#	crates/render/src/lib.rs
2026-10-13 19:37:18 +00:00
aiongg 1847b8cef5 Merge #825: Gradient swatches on text, laid across the text frame
# Conflicts:
#	ROADMAP.md
#	crates/pdf/src/export.rs
#	crates/pdf/src/text.rs
#	crates/render/src/text.rs
#	docs/target-app-parity.md
2026-10-13 19:30:47 +00:00
aiongg 42f000e95a Merge #832: Window menu in InDesign's order; Window > Workspace with Essentials Classic
# Conflicts:
#	ROADMAP.md
#	crates/ui-egui/src/chrome.rs
#	crates/ui-egui/src/dock.rs
#	crates/ui-egui/src/menus.rs
2026-10-13 19:28:59 +00:00
aiongg f60eb24656 Merge #823: Gradient strokes: on screen, in PDF, in IDML and the Gradient panel
# Conflicts:
#	ROADMAP.md
#	crates/engine/src/cmd/object.rs
#	crates/engine/src/cmd/style.rs
#	crates/idml/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
#	crates/ui-egui/src/panels/swatches.rs
#	docs/target-app-parity.md
2026-10-13 19:28:11 +00:00
aiongg da8aaa9cdc Merge #826: Gradient panel layout; drop swatches from the Swatches panel onto its stops
# Conflicts:
#	ROADMAP.md
#	crates/ui-egui/src/panels/swatches.rs
#	docs/target-app-parity.md
2026-10-13 19:25:12 +00:00
aiongg fce28331ec Merge #763: New Swatch names a gradient "New Gradient Swatch"; gradient swatches from colour swatches
# Conflicts:
#	ROADMAP.md
#	crates/engine/src/cmd/style.rs
#	docs/target-app-parity.md
2026-10-13 19:23:33 +00:00
aiongg 9d5d341a7d Merge #765: Radial gradients stretch with the object's box (an ellipse) 2026-10-13 19:21:58 +00:00
skylar taylor-barrick efd2310c83 refactor(pdf): share writer backend (PDFW) 2026-10-13 13:20:47 -06:00
aiongg 8a4dac7faa Merge #815: fix(pdf): leave form fields and media out of PDF/A-2b exports (#743) 2026-10-13 19:03:42 +00:00
aiongg b4f7286482 Merge text-autosize: opening a file keeps its auto-size frame sizes (#632)
# Conflicts:
#	ROADMAP.md
#	crates/engine/src/cmd/interchange.rs
#	docs/gaps.md
#	docs/target-app-parity.md
2026-10-13 18:40:15 +00:00
aiongg 935741d47c Text frames: opening a file keeps its auto-size frame sizes 2026-10-13 18:40:01 +00:00
moppeeerandClaude Opus 5.5 dc712baeca fix(color): gradients between process colours blend as inks, as InDesign shows them
LYH Studio episode 6 builds every gradient from C=0 M=100 Y=0 K=0 to
C=100 M=0 Y=0 K=0. InDesign blends a gradient's process stops as inks:
halfway is C 50 M 50, a light lilac. DesignCraft converted both ends to
RGB and blended there, so the middle came out a darker violet (117, 88,
189 instead of 135, 119, 181), and every Episode 6 gradient looked
different. A midpoint between CMYK stops also became an RGB colour, so
the PDF shading turned RGB with a conversion warning.

- color: `Color::lerp` blends CMYK with CMYK (or grey), and grey with
  grey, in ink space; anything with RGB still blends in RGB.
- `Gradient::display_stops`: the expanded stops plus samples through
  each span that isn't RGB at both ends, for renderers that interpolate
  in RGB; the screen renderer uses it.
- pdf: a midpoint's expanded stop now keeps the stops' space; the
  colour-space test expects no conversion for CMYK or grey midpoints.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 20:38:38 +02:00
moppeeerandClaude Opus 5.5 0a34316b82 feat(ui): Window menu in InDesign's order; Window > Workspace with Essentials Classic
LYH Studio episode 6 starts with "Window > Workspace > Essential
Classic" and opens panels with "Window > Color > Gradient & Swatches".
DesignCraft's Window menu had no Workspace or Color submenu (panels sat
in one "Panels" list) and no Essentials Classic workspace.

- Window menu: Arrange, Workspace, then the panels alphabetically with
  InDesign's groups (Color: Color, Gradient, Swatches; Editorial;
  Interactive; Object & Layout; Output; Styles; Type & Tables;
  Utilities). Every panel stays reachable; Next/Previous Document moved
  into Arrange.
- Window > Workspace: the built-in workspaces as "[Essentials]", the
  current one checked, Reset <current>, New Workspace. The app bar's
  switcher uses the same list and order.
- Essentials Classic: the Control panel, no Properties stack, and an
  icon column of named panel groups ([Pages, Layers, Links] [Stroke,
  Color] [Swatches] [Effects] [Paragraph] [Text Wrap] [Character
  Styles, Paragraph Styles] [Gradient]); Window > Pages opens Pages
  from its group. Saved workspaces keep the groups.
- Flyouts and floating panels name Pages, Layers and Properties.
- Translations for Editorial, Object & Layout, Styles and Essentials
  Classic.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 20:16:51 +02:00
moppeeerandClaude Opus 5.5 bdf66d7749 feat(ui): Gradient panel in InDesign's layout; swatches drop onto its stops
LYH Studio episode 6 (1:36-2:05) builds its gradient in the Gradient
panel: it drags C=0 M=100 Y=0 K=0 from the Swatches panel onto the left
stop, drops C=100 M=0 Y=0 K=0 on the ramp (a new stop at 68.636 %), then
drags the black stop off. DesignCraft's Gradient panel took no swatches,
showed only a hint until the fill was a gradient, and laid out its
fields differently.

- Gradient panel: InDesign's layout (thumbnail; Type; Location % and
  Angle; Reverse; the ramp with midpoint diamonds above and stops below).
  Until the fill is a gradient it shows the default White -> Black ramp;
  clicking the thumbnail or using the ramp starts one. Midpoints drag
  and take a Location. A stop's colour picker moved to its right-click
  menu, so selecting a stop no longer grows the panel.
- Swatches panel rows are drag sources (the chip follows the pointer):
  dropped on a stop a swatch colours it, elsewhere on the ramp it adds
  a stop there.
- Stops keep their colour model through panel edits (CMYK used to turn
  into hex RGB whenever a stop moved).
- engine: `object.gradient` stops accept `swatch` (its colour; gradient
  swatches and [None] are refused) and colours accept `{gray}`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 20:02:45 +02:00
moppeeerandClaude Opus 5.5 ac54c8faf7 feat(text): gradient swatches on text, laid across the frame as in InDesign
LYH Studio episode 6 (8:28) gives the "1969" headline the "New Gradient
Swatch" (magenta → cyan) from the Swatches panel. InDesign runs a gradient
on text across its text frame's box. DesignCraft resolved a character
fill to one solid colour, so a gradient swatch drew no text at all.

- render: a character fill or stroke that names a gradient swatch is
  painted with that gradient over the frame's box in text space (type on
  a path: the path's box).
- pdf: text runs take a gradient paint: the shading is laid out in the
  frame's text space and mapped into each run's origin, so skew and
  horizontal scale don't bend it; outlined runs and type on a path too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 19:30:55 +02:00
Tomasz LewandowskiandClaude Opus 5.5 226991cb28 i18n: add Polish interface language
Adds a Polish catalog (i18n/pl.rs, 1,698 strings), registers Polski in
Edit › Interface Language, uses category-first count captions for Polish
(as for Ukrainian) and adds catalog and language-switch tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DukHNvUY45rjRnvtz91x33
2026-10-13 19:16:32 +02:00
moppeeerandClaude Opus 5.5 370dca2ca2 feat(render): gradient strokes, on screen, in PDF and in the Gradient panel
A gradient swatch on a stroke drew nothing: strokes were painted with a
single resolved colour. LYH Studio episode 6 gives the loop on the right
page (9:13) and, at first by accident, the circle (1:19, "right now it
is on the stroke") a gradient stroke.

- doc: Stroke::gradient_angle / gradient_vector (as Fill's) and
  Stroke::as_fill(), the stroke's paint as a fill.
- render and PDF: a gradient stroke is painted like a gradient fill,
  across the path's box (dash gaps and arrowheads keep their paints).
- engine: object.gradient {target: stroke} edits the stroke's
  gradient (kind, stops, angle, the Gradient Swatch tool's from/to);
  scaling moves the stroke's vector with the shape.
- IDML: GradientStrokeStart/Length/Angle round-trip.
- Gradient panel: acts on the stroke when the toolbox's Stroke box is
  in front, as InDesign's follows the Fill/Stroke proxy.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 19:11:58 +02:00
MarekSpodBiedry 79b9971939 fix(pdf): leave form fields and media out of PDF/A-2b exports (#743) 2026-10-13 18:44:45 +02:00