Merge master into partial-preset-scope
🐳 Android image / Build and push (push) Successful in 8s
Build and test / android-image (push) Successful in 8s
Build and test / Desktop (Linux) (push) Failing after 1h17m12s
Build and test / Layer separation (push) Successful in 56s
Traceability / Requirement traces (push) Successful in 1m33s
Build and test / Android (aarch64) (push) Successful in 1h0m38s

# Conflicts:
#	docs/traceability.md
#	ui/dr-ui/ui/app.slint
This commit is contained in:
2026-08-29 22:02:03 +02:00
31 changed files with 2855 additions and 92 deletions
+49
View File
@@ -11,6 +11,7 @@ import { Button, PanelHeading, Label, Value, Caption, Panel, EmptyState, Progres
import { CollectionsPanel, CollectionRow, OfflinePrompt } from "collections.slint";
import { HistogramPanel, HistogramView } from "histogram.slint";
import { PresetSheet, ScopeChips, ScopeKind } from "presets.slint";
import { FocusMarks, FocusPanel } from "peaking.slint";
import { SettingsPage } from "settings.slint";
import { ImportPage } from "import.slint";
import { StatusBar, InfoPanel } from "develop.slint";
@@ -71,6 +72,22 @@ export component AppWindow inherits Window {
/// of a draft frame is a histogram of an image nobody is reading.
in property <HistogramView> histogram;
/// TRACES: FR-CULL-3
/// Focus peaking: the marks, whether they describe *this* frame, and the
/// three things the photographer chose. All of them are Rust's, because
/// the marks come from a compute pass — see `peaking.slint` for why
/// `focus-overlay-ready` is a separate question from `peaking-on`.
in property <image> focus-overlay;
in property <bool> focus-overlay-ready: false;
in property <bool> peaking-on: false;
in property <bool> peaking-available: true;
in property <int> peaking-sensitivity: 1;
in property <int> peaking-colour: 0;
callback peaking-toggled(bool);
callback peaking-sensitivity-picked(int);
callback peaking-colour-picked(int);
// --- zoom, pan and crop (FR-DEV-4) ---
//
// Zoom is a *viewing* state, not an edit: it changes the resolution the
@@ -1669,6 +1686,18 @@ in property <bool> panel-visible: true;
image-rendering: ImageRendering.pixelated;
}
// TRACES: FR-CULL-3
// The focus marks, over the same fitted rect. See
// `peaking.slint` for why they are a layer over the canvas
// rather than a tint in it.
if root.focus-overlay-ready && root.total > 0: FocusMarks {
x: parent.shown-x;
y: parent.shown-y;
width: parent.shown-w;
height: parent.shown-h;
marks: root.focus-overlay;
}
// Where the photograph actually sits inside this box.
//
// `image-fit: contain` letterboxes, and Slint does not report
@@ -2202,6 +2231,26 @@ in property <bool> panel-visible: true;
background: Theme.rule;
}
// TRACES: FR-CULL-3
// Under the histogram, because the two are the same
// kind of thing: instruments that report on the
// photograph rather than change it. Kept in every
// mode for the same reason the histogram is.
FocusPanel {
available: root.peaking-available;
showing: root.peaking-on;
sensitivity: root.peaking-sensitivity;
colour: root.peaking-colour;
toggled(v) => { root.peaking-toggled(v); }
sensitivity-picked(i) => { root.peaking-sensitivity-picked(i); }
colour-picked(i) => { root.peaking-colour-picked(i); }
}
Rectangle {
height: 1px;
background: Theme.rule;
}
// Framing above the colour work, matching how the edit is
// made rather than how it is applied: the frame is decided
// by eye first and the pipeline runs it last (see