Merge: group the frames of one moment, and let a burst fold away
FR-CULL-5. Frames join a burst when they are adjacent in time and look like the frame before them -- both, because time alone groups a whole ceremony and similarity alone groups a studio setup across two days. Adjacent pairs only, chained; there is no all-pairs step and there must never be one. No selection of any kind. The representative is the earliest frame, a fact about the clock rather than a judgement about the photograph, and a newly found burst arrives open, so the pass never takes a row off the screen. Verified: fmt, clippy --workspace --all-targets -D warnings, 346 dr-catalog tests, 511 dr-ui tests. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -458,6 +458,16 @@ export struct LibraryCell {
|
||||
// 0 unflagged, 1 pick, 2 reject. Independent of the stars: rejecting a
|
||||
// four-star frame is a normal thing to do mid-cull.
|
||||
flag: int,
|
||||
// Frames in the burst this cell belongs to (FR-CULL-5), itself included; 0 where it
|
||||
// belongs to none, which is most of a library. A burst that is collapsed
|
||||
// draws only its representative, so on that cell this is the count of what
|
||||
// is hidden behind it — the reason it is shown at all.
|
||||
burst-count: int,
|
||||
// Whether the group is currently open. Drawn differently rather than
|
||||
// hidden: a burst the user has expanded is the one thing on screen that
|
||||
// needs a way back, and a control that disappears once used is a control
|
||||
// nobody finds twice.
|
||||
burst-expanded: bool,
|
||||
}
|
||||
|
||||
// The photo roll: the grid's loaded window along the foot of the develop view.
|
||||
@@ -1155,6 +1165,11 @@ export component LibraryGrid inherits Rectangle {
|
||||
callback cell-clicked(int);
|
||||
/// A star was clicked on a cell: row, and the rating 0..5.
|
||||
callback cell-rated(int, int);
|
||||
/// The burst mark on a cell was clicked (FR-CULL-5): open the group, or fold it back
|
||||
/// up. Which of the two is decided in Rust, from what the catalog says the
|
||||
/// group is currently doing, so the mark cannot get out of step with the
|
||||
/// query that actually hides the frames.
|
||||
callback burst-toggled(int);
|
||||
/// Whether the grid is currently listing the trash rather than the
|
||||
/// library. Suppresses the per-cell trash target, which would be inert
|
||||
/// there — `plan_trash` skips an already-trashed image — and offering a
|
||||
@@ -2925,6 +2940,75 @@ export component LibraryGrid inherits Rectangle {
|
||||
rate(n) => { root.cell-rated(i, n); }
|
||||
trash() => { root.cell-trashed(i); }
|
||||
}
|
||||
|
||||
// The burst mark (FR-CULL-5): how many frames this
|
||||
// moment holds,
|
||||
// and the way in and out of them.
|
||||
//
|
||||
// A child of `cell-touch` for exactly the reason the
|
||||
// stars above are: a click here must not also reach
|
||||
// `cell-clicked` and throw the user into develop, and
|
||||
// children are hit-tested before the element they sit
|
||||
// in. Unlike the stars it is never hidden — a collapsed
|
||||
// burst is standing in for frames that are not on
|
||||
// screen, and there has to be something visible saying
|
||||
// so whether or not a pointer is anywhere near.
|
||||
//
|
||||
// Bottom left, clear of the centred star strip and of
|
||||
// both top corners, which the flag and the collection
|
||||
// badge already have.
|
||||
if cell.burst-count > 1: Rectangle {
|
||||
x: 6px;
|
||||
y: parent.height - self.height - 26px;
|
||||
width: 30px;
|
||||
height: 18px;
|
||||
|
||||
// The pile behind the top card, drawn only while the
|
||||
// group is folded up. It is the whole of the "there
|
||||
// is more than one of these" cue; once the burst is
|
||||
// open the frames themselves say it.
|
||||
Rectangle {
|
||||
x: 3px;
|
||||
y: -3px;
|
||||
width: parent.width - 3px;
|
||||
height: parent.height;
|
||||
visible: !cell.burst-expanded;
|
||||
background: Theme.surface;
|
||||
border-radius: Theme.radius-sm;
|
||||
border-width: 1px;
|
||||
border-color: Theme.rule;
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: cell.burst-expanded ? Theme.selected
|
||||
: Theme.surface;
|
||||
border-radius: Theme.radius-sm;
|
||||
border-width: 1px;
|
||||
border-color: cell.burst-expanded ? Theme.selected-ring
|
||||
: Theme.rule;
|
||||
|
||||
Text {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
horizontal-alignment: center;
|
||||
vertical-alignment: center;
|
||||
// No "of": the number is the size of the
|
||||
// group, and a cell this small cannot
|
||||
// afford a word to say so.
|
||||
text: cell.burst-count;
|
||||
color: Theme.ink;
|
||||
font-size: 10px;
|
||||
font-weight: 700;
|
||||
}
|
||||
}
|
||||
|
||||
TouchArea {
|
||||
mouse-cursor: pointer;
|
||||
clicked => { root.burst-toggled(i); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user