Hang the auto-crop off the slider's commit, not off the pointer passing over
The straighten auto-crop worked once and then stopped. It was keyed on `PlainSlider::drag-changed`, whose name is a lie inherited from what it forwards: `SliderTrack` defines `engaged` as `has-hover || claimed`, and it has to — a `Flickable` withholds the press for 100ms, so hover is the only signal that arrives in time to stand the scrolling ancestor down. That is the right definition for the job it was written for and the wrong one for this. Keyed on hover, the correction fires when the pointer first crosses the track — before anything has been dragged — and then does not fire again for as long as the pointer stays on it, however many times the angle is changed. Which is exactly what "it only works once" looks like. `SliderTrack` already publishes the signal this wants. `committed` fires on release, once per gesture, after the final `changed`, and its doc comment says so in as many words. It was simply not forwarded through `PlainSlider`, so it now is, and the geometry panel's callback is a `committed(float)` rather than a `drag-changed(bool)`. The angle needs no re-applying here: the track emits its last `changed` before it commits, so the value is already in the graph by the time this runs. What is left is the correction that has to happen exactly once. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -324,6 +324,17 @@ component PlainSlider inherits Rectangle {
|
||||
in property <string> unit;
|
||||
|
||||
callback changed(float);
|
||||
/// The gesture is over and this is the value to keep.
|
||||
///
|
||||
/// **Not the same thing as `drag-changed`, which is hover.** `SliderTrack`
|
||||
/// defines `engaged` as `has-hover || claimed`, because a `Flickable`
|
||||
/// withholds the press and hover is the only signal that gets through in
|
||||
/// time to stand it down. That makes it exactly right for what it is for —
|
||||
/// telling a scrolling ancestor to let go — and exactly wrong for anything
|
||||
/// that must run once when the user has finished choosing: it fires on the
|
||||
/// way past without a drag at all, and then does not fire again while the
|
||||
/// pointer stays on the track, however many times the value is dragged.
|
||||
callback committed(float);
|
||||
callback reset();
|
||||
callback drag-changed(bool);
|
||||
|
||||
@@ -341,6 +352,7 @@ component PlainSlider inherits Rectangle {
|
||||
maximum: root.maximum;
|
||||
|
||||
changed(v) => { root.changed(v); }
|
||||
committed(v) => { root.committed(v); }
|
||||
reset => { root.reset(); }
|
||||
engaged-changed(on) => { root.drag-changed(on); }
|
||||
}
|
||||
@@ -512,10 +524,12 @@ export component GeometryPanel inherits Rectangle {
|
||||
callback flip-h-toggled();
|
||||
callback flip-v-toggled();
|
||||
callback angle-changed(float);
|
||||
/// The straightening gesture began or ended. What the auto-crop hangs
|
||||
/// off — see `DevelopSession::auto_crop_to_angle` for why it must be the
|
||||
/// end of the drag and not every frame of it.
|
||||
callback angle-drag-changed(bool);
|
||||
/// The straightening gesture is over and this is the angle to keep.
|
||||
///
|
||||
/// What the auto-crop hangs off — see `DevelopSession::auto_crop_to_angle`
|
||||
/// for why it must be the end of the drag and not every frame of it, and
|
||||
/// `PlainSlider::committed` for why it must not be `drag-changed`.
|
||||
callback angle-committed(float);
|
||||
callback angle-reset();
|
||||
callback aspect-picked(int);
|
||||
callback portrait-toggled();
|
||||
@@ -608,7 +622,7 @@ export component GeometryPanel inherits Rectangle {
|
||||
maximum: root.max-straighten;
|
||||
unit: "°";
|
||||
changed(v) => { root.angle-changed(v); }
|
||||
drag-changed(on) => { root.angle-drag-changed(on); }
|
||||
committed(v) => { root.angle-committed(v); }
|
||||
reset => { root.angle-reset(); }
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user