Give the library somewhere to type a keyword
A sheet over the grid, opened from the header beside "Add to collection" — deliberately the same card, scrim and dismissal as the filing sheet, because they are the same gesture applied to two kinds of label: pick the photographs, then say what they are. A user who has filed a selection already knows how this works. A word the whole selection carries, a word only some of it carries, and a word none of it carries are three visibly different marks. Half-applied shown as applied would be a lie about photographs the user cannot see from here, so a partial keyword draws a dash and says "3 of 12" beside it. Tapping a dash completes the keyword rather than removing it, which is what it means nine times in ten, and the tenth is one more tap away. The vocabulary is answered against the selection in Rust and pulled when the sheet opens rather than pushed on every selection change — the selection moves on each arrow key and the sheet is shut for almost all of them. Assign and unassign travel by name, so a word typed into the field and a word tapped in the list are one path rather than two, and the sheet never has to invent an identity for a keyword that does not exist yet. One gap, commented at the call site: unlike a star or a flag, a keyword is not queued to the image's sidecar, because the sidecar format has no field for one. So it reaches the user's other devices through the catalog merge, and a deleted catalog loses keywords where it would keep ratings. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+24
-1
@@ -2,7 +2,7 @@ import { Theme } from "theme.slint";
|
||||
import { AdjustPanel, GeometryPanel, GroupStrip, ParamRow, TransferPanel } from "adjust.slint";
|
||||
import { MaskPanel, MaskRow, SubjectRow } from "masks.slint";
|
||||
import { LaunchScreen } from "launch.slint";
|
||||
import { LibraryGrid, LibraryCell, TimelineBar, PhotoRoll } from "library.slint";
|
||||
import { LibraryGrid, LibraryCell, TimelineBar, PhotoRoll, KeywordRow } from "library.slint";
|
||||
import { Button, PanelHeading, Label, Value, Caption, Panel, EmptyState, ProgressBar, ActivityRow } from "widgets.slint";
|
||||
import { CollectionsPanel, CollectionRow, OfflinePrompt } from "collections.slint";
|
||||
import { HistogramPanel, HistogramView } from "histogram.slint";
|
||||
@@ -572,6 +572,25 @@ export component AppWindow inherits Window {
|
||||
/// the target's id, and whether to take the images out of the collection
|
||||
/// currently being shown.
|
||||
callback library-file-in-collection(int, bool);
|
||||
/// TRACES: FR-CAT-5 | FR-CAT-6
|
||||
/// Keywording the grid's selection. The catalog has been searchable by
|
||||
/// keyword since it existed and there was nowhere to type one; this is it.
|
||||
///
|
||||
/// The vocabulary arrives already answered against the selection — each row
|
||||
/// says how many of the selected photographs carry that word — because only
|
||||
/// Rust knows what is selected, and a `.slint` file counting it would need
|
||||
/// the selection as a second model that could disagree with the first.
|
||||
in property <[KeywordRow]> library-keywords;
|
||||
/// The sheet is opening: recompute the rows against the selection as it
|
||||
/// stands now. Pulled rather than pushed, because the selection changes on
|
||||
/// every arrow key and the sheet is shut for almost all of them.
|
||||
callback library-keywords-opened();
|
||||
/// Put a keyword on the selection, creating it if it is new. By name, so a
|
||||
/// word typed into the field and a word tapped in the list are one path.
|
||||
callback library-assign-keyword(string);
|
||||
/// Take a keyword off the selection. Never deletes the keyword itself —
|
||||
/// it stays in the vocabulary and on every other photograph that carries it.
|
||||
callback library-unassign-keyword(string);
|
||||
/// TRACES: FR-UI-2
|
||||
/// Whether a tap in the grid selects rather than opens, and the button
|
||||
/// that turns it on. The long press does the same thing without it.
|
||||
@@ -1229,6 +1248,10 @@ in property <bool> panel-visible: true;
|
||||
file-in-collection(id, moves) => {
|
||||
root.library-file-in-collection(id, moves);
|
||||
}
|
||||
keywords: root.library-keywords;
|
||||
keywords-opened() => { root.library-keywords-opened(); }
|
||||
assign-keyword(word) => { root.library-assign-keyword(word); }
|
||||
unassign-keyword(word) => { root.library-unassign-keyword(word); }
|
||||
cursor: root.library-cursor;
|
||||
move-cursor(delta, extend) => {
|
||||
root.library-move-cursor(delta, extend);
|
||||
|
||||
Reference in New Issue
Block a user