fix(input,examples): a linked figure's wheel anchor uses the group's live edge, and every demo verdict reaches its exit status
Review fix pass 1 on the task 7 work; four findings, all closed. 1. The Qt demo's region sat across the middle of the window, which is exactly where its own scripted input check pans: after the check's box zoom the press opened DragMode::MoveRegion, the x range never moved, and the check printed 'input check pan FAIL' -- under an exit 0, because the verdict was printed and not returned. The region now rides the left sixth (as the GLFW demo's does), both checks pass, and the verdict is wired to the exit status. The same audit found two more printed-only verdicts -- the GTK demo's scripted-resize layout check and its screenshot write (and Qt's) -- now wired too. What stays printed-only is the screenshot line of the GLFW host and the ImGui widget, where the dump happens inside the adapter's frame loop. 2. A follow-ing link group was invisible to the input layer: a member's own axis must be XFollow::Off (link_x() refuses a Live member), so Controller's x_zoom_anchor() extrapolated a coordinate from the pointer instead of using the live edge and a wheel over a row's axis strip walked the window back by 19% of its width (behind 0.000000 -> 0.285809 s). The group now publishes its own edge to every member (Axis::live_owner + Plot::set_x_live_owner, written by Figure::push_link, cleared when the group stops following or the row unlinks), and x_zoom_anchor() reads it. Public-header addition, called out. Measured after: behind 0.012992 s and the window's right edge bit-identical to the edge the group published at the gesture. 3. The multiplot summary printed x_link_count() -- a number of groups -- under 'rows in it'. It now reports the members and the group count separately, and every row line carries its own group id. 4. Host::controller_at() promised to clamp a pixel in a row gap to the nearest row and only clamped below the last one, so a gap pixel went to row 0. It now selects by distance, and tests/test_glfw_host.cpp pins it with a 40 px gap -- the first coverage of the host's figure routing, which needs no window. New cases: tests/test_controller.cpp x2 (the anchor and the hint's lifecycle), tests/test_glfw_host.cpp x3 (routing, the gap, the single-plot fallback): 229 cases, 0 failed, ASan clean. All five demos exit 0, the three self-checking modes exit 0, and the amended assertions were confirmed failing against the pre-fix behaviour.
This commit is contained in:
1 parent
a70c381a1e
commit
daff60e3f0
14 files changed
+441
-55
No files matched your search
@@ -63,6 +63,19 @@ struct Axis {
|
||||
/// directly, and `Plot::layout()`'s placement, which re-clamps it against the
|
||||
/// retained window every frame. `Plot::x_offset()` reads it back.
|
||||
f64 offset = 0.0;
|
||||
/// Set by an *owner* that is following this axis' window on the plot's behalf: a
|
||||
/// `Figure` link group, while it follows, writes its own live edge here every frame.
|
||||
/// A member's own `follow` must be `Off` (`Figure::link_x()` refuses a `Live` member
|
||||
/// -- the group owns the shared window and its follow state), so without this the
|
||||
/// input layer could not see that the axis is following: the controller's wheel
|
||||
/// anchor would extrapolate a coordinate from the pointer instead of using the live
|
||||
/// edge, and a zoom made from the axis strip would walk the window back off the edge.
|
||||
///
|
||||
/// `live_owner_newest` is the *owner's* edge, not this plot's: rows may be fed at
|
||||
/// different rates, and a group's edge is the union of its members'. Cleared when the
|
||||
/// group stops following or the row leaves it.
|
||||
bool live_owner = false;
|
||||
f64 live_owner_newest = 0.0;
|
||||
/// Ticks for the last `refresh()`, ascending, majors and (when asked) minors.
|
||||
std::vector<Tick> ticks;
|
||||
|
||||
|
||||
@@ -213,6 +213,12 @@ class Figure {
|
||||
f64 offset = 0.0;
|
||||
XFollow follow = XFollow::Off;
|
||||
bool has_range = false;
|
||||
/// The group's live edge, as the last `place_live_window()` found it, and whether it
|
||||
/// found one at all. Published to every member by `push_link()` (`Plot::set_x_live_owner`)
|
||||
/// so the input layer can see that the member's window is following even though the
|
||||
/// member's own axis must be `Off`.
|
||||
f64 live_newest = 0.0;
|
||||
bool has_live = false;
|
||||
std::vector<u32> rows;
|
||||
std::vector<Range> pushed;
|
||||
};
|
||||
|
||||
@@ -325,6 +325,14 @@ class Plot {
|
||||
/// zoom made from outside `axes`. False -- and `newest` untouched -- when the axis
|
||||
/// has no such trace, i.e. when there is no live edge to follow.
|
||||
bool x_live_edge(u32 axis, f64& newest) const;
|
||||
/// Publishes -- or clears -- the live edge of an owner that is following this axis'
|
||||
/// window on the plot's behalf (a `Figure` link group while it follows; see
|
||||
/// `Axis::live_owner`). A no-op for an axis that does not exist.
|
||||
void set_x_live_owner(u32 axis, bool live, f64 newest) noexcept;
|
||||
/// Whether an owner is following this axis' window, and the edge it is following: the
|
||||
/// answer `set_x_live_owner()` last wrote. False -- and `newest` untouched -- for an
|
||||
/// axis no owner has claimed, and for an axis that does not exist.
|
||||
bool x_live_owner(u32 axis, f64& newest) const 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
|
||||
|
||||
Reference in new issue
Block a user