mirror of
https://github.com/storytold/lightcraft.git
synced 2026-11-01 05:57:09 -06:00
Merge main into feat/keyword-shortcut-keys
Follows main's split of menus.rs into menus/ and of the keyword tests into keywords/tests.rs: Set Keyword Shortcut moves to menus/ui_commands.rs and menus/run.rs, its catalog test to keywords/tests.rs, and the docs name the moved test files.
This commit is contained in:
+1
-1
@@ -115,7 +115,7 @@ The model is fetched from an ordered list of mirrors: base URLs where `<base>/mo
|
||||
2. the file `models/sam3-mirrors.txt` in LightCraft's settings folder (one URL per line, `#`
|
||||
comments) — `~/Library/Application Support/LightCraft/` (macOS), `%APPDATA%\LightCraft\`
|
||||
(Windows), `~/.config/lightcraft/` (Linux);
|
||||
3. the built-in list, `DEFAULT_MIRRORS` in `crates/segment/src/fetch/mod.rs`.
|
||||
3. the built-in list, `DEFAULT_MIRRORS` in `crates/segment/src/fetch.rs`.
|
||||
|
||||
> **Maintainers:** the built-in list is **empty** until LightCraft's own CDN locations exist
|
||||
> (see the `TODO(maintainer)` there): add them in order of preference, host the three files
|
||||
|
||||
@@ -66,6 +66,6 @@ guard.detail(&file_name);
|
||||
## Testing
|
||||
|
||||
Assert the row (`session.activity.list()`: kind, label, total, `cancellable`), that `activity.cancel(id)` stops the
|
||||
job, and that the row is gone once the job ends. `crates/ui-egui/src/tests_activity.rs` has the helpers, and the
|
||||
job, and that the row is gone once the job ends. `crates/ui-egui/src/tests/activity.rs` has the helpers, and the
|
||||
job-specific tests show the pattern (`tests_sync.rs`, `export_task.rs`, `tests_denoise.rs`…). A row only appears
|
||||
on screen once its task is 0.5 s old, so tests that click its ✕ wait for `activity:cancel:<id>` first.
|
||||
|
||||
@@ -23,7 +23,7 @@ this page is the local copy of the decision.
|
||||
|
||||
## In LightCraft
|
||||
|
||||
- The About dialog (`crates/ui-egui/src/panels/dialogs.rs`, Help ▸ About LightCraft) has the tabs
|
||||
- The About dialog (`crates/ui-egui/src/dialogs.rs`, Help ▸ About LightCraft) has the tabs
|
||||
**About · Contributors · Models**; the control channel can switch them with
|
||||
`ui.clickWidget {"id": "button:aboutTab-contributors"}` (`-about`, `-models`), and the list view
|
||||
with `button:creditsGrabBag` / `button:creditsTable`.
|
||||
|
||||
@@ -373,11 +373,11 @@ the pending name. `ui.dialog.confirm` starts the same import into the selected a
|
||||
|
||||
## Panel docking
|
||||
|
||||
Library, Tools, and Presets panels can be regrouped, split, floated within the app window, closed, and reopened. Tools keeps the current Edit/Crop/Masking mode; the photo view and filmstrip stay together. The document/session view is protected. Layouts, active tabs, panel visibility, and floating rectangles are saved with the app's existing UI preferences. These operations do not edit document contents.
|
||||
Library, Tools, and Presets panels can be regrouped, split, floated within the app window, closed, and reopened. Tools keeps the current Edit/Crop/Masking mode; the photo view and filmstrip stay together. The document/session view is protected. Layouts, active tabs, panel visibility, and floating rectangles are saved with the app's existing UI preferences as a craft-ui docking workspace (`docking`: `version`, `layout`, `hidden`, `saved`, `locked`); settings written before workspaces had a `version` load as version 1. These operations do not edit document contents.
|
||||
|
||||
Panel IDs: `library`, `tools`, `presets`. The protected center is `canvas`.
|
||||
|
||||
`ui.dock` accepts `operation` and `panel`. Operations are `open`, `close`, `activate`, `float` (with finite positive `rect: [x, y, width, height]`), or `move` (with `target` and `zone: center|left|right|top|bottom`). Center groups with the target; side zones split beside it. `ui.dock.reset` restores the default arrangement. Invalid moves return an error without changing the layout.
|
||||
`ui.dock` accepts `operation` and `panel`. Operations are `open`, `close`, `activate`, `float` (with finite positive `rect: [x, y, width, height]`), or `move` (with `target` and `zone: center|tab|left|right|top|bottom|above|below`; `Center`, `Left`, `Right`, `Top` and `Bottom` also parse, while `tab`, `above` and `below` are lowercase only). Center and tab group with the target; side zones split beside it; above and below put the panel in a new group above or below the target's group. `ui.dock.reset` restores the default arrangement. Invalid moves return an error without changing the layout. Both commands return `{"docking": workspace}`.
|
||||
|
||||
Invoke these UI commands through `engine.execute`, for example `{"command":"ui.dock","params":{"operation":"float","panel":"tools","rect":[100,100,320,440]}}`.
|
||||
|
||||
|
||||
@@ -616,7 +616,7 @@ admission and completion (neither destination receives a screenshot).
|
||||
|
||||
### 4.7 Panels, IDs and docking
|
||||
|
||||
Anchors: `crates/ui-egui/src/panels/mod.rs:52-77` (`resizable_side`),
|
||||
Anchors: `crates/ui-egui/src/panels.rs:52-77` (`resizable_side`),
|
||||
`panels/bottombar.rs:24,371`, `panels/strip.rs:19`, `panels/topbar.rs:57`,
|
||||
`panels/library_problem.rs:169`, `crates/ui-egui/src/docking.rs:430`, `shortcuts.rs:339`.
|
||||
|
||||
@@ -1389,7 +1389,7 @@ exactly (the pinned fork's winit byte-range event).
|
||||
|
||||
### Tests added (source only)
|
||||
|
||||
`crates/ui-egui/src/tests_lifecycle_037.rs`:
|
||||
`crates/ui-egui/src/tests/lifecycle_037.rs`:
|
||||
|
||||
- bundled monochrome emoji + explicit font-feature gate;
|
||||
- parent-salted panel state (and no legacy exact-`Id` state);
|
||||
|
||||
@@ -21,7 +21,7 @@ import and export formats. Ours come from `crates/codecs/src/sniff.rs`, `crates/
|
||||
| PSD / PSB | ✅ (maximized-compatibility composite) | ✅ (Classic: PSD export, edit-in round trip) | ✅ merged composite | ⬜ (external-editor round trip writes 16-bit TIFF) | `crates/codecs/src/psd.rs` |
|
||||
| HEIC / HEIF | ✅ | ⬜ (Classic) / HDR only | ✅ in every release build (`crates/heif`, heic-rs) | ⬜ | `heif` feature on by packaging scripts |
|
||||
| AVIF | ✅ | ✅ (HDR) | ⬜ recognised, not decoded (no permissive pure-Rust AV1 decoder) | ✅ 8/10-bit, PQ HDR | |
|
||||
| JPEG XL | ✅ | ✅ | ✅ (`jxl-oxide`) incl. DNG 1.7 JXL tiles | ✅ lossy / lossless, 8/16-bit, PQ HDR (`jixel`, native only; ⬜ web) | `crates/engine/src/tests_export.rs` |
|
||||
| JPEG XL | ✅ | ✅ | ✅ (`jxl-oxide`) incl. DNG 1.7 JXL tiles | ✅ lossy / lossless, 8/16-bit, PQ HDR (`jixel`, native only; ⬜ web) | `crates/engine/src/tests/export.rs` |
|
||||
| WebP | not in its document types | ⬜ | ✅ | ✅ | beyond target |
|
||||
| GIF, BMP | ⬜ | ⬜ | ✅ | ⬜ | beyond target |
|
||||
| DNG (from raw) | ✅ | ✅ incl. lossy, embedded original | ✅ | ✅ uncompressed, LJ92, Deflate or lossy (JPEG tiles, optional long edge); ⬜ embedded original | `crates/raw/src/dngwrite.rs` |
|
||||
|
||||
@@ -113,7 +113,7 @@ DMF (AF, then manual touch-up) keeps its point.
|
||||
- `crates/meta/src/focus_read.rs`: the header-only read; its tests check it against the whole-file read on intact,
|
||||
truncated and corrupted files and count what it reads.
|
||||
- `crates/engine/src/focus_scan.rs`: the background job (`photo.readFocusPoints`, `focus.pump`) and
|
||||
`crates/engine/src/tests_focus_scan.rs`, with an opt-in comparison over real files
|
||||
`crates/engine/src/tests/focus_scan.rs`, with an opt-in comparison over real files
|
||||
(`LIGHTCRAFT_FOCUS_FILES=<a list of paths>`); `crates/ui-egui/src/focus_scan.rs` drives it from the frame loop.
|
||||
- `crates/ui-egui/src/panels/detail.rs` (`focus_box`, `focus_pan`, `draw_focus_point`): mapping through the user's
|
||||
rotation and crop, the overlay, and the zoom target; `crates/ui-egui/src/tests_focus_point.rs`.
|
||||
rotation and crop, the overlay, and the zoom target; `crates/ui-egui/src/tests/focus_point.rs`.
|
||||
|
||||
+3
-3
@@ -96,13 +96,13 @@ The release packages ship `lightcraft-cli` alongside the desktop app, so no buil
|
||||
|
||||
| Install | CLI |
|
||||
|---|---|
|
||||
| Windows (MSI) | `C:\Program Files\LightCraft\lightcraft-cli.exe` by default (wherever you installed it otherwise), not on `PATH` |
|
||||
| Windows (MSI) | `%LOCALAPPDATA%\Programs\ArtCraft\LightCraft\lightcraft-cli.exe` by default (`C:\Program Files\ArtCraft\LightCraft\lightcraft-cli.exe` for an all-users install, under `Program Files (x86)` instead for the 32-bit build, or wherever you installed it otherwise), not on `PATH` |
|
||||
| Linux (deb, rpm) | `/usr/bin/lightcraft-cli` |
|
||||
| macOS | the separate `lightcraft-cli-<version>-macos-<arch>.zip` release asset (the `.app` holds only the desktop app) |
|
||||
|
||||
```sh
|
||||
# Windows, default install folder
|
||||
claude mcp add lightcraft -- "C:\Program Files\LightCraft\lightcraft-cli.exe" mcp
|
||||
# Windows (PowerShell), default install folder
|
||||
claude mcp add lightcraft -- "$env:LOCALAPPDATA\Programs\ArtCraft\LightCraft\lightcraft-cli.exe" mcp
|
||||
# Linux, or macOS with the CLI unzipped onto PATH
|
||||
claude mcp add lightcraft -- lightcraft-cli mcp
|
||||
```
|
||||
|
||||
+86
-86
File diff suppressed because one or more lines are too long
+3
-3
@@ -70,13 +70,13 @@ under the UI command that wraps it (a no-op error); the UI command now wins.
|
||||
|
||||
**Grid thumbnail size (KEYC-COMPARE):** Classic's `=` and `-` increase and decrease the Grid thumbnail size (same keys on macOS and Windows; `+` also works for the larger size here, as Shift+`=` or the keypad). They step the bottom-bar slider by 30 pt inside its 90–480 pt range, in Photo Grid, Square Grid and People only; Detail, Compare, Survey and Reference ignore them, and ⌘= / ⌘− stay Zoom In / Out. See [library shortcuts](library-shortcuts.md).
|
||||
|
||||
**Add Keywords key (KEYC-METADATA):** `⌘K` (`Ctrl+K` on Windows and Linux) is Add Keywords (`panel.addKeywords`): it shows the Keywords panel, opens its Keywording section when that is folded shut, and puts the cursor in the Add keyword box; pressed again it leaves the panel open. With no photo selected the panel says "Select photos to give them keywords." and the key does not move the cursor. The shortcut list names the key only; what the key opens is LightCraft's choice. Covered by `crates/ui-egui/src/tests_keywording.rs`.
|
||||
**Add Keywords key (KEYC-METADATA):** `⌘K` (`Ctrl+K` on Windows and Linux) is Add Keywords (`panel.addKeywords`): it shows the Keywords panel, opens its Keywording section when that is folded shut, and puts the cursor in the Add keyword box; pressed again it leaves the panel open. With no photo selected the panel says "Select photos to give them keywords." and the key does not move the cursor. The shortcut list names the key only; what the key opens is LightCraft's choice. Covered by `crates/ui-egui/src/tests/keywording.rs`.
|
||||
|
||||
**Library navigation keys (KEYC-COMPARE):** in Photo Grid and Square Grid, `Home` / `End` make the first / last photo of the view the active, selected one, and `Shift+Left` / `Shift+Right` add the previous / next photo of the view to the selection (the added photo becomes active; the keys never remove a photo from the selection, and do nothing at either end of the view). They wait in the other views, in the full-screen preview, while a text field or a dialog has the keyboard, and when you gave the key to a command; they are listed under Fixed keys in Help → Keyboard Shortcuts. `Cmd+O` (`Ctrl+O` on Windows and Linux) runs File → Open Library… ; View → Visualize HDR has no default key (`Shift+H` cycles the Tool Overlay, issue #224; `Cmd+Shift+H` stays the Histogram). Covered by `crates/ui-egui/src/tests_keymap.rs`; the macOS native menu path for `Cmd+O` is not exercised by the headless tests.
|
||||
**Library navigation keys (KEYC-COMPARE):** in Photo Grid and Square Grid, `Home` / `End` make the first / last photo of the view the active, selected one, and `Shift+Left` / `Shift+Right` add the previous / next photo of the view to the selection (the added photo becomes active; the keys never remove a photo from the selection, and do nothing at either end of the view). They wait in the other views, in the full-screen preview, while a text field or a dialog has the keyboard, and when you gave the key to a command; they are listed under Fixed keys in Help → Keyboard Shortcuts. `Cmd+O` (`Ctrl+O` on Windows and Linux) runs File → Open Library… ; View → Visualize HDR has no default key (`Shift+H` cycles the Tool Overlay, issue #224; `Cmd+Shift+H` stays the Histogram). Covered by `crates/ui-egui/src/tests/keymap.rs`; the macOS native menu path for `Cmd+O` is not exercised by the headless tests.
|
||||
|
||||
**Keyword sets (KEYC-METADATA):** `⌥0` / `⌥⇧0` (`Alt+0` / `Alt+Shift+0` on Windows and Linux) make the next / previous keyword set current (`keyword.nextSet`, `keyword.previousSet`), in the Keyword Set menu's order: Recent Keywords, then the saved sets. After the last set comes Recent Keywords, and before Recent Keywords comes the last set (not documented by Adobe, our choice). `⌥1`–`⌥9` then apply the new set's keywords. Both keys can be reassigned in Help → Keyboard Shortcuts.
|
||||
|
||||
**Keyword shortcut keys (KEYC-METADATA):** `⌘⌥⇧K` (`Ctrl+Alt+Shift+K` on Windows and Linux) is Set Keyword Shortcut… (`dialog.keywordShortcut`): it asks for one or more keywords with commas between them and shows the ones set before; a new name goes inside the default parent, as in the Keywording box. A keyword's Use This as Keyword Shortcut in the Keyword List sets that keyword alone, and the list shows a + after each keyword of the keyword shortcut. `Shift+K` (`keyword.toggleShortcut`) adds the keyword shortcut's keywords to the selected photos, or removes them when every selected photo has them all (the help pages do not say how a mixed selection behaves; this rule is our choice); with no keyword shortcut it does nothing. A photo's context menu offers Add Keyword with the keyword shortcut's keywords. The keyword shortcut is a mark on its keywords in the library's keyword list (`keywordShortcut`, like Put New Keywords Inside This Keyword): a new name is listed, the mark moves with a renamed, moved or merged keyword and goes with a deleted one, and setting it is one undo step. The tests are in `crates/ui-egui/src/tests_keyword_list.rs`, `crates/engine/src/tests_keyword_list.rs` and `crates/catalog/src/keywords.rs`.
|
||||
**Keyword shortcut keys (KEYC-METADATA):** `⌘⌥⇧K` (`Ctrl+Alt+Shift+K` on Windows and Linux) is Set Keyword Shortcut… (`dialog.keywordShortcut`): it asks for one or more keywords with commas between them and shows the ones set before; a new name goes inside the default parent, as in the Keywording box. A keyword's Use This as Keyword Shortcut in the Keyword List sets that keyword alone, and the list shows a + after each keyword of the keyword shortcut. `Shift+K` (`keyword.toggleShortcut`) adds the keyword shortcut's keywords to the selected photos, or removes them when every selected photo has them all (the help pages do not say how a mixed selection behaves; this rule is our choice); with no keyword shortcut it does nothing. A photo's context menu offers Add Keyword with the keyword shortcut's keywords. The keyword shortcut is a mark on its keywords in the library's keyword list (`keywordShortcut`, like Put New Keywords Inside This Keyword): a new name is listed, the mark moves with a renamed, moved or merged keyword and goes with a deleted one, and setting it is one undo step. The tests are in `crates/ui-egui/src/tests/keyword_list.rs`, `crates/engine/src/tests/keyword_list.rs` and `crates/catalog/src/keywords/tests.rs`.
|
||||
|
||||
**Still missing / broken:**
|
||||
- Tab / ⇧Tab (hide the side panels / all panels): Tab moves the keyboard focus here (accessibility), so it is
|
||||
|
||||
@@ -11,12 +11,12 @@ Download the file for your system from the [latest release](https://github.com/s
|
||||
|
||||
1. Open the [latest release](https://github.com/storytold/lightcraft/releases/latest).
|
||||
2. Download `lightcraft-<version>-windows-x64.msi`. It fits most PCs (Intel and AMD, 64-bit).
|
||||
3. Run the file. The installer asks where to install. The default is `C:\Program Files\LightCraft`, and upgrades stay in the folder you chose.
|
||||
3. Run the file. The first page asks who to install LightCraft for. **Only for me** is the default: it needs no administrator permission and installs to `%LOCALAPPDATA%\Programs\ArtCraft\LightCraft`. **Everyone on this computer** asks for an administrator and installs to `C:\Program Files\ArtCraft\LightCraft` (`Program Files (x86)` for the 32-bit build). Upgrades stay in the folder you chose.
|
||||
4. At the end, choose the option to start LightCraft.
|
||||
|
||||
For a Snapdragon or other Arm PC, download `lightcraft-<version>-windows-arm64.msi` instead. For a 32-bit Windows, download `lightcraft-<version>-windows-x86.msi`.
|
||||
|
||||
Upgrading from an installer older than 0.6.0 also keeps LightCraft in the folder it was installed in. If that folder was deleted, the upgrade installs to `C:\Program Files\LightCraft`.
|
||||
Upgrading from an installer older than 0.6.0 also keeps LightCraft in the folder it was installed in. An upgrade uses the folder that the earlier install recorded and does not check that it still exists, so if you deleted that folder, the upgrade creates it again.
|
||||
|
||||
To run it without installing, download `lightcraft-<version>-windows-x64-portable.zip`. Portable builds for `arm64` and `x86` are on the release page too.
|
||||
|
||||
|
||||
+1
-1
@@ -59,7 +59,7 @@ packets between scans are not supported by manual JPEG rereading.
|
||||
Packet completeness is stricter than the shared best-effort JPEG extractor; it is not strict whole-JPEG
|
||||
validation. A complete early XMP packet can be returned without examining the remaining file. Import and
|
||||
`photo.allMetadata` retain their existing extraction paths. Command regressions in
|
||||
`crates/engine/src/tests_xmp.rs` cover metadata/undo and sidecar precedence, an over-nested XMP packet and a
|
||||
`crates/engine/src/tests/xmp.rs` cover metadata/undo and sidecar precedence, an over-nested XMP packet and a
|
||||
truncated APP1 without an XMP signature. Separate reader cases in `sidecar::jpeg_header_tests` use small
|
||||
counted readers and injected limits for span/step boundaries, complete versus truncated APP1, early stopping,
|
||||
short reads and I/O errors.
|
||||
|
||||
Reference in New Issue
Block a user