Wire the launch screen into the app
The app now opens on the login screen when there is nothing else to show
— no local paths and no configured library — and goes straight to the
images otherwise. Making someone click past a login they already
completed is pure friction.
launch.slint imported by app.slint, replacing the window rather
than overlaying it: there is no library to look at
until an account is configured
launch_ui.rs the Slint wiring, kept out of lib.rs so the launch
flow can change without touching the develop window
Login runs on a worker thread and posts results back through a channel,
since Slint's event loop is single-threaded and a 20-minute browser wait
cannot block it. The system browser is opened via xdg-open, never an
embedded webview (FR-NC-1).
Sign-out deletes the local credential even if server-side revocation
fails: a network error must not leave a usable secret on the machine.
Format tick-boxes persist on each toggle, so a selection survives a
crash before the library is opened.
Two things deliberately incomplete rather than faked:
- "Choose folder" lists the account's folders and reports them, but
there is no picker widget yet, so selection still happens via the
connect example.
- "Open library" logs the request. Opening a remote library needs the
scan-and-cache path, which belongs with the catalog work in flight.
Earlier I broke the other in-flight dr-ui work by calling
slint_build::compile twice, which replaces the generated module. The
correct wiring is an import inside app.slint, which is what this does.
30 dr-ui tests passing; both launch paths verified by running the app.
This commit is contained in:
@@ -39,7 +39,8 @@ pub mod operation;
|
||||
pub mod ops;
|
||||
|
||||
pub use descriptor::{
|
||||
LocalizedKey, OpDescriptor, OpId, ParamDescriptor, ParamId, ParamKind, Scale, Unit,
|
||||
LocalizedKey, OpDescriptor, OpId, ParamDescriptor, ParamId, ParamKind, Presentation, Scale,
|
||||
Unit, WidgetKind,
|
||||
};
|
||||
pub use framing::{CropRect, Framing};
|
||||
pub use graph::{EditGraph, OpCapability, ParamCapability};
|
||||
@@ -54,14 +55,30 @@ mod tests {
|
||||
use super::*;
|
||||
|
||||
/// Every operation in the default chain, activated.
|
||||
///
|
||||
/// Parameters are moved away from their defaults by differing amounts,
|
||||
/// scaled by position. A uniform nudge is not enough: the tone curve's
|
||||
/// neutral is a *relationship* between its parameters rather than a set
|
||||
/// of values, so shifting every point by the same amount slides it along
|
||||
/// the identity diagonal and leaves the operation correctly inactive.
|
||||
/// Varying the step breaks that symmetry, as any real edit would.
|
||||
fn fully_active() -> EditGraph {
|
||||
let mut g = EditGraph::default_chain();
|
||||
for desc in g.descriptors() {
|
||||
for p in desc.params {
|
||||
// A value away from the default, within range.
|
||||
for (i, p) in desc.params.iter().enumerate() {
|
||||
let v = match p.kind {
|
||||
ParamKind::Scalar { max, .. } => max * 0.5,
|
||||
ParamKind::Bool => 1.0,
|
||||
ParamKind::Scalar { min, max, .. } => {
|
||||
// A fraction that differs per parameter, so no two
|
||||
// move in lockstep.
|
||||
let fraction = 0.15 + 0.05 * (i % 4) as f32;
|
||||
let step = (max - min) * fraction;
|
||||
if p.default + step <= max {
|
||||
p.default + step
|
||||
} else {
|
||||
p.default - step
|
||||
}
|
||||
}
|
||||
ParamKind::Bool => 1.0 - p.default,
|
||||
};
|
||||
g.set_param(desc.id, p.id, v);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user