Commit Graph
352 Commits
Author SHA1 Message Date
aiongg f4e769369c Merge main: fix(macos): make Dock Quit cancelable; test(recovery): make failed republishing fixtures deterministic
Conflict: Cargo.toml: next's winit patch (rust-windowing/winit#4694, Windows mixed-DPI drags) kept; main's skylartaylor/winit patch held back (Cargo takes one patch per crate; both are single commits on v0.30.13 for different platforms, no published commit has both)
Conflict: Cargo.lock: next's winit source; main's ui-egui tempfile dev-dependency taken
Conflict: apps/designcraft/src/main.rs: next's startup; main's macOS with_close_requested_on_terminate block left out (needs main's winit patch); apps/designcraft/Cargo.toml keeps next's (no macOS winit dependency)
Conflict: ROADMAP.md: headers combined, logs both
Conflict: docs/target-app-parity.md: headers combined
2026-10-12 21:40:47 +00:00
skylar taylor-barrick 64f0ca8fa6 fix(macos): make Dock Quit cancelable
Route AppKit termination through the existing unsaved-document close transaction using the immutable winit patch. Restore pending prompts from hidden or minimized windows and preserve answers across repeated requests.

Validation: all six local gates, native cancellation/retry/save smoke, and hosted platform checks.

Fixes #544.

PR #623.
2026-10-12 14:52:12 -06:00
aiongg dfd98fca13 Merge parent-pages-panel: Pages panel: double-clicking a parent shows that parent; parent thumbnails (#624)
parent-pages-panel 4e7b3360.

Conflict: crates/engine/src/cmd/layout.rs: branch's layout.parents.edit {on?, parent?} with bump_revision; branch's Result-returning parent_ref (pages.insert and applyParent callers merged clean) next to next's set_margins_columns and parent_spread_index (a stray parent_ref doc line above set_margins_columns dropped); next's test modules plus the branch's parent_tests
Conflict: crates/ui-egui/src/panels/pages.rs: branch's page and parent thumbnails through next's widgets::load_texture
Conflict: ROADMAP.md: header keeps next's change list plus Pages panel parents; the branch's progress line first
2026-10-12 20:11:02 +00:00
aiongg e2dd71378e Merge #609: Balance Columns evens out the last frame's columns
balance-columns 30ba4721.

Conflict: crates/compose/src/lib.rs: story-end check (balance_end) before next's deleted-paragraph filler, then prange; next's `go` closure with the branch's band tail on Next Column; next's Cursor::clip replaced by the branch's tail-aware clip (the auto-placed duplicate dropped)
Conflict: crates/compose/src/tests.rs, crates/idml/src/tests.rs: tests both
Conflict: ROADMAP.md, docs/target-app-parity.md: both (auto-size and Balance Columns lines)
2026-10-12 20:06:06 +00:00
aiongg 38bdc19232 Merge #180: text frame auto-size grows and shrinks frames to fit their text
text-autosize 60551322.

Conflict: crates/doc/src/item.rs: next's reference-point doc and default auto_size_ref 4 (centre, as IDML leaves it) plus the branch's minimum-size and No Line Breaks fields
Conflict: crates/engine/src/lib.rs: autosize pass before next's record_undo_step on the success path; bump_revision for next's global revisions
Conflict: crates/engine/src/cmd/interchange.rs: next's grep_style_warnings and .indd comment plus the branch's autosize::apply on import
Conflict: crates/engine/src/cmd/object.rs: branch's textFrameOptions params doc with next's firstBaseline values
Conflict: ROADMAP.md: progress log both
Conflict: docs/gaps.md: next's optical kerning wording with the branch's auto-size note on #180
2026-10-12 19:57:02 +00:00
aiongg 4e7b33607e Pages panel: double-clicking a parent shows that parent; parents are identified by id
- layout.parents.edit takes `parent` (id, full name, or a prefix only one
  parent has) and asks the canvas to fit that parent's spread; turning
  editing on without one shows the first parent. The result names the
  parent shown.
- Commands resolve parents by id, then full name, then a unique prefix.
  Unknown or ambiguous names are errors, so a typo no longer clears a
  page's parent; null or "[None]" clears it.
- Pages panel: only the row of the parent the canvas shows is selected;
  rows, drag payloads and the Apply Parent menu carry the parent id.
  Parent rows show rendered thumbnails of the parent spread, cached by
  document revision like page thumbnails.
- Delete All Guides on a parent acts on the parent the canvas shows.

Fixes #624.
2026-10-12 19:49:59 +00:00
aiongg b32deda339 Merge #612: Windows mixed-DPI drag keeps the window's size; GPU surface up to the adapter's texture limit
win-mixed-dpi 38dad0fb. Cargo.lock: next's lock plus the winit git source and the dpi 0.1.1 it brings (merged clean; cargo metadata --offline leaves it unchanged).

Conflict: apps/designcraft/src/main.rs: next's startup (adapter selection, catch_unwind, apple events) with log_uncaptured_errors at the top of its wgpu_render_state block; request_adapter_texture_size and mod gpu_limits merged clean
Conflict: ROADMAP.md: progress log both
Conflict: docs/hardware-parity.md: header keeps next's change list plus the mixed-DPI note
2026-10-12 19:49:59 +00:00
aiongg 527e5cbc0c Merge main: atomic desktop and CLI exports, staged book updates, recovery checkpoint retention, exit recovery
upstream/main c3859c82 (#614 e198eb5d, #615 9509b2bc, #616 8e151a2f, #617 c3859c82).

Conflict: ROADMAP.md: header keeps next's change list plus orderly native exit recovery; progress log both
Conflict: apps/designcraft-cli/src/main.rs: next's case-insensitive .jpg/.jpeg check with main's write_atomic
Conflict: apps/designcraft/src/main.rs: on_exit keeps next's startup.presented() (not an Option) and adds preserve_documents_on_exit; next's discard_marked_text and main's preserve_documents_on_exit both; Services write uses write_atomic and keeps next's clipboard_text; tests both
Conflict: crates/engine/src/cmd/book.rs: main's ChapterBatch paginate with next's chapter-number resolution and {pages, chapters} result and doc
Conflict: crates/engine/src/cmd/file.rs: revert takes main's discard_document ordering without the revision + 1 (next's DocState::new hands out a fresh revision)
Conflict: crates/engine/src/recovery.rs: main's save_tracked, write_entry and open (st.bump_revision() for next's global revisions); next's reopen-twice test assertions kept
Conflict: docs/gaps.md, docs/target-app-parity.md: headers combined; next's Language, Books and Numbering lines plus main's book update safety line
2026-10-12 19:46:34 +00:00
aiongg 30ba47211e Text frames: Balance Columns evens out the last frame's columns (#609)
In the frame a story ends in, Balance Columns lowers the bottom of the
columns after the last explicit column break as far as the text still
fits, reusing the bounded search that balances columns above spanning
paragraphs. Frames the text runs on from fill normally. Text Frame
Options gets a Balance Columns checkbox.
2026-10-12 19:18:45 +00: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 605513228a Text frames: auto-size grows and shrinks frames to fit their text
Height Only, Width Only, Height and Width and Keep Proportions frames fit
their text after every undoable command (same undo step) and after IDML
import, around the reference point, with minimum height/width and No Line
Breaks. Text Frame Options gains an Auto-Size section; IDML reads and writes
the minimum and no-line-break attributes. Applies to unthreaded frames and
the last frame of a thread; vertical frames and type on a path are left as
they are. (#180)
2026-10-12 18:55:57 +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
aiongg 38dad0fbde Windows: dragging across monitors with different scales doesn't grow or crash the window
winit 0.30.13 mishandles WM_DPICHANGED during a live drag on Windows 11:
the window flips between the two scales and grows past the GPU surface
limit. Pin winit to the one commit of rust-windowing/winit#4694, its
0.30.x backport of the fix.

The device asks for the adapter's largest texture side instead of
eframe's fixed 8192, and an uncaptured wgpu error is logged instead of
panicking, so a window larger than the surface limit draws wrongly
until it shrinks rather than closing the app.
2026-10-12 18:29:54 +00:00
aiongg 3f6f8453ca Merge #577: fix(render): A group's gradient feather fades the group, on screen and in PDF
Conflict: crates/doc/src/item.rs: both tests (next's rotated group bounds, the PR's feather bounds)
Conflict: ROADMAP.md: both progress lines
2026-10-12 18:29:39 +00:00
aiongg 8e212fb611 Merge #255 (update): fix(ui): Compact the Advanced object Control panel into aligned rows
The update rebases the compact panel next has (already inside the control bar's scroll area) and adds accessibility labels and the progress line.
Conflict: crates/ui-egui/src/panels/mod.rs: next's swatch_list with the PR's swatch_picker returning the chip's response; next's swatch-list test discards it
Conflict: crates/ui-egui/src/chrome.rs: kept next's control-bar tests (they find the Fill chip by its group)
Conflict: crates/ui-egui/src/{lib.rs,object_control.rs}: rebased duplicates; kept next's side, then took the PR's labels
Conflict: ROADMAP.md: both progress lines
2026-10-12 18:23:46 +00:00
aiongg 2e777eb41d Merge #341 (update): feat(engine): Document chapter numbering and section prefix rules
The update rebases the engine commits next has and adds the progress docs.
Conflict: crates/engine/src/cmd/{book,layout}.rs: rebased duplicates; kept next's side
Conflict: docs/target-app-parity.md: next's Language line (Norwegian) with the PR's Books line
2026-10-12 18:20:18 +00:00
skylar taylor-barrick c3859c828b fix(recovery): preserve documents on orderly app exit
Checkpoint the latest document state during App::on_exit after honoring current quit approvals. Keep incomplete or stale plans, clear recovery for clean documents and report unavailable or failed storage.

Follow-up to #545; cancelable macOS Dock Quit remains open in #544.

PR #617.
2026-10-12 12:18:32 -06:00
aiongg e439d5d4d2 Merge main: preserve live state when persistence fails (#613)
Conflict: crates/engine/src/cmd/file.rs: spec strings keep next's (extension, return value, .indd); Save a Copy adds the extension then rebases data-source paths on a copy; file_save takes main's prepare-then-commit order with next's bump_revision
Conflict: ROADMAP.md: status line lists both changes; progress log keeps both sides
2026-10-12 18:17:47 +00:00
skylar taylor-barrick 8e151a2fd4 fix(recovery): retain recovered checkpoints until save or close
Keep recovered snapshots available through a second crash before autosave. Track checkpoint ownership across folders and restarted IDs; Save, Close and Revert clean only checkpoints owned by that document.

Follow-up to #506 and the retention concern in #380.

PR #616.
2026-10-12 12:15:46 -06:00
skylar taylor-barrick 9509b2bcea fix(book): stage chapter updates before saving
Prepare and stage every chapter before a book update writes files. Preserve imported IDML sources, reject open native chapters and report completed paths after a later write failure.

Follow-up to #485.

PR #615.
2026-10-12 12:12:01 -06:00
skylar taylor-barrick e198eb5d1d fix(export): replace desktop and CLI outputs atomically
Route desktop writes and CLI raster exports through the engine atomic writer. Add actual-caller regressions for reader visibility, private modes, symlinks and valid long filenames.

Follow-up to #485.

PR #614.
2026-10-12 12:04:39 -06:00
skylar taylor-barrick b9048a5b08 fix(save): preserve live state when persistence fails
Preserve document paths, revisions and collection contents when persistence fails. Rebase Save a Copy paths without changing the open document.

Follow-up to #485.

PR #613.
2026-10-12 11:53:46 -06:00
aiongg 3ac3bc90de Merge main (0.7.1): atomic saves, recovery per instance, quit keeps documents when cancelled
Conflict: crates/engine/src/atomic.rs: main's side (the reviewed #485 code supersedes the PR head on next)
Conflict: crates/engine/src/recovery.rs: main's #506 code, with next's write_entry helper kept
Conflict: apps/designcraft/src/profile.rs: main's own_run returning Option (and_then), with next's portable root_with argument
Conflict: crates/ui-egui/src/lib.rs: main's QuitState quit flow (d020b4e8) over the #545 head; next's Find Font alert guard; one import_warning_tests module (next's, with the Find Font test)
Conflict: apps/designcraft/src/native_menu.rs: next's MAC_APP_MENU layout, which already has the dc-quit item running app.quit
Conflict: ROADMAP.md: next's header with the quit change added; next's log entries then main's three
Conflict: docs/target-app-parity.md: main's atomic save, recovery and quit lines
2026-10-12 17:14:07 +00:00
moppeeerandClaude Opus 5.5 dac7abde88 docs: Compact Control panel in the progress log
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 18:29:18 +02:00
moppeeerandClaude Opus 5.5 4770a494be docs: Chapter numbering in the progress docs
Rebased on the progress-docs restructure: the ROADMAP bullet moved to the
inventory in docs/target-app-parity.md (Books), with a progress-log line.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 18:29:16 +02:00
moppeeerandClaude Opus 5.5 1c4b6885c7 fix(render): A group's gradient feather fades the group, on screen and in PDF
A gradient feather on a group (Gradient Feather tool over grouped text, as
in LYH Studio's poster tutorial) did nothing on screen: groups never went
through the effects path. In PDF the group's mask was the group's own path
bounds, and a group has no path, so the mask covered a box of zero size and
hid the group.

- Item::feather_bounds: the box the feather spans, the objects' bounds for
  a group.
- Render: a feathered group draws its objects in one layer, then fades it
  with the same mask as other objects (fx::gradient_feather_mask).
- PDF: the group's mask spans its objects.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 18:01:25 +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
moppeeerandClaude Opus 5.5 4e250565ac feat(tools): Double-click a frame handle to fit the frame to its content
In InDesign double-clicking a selection handle fits the frame to its
content: a corner fits both sides, a top or bottom handle the height, a
side handle the width. LYH Studio's tutorial uses it at 9:30 to fit the
INDESIGN text frame before moving it to the corner. In DesignCraft the
double-click switched to the Type tool.

- Selection tool: a double-click on a handle runs object.fit
  {mode: fitFrameToContent, axis: both|height|width}.
- object.fit fitFrameToContent fits text frames to their composed text:
  the bottom to the last line's descent, the right side to the longest
  line (one column), plus the insets, keeping the top-left. Overset text
  grows the frame first. Before, it fitted graphic frames only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 17:40:35 +02:00
d020b4e85d fix(ui): preserve documents when quitting is cancelled
Prompt for unsaved documents on window close and application/menu quit. Defer discarding documents until all approvals are current, retaining every tab when a later decision cancels quitting.

Refs #544. Cancelable macOS Dock Quit remains separate.

Co-authored-by: aiongg <aiongtaigi@gmail.com>
Co-authored-by: skylar taylor-barrick <hi@skylar.cc>
2026-10-12 09:31:24 -06:00
Noah Scholzandskylar taylor-barrick 328b4d5a52 fix(recovery): isolate recovery data between app instances
Keep each app's recovery data in an owned run folder. Validate current folder and lock ownership and disable recovery when isolation fails instead of using the shared root.

Fixes #496.

Co-authored-by: noah1400 <48360809+noah1400@users.noreply.github.com>
Co-authored-by: skylar taylor-barrick <hi@skylar.cc>
2026-10-12 09:26:34 -06:00
5cdcac4ace fix(save): replace files atomically
Replace native engine saves and engine/MCP exports atomically, preserving private permissions during staging and cleaning up failed writes. Add regressions for long filenames and caught writer unwinding.

Fixes #436.

Co-authored-by: aiongg <aiongtaigi@gmail.com>
Co-authored-by: skylar taylor-barrick <hi@skylar.cc>
2026-10-12 09:19:36 -06:00
rasnoland 99ced6cc0a UI: spring-loaded zoom (Cmd+Space / Cmd+Alt+Space) 2026-10-12 16:09:24 +01:00
aiongg a5fbf5d8d4 Merge table-border-drag: Tables: drag row and column borders with the Type tool
Conflict: crates/compose/src/lib.rs: one re-export line with next's hit_cell_with and the branch's BorderHit/hit_border
Conflict: crates/tools/src/text.rs: next's IME/preedit, guides and unit_selected kept alongside the border drag; border press checked after the Down resets; drag keeps next's `cell_drag || unit_selected` guard after the border branch; Esc cancels a border drag before next's preedit guard; BorderHit via next's `compose` alias
Conflict: crates/tools/src/tests.rs: both sides' appended tests kept
Conflict: docs/target-app-parity.md: next's IDML line, branch's Tables line
Conflict: ROADMAP.md: branch entry on top of next's entries
2026-10-12 14:56:19 +00:00
aiongg 44fde50463 Tables: drag row and column borders with the Type tool
Hovering a table's inner column or row border, or its end or bottom
edge, shows a double-arrow cursor; dragging resizes instead of selecting
text. A column drag changes the column before the border and moves later
columns; Shift keeps the table width (the next column compensates), and
Shift on the end edge scales every column. Rows work the same way, and a
dragged row becomes At Least. Sizes clamp at 3 pt. One undo step per
drag, Esc cancels, locked frames refuse, and the pointer is mapped
through the frame's transform so rotated frames and turned spreads work.

New command table.resizeBorder {story?, table?, frame?, axis, index,
delta | size, keepTableSize?}; the Type tool emits it through
Begin/Preview/Commit. compose::hit_border finds the border under a point
in frame inner space.

Closes #595
2026-10-12 14:52:31 +00:00
aiongg 1ebefe4db4 Merge fill-stroke-keys: Engine: swap and default fill and stroke in one undo step
Conflict: ROADMAP.md: both progress lines kept
Conflict: docs/target-app-parity.md: next's UI and tools lines kept, with the Fill/Stroke proxy keys added to the UI line
Conflict: crates/ui-egui/src/lib.rs: UiState keeps next's tabs_panel and the branch's stroke_front
Conflict: crates/ui-egui/src/menus.rs: UI_COMMANDS keep next's togglePresentation and formattingAffectsText entries and add the color.* entries
Conflict: crates/ui-egui/src/toolbar.rs: next's text-aware proxy buttons (color_target, colors_affect_text, apply_swatch) kept; the proxy reads stroke_front from UiState instead of egui temp data
2026-10-12 14:48:16 +00:00
aiongg 4ac6e9a540 Engine: swap and default fill and stroke in one undo step
object.swapFillStroke and object.defaultFillStroke change every unlocked
target in one edit, so one undo restores them all. Swap works per object
and keeps each object's tints; a stroke that gets a colour at zero weight
gets the default 1 pt. Objects that are locked, or on a locked layer,
stay as they are. color.swapFillStroke and color.defaultFillStroke run
these commands.
2026-10-12 14:28:58 +00:00
aiongg b21111f232 Toolbox: Shift+X, D, X and / shortcuts for the Fill/Stroke proxy
The proxy's tooltips named keys that did nothing. color.defaultFillStroke
(D), color.swapFillStroke (Shift+X), color.toggleFillStroke (X) and
color.applyNone (/) are UI commands; the proxy's buttons run the same
commands. Swap keeps the fill and stroke tints.

Which of fill and stroke is in front lives in UiState, shared by the
Tools panel proxy, the Color panel and the commands. The single-key
shortcuts stay out of text being typed, like the tool shortcuts.
2026-10-12 14:21:36 +00:00
aiongg 432e1cbbcc Merge #585: Hyphenation Zone applies to the Single-line Composer only
Conflict: ROADMAP.md: both progress-log lines kept
2026-10-12 14:10:25 +00:00
moppeeerandClaude Opus 5.5 0c4a6641cb fix(compose): Hyphenation Zone applies to the Single-line Composer only
InDesign's Hyphenation Zone ("the white space allowed at the end of a
line of unjustified text before hyphenation begins") applies only with the
Single-line Composer. The Paragraph Composer, the default, weighs every
break of the paragraph instead. DesignCraft applied the default 3p0 zone
to both, so ragged paragraphs under the Paragraph Composer refused
hyphens InDesign makes. In LYH Studio's poster tutorial the placeholder
text breaks "aper-natem" and "mosticsia-tur"; ours ran a line longer.

The breaker now gets the zone only for unjustified Single-line Composer
paragraphs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 14:57:09 +02:00
aiongg 4dbd73a6fd Merge #550: Transform values act on a selected placed graphic, not its frame
Conflict: crates/engine/src/cmd/object.rs: transform.set doc string joins next's "measured from the rulers' zero point" with the PR's `content?`; test modules: kept next's copy_ids_tests/tint_alone_tests and the PR's content_transform_tests
Conflict: crates/ui-egui/src/panels/mod.rs: kept next's swatch_list_tests and the PR's content_selection_tests
Conflict: ROADMAP.md: kept both progress-log lines
2026-10-12 12:29:25 +00:00
aiongg 22d428f747 Merge #466: feat(ui): Lay out the font menu like InDesign's
The PR's first three commits are patch-identical to #536/#537, already on next.

Conflict: crates/engine/src/cmd/text.rs: next's side (its `type.selectionAttrs` already carries the PR's selected text, plus next's later `mixed` and typing-format work)
Conflict: crates/fonts/src/fontdb.rs, crates/fonts/src/lib.rs: next's side (the PR's font-kind code is already there through #536; next adds aliases, PostScript names, mac_fonts)
Conflict: crates/ui-egui/src/lib.rs: kept both field sets (`recent_new_documents`, `font_sample`/`font_preview_size`)
Conflict: crates/ui-egui/src/panels/mod.rs: took the PR's move of `font_menu_body` into font_menu.rs; next's #447 test edit and `swatch_list_tests` stay
Conflict: crates/ui-egui/src/i18n.rs, crates/ui-egui/src/i18n/it.rs, ROADMAP.md: kept both sides' rows
2026-10-12 12:27:18 +00:00
aiongg 1f69461ff5 Merge #575: Effects panel: the level row, Isolate Blending and Knockout Group
Conflict: crates/ui-egui/src/i18n.rs: kept next's Step and Repeat rows and the PR's Effects rows
Conflict: crates/ui-egui/src/i18n/ar.rs, it.rs, ja.rs, pt_br.rs, uk.rs: kept both sides' rows
Conflict: ROADMAP.md: kept both progress-log lines
2026-10-12 12:25:51 +00:00
aiongg 19bf6dd868 Merge #573: Step and Repeat: InDesign's dialog with Create as a grid and Preview
Conflict: crates/ui-egui/src/dialogs.rs: kept next's Cell Options functions and the PR's Step and Repeat code; both sides added `cancel()`, joined into one that ends a dialog preview (PR) and puts back the Preferences language (next); tests keep next's `document_setup_app` and the PR's Step and Repeat test (the PR's copy of `dialog_context` already exists further down)
Conflict: ROADMAP.md: kept both progress-log lines
2026-10-12 12:25:32 +00:00
aiongg 8cd0e74a33 Merge #571: Styles: Load Styles from another document or IDML file
Conflict: crates/ui-egui/src/lib.rs: import_file takes the PR's `styles` early return first, then next's content-sniffing `layout` line
Conflict: ROADMAP.md: kept both progress-log lines
2026-10-12 12:24:34 +00:00
aiongg dcabd61597 Merge #570: Blend modes don't blend with the paper
Conflict: crates/render/src/lib.rs: push_layer after next's back document-grid drawing and pop_layer before the front grid, so items never blend with the grid
Conflict: ROADMAP.md: kept both progress-log lines
2026-10-12 12:24:20 +00:00
aiongg 4fb32bdb1b Merge #567: Swatches: Load Swatches refuses .ase files over 100,000 colors and merges in linear time
Conflict: ROADMAP.md: kept both progress-log lines (the PR's 2026-10-12 line above next's 2026-10-11 lines)
2026-10-12 12:24:00 +00:00
moppeeerandClaude Opus 5.5 fbb238af88 feat(ui): Effects panel shows the level, Isolate Blending and Knockout Group
The Effects panel had the blend mode, opacity and Drop Shadow only. Like InDesign's it now names the level the settings apply to with its blend mode and opacity (Group: Color Dodge 100%, Object: Normal 100%), and has Isolate Blending and Knockout Group, enabled for a selected group, through object.transparencyGroup.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 11:03:34 +02:00
moppeeerandClaude Opus 5.5 cff0e8b2f8 feat(ui): Step and Repeat dialog with Create as a grid and Preview
Edit > Step and Repeat opened the generic command form (Count 1..1000, Dx, Dy, Rows, Columns, Ids). It now has InDesign's dialog: Repeat (Count, or Rows and Columns when Create as a grid is on), Offset (Vertical, Horizontal, in the document's ruler units or any unit typed) and Preview, which shows the copies on the page while the dialog is open. Cancel, Esc and ui.dialog.cancel take the preview away; OK makes the copies once, as one undo step. A value that isn't a number keeps the dialog open and says so.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 10:58:17 +02:00
noah1400 d298555e43 Styles: Load Styles from another document or IDML file (#405)
Styles could not be taken from one document into another; a client's
styles had to be rebuilt in every new file. The Paragraph Styles and
Character Styles panels now have Load Paragraph Styles, Load Character
Styles and Load All Text Styles: pick a .designcraft or .idml file,
tick the styles to load and choose what happens to one the document
defines differently (redefine, keep, or load under a new name). The
styles, swatches and lists a loaded style names come along.
`style.load` does it in one undo step.
2026-10-12 10:41:37 +02:00