1 /*
2  Copyright (C) 2010-2014 Kristian Duske
3 
4  This file is part of TrenchBroom.
5 
6  TrenchBroom is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  TrenchBroom is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with TrenchBroom. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include "CameraTool2D.h"
21 
22 #include "Preferences.h"
23 #include "PreferenceManager.h"
24 #include "View/InputState.h"
25 #include "Renderer/OrthographicCamera.h"
26 
27 namespace TrenchBroom {
28     namespace View {
CameraTool2D(Renderer::OrthographicCamera & camera)29         CameraTool2D::CameraTool2D(Renderer::OrthographicCamera& camera) :
30         ToolControllerBase(),
31         Tool(true),
32         m_camera(camera) {}
33 
doGetTool()34         Tool* CameraTool2D::doGetTool() {
35             return this;
36         }
37 
doMouseScroll(const InputState & inputState)38         void CameraTool2D::doMouseScroll(const InputState& inputState) {
39             if (zoom(inputState)) {
40                 const float speed = pref(Preferences::CameraMouseWheelInvert) ? -1.0f : 1.0f;
41                 if (inputState.scrollY() != 0.0f) {
42                     const Vec2f mousePos(static_cast<float>(inputState.mouseX()), static_cast<float>(inputState.mouseY()));
43                     const Vec3f oldWorldPos = m_camera.unproject(mousePos.x(), mousePos.y(), 0.0f);
44 
45                     const float factor = 1.0f + inputState.scrollY() / 50.0f * speed;
46                     m_camera.zoom(factor);
47 
48                     const Vec3f newWorldPos = m_camera.unproject(mousePos.x(), mousePos.y(), 0.0f);
49                     const Vec3f delta = newWorldPos - oldWorldPos;
50                     m_camera.moveBy(-delta);
51                 }
52             }
53         }
54 
doStartMouseDrag(const InputState & inputState)55         bool CameraTool2D::doStartMouseDrag(const InputState& inputState) {
56             if (pan(inputState)) {
57                 m_lastMousePos = Vec2f(static_cast<float>(inputState.mouseX()),
58                                        static_cast<float>(inputState.mouseY()));
59                 return true;
60             }
61             return false;
62         }
63 
doMouseDrag(const InputState & inputState)64         bool CameraTool2D::doMouseDrag(const InputState& inputState) {
65             if (pan(inputState)) {
66                 const Vec2f currentMousePos(static_cast<float>(inputState.mouseX()), static_cast<float>(inputState.mouseY()));
67                 const Vec3f lastWorldPos = m_camera.unproject(m_lastMousePos.x(), m_lastMousePos.y(), 0.0f);
68                 const Vec3f currentWorldPos = m_camera.unproject(currentMousePos.x(), currentMousePos.y(), 0.0f);
69                 const Vec3f delta = currentWorldPos - lastWorldPos;
70                 m_camera.moveBy(-delta);
71                 m_lastMousePos = currentMousePos;
72                 return true;
73             }
74             return false;
75         }
76 
doEndMouseDrag(const InputState & inputState)77         void CameraTool2D::doEndMouseDrag(const InputState& inputState) {}
doCancelMouseDrag()78         void CameraTool2D::doCancelMouseDrag() {}
79 
doCancel()80         bool CameraTool2D::doCancel() {
81             return false;
82         }
83 
zoom(const InputState & inputState) const84         bool CameraTool2D::zoom(const InputState& inputState) const {
85             return (inputState.mouseButtonsPressed(MouseButtons::MBNone) &&
86                     inputState.modifierKeysPressed(ModifierKeys::MKNone));
87         }
88 
look(const InputState & inputState) const89         bool CameraTool2D::look(const InputState& inputState) const {
90             return (inputState.mouseButtonsPressed(MouseButtons::MBRight) &&
91                     inputState.modifierKeysPressed(ModifierKeys::MKNone));
92         }
93 
pan(const InputState & inputState) const94         bool CameraTool2D::pan(const InputState& inputState) const {
95             return inputState.mouseButtonsPressed(MouseButtons::MBRight) || inputState.mouseButtonsPressed(MouseButtons::MBMiddle);
96         }
97     }
98 }
99