e0cdd95a3b08344538e2928e1a8ad4b9dea036b0
Every pixel-to-data conversion in the controller now maps through the same rectangle Plot::x_transform/y_transform are built from: - pan() derives the scale from layout().axes.w/.h, so a drag moves the grabbed data point by exactly the drag distance (the viewport model stranded it behind the pointer by the label-strip fraction). - apply_box_zoom() clamps the selection to layout().axes and sets each range from the transforms (x_transform().to_data_x(l/r), y_transform() .to_data_y(bottom/top)); the selection's bottom edge is the y minimum. - end_drag() takes the release event and refreshes the selection from its coordinates before applying, so a host that reports only press and release still frames the box instead of degrading it to a click. - axis_zoom() uses a per-pixel sensitivity (200 px == one decade) rather than reusing the wheel's per-notch constant, so a pixel drag is no longer treated as a wheel notch. Tests now assert the grab-and-drag invariant through the transform (the old pixel-fraction assertions certified the viewport defect), add a press+release-only box zoom, and pin the axis-zoom magnitude.
Languages
C++
95.7%
CMake
2.4%
Python
1.7%
Shell
0.2%