Fix the workspace build off-device
Two breaks that only appeared on a full `cargo test --workspace`. `slint::android` exists only when compiling for Android, so darkroom-android failed to compile on the host even though it is a workspace member. The entry point is now gated on the target rather than on a feature. The timeline forwarded `scrub` where the Timeline component declares `scrub-to`, which the Slint compiler rejects. Assisted-by: LLM
This commit is contained in:
@@ -217,8 +217,9 @@ export component AppWindow inherits Window {
|
||||
in property <int> library-current-index: -1;
|
||||
in property <bool> library-timeline-anchored: false;
|
||||
|
||||
callback library-scrub(int);
|
||||
callback library-timeline-pan(int);
|
||||
callback library-scrub-fraction(float);
|
||||
callback library-timeline-pinch(float);
|
||||
callback library-timeline-pan(float);
|
||||
callback library-timeline-zoom(int);
|
||||
in-out property <int> library-columns: 1;
|
||||
in property <bool> library-syncing: false;
|
||||
@@ -468,7 +469,8 @@ export component AppWindow inherits Window {
|
||||
current-bucket-index: root.library-current-index;
|
||||
timeline-anchored: root.library-timeline-anchored;
|
||||
|
||||
scrub(t) => { root.library-scrub(t); }
|
||||
scrub-fraction(f) => { root.library-scrub-fraction(f); }
|
||||
timeline-pinch(r) => { root.library-timeline-pinch(r); }
|
||||
timeline-pan(d) => { root.library-timeline-pan(d); }
|
||||
timeline-zoom(d) => { root.library-timeline-zoom(d); }
|
||||
syncing: root.library-syncing;
|
||||
|
||||
+47
-13
@@ -61,9 +61,14 @@ export component Timeline inherits Rectangle {
|
||||
/// that has not been made.
|
||||
in property <bool> anchored: false;
|
||||
|
||||
callback scrub(int);
|
||||
callback pan(int);
|
||||
/// Scrub to a fraction along the visible span. Rust turns it into an
|
||||
/// instant, interpolating within a bucket rather than snapping to its edge.
|
||||
callback scrub-to(float);
|
||||
callback pan(float);
|
||||
callback zoom(int);
|
||||
/// Pinch: a ratio above 1 spreads the fingers (zoom in), below 1 pinches
|
||||
/// them together. Continuous, unlike the wheel's discrete steps.
|
||||
callback pinch(float);
|
||||
|
||||
width: 96px;
|
||||
background: Theme.surface;
|
||||
@@ -81,6 +86,17 @@ export component Timeline inherits Rectangle {
|
||||
0, max(0, root.bars.length - 1));
|
||||
}
|
||||
|
||||
/// Position along the axis as a fraction, 0 at the first bucket's start and
|
||||
/// 1 at the last one's end.
|
||||
///
|
||||
/// **Fractional rather than a bucket index.** Snapping to whole buckets
|
||||
/// makes a slow drag feel dead — the pointer moves and nothing happens
|
||||
/// until it crosses a boundary, then the grid jumps a whole month. Rust
|
||||
/// interpolates an instant from this, so the grid tracks the finger.
|
||||
function fraction-at(y: length) -> float {
|
||||
return clamp((y - root.track-top) / max(1px, root.track-height), 0.0, 1.0);
|
||||
}
|
||||
|
||||
// Header: the hovered bucket, else the whole span.
|
||||
Caption {
|
||||
x: 8px;
|
||||
@@ -137,6 +153,27 @@ export component Timeline inherits Rectangle {
|
||||
}
|
||||
|
||||
// The single hit area. Everything above is inert.
|
||||
// Two-finger pinch, for tablet. There is no wheel there, so without this
|
||||
// the axis could only be zoomed by a control a finger cannot reach.
|
||||
//
|
||||
// `scale` is cumulative from 1.0 for the whole gesture, so the delta since
|
||||
// the last update is what maps onto a zoom step — otherwise a slow spread
|
||||
// would apply its total repeatedly and shoot straight to full zoom.
|
||||
pinch := ScaleRotateGestureHandler {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
property <float> last-scale: 1.0;
|
||||
|
||||
started => { self.last-scale = 1.0; }
|
||||
updated => {
|
||||
root.pinch(self.scale / max(0.01, self.last-scale));
|
||||
self.last-scale = self.scale;
|
||||
}
|
||||
ended => { self.last-scale = 1.0; }
|
||||
cancelled => { self.last-scale = 1.0; }
|
||||
}
|
||||
|
||||
touch := TouchArea {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
@@ -147,15 +184,12 @@ export component Timeline inherits Rectangle {
|
||||
|
||||
moved => {
|
||||
if (self.panning) {
|
||||
// Pan by whole buckets, so the view moves in the same units it
|
||||
// is drawn in.
|
||||
root.pan(round((self.press-y - self.mouse-y) / max(1px, root.slot)));
|
||||
// Fractional, so a slow drag moves the view continuously
|
||||
// rather than sitting still until it crosses a bucket edge.
|
||||
root.pan((self.press-y - self.mouse-y) / max(1px, root.track-height));
|
||||
self.press-y = self.mouse-y;
|
||||
} else if (self.pressed && root.bars.length > 0) {
|
||||
// Guarded like the press handler below: the sidebar is now
|
||||
// always present, so a drag across it on an undated library
|
||||
// would index an empty array.
|
||||
root.scrub(root.bars[root.bucket-at(self.mouse-y)].start);
|
||||
root.scrub-to(root.fraction-at(self.mouse-y));
|
||||
}
|
||||
root.hovered = root.bars.length > 0 ? root.bucket-at(self.mouse-y) : -1;
|
||||
}
|
||||
@@ -163,13 +197,12 @@ export component Timeline inherits Rectangle {
|
||||
pointer-event(e) => {
|
||||
if (e.kind == PointerEventKind.down) {
|
||||
self.press-y = self.mouse-y;
|
||||
// Middle button or shift pans; anything else scrubs.
|
||||
// Middle button pans. Shift is not consulted here: the
|
||||
// modifier state belongs to the key handler, not the pointer
|
||||
// event, and a middle-drag is the unambiguous gesture.
|
||||
self.panning = e.button == PointerEventButton.middle;
|
||||
if (!self.panning && root.bars.length > 0) {
|
||||
root.scrub(root.bars[root.bucket-at(self.mouse-y)].start);
|
||||
root.scrub-to(root.fraction-at(self.mouse-y));
|
||||
}
|
||||
}
|
||||
if (e.kind == PointerEventKind.up) { self.panning = false; }
|
||||
@@ -478,7 +511,7 @@ export component LibraryGrid inherits Rectangle {
|
||||
in property <bool> timeline-anchored: false;
|
||||
|
||||
callback scrub(int);
|
||||
callback timeline-pan(int);
|
||||
callback timeline-pan(float);
|
||||
callback timeline-zoom(int);
|
||||
callback columns-changed(int);
|
||||
callback sync-now();
|
||||
@@ -877,7 +910,8 @@ export component LibraryGrid inherits Rectangle {
|
||||
current-index: root.current-bucket-index;
|
||||
anchored: root.timeline-anchored;
|
||||
|
||||
scrub(t) => { root.scrub(t); }
|
||||
scrub-to(f) => { root.scrub-fraction(f); }
|
||||
pinch(r) => { root.timeline-pinch(r); }
|
||||
pan(d) => { root.timeline-pan(d); }
|
||||
zoom(d) => { root.timeline-zoom(d); }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user