From: David Gow Date: Wed, 9 Apr 2014 06:40:43 +0000 (+0800) Subject: You can move around a document with Click+Drag! X-Git-Url: https://git.ucc.asn.au/?a=commitdiff_plain;h=e6c66a8e58f1dda071e6fc4abed39afe49d348f8;p=ipdf%2Fcode.git You can move around a document with Click+Drag! Uses some scary C++11 features, so no idea if this will break the CS Lab machines and their ancient version of gcc. --- diff --git a/src/main.h b/src/main.h index ee8076a..c7d5eca 100644 --- a/src/main.h +++ b/src/main.h @@ -12,6 +12,31 @@ inline void MainLoop(Document & doc) { View view(doc); Screen scr; + scr.SetMouseHandler([&](int x, int y, int buttons, int wheel) + { + static bool oldButtonDown = false; + static int oldx, oldy; + if (buttons && !oldButtonDown) + { + // We're beginning a drag. + oldButtonDown = true; + oldx = x; + oldy = y; + scr.SetMouseCursor(Screen::CursorMove); + } + if (buttons) + { + view.Translate(Real(oldx-x)/Real(scr.ViewportWidth()), Real(oldy-y)/Real(scr.ViewportHeight())); + } + else + { + oldButtonDown = false; + scr.SetMouseCursor(Screen::CursorArrow); + } + oldx = x; + oldy = y; + } + ); while (scr.PumpEvents()) { view.Render(); diff --git a/src/screen.cpp b/src/screen.cpp index 6909be2..d924c06 100644 --- a/src/screen.cpp +++ b/src/screen.cpp @@ -18,6 +18,8 @@ Screen::Screen() } m_gl_context = SDL_GL_CreateContext(m_window); + + ResizeViewport(800, 600); } @@ -55,6 +57,19 @@ bool Screen::PumpEvents() break; } break; + case SDL_MOUSEMOTION: + if (m_mouse_handler) + { + m_mouse_handler(evt.motion.x, evt.motion.y,evt.motion.state, 0); + } + break; + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: + if (m_mouse_handler) + { + m_mouse_handler(evt.button.x, evt.button.y, evt.button.state, 0); + } + break; default: break; } @@ -62,6 +77,23 @@ bool Screen::PumpEvents() return no_quit_requested; } +void Screen::SetMouseCursor(Screen::MouseCursors cursor) +{ + SDL_SystemCursor system_cursor_id = SDL_SYSTEM_CURSOR_ARROW; + switch (cursor) + { + case CursorArrow: system_cursor_id = SDL_SYSTEM_CURSOR_ARROW; break; + case CursorWait: system_cursor_id = SDL_SYSTEM_CURSOR_WAIT; break; + case CursorWaitArrow: system_cursor_id = SDL_SYSTEM_CURSOR_WAITARROW; break; + case CursorMove: system_cursor_id = SDL_SYSTEM_CURSOR_SIZEALL; break; + case CursorHand: system_cursor_id = SDL_SYSTEM_CURSOR_HAND; break; + default: break; + } + SDL_Cursor *system_cursor = SDL_CreateSystemCursor(system_cursor_id); + SDL_SetCursor(system_cursor); + //TODO: Check if we need to free the system cursors. +} + void Screen::Present() { SDL_GL_SwapWindow(m_window); diff --git a/src/screen.h b/src/screen.h index ebe9da2..8452efc 100644 --- a/src/screen.h +++ b/src/screen.h @@ -3,6 +3,8 @@ #include +#include + namespace IPDF { /* @@ -24,14 +26,34 @@ namespace IPDF // Get the current width/height of the window's viewport. int ViewportWidth() { return m_viewport_width; } int ViewportHeight() { return m_viewport_height; } + + // Handle mouse input. + typedef std::function MouseHandler; + void SetMouseHandler(MouseHandler handler) + { + m_mouse_handler = handler; + } + + enum MouseCursors + { + CursorArrow, + CursorWait, + CursorWaitArrow, + CursorMove, + CursorHand + }; + void SetMouseCursor(MouseCursors cursor); private: void ResizeViewport(int width, int height); + + MouseHandler m_mouse_handler; int m_viewport_width; int m_viewport_height; SDL_Window *m_window; SDL_GLContext m_gl_context; }; + } #endif // _SCREEN_H diff --git a/src/view.cpp b/src/view.cpp index ed62704..f78ec40 100644 --- a/src/view.cpp +++ b/src/view.cpp @@ -5,6 +5,12 @@ using namespace IPDF; using namespace std; +void View::Translate(Real x, Real y) +{ + m_bounds.x += x; + m_bounds.y += y; +} + void View::Render() { static bool debug_output_done = false; diff --git a/src/view.h b/src/view.h index 9a519b0..cc09a89 100644 --- a/src/view.h +++ b/src/view.h @@ -13,6 +13,8 @@ namespace IPDF virtual ~View() {} void Render(); + + void Translate(Real x, Real y); private: Document & m_document;