Group the panel by what operations say they are about
A strip of groups over the adjust panel — Light, Colour, Detail — derived from the attributes the operations declare. `adjust.slint` names none of them: the strings arrive resolved and the panel only draws them, so a new operation joins the right group by saying what it is and this file does not change (FR-DEV-3a). A group nothing carries is not offered, so a tab never opens onto nothing. Geometry is left out because its one operation prefers an on-canvas widget and is skipped by the row builder — a Geometry tab would be empty while `GeometryPanel` holds the real controls. The strip appears only when there is more than one group to choose between; a single tab is a control with one option. The selected group is underlined rather than filled. The accent means *modified* everywhere else in this interface, and spending it on "which tab" would blunt the one signal the panel has. **The trap, and it nearly bit again.** `op_index` on a row counts over every capability, not over the ones a filter kept — it is how a row routes back to the core. Renumbering it while filtering would make a slider drive a different operation, which looks like a rendering fault rather than a routing one. `rows_filtered` keeps `enumerate` over the full list and only `group_head` is a position within the emitted rows; a test moves a value through a filtered row and checks it lands where it was asked to. Six tests, including that a nonsense index falls back to showing everything rather than to showing nothing.
This commit is contained in:
@@ -383,3 +383,56 @@ fn an_untouched_layer_is_left_alone() {
|
||||
assert!(ours.merge(&theirs, Some(&base)).is_empty());
|
||||
assert_eq!(ours.masks.len(), 2, "our new layer is not a conflict");
|
||||
}
|
||||
|
||||
/// Print a real sidecar carrying a subject mask, for eyeballing the format.
|
||||
///
|
||||
/// Ignored because it asserts nothing — it exists so the on-disk shape can be
|
||||
/// looked at without reverse-engineering it from the writer.
|
||||
///
|
||||
/// ```sh
|
||||
/// cargo test -p dr-pipeline --test mask_sidecar show_a_sidecar -- --ignored --nocapture
|
||||
/// ```
|
||||
#[test]
|
||||
#[ignore = "prints the format rather than checking it"]
|
||||
fn show_a_sidecar() {
|
||||
let mut graph = EditGraph::default_chain();
|
||||
graph.set_param(dr_pipeline::OpId("exposure"), ParamId("exposure"), 0.35);
|
||||
|
||||
let mut subject = MaskLayer::new(
|
||||
"m1",
|
||||
MaskSource::Subject {
|
||||
signature: 0x9f2c_41aa,
|
||||
index: 0,
|
||||
class: "person".into(),
|
||||
score: 0.94,
|
||||
},
|
||||
);
|
||||
subject.name = "person".into();
|
||||
subject.invert = true;
|
||||
subject.feather = 0.02;
|
||||
subject.falloff = dr_pipeline::mask::Falloff::Gaussian;
|
||||
subject.morphology = dr_pipeline::mask::Morphology::Dilate;
|
||||
subject.morph_radius = 0.012;
|
||||
subject.set_param("saturation", ParamId("saturation"), -100.0);
|
||||
subject.set_param("exposure", ParamId("exposure"), -0.4);
|
||||
graph.masks_mut().push(subject);
|
||||
|
||||
let mut grad = MaskLayer::new(
|
||||
"m2",
|
||||
MaskSource::Linear {
|
||||
centre: (0.5, 0.25),
|
||||
angle: 1.5708,
|
||||
width: 0.4,
|
||||
},
|
||||
);
|
||||
grad.set_param("exposure", ParamId("exposure"), -0.6);
|
||||
graph.masks_mut().push(grad);
|
||||
|
||||
let mut sidecar = Sidecar::new();
|
||||
let mut v = Version::from_graph("default", "Default", &graph);
|
||||
v.is_default = true;
|
||||
v.rating = 4;
|
||||
sidecar.put(v);
|
||||
|
||||
println!("\n{}", sidecar.to_text());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user