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

+19
View File
@@ -2789,3 +2789,22 @@ PLOT_TEST(an_annotation_can_be_moved_by_id) {
p.set_annotation(42u, other);
PLOT_CHECK_NEAR(p.annotation(id).x, 3.5, 1e-12);
}
PLOT_TEST(the_selection_frame_is_carried_and_taken_off) {
// The box-zoom frame is the host's to set -- the plot has no controller and learns nothing about
// pointers -- so what it owes is to carry it: out through `layout()` unchanged, because it is
// already in viewport pixels and a second derivation would be a second rounding of the same
// rectangle, and gone when the host takes it off, because a frame left behind claims the selection
// is still open.
plot::Plot p;
p.set_viewport({0, 0, 800, 400});
PLOT_CHECK(p.layout().selection.w == 0.0f && p.layout().selection.h == 0.0f); // nothing swept
p.set_selection_rect({10.0f, 20.0f, 30.0f, 40.0f});
PLOT_CHECK_NEAR(p.selection_rect().x, 10.0, 1e-6);
PLOT_CHECK_NEAR(p.layout().selection.y, 20.0, 1e-6);
PLOT_CHECK_NEAR(p.layout().selection.w, 30.0, 1e-6);
PLOT_CHECK_NEAR(p.layout().selection.h, 40.0, 1e-6);
p.clear_selection_rect();
PLOT_CHECK_NEAR(p.selection_rect().w, 0.0, 1e-6);
PLOT_CHECK_NEAR(p.layout().selection.h, 0.0, 1e-6);
}