From a269b3e29535918a390f448829a3459e4853425b Mon Sep 17 00:00:00 2001 From: David Gow Date: Wed, 9 Apr 2014 16:01:54 +0800 Subject: [PATCH] Zoom in and out with the mouse wheel. Note that zoom-out is totally broken with half-precision, so single-precision is the default. You can still see some artefacts in single precision mode if you zoom in enough. Zoom into the corner of a rectangle and then click on the corner an try to drag it. Eventually you'll notice the reduced precision, and the rectangle will jump around. --- src/main.h | 5 +++++ src/real.h | 4 ++-- src/screen.cpp | 10 ++++++++++ src/screen.h | 2 ++ src/view.cpp | 24 ++++++++++++++++++++++++ src/view.h | 1 + 6 files changed, 44 insertions(+), 2 deletions(-) diff --git a/src/main.h b/src/main.h index c7d5eca..2346119 100644 --- a/src/main.h +++ b/src/main.h @@ -35,6 +35,11 @@ inline void MainLoop(Document & doc) } oldx = x; oldy = y; + + if (wheel) + { + view.ScaleAroundPoint(Real(x)/Real(scr.ViewportWidth()),Real(y)/Real(scr.ViewportHeight()), expf(-wheel/20.f)); + } } ); while (scr.PumpEvents()) diff --git a/src/real.h b/src/real.h index a7f56be..5703671 100644 --- a/src/real.h +++ b/src/real.h @@ -6,9 +6,9 @@ namespace IPDF { -//#define REAL_FLOAT +#define REAL_SINGLE //#define REAL_DOUBLE -#define REAL_HALF +//#define REAL_HALF #ifdef REAL_SINGLE typedef float Real; diff --git a/src/screen.cpp b/src/screen.cpp index d924c06..9ee15b4 100644 --- a/src/screen.cpp +++ b/src/screen.cpp @@ -58,6 +58,8 @@ bool Screen::PumpEvents() } break; case SDL_MOUSEMOTION: + m_last_mouse_x = evt.motion.x; + m_last_mouse_y = evt.motion.y; if (m_mouse_handler) { m_mouse_handler(evt.motion.x, evt.motion.y,evt.motion.state, 0); @@ -65,11 +67,19 @@ bool Screen::PumpEvents() break; case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: + m_last_mouse_x = evt.button.x; + m_last_mouse_y = evt.button.y; if (m_mouse_handler) { m_mouse_handler(evt.button.x, evt.button.y, evt.button.state, 0); } break; + case SDL_MOUSEWHEEL: + if (m_mouse_handler) + { + m_mouse_handler(m_last_mouse_x, m_last_mouse_y, 0, evt.wheel.y); + } + break; default: break; } diff --git a/src/screen.h b/src/screen.h index 8452efc..4d92cb3 100644 --- a/src/screen.h +++ b/src/screen.h @@ -47,6 +47,8 @@ namespace IPDF void ResizeViewport(int width, int height); MouseHandler m_mouse_handler; + int m_last_mouse_x; + int m_last_mouse_y; int m_viewport_width; int m_viewport_height; diff --git a/src/view.cpp b/src/view.cpp index f78ec40..80f4986 100644 --- a/src/view.cpp +++ b/src/view.cpp @@ -7,10 +7,34 @@ using namespace std; void View::Translate(Real x, Real y) { + x *= m_bounds.w; + y *= m_bounds.h; m_bounds.x += x; m_bounds.y += y; } +void View::ScaleAroundPoint(Real x, Real y, Real scaleAmt) +{ + // Convert to local coords. + x *= m_bounds.w; + y *= m_bounds.h; + x += m_bounds.x; + y += m_bounds.y; + + Debug("Mouse wheel event %f %f %f\n", Float(x), Float(y), Float(scaleAmt)); + + Real top = y - m_bounds.y; + Real left = x - m_bounds.x; + + top *= scaleAmt; + left *= scaleAmt; + + m_bounds.x = x - left; + m_bounds.y = y - top; + m_bounds.w *= scaleAmt; + m_bounds.h *= scaleAmt; +} + void View::Render() { static bool debug_output_done = false; diff --git a/src/view.h b/src/view.h index cc09a89..6b63799 100644 --- a/src/view.h +++ b/src/view.h @@ -15,6 +15,7 @@ namespace IPDF void Render(); void Translate(Real x, Real y); + void ScaleAroundPoint(Real x, Real y, Real scaleAmt); private: Document & m_document; -- 2.20.1