Commit Graph
2894 Commits
Author SHA1 Message Date
moppeeer b6fec896f9 Merge remote-tracking branch 'origin/main' into effect-blend-modes
# Conflicts:
#	crates/doc/src/item.rs
#	crates/idml/src/export.rs
#	crates/idml/src/import.rs
#	crates/ui-egui/src/effects_dialog.rs
2026-10-29 11:42:14 +01:00
aiongg 855d606325 Show file and message dialogs without blocking the frame (fixes macOS crash) (#1961)
* Show file and message dialogs without blocking the frame

A blocking rfd dialog inside the egui frame runs AppKit's modal loop; a
file dragged from Finder and held over the window then re-enters winit's
handler and aborts the app. Dialogs now go through craft-dialogs: a
command without a path asks with a continuation and returns, the host
shows the dialog at the end of the frame, and the continuation runs with
the answer on a later frame, in the document it was asked for. Commands
given a path stay synchronous. The replace-file question is a message
box from the same queue. Quit and Close wait for a Save As dialog's
answer. clippy.toml disallows rfd::FileDialog and rfd::MessageDialog.

* Raise the open file panel when File > Open is chosen again

* Repin craft-dialogs to the craft-libs PR head

* Queue dialogs asked by different code or documents; hold answers behind newer dialogs

Two asks for the same file dialog were treated as one, so Place for one
document and then Choose Image, or Place again for another document, ran
the first ask's action. An ask is now skipped (and the open panel
raised) only when the same code asked for the same dialog for the same
document. An answer that would replace an egui dialog opened since the
asking (an unsaved-changes question, Preferences) waits until it closes;
Quit counts it as pending.

* Repin craft-dialogs to the craft-libs PR head

* Allow the file dialogs' existence checks in the file guard

* Repin craft-dialogs to storytold/craft-libs main
2026-10-28 17:13:45 -04:00
Dylan M. Taylor d04c8b2e58 Refactor ui-egui for strict Clippy checks 2026-10-28 11:39:26 +00:00
Dylan M. Taylor 5b21472180 Refactor engine for strict Clippy checks 2026-10-28 11:39:26 +00:00
Dylan M. Taylor 072dd02f73 Refactor render for strict Clippy checks 2026-10-28 11:39:26 +00:00
Dylan M. Taylor be9b8f360e Refactor idml for strict Clippy checks 2026-10-28 11:39:26 +00:00
Dylan M. Taylor 0104122f06 Refactor doc for strict Clippy checks 2026-10-28 11:39:26 +00:00
Dylan M. Taylor e6ff9d5aac Refactor fonts for strict Clippy checks 2026-10-28 11:39:26 +00:00
Dylan M. Taylor 71a579e8da Refactor compose for strict Clippy checks 2026-10-28 11:39:26 +00:00
Dylan M. Taylor 07366af1b6 Refactor pdf for strict Clippy checks 2026-10-28 11:39:26 +00:00
Dylan M. Taylor bcb9546f5d Refactor tools for strict Clippy checks 2026-10-28 11:39:26 +00:00
Dylan M. Taylor f1a5744e8c Refactor textimport for strict Clippy checks 2026-10-28 11:39:25 +00:00
Dylan M. Taylor c2869280a2 Refactor epub for strict Clippy checks 2026-10-28 11:39:25 +00:00
aiongg 1abeda4459 Merge pull request #1802 from dotCooCoo/fix/column-rules-span-the-text
Text frames: column rules run from the top line's ascent to the bottom line's descent
2026-10-27 13:45:19 -04:00
aiongg 5d8739b3d8 Merge pull request #1795 from dotCooCoo/feat/story-editor-depth-ruler
Story Editor: a depth ruler beside the text, and View › Story Editor › Show/Hide Depth Ruler, as in InDesign
2026-10-27 13:44:46 -04:00
aiongg d36e5fb63f Merge pull request #1927 from Silvertree2010/perf/export-speed
PDF export: ask the composition cache once per story and page
2026-10-27 13:41:05 -04:00
NetterSilverandClaude Opus 5.5 1db1635a88 Ask the composition cache once per story and page in PDF export
The PDF exporter called Cache::get twice for every text frame it drew.
Each call rebuilds the cache signature of the whole story, which looks up
every frame of the story with Document::find (a linear walk over all
spreads), and the anchored-frame placements walk them again. For a story
threaded through many frames this is O(frames^2 x items) per export.

The document doesn't change during an export, so the exporter now keeps
the composition it got for each (story, page) and reuses it. The cache
still decides what to compose; the output is byte-identical.

Add examples/pdf_export.rs to designcraft-cli: File > Export PDF through
a headless session on the `designcraft-cli perf` stress document (200
pages, 1M characters in 40 threaded stories, 500 placed images). The
stress document generator moves unchanged from src/perf.rs to a small
library module (src/stress.rs) that the binary and the example share.

Ryzen 16 threads, Linux, 12 runs each, interleaved:
  main     median 3485 ms, min 3427 ms
  patched  median 2016 ms, min 1656 ms  (-42 % median, -52 % min)
