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
@@ -344,6 +344,21 @@ u32 PlotArea::pointer_row() const noexcept {
|
||||
return row_in(row_rects_, pointer_.y);
|
||||
}
|
||||
|
||||
void PlotArea::sync_selection_frames() noexcept {
|
||||
const auto frame_for = [](input::Controller& c) -> Rect {
|
||||
return c.drag_mode() == input::DragMode::BoxZoom ? c.selection_preview() : Rect{};
|
||||
};
|
||||
if (figure_ != nullptr) {
|
||||
for (u32 i = 0; i < row_controllers_.size(); ++i) {
|
||||
// An empty rect on the rows that are not choosing: `Rect` has no equality to compare
|
||||
// with, and a store of the same value is what keeps this path free of anything else.
|
||||
figure_->plot(i).set_selection_rect(frame_for(*row_controllers_[i]));
|
||||
}
|
||||
return;
|
||||
}
|
||||
plot_->set_selection_rect(frame_for(controller_));
|
||||
}
|
||||
|
||||
void PlotArea::sync_figure_crosshair() noexcept {
|
||||
if (row_rects_.empty() || row_controllers_.empty()) return;
|
||||
const u32 row_count = static_cast<u32>(row_rects_.size());
|
||||
@@ -534,6 +549,9 @@ void PlotArea::render() noexcept {
|
||||
// `::resize` ratio, not `gtk_widget_get_scale_factor()` -- the latter is the
|
||||
// ceiling under fractional scaling and would over-scale the chrome by up to 60%.
|
||||
renderer_->style().ui_scale = mapping_.factor;
|
||||
// After the scale and before the draw: the preview reads the row's layout, and a layout measured
|
||||
// with the previous frame's scale is not the one being drawn.
|
||||
sync_selection_frames();
|
||||
renderer_->begin_frame(static_cast<u32>(viewport.w), static_cast<u32>(viewport.h), viewport);
|
||||
if (figure_ != nullptr) {
|
||||
renderer_->draw(*figure_);
|
||||
|
||||
Reference in new issue
Block a user