Make zooming feel more linear

with a "good enough" implementation
This commit is contained in:
moex3 2021-04-21 00:22:18 +02:00 committed by Sodra
parent db6297c8c3
commit 09ea0f54d3
2 changed files with 12 additions and 10 deletions

View File

@ -399,7 +399,7 @@ void VideoDisplay::OnMouseWheel(wxMouseEvent& event) {
if (event.ControlDown()) if (event.ControlDown())
SetWindowZoom(windowZoomValue + .125 * (wheel / event.GetWheelDelta())); SetWindowZoom(windowZoomValue + .125 * (wheel / event.GetWheelDelta()));
else else
SetVideoZoom(videoZoomValue + .125 * (wheel / event.GetWheelDelta())); SetVideoZoom(wheel / event.GetWheelDelta());
} }
} }
@ -434,17 +434,19 @@ void VideoDisplay::SetWindowZoom(double value) {
UpdateSize(); UpdateSize();
} }
void VideoDisplay::SetVideoZoom(double value) { void VideoDisplay::SetVideoZoom(int step) {
if (value == 0) return; if (step == 0) return;
value = std::max(value, .125); double newVideoZoom = videoZoomValue + (.125 * step) * videoZoomValue;
if (newVideoZoom < 0.125 || newVideoZoom > 10.0)
return;
// With the current blackbox algorithm in PositionVideo(), viewport_{width,height} could go negative. Stop that here // With the current blackbox algorithm in PositionVideo(), viewport_{width,height} could go negative. Stop that here
wxSize cs = GetClientSize(); wxSize cs = GetClientSize();
wxSize videoNewSize = videoSize * (value / videoZoomValue); wxSize videoNewSize = videoSize * (newVideoZoom / videoZoomValue);
float windowAR = (float)cs.GetWidth() / cs.GetHeight(); float windowAR = (float)cs.GetWidth() / cs.GetHeight();
float videoAR = (float)videoNewSize.GetWidth() / videoNewSize.GetHeight(); float videoAR = (float)videoNewSize.GetWidth() / videoNewSize.GetHeight();
if (windowAR < videoAR) { if (windowAR < videoAR) {
float delta = cs.GetHeight() - cs.GetWidth() / videoAR; int delta = cs.GetHeight() - cs.GetWidth() / videoAR;
if (videoNewSize.GetHeight() - delta < 0) if (videoNewSize.GetHeight() - delta < 0)
return; return;
} }
@ -453,13 +455,13 @@ void VideoDisplay::SetVideoZoom(double value) {
Vector2D mp = GetMousePosition() * videoZoomValue * windowZoomValue; Vector2D mp = GetMousePosition() * videoZoomValue * windowZoomValue;
// The video size will change by this many pixels // The video size will change by this many pixels
int pixelChangeW = videoSize.GetWidth() * (value / videoZoomValue - 1); int pixelChangeW = std::lround(videoSize.GetWidth() * (newVideoZoom / videoZoomValue - 1.0));
int pixelChangeH = videoSize.GetHeight() * (value / videoZoomValue - 1); int pixelChangeH = std::lround(videoSize.GetHeight() * (newVideoZoom / videoZoomValue - 1.0));
pan_x -= pixelChangeW * (mp.X() / videoSize.GetWidth()); pan_x -= pixelChangeW * (mp.X() / videoSize.GetWidth());
pan_y -= pixelChangeH * (mp.Y() / videoSize.GetHeight()); pan_y -= pixelChangeH * (mp.Y() / videoSize.GetHeight());
videoZoomValue = value; videoZoomValue = newVideoZoom;
UpdateSize(); UpdateSize();
} }

View File

@ -168,7 +168,7 @@ public:
/// @brief Set the zoom level /// @brief Set the zoom level
/// @param value The new zoom level /// @param value The new zoom level
void SetWindowZoom(double value); void SetWindowZoom(double value);
void SetVideoZoom(double value); void SetVideoZoom(int step);
/// @brief Get the current zoom level /// @brief Get the current zoom level
double GetZoom() const { return windowZoomValue; } double GetZoom() const { return windowZoomValue; }