fix(input): cursors follow the pointer while dragging and snap on drop

This commit is contained in:
Martino Ferrari committed 2026-09-28 20:46:14 +02:00
1 parent ea70cf4fca
commit d2ba67921e
7 files changed
+292 -27

No files matched your search

+22 -4
View File
@@ -571,7 +571,7 @@ void Plot::autoscale_axes() {
}
}
void Plot::set_cursor_x(u32 id, f64 x) {
void Plot::set_cursor_x(u32 id, f64 x, CursorPlacement placement) {
if (id >= cursors_.size()) return;
Cursor& cursor = cursors_[id];
// `x` is the vertical cursor's coordinate and nobody else's: a ruler's `x` is dead, and
@@ -579,10 +579,26 @@ void Plot::set_cursor_x(u32 id, f64 x) {
// cursor is (see CursorOrientation).
if (cursor.is_horizontal()) return;
cursor.x = x;
cursor.x = snapped_x(cursor);
// `Free` stores the value and stops: a drag moves the marker under the pointer and the
// snap is a separate act (`snap_cursor()`), which is what keeps the two orientations
// agreeing about *when* they land on their grid -- see CursorPlacement.
if (placement == CursorPlacement::Snapped) cursor.x = snapped_x(cursor);
mark_measures_dirty();
}
void Plot::snap_cursor(u32 id) {
if (id >= cursors_.size()) return;
const Cursor& cursor = cursors_[id];
// One act, the orientation's own rule: the ruler's half of the same shape a region's
// `snap_region()` has. Both setters default to `Snapped`, so re-storing the coordinate
// the cursor already holds is what applies the rule.
if (cursor.is_horizontal()) {
set_cursor_y(id, cursor.y);
} else {
set_cursor_x(id, cursor.x);
}
}
void Plot::set_cursor_snap(u32 id, SnapMode mode) {
if (id >= cursors_.size()) return;
Cursor& cursor = cursors_[id];
@@ -595,12 +611,14 @@ void Plot::set_cursor_snap(u32 id, SnapMode mode) {
mark_measures_dirty();
}
void Plot::set_cursor_y(u32 id, f64 y) {
void Plot::set_cursor_y(u32 id, f64 y, CursorPlacement placement) {
if (id >= cursors_.size()) return;
Cursor& ruler = cursors_[id];
if (!ruler.is_horizontal()) return;
ruler.y = y;
ruler.y = snapped_y(ruler);
// As `set_cursor_x()`: `Free` is the drag's half of the gesture, and `snap_cursor()`
// commits the ruler's own rule on release.
if (placement == CursorPlacement::Snapped) ruler.y = snapped_y(ruler);
// No mark_measures_dirty(), for `add_h_ruler()`'s reason: a measurement is read from two
// x coordinates, and a ruler's y is not one of them.
}