diff --git a/docs/dev/traceability.md b/docs/dev/traceability.md index 8f5cde6..3a9c5ed 100644 --- a/docs/dev/traceability.md +++ b/docs/dev/traceability.md @@ -50,7 +50,7 @@ A tag naming an ID `requirements.md` does not define — what renumbering produc | FR-CAT-8 | [`core/dr-catalog/src/schema.rs:740`](../../core/dr-catalog/src/schema.rs#L740), [`core/dr-pipeline/src/coverage.rs:1`](../../core/dr-pipeline/src/coverage.rs#L1), [`core/dr-pipeline/src/graph.rs:587`](../../core/dr-pipeline/src/graph.rs#L587), [`core/dr-pipeline/src/graph.rs:640`](../../core/dr-pipeline/src/graph.rs#L640), [`core/dr-pipeline/src/ops/curve.rs:137`](../../core/dr-pipeline/src/ops/curve.rs#L137), [`core/dr-pipeline/src/ops/curve.rs:656`](../../core/dr-pipeline/src/ops/curve.rs#L656), [`core/dr-pipeline/src/sidecar.rs:1400`](../../core/dr-pipeline/src/sidecar.rs#L1400), [`core/dr-pipeline/src/sidecar.rs:2232`](../../core/dr-pipeline/src/sidecar.rs#L2232), [`core/dr-pipeline/src/sidecar.rs:96`](../../core/dr-pipeline/src/sidecar.rs#L96), [`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), [`core/dr-pipeline/tests/tone_curve.rs:34`](../../core/dr-pipeline/tests/tone_curve.rs#L34), [`core/dr-sync/src/scan.rs:31`](../../core/dr-sync/src/scan.rs#L31), [`core/dr-sync/src/scan.rs:56`](../../core/dr-sync/src/scan.rs#L56), [`core/dr-sync/src/scan.rs:926`](../../core/dr-sync/src/scan.rs#L926), [`ui/dr-ui/src/develop.rs:2155`](../../ui/dr-ui/src/develop.rs#L2155), [`ui/dr-ui/src/develop.rs:5463`](../../ui/dr-ui/src/develop.rs#L5463), [`ui/dr-ui/src/develop.rs:5492`](../../ui/dr-ui/src/develop.rs#L5492), [`ui/dr-ui/src/develop.rs:7057`](../../ui/dr-ui/src/develop.rs#L7057), [`ui/dr-ui/src/develop.rs:7111`](../../ui/dr-ui/src/develop.rs#L7111), [`ui/dr-ui/src/develop.rs:7213`](../../ui/dr-ui/src/develop.rs#L7213), [`ui/dr-ui/src/export.rs:812`](../../ui/dr-ui/src/export.rs#L812), [`ui/dr-ui/src/lib.rs:1330`](../../ui/dr-ui/src/lib.rs#L1330), [`ui/dr-ui/src/lib.rs:1888`](../../ui/dr-ui/src/lib.rs#L1888), [`ui/dr-ui/src/lib.rs:2457`](../../ui/dr-ui/src/lib.rs#L2457), [`ui/dr-ui/src/lib.rs:2604`](../../ui/dr-ui/src/lib.rs#L2604), [`ui/dr-ui/src/lib.rs:757`](../../ui/dr-ui/src/lib.rs#L757), [`ui/dr-ui/src/library.rs:1455`](../../ui/dr-ui/src/library.rs#L1455), [`ui/dr-ui/src/library.rs:1490`](../../ui/dr-ui/src/library.rs#L1490), [`ui/dr-ui/src/library.rs:2491`](../../ui/dr-ui/src/library.rs#L2491), [`ui/dr-ui/src/library.rs:564`](../../ui/dr-ui/src/library.rs#L564), [`ui/dr-ui/src/library.rs:616`](../../ui/dr-ui/src/library.rs#L616), [`ui/dr-ui/src/library.rs:653`](../../ui/dr-ui/src/library.rs#L653), [`ui/dr-ui/src/library.rs:7386`](../../ui/dr-ui/src/library.rs#L7386), [`ui/dr-ui/src/library.rs:73`](../../ui/dr-ui/src/library.rs#L73), [`ui/dr-ui/src/library.rs:926`](../../ui/dr-ui/src/library.rs#L926), [`ui/dr-ui/src/library_ui.rs:1339`](../../ui/dr-ui/src/library_ui.rs#L1339), [`ui/dr-ui/src/library_ui.rs:6350`](../../ui/dr-ui/src/library_ui.rs#L6350), [`ui/dr-ui/src/sidecar_cache.rs:1`](../../ui/dr-ui/src/sidecar_cache.rs#L1) | | FR-CAT-9 | [`core/dr-catalog/src/cache.rs:1`](../../core/dr-catalog/src/cache.rs#L1), [`core/dr-catalog/src/scan.rs:1`](../../core/dr-catalog/src/scan.rs#L1), [`core/dr-catalog/src/schema.rs:1182`](../../core/dr-catalog/src/schema.rs#L1182), [`core/dr-catalog/src/walk.rs:1022`](../../core/dr-catalog/src/walk.rs#L1022), [`core/dr-catalog/src/walk.rs:162`](../../core/dr-catalog/src/walk.rs#L162), [`core/dr-catalog/src/walk.rs:1`](../../core/dr-catalog/src/walk.rs#L1), [`core/dr-catalog/src/walk.rs:435`](../../core/dr-catalog/src/walk.rs#L435), [`core/dr-catalog/src/walk.rs:728`](../../core/dr-catalog/src/walk.rs#L728), [`core/dr-sync-nextcloud/src/desktop_client.rs:35`](../../core/dr-sync-nextcloud/src/desktop_client.rs#L35), [`core/dr-sync/src/error.rs:113`](../../core/dr-sync/src/error.rs#L113), [`core/dr-sync/src/reachability.rs:1`](../../core/dr-sync/src/reachability.rs#L1), [`core/dr-sync/src/scan.rs:211`](../../core/dr-sync/src/scan.rs#L211), [`core/dr-sync/src/scan.rs:519`](../../core/dr-sync/src/scan.rs#L519), [`core/dr-types/src/lib.rs:122`](../../core/dr-types/src/lib.rs#L122), [`ui/dr-ui/src/develop.rs:4752`](../../ui/dr-ui/src/develop.rs#L4752), [`ui/dr-ui/src/develop.rs:4795`](../../ui/dr-ui/src/develop.rs#L4795), [`ui/dr-ui/src/library.rs:1355`](../../ui/dr-ui/src/library.rs#L1355), [`ui/dr-ui/src/library.rs:1408`](../../ui/dr-ui/src/library.rs#L1408), [`ui/dr-ui/src/library.rs:1439`](../../ui/dr-ui/src/library.rs#L1439), [`ui/dr-ui/src/library.rs:1490`](../../ui/dr-ui/src/library.rs#L1490), [`ui/dr-ui/src/library.rs:169`](../../ui/dr-ui/src/library.rs#L169), [`ui/dr-ui/src/library.rs:2019`](../../ui/dr-ui/src/library.rs#L2019), [`ui/dr-ui/src/library.rs:2471`](../../ui/dr-ui/src/library.rs#L2471), [`ui/dr-ui/src/library.rs:2527`](../../ui/dr-ui/src/library.rs#L2527), [`ui/dr-ui/src/library.rs:274`](../../ui/dr-ui/src/library.rs#L274), [`ui/dr-ui/src/library.rs:5224`](../../ui/dr-ui/src/library.rs#L5224), [`ui/dr-ui/src/library.rs:653`](../../ui/dr-ui/src/library.rs#L653), [`ui/dr-ui/src/library.rs:910`](../../ui/dr-ui/src/library.rs#L910), [`ui/dr-ui/src/library.rs:926`](../../ui/dr-ui/src/library.rs#L926), [`ui/dr-ui/src/library.rs:980`](../../ui/dr-ui/src/library.rs#L980), [`ui/dr-ui/src/library_ui.rs:1406`](../../ui/dr-ui/src/library_ui.rs#L1406), [`ui/dr-ui/src/library_ui.rs:1997`](../../ui/dr-ui/src/library_ui.rs#L1997), [`ui/dr-ui/src/library_ui.rs:2041`](../../ui/dr-ui/src/library_ui.rs#L2041), [`ui/dr-ui/src/library_ui.rs:2057`](../../ui/dr-ui/src/library_ui.rs#L2057), [`ui/dr-ui/src/library_ui.rs:2151`](../../ui/dr-ui/src/library_ui.rs#L2151), [`ui/dr-ui/src/library_ui.rs:284`](../../ui/dr-ui/src/library_ui.rs#L284), [`ui/dr-ui/src/library_ui.rs:2993`](../../ui/dr-ui/src/library_ui.rs#L2993), [`ui/dr-ui/src/library_ui.rs:320`](../../ui/dr-ui/src/library_ui.rs#L320), [`ui/dr-ui/src/library_ui.rs:328`](../../ui/dr-ui/src/library_ui.rs#L328), [`ui/dr-ui/src/library_ui.rs:3616`](../../ui/dr-ui/src/library_ui.rs#L3616), [`ui/dr-ui/src/library_ui.rs:3838`](../../ui/dr-ui/src/library_ui.rs#L3838), [`ui/dr-ui/src/library_ui.rs:4116`](../../ui/dr-ui/src/library_ui.rs#L4116), [`ui/dr-ui/src/library_ui.rs:4232`](../../ui/dr-ui/src/library_ui.rs#L4232), [`ui/dr-ui/src/library_ui.rs:4420`](../../ui/dr-ui/src/library_ui.rs#L4420), [`ui/dr-ui/src/library_ui.rs:4542`](../../ui/dr-ui/src/library_ui.rs#L4542), [`ui/dr-ui/src/library_ui.rs:573`](../../ui/dr-ui/src/library_ui.rs#L573), [`ui/dr-ui/src/library_ui.rs:662`](../../ui/dr-ui/src/library_ui.rs#L662), [`ui/dr-ui/src/library_ui.rs:6864`](../../ui/dr-ui/src/library_ui.rs#L6864), [`ui/dr-ui/src/library_ui.rs:6946`](../../ui/dr-ui/src/library_ui.rs#L6946), [`ui/dr-ui/src/presets.rs:486`](../../ui/dr-ui/src/presets.rs#L486), [`ui/dr-ui/src/presets.rs:498`](../../ui/dr-ui/src/presets.rs#L498), [`ui/dr-ui/src/sidecar_cache.rs:1`](../../ui/dr-ui/src/sidecar_cache.rs#L1), [`ui/dr-ui/tests/export_ignores_the_viewport.rs:1`](../../ui/dr-ui/tests/export_ignores_the_viewport.rs#L1) | | FR-CULL-1 | [`core/dr-decode/src/preview.rs:121`](../../core/dr-decode/src/preview.rs#L121) | -| FR-CULL-10 | [`core/dr-catalog/src/faces.rs:1`](../../core/dr-catalog/src/faces.rs#L1), [`core/dr-catalog/src/schema.rs:1011`](../../core/dr-catalog/src/schema.rs#L1011), [`core/dr-catalog/src/schema.rs:603`](../../core/dr-catalog/src/schema.rs#L603), [`core/dr-catalog/src/schema.rs:781`](../../core/dr-catalog/src/schema.rs#L781), [`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), [`core/dr-face/src/references.rs:1`](../../core/dr-face/src/references.rs#L1), [`core/dr-types/src/settings.rs:129`](../../core/dr-types/src/settings.rs#L129), [`ui/dr-ui/src/develop.rs:121`](../../ui/dr-ui/src/develop.rs#L121), [`ui/dr-ui/src/develop.rs:130`](../../ui/dr-ui/src/develop.rs#L130), [`ui/dr-ui/src/develop.rs:196`](../../ui/dr-ui/src/develop.rs#L196), [`ui/dr-ui/src/develop.rs:2416`](../../ui/dr-ui/src/develop.rs#L2416), [`ui/dr-ui/src/develop.rs:715`](../../ui/dr-ui/src/develop.rs#L715), [`ui/dr-ui/src/faces.rs:1`](../../ui/dr-ui/src/faces.rs#L1), [`ui/dr-ui/src/identity.rs:1`](../../ui/dr-ui/src/identity.rs#L1), [`ui/dr-ui/src/identity_ui.rs:1325`](../../ui/dr-ui/src/identity_ui.rs#L1325), [`ui/dr-ui/src/identity_ui.rs:1`](../../ui/dr-ui/src/identity_ui.rs#L1), [`ui/dr-ui/src/lib.rs:2576`](../../ui/dr-ui/src/lib.rs#L2576), [`ui/dr-ui/src/repairs.rs:1`](../../ui/dr-ui/src/repairs.rs#L1), [`ui/dr-ui/ui/identity.slint:1`](../../ui/dr-ui/ui/identity.slint#L1), [`ui/dr-ui/ui/settings.slint:529`](../../ui/dr-ui/ui/settings.slint#L529), [`ui/dr-ui/ui/settings.slint:94`](../../ui/dr-ui/ui/settings.slint#L94) | +| FR-CULL-10 | [`core/dr-catalog/src/faces.rs:1`](../../core/dr-catalog/src/faces.rs#L1), [`core/dr-catalog/src/schema.rs:1011`](../../core/dr-catalog/src/schema.rs#L1011), [`core/dr-catalog/src/schema.rs:603`](../../core/dr-catalog/src/schema.rs#L603), [`core/dr-catalog/src/schema.rs:781`](../../core/dr-catalog/src/schema.rs#L781), [`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), [`core/dr-face/src/references.rs:1`](../../core/dr-face/src/references.rs#L1), [`core/dr-types/src/settings.rs:129`](../../core/dr-types/src/settings.rs#L129), [`ui/dr-ui/src/develop.rs:121`](../../ui/dr-ui/src/develop.rs#L121), [`ui/dr-ui/src/develop.rs:130`](../../ui/dr-ui/src/develop.rs#L130), [`ui/dr-ui/src/develop.rs:196`](../../ui/dr-ui/src/develop.rs#L196), [`ui/dr-ui/src/develop.rs:2416`](../../ui/dr-ui/src/develop.rs#L2416), [`ui/dr-ui/src/develop.rs:715`](../../ui/dr-ui/src/develop.rs#L715), [`ui/dr-ui/src/faces.rs:1`](../../ui/dr-ui/src/faces.rs#L1), [`ui/dr-ui/src/identity.rs:1`](../../ui/dr-ui/src/identity.rs#L1), [`ui/dr-ui/src/identity_ui.rs:1431`](../../ui/dr-ui/src/identity_ui.rs#L1431), [`ui/dr-ui/src/identity_ui.rs:1`](../../ui/dr-ui/src/identity_ui.rs#L1), [`ui/dr-ui/src/lib.rs:2576`](../../ui/dr-ui/src/lib.rs#L2576), [`ui/dr-ui/src/repairs.rs:1`](../../ui/dr-ui/src/repairs.rs#L1), [`ui/dr-ui/ui/identity.slint:1`](../../ui/dr-ui/ui/identity.slint#L1), [`ui/dr-ui/ui/settings.slint:529`](../../ui/dr-ui/ui/settings.slint#L529), [`ui/dr-ui/ui/settings.slint:94`](../../ui/dr-ui/ui/settings.slint#L94) | | FR-CULL-11 | [`core/dr-catalog/src/faces.rs:1`](../../core/dr-catalog/src/faces.rs#L1), [`core/dr-catalog/src/schema.rs:1011`](../../core/dr-catalog/src/schema.rs#L1011), [`ui/dr-ui/src/identity.rs:1`](../../ui/dr-ui/src/identity.rs#L1), [`ui/dr-ui/src/identity_ui.rs:1`](../../ui/dr-ui/src/identity_ui.rs#L1), [`ui/dr-ui/src/library.rs:295`](../../ui/dr-ui/src/library.rs#L295), [`ui/dr-ui/src/library.rs:345`](../../ui/dr-ui/src/library.rs#L345), [`ui/dr-ui/ui/identity.slint:1`](../../ui/dr-ui/ui/identity.slint#L1) | | FR-CULL-12 | [`core/dr-catalog/src/faces.rs:1`](../../core/dr-catalog/src/faces.rs#L1), [`core/dr-catalog/src/schema.rs:1011`](../../core/dr-catalog/src/schema.rs#L1011), [`core/dr-catalog/src/schema.rs:603`](../../core/dr-catalog/src/schema.rs#L603), [`ui/dr-ui/src/identity.rs:1`](../../ui/dr-ui/src/identity.rs#L1), [`ui/dr-ui/ui/identity.slint:1`](../../ui/dr-ui/ui/identity.slint#L1) | | FR-CULL-13 | [`core/dr-catalog/src/schema.rs:917`](../../core/dr-catalog/src/schema.rs#L917), [`core/dr-types/src/place.rs:129`](../../core/dr-types/src/place.rs#L129), [`ui/dr-ui/src/identity.rs:104`](../../ui/dr-ui/src/identity.rs#L104), [`ui/dr-ui/src/library.rs:321`](../../ui/dr-ui/src/library.rs#L321), [`ui/dr-ui/src/library.rs:7219`](../../ui/dr-ui/src/library.rs#L7219), [`ui/dr-ui/src/library.rs:7262`](../../ui/dr-ui/src/library.rs#L7262), [`ui/dr-ui/src/library.rs:7300`](../../ui/dr-ui/src/library.rs#L7300), [`ui/dr-ui/ui/app.slint:707`](../../ui/dr-ui/ui/app.slint#L707), [`ui/dr-ui/ui/identity.slint:63`](../../ui/dr-ui/ui/identity.slint#L63), [`ui/dr-ui/ui/library.slint:1512`](../../ui/dr-ui/ui/library.slint#L1512) | @@ -58,7 +58,7 @@ A tag naming an ID `requirements.md` does not define — what renumbering produc | FR-CULL-3 | [`core/dr-gpu/src/focus.rs:154`](../../core/dr-gpu/src/focus.rs#L154), [`core/dr-gpu/src/focus.rs:186`](../../core/dr-gpu/src/focus.rs#L186), [`core/dr-gpu/src/focus.rs:1`](../../core/dr-gpu/src/focus.rs#L1), [`core/dr-gpu/src/focus.rs:317`](../../core/dr-gpu/src/focus.rs#L317), [`core/dr-gpu/src/raw_histogram.rs:129`](../../core/dr-gpu/src/raw_histogram.rs#L129), [`core/dr-gpu/src/raw_histogram.rs:1`](../../core/dr-gpu/src/raw_histogram.rs#L1), [`core/dr-gpu/src/raw_histogram.rs:272`](../../core/dr-gpu/src/raw_histogram.rs#L272), [`core/dr-gpu/src/raw_histogram.rs:407`](../../core/dr-gpu/src/raw_histogram.rs#L407), [`core/dr-gpu/src/shaders/focus_peak.wgsl:1`](../../core/dr-gpu/src/shaders/focus_peak.wgsl#L1), [`core/dr-gpu/src/shaders/raw_histogram.wgsl:1`](../../core/dr-gpu/src/shaders/raw_histogram.wgsl#L1), [`ui/dr-ui/src/develop.rs:4146`](../../ui/dr-ui/src/develop.rs#L4146), [`ui/dr-ui/src/develop.rs:4159`](../../ui/dr-ui/src/develop.rs#L4159), [`ui/dr-ui/src/develop.rs:4204`](../../ui/dr-ui/src/develop.rs#L4204), [`ui/dr-ui/src/develop.rs:4215`](../../ui/dr-ui/src/develop.rs#L4215), [`ui/dr-ui/src/develop.rs:4221`](../../ui/dr-ui/src/develop.rs#L4221), [`ui/dr-ui/src/develop.rs:4238`](../../ui/dr-ui/src/develop.rs#L4238), [`ui/dr-ui/src/develop.rs:810`](../../ui/dr-ui/src/develop.rs#L810), [`ui/dr-ui/src/develop.rs:830`](../../ui/dr-ui/src/develop.rs#L830), [`ui/dr-ui/src/develop.rs:836`](../../ui/dr-ui/src/develop.rs#L836), [`ui/dr-ui/src/develop.rs:8992`](../../ui/dr-ui/src/develop.rs#L8992), [`ui/dr-ui/src/develop.rs:9056`](../../ui/dr-ui/src/develop.rs#L9056), [`ui/dr-ui/src/develop.rs:9079`](../../ui/dr-ui/src/develop.rs#L9079), [`ui/dr-ui/src/histogram.rs:1`](../../ui/dr-ui/src/histogram.rs#L1), [`ui/dr-ui/src/histogram.rs:208`](../../ui/dr-ui/src/histogram.rs#L208), [`ui/dr-ui/src/histogram.rs:228`](../../ui/dr-ui/src/histogram.rs#L228), [`ui/dr-ui/src/histogram.rs:272`](../../ui/dr-ui/src/histogram.rs#L272), [`ui/dr-ui/src/histogram.rs:544`](../../ui/dr-ui/src/histogram.rs#L544), [`ui/dr-ui/src/histogram.rs:565`](../../ui/dr-ui/src/histogram.rs#L565), [`ui/dr-ui/src/histogram.rs:593`](../../ui/dr-ui/src/histogram.rs#L593), [`ui/dr-ui/src/histogram.rs:621`](../../ui/dr-ui/src/histogram.rs#L621), [`ui/dr-ui/src/histogram.rs:658`](../../ui/dr-ui/src/histogram.rs#L658), [`ui/dr-ui/src/lib.rs:1932`](../../ui/dr-ui/src/lib.rs#L1932), [`ui/dr-ui/src/lib.rs:2040`](../../ui/dr-ui/src/lib.rs#L2040), [`ui/dr-ui/src/lib.rs:2153`](../../ui/dr-ui/src/lib.rs#L2153), [`ui/dr-ui/src/lib.rs:2194`](../../ui/dr-ui/src/lib.rs#L2194), [`ui/dr-ui/src/lib.rs:3685`](../../ui/dr-ui/src/lib.rs#L3685), [`ui/dr-ui/src/lib.rs:442`](../../ui/dr-ui/src/lib.rs#L442), [`ui/dr-ui/src/peaking.rs:1`](../../ui/dr-ui/src/peaking.rs#L1), [`ui/dr-ui/ui/app.slint:2028`](../../ui/dr-ui/ui/app.slint#L2028), [`ui/dr-ui/ui/app.slint:3035`](../../ui/dr-ui/ui/app.slint#L3035), [`ui/dr-ui/ui/app.slint:90`](../../ui/dr-ui/ui/app.slint#L90), [`ui/dr-ui/ui/peaking.slint:1`](../../ui/dr-ui/ui/peaking.slint#L1), [`ui/dr-ui/ui/peaking.slint:25`](../../ui/dr-ui/ui/peaking.slint#L25), [`ui/dr-ui/ui/peaking.slint:56`](../../ui/dr-ui/ui/peaking.slint#L56), [`ui/dr-ui/ui/peaking.slint:91`](../../ui/dr-ui/ui/peaking.slint#L91) | | FR-CULL-4 | [`core/dr-catalog/src/rating.rs:1`](../../core/dr-catalog/src/rating.rs#L1), [`core/dr-pipeline/src/sidecar.rs:171`](../../core/dr-pipeline/src/sidecar.rs#L171), [`core/dr-xmp/src/lib.rs:442`](../../core/dr-xmp/src/lib.rs#L442), [`ui/dr-ui/src/library.rs:254`](../../ui/dr-ui/src/library.rs#L254), [`ui/dr-ui/src/library.rs:564`](../../ui/dr-ui/src/library.rs#L564) | | FR-CULL-5 | [`core/dr-catalog/src/bursts.rs:1`](../../core/dr-catalog/src/bursts.rs#L1), [`core/dr-catalog/src/schema.rs:646`](../../core/dr-catalog/src/schema.rs#L646), [`ui/dr-ui/src/bursts.rs:1`](../../ui/dr-ui/src/bursts.rs#L1), [`ui/dr-ui/src/library.rs:210`](../../ui/dr-ui/src/library.rs#L210), [`ui/dr-ui/src/library.rs:6039`](../../ui/dr-ui/src/library.rs#L6039) | -| 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:1011`](../../core/dr-catalog/src/schema.rs#L1011), [`core/dr-catalog/src/schema.rs:714`](../../core/dr-catalog/src/schema.rs#L714), [`core/dr-catalog/src/schema.rs:970`](../../core/dr-catalog/src/schema.rs#L970), [`core/dr-face/src/align.rs:296`](../../core/dr-face/src/align.rs#L296), [`core/dr-types/src/settings.rs:176`](../../core/dr-types/src/settings.rs#L176), [`ui/dr-ui/examples/face_detectors.rs:1`](../../ui/dr-ui/examples/face_detectors.rs#L1), [`ui/dr-ui/examples/face_native.rs:1`](../../ui/dr-ui/examples/face_native.rs#L1), [`ui/dr-ui/src/derived_sync.rs:124`](../../ui/dr-ui/src/derived_sync.rs#L124), [`ui/dr-ui/src/faces.rs:1`](../../ui/dr-ui/src/faces.rs#L1), [`ui/dr-ui/src/faces.rs:446`](../../ui/dr-ui/src/faces.rs#L446), [`ui/dr-ui/src/faces.rs:462`](../../ui/dr-ui/src/faces.rs#L462), [`ui/dr-ui/src/faces.rs:584`](../../ui/dr-ui/src/faces.rs#L584), [`ui/dr-ui/src/identity_ui.rs:1325`](../../ui/dr-ui/src/identity_ui.rs#L1325), [`ui/dr-ui/src/identity_ui.rs:603`](../../ui/dr-ui/src/identity_ui.rs#L603), [`ui/dr-ui/src/lib.rs:1511`](../../ui/dr-ui/src/lib.rs#L1511), [`ui/dr-ui/src/lib.rs:3940`](../../ui/dr-ui/src/lib.rs#L3940), [`ui/dr-ui/src/library.rs:3624`](../../ui/dr-ui/src/library.rs#L3624), [`ui/dr-ui/src/library.rs:3889`](../../ui/dr-ui/src/library.rs#L3889), [`ui/dr-ui/src/library_ui.rs:406`](../../ui/dr-ui/src/library_ui.rs#L406), [`ui/dr-ui/src/library_ui.rs:493`](../../ui/dr-ui/src/library_ui.rs#L493), [`ui/dr-ui/src/repairs.rs:1`](../../ui/dr-ui/src/repairs.rs#L1), [`ui/dr-ui/src/settings_ui.rs:210`](../../ui/dr-ui/src/settings_ui.rs#L210), [`ui/dr-ui/src/settings_ui.rs:552`](../../ui/dr-ui/src/settings_ui.rs#L552), [`ui/dr-ui/ui/app.slint:946`](../../ui/dr-ui/ui/app.slint#L946), [`ui/dr-ui/ui/settings.slint:100`](../../ui/dr-ui/ui/settings.slint#L100), [`ui/dr-ui/ui/settings.slint:467`](../../ui/dr-ui/ui/settings.slint#L467), [`ui/dr-ui/ui/settings.slint:529`](../../ui/dr-ui/ui/settings.slint#L529), [`ui/dr-ui/ui/settings.slint:82`](../../ui/dr-ui/ui/settings.slint#L82), [`ui/dr-ui/ui/settings.slint:94`](../../ui/dr-ui/ui/settings.slint#L94) | +| 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:1011`](../../core/dr-catalog/src/schema.rs#L1011), [`core/dr-catalog/src/schema.rs:714`](../../core/dr-catalog/src/schema.rs#L714), [`core/dr-catalog/src/schema.rs:970`](../../core/dr-catalog/src/schema.rs#L970), [`core/dr-face/src/align.rs:296`](../../core/dr-face/src/align.rs#L296), [`core/dr-types/src/settings.rs:176`](../../core/dr-types/src/settings.rs#L176), [`ui/dr-ui/examples/face_detectors.rs:1`](../../ui/dr-ui/examples/face_detectors.rs#L1), [`ui/dr-ui/examples/face_native.rs:1`](../../ui/dr-ui/examples/face_native.rs#L1), [`ui/dr-ui/src/derived_sync.rs:124`](../../ui/dr-ui/src/derived_sync.rs#L124), [`ui/dr-ui/src/faces.rs:1`](../../ui/dr-ui/src/faces.rs#L1), [`ui/dr-ui/src/faces.rs:446`](../../ui/dr-ui/src/faces.rs#L446), [`ui/dr-ui/src/faces.rs:462`](../../ui/dr-ui/src/faces.rs#L462), [`ui/dr-ui/src/faces.rs:584`](../../ui/dr-ui/src/faces.rs#L584), [`ui/dr-ui/src/identity_ui.rs:1431`](../../ui/dr-ui/src/identity_ui.rs#L1431), [`ui/dr-ui/src/identity_ui.rs:617`](../../ui/dr-ui/src/identity_ui.rs#L617), [`ui/dr-ui/src/lib.rs:1511`](../../ui/dr-ui/src/lib.rs#L1511), [`ui/dr-ui/src/lib.rs:3940`](../../ui/dr-ui/src/lib.rs#L3940), [`ui/dr-ui/src/library.rs:3624`](../../ui/dr-ui/src/library.rs#L3624), [`ui/dr-ui/src/library.rs:3889`](../../ui/dr-ui/src/library.rs#L3889), [`ui/dr-ui/src/library_ui.rs:406`](../../ui/dr-ui/src/library_ui.rs#L406), [`ui/dr-ui/src/library_ui.rs:493`](../../ui/dr-ui/src/library_ui.rs#L493), [`ui/dr-ui/src/repairs.rs:1`](../../ui/dr-ui/src/repairs.rs#L1), [`ui/dr-ui/src/settings_ui.rs:210`](../../ui/dr-ui/src/settings_ui.rs#L210), [`ui/dr-ui/src/settings_ui.rs:552`](../../ui/dr-ui/src/settings_ui.rs#L552), [`ui/dr-ui/ui/app.slint:946`](../../ui/dr-ui/ui/app.slint#L946), [`ui/dr-ui/ui/settings.slint:100`](../../ui/dr-ui/ui/settings.slint#L100), [`ui/dr-ui/ui/settings.slint:467`](../../ui/dr-ui/ui/settings.slint#L467), [`ui/dr-ui/ui/settings.slint:529`](../../ui/dr-ui/ui/settings.slint#L529), [`ui/dr-ui/ui/settings.slint:82`](../../ui/dr-ui/ui/settings.slint#L82), [`ui/dr-ui/ui/settings.slint:94`](../../ui/dr-ui/ui/settings.slint#L94) | | FR-CULL-8a | [`core/dr-catalog/src/faces.rs:124`](../../core/dr-catalog/src/faces.rs#L124), [`core/dr-catalog/src/schema.rs:917`](../../core/dr-catalog/src/schema.rs#L917), [`core/dr-face/src/classify.rs:1`](../../core/dr-face/src/classify.rs#L1), [`core/dr-face/src/eyes.rs:1`](../../core/dr-face/src/eyes.rs#L1), [`core/dr-face/src/landmarks.rs:1`](../../core/dr-face/src/landmarks.rs#L1), [`core/dr-types/src/place.rs:129`](../../core/dr-types/src/place.rs#L129), [`ui/dr-ui/src/faces.rs:166`](../../ui/dr-ui/src/faces.rs#L166), [`ui/dr-ui/src/faces.rs:1821`](../../ui/dr-ui/src/faces.rs#L1821), [`ui/dr-ui/src/faces.rs:308`](../../ui/dr-ui/src/faces.rs#L308), [`ui/dr-ui/src/identity.rs:104`](../../ui/dr-ui/src/identity.rs#L104), [`ui/dr-ui/src/library.rs:321`](../../ui/dr-ui/src/library.rs#L321), [`ui/dr-ui/src/library.rs:7219`](../../ui/dr-ui/src/library.rs#L7219), [`ui/dr-ui/src/library.rs:7262`](../../ui/dr-ui/src/library.rs#L7262), [`ui/dr-ui/src/library.rs:7300`](../../ui/dr-ui/src/library.rs#L7300), [`ui/dr-ui/src/repairs.rs:571`](../../ui/dr-ui/src/repairs.rs#L571), [`ui/dr-ui/ui/app.slint:707`](../../ui/dr-ui/ui/app.slint#L707), [`ui/dr-ui/ui/identity.slint:273`](../../ui/dr-ui/ui/identity.slint#L273), [`ui/dr-ui/ui/identity.slint:63`](../../ui/dr-ui/ui/identity.slint#L63), [`ui/dr-ui/ui/library.slint:1512`](../../ui/dr-ui/ui/library.slint#L1512) | | FR-CULL-9 | [`core/dr-catalog/src/faces.rs:1`](../../core/dr-catalog/src/faces.rs#L1), [`core/dr-catalog/src/schema.rs:1011`](../../core/dr-catalog/src/schema.rs#L1011), [`core/dr-catalog/src/schema.rs:781`](../../core/dr-catalog/src/schema.rs#L781), [`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), [`core/dr-types/src/settings.rs:129`](../../core/dr-types/src/settings.rs#L129), [`ui/dr-ui/src/faces.rs:1`](../../ui/dr-ui/src/faces.rs#L1), [`ui/dr-ui/src/faces.rs:584`](../../ui/dr-ui/src/faces.rs#L584), [`ui/dr-ui/src/identity_ui.rs:1`](../../ui/dr-ui/src/identity_ui.rs#L1), [`ui/dr-ui/src/repairs.rs:517`](../../ui/dr-ui/src/repairs.rs#L517), [`ui/dr-ui/ui/identity.slint:347`](../../ui/dr-ui/ui/identity.slint#L347) | | FR-DEV-1 | [`core/dr-pipeline/src/graph.rs:1`](../../core/dr-pipeline/src/graph.rs#L1), [`core/dr-pipeline/src/sidecar.rs:1`](../../core/dr-pipeline/src/sidecar.rs#L1) | diff --git a/ui/dr-ui/src/identity_ui.rs b/ui/dr-ui/src/identity_ui.rs index dfc0d5f..6538f45 100644 --- a/ui/dr-ui/src/identity_ui.rs +++ b/ui/dr-ui/src/identity_ui.rs @@ -582,6 +582,20 @@ fn push_grouping(window: &AppWindow, settings: &crate::settings_ui::SettingsCont window.set_identity_min_group_size(s.faces.min_group_size as i32); } +macro_rules! reload { + ($w:expr, $ctl:expr, $catalog:expr, $store:expr, $settings:expr, $eyes:expr, $changed:ident) => { + refresh( + &$w, + &$ctl, + &$catalog, + $store(), + &model_id(&$settings), + $eyes(), + Changed::$changed, + ) + }; +} + /// Attach every Identity callback. /// /// Eight arguments because the screen has eight distinct dependencies and no @@ -616,10 +630,69 @@ pub fn wire( let models: Rc Option> = Rc::new(models); let paths: Rc Option> = Rc::new(paths); - // The dials start where the settings file left them, once, rather than on - // every open: the screen writes them back through the two callbacks below, - // and re-pushing them mid-drag would fight the slider's own live value. - push_grouping(window, &settings); + // Re-read everything and redraw. Every mutating callback ends in this + // rather than patching the model in place: the operations here have + // second-order effects — a merge empties a person, a split creates one, + // a rejection changes two counts — and a model patched by hand would + // drift from the catalog in exactly the cases that matter. + // Whether the eye models are on this machine, asked each time rather + // than once: it is two `is_file` checks, and a user who drops the files + // in while the app is open should see the faces become work to measure. + let eyes_available: Rc bool> = { + let models = models.clone(); + Rc::new(move || models().is_some_and(|m| m.eyes.is_some())) + }; + // The availability closure is an argument rather than named in the + // body: macro hygiene would bind the name to this scope's `Rc`, which the + // first `move` closure would then take with it. + // The last argument is a `Changed` variant, named bare so the call + // stays on one line. + + wire_dials(window, &settings); + + wire_navigation( + window, + &ctl, + &catalog, + &store, + &models, + &settings, + &eyes_available, + ); + wire_rename_and_merge(window, &ctl, &catalog, &store, &settings, &eyes_available); + wire_face_actions(window, &ctl, &catalog, &store, &settings, &eyes_available); + wire_grouping_preview(window, &ctl, &paths, &settings); + wire_recluster( + window, + &ctl, + &catalog, + &store, + &paths, + &settings, + &eyes_available, + ); + wire_indexing( + window, + &ctl, + &catalog, + &activity, + &store, + &models, + &paths, + &gpu, + &settings, + &eyes_available, + ); + wire_coverage_and_ignore(window, &ctl, &catalog, &store, &settings, &eyes_available); +} + +/// The dials. +/// +/// The dials start where the settings file left them, once, rather than on +/// every open: the screen writes them back through the two callbacks below, +/// and re-pushing them mid-drag would fight the slider's own live value. +fn wire_dials(window: &AppWindow, settings: &Rc) { + push_grouping(window, settings); { let weak = window.as_weak(); @@ -645,38 +718,18 @@ pub fn wire( w.set_identity_grouping_preview(Default::default()); }); } +} - // Re-read everything and redraw. Every mutating callback ends in this - // rather than patching the model in place: the operations here have - // second-order effects — a merge empties a person, a split creates one, - // a rejection changes two counts — and a model patched by hand would - // drift from the catalog in exactly the cases that matter. - // Whether the eye models are on this machine, asked each time rather - // than once: it is two `is_file` checks, and a user who drops the files - // in while the app is open should see the faces become work to measure. - let eyes_available: Rc bool> = { - let models = models.clone(); - Rc::new(move || models().is_some_and(|m| m.eyes.is_some())) - }; - // The availability closure is an argument rather than named in the - // body: macro hygiene would bind the name to this scope's `Rc`, which the - // first `move` closure would then take with it. - // The last argument is a `Changed` variant, named bare so the call - // stays on one line. - macro_rules! reload { - ($w:expr, $ctl:expr, $catalog:expr, $store:expr, $settings:expr, $eyes:expr, $changed:ident) => { - refresh( - &$w, - &$ctl, - &$catalog, - $store(), - &model_id(&$settings), - $eyes(), - Changed::$changed, - ) - }; - } - +/// Opening and closing the screen, and switching which person is shown. +fn wire_navigation( + window: &AppWindow, + ctl: &Rc, + catalog: &Rc>>, + store: &Rc Option>>, + models: &Rc Option>, + settings: &Rc, + eyes_available: &Rc bool>, +) { { let weak = window.as_weak(); let eyes_available = eyes_available.clone(); @@ -742,7 +795,17 @@ pub fn wire( reset_name_field(&w); }); } +} +/// Renaming a person, and the namesake merge offer a rename can raise. +fn wire_rename_and_merge( + window: &AppWindow, + ctl: &Rc, + catalog: &Rc>>, + store: &Rc Option>>, + settings: &Rc, + eyes_available: &Rc bool>, +) { { let weak = window.as_weak(); let eyes_available = eyes_available.clone(); @@ -850,7 +913,17 @@ pub fn wire( clear_merge_offer(&w, &ctl); }); } +} +/// The grid: picking, confirming, rejecting and splitting off faces. +fn wire_face_actions( + window: &AppWindow, + ctl: &Rc, + catalog: &Rc>>, + store: &Rc Option>>, + settings: &Rc, + eyes_available: &Rc bool>, +) { { let weak = window.as_weak(); let eyes_available = eyes_available.clone(); @@ -970,7 +1043,15 @@ pub fn wire( reload!(w, ctl, catalog, store, settings, eyes_available, Identities); }); } +} +/// A dry run of the grouping dials, without writing anything. +fn wire_grouping_preview( + window: &AppWindow, + ctl: &Rc, + paths: &Rc Option>, + settings: &Rc, +) { { let weak = window.as_weak(); let ctl = ctl.clone(); @@ -1033,7 +1114,18 @@ pub fn wire( park_preview_timer(timer); }); } +} +/// Regroup: rerun clustering over faces already indexed. +fn wire_recluster( + window: &AppWindow, + ctl: &Rc, + catalog: &Rc>>, + store: &Rc Option>>, + paths: &Rc Option>, + settings: &Rc, + eyes_available: &Rc bool>, +) { { let weak = window.as_weak(); let ctl = ctl.clone(); @@ -1135,12 +1227,26 @@ pub fn wire( park_timer(timer); }); } +} - // One launcher behind two buttons. "Index faces" and "Re-index every - // face" differ only in which images the pass visits (`FaceSweepScope`); - // the models, the progress, the activity row and the Stop button are the - // same, and a second copy of this closure would be a second place for - // them to disagree. +#[allow(clippy::too_many_arguments)] +/// One launcher behind two buttons. "Index faces" and "Re-index every +/// face" differ only in which images the pass visits (`FaceSweepScope`); +/// the models, the progress, the activity row and the Stop button are the +/// same, and a second copy of this closure would be a second place for +/// them to disagree. +fn wire_indexing( + window: &AppWindow, + ctl: &Rc, + catalog: &Rc>>, + activity: &Rc, + store: &Rc Option>>, + models: &Rc Option>, + paths: &Rc Option>, + gpu: &Rc>, + settings: &Rc, + eyes_available: &Rc bool>, +) { let launch: Rc = { let weak = window.as_weak(); let ctl = ctl.clone(); @@ -1347,7 +1453,17 @@ pub fn wire( reload!(w, ctl, catalog, store, settings, eyes_available, Library); }); } +} +/// Coverage, setting a person aside, and clearing every person and face. +fn wire_coverage_and_ignore( + window: &AppWindow, + ctl: &Rc, + catalog: &Rc>>, + store: &Rc Option>>, + settings: &Rc, + eyes_available: &Rc bool>, +) { { let weak = window.as_weak(); let catalog = catalog.clone();