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:
1 parent
1fc97d818f
commit
be1f31a04f
14 files changed
+276
-1
No files matched your search
@@ -545,6 +545,9 @@ void Renderer::draw_plot(Plot& plot, const PlotLayout& layout) {
|
||||
// panel is drawn over the legend and every other overlay rather than under them, and its
|
||||
// text joins the frame's over flush with the tick labels and titles.
|
||||
draw_crosshair_readout(plot, layout);
|
||||
// The selection frame last of all: it is the gesture still in progress, and nothing inside the axes
|
||||
// should be able to sit on top of the area being chosen.
|
||||
draw_selection_frame(layout);
|
||||
clear_clip();
|
||||
draw_tick_labels(plot, layout);
|
||||
draw_titles(plot, layout);
|
||||
@@ -1960,6 +1963,27 @@ void Renderer::stage_marker(plot::Marker marker, Vec2 centre_px, f32 size_px) {
|
||||
}
|
||||
}
|
||||
|
||||
void Renderer::draw_selection_frame(const PlotLayout& layout) {
|
||||
const Rect& frame = layout.selection;
|
||||
// Two guards, not one: a drag swept flat in one direction has a real extent on one axis and none on
|
||||
// the other, and a border on that is still the gesture's own answer -- the fill is what a zero
|
||||
// extent has nothing of.
|
||||
if (!(frame.w > 0.0f) && !(frame.h > 0.0f)) return;
|
||||
if (frame.w > 0.0f && frame.h > 0.0f) fill_pixels(frame, style_.selection_fill);
|
||||
// The border frames the pixels the fill covers and not the measured rect's own fractional edges:
|
||||
// the readout panel's rounding and the readout panel's reason, since a hairline straddling a
|
||||
// fractional edge is a frame bright on two sides and dim on the others.
|
||||
const f32 left = std::ceil(frame.x - 0.5f) + 0.5f;
|
||||
const f32 right = std::ceil(frame.right() - 0.5f) - 0.5f;
|
||||
const f32 top = std::ceil(frame.y - 0.5f) + 0.5f;
|
||||
const f32 bottom = std::ceil(frame.bottom() - 0.5f) - 0.5f;
|
||||
lines_.add_segment({left, top}, {right, top});
|
||||
lines_.add_segment({left, bottom}, {right, bottom});
|
||||
lines_.add_segment({left, top}, {left, bottom});
|
||||
lines_.add_segment({right, top}, {right, bottom});
|
||||
flush_lines(pixel_mapping(), style_.selection_edge, style_.device(1.0f));
|
||||
}
|
||||
|
||||
void Renderer::draw_readout_panel(const Rect& panel, Color border) {
|
||||
if (!(panel.w > 0.0f) || !(panel.h > 0.0f)) return;
|
||||
// The frame's own background at a partial alpha, which dims whatever it covers instead of erasing
|
||||
|
||||
Reference in new issue
Block a user