Let a paste carry some kinds of edit and not others
FR-DEV-6 asks for presets "covering a subset of the edit graph". What landed with the named presets covered two subsets: everything, and everything but the crop. "Match the colour but not the sharpening" had no way to be said. `Scope` is now a set of `Attribute` — the same six kinds every operation already declares and the develop panel already builds its tabs from. The photographer ticking "tone and colour" is naming the groups they navigate by, and neither this module nor the interface has to name an operation to do it (FR-DEV-3c). The pleasing part is what left. Framing used to be excluded by an explicit test against one operation's id; it is now excluded because Geometry is not in the default set. The special case dissolved into the general rule, and the argument for it — a crop is a decision about *this* photograph, and carrying it across forty destroys forty compositions — is now a statement about a kind of edit rather than about a node. All thirty-three existing preset tests pass unchanged, which is the evidence that the generalisation kept its promises. One decision that is a field rather than a rule, because the two cases genuinely differ. An operation this build cannot classify — from a newer version, arriving over sync — travels under "everything" and "everything but the crop", because those are claims about the whole edit and an unrecognised operation is part of it (FR-NC-8). It does not travel under a hand-picked set, because that is a claim about kinds, and an unknown kind is not one of the kinds that were ticked. The settings page's "Copy crop and rotation" checkbox is gone, replaced by the same chips the preset sheet draws. It asked the right first question — geometry is the kind whose accidental travel destroys work — but it was the only question a boolean could ask. The field stays in `Settings`, read exactly once to seed the new set, so anyone who had ticked it keeps their behaviour. The chips are deliberately not in the develop column. Six of them there would set the width of the whole sidebar, which is the bug `ChipGrid`'s comment records at length. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+39
-17
@@ -1,6 +1,7 @@
|
||||
import { Theme } from "theme.slint";
|
||||
import { Button, PanelHeading, Label, Value, Caption, Panel, ProgressBar, ActivityRow } from "widgets.slint";
|
||||
import { Segmented, TextRow, Check, SliderRow } from "controls.slint";
|
||||
import { ScopeChips, ScopeKind } from "presets.slint";
|
||||
|
||||
// Settings: how much disk the app may spend, and what an export defaults to.
|
||||
//
|
||||
@@ -98,8 +99,11 @@ export component SettingsPage inherits Rectangle {
|
||||
in property <bool> thumbnail-unlimited: false;
|
||||
in property <bool> keep-opened: true;
|
||||
/// TRACES: FR-DEV-6
|
||||
/// Whether copying settings carries the crop and rotation with it.
|
||||
in property <bool> copy-includes-framing: false;
|
||||
/// Which kinds of edit a copy or preset carries. Supersedes the boolean
|
||||
/// above, which named only the one kind anybody wanted to exclude.
|
||||
in property <[ScopeKind]> copy-scope-kinds;
|
||||
in property <bool> copy-scope-empty: false;
|
||||
callback copy-scope-toggled(string);
|
||||
/// What the cache currently holds. Empty hides the line.
|
||||
in property <string> cache-usage;
|
||||
|
||||
@@ -141,7 +145,6 @@ export component SettingsPage inherits Rectangle {
|
||||
callback thumbnail-budget-changed(string);
|
||||
callback thumbnail-unlimited-toggled(bool);
|
||||
callback keep-opened-toggled(bool);
|
||||
callback copy-includes-framing-toggled(bool);
|
||||
|
||||
// --- library -------------------------------------------------------
|
||||
/// TRACES: FR-CAT-6
|
||||
@@ -551,20 +554,39 @@ export component SettingsPage inherits Rectangle {
|
||||
|
||||
PanelHeading { text: "DEVELOP"; }
|
||||
|
||||
Check {
|
||||
label: "Copy crop and rotation with settings";
|
||||
// Says what the *off* state does, because off is
|
||||
// the default and is the behaviour that needs
|
||||
// explaining: a user who has never opened this
|
||||
// page should still be able to predict what a
|
||||
// paste did to their crops.
|
||||
hint: "Off, pasting settings changes only colour and "
|
||||
+ "tone, and each photograph keeps its own "
|
||||
+ "composition. On, the crop, straightening, "
|
||||
+ "rotation and flips travel too — which "
|
||||
+ "re-frames every image pasted onto.";
|
||||
checked: root.copy-includes-framing;
|
||||
toggled(on) => { root.copy-includes-framing-toggled(on); }
|
||||
// TRACES: FR-DEV-6
|
||||
// Which kinds of edit a copy, a paste or a preset
|
||||
// carries.
|
||||
//
|
||||
// This replaced a single "copy crop and rotation"
|
||||
// checkbox. That question was the right one to ask
|
||||
// first — geometry is the kind whose accidental
|
||||
// travel destroys work — but it was the only question
|
||||
// a boolean could ask, and "match the colour but not
|
||||
// the sharpening" had no way to be said.
|
||||
//
|
||||
// Chips rather than six checkboxes: these are one
|
||||
// question with six answers, and a column of ticks
|
||||
// reads as six unrelated preferences.
|
||||
VerticalLayout {
|
||||
spacing: 4px;
|
||||
|
||||
Label { text: "Copying carries"; }
|
||||
|
||||
ScopeChips {
|
||||
kinds: root.copy-scope-kinds;
|
||||
columns: 6;
|
||||
toggled(name) => { root.copy-scope-toggled(name); }
|
||||
}
|
||||
|
||||
Caption {
|
||||
text: root.copy-scope-empty
|
||||
? "Nothing selected — a paste would change nothing."
|
||||
: "Geometry is off by default: a crop is a decision "
|
||||
+ "about one photograph's composition, and carrying "
|
||||
+ "it re-frames every image pasted onto.";
|
||||
warn: root.copy-scope-empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user