Drive develop, the grid, the sidebar and People from the keyboard
An audit of every action by view against the keys the handlers bind left develop without zoom, pan, fit or a way back to the grid, the grid without select-none, thumbnail size or keywording, People with no key at all, and the export and copy sheets without Enter. It also found the reverse gap FR-UI-5 forbids: pick and reject had no route but P, X and U, and the 2026-09-19 amendment's judging in develop had not been built. Develop: Ctrl+= and Ctrl+Plus zoom in and Ctrl+- out about the middle of the view, Ctrl+0 fits and Ctrl+1 goes to 1:1, Shift and an arrow pan a magnified view, G goes back to the grid, Ctrl+Y redoes, and Enter keeps a crop that hid a mask. 0-5, P, X and U rate and flag the open photograph without moving on, with stars and Pick/Reject in the top bar as the pointer and touch route. = and - nudge the control last moved by a hundredth of its travel; the framing sliders, perspective included, now count as "last moved", so R puts them back as well. J turns the selected mask part's join chip. Grid: Ctrl+D and Ctrl+Shift+A clear the selection, = and - resize the thumbnails, Ctrl+K opens keywording, and Flag in the selection bar gives pick and reject a pointer and touch route. Sidebar: Enter commits a collection's name, and Enter or Escape hands the keyboard back to the grid, where it used to go nowhere until something was clicked. People: Up and Down walk the rail, F2 puts the name field under the keys, and Escape or Back now leave the screen the way its back button does instead of doing nothing. Sheets: Enter does what the export or copy sheet's button does. The choices follow Lightroom where it has one. No new key steals typing: the grid's and People's keys live on focus holders that are not ancestors of any text field, and the sheets' Enter comes after a focused field has had it. Every binding is tagged beside its handler, and the gate added in the previous commit holds the two to each other.
This commit is contained in:
@@ -632,6 +632,10 @@ export global Library {
|
||||
// own rather than a zero score.
|
||||
/// A star was clicked on a cell: row, then the rating 0..5.
|
||||
callback library-cell-rated(int, int);
|
||||
/// TRACES: FR-UI-5 | FR-CULL-4
|
||||
/// Pick (1), reject (2) or clear the flag (0) of one photograph by row —
|
||||
/// the one open in develop.
|
||||
callback library-cell-flagged(int, int);
|
||||
/// The trash target was clicked on one cell, by row.
|
||||
callback library-cell-trashed(int);
|
||||
/// The burst mark was clicked on one cell, by row (FR-CULL-5).
|
||||
@@ -1556,6 +1560,22 @@ export component LibraryGrid inherits Rectangle {
|
||||
/// Whether the selection bar's label picker is open. Local, like
|
||||
/// `keywording`.
|
||||
property <bool> labelling: false;
|
||||
/// TRACES: FR-UI-5 | FR-CULL-4
|
||||
/// Whether the selection bar's pick / reject choices are open. Local,
|
||||
/// like `labelling`.
|
||||
property <bool> flagging: false;
|
||||
|
||||
/// TRACES: FR-UI-5
|
||||
/// Give the keyboard back to the grid.
|
||||
///
|
||||
/// For a field outside the grid that has just finished — a collection's
|
||||
/// name in the sidebar. The field took focus to be typed into and then
|
||||
/// went away with it, and from there no key reached anything: the arrows,
|
||||
/// the judgement keys and Escape were all dead until something was
|
||||
/// clicked.
|
||||
public function take-keys() {
|
||||
judge-keys.focus();
|
||||
}
|
||||
|
||||
/// TRACES: FR-UI-5
|
||||
/// The library ordinal of the cell under the pointer, -1 when none.
|
||||
@@ -3070,6 +3090,10 @@ export component LibraryGrid inherits Rectangle {
|
||||
root.labelling = false;
|
||||
return accept;
|
||||
}
|
||||
if (root.flagging) {
|
||||
root.flagging = false;
|
||||
return accept;
|
||||
}
|
||||
if (root.filing) {
|
||||
root.filing = false;
|
||||
return accept;
|
||||
@@ -3125,6 +3149,48 @@ export component LibraryGrid inherits Rectangle {
|
||||
root.select-all();
|
||||
return accept;
|
||||
}
|
||||
// TRACES: FR-CAT-5 | FR-UI-5
|
||||
// Lightroom's two chords for "select none". Clears, and
|
||||
// stays in select mode, as the strip's Clear does.
|
||||
if (Keys.chord(event) == "Ctrl+D"
|
||||
|| Keys.chord(event) == "Ctrl+Shift+A") {
|
||||
root.clear-selection();
|
||||
return accept;
|
||||
}
|
||||
// GESTURE: Keyword the selection
|
||||
// where: Library grid
|
||||
// touch: Select them, then Keywords in the selection
|
||||
// bar
|
||||
// pointer: Select them, then Keywords in the selection
|
||||
// bar
|
||||
// keys: `Ctrl+K`
|
||||
// why: Lightroom's keywording chord. The sheet opens
|
||||
// with its field ready for typing, so the
|
||||
// keys that judge in the grid are out of the
|
||||
// way until it closes.
|
||||
//
|
||||
// TRACES: FR-CAT-5 | FR-CAT-6 | FR-UI-5
|
||||
// What the Keywords button does, and only when it is on
|
||||
// the bar: with nothing selected there is nothing to
|
||||
// keyword.
|
||||
if (Keys.chord(event) == "Ctrl+K") {
|
||||
if (root.selected-count > 0) {
|
||||
root.keywords-opened();
|
||||
root.keywording = true;
|
||||
}
|
||||
return accept;
|
||||
}
|
||||
// TRACES: FR-UI-4 | FR-UI-5
|
||||
// Lightroom's grid keys for the thumbnail size, the same
|
||||
// step as a notch of Ctrl and the wheel.
|
||||
if (Keys.chord(event) == "=" || Keys.chord(event) == "Plus") {
|
||||
root.zoom-cells(1);
|
||||
return accept;
|
||||
}
|
||||
if (Keys.chord(event) == "-") {
|
||||
root.zoom-cells(-1);
|
||||
return accept;
|
||||
}
|
||||
// GESTURE: Show only photographs with some number of stars
|
||||
// where: Library grid
|
||||
// touch: Tap a star chip in the filter bar
|
||||
@@ -3201,6 +3267,10 @@ export component LibraryGrid inherits Rectangle {
|
||||
if (Keys.chord(event) == "9") { root.labelled(4, root.hover-ordinal); return accept; }
|
||||
// GESTURE: Pick or reject a photograph
|
||||
// where: Library grid
|
||||
// touch: Select them, then Flag in the selection bar
|
||||
// and Pick, Reject or No flag
|
||||
// pointer: Select them, then Flag in the selection bar
|
||||
// and Pick, Reject or No flag
|
||||
// keys: `P` picks, `X` rejects and `U` takes the flag
|
||||
// off, with the pointer over it or on the
|
||||
// selection
|
||||
@@ -3404,6 +3474,7 @@ export component LibraryGrid inherits Rectangle {
|
||||
// where: Library grid
|
||||
// touch: Pinch the grid with two fingers
|
||||
// pointer: Ctrl and the scroll wheel
|
||||
// keys: `=` or `Plus` for larger, `-` for smaller
|
||||
// why: There is no wheel on a tablet, so without the
|
||||
// pinch the cell size could only be changed by a
|
||||
// control a finger cannot reach.
|
||||
@@ -4832,6 +4903,7 @@ export component LibraryGrid inherits Rectangle {
|
||||
// where: Library grid
|
||||
// touch: Press Clear in the selection strip
|
||||
// pointer: Press Clear in the selection strip
|
||||
// keys: `Ctrl+D` or `Ctrl+Shift+A`
|
||||
// why: Distinct from Done, which leaves the mode
|
||||
// entirely. Clearing keeps it, so the next
|
||||
// selection can start straight away.
|
||||
@@ -4933,6 +5005,45 @@ export component LibraryGrid inherits Rectangle {
|
||||
}
|
||||
}
|
||||
|
||||
// TRACES: FR-UI-5 | FR-CULL-4
|
||||
// Pick or reject the selection. Until this the flag had no route
|
||||
// but `P`, `X` and `U`, which a tablet does not have. Opened like
|
||||
// Label, so the three choices take room on the bar only while
|
||||
// they are being made.
|
||||
if !root.ranging && root.selected-count > 0: Button {
|
||||
text: "Flag";
|
||||
active: root.flagging;
|
||||
y: (parent.height - self.height) / 2;
|
||||
clicked => { root.flagging = !root.flagging; }
|
||||
}
|
||||
|
||||
if !root.ranging && root.selected-count > 0 && root.flagging: Button {
|
||||
text: "Pick";
|
||||
y: (parent.height - self.height) / 2;
|
||||
clicked => {
|
||||
root.judged(-1, 1, -1);
|
||||
root.flagging = false;
|
||||
}
|
||||
}
|
||||
|
||||
if !root.ranging && root.selected-count > 0 && root.flagging: Button {
|
||||
text: "Reject";
|
||||
y: (parent.height - self.height) / 2;
|
||||
clicked => {
|
||||
root.judged(-1, 2, -1);
|
||||
root.flagging = false;
|
||||
}
|
||||
}
|
||||
|
||||
if !root.ranging && root.selected-count > 0 && root.flagging: Button {
|
||||
text: "No flag";
|
||||
y: (parent.height - self.height) / 2;
|
||||
clicked => {
|
||||
root.judged(-1, 0, -1);
|
||||
root.flagging = false;
|
||||
}
|
||||
}
|
||||
|
||||
// TRACES: FR-DEV-6
|
||||
// Paste the copied edit onto the selection. One of the things a
|
||||
// selection can have done to it, like filing it in a collection,
|
||||
|
||||
Reference in New Issue
Block a user