The exported PDF is byte-identical (12,075,744 bytes).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 16:47:25 +01:00
aiongg d77fdf2d4c fix(ui): dropdown menus grow back after a search with no matches (#1917)
* fix(ui): font menus grow back after a search with no matches

Every combo box is craft_ui::ComboBox (craft-libs pinned at 62bb0e1d), whose
menu follows its contents' height while open (egui#5225); clippy.toml bans
egui::ComboBox.

The Font menu splits into a header (search field, filters) and a list
(font_menu_header, font_menu_list). Font fields show it in a
craft_ui::combo::Menu and the style dialogs' Font Family combo boxes in
ComboBox::show_ui_with_header, so only the rows scroll and the search field
stays in place. The blank and Parent's Font rows sit in the header, above
the search.

* chore(deps): craft-libs 60d60d48 (dropdown fixes)

* chore(deps): craft-libs 4d7b82f7 (dropdown fixes)

* chore(deps): craft-libs 92d392cf (#387 merged)

* chore(xtask): pdf-deps expects craft-libs 92d392cf
2026-10-27 10:27:32 -04:00
dotCooCoo 9ef2e64f9f Merge main into the column rule extent fix 2026-10-27 07:16:50 -07:00
aiongg 50650f74d7 Iconic panel flyouts stay open while the canvas is in use (#1902)
Auto-Collapse Iconic Panels is off by default, so a flyout closes only from its icon or
another icon. The setting is saved under a new key, so preferences saved with the old
default start with it off, and Preferences > Interface > Panels shows it.
2026-10-27 01:54:50 -04:00
dotCooCoo fcea4173be Hide stale Story Editor depth marks while text changes
Draw the depth ruler and overset line after composition reflects the edited
text. Add a paint-output regression for inserting a paragraph break.
2026-10-26 21:42:22 -07:00
dotCooCoo 17247c929e Merge main into feat/story-editor-depth-ruler
Move the depth ruler state, translations, and menu command into the split UI modules.
2026-10-26 21:02:19 -07:00
aiongg 42993ae680 test(engine): read only test cfgs and any pub(…) mod as test modules in the file guard
Split files share test helpers through pub(super)/pub(crate) test modules. The guard read only `mod` and `pub mod` as a test module, so it scanned their fixtures as production code. `attr.contains("test")` also matched `#[cfg(not(test))]`, so such a module was skipped; it is scanned now.
2026-10-26 23:06:07 +00:00
aiongg bbb495111e refactor(epub): split lib.rs into modules 2026-10-26 23:05:57 +00:00
aiongg 27e21ba19a refactor(render): split lib.rs into modules 2026-10-26 23:05:57 +00:00
aiongg 08f633ae48 refactor(fonts): split fontdb.rs into fontdb/ 2026-10-26 23:05:57 +00:00
aiongg f553e17406 refactor(doc): move the CharAttrs and ParaAttrs sets to attrs/char_attrs.rs and attrs/para_attrs.rs 2026-10-26 21:00:23 +00:00
aiongg f15fe7aef0 refactor(ui-egui): split i18n.rs into i18n/table.rs 2026-10-26 21:00:23 +00:00
aiongg 2bca3285bf refactor(ui-egui): split app.rs into app/ 2026-10-26 21:00:23 +00:00
aiongg 02f595fe92 refactor(ui-egui): split lib.rs into app, state, services, clock and key_names 2026-10-26 21:00:23 +00:00
aiongg 2dd87273a2 refactor(doc): split attrs.rs into attrs/ 2026-10-26 21:00:23 +00:00
aiongg bc345384f6 refactor(doc): split table.rs into table/ 2026-10-26 21:00:23 +00:00
aiongg a24e9dffd1 refactor(doc): split item.rs into item/ 2026-10-26 21:00:23 +00:00
aiongg f70c3efa3c refactor(ui-egui): split chrome.rs into chrome/ 2026-10-26 21:00:23 +00:00
aiongg 8f601148b6 refactor(engine): split cmd/layout.rs into cmd/layout/ 2026-10-26 21:00:23 +00:00
aiongg f33de8f4aa refactor(pdf): split export.rs into export/ 2026-10-26 21:00:23 +00:00
aiongg bec8800b62 refactor(idml): split export.rs into export/ 2026-10-26 21:00:23 +00:00
aiongg 2c0882c6e0 refactor(idml): split import.rs into import/ 2026-10-26 21:00:23 +00:00
aiongg a1ec465207 refactor(engine): split cmd/style.rs into cmd/style/ 2026-10-26 21:00:23 +00:00
aiongg 7afc1af676 refactor(engine): split cmd/text.rs into cmd/text/ 2026-10-26 21:00:23 +00:00
aiongg 2f7e956e8e refactor(ui-egui): split panels/properties.rs into panels/properties/ 2026-10-26 21:00:23 +00:00
aiongg d93acf7120 refactor(engine): split cmd/export.rs into cmd/export/ 2026-10-26 21:00:23 +00:00
aiongg b2f1ad1867 refactor(engine): split cmd/file.rs into cmd/file/ 2026-10-26 21:00:23 +00:00
aiongg 18e03a3035 refactor(engine): split cmd/table.rs into cmd/table/ 2026-10-26 21:00:23 +00:00
aiongg 96295e3f58 refactor(ui-egui): split menus.rs into menus/ 2026-10-26 21:00:23 +00:00
aiongg 9d5dbb4b8c refactor(ui-egui): split canvas.rs into canvas/ 2026-10-26 19:02:05 +00:00
aiongg 5f53d41387 docs(engine): name the file guard test's new path 2026-10-26 19:02:05 +00:00
aiongg bec8b28cbc refactor(ui-egui): move panel_docking_tests.rs to panel_docking/tests.rs 2026-10-26 19:02:05 +00:00
aiongg 09688b34d6 refactor(fonts): move the fontdb tests_*.rs files to fontdb/tests/ 2026-10-26 19:02:05 +00:00
dotCooCoo af46697a88 Merge branch 'main' into feat/story-editor-depth-ruler
# Conflicts:
#	ROADMAP.md
2026-10-26 11:57:12 -07:00