Two halves of the same complaint: a preset sheet that opens on "No presets yet" is homework, and a photographer with ten years of presets in Lightroom has no way to bring them. `dr-preset-xmp` reads Camera Raw `.xmp`. The mapping turned out to be mostly a rename rather than a conversion, because Adobe and this pipeline already agree: exposure is in stops in both, and contrast, the four recovery controls, clarity, texture, vibrance and saturation are all ±100 in both. That is not imitation, it is the convention raw developers converged on — `highlights_shadows.yaml` cites it in as many words. Only sharpening needed arithmetic, Adobe's 0…150 against our 0…100. The white balance does not come across, and says so rather than guessing. Adobe writes absolute Kelvin for a raw file where ours is a relative nudge from what the camera recorded, so converting needs the *target image's* as-shot white balance — exactly what a preset cannot carry, since the same preset lands on a frame shot at 3200K and one shot at 7000K. A guess would be wrong on most images and invisibly so. A folder is read as readily as a file, nested, because that is the shape an exported preset folder is in and importing ninety files one at a time is asking someone not to bother. `dr_pipeline::starter` is six presets a first run begins with, written against this pipeline in its units and deliberately mild — a starting point, not a caricature. They are seeded when the library *file* does not exist rather than when the library is empty, so deleting all six does not hand them back on the next launch. Both of these name operations, and `ui_names_no_operation` was right to stop them living in `ui/`. That test exists because the failure is silent and cumulative, and it caught exactly what it was written for: a preset called "Punch" is a statement about contrast, clarity and vibrance, and a table mapping Adobe's vocabulary to ours is a statement about the pipeline. Neither is a fact about an interface. So the starter set went into `dr-pipeline`, and the importer into its own crate — between two walls, since `dr-pipeline` depends on nothing on purpose and XMP is real XML not worth hand-rolling. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
130 lines
6.1 KiB
TOML
130 lines
6.1 KiB
TOML
[package]
|
|
name = "dr-ui"
|
|
version.workspace = true
|
|
edition.workspace = true
|
|
rust-version.workspace = true
|
|
license.workspace = true
|
|
|
|
[dependencies]
|
|
dr-types.workspace = true
|
|
# TRACES: FR-DEV-6
|
|
# Reading Lightroom `.xmp` presets. Its own crate because the translation names
|
|
# operations, which the interface may not — see `ui_names_no_operation.rs`.
|
|
dr-preset-xmp.workspace = true
|
|
# No `readback`. S1 wired Slint's texture import, so the develop view hands
|
|
# the compositor the texture itself and there is no display round-trip left to
|
|
# gate (ARCH §6.1, AC-8). The export path reads pixels back through
|
|
# `export_pixels`, which is ungated and always was.
|
|
#
|
|
# `segment-readback` *is* on, and it is not a contradiction of the above. It
|
|
# gates the region-graph transfer that local masking is built on: once per
|
|
# image, on a worker, off the frame path. The display round-trip AC-8 forbids
|
|
# stays behind its own switch, which remains off. See `dr-gpu/src/segment.rs`.
|
|
dr-gpu = { workspace = true, features = ["segment-readback"] }
|
|
# The semantic arm and its weights, for local adjustments (FR-DEV-3, D14).
|
|
dr-segment = { workspace = true, features = ["semantic", "embedded-model"] }
|
|
dr-decode.workspace = true
|
|
serde_json.workspace = true
|
|
tokio.workspace = true
|
|
reqwest.workspace = true
|
|
dr-plat.workspace = true
|
|
dr-sync.workspace = true
|
|
dr-sync-folder.workspace = true
|
|
dr-sync-nextcloud.workspace = true
|
|
dr-export.workspace = true
|
|
dr-ingest.workspace = true
|
|
dr-film.workspace = true
|
|
dr-pipeline.workspace = true
|
|
dr-catalog.workspace = true
|
|
# The face pipeline, with the ONNX runtime: this is the layer that actually
|
|
# runs the models over the library (docs/faces.md).
|
|
dr-face = { workspace = true, features = ["inference"] }
|
|
dr-thumbs.workspace = true
|
|
# The library module writes scan results straight into the catalog, so it
|
|
# needs the same SQLite types dr-catalog exposes.
|
|
rusqlite.workspace = true
|
|
# The renderer is shared, but the backend is not: winit on desktop,
|
|
# android-activity on Android, and enabling both makes the backend selector
|
|
# pick at random. So the backend features live on the target-specific
|
|
# dependencies below rather than here.
|
|
#
|
|
# `renderer-femtovg-wgpu` rather than `renderer-femtovg`: the latter is
|
|
# FemtoVG over OpenGL, and a compositor drawing through GL cannot be handed a
|
|
# `wgpu::Texture`. Importing one requires Slint itself to be rendering with
|
|
# wgpu, and this is the FemtoVG backend that does (ARCH §6.1, spike S1).
|
|
#
|
|
# `unstable-wgpu-29` is the other half: the renderer feature makes Slint draw
|
|
# with wgpu, and this one exposes the API to say so — `BackendSelector::
|
|
# require_wgpu_29` and `Image::try_from(wgpu::Texture)`. Unstable is Slint's
|
|
# word for it; the surface is small and the alternative is the 7 ms round-trip.
|
|
#
|
|
# `renderer-femtovg` is *not* kept alongside as a fallback, though it would
|
|
# still compile. Slint's winit backend prefers the wgpu FemtoVG renderer
|
|
# whenever both are built, so the GL one would only ever be reached by someone
|
|
# setting `SLINT_BACKEND=winit-femtovg` — and on that path an imported texture
|
|
# is not drawn at all. FemtoVG-over-GL has no branch for a `wgpu::Texture`, so
|
|
# it falls through to "render this image to a buffer", gets nothing back, and
|
|
# draws nothing. A blank canvas with no error is a far worse failure than the
|
|
# one below, so the fallback is removed rather than left as a trap.
|
|
#
|
|
# Consequence worth stating plainly: the desktop app now needs a working wgpu
|
|
# adapter to open a window at all. Slint refuses a CPU adapter for this
|
|
# renderer unless `SLINT_WGPU_CPU` is set in the environment.
|
|
# TEST BUILD: the wgpu renderer features have moved to the desktop-only
|
|
# dependency below. On Android they made `AndroidWindowAdapter` choose
|
|
# `SkiaRenderer::default_wgpu_29`, and so put the app on wgpu's Vulkan
|
|
# swapchain — which hardcodes `preTransform = IDENTITY` (gfx-rs/wgpu#3345).
|
|
# Without them the Android backend uses `SkiaRenderer::default`, which on
|
|
# Android resolves to Skia over OpenGL, where the driver owns the display
|
|
# rotation and there is no transform to get wrong.
|
|
slint = { workspace = true, features = ["compat-1-2"] }
|
|
wgpu.workspace = true
|
|
anyhow.workspace = true
|
|
# `SettingsError` distinguishes an io failure from a malformed file, which the
|
|
# settings page reports differently; anyhow would flatten both to a string.
|
|
thiserror.workspace = true
|
|
log.workspace = true
|
|
pollster.workspace = true
|
|
# Runtime YAML only for `live-style`; release builds read the tokens the
|
|
# Slint compiler folded in at build time and never touch style.yaml.
|
|
serde_norway = { workspace = true, optional = true }
|
|
|
|
# Backend per platform. Slint already declares its android-activity backend
|
|
# under `cfg(target_os = "android")`, so this only has to name the feature;
|
|
# cargo resolves it away entirely on desktop.
|
|
[target.'cfg(not(target_os = "android"))'.dependencies]
|
|
slint = { workspace = true, features = [
|
|
"backend-winit",
|
|
"renderer-femtovg-wgpu",
|
|
"unstable-wgpu-29",
|
|
] }
|
|
|
|
[target.'cfg(target_os = "android")'.dependencies]
|
|
slint = { workspace = true, features = ["backend-android-activity-06"] }
|
|
# Opening the sign-in URL needs an ACTION_VIEW Intent — Android has no
|
|
# xdg-open. Version-matched to Slint's Android backend so both halves of the
|
|
# process agree on the JavaVM types; ndk-context supplies the VM and activity
|
|
# that android-activity's glue already stashed.
|
|
jni = "0.22"
|
|
ndk-context = "0.1"
|
|
|
|
[build-dependencies]
|
|
slint-build.workspace = true
|
|
# build.rs generates theme.slint from style.yaml (S2).
|
|
serde_norway.workspace = true
|
|
|
|
[features]
|
|
default = []
|
|
# Debug convenience: re-read style.yaml at startup so a palette can be tuned
|
|
# without rebuilding. Costs the constant-folding of every token, so it stays
|
|
# off by default and has no business in a release build.
|
|
live-style = ["dep:serde_norway"]
|
|
|
|
[dev-dependencies]
|
|
# The face_index batch job wants a log level from the environment; the library
|
|
# itself only ever calls `log`, and picks up whatever the application installs.
|
|
env_logger.workspace = true
|
|
# Standing in a test backend behind `dyn RemoteBackend`, which is an
|
|
# `#[async_trait]` trait — implementing one needs the same attribute.
|
|
async-trait.workspace = true
|