fix(plot,glfw): layer the crosshair under the handles, sync it across a figure, and harden the lookup
This commit is contained in:
1 parent
8e27e22ebe
commit
29824b6919
5 files changed
+183
-63
No files matched your search
@@ -107,6 +107,12 @@ class Host {
|
||||
/// `Renderer::draw(Figure&)`. The frame callback is handed the figure's **row 0**
|
||||
/// as its `Plot&`, so `plot()` and the frame argument agree.
|
||||
///
|
||||
/// The figure's **crosshair** follows the pointer as one crosshair and not one per row: the run
|
||||
/// loop reads the hover out of the row under the pointer and applies it to the whole figure
|
||||
/// (`sync_figure_crosshair()`), so every row's readout lists its own signals at the one x the
|
||||
/// pointer is over. That is what "synced if multiple plots available" means, and the host is the
|
||||
/// layer that can do it -- it is the one that knows which row the pointer is in.
|
||||
///
|
||||
/// The figure is borrowed and must outlive the run. Passing null restores the
|
||||
/// single-plot loop, which is what every other caller uses; the host's own
|
||||
/// `plot_` is then untouched by any of this.
|
||||
@@ -168,6 +174,28 @@ class Host {
|
||||
void on_scroll(f64 dx, f64 dy) noexcept;
|
||||
void on_key(int key, int action, int mods) noexcept;
|
||||
|
||||
/// The index of the figure row a framebuffer pixel belongs to, by the rule
|
||||
/// `controller_at()` routes by: the row the pixel is in, or the nearest row when it is in none
|
||||
/// (a row gap, or a margin outside the figure). 0 while no figure is set.
|
||||
u32 row_at(f32 x, f32 y) const noexcept;
|
||||
|
||||
/// Spreads the hover over a whole `Figure` (spec §15).
|
||||
///
|
||||
/// A figure's rows share one x, so the crosshair one row's controller placed is read back here and
|
||||
/// applied to every row: the controller turns a pointer position into a data coordinate -- which
|
||||
/// is its job, and the same one it does for a single plot -- and the figure spreads that one
|
||||
/// coordinate over its rows. Reading it back rather than deriving a second coordinate here is what
|
||||
/// keeps the hover the row shows and the hover the figure shows the same number.
|
||||
///
|
||||
/// The row it reads is the one under the host's pointer, or -- with no pointer of the host's own,
|
||||
/// which is how a scripted run injects its events -- the row whose crosshair is not the value this
|
||||
/// host spread last (`spread_x_`/`spread_active_`), i.e. the row something outside changed. A row
|
||||
/// whose controller has no crosshair clears the figure's.
|
||||
///
|
||||
/// Called once per frame from the run loop, so a scripted run that bypasses the GLFW callbacks
|
||||
/// gets the same synced figure a real pointer does.
|
||||
void sync_figure_crosshair() noexcept;
|
||||
|
||||
Plot plot_;
|
||||
input::Controller controller_; ///< forwards its viewport to `plot_`
|
||||
std::optional<Renderer> renderer_;
|
||||
@@ -183,6 +211,13 @@ class Host {
|
||||
/// no position of its own, and the row the pointer is over is the one the user is
|
||||
/// looking at.
|
||||
u32 last_row_ = 0u;
|
||||
/// The crosshair this host last spread over the figure (see
|
||||
/// `sync_figure_crosshair()`): what a row is compared against to find the one a
|
||||
/// scripted run touched, since the figure writes one value to every row.
|
||||
/// `spread_active_` false means "spread nothing" -- the state before the first
|
||||
/// sync, and the one a clear leaves.
|
||||
f64 spread_x_ = 0.0;
|
||||
bool spread_active_ = false;
|
||||
|
||||
u32 fb_width_ = 0; ///< framebuffer size of the last refresh_sizes()
|
||||
u32 fb_height_ = 0;
|
||||
|
||||
Reference in new issue
Block a user