Commit Graph
14 Commits
Author SHA1 Message Date
Lucas Sampaio Dias 03996b1025 Improve reading-colour preferences and add a settings shortcut (#2627)
* M3: improve reading-colour preferences and add settings shortcut

* M3: clarify the disabled reading-colour preview

* M3: adapt rebased preferences to current UI dependencies
2026-10-28 17:41:29 -04:00
aiongg 64e0868b84 feat(ui): menus from craft-menu, native on macOS (#4752)
* feat(ui): menus from craft-menu, native on macOS

One menu definition (crates/ui-egui/src/menus.rs) built from the command
registry drives the native macOS menu bar (craft-menu's muda backend) and
an in-window egui bar on Windows, Linux and the web, which takes the place
of the "Menu" button at the start of the top bar.

- File, Edit, View, Sign, Window and Help, with separators and submenus.
  Edit gains Cut, Paste, Delete and Select All (they act as their keys
  do) and a Pages submenu; View gains a Tools submenu built from the All
  tools groups; Sign holds Fill & Sign and the certificate commands;
  Window lists the open documents.
- Toggles are check items and the page layouts, side panels and themes
  radio items, with their state from the app.
- File > Open Recent lists the recent files (file.open_recent with an
  index).
- A menu click and its shortcut run the same dispatch, including the
  form-field deferral (#166) and macOS Cmd+W closing the window (#869).
  Dialogs and the palette grey the menus through craft-menu's gate.
- Quit goes through craft-quit, so the unsaved-changes prompt runs.
- craft-ui, craft-quit, craft-menu and craft-keymap pinned to
  storytold/craft-libs 70ade1fb.

Menu state and dispatch follow #2610 by @hajdukste; the menu tree and the
view and panel items follow #3870 by @RivanJarjes.

* test(ui): the menu model, native dispatch and the in-window bar

- Unit tests for the menu definition: every registry menu command is
  listed once with its registry shortcut; check and radio items follow
  the app; a dialog greys document commands and drops their clicks; the
  recent files and open documents are listed once each; a native menu
  click (through a fake craft-menu backend) runs its command once.
- The kittests that opened the old "Menu" button use the menu bar, and
  the ones that look up a label the bar's titles share (Edit, File,
  Sign) skip the bar.
- The in-window bar takes its titles' width, so the mode tabs, search
  and buttons keep their place in the top bar.
- Edit menu clicks that stand for keys (Copy, Cut, Delete, Select All)
  reach this frame's input from `logic`, where test hosts see them too.

* test(ui): the language switch test opens File in the menu bar

Translated titles and rows carry their mnemonic ("ファイル(F)", "開く(O)…").

* feat(ui): the menu bars run Quit themselves, the bar shrinks to its titles, and AppKit's window list stays off

craft-libs main edc41f6 (craft-libs#354): MenuBarUi runs Quit and Minimize, shrink_to_fit sizes the in-window bar, Key::parse reads the registry's arrow and minus glyphs, and mac::install_with(.., window_list(false)) keeps the Window menu to PdfCraft's own document list.

* fix(ui): the menu command filter is an if, for clippy

* test(ui): drop a needless borrow in the edit-tab helper

* test(ui): two tests follow the menu bar

The tests were wrong, not the app. The Preferences language test clicked the old Menu button; it opens Edit in the menu bar and its Preferences row. The prepare Actions test counted the Edit labels: the narrower menu bar leaves room for the Edit tab, so the rows' Edit buttons come third and fourth.
2026-10-26 00:57:46 -04:00
skylar taylor-barrick e90f7882f1 Migrate PdfCraft to egui 0.37 (#4591)
* Record successful PdfCraft web application check

* E21: bound startup requests and validate font and license inputs

* E21: separate pending control completion and gesture regression phases

* M-egui037: enforce control admission and per-family font notices

* M-egui037: qualify capture fixes and document migration behavior

* egui-037: identify current and historical qualification results
2026-10-25 14:30:31 -04:00
aiongg d764a8ebca refactor(ui): side panels on craft-ui task panes and the shared rail (#4606)
* refactor(ui): side panels on craft-ui task panes and the shared rail

The Tools pane and the open side panel are docked craft-ui task panes
(craft_ui::panes::PaneHost, Columns policy, no title bars, not movable),
and the rail is craft_ui::panes::Rail with the page navigation cluster
as its foot. On the right, outermost first: the rail, Tools when
Preferences > Tools panel side is Right, the side panel, the page.
Read mode uses the same panes without Tools; All tools full view still
covers them. Floating, tab groups and drag-in are gone with docking.rs.

- Widths are resizable within the old limits and saved under a new
  side_panels preference (version 1) with the Tools side and open state.
  The old docking value is read once as plain JSON and dropped on save.
- ui.dock becomes ui.panel {panel: tools|side, open, width};
  ui.dock.reset resets the side panels ("Reset side panels").
- F4 shows or hides the side panel (reopening the last one) and
  Shift+F4 the Tools panel, as View menu commands.
- craft-ui pinned to e9630ae7 (craft-libs#309).

* fix(ui): side panels clippy lint and the dragged-width test's grab offset

* chore(deps): pin craft-ui at 7c42807, whose pane resize edges work over the page

* chore(deps): pin craft-ui at craft-libs main ea4c823, with panes::Rail
2026-10-25 12:06:35 -04:00
alehel e5800e8a13 Merge remote-tracking branch 'origin/main' into feat/all-tools-expand-view
# Conflicts:
#	crates/ui-egui/src/i18n/ar.tsv
#	crates/ui-egui/src/i18n/bg.tsv
#	crates/ui-egui/src/i18n/ckb.tsv
#	crates/ui-egui/src/i18n/cs.tsv
#	crates/ui-egui/src/i18n/de.tsv
#	crates/ui-egui/src/i18n/el.tsv
#	crates/ui-egui/src/i18n/fr.tsv
#	crates/ui-egui/src/i18n/hu.tsv
#	crates/ui-egui/src/i18n/it.tsv
#	crates/ui-egui/src/i18n/ja.tsv
#	crates/ui-egui/src/i18n/kk.tsv
#	crates/ui-egui/src/i18n/lo.tsv
#	crates/ui-egui/src/i18n/pl.tsv
#	crates/ui-egui/src/i18n/pt-br.tsv
#	crates/ui-egui/src/i18n/ru.tsv
#	crates/ui-egui/src/i18n/sl.tsv
#	crates/ui-egui/src/i18n/te.tsv
#	crates/ui-egui/src/i18n/tr.tsv
#	crates/ui-egui/src/i18n/uk.tsv
#	crates/ui-egui/src/i18n/zh-hans.tsv
#	crates/ui-egui/src/i18n/zh-hant.tsv
2026-10-24 14:54:25 +02:00
aiongg ce684cd1d3 Merge track r3-t06 2026-10-24 06:50:31 +00:00
mtlcl410andClaude Opus 5.5 6506c8cc45 M3: a fractional zoom is remembered as it was, not rounded to a whole percent (#1767)
Review follow-up on #2195: the last view stored ViewDefaults::zoom_name(),
which rounds 62.5% to 63%. A fixed zoom is now written with its fraction
(with_zoom already reads it back); the fit tokens are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0175FWj4xFhMhSH3UpMU8DSC
2026-10-24 10:09:48 +08:00
mtlcl410andClaude Opus 5.5 fb53ddf02f M3: full screen neither is remembered as the last view nor hides it (#1767)
CodeRabbit on #2195: a file opened while full screen was on entered the presentation
first, and the remembered view then replaced its one fitted page, while leaving full
screen went back to the display from before the restore; and a tab closed (or settings
saved) in full screen remembered full screen's temporary fit and display. The remembered
view is now applied before the presentation starts, and the view remembered is the
normal display (DocView::normal_display: the one presenting replaced) at the page
reached.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 10:09:47 +08:00
mtlcl410andClaude Opus 5.5 5e69e620a3 M12: the last view remembers the two-page cover setting (#1767)
Review follow-up on #2195.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 10:09:47 +08:00
mtlcl410andClaude Fable 5.1 946fb31eef M3: restore last view settings when reopening documents (#1767)
A file opened again shows the page, zoom and page display it was last
shown with, as Acrobat's "Restore last view settings when reopening
documents" does: remembered by path (the last 100 files) when its tab
closes or settings are saved with it open, applied over the file's own
initial view, on by default and switched off in Preferences ▸ Documents
and view.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-24 10:09:47 +08:00
alehelandClaude Opus 5.5 45dccb22d0 M3: All tools search finds menu commands; Escape stays with the palette
Local CodeRabbit review follow-ups for the expanded All tools view:

- The search field promises tools and commands, but an entry with a menu
  (Watermark: Add, Update, Remove) matched only by its own name, so
  "remove watermark" found nothing. Entries now also match by their menu
  commands' names, in English or the UI language.
- With the command palette open over the view, Escape closed the view as
  well as the palette. The palette now owns Escape, as dialogs do.

Each new test was seen to fail with its fix reverted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 17:26:53 +02:00
Jayesh-Prajapati9 3b9cfe1d52 Tests: UI tests wait for background work by time, not frame count (#4186)
A frame count is not a time: on a busy runner the worker had not finished
the open, or the page text had not arrived, within 30 frames or 50 hover
rounds. support::step_until (#[must_use]) steps frames until a condition
holds or 30 s pass, sleeping briefly between frames, and says whether it
held; each test asserts on that with its own message.

- control_open_replies_pending_while_the_worker_opens_and_focuses_once_it_has
  and mode_tabs_keep_the_hand_over_page_text_scrolled_under_them wait with it,
  and so does control.rs call() for its reply.
- support::settle waits for every pending render and fails if the pages are
  not rendered within 30 s. It replaces all the render-pending settle loops
  (40 to 3000 frames) and the local settle/wait_for_pages wrappers, except
  text_select's double-click wait, which is held to 8 frames on purpose to
  stay inside egui's multi-click window, and view.rs's loops that already
  wait by a deadline.
- wait_until is built on step_until, keeping its diagnostic message.
- tabbing_back_to_the_same_field_then_saving_keeps_the_committed_value already
  waited 30 s for its file. It failed because its "same-frame" case shared
  its scratch directory with typing_and_saving_in_the_same_frame_saves_the_last_keystrokes,
  which runs in the same test process (since ee1ee704, #1045) and deleted
  the directory mid-save. forms' and pickers' scratch() now give every call
  a directory of its own.

Fixes #4186
2026-10-23 18:40:53 +05:30
alehel 845642691f Merge remote-tracking branch 'origin/main' into feat/all-tools-expand-view 2026-10-22 17:32:21 +02:00
aiongg 9526363152 Build each crate's integration tests as one binary (#4087)
* Build each crate's integration tests as one binary

Every tests/*.rs file is its own executable that links the whole crate
graph. Move each crate's test files into tests/it/ as modules of one
tests/it/main.rs, for apps/pdfcraft, apps/pdfcraft-cli, automation, cos,
crypt, engine, render, sign and ui-egui. ui-egui's ui_group binary and
the support modules move into tests/it/ too. Crates with a single test
file keep it. The test executables go from 150 to 52, and every crate
runs the same number of tests as before.

ui-egui perf keeps its own binary (own process): its frame-time budgets
would charge each measurement for the other tests running beside it.

What the move needs:
- include_str!/include_bytes! and #[path] paths gain one "../".
- ui-egui: one GPU lock in tests/it/main.rs replaces the five per-file
  ones (content, document_links, editing, fill_sign, view), so one
  process creates one wgpu device at a time. The drop-line test in ui.rs
  and the screenshot blocks behind PDFCRAFT_*_SHOT(S) and
  CRAFT_UI_DOCKING_DIR, which render without holding it, take it too.
- pdfcraft winit_wayland_scroll: the vendored winit source it compiles
  names crate::event, so that shim lives in main.rs.
- parity evidence names the new paths.

* Name the one-binary test paths in docs and comments

- READMEs, docs, ATTRIBUTION and source comments name tests/it/<file>.rs.
- The oracle README's example filters with --test it encryption::qpdf_agrees.
- pdfcraft's GPU lock comment points at the UI tests' shared lock in
  crates/ui-egui/tests/it/main.rs.
2026-10-22 11:28:58 -04:00