fix(plot,figure): re-index hot region, logical row floor, refuse live on a linked axis
Three smaller findings at the plot/figure seam: * `Plot::remove_region()` re-indexed `region_stats_` but left `hot_.region` naming the old index, so a frame after a removal highlighted the wrong region's bound and an open drag edited a different region. The published handle (and its zone) is now cleared or decremented with the cache, and the contract documents that a host must not remove a region mid-drag. * `Figure`'s `kMinRowHeightPx` was applied as a *device*-pixel floor while chrome is logical, so at 2x the guarantee was half as strong exactly where the chrome is twice as large. It is now a logical constant converted through the row's own `ui_scale()`, 1:1 for a non-positive scale as `Style::device()` does. * `Figure::link_x()` refused a member whose axis 0 was `XFollow::Live`, but nothing refused `set_x_follow(0u, XFollow::Live)` *after* linking. The group then wrote its range into an axis that reinterpreted it against its own live edge, read it back as an external change, and tracked one member instead of the union. `Plot` now carries a linkage flag (`set_x_link_member()`), set by `link_x()` and cleared by `unlink_row()`, and `set_x_follow()` refuses `Live` on a linked axis. Tests: arming `Live` on a linked member leaves it `Off` and unlinking restores the ability to arm it; the row-height floor is 24 and 48 device pixels at 1x and 2x respectively.
This commit is contained in:
1 parent
2fbd1de7d4
commit
1f5ce0d4a5
5 files changed
+123
-12
No files matched your search
@@ -79,6 +79,13 @@ struct Axis {
|
||||
/// group stops following or the row leaves it.
|
||||
bool live_owner = false;
|
||||
f64 live_owner_newest = 0.0;
|
||||
/// Set while this plot is a member of a `Figure` x link group (`Figure::link_x()`
|
||||
/// writes it, `unlink_row()` clears it). The group owns the shared x window *and*
|
||||
/// its follow state -- `Figure::link_x()` refuses a `Live` member joiner -- so
|
||||
/// `Plot::set_x_follow(Live)` on this axis is refused after linking too, rather
|
||||
/// than letting a later call put the member's axis back into a state the group
|
||||
/// cannot drive (see `Plot::set_x_follow()`).
|
||||
bool link_member = false;
|
||||
/// Ticks for the last `refresh()`, ascending, majors and (when asked) minors.
|
||||
std::vector<Tick> ticks;
|
||||
|
||||
|
||||
@@ -329,6 +329,11 @@ class Plot {
|
||||
/// newest sample* rather than a pair of numbers. With no live edge -- no trace on
|
||||
/// the axis, or none of them streaming -- nothing is recomputed and the axis
|
||||
/// keeps its stored range, `auto_scale` included, exactly as an `Off` axis does.
|
||||
///
|
||||
/// On an axis that is a member of a `Figure` x link group, arming `Live` is
|
||||
/// **refused** (the state is left as it was): the group owns the shared window and
|
||||
/// its follow state, exactly as `Figure::link_x()` refuses a `Live` member joiner.
|
||||
/// See `set_x_link_member()`.
|
||||
void set_x_follow(u32 axis, XFollow f);
|
||||
/// The follow state of one x axis. `Off` for an axis that does not exist.
|
||||
XFollow x_follow(u32 axis) const;
|
||||
@@ -363,6 +368,14 @@ class Plot {
|
||||
/// axis no owner has claimed, and for an axis that does not exist.
|
||||
bool x_live_owner(u32 axis, f64& newest) const noexcept;
|
||||
|
||||
/// Publishes -- or clears -- that this axis is a member of a `Figure` x link group.
|
||||
/// `Figure::link_x()` sets it when a row joins and `unlink_row()` clears it when one
|
||||
/// leaves; it is what makes `set_x_follow(Live)` refused on a linked axis, because
|
||||
/// the group owns the shared window and the follow state. A no-op for an axis that
|
||||
/// does not exist. Not for callers outside the figure: a `Plot` that is not in a
|
||||
/// figure never has a linked axis.
|
||||
void set_x_link_member(u32 axis, bool linked) noexcept;
|
||||
|
||||
/// Data -> pixels for one axis, built from the axis' range, log flag and the
|
||||
/// current layout. Always invertible: a collapsed range or a collapsed axes
|
||||
/// rect is widened by math::Transform, so to_data_*(to_screen_*(v)) == v.
|
||||
|
||||
Reference in new issue
Block a user