From ff6c313bab26746c5f820f139d589ebd1b951a88 Mon Sep 17 00:00:00 2001 From: Duncan Tourolle Date: Sat, 29 Aug 2026 15:08:47 +0200 Subject: [PATCH] Wrap the chip rows, so one six-choice parameter stops sizing the sidebar MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The develop column asked for 482px. Every comment in it, a dozen of them, describes it as a 280px column — and on a tablet it was taking 40% of the screen from the photograph it exists to serve. Measured rather than guessed, because none of it is visible in the source: the column takes the widest width any panel declares, `AdjustPanel` wanted 482 of it, its rows wanted 458, and after the 44px scroll gutter the widest single row was 414. That row is `film_sim`'s `format` — six film formats from 35mm to 8x10, laid out by `Segmented` as six 64px chips in a `HorizontalLayout` that cannot wrap. 6 x 64 + 5 x 6 = 414, exactly. Nothing about that is the film simulation's fault. An operation declares its parameters and the panel decides how to draw them (FR-DEV-3a), so a node is entitled to offer six choices; it is the drawing that has to cope. Any future operation with a five-choice enum would have done the same thing, silently, to every screen in the application. `ChipGrid` is the general answer: chips placed by index arithmetic inside a plain `Rectangle`, wrapping at a column count, declaring a width that depends on the columns rather than on the number of choices. `Segmented` takes a `columns` property and uses it when asked — zero, one row however many chips, stays the settings page's behaviour, where the page is full-width and reading the alternatives side by side is the whole argument for chips over a dropdown. The generated enum rows and the curve-channel picker now wrap at three, and the crop ratio chips use the shared grid instead of the private copy of it they shipped with last week. The column measures 351 now, down from 482, and what sets it is the mode strip rather than a parameter — which is a control the user chose to have on screen rather than an accident of one node's variant list. Co-Authored-By: Claude Opus 5 (1M context) --- docs/traceability.md | 12 +++--- ui/dr-ui/ui/adjust.slint | 57 ++++++++-------------------- ui/dr-ui/ui/controls.slint | 77 +++++++++++++++++++++++++++++++++++++- 3 files changed, 98 insertions(+), 48 deletions(-) diff --git a/docs/traceability.md b/docs/traceability.md index 542b689..42b6720 100644 --- a/docs/traceability.md +++ b/docs/traceability.md @@ -10,7 +10,7 @@ Denominators are parsed from [`requirements.md`](requirements.md) at run time, n | Metric | Value | |---|---| | Source files scanned | 290 | -| TRACES tags found | 880 | +| TRACES tags found | 881 | | Requirements defined | 179 | | Requirements covered | 107 | | **Coverage** | **59.8%** (107/179) | @@ -57,19 +57,19 @@ _None._ | FR-CULL-8 | [`core/dr-catalog/src/face_shard.rs:1`](../core/dr-catalog/src/face_shard.rs#L1), [`core/dr-catalog/src/faces.rs:1`](../core/dr-catalog/src/faces.rs#L1), [`core/dr-catalog/src/schema.rs:401`](../core/dr-catalog/src/schema.rs#L401), [`core/dr-catalog/src/schema.rs:442`](../core/dr-catalog/src/schema.rs#L442), [`ui/dr-ui/src/faces.rs:1`](../ui/dr-ui/src/faces.rs#L1), [`ui/dr-ui/src/library.rs:2849`](../ui/dr-ui/src/library.rs#L2849), [`ui/dr-ui/src/library.rs:2953`](../ui/dr-ui/src/library.rs#L2953), [`ui/dr-ui/ui/settings.slint:416`](../ui/dr-ui/ui/settings.slint#L416), [`ui/dr-ui/ui/settings.slint:81`](../ui/dr-ui/ui/settings.slint#L81) | | FR-CULL-9 | [`core/dr-catalog/src/faces.rs:1`](../core/dr-catalog/src/faces.rs#L1), [`core/dr-catalog/src/schema.rs:442`](../core/dr-catalog/src/schema.rs#L442), [`core/dr-face/src/assign.rs:1`](../core/dr-face/src/assign.rs#L1), [`core/dr-face/src/neighbours.rs:1`](../core/dr-face/src/neighbours.rs#L1), [`ui/dr-ui/src/faces.rs:1`](../ui/dr-ui/src/faces.rs#L1), [`ui/dr-ui/src/identity_ui.rs:1`](../ui/dr-ui/src/identity_ui.rs#L1) | | FR-DEV-2 | [`core/dr-pipeline/src/operation.rs:389`](../core/dr-pipeline/src/operation.rs#L389) | -| FR-DEV-3 | [`core/dr-gpu/src/adjust.rs:2165`](../core/dr-gpu/src/adjust.rs#L2165), [`core/dr-gpu/src/adjust.rs:651`](../core/dr-gpu/src/adjust.rs#L651), [`core/dr-gpu/src/adjust.rs:770`](../core/dr-gpu/src/adjust.rs#L770), [`core/dr-gpu/src/adjust.rs:84`](../core/dr-gpu/src/adjust.rs#L84), [`core/dr-gpu/tests/tone_curve.rs:1`](../core/dr-gpu/tests/tone_curve.rs#L1), [`core/dr-pipeline/src/detail.rs:434`](../core/dr-pipeline/src/detail.rs#L434), [`core/dr-pipeline/src/detail.rs:524`](../core/dr-pipeline/src/detail.rs#L524), [`core/dr-pipeline/src/framing.rs:177`](../core/dr-pipeline/src/framing.rs#L177), [`core/dr-pipeline/src/framing.rs:234`](../core/dr-pipeline/src/framing.rs#L234), [`core/dr-pipeline/src/framing.rs:314`](../core/dr-pipeline/src/framing.rs#L314), [`core/dr-pipeline/src/framing.rs:488`](../core/dr-pipeline/src/framing.rs#L488), [`core/dr-pipeline/src/framing.rs:743`](../core/dr-pipeline/src/framing.rs#L743), [`core/dr-pipeline/src/graph.rs:169`](../core/dr-pipeline/src/graph.rs#L169), [`core/dr-pipeline/src/graph.rs:577`](../core/dr-pipeline/src/graph.rs#L577), [`core/dr-pipeline/src/mask.rs:121`](../core/dr-pipeline/src/mask.rs#L121), [`core/dr-pipeline/src/operation.rs:330`](../core/dr-pipeline/src/operation.rs#L330), [`core/dr-pipeline/src/operation.rs:516`](../core/dr-pipeline/src/operation.rs#L516), [`core/dr-pipeline/src/ops/capture_sharpen.rs:1`](../core/dr-pipeline/src/ops/capture_sharpen.rs#L1), [`core/dr-pipeline/src/ops/capture_sharpen.rs:210`](../core/dr-pipeline/src/ops/capture_sharpen.rs#L210), [`core/dr-pipeline/src/ops/curve.rs:100`](../core/dr-pipeline/src/ops/curve.rs#L100), [`core/dr-pipeline/src/ops/curve.rs:1`](../core/dr-pipeline/src/ops/curve.rs#L1), [`core/dr-pipeline/src/ops/curve.rs:219`](../core/dr-pipeline/src/ops/curve.rs#L219), [`core/dr-pipeline/src/ops/curve.rs:635`](../core/dr-pipeline/src/ops/curve.rs#L635), [`core/dr-pipeline/src/ops/local_contrast.rs:1`](../core/dr-pipeline/src/ops/local_contrast.rs#L1), [`core/dr-pipeline/src/ops/noise_reduction.rs:1`](../core/dr-pipeline/src/ops/noise_reduction.rs#L1), [`core/dr-pipeline/src/ops/noise_reduction.rs:273`](../core/dr-pipeline/src/ops/noise_reduction.rs#L273), [`core/dr-pipeline/src/sidecar.rs:156`](../core/dr-pipeline/src/sidecar.rs#L156), [`core/dr-pipeline/src/sidecar.rs:1636`](../core/dr-pipeline/src/sidecar.rs#L1636), [`core/dr-pipeline/src/sidecar.rs:1696`](../core/dr-pipeline/src/sidecar.rs#L1696), [`core/dr-pipeline/tests/tone_curve.rs:1`](../core/dr-pipeline/tests/tone_curve.rs#L1), [`ui/dr-ui/src/develop.rs:101`](../ui/dr-ui/src/develop.rs#L101), [`ui/dr-ui/src/develop.rs:1395`](../ui/dr-ui/src/develop.rs#L1395), [`ui/dr-ui/src/develop.rs:163`](../ui/dr-ui/src/develop.rs#L163), [`ui/dr-ui/src/develop.rs:1873`](../ui/dr-ui/src/develop.rs#L1873), [`ui/dr-ui/src/develop.rs:1891`](../ui/dr-ui/src/develop.rs#L1891), [`ui/dr-ui/src/develop.rs:1905`](../ui/dr-ui/src/develop.rs#L1905), [`ui/dr-ui/src/develop.rs:1927`](../ui/dr-ui/src/develop.rs#L1927), [`ui/dr-ui/src/develop.rs:2073`](../ui/dr-ui/src/develop.rs#L2073), [`ui/dr-ui/src/develop.rs:2171`](../ui/dr-ui/src/develop.rs#L2171), [`ui/dr-ui/src/develop.rs:3239`](../ui/dr-ui/src/develop.rs#L3239), [`ui/dr-ui/src/develop.rs:3269`](../ui/dr-ui/src/develop.rs#L3269), [`ui/dr-ui/src/develop.rs:326`](../ui/dr-ui/src/develop.rs#L326), [`ui/dr-ui/src/develop.rs:3335`](../ui/dr-ui/src/develop.rs#L3335), [`ui/dr-ui/src/develop.rs:3515`](../ui/dr-ui/src/develop.rs#L3515), [`ui/dr-ui/src/develop.rs:363`](../ui/dr-ui/src/develop.rs#L363), [`ui/dr-ui/src/develop.rs:4175`](../ui/dr-ui/src/develop.rs#L4175), [`ui/dr-ui/src/develop.rs:4229`](../ui/dr-ui/src/develop.rs#L4229), [`ui/dr-ui/src/develop.rs:4273`](../ui/dr-ui/src/develop.rs#L4273), [`ui/dr-ui/src/develop.rs:4323`](../ui/dr-ui/src/develop.rs#L4323), [`ui/dr-ui/src/develop.rs:586`](../ui/dr-ui/src/develop.rs#L586), [`ui/dr-ui/src/develop.rs:647`](../ui/dr-ui/src/develop.rs#L647), [`ui/dr-ui/src/develop.rs:726`](../ui/dr-ui/src/develop.rs#L726), [`ui/dr-ui/src/develop.rs:773`](../ui/dr-ui/src/develop.rs#L773), [`ui/dr-ui/src/lib.rs:1513`](../ui/dr-ui/src/lib.rs#L1513), [`ui/dr-ui/src/lib.rs:2214`](../ui/dr-ui/src/lib.rs#L2214), [`ui/dr-ui/src/lib.rs:2410`](../ui/dr-ui/src/lib.rs#L2410), [`ui/dr-ui/src/lib.rs:2582`](../ui/dr-ui/src/lib.rs#L2582), [`ui/dr-ui/src/lib.rs:2646`](../ui/dr-ui/src/lib.rs#L2646), [`ui/dr-ui/src/lib.rs:2700`](../ui/dr-ui/src/lib.rs#L2700), [`ui/dr-ui/src/lib.rs:319`](../ui/dr-ui/src/lib.rs#L319), [`ui/dr-ui/src/lib.rs:362`](../ui/dr-ui/src/lib.rs#L362), [`ui/dr-ui/src/lib.rs:385`](../ui/dr-ui/src/lib.rs#L385), [`ui/dr-ui/src/library.rs:506`](../ui/dr-ui/src/library.rs#L506), [`ui/dr-ui/src/masks_ui.rs:218`](../ui/dr-ui/src/masks_ui.rs#L218), [`ui/dr-ui/src/masks_ui.rs:41`](../ui/dr-ui/src/masks_ui.rs#L41), [`ui/dr-ui/src/masks_ui.rs:816`](../ui/dr-ui/src/masks_ui.rs#L816), [`ui/dr-ui/src/masks_ui.rs:930`](../ui/dr-ui/src/masks_ui.rs#L930), [`ui/dr-ui/src/segmentation.rs:219`](../ui/dr-ui/src/segmentation.rs#L219), [`ui/dr-ui/src/segmentation.rs:322`](../ui/dr-ui/src/segmentation.rs#L322), [`ui/dr-ui/src/segmentation.rs:350`](../ui/dr-ui/src/segmentation.rs#L350), [`ui/dr-ui/ui/adjust.slint:511`](../ui/dr-ui/ui/adjust.slint#L511), [`ui/dr-ui/ui/adjust.slint:629`](../ui/dr-ui/ui/adjust.slint#L629), [`ui/dr-ui/ui/app.slint:118`](../ui/dr-ui/ui/app.slint#L118), [`ui/dr-ui/ui/app.slint:164`](../ui/dr-ui/ui/app.slint#L164), [`ui/dr-ui/ui/app.slint:1810`](../ui/dr-ui/ui/app.slint#L1810), [`ui/dr-ui/ui/app.slint:828`](../ui/dr-ui/ui/app.slint#L828), [`ui/dr-ui/ui/masks.slint:490`](../ui/dr-ui/ui/masks.slint#L490) | +| FR-DEV-3 | [`core/dr-gpu/src/adjust.rs:2165`](../core/dr-gpu/src/adjust.rs#L2165), [`core/dr-gpu/src/adjust.rs:651`](../core/dr-gpu/src/adjust.rs#L651), [`core/dr-gpu/src/adjust.rs:770`](../core/dr-gpu/src/adjust.rs#L770), [`core/dr-gpu/src/adjust.rs:84`](../core/dr-gpu/src/adjust.rs#L84), [`core/dr-gpu/tests/tone_curve.rs:1`](../core/dr-gpu/tests/tone_curve.rs#L1), [`core/dr-pipeline/src/detail.rs:434`](../core/dr-pipeline/src/detail.rs#L434), [`core/dr-pipeline/src/detail.rs:524`](../core/dr-pipeline/src/detail.rs#L524), [`core/dr-pipeline/src/framing.rs:177`](../core/dr-pipeline/src/framing.rs#L177), [`core/dr-pipeline/src/framing.rs:234`](../core/dr-pipeline/src/framing.rs#L234), [`core/dr-pipeline/src/framing.rs:314`](../core/dr-pipeline/src/framing.rs#L314), [`core/dr-pipeline/src/framing.rs:488`](../core/dr-pipeline/src/framing.rs#L488), [`core/dr-pipeline/src/framing.rs:743`](../core/dr-pipeline/src/framing.rs#L743), [`core/dr-pipeline/src/graph.rs:169`](../core/dr-pipeline/src/graph.rs#L169), [`core/dr-pipeline/src/graph.rs:577`](../core/dr-pipeline/src/graph.rs#L577), [`core/dr-pipeline/src/mask.rs:121`](../core/dr-pipeline/src/mask.rs#L121), [`core/dr-pipeline/src/operation.rs:330`](../core/dr-pipeline/src/operation.rs#L330), [`core/dr-pipeline/src/operation.rs:516`](../core/dr-pipeline/src/operation.rs#L516), [`core/dr-pipeline/src/ops/capture_sharpen.rs:1`](../core/dr-pipeline/src/ops/capture_sharpen.rs#L1), [`core/dr-pipeline/src/ops/capture_sharpen.rs:210`](../core/dr-pipeline/src/ops/capture_sharpen.rs#L210), [`core/dr-pipeline/src/ops/curve.rs:100`](../core/dr-pipeline/src/ops/curve.rs#L100), [`core/dr-pipeline/src/ops/curve.rs:1`](../core/dr-pipeline/src/ops/curve.rs#L1), [`core/dr-pipeline/src/ops/curve.rs:219`](../core/dr-pipeline/src/ops/curve.rs#L219), [`core/dr-pipeline/src/ops/curve.rs:635`](../core/dr-pipeline/src/ops/curve.rs#L635), [`core/dr-pipeline/src/ops/local_contrast.rs:1`](../core/dr-pipeline/src/ops/local_contrast.rs#L1), [`core/dr-pipeline/src/ops/noise_reduction.rs:1`](../core/dr-pipeline/src/ops/noise_reduction.rs#L1), [`core/dr-pipeline/src/ops/noise_reduction.rs:273`](../core/dr-pipeline/src/ops/noise_reduction.rs#L273), [`core/dr-pipeline/src/sidecar.rs:156`](../core/dr-pipeline/src/sidecar.rs#L156), [`core/dr-pipeline/src/sidecar.rs:1636`](../core/dr-pipeline/src/sidecar.rs#L1636), [`core/dr-pipeline/src/sidecar.rs:1696`](../core/dr-pipeline/src/sidecar.rs#L1696), [`core/dr-pipeline/tests/tone_curve.rs:1`](../core/dr-pipeline/tests/tone_curve.rs#L1), [`ui/dr-ui/src/develop.rs:101`](../ui/dr-ui/src/develop.rs#L101), [`ui/dr-ui/src/develop.rs:1395`](../ui/dr-ui/src/develop.rs#L1395), [`ui/dr-ui/src/develop.rs:163`](../ui/dr-ui/src/develop.rs#L163), [`ui/dr-ui/src/develop.rs:1873`](../ui/dr-ui/src/develop.rs#L1873), [`ui/dr-ui/src/develop.rs:1891`](../ui/dr-ui/src/develop.rs#L1891), [`ui/dr-ui/src/develop.rs:1905`](../ui/dr-ui/src/develop.rs#L1905), [`ui/dr-ui/src/develop.rs:1927`](../ui/dr-ui/src/develop.rs#L1927), [`ui/dr-ui/src/develop.rs:2073`](../ui/dr-ui/src/develop.rs#L2073), [`ui/dr-ui/src/develop.rs:2171`](../ui/dr-ui/src/develop.rs#L2171), [`ui/dr-ui/src/develop.rs:3239`](../ui/dr-ui/src/develop.rs#L3239), [`ui/dr-ui/src/develop.rs:3269`](../ui/dr-ui/src/develop.rs#L3269), [`ui/dr-ui/src/develop.rs:326`](../ui/dr-ui/src/develop.rs#L326), [`ui/dr-ui/src/develop.rs:3335`](../ui/dr-ui/src/develop.rs#L3335), [`ui/dr-ui/src/develop.rs:3515`](../ui/dr-ui/src/develop.rs#L3515), [`ui/dr-ui/src/develop.rs:363`](../ui/dr-ui/src/develop.rs#L363), [`ui/dr-ui/src/develop.rs:4175`](../ui/dr-ui/src/develop.rs#L4175), [`ui/dr-ui/src/develop.rs:4229`](../ui/dr-ui/src/develop.rs#L4229), [`ui/dr-ui/src/develop.rs:4273`](../ui/dr-ui/src/develop.rs#L4273), [`ui/dr-ui/src/develop.rs:4323`](../ui/dr-ui/src/develop.rs#L4323), [`ui/dr-ui/src/develop.rs:586`](../ui/dr-ui/src/develop.rs#L586), [`ui/dr-ui/src/develop.rs:647`](../ui/dr-ui/src/develop.rs#L647), [`ui/dr-ui/src/develop.rs:726`](../ui/dr-ui/src/develop.rs#L726), [`ui/dr-ui/src/develop.rs:773`](../ui/dr-ui/src/develop.rs#L773), [`ui/dr-ui/src/lib.rs:1513`](../ui/dr-ui/src/lib.rs#L1513), [`ui/dr-ui/src/lib.rs:2214`](../ui/dr-ui/src/lib.rs#L2214), [`ui/dr-ui/src/lib.rs:2410`](../ui/dr-ui/src/lib.rs#L2410), [`ui/dr-ui/src/lib.rs:2582`](../ui/dr-ui/src/lib.rs#L2582), [`ui/dr-ui/src/lib.rs:2646`](../ui/dr-ui/src/lib.rs#L2646), [`ui/dr-ui/src/lib.rs:2700`](../ui/dr-ui/src/lib.rs#L2700), [`ui/dr-ui/src/lib.rs:319`](../ui/dr-ui/src/lib.rs#L319), [`ui/dr-ui/src/lib.rs:362`](../ui/dr-ui/src/lib.rs#L362), [`ui/dr-ui/src/lib.rs:385`](../ui/dr-ui/src/lib.rs#L385), [`ui/dr-ui/src/library.rs:506`](../ui/dr-ui/src/library.rs#L506), [`ui/dr-ui/src/masks_ui.rs:218`](../ui/dr-ui/src/masks_ui.rs#L218), [`ui/dr-ui/src/masks_ui.rs:41`](../ui/dr-ui/src/masks_ui.rs#L41), [`ui/dr-ui/src/masks_ui.rs:816`](../ui/dr-ui/src/masks_ui.rs#L816), [`ui/dr-ui/src/masks_ui.rs:930`](../ui/dr-ui/src/masks_ui.rs#L930), [`ui/dr-ui/src/segmentation.rs:219`](../ui/dr-ui/src/segmentation.rs#L219), [`ui/dr-ui/src/segmentation.rs:322`](../ui/dr-ui/src/segmentation.rs#L322), [`ui/dr-ui/src/segmentation.rs:350`](../ui/dr-ui/src/segmentation.rs#L350), [`ui/dr-ui/ui/adjust.slint:517`](../ui/dr-ui/ui/adjust.slint#L517), [`ui/dr-ui/ui/adjust.slint:635`](../ui/dr-ui/ui/adjust.slint#L635), [`ui/dr-ui/ui/app.slint:118`](../ui/dr-ui/ui/app.slint#L118), [`ui/dr-ui/ui/app.slint:164`](../ui/dr-ui/ui/app.slint#L164), [`ui/dr-ui/ui/app.slint:1810`](../ui/dr-ui/ui/app.slint#L1810), [`ui/dr-ui/ui/app.slint:828`](../ui/dr-ui/ui/app.slint#L828), [`ui/dr-ui/ui/masks.slint:490`](../ui/dr-ui/ui/masks.slint#L490) | | FR-DEV-3a | [`core/dr-pipeline/build.rs:756`](../core/dr-pipeline/build.rs#L756), [`core/dr-pipeline/ops/exposure.yaml:1`](../core/dr-pipeline/ops/exposure.yaml#L1), [`core/dr-pipeline/src/descriptor.rs:194`](../core/dr-pipeline/src/descriptor.rs#L194), [`core/dr-pipeline/src/descriptor.rs:234`](../core/dr-pipeline/src/descriptor.rs#L234), [`core/dr-pipeline/src/descriptor.rs:258`](../core/dr-pipeline/src/descriptor.rs#L258), [`core/dr-pipeline/src/descriptor.rs:313`](../core/dr-pipeline/src/descriptor.rs#L313), [`core/dr-pipeline/src/framing.rs:385`](../core/dr-pipeline/src/framing.rs#L385), [`core/dr-pipeline/src/graph.rs:23`](../core/dr-pipeline/src/graph.rs#L23), [`core/dr-pipeline/src/graph.rs:250`](../core/dr-pipeline/src/graph.rs#L250), [`core/dr-pipeline/src/graph.rs:45`](../core/dr-pipeline/src/graph.rs#L45), [`core/dr-pipeline/src/graph.rs:58`](../core/dr-pipeline/src/graph.rs#L58), [`core/dr-pipeline/src/mask.rs:955`](../core/dr-pipeline/src/mask.rs#L955), [`core/dr-pipeline/src/operation.rs:232`](../core/dr-pipeline/src/operation.rs#L232), [`core/dr-pipeline/src/operation.rs:365`](../core/dr-pipeline/src/operation.rs#L365), [`core/dr-pipeline/src/ops/curve.rs:319`](../core/dr-pipeline/src/ops/curve.rs#L319), [`ui/dr-ui/src/develop.rs:1292`](../ui/dr-ui/src/develop.rs#L1292), [`ui/dr-ui/src/lib.rs:668`](../ui/dr-ui/src/lib.rs#L668), [`ui/dr-ui/tests/ui_names_no_operation.rs:1`](../ui/dr-ui/tests/ui_names_no_operation.rs#L1) | | FR-DEV-3b | [`core/dr-pipeline/src/descriptor.rs:258`](../core/dr-pipeline/src/descriptor.rs#L258), [`core/dr-pipeline/src/framing.rs:385`](../core/dr-pipeline/src/framing.rs#L385), [`core/dr-pipeline/src/graph.rs:58`](../core/dr-pipeline/src/graph.rs#L58), [`core/dr-pipeline/src/operation.rs:365`](../core/dr-pipeline/src/operation.rs#L365) | | FR-DEV-3c | [`core/dr-pipeline/build.rs:756`](../core/dr-pipeline/build.rs#L756), [`core/dr-pipeline/ops/exposure.yaml:1`](../core/dr-pipeline/ops/exposure.yaml#L1), [`core/dr-pipeline/src/graph.rs:250`](../core/dr-pipeline/src/graph.rs#L250), [`core/dr-pipeline/src/graph.rs:45`](../core/dr-pipeline/src/graph.rs#L45), [`core/dr-pipeline/src/mask.rs:955`](../core/dr-pipeline/src/mask.rs#L955), [`ui/dr-ui/src/develop.rs:4902`](../ui/dr-ui/src/develop.rs#L4902) | | FR-DEV-3d | [`core/dr-gpu/src/adjust.rs:1041`](../core/dr-gpu/src/adjust.rs#L1041), [`core/dr-gpu/src/adjust.rs:104`](../core/dr-gpu/src/adjust.rs#L104), [`core/dr-gpu/src/adjust.rs:770`](../core/dr-gpu/src/adjust.rs#L770), [`core/dr-gpu/src/adjust.rs:84`](../core/dr-gpu/src/adjust.rs#L84), [`core/dr-gpu/src/adjust.rs:986`](../core/dr-gpu/src/adjust.rs#L986), [`core/dr-gpu/tests/capture_sharpen.rs:434`](../core/dr-gpu/tests/capture_sharpen.rs#L434), [`core/dr-gpu/tests/detail_stage.rs:242`](../core/dr-gpu/tests/detail_stage.rs#L242), [`core/dr-gpu/tests/local_contrast.rs:558`](../core/dr-gpu/tests/local_contrast.rs#L558), [`core/dr-gpu/tests/noise_reduction.rs:556`](../core/dr-gpu/tests/noise_reduction.rs#L556), [`core/dr-pipeline/src/framing.rs:314`](../core/dr-pipeline/src/framing.rs#L314), [`core/dr-pipeline/src/graph.rs:616`](../core/dr-pipeline/src/graph.rs#L616), [`core/dr-pipeline/src/operation.rs:32`](../core/dr-pipeline/src/operation.rs#L32), [`core/dr-pipeline/src/operation.rs:389`](../core/dr-pipeline/src/operation.rs#L389), [`core/dr-pipeline/src/operation.rs:53`](../core/dr-pipeline/src/operation.rs#L53), [`core/dr-pipeline/src/operation.rs:71`](../core/dr-pipeline/src/operation.rs#L71) | | FR-DEV-3e | [`core/dr-decode/src/base_curve.rs:145`](../core/dr-decode/src/base_curve.rs#L145), [`core/dr-decode/src/base_curve.rs:158`](../core/dr-decode/src/base_curve.rs#L158), [`core/dr-decode/src/base_curve.rs:1`](../core/dr-decode/src/base_curve.rs#L1), [`core/dr-decode/src/base_curve.rs:267`](../core/dr-decode/src/base_curve.rs#L267), [`core/dr-decode/src/base_curve.rs:347`](../core/dr-decode/src/base_curve.rs#L347), [`core/dr-decode/src/base_curve.rs:55`](../core/dr-decode/src/base_curve.rs#L55), [`core/dr-decode/src/lib.rs:121`](../core/dr-decode/src/lib.rs#L121), [`core/dr-decode/src/lib.rs:708`](../core/dr-decode/src/lib.rs#L708), [`core/dr-decode/src/lib.rs:748`](../core/dr-decode/src/lib.rs#L748), [`core/dr-decode/src/profile.rs:102`](../core/dr-decode/src/profile.rs#L102), [`core/dr-decode/src/profile.rs:151`](../core/dr-decode/src/profile.rs#L151), [`core/dr-decode/src/profile.rs:1`](../core/dr-decode/src/profile.rs#L1), [`core/dr-decode/src/profile.rs:235`](../core/dr-decode/src/profile.rs#L235), [`core/dr-decode/src/profile.rs:286`](../core/dr-decode/src/profile.rs#L286), [`core/dr-decode/src/profile.rs:343`](../core/dr-decode/src/profile.rs#L343), [`core/dr-decode/src/profile.rs:458`](../core/dr-decode/src/profile.rs#L458), [`core/dr-decode/src/profile.rs:492`](../core/dr-decode/src/profile.rs#L492), [`core/dr-decode/src/profile.rs:630`](../core/dr-decode/src/profile.rs#L630), [`core/dr-gpu/src/adjust.rs:37`](../core/dr-gpu/src/adjust.rs#L37), [`core/dr-gpu/src/adjust.rs:967`](../core/dr-gpu/src/adjust.rs#L967), [`core/dr-gpu/src/demosaic.rs:121`](../core/dr-gpu/src/demosaic.rs#L121), [`core/dr-gpu/src/demosaic.rs:86`](../core/dr-gpu/src/demosaic.rs#L86), [`core/dr-gpu/tests/base_curve.rs:1`](../core/dr-gpu/tests/base_curve.rs#L1), [`core/dr-pipeline/src/operation.rs:1495`](../core/dr-pipeline/src/operation.rs#L1495), [`core/dr-pipeline/src/operation.rs:1576`](../core/dr-pipeline/src/operation.rs#L1576), [`core/dr-pipeline/src/operation.rs:1601`](../core/dr-pipeline/src/operation.rs#L1601), [`core/dr-pipeline/src/operation.rs:1616`](../core/dr-pipeline/src/operation.rs#L1616), [`core/dr-pipeline/src/operation.rs:1640`](../core/dr-pipeline/src/operation.rs#L1640), [`core/dr-pipeline/src/operation.rs:310`](../core/dr-pipeline/src/operation.rs#L310), [`core/dr-pipeline/src/operation.rs:440`](../core/dr-pipeline/src/operation.rs#L440), [`core/dr-pipeline/src/operation.rs:450`](../core/dr-pipeline/src/operation.rs#L450), [`core/dr-pipeline/src/operation.rs:600`](../core/dr-pipeline/src/operation.rs#L600) | -| FR-DEV-3f | [`core/dr-film/src/bake.rs:271`](../core/dr-film/src/bake.rs#L271), [`core/dr-film/src/bake.rs:62`](../core/dr-film/src/bake.rs#L62), [`core/dr-film/src/boolean_grain.rs:1`](../core/dr-film/src/boolean_grain.rs#L1), [`core/dr-film/src/boolean_grain.rs:78`](../core/dr-film/src/boolean_grain.rs#L78), [`core/dr-film/src/grain.rs:140`](../core/dr-film/src/grain.rs#L140), [`core/dr-film/src/grain.rs:1`](../core/dr-film/src/grain.rs#L1), [`core/dr-film/src/grain.rs:302`](../core/dr-film/src/grain.rs#L302), [`core/dr-film/src/grain.rs:79`](../core/dr-film/src/grain.rs#L79), [`core/dr-film/src/lib.rs:160`](../core/dr-film/src/lib.rs#L160), [`core/dr-film/src/lib.rs:1`](../core/dr-film/src/lib.rs#L1), [`core/dr-film/src/profile.rs:100`](../core/dr-film/src/profile.rs#L100), [`core/dr-film/src/profile.rs:142`](../core/dr-film/src/profile.rs#L142), [`core/dr-film/src/profile.rs:182`](../core/dr-film/src/profile.rs#L182), [`core/dr-film/src/profile.rs:259`](../core/dr-film/src/profile.rs#L259), [`core/dr-film/src/profile.rs:502`](../core/dr-film/src/profile.rs#L502), [`core/dr-film/src/profile.rs:73`](../core/dr-film/src/profile.rs#L73), [`core/dr-gpu/src/adjust.rs:139`](../core/dr-gpu/src/adjust.rs#L139), [`core/dr-gpu/src/adjust.rs:196`](../core/dr-gpu/src/adjust.rs#L196), [`core/dr-gpu/src/adjust.rs:357`](../core/dr-gpu/src/adjust.rs#L357), [`core/dr-gpu/src/adjust.rs:483`](../core/dr-gpu/src/adjust.rs#L483), [`core/dr-gpu/src/adjust.rs:77`](../core/dr-gpu/src/adjust.rs#L77), [`core/dr-gpu/tests/film_sim.rs:191`](../core/dr-gpu/tests/film_sim.rs#L191), [`core/dr-gpu/tests/film_sim.rs:1`](../core/dr-gpu/tests/film_sim.rs#L1), [`core/dr-pipeline/src/graph.rs:101`](../core/dr-pipeline/src/graph.rs#L101), [`core/dr-pipeline/src/graph.rs:124`](../core/dr-pipeline/src/graph.rs#L124), [`core/dr-pipeline/src/graph.rs:324`](../core/dr-pipeline/src/graph.rs#L324), [`core/dr-pipeline/src/operation.rs:1065`](../core/dr-pipeline/src/operation.rs#L1065), [`core/dr-pipeline/src/operation.rs:1094`](../core/dr-pipeline/src/operation.rs#L1094), [`core/dr-pipeline/src/operation.rs:1495`](../core/dr-pipeline/src/operation.rs#L1495), [`core/dr-pipeline/src/operation.rs:296`](../core/dr-pipeline/src/operation.rs#L296), [`core/dr-pipeline/src/operation.rs:310`](../core/dr-pipeline/src/operation.rs#L310), [`core/dr-pipeline/src/ops/film_sim.rs:129`](../core/dr-pipeline/src/ops/film_sim.rs#L129), [`core/dr-pipeline/src/ops/film_sim.rs:153`](../core/dr-pipeline/src/ops/film_sim.rs#L153), [`core/dr-pipeline/src/ops/film_sim.rs:1`](../core/dr-pipeline/src/ops/film_sim.rs#L1), [`core/dr-pipeline/src/ops/film_sim.rs:331`](../core/dr-pipeline/src/ops/film_sim.rs#L331), [`core/dr-pipeline/src/ops/film_sim.rs:43`](../core/dr-pipeline/src/ops/film_sim.rs#L43), [`core/dr-pipeline/src/ops/film_sim.rs:87`](../core/dr-pipeline/src/ops/film_sim.rs#L87), [`core/dr-pipeline/src/ops/film_sim.rs:92`](../core/dr-pipeline/src/ops/film_sim.rs#L92), [`core/dr-pipeline/src/sidecar.rs:111`](../core/dr-pipeline/src/sidecar.rs#L111), [`core/dr-pipeline/src/sidecar.rs:167`](../core/dr-pipeline/src/sidecar.rs#L167), [`core/dr-pipeline/src/sidecar.rs:1957`](../core/dr-pipeline/src/sidecar.rs#L1957), [`core/dr-pipeline/src/sidecar.rs:2033`](../core/dr-pipeline/src/sidecar.rs#L2033), [`core/dr-pipeline/src/sidecar.rs:533`](../core/dr-pipeline/src/sidecar.rs#L533), [`core/dr-pipeline/src/sidecar.rs:660`](../core/dr-pipeline/src/sidecar.rs#L660), [`core/dr-pipeline/src/sidecar.rs:792`](../core/dr-pipeline/src/sidecar.rs#L792), [`core/dr-pipeline/src/state.rs:100`](../core/dr-pipeline/src/state.rs#L100), [`core/dr-pipeline/src/state.rs:115`](../core/dr-pipeline/src/state.rs#L115), [`core/dr-pipeline/src/state.rs:60`](../core/dr-pipeline/src/state.rs#L60), [`ui/dr-ui/src/develop.rs:2983`](../ui/dr-ui/src/develop.rs#L2983), [`ui/dr-ui/src/develop.rs:3000`](../ui/dr-ui/src/develop.rs#L3000), [`ui/dr-ui/src/develop.rs:3012`](../ui/dr-ui/src/develop.rs#L3012), [`ui/dr-ui/src/develop.rs:3050`](../ui/dr-ui/src/develop.rs#L3050), [`ui/dr-ui/src/develop.rs:3059`](../ui/dr-ui/src/develop.rs#L3059), [`ui/dr-ui/src/develop.rs:3162`](../ui/dr-ui/src/develop.rs#L3162), [`ui/dr-ui/src/develop.rs:3552`](../ui/dr-ui/src/develop.rs#L3552), [`ui/dr-ui/src/develop.rs:3567`](../ui/dr-ui/src/develop.rs#L3567), [`ui/dr-ui/src/lib.rs:2188`](../ui/dr-ui/src/lib.rs#L2188), [`ui/dr-ui/src/lib.rs:601`](../ui/dr-ui/src/lib.rs#L601), [`ui/dr-ui/src/lib.rs:659`](../ui/dr-ui/src/lib.rs#L659), [`ui/dr-ui/src/library.rs:497`](../ui/dr-ui/src/library.rs#L497), [`ui/dr-ui/src/library.rs:745`](../ui/dr-ui/src/library.rs#L745), [`ui/dr-ui/src/presets.rs:275`](../ui/dr-ui/src/presets.rs#L275), [`ui/dr-ui/ui/adjust.slint:1045`](../ui/dr-ui/ui/adjust.slint#L1045), [`ui/dr-ui/ui/adjust.slint:1127`](../ui/dr-ui/ui/adjust.slint#L1127), [`ui/dr-ui/ui/app.slint:2316`](../ui/dr-ui/ui/app.slint#L2316), [`ui/dr-ui/ui/app.slint:599`](../ui/dr-ui/ui/app.slint#L599) | +| FR-DEV-3f | [`core/dr-film/src/bake.rs:271`](../core/dr-film/src/bake.rs#L271), [`core/dr-film/src/bake.rs:62`](../core/dr-film/src/bake.rs#L62), [`core/dr-film/src/boolean_grain.rs:1`](../core/dr-film/src/boolean_grain.rs#L1), [`core/dr-film/src/boolean_grain.rs:78`](../core/dr-film/src/boolean_grain.rs#L78), [`core/dr-film/src/grain.rs:140`](../core/dr-film/src/grain.rs#L140), [`core/dr-film/src/grain.rs:1`](../core/dr-film/src/grain.rs#L1), [`core/dr-film/src/grain.rs:302`](../core/dr-film/src/grain.rs#L302), [`core/dr-film/src/grain.rs:79`](../core/dr-film/src/grain.rs#L79), [`core/dr-film/src/lib.rs:160`](../core/dr-film/src/lib.rs#L160), [`core/dr-film/src/lib.rs:1`](../core/dr-film/src/lib.rs#L1), [`core/dr-film/src/profile.rs:100`](../core/dr-film/src/profile.rs#L100), [`core/dr-film/src/profile.rs:142`](../core/dr-film/src/profile.rs#L142), [`core/dr-film/src/profile.rs:182`](../core/dr-film/src/profile.rs#L182), [`core/dr-film/src/profile.rs:259`](../core/dr-film/src/profile.rs#L259), [`core/dr-film/src/profile.rs:502`](../core/dr-film/src/profile.rs#L502), [`core/dr-film/src/profile.rs:73`](../core/dr-film/src/profile.rs#L73), [`core/dr-gpu/src/adjust.rs:139`](../core/dr-gpu/src/adjust.rs#L139), [`core/dr-gpu/src/adjust.rs:196`](../core/dr-gpu/src/adjust.rs#L196), [`core/dr-gpu/src/adjust.rs:357`](../core/dr-gpu/src/adjust.rs#L357), [`core/dr-gpu/src/adjust.rs:483`](../core/dr-gpu/src/adjust.rs#L483), [`core/dr-gpu/src/adjust.rs:77`](../core/dr-gpu/src/adjust.rs#L77), [`core/dr-gpu/tests/film_sim.rs:191`](../core/dr-gpu/tests/film_sim.rs#L191), [`core/dr-gpu/tests/film_sim.rs:1`](../core/dr-gpu/tests/film_sim.rs#L1), [`core/dr-pipeline/src/graph.rs:101`](../core/dr-pipeline/src/graph.rs#L101), [`core/dr-pipeline/src/graph.rs:124`](../core/dr-pipeline/src/graph.rs#L124), [`core/dr-pipeline/src/graph.rs:324`](../core/dr-pipeline/src/graph.rs#L324), [`core/dr-pipeline/src/operation.rs:1065`](../core/dr-pipeline/src/operation.rs#L1065), [`core/dr-pipeline/src/operation.rs:1094`](../core/dr-pipeline/src/operation.rs#L1094), [`core/dr-pipeline/src/operation.rs:1495`](../core/dr-pipeline/src/operation.rs#L1495), [`core/dr-pipeline/src/operation.rs:296`](../core/dr-pipeline/src/operation.rs#L296), [`core/dr-pipeline/src/operation.rs:310`](../core/dr-pipeline/src/operation.rs#L310), [`core/dr-pipeline/src/ops/film_sim.rs:129`](../core/dr-pipeline/src/ops/film_sim.rs#L129), [`core/dr-pipeline/src/ops/film_sim.rs:153`](../core/dr-pipeline/src/ops/film_sim.rs#L153), [`core/dr-pipeline/src/ops/film_sim.rs:1`](../core/dr-pipeline/src/ops/film_sim.rs#L1), [`core/dr-pipeline/src/ops/film_sim.rs:331`](../core/dr-pipeline/src/ops/film_sim.rs#L331), [`core/dr-pipeline/src/ops/film_sim.rs:43`](../core/dr-pipeline/src/ops/film_sim.rs#L43), [`core/dr-pipeline/src/ops/film_sim.rs:87`](../core/dr-pipeline/src/ops/film_sim.rs#L87), [`core/dr-pipeline/src/ops/film_sim.rs:92`](../core/dr-pipeline/src/ops/film_sim.rs#L92), [`core/dr-pipeline/src/sidecar.rs:111`](../core/dr-pipeline/src/sidecar.rs#L111), [`core/dr-pipeline/src/sidecar.rs:167`](../core/dr-pipeline/src/sidecar.rs#L167), [`core/dr-pipeline/src/sidecar.rs:1957`](../core/dr-pipeline/src/sidecar.rs#L1957), [`core/dr-pipeline/src/sidecar.rs:2033`](../core/dr-pipeline/src/sidecar.rs#L2033), [`core/dr-pipeline/src/sidecar.rs:533`](../core/dr-pipeline/src/sidecar.rs#L533), [`core/dr-pipeline/src/sidecar.rs:660`](../core/dr-pipeline/src/sidecar.rs#L660), [`core/dr-pipeline/src/sidecar.rs:792`](../core/dr-pipeline/src/sidecar.rs#L792), [`core/dr-pipeline/src/state.rs:100`](../core/dr-pipeline/src/state.rs#L100), [`core/dr-pipeline/src/state.rs:115`](../core/dr-pipeline/src/state.rs#L115), [`core/dr-pipeline/src/state.rs:60`](../core/dr-pipeline/src/state.rs#L60), [`ui/dr-ui/src/develop.rs:2983`](../ui/dr-ui/src/develop.rs#L2983), [`ui/dr-ui/src/develop.rs:3000`](../ui/dr-ui/src/develop.rs#L3000), [`ui/dr-ui/src/develop.rs:3012`](../ui/dr-ui/src/develop.rs#L3012), [`ui/dr-ui/src/develop.rs:3050`](../ui/dr-ui/src/develop.rs#L3050), [`ui/dr-ui/src/develop.rs:3059`](../ui/dr-ui/src/develop.rs#L3059), [`ui/dr-ui/src/develop.rs:3162`](../ui/dr-ui/src/develop.rs#L3162), [`ui/dr-ui/src/develop.rs:3552`](../ui/dr-ui/src/develop.rs#L3552), [`ui/dr-ui/src/develop.rs:3567`](../ui/dr-ui/src/develop.rs#L3567), [`ui/dr-ui/src/lib.rs:2188`](../ui/dr-ui/src/lib.rs#L2188), [`ui/dr-ui/src/lib.rs:601`](../ui/dr-ui/src/lib.rs#L601), [`ui/dr-ui/src/lib.rs:659`](../ui/dr-ui/src/lib.rs#L659), [`ui/dr-ui/src/library.rs:497`](../ui/dr-ui/src/library.rs#L497), [`ui/dr-ui/src/library.rs:745`](../ui/dr-ui/src/library.rs#L745), [`ui/dr-ui/src/presets.rs:275`](../ui/dr-ui/src/presets.rs#L275), [`ui/dr-ui/ui/adjust.slint:1020`](../ui/dr-ui/ui/adjust.slint#L1020), [`ui/dr-ui/ui/adjust.slint:1102`](../ui/dr-ui/ui/adjust.slint#L1102), [`ui/dr-ui/ui/app.slint:2316`](../ui/dr-ui/ui/app.slint#L2316), [`ui/dr-ui/ui/app.slint:599`](../ui/dr-ui/ui/app.slint#L599) | | FR-DEV-3h | [`core/dr-decode/src/lib.rs:404`](../core/dr-decode/src/lib.rs#L404), [`core/dr-decode/src/preview.rs:29`](../core/dr-decode/src/preview.rs#L29), [`core/dr-pipeline/src/framing.rs:1050`](../core/dr-pipeline/src/framing.rs#L1050), [`core/dr-pipeline/src/framing.rs:328`](../core/dr-pipeline/src/framing.rs#L328), [`core/dr-pipeline/src/framing.rs:488`](../core/dr-pipeline/src/framing.rs#L488), [`core/dr-types/src/lib.rs:337`](../core/dr-types/src/lib.rs#L337), [`core/dr-types/src/lib.rs:445`](../core/dr-types/src/lib.rs#L445), [`core/dr-types/src/lib.rs:457`](../core/dr-types/src/lib.rs#L457), [`core/dr-types/src/lib.rs:473`](../core/dr-types/src/lib.rs#L473), [`ui/dr-ui/src/develop.rs:138`](../ui/dr-ui/src/develop.rs#L138), [`ui/dr-ui/src/develop.rs:2090`](../ui/dr-ui/src/develop.rs#L2090), [`ui/dr-ui/src/segmentation.rs:322`](../ui/dr-ui/src/segmentation.rs#L322) | | FR-DEV-4 | [`core/dr-gpu/src/adjust.rs:770`](../core/dr-gpu/src/adjust.rs#L770), [`core/dr-gpu/src/lib.rs:335`](../core/dr-gpu/src/lib.rs#L335), [`ui/dr-ui/ui/crop.slint:1`](../ui/dr-ui/ui/crop.slint#L1) | | FR-DEV-5 | [`core/dr-pipeline/src/graph.rs:345`](../core/dr-pipeline/src/graph.rs#L345), [`core/dr-pipeline/src/graph.rs:384`](../core/dr-pipeline/src/graph.rs#L384), [`core/dr-pipeline/src/history.rs:102`](../core/dr-pipeline/src/history.rs#L102), [`core/dr-pipeline/src/history.rs:110`](../core/dr-pipeline/src/history.rs#L110), [`core/dr-pipeline/src/history.rs:127`](../core/dr-pipeline/src/history.rs#L127), [`core/dr-pipeline/src/history.rs:184`](../core/dr-pipeline/src/history.rs#L184), [`core/dr-pipeline/src/history.rs:1`](../core/dr-pipeline/src/history.rs#L1), [`core/dr-pipeline/src/history.rs:214`](../core/dr-pipeline/src/history.rs#L214), [`core/dr-pipeline/src/history.rs:234`](../core/dr-pipeline/src/history.rs#L234), [`core/dr-pipeline/src/history.rs:293`](../core/dr-pipeline/src/history.rs#L293), [`core/dr-pipeline/src/history.rs:479`](../core/dr-pipeline/src/history.rs#L479), [`core/dr-pipeline/src/history.rs:489`](../core/dr-pipeline/src/history.rs#L489), [`core/dr-pipeline/src/history.rs:499`](../core/dr-pipeline/src/history.rs#L499), [`core/dr-pipeline/src/history.rs:526`](../core/dr-pipeline/src/history.rs#L526), [`core/dr-pipeline/src/history.rs:86`](../core/dr-pipeline/src/history.rs#L86), [`core/dr-pipeline/src/state.rs:1`](../core/dr-pipeline/src/state.rs#L1), [`core/dr-pipeline/src/state.rs:75`](../core/dr-pipeline/src/state.rs#L75), [`ui/dr-ui/src/develop.rs:3012`](../ui/dr-ui/src/develop.rs#L3012), [`ui/dr-ui/src/develop.rs:3567`](../ui/dr-ui/src/develop.rs#L3567), [`ui/dr-ui/src/develop.rs:3597`](../ui/dr-ui/src/develop.rs#L3597), [`ui/dr-ui/src/develop.rs:3610`](../ui/dr-ui/src/develop.rs#L3610), [`ui/dr-ui/src/develop.rs:3622`](../ui/dr-ui/src/develop.rs#L3622), [`ui/dr-ui/src/develop.rs:3638`](../ui/dr-ui/src/develop.rs#L3638), [`ui/dr-ui/src/develop.rs:3670`](../ui/dr-ui/src/develop.rs#L3670), [`ui/dr-ui/src/develop.rs:3674`](../ui/dr-ui/src/develop.rs#L3674), [`ui/dr-ui/src/develop.rs:3693`](../ui/dr-ui/src/develop.rs#L3693), [`ui/dr-ui/src/develop.rs:3709`](../ui/dr-ui/src/develop.rs#L3709), [`ui/dr-ui/src/develop.rs:708`](../ui/dr-ui/src/develop.rs#L708), [`ui/dr-ui/src/labels.rs:12`](../ui/dr-ui/src/labels.rs#L12), [`ui/dr-ui/src/labels.rs:215`](../ui/dr-ui/src/labels.rs#L215), [`ui/dr-ui/src/lib.rs:1461`](../ui/dr-ui/src/lib.rs#L1461), [`ui/dr-ui/src/lib.rs:1491`](../ui/dr-ui/src/lib.rs#L1491), [`ui/dr-ui/src/lib.rs:1499`](../ui/dr-ui/src/lib.rs#L1499), [`ui/dr-ui/src/lib.rs:2384`](../ui/dr-ui/src/lib.rs#L2384), [`ui/dr-ui/ui/history.slint:1`](../ui/dr-ui/ui/history.slint#L1) | -| FR-DEV-6 | [`core/dr-pipeline/src/preset.rs:1`](../core/dr-pipeline/src/preset.rs#L1), [`core/dr-types/src/settings.rs:182`](../core/dr-types/src/settings.rs#L182), [`ui/dr-ui/src/develop.rs:3509`](../ui/dr-ui/src/develop.rs#L3509), [`ui/dr-ui/src/develop.rs:3530`](../ui/dr-ui/src/develop.rs#L3530), [`ui/dr-ui/src/lib.rs:1428`](../ui/dr-ui/src/lib.rs#L1428), [`ui/dr-ui/src/library.rs:1787`](../ui/dr-ui/src/library.rs#L1787), [`ui/dr-ui/src/library.rs:459`](../ui/dr-ui/src/library.rs#L459), [`ui/dr-ui/src/library.rs:487`](../ui/dr-ui/src/library.rs#L487), [`ui/dr-ui/src/library_ui.rs:2592`](../ui/dr-ui/src/library_ui.rs#L2592), [`ui/dr-ui/src/library_ui.rs:2992`](../ui/dr-ui/src/library_ui.rs#L2992), [`ui/dr-ui/src/library_ui.rs:472`](../ui/dr-ui/src/library_ui.rs#L472), [`ui/dr-ui/src/presets.rs:1`](../ui/dr-ui/src/presets.rs#L1), [`ui/dr-ui/src/settings_ui.rs:630`](../ui/dr-ui/src/settings_ui.rs#L630), [`ui/dr-ui/ui/adjust.slint:734`](../ui/dr-ui/ui/adjust.slint#L734), [`ui/dr-ui/ui/library.slint:1328`](../ui/dr-ui/ui/library.slint#L1328), [`ui/dr-ui/ui/library.slint:837`](../ui/dr-ui/ui/library.slint#L837), [`ui/dr-ui/ui/library.slint:919`](../ui/dr-ui/ui/library.slint#L919), [`ui/dr-ui/ui/settings.slint:100`](../ui/dr-ui/ui/settings.slint#L100) | +| FR-DEV-6 | [`core/dr-pipeline/src/preset.rs:1`](../core/dr-pipeline/src/preset.rs#L1), [`core/dr-types/src/settings.rs:182`](../core/dr-types/src/settings.rs#L182), [`ui/dr-ui/src/develop.rs:3509`](../ui/dr-ui/src/develop.rs#L3509), [`ui/dr-ui/src/develop.rs:3530`](../ui/dr-ui/src/develop.rs#L3530), [`ui/dr-ui/src/lib.rs:1428`](../ui/dr-ui/src/lib.rs#L1428), [`ui/dr-ui/src/library.rs:1787`](../ui/dr-ui/src/library.rs#L1787), [`ui/dr-ui/src/library.rs:459`](../ui/dr-ui/src/library.rs#L459), [`ui/dr-ui/src/library.rs:487`](../ui/dr-ui/src/library.rs#L487), [`ui/dr-ui/src/library_ui.rs:2592`](../ui/dr-ui/src/library_ui.rs#L2592), [`ui/dr-ui/src/library_ui.rs:2992`](../ui/dr-ui/src/library_ui.rs#L2992), [`ui/dr-ui/src/library_ui.rs:472`](../ui/dr-ui/src/library_ui.rs#L472), [`ui/dr-ui/src/presets.rs:1`](../ui/dr-ui/src/presets.rs#L1), [`ui/dr-ui/src/settings_ui.rs:630`](../ui/dr-ui/src/settings_ui.rs#L630), [`ui/dr-ui/ui/adjust.slint:709`](../ui/dr-ui/ui/adjust.slint#L709), [`ui/dr-ui/ui/library.slint:1328`](../ui/dr-ui/ui/library.slint#L1328), [`ui/dr-ui/ui/library.slint:837`](../ui/dr-ui/ui/library.slint#L837), [`ui/dr-ui/ui/library.slint:919`](../ui/dr-ui/ui/library.slint#L919), [`ui/dr-ui/ui/settings.slint:100`](../ui/dr-ui/ui/settings.slint#L100) | | FR-DEV-7 | [`core/dr-pipeline/src/history.rs:214`](../core/dr-pipeline/src/history.rs#L214), [`core/dr-pipeline/src/history.rs:499`](../core/dr-pipeline/src/history.rs#L499), [`core/dr-pipeline/src/history.rs:526`](../core/dr-pipeline/src/history.rs#L526), [`ui/dr-ui/src/develop.rs:3638`](../ui/dr-ui/src/develop.rs#L3638), [`ui/dr-ui/src/develop.rs:3670`](../ui/dr-ui/src/develop.rs#L3670), [`ui/dr-ui/src/lib.rs:1499`](../ui/dr-ui/src/lib.rs#L1499), [`ui/dr-ui/src/lib.rs:2384`](../ui/dr-ui/src/lib.rs#L2384), [`ui/dr-ui/ui/history.slint:1`](../ui/dr-ui/ui/history.slint#L1) | -| FR-DEV-8 | [`core/dr-gpu/src/detail.rs:387`](../core/dr-gpu/src/detail.rs#L387), [`core/dr-gpu/src/detail.rs:592`](../core/dr-gpu/src/detail.rs#L592), [`core/dr-gpu/tests/detail_instances.rs:1`](../core/dr-gpu/tests/detail_instances.rs#L1), [`core/dr-gpu/tests/spot_removal.rs:1`](../core/dr-gpu/tests/spot_removal.rs#L1), [`core/dr-pipeline/src/detail.rs:410`](../core/dr-pipeline/src/detail.rs#L410), [`core/dr-pipeline/src/detail.rs:434`](../core/dr-pipeline/src/detail.rs#L434), [`core/dr-pipeline/src/detail.rs:469`](../core/dr-pipeline/src/detail.rs#L469), [`core/dr-pipeline/src/detail.rs:555`](../core/dr-pipeline/src/detail.rs#L555), [`core/dr-pipeline/src/graph.rs:113`](../core/dr-pipeline/src/graph.rs#L113), [`core/dr-pipeline/src/graph.rs:191`](../core/dr-pipeline/src/graph.rs#L191), [`core/dr-pipeline/src/graph.rs:685`](../core/dr-pipeline/src/graph.rs#L685), [`core/dr-pipeline/src/operation.rs:330`](../core/dr-pipeline/src/operation.rs#L330), [`core/dr-pipeline/src/operation.rs:554`](../core/dr-pipeline/src/operation.rs#L554), [`core/dr-pipeline/src/sidecar.rs:183`](../core/dr-pipeline/src/sidecar.rs#L183), [`core/dr-pipeline/src/sidecar.rs:352`](../core/dr-pipeline/src/sidecar.rs#L352), [`core/dr-pipeline/src/sidecar.rs:672`](../core/dr-pipeline/src/sidecar.rs#L672), [`core/dr-pipeline/src/sidecar.rs:808`](../core/dr-pipeline/src/sidecar.rs#L808), [`core/dr-pipeline/src/sidecar.rs:862`](../core/dr-pipeline/src/sidecar.rs#L862), [`core/dr-pipeline/src/sidecar.rs:892`](../core/dr-pipeline/src/sidecar.rs#L892), [`core/dr-pipeline/src/spot.rs:115`](../core/dr-pipeline/src/spot.rs#L115), [`core/dr-pipeline/src/spot.rs:151`](../core/dr-pipeline/src/spot.rs#L151), [`core/dr-pipeline/src/spot.rs:1`](../core/dr-pipeline/src/spot.rs#L1), [`core/dr-pipeline/src/spot.rs:207`](../core/dr-pipeline/src/spot.rs#L207), [`core/dr-pipeline/src/spot.rs:387`](../core/dr-pipeline/src/spot.rs#L387), [`core/dr-pipeline/src/spot.rs:472`](../core/dr-pipeline/src/spot.rs#L472), [`core/dr-pipeline/src/spot.rs:582`](../core/dr-pipeline/src/spot.rs#L582), [`core/dr-pipeline/src/spot.rs:673`](../core/dr-pipeline/src/spot.rs#L673), [`core/dr-pipeline/src/state.rs:103`](../core/dr-pipeline/src/state.rs#L103), [`core/dr-pipeline/tests/spot_sidecar.rs:1`](../core/dr-pipeline/tests/spot_sidecar.rs#L1), [`core/dr-pipeline/tests/spots.rs:1`](../core/dr-pipeline/tests/spots.rs#L1), [`ui/dr-ui/src/develop.rs:2242`](../ui/dr-ui/src/develop.rs#L2242), [`ui/dr-ui/src/develop.rs:2280`](../ui/dr-ui/src/develop.rs#L2280), [`ui/dr-ui/src/develop.rs:2345`](../ui/dr-ui/src/develop.rs#L2345), [`ui/dr-ui/src/develop.rs:2428`](../ui/dr-ui/src/develop.rs#L2428), [`ui/dr-ui/src/develop.rs:2442`](../ui/dr-ui/src/develop.rs#L2442), [`ui/dr-ui/src/develop.rs:756`](../ui/dr-ui/src/develop.rs#L756), [`ui/dr-ui/src/labels.rs:52`](../ui/dr-ui/src/labels.rs#L52), [`ui/dr-ui/src/lib.rs:1520`](../ui/dr-ui/src/lib.rs#L1520), [`ui/dr-ui/src/lib.rs:2502`](../ui/dr-ui/src/lib.rs#L2502), [`ui/dr-ui/src/lib.rs:324`](../ui/dr-ui/src/lib.rs#L324), [`ui/dr-ui/src/spots_ui.rs:19`](../ui/dr-ui/src/spots_ui.rs#L19), [`ui/dr-ui/src/spots_ui.rs:1`](../ui/dr-ui/src/spots_ui.rs#L1), [`ui/dr-ui/src/spots_ui.rs:265`](../ui/dr-ui/src/spots_ui.rs#L265), [`ui/dr-ui/ui/adjust.slint:821`](../ui/dr-ui/ui/adjust.slint#L821), [`ui/dr-ui/ui/app.slint:108`](../ui/dr-ui/ui/app.slint#L108), [`ui/dr-ui/ui/app.slint:1713`](../ui/dr-ui/ui/app.slint#L1713), [`ui/dr-ui/ui/app.slint:1888`](../ui/dr-ui/ui/app.slint#L1888), [`ui/dr-ui/ui/app.slint:2222`](../ui/dr-ui/ui/app.slint#L2222), [`ui/dr-ui/ui/spots.slint:180`](../ui/dr-ui/ui/spots.slint#L180), [`ui/dr-ui/ui/spots.slint:48`](../ui/dr-ui/ui/spots.slint#L48), [`ui/dr-ui/ui/spots.slint:5`](../ui/dr-ui/ui/spots.slint#L5) | +| FR-DEV-8 | [`core/dr-gpu/src/detail.rs:387`](../core/dr-gpu/src/detail.rs#L387), [`core/dr-gpu/src/detail.rs:592`](../core/dr-gpu/src/detail.rs#L592), [`core/dr-gpu/tests/detail_instances.rs:1`](../core/dr-gpu/tests/detail_instances.rs#L1), [`core/dr-gpu/tests/spot_removal.rs:1`](../core/dr-gpu/tests/spot_removal.rs#L1), [`core/dr-pipeline/src/detail.rs:410`](../core/dr-pipeline/src/detail.rs#L410), [`core/dr-pipeline/src/detail.rs:434`](../core/dr-pipeline/src/detail.rs#L434), [`core/dr-pipeline/src/detail.rs:469`](../core/dr-pipeline/src/detail.rs#L469), [`core/dr-pipeline/src/detail.rs:555`](../core/dr-pipeline/src/detail.rs#L555), [`core/dr-pipeline/src/graph.rs:113`](../core/dr-pipeline/src/graph.rs#L113), [`core/dr-pipeline/src/graph.rs:191`](../core/dr-pipeline/src/graph.rs#L191), [`core/dr-pipeline/src/graph.rs:685`](../core/dr-pipeline/src/graph.rs#L685), [`core/dr-pipeline/src/operation.rs:330`](../core/dr-pipeline/src/operation.rs#L330), [`core/dr-pipeline/src/operation.rs:554`](../core/dr-pipeline/src/operation.rs#L554), [`core/dr-pipeline/src/sidecar.rs:183`](../core/dr-pipeline/src/sidecar.rs#L183), [`core/dr-pipeline/src/sidecar.rs:352`](../core/dr-pipeline/src/sidecar.rs#L352), [`core/dr-pipeline/src/sidecar.rs:672`](../core/dr-pipeline/src/sidecar.rs#L672), [`core/dr-pipeline/src/sidecar.rs:808`](../core/dr-pipeline/src/sidecar.rs#L808), [`core/dr-pipeline/src/sidecar.rs:862`](../core/dr-pipeline/src/sidecar.rs#L862), [`core/dr-pipeline/src/sidecar.rs:892`](../core/dr-pipeline/src/sidecar.rs#L892), [`core/dr-pipeline/src/spot.rs:115`](../core/dr-pipeline/src/spot.rs#L115), [`core/dr-pipeline/src/spot.rs:151`](../core/dr-pipeline/src/spot.rs#L151), [`core/dr-pipeline/src/spot.rs:1`](../core/dr-pipeline/src/spot.rs#L1), [`core/dr-pipeline/src/spot.rs:207`](../core/dr-pipeline/src/spot.rs#L207), [`core/dr-pipeline/src/spot.rs:387`](../core/dr-pipeline/src/spot.rs#L387), [`core/dr-pipeline/src/spot.rs:472`](../core/dr-pipeline/src/spot.rs#L472), [`core/dr-pipeline/src/spot.rs:582`](../core/dr-pipeline/src/spot.rs#L582), [`core/dr-pipeline/src/spot.rs:673`](../core/dr-pipeline/src/spot.rs#L673), [`core/dr-pipeline/src/state.rs:103`](../core/dr-pipeline/src/state.rs#L103), [`core/dr-pipeline/tests/spot_sidecar.rs:1`](../core/dr-pipeline/tests/spot_sidecar.rs#L1), [`core/dr-pipeline/tests/spots.rs:1`](../core/dr-pipeline/tests/spots.rs#L1), [`ui/dr-ui/src/develop.rs:2242`](../ui/dr-ui/src/develop.rs#L2242), [`ui/dr-ui/src/develop.rs:2280`](../ui/dr-ui/src/develop.rs#L2280), [`ui/dr-ui/src/develop.rs:2345`](../ui/dr-ui/src/develop.rs#L2345), [`ui/dr-ui/src/develop.rs:2428`](../ui/dr-ui/src/develop.rs#L2428), [`ui/dr-ui/src/develop.rs:2442`](../ui/dr-ui/src/develop.rs#L2442), [`ui/dr-ui/src/develop.rs:756`](../ui/dr-ui/src/develop.rs#L756), [`ui/dr-ui/src/labels.rs:52`](../ui/dr-ui/src/labels.rs#L52), [`ui/dr-ui/src/lib.rs:1520`](../ui/dr-ui/src/lib.rs#L1520), [`ui/dr-ui/src/lib.rs:2502`](../ui/dr-ui/src/lib.rs#L2502), [`ui/dr-ui/src/lib.rs:324`](../ui/dr-ui/src/lib.rs#L324), [`ui/dr-ui/src/spots_ui.rs:19`](../ui/dr-ui/src/spots_ui.rs#L19), [`ui/dr-ui/src/spots_ui.rs:1`](../ui/dr-ui/src/spots_ui.rs#L1), [`ui/dr-ui/src/spots_ui.rs:265`](../ui/dr-ui/src/spots_ui.rs#L265), [`ui/dr-ui/ui/adjust.slint:796`](../ui/dr-ui/ui/adjust.slint#L796), [`ui/dr-ui/ui/app.slint:108`](../ui/dr-ui/ui/app.slint#L108), [`ui/dr-ui/ui/app.slint:1713`](../ui/dr-ui/ui/app.slint#L1713), [`ui/dr-ui/ui/app.slint:1888`](../ui/dr-ui/ui/app.slint#L1888), [`ui/dr-ui/ui/app.slint:2222`](../ui/dr-ui/ui/app.slint#L2222), [`ui/dr-ui/ui/spots.slint:180`](../ui/dr-ui/ui/spots.slint#L180), [`ui/dr-ui/ui/spots.slint:48`](../ui/dr-ui/ui/spots.slint#L48), [`ui/dr-ui/ui/spots.slint:5`](../ui/dr-ui/ui/spots.slint#L5) | | FR-DSP-1 | [`core/dr-gpu/src/adjust.rs:2088`](../core/dr-gpu/src/adjust.rs#L2088), [`core/dr-gpu/src/adjust.rs:2165`](../core/dr-gpu/src/adjust.rs#L2165), [`core/dr-gpu/src/adjust.rs:2250`](../core/dr-gpu/src/adjust.rs#L2250), [`core/dr-gpu/src/adjust.rs:54`](../core/dr-gpu/src/adjust.rs#L54), [`core/dr-gpu/src/adjust.rs:770`](../core/dr-gpu/src/adjust.rs#L770), [`core/dr-gpu/src/lib.rs:156`](../core/dr-gpu/src/lib.rs#L156), [`core/dr-gpu/src/lib.rs:176`](../core/dr-gpu/src/lib.rs#L176), [`core/dr-gpu/src/lib.rs:54`](../core/dr-gpu/src/lib.rs#L54), [`core/dr-gpu/src/lib.rs:77`](../core/dr-gpu/src/lib.rs#L77), [`core/dr-gpu/tests/capture_sharpen.rs:200`](../core/dr-gpu/tests/capture_sharpen.rs#L200), [`core/dr-gpu/tests/detail_stage.rs:328`](../core/dr-gpu/tests/detail_stage.rs#L328), [`core/dr-gpu/tests/local_contrast.rs:264`](../core/dr-gpu/tests/local_contrast.rs#L264), [`core/dr-gpu/tests/noise_reduction.rs:378`](../core/dr-gpu/tests/noise_reduction.rs#L378), [`core/dr-pipeline/src/detail.rs:136`](../core/dr-pipeline/src/detail.rs#L136), [`core/dr-pipeline/src/detail.rs:524`](../core/dr-pipeline/src/detail.rs#L524), [`core/dr-pipeline/src/graph.rs:547`](../core/dr-pipeline/src/graph.rs#L547), [`core/dr-pipeline/src/graph.rs:577`](../core/dr-pipeline/src/graph.rs#L577), [`core/dr-pipeline/src/ops/capture_sharpen.rs:1`](../core/dr-pipeline/src/ops/capture_sharpen.rs#L1), [`core/dr-pipeline/src/ops/capture_sharpen.rs:659`](../core/dr-pipeline/src/ops/capture_sharpen.rs#L659), [`core/dr-pipeline/src/ops/local_contrast.rs:1`](../core/dr-pipeline/src/ops/local_contrast.rs#L1), [`core/dr-pipeline/src/ops/local_contrast.rs:971`](../core/dr-pipeline/src/ops/local_contrast.rs#L971), [`core/dr-pipeline/src/ops/noise_reduction.rs:700`](../core/dr-pipeline/src/ops/noise_reduction.rs#L700), [`core/dr-pipeline/src/spot.rs:673`](../core/dr-pipeline/src/spot.rs#L673), [`ui/dr-ui/src/develop.rs:2766`](../ui/dr-ui/src/develop.rs#L2766), [`ui/dr-ui/src/develop.rs:3964`](../ui/dr-ui/src/develop.rs#L3964), [`ui/dr-ui/src/develop.rs:4447`](../ui/dr-ui/src/develop.rs#L4447), [`ui/dr-ui/src/develop.rs:4481`](../ui/dr-ui/src/develop.rs#L4481), [`ui/dr-ui/src/lib.rs:72`](../ui/dr-ui/src/lib.rs#L72), [`ui/dr-ui/src/lib.rs:809`](../ui/dr-ui/src/lib.rs#L809), [`ui/dr-ui/src/lib.rs:868`](../ui/dr-ui/src/lib.rs#L868) | | FR-DSP-3 | [`core/dr-gpu/tests/frame_budget.rs:101`](../core/dr-gpu/tests/frame_budget.rs#L101), [`core/dr-gpu/tests/local_contrast.rs:329`](../core/dr-gpu/tests/local_contrast.rs#L329), [`core/dr-pipeline/src/ops/local_contrast.rs:447`](../core/dr-pipeline/src/ops/local_contrast.rs#L447) | | FR-DSP-5 | [`core/dr-gpu/tests/frame_budget.rs:101`](../core/dr-gpu/tests/frame_budget.rs#L101), [`core/dr-gpu/tests/zoom_resolution.rs:135`](../core/dr-gpu/tests/zoom_resolution.rs#L135), [`core/dr-gpu/tests/zoom_resolution.rs:166`](../core/dr-gpu/tests/zoom_resolution.rs#L166), [`core/dr-gpu/tests/zoom_resolution.rs:1`](../core/dr-gpu/tests/zoom_resolution.rs#L1), [`core/dr-gpu/tests/zoom_resolution.rs:216`](../core/dr-gpu/tests/zoom_resolution.rs#L216) | @@ -113,7 +113,7 @@ _None._ | FR-RAW-4 | [`core/dr-decode/src/error.rs:1`](../core/dr-decode/src/error.rs#L1), [`ui/dr-ui/src/lib.rs:204`](../ui/dr-ui/src/lib.rs#L204) | | FR-RAW-5 | [`core/dr-decode/src/lib.rs:167`](../core/dr-decode/src/lib.rs#L167), [`core/dr-gpu/src/demosaic.rs:34`](../core/dr-gpu/src/demosaic.rs#L34), [`core/dr-gpu/src/demosaic.rs:602`](../core/dr-gpu/src/demosaic.rs#L602), [`core/dr-gpu/src/demosaic.rs:681`](../core/dr-gpu/src/demosaic.rs#L681), [`core/dr-gpu/src/demosaic.rs:805`](../core/dr-gpu/src/demosaic.rs#L805) | | FR-UI-1 | [`ui/dr-ui/src/lib.rs:2966`](../ui/dr-ui/src/lib.rs#L2966), [`ui/dr-ui/src/lib.rs:80`](../ui/dr-ui/src/lib.rs#L80), [`ui/dr-ui/src/masks_ui.rs:816`](../ui/dr-ui/src/masks_ui.rs#L816), [`ui/dr-ui/ui/identity.slint:164`](../ui/dr-ui/ui/identity.slint#L164), [`ui/dr-ui/ui/library.slint:1046`](../ui/dr-ui/ui/library.slint#L1046) | -| FR-UI-2 | [`ui/dr-ui/src/collections_ui.rs:1005`](../ui/dr-ui/src/collections_ui.rs#L1005), [`ui/dr-ui/src/collections_ui.rs:118`](../ui/dr-ui/src/collections_ui.rs#L118), [`ui/dr-ui/src/collections_ui.rs:1488`](../ui/dr-ui/src/collections_ui.rs#L1488), [`ui/dr-ui/src/collections_ui.rs:1502`](../ui/dr-ui/src/collections_ui.rs#L1502), [`ui/dr-ui/src/collections_ui.rs:1548`](../ui/dr-ui/src/collections_ui.rs#L1548), [`ui/dr-ui/src/collections_ui.rs:159`](../ui/dr-ui/src/collections_ui.rs#L159), [`ui/dr-ui/src/collections_ui.rs:1646`](../ui/dr-ui/src/collections_ui.rs#L1646), [`ui/dr-ui/src/collections_ui.rs:485`](../ui/dr-ui/src/collections_ui.rs#L485), [`ui/dr-ui/src/collections_ui.rs:514`](../ui/dr-ui/src/collections_ui.rs#L514), [`ui/dr-ui/src/collections_ui.rs:995`](../ui/dr-ui/src/collections_ui.rs#L995), [`ui/dr-ui/src/lib.rs:80`](../ui/dr-ui/src/lib.rs#L80), [`ui/dr-ui/src/lib.rs:87`](../ui/dr-ui/src/lib.rs#L87), [`ui/dr-ui/src/library_ui.rs:292`](../ui/dr-ui/src/library_ui.rs#L292), [`ui/dr-ui/src/library_ui.rs:5203`](../ui/dr-ui/src/library_ui.rs#L5203), [`ui/dr-ui/src/library_ui.rs:5348`](../ui/dr-ui/src/library_ui.rs#L5348), [`ui/dr-ui/src/library_ui.rs:6479`](../ui/dr-ui/src/library_ui.rs#L6479), [`ui/dr-ui/ui/adjust.slint:1083`](../ui/dr-ui/ui/adjust.slint#L1083), [`ui/dr-ui/ui/adjust.slint:538`](../ui/dr-ui/ui/adjust.slint#L538), [`ui/dr-ui/ui/adjust.slint:762`](../ui/dr-ui/ui/adjust.slint#L762), [`ui/dr-ui/ui/app.slint:1994`](../ui/dr-ui/ui/app.slint#L1994), [`ui/dr-ui/ui/app.slint:492`](../ui/dr-ui/ui/app.slint#L492), [`ui/dr-ui/ui/app.slint:499`](../ui/dr-ui/ui/app.slint#L499), [`ui/dr-ui/ui/app.slint:54`](../ui/dr-ui/ui/app.slint#L54), [`ui/dr-ui/ui/app.slint:799`](../ui/dr-ui/ui/app.slint#L799), [`ui/dr-ui/ui/develop.slint:223`](../ui/dr-ui/ui/develop.slint#L223), [`ui/dr-ui/ui/histogram.slint:127`](../ui/dr-ui/ui/histogram.slint#L127), [`ui/dr-ui/ui/history.slint:118`](../ui/dr-ui/ui/history.slint#L118), [`ui/dr-ui/ui/library.slint:1202`](../ui/dr-ui/ui/library.slint#L1202), [`ui/dr-ui/ui/library.slint:1209`](../ui/dr-ui/ui/library.slint#L1209), [`ui/dr-ui/ui/library.slint:1215`](../ui/dr-ui/ui/library.slint#L1215), [`ui/dr-ui/ui/library.slint:2314`](../ui/dr-ui/ui/library.slint#L2314), [`ui/dr-ui/ui/library.slint:829`](../ui/dr-ui/ui/library.slint#L829), [`ui/dr-ui/ui/library.slint:879`](../ui/dr-ui/ui/library.slint#L879), [`ui/dr-ui/ui/masks.slint:304`](../ui/dr-ui/ui/masks.slint#L304), [`ui/dr-ui/ui/settings.slint:106`](../ui/dr-ui/ui/settings.slint#L106), [`ui/dr-ui/ui/spots.slint:88`](../ui/dr-ui/ui/spots.slint#L88) | +| FR-UI-2 | [`ui/dr-ui/src/collections_ui.rs:1005`](../ui/dr-ui/src/collections_ui.rs#L1005), [`ui/dr-ui/src/collections_ui.rs:118`](../ui/dr-ui/src/collections_ui.rs#L118), [`ui/dr-ui/src/collections_ui.rs:1488`](../ui/dr-ui/src/collections_ui.rs#L1488), [`ui/dr-ui/src/collections_ui.rs:1502`](../ui/dr-ui/src/collections_ui.rs#L1502), [`ui/dr-ui/src/collections_ui.rs:1548`](../ui/dr-ui/src/collections_ui.rs#L1548), [`ui/dr-ui/src/collections_ui.rs:159`](../ui/dr-ui/src/collections_ui.rs#L159), [`ui/dr-ui/src/collections_ui.rs:1646`](../ui/dr-ui/src/collections_ui.rs#L1646), [`ui/dr-ui/src/collections_ui.rs:485`](../ui/dr-ui/src/collections_ui.rs#L485), [`ui/dr-ui/src/collections_ui.rs:514`](../ui/dr-ui/src/collections_ui.rs#L514), [`ui/dr-ui/src/collections_ui.rs:995`](../ui/dr-ui/src/collections_ui.rs#L995), [`ui/dr-ui/src/lib.rs:80`](../ui/dr-ui/src/lib.rs#L80), [`ui/dr-ui/src/lib.rs:87`](../ui/dr-ui/src/lib.rs#L87), [`ui/dr-ui/src/library_ui.rs:292`](../ui/dr-ui/src/library_ui.rs#L292), [`ui/dr-ui/src/library_ui.rs:5203`](../ui/dr-ui/src/library_ui.rs#L5203), [`ui/dr-ui/src/library_ui.rs:5348`](../ui/dr-ui/src/library_ui.rs#L5348), [`ui/dr-ui/src/library_ui.rs:6479`](../ui/dr-ui/src/library_ui.rs#L6479), [`ui/dr-ui/ui/adjust.slint:1058`](../ui/dr-ui/ui/adjust.slint#L1058), [`ui/dr-ui/ui/adjust.slint:544`](../ui/dr-ui/ui/adjust.slint#L544), [`ui/dr-ui/ui/adjust.slint:737`](../ui/dr-ui/ui/adjust.slint#L737), [`ui/dr-ui/ui/app.slint:1994`](../ui/dr-ui/ui/app.slint#L1994), [`ui/dr-ui/ui/app.slint:492`](../ui/dr-ui/ui/app.slint#L492), [`ui/dr-ui/ui/app.slint:499`](../ui/dr-ui/ui/app.slint#L499), [`ui/dr-ui/ui/app.slint:54`](../ui/dr-ui/ui/app.slint#L54), [`ui/dr-ui/ui/app.slint:799`](../ui/dr-ui/ui/app.slint#L799), [`ui/dr-ui/ui/controls.slint:474`](../ui/dr-ui/ui/controls.slint#L474), [`ui/dr-ui/ui/develop.slint:223`](../ui/dr-ui/ui/develop.slint#L223), [`ui/dr-ui/ui/histogram.slint:127`](../ui/dr-ui/ui/histogram.slint#L127), [`ui/dr-ui/ui/history.slint:118`](../ui/dr-ui/ui/history.slint#L118), [`ui/dr-ui/ui/library.slint:1202`](../ui/dr-ui/ui/library.slint#L1202), [`ui/dr-ui/ui/library.slint:1209`](../ui/dr-ui/ui/library.slint#L1209), [`ui/dr-ui/ui/library.slint:1215`](../ui/dr-ui/ui/library.slint#L1215), [`ui/dr-ui/ui/library.slint:2314`](../ui/dr-ui/ui/library.slint#L2314), [`ui/dr-ui/ui/library.slint:829`](../ui/dr-ui/ui/library.slint#L829), [`ui/dr-ui/ui/library.slint:879`](../ui/dr-ui/ui/library.slint#L879), [`ui/dr-ui/ui/masks.slint:304`](../ui/dr-ui/ui/masks.slint#L304), [`ui/dr-ui/ui/settings.slint:106`](../ui/dr-ui/ui/settings.slint#L106), [`ui/dr-ui/ui/spots.slint:88`](../ui/dr-ui/ui/spots.slint#L88) | | FR-UI-3 | [`ui/dr-ui/src/develop.rs:2171`](../ui/dr-ui/src/develop.rs#L2171), [`ui/dr-ui/src/develop.rs:2280`](../ui/dr-ui/src/develop.rs#L2280), [`ui/dr-ui/src/library_ui.rs:4387`](../ui/dr-ui/src/library_ui.rs#L4387), [`ui/dr-ui/src/masks_ui.rs:218`](../ui/dr-ui/src/masks_ui.rs#L218), [`ui/dr-ui/src/masks_ui.rs:908`](../ui/dr-ui/src/masks_ui.rs#L908), [`ui/dr-ui/src/masks_ui.rs:930`](../ui/dr-ui/src/masks_ui.rs#L930), [`ui/dr-ui/src/spots_ui.rs:19`](../ui/dr-ui/src/spots_ui.rs#L19), [`ui/dr-ui/ui/app.slint:1810`](../ui/dr-ui/ui/app.slint#L1810), [`ui/dr-ui/ui/collections.slint:4`](../ui/dr-ui/ui/collections.slint#L4), [`ui/dr-ui/ui/collections.slint:682`](../ui/dr-ui/ui/collections.slint#L682), [`ui/dr-ui/ui/masks.slint:490`](../ui/dr-ui/ui/masks.slint#L490) | | FR-UI-4 | [`ui/dr-ui/src/collections_ui.rs:1005`](../ui/dr-ui/src/collections_ui.rs#L1005), [`ui/dr-ui/src/collections_ui.rs:118`](../ui/dr-ui/src/collections_ui.rs#L118), [`ui/dr-ui/src/collections_ui.rs:131`](../ui/dr-ui/src/collections_ui.rs#L131), [`ui/dr-ui/src/collections_ui.rs:1488`](../ui/dr-ui/src/collections_ui.rs#L1488), [`ui/dr-ui/src/collections_ui.rs:1502`](../ui/dr-ui/src/collections_ui.rs#L1502), [`ui/dr-ui/src/collections_ui.rs:1548`](../ui/dr-ui/src/collections_ui.rs#L1548), [`ui/dr-ui/src/collections_ui.rs:159`](../ui/dr-ui/src/collections_ui.rs#L159), [`ui/dr-ui/src/collections_ui.rs:1646`](../ui/dr-ui/src/collections_ui.rs#L1646), [`ui/dr-ui/src/collections_ui.rs:1673`](../ui/dr-ui/src/collections_ui.rs#L1673), [`ui/dr-ui/src/collections_ui.rs:485`](../ui/dr-ui/src/collections_ui.rs#L485), [`ui/dr-ui/src/collections_ui.rs:514`](../ui/dr-ui/src/collections_ui.rs#L514), [`ui/dr-ui/src/collections_ui.rs:582`](../ui/dr-ui/src/collections_ui.rs#L582), [`ui/dr-ui/src/collections_ui.rs:995`](../ui/dr-ui/src/collections_ui.rs#L995), [`ui/dr-ui/src/library_ui.rs:4387`](../ui/dr-ui/src/library_ui.rs#L4387), [`ui/dr-ui/src/library_ui.rs:4432`](../ui/dr-ui/src/library_ui.rs#L4432), [`ui/dr-ui/src/library_ui.rs:4535`](../ui/dr-ui/src/library_ui.rs#L4535), [`ui/dr-ui/src/library_ui.rs:4563`](../ui/dr-ui/src/library_ui.rs#L4563), [`ui/dr-ui/src/library_ui.rs:5336`](../ui/dr-ui/src/library_ui.rs#L5336), [`ui/dr-ui/src/library_ui.rs:5348`](../ui/dr-ui/src/library_ui.rs#L5348), [`ui/dr-ui/ui/app.slint:1650`](../ui/dr-ui/ui/app.slint#L1650), [`ui/dr-ui/ui/app.slint:468`](../ui/dr-ui/ui/app.slint#L468), [`ui/dr-ui/ui/app.slint:499`](../ui/dr-ui/ui/app.slint#L499), [`ui/dr-ui/ui/library.slint:1202`](../ui/dr-ui/ui/library.slint#L1202), [`ui/dr-ui/ui/library.slint:1209`](../ui/dr-ui/ui/library.slint#L1209), [`ui/dr-ui/ui/library.slint:1215`](../ui/dr-ui/ui/library.slint#L1215), [`ui/dr-ui/ui/library.slint:2314`](../ui/dr-ui/ui/library.slint#L2314), [`ui/dr-ui/ui/library.slint:829`](../ui/dr-ui/ui/library.slint#L829), [`ui/dr-ui/ui/library.slint:879`](../ui/dr-ui/ui/library.slint#L879), [`ui/dr-ui/ui/library.slint:898`](../ui/dr-ui/ui/library.slint#L898) | | FR-UI-5 | [`ui/dr-ui/src/collections_ui.rs:1`](../ui/dr-ui/src/collections_ui.rs#L1), [`ui/dr-ui/src/lib.rs:2467`](../ui/dr-ui/src/lib.rs#L2467), [`ui/dr-ui/src/lib.rs:3005`](../ui/dr-ui/src/lib.rs#L3005), [`ui/dr-ui/src/lib.rs:3190`](../ui/dr-ui/src/lib.rs#L3190), [`ui/dr-ui/src/masks_ui.rs:863`](../ui/dr-ui/src/masks_ui.rs#L863), [`ui/dr-ui/ui/app.slint:89`](../ui/dr-ui/ui/app.slint#L89), [`ui/dr-ui/ui/collections.slint:4`](../ui/dr-ui/ui/collections.slint#L4) | diff --git a/ui/dr-ui/ui/adjust.slint b/ui/dr-ui/ui/adjust.slint index b630d11..e96eed9 100644 --- a/ui/dr-ui/ui/adjust.slint +++ b/ui/dr-ui/ui/adjust.slint @@ -9,7 +9,7 @@ import { Theme } from "theme.slint"; import { PanelHeading, Label, Value, Caption, Button, IconButton, Swatch } from "widgets.slint"; -import { SliderTrack, ControlRow, CurveEditor, Segmented, ChoiceChip } from "controls.slint"; +import { SliderTrack, ControlRow, CurveEditor, Segmented, ChoiceChip, ChipGrid } from "controls.slint"; // One parameter, flattened for Slint's model system. // @@ -434,6 +434,11 @@ component ParamControl inherits Rectangle { label: root.data.param-label; options: root.data.choices; selected: Math.round(root.data.value); + // Wrapped, because this column's width is the largest any panel + // asks for and an operation may declare as many choices as it + // likes. `film_sim`'s six film formats laid in one row came to + // 414px, which set the width of the sidebar on every screen. + columns: 3; picked(i) => { root.param-changed(root.data.op-index, root.data.param-index, i); } @@ -457,6 +462,7 @@ component ParamControl inherits Rectangle { // draws: a curve row heads no group, so without this the plot // would sit in the panel unlabelled. label: root.data.op-label; + columns: 3; options: root.curve-channels; selected: root.curve-channel; picked(i) => { root.curve-channel-picked(i); } @@ -647,45 +653,14 @@ export component GeometryPanel inherits Rectangle { // for the same reason. if root.cropping: Label { text: "Ratio"; body: true; } - // **The chips are placed, not laid out, and that is not a - // shortcut.** Slint has no wrapping layout, and a `for` inside a - // `GridLayout` compiles and then fails at run time — - // `RepeatedItemTree::grid_layout_input_data() not implemented`, - // printed once per frame while every chip piles into a single row - // that runs off the panel. A `HorizontalLayout` is worse still: six - // chips side by side need over 400px, and this column's width is - // the largest any panel declares, so it would widen every other - // panel in the application to fit a control that is on screen only - // while cropping. - // - // So the grid is arithmetic over the index. It costs the layout - // engine nothing, it wraps a seventh ratio onto a third row by - // itself, and — because a bare `Rectangle` declares no preferred - // width — it takes whatever width the column already has instead - // of setting it. - if root.cropping: Rectangle { - property columns: 3; - property rows: ceil(root.aspects.length / self.columns); - property pitch: Theme.control-height + Theme.gap-sm; - property chip-width: - (self.width - (self.columns - 1) * Theme.gap-sm) / self.columns; - - // A floor, so a narrow window shrinks the column rather than - // the chips: three chips at the width `ChoiceChip` calls - // comfortable is what this row is for. - min-width: self.columns * 64px + (self.columns - 1) * Theme.gap-sm; - height: self.rows * self.pitch - Theme.gap-sm; - - for name[i] in root.aspects: ChoiceChip { - x: mod(i, parent.columns) * (parent.chip-width + Theme.gap-sm); - y: floor(i / parent.columns) * parent.pitch; - width: parent.chip-width; - height: Theme.control-height; - label: name; - selected: i == root.aspect; - enabled: root.enabled; - clicked => { root.aspect-picked(i); } - } + // The same wrapping grid the generated enum rows use, for the + // same reason: six chips in a row would be 414px of chips setting + // the width of a column that is meant to be 280. + if root.cropping: ChipGrid { + options: root.aspects; + selected: root.aspect; + enabled: root.enabled; + picked(i) => { root.aspect-picked(i); } } // One chip, lit when the ratio is standing on its short edge, @@ -705,7 +680,7 @@ export component GeometryPanel inherits Rectangle { ChoiceChip { x: 0; - width: (parent.width - 2 * Theme.gap-sm) / 3; + width: 88px; height: 100%; label: "Portrait"; selected: root.portrait; diff --git a/ui/dr-ui/ui/controls.slint b/ui/dr-ui/ui/controls.slint index f095afb..cee8045 100644 --- a/ui/dr-ui/ui/controls.slint +++ b/ui/dr-ui/ui/controls.slint @@ -471,6 +471,64 @@ export component FieldRow inherits HorizontalLayout { } } +// TRACES: FR-UI-2 +// A block of chips that wraps, laid out by arithmetic rather than by a layout. +// +// **Slint has no wrapping layout, and a `HorizontalLayout` of chips is a +// hazard in a narrow column.** Chips carry a comfortable minimum width, so a +// row of them reports that minimum times their count as the width it needs — +// and in the develop column, where every panel's declared width is `max`ed +// into one number, a single six-choice parameter silently sets the width of +// the whole application's sidebar. `film_sim`'s six film formats did exactly +// that: 414px of chips holding a column open that documents itself, in a +// dozen comments, as 280px wide. +// +// A `GridLayout` is not the alternative — a `for` inside one compiles and then +// fails at run time with `RepeatedItemTree::grid_layout_input_data() not +// implemented`, piling every chip into a single row. So the grid is index +// arithmetic inside a plain `Rectangle`: it costs the layout engine nothing, +// it wraps a seventh choice onto a third row by itself, and it declares a +// width that depends on the column count rather than on the choice count. +// +// **The chip width is fixed, not a share of the container's.** Dividing +// `self.width` looks right and clips: the develop column sets its width to +// `min(panel-max-width, content-width)` with `clip: true`, so when the policy +// bites, `self.width` here is the width that was *asked for* and the visible +// column is narrower. +export component ChipGrid inherits Rectangle { + in property <[string]> options; + in property selected: -1; + in property enabled: true; + /// How many chips to a row. Three is what fits the narrowest column the + /// application supports. + in property columns: 3; + /// Comfortable for a one-word label at `Theme.text`, and three of them + /// plus their gaps fit a 280px column. + in property chip-width: 88px; + + callback picked(int); + + property rows: max(1, ceil(root.options.length / max(1, root.columns))); + property pitch: Theme.control-height + Theme.gap-sm; + + // Stated so a column measuring itself counts this block, and counts it at + // the width it will actually draw at rather than at the width a single row + // of every choice would need. + min-width: root.columns * root.chip-width + (root.columns - 1) * Theme.gap-sm; + height: root.rows * root.pitch - Theme.gap-sm; + + for option[i] in root.options: ChoiceChip { + x: mod(i, root.columns) * (root.chip-width + Theme.gap-sm); + y: floor(i / root.columns) * root.pitch; + width: root.chip-width; + height: Theme.control-height; + label: option; + selected: i == root.selected; + enabled: root.enabled; + clicked => { root.picked(i); } + } +} + // A labelled row of chips: one choice out of a short list. // // Not a dropdown. Every choice set on the settings page is short and the @@ -486,6 +544,15 @@ export component Segmented inherits VerticalLayout { in property <[string]> options; in property selected: 0; in property enabled: true; + /// Wrap onto this many chips per row instead of laying them all in one. + /// + /// Zero — one row, however many chips — is right for the settings page, + /// which is a full-width page and where reading the alternatives side by + /// side is the whole argument for chips over a dropdown. The develop + /// column is the opposite case: it is narrow, its width is the largest any + /// panel asks for, and a row of six chips there sets the width of the + /// sidebar for every other panel. See `ChipGrid`. + in property columns: 0; callback picked(int); @@ -493,7 +560,7 @@ export component Segmented inherits VerticalLayout { FieldRow { label: root.label; hint: root.hint; } - HorizontalLayout { + if root.columns <= 0: HorizontalLayout { spacing: Theme.gap-sm; alignment: start; @@ -504,6 +571,14 @@ export component Segmented inherits VerticalLayout { clicked => { root.picked(i); } } } + + if root.columns > 0: ChipGrid { + options: root.options; + selected: root.selected; + enabled: root.enabled; + columns: root.columns; + picked(i) => { root.picked(i); } + } } // A text entry with its label above and an optional unit after it.