fix(input): refuse non-finite region bounds, keep narrow regions movable, republish hot handles
This commit is contained in:
1 parent
4681d7015b
commit
7cc06f07f5
7 files changed
+263
-19
No files matched your search
@@ -83,16 +83,22 @@ using plot::RegionGrab;
|
||||
/// dragging either of the cursors that bound it, because its edges *are* those
|
||||
/// cursors -- no second path, no second tolerance.
|
||||
/// 2. **Regions next**, resolved nearest-first against the geometry `Plot::layout()`
|
||||
/// measured: a bound inside the grab radius beats the body (so the bound of a
|
||||
/// measured: a bound within the grab radius beats the body (so the bound of a
|
||||
/// wide region is grabbable even though the pointer is inside the fill), the
|
||||
/// nearer of the two bounds wins, and with no bound in range the topmost region
|
||||
/// whose interior holds the pointer is the body.
|
||||
/// whose interior holds the pointer is the body. The radius is the one above, cut
|
||||
/// back when a region is too narrow to hold a band at each end *and* an interior:
|
||||
/// a region narrower than twice it would otherwise have every interior point
|
||||
/// within a bound's reach, and could be resized but never moved.
|
||||
/// 3. **Nothing hot**, and the press pans.
|
||||
///
|
||||
/// A region narrower than a few logical pixels is a click rather than an edge grab:
|
||||
/// its two bounds are under the pointer together, so an edge would always win and
|
||||
/// the region could never be moved again once collapsed. Such a region is
|
||||
/// grabbed by its body instead, widened to that same minimum, and it stays movable.
|
||||
/// grabbed by its body instead, widened to that same minimum, and it stays movable --
|
||||
/// and between that minimum and twice the grab radius, where the two bounds would
|
||||
/// still cover every interior point, the edge bands are cut back until the middle is
|
||||
/// left, so a region in that band of widths can be moved as well as resized.
|
||||
/// The *body* drag translates both bounds by one delta -- the width is preserved
|
||||
/// exactly -- while a bound drag moves one end and leaves the other where it was,
|
||||
/// so a drag that crosses one bound over the other swaps them rather than inverting
|
||||
@@ -103,7 +109,8 @@ using plot::RegionGrab;
|
||||
/// both ends back to where they started and never move at all.
|
||||
///
|
||||
/// The hovered and grabbed handles are published to the plot
|
||||
/// (`Plot::set_hot_handles()`) after every pointer event, so the renderer draws them
|
||||
/// (`Plot::set_hot_handles()`) after every event that can move the geometry under the
|
||||
/// pointer -- a pointer event, a wheel notch, a key stroke -- so the renderer draws them
|
||||
/// highlighted without knowing what a pointer is; `hovered_cursor()`,
|
||||
/// `grabbed_cursor()`, `hovered_region()`, `grabbed_region()` and `region_grab()` are
|
||||
/// the same answer for a host that wants it directly -- a resize cursor, a tooltip,
|
||||
@@ -190,7 +197,8 @@ class Controller {
|
||||
/// The region the pointer is on, or `kInvalid`. `region_grab()` says which zone.
|
||||
u64 hovered_region() const;
|
||||
/// Which zone of `region` the pointer is on: the bound nearest within the grab
|
||||
/// radius (`Left`/`Right`), else `Body` when the pointer is inside the interval --
|
||||
/// radius (`Left`/`Right`) -- cut back for a narrow region, see `zone_hit()` -- else
|
||||
/// `Body` when the pointer is inside the interval --
|
||||
/// widened to the minimum a collapsed region keeps -- and `None` when it is on
|
||||
/// neither, when the pointer is outside the plot area, or when no pointer has been
|
||||
/// seen yet. What a host sets its resize cursor from; an id that names no region
|
||||
@@ -229,6 +237,10 @@ class Controller {
|
||||
RegionGrab zone = RegionGrab::None;
|
||||
f32 distance = 0.0f;
|
||||
};
|
||||
/// The band a bound answers to is the controller's grab radius, cut back so that a
|
||||
/// narrow region keeps an interior a body drag can reach (see the class comment):
|
||||
/// `min(radius, (width - minimum interior) / 2)`, and no band at all when the two
|
||||
/// bounds are closer together than the minimum width that separates them.
|
||||
ZoneHit zone_hit(const RegionLayout& region, f32 px, f32 py) const;
|
||||
/// Resolves that hit against the geometry `Plot::layout()` measured -- the same
|
||||
/// rects the renderer paints, so what is drawn and what can be grabbed cannot
|
||||
@@ -242,8 +254,10 @@ class Controller {
|
||||
/// the width -- so a changed pointer motion never accumulates error.
|
||||
bool begin_handle_drag(const PointerEvent& e);
|
||||
/// Publishes what the pointer is on to the plot, for the renderer to highlight
|
||||
/// (see HotHandles). Called after every pointer event, so hover and grab are the
|
||||
/// same answer the hit test gave.
|
||||
/// (see HotHandles). Called after every event that can move the geometry under the
|
||||
/// pointer -- a pointer event, a wheel notch, a key stroke -- so hover and grab are
|
||||
/// always the answer the hit test gives for the geometry of this frame rather than
|
||||
/// the geometry of the last time the pointer moved.
|
||||
void publish_hot();
|
||||
|
||||
/// The data x a zoom of `axis` holds fixed, for a gesture at (px, py). The
|
||||
|
||||
Reference in new issue
Block a user