feat: an open box zoom draws the frame the release will apply

The controller has always tracked its selection; nothing drew it, so a Ctrl or
Shift drag framed a range with no feedback until the release.

The preview is the area the release will change, not what the pointer swept:
Ctrl frames the x range only, so a band across the plot is what it will zoom,
where the sliver a straight horizontal drag sweeps is only the gesture. The
plot carries the rect a host hands it -- it learns nothing about pointers --
and the renderer draws a low-alpha fill under a light border over everything
else inside the axes.
This commit is contained in:
Martino Ferrari committed 2026-10-11 11:07:55 +02:00
1 parent 1fc97d818f
commit be1f31a04f
14 files changed
+276 -1

No files matched your search

+11
View File
@@ -397,6 +397,17 @@ class PlotArea {
/// Spreads one row's crosshair over the whole figure (see "Figure mode"). Run once
/// per frame, from the render callback, after this frame's row rects are cached.
void sync_figure_crosshair() noexcept;
/// Hands each row's plot the box-zoom frame its controller is showing, or takes it off
/// the ones whose gesture is over. Run once per frame from the render callback, like
/// the crosshair's spread and for a related reason: a frame has to go away when a drag
/// ends by *any* route -- the release, Escape, a row rebuilt mid-gesture -- and a
/// per-event hook would have to be repeated at every one of them, which is how a frame
/// ends up stuck on screen after a cancelled zoom.
///
/// Reads `selection_preview()`, which needs the row's layout, only for a controller
/// actually in `BoxZoom`: the cost is paid while a range is being chosen and never
/// otherwise.
void sync_selection_frames() noexcept;
/// `figure_->set_viewport(px)`, one `layout()` into the rect cache, and each row's
/// own rect to its controller. The figure-mode half of `refresh_viewport()` and of
/// `render()`, which must not drift apart.