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 "ToolChain.h"
21 
22 #include "View/ToolController.h"
23 
24 #include <cassert>
25 
26 namespace TrenchBroom {
27     namespace View {
ToolChain()28         ToolChain::ToolChain() :
29         m_tool(NULL),
30         m_suffix(NULL) {}
31 
~ToolChain()32         ToolChain::~ToolChain() {
33             delete m_suffix;
34             delete m_tool;
35         }
36 
append(ToolController * tool)37         void ToolChain::append(ToolController* tool) {
38             assert(checkInvariant());
39             if (chainEndsHere()) {
40                 assert(m_suffix == NULL);
41                 m_tool = tool;
42                 m_suffix = new ToolChain();
43             } else {
44                 assert(m_suffix != NULL);
45                 m_suffix->append(tool);
46             }
47             assert(checkInvariant());
48         }
49 
pick(const InputState & inputState,Model::PickResult & pickResult)50         void ToolChain::pick(const InputState& inputState, Model::PickResult& pickResult) {
51             assert(checkInvariant());
52             if (!chainEndsHere()) {
53                 m_tool->pick(inputState, pickResult);
54                 m_suffix->pick(inputState, pickResult);
55             }
56         }
57 
modifierKeyChange(const InputState & inputState)58         void ToolChain::modifierKeyChange(const InputState& inputState) {
59             assert(checkInvariant());
60             if (!chainEndsHere()) {
61                 m_tool->modifierKeyChange(inputState);
62                 m_suffix->modifierKeyChange(inputState);
63             }
64         }
65 
mouseDown(const InputState & inputState)66         void ToolChain::mouseDown(const InputState& inputState) {
67             assert(checkInvariant());
68             if (!chainEndsHere()) {
69                 m_tool->mouseDown(inputState);
70                 m_suffix->mouseDown(inputState);
71             }
72         }
73 
mouseUp(const InputState & inputState)74         void ToolChain::mouseUp(const InputState& inputState) {
75             assert(checkInvariant());
76             if (!chainEndsHere()) {
77                 m_tool->mouseUp(inputState);
78                 m_suffix->mouseUp(inputState);
79             }
80         }
81 
mouseClick(const InputState & inputState)82         bool ToolChain::mouseClick(const InputState& inputState) {
83             assert(checkInvariant());
84             if (chainEndsHere())
85                 return false;
86             if (m_tool->mouseClick(inputState))
87                 return true;
88             return m_suffix->mouseClick(inputState);
89         }
90 
mouseDoubleClick(const InputState & inputState)91         bool ToolChain::mouseDoubleClick(const InputState& inputState) {
92             assert(checkInvariant());
93             if (chainEndsHere())
94                 return false;
95             if (m_tool->mouseDoubleClick(inputState))
96                 return true;
97             return m_suffix->mouseDoubleClick(inputState);
98         }
99 
mouseScroll(const InputState & inputState)100         void ToolChain::mouseScroll(const InputState& inputState) {
101             assert(checkInvariant());
102             if (!chainEndsHere()) {
103                 m_tool->mouseScroll(inputState);
104                 m_suffix->mouseScroll(inputState);
105             }
106         }
107 
mouseMove(const InputState & inputState)108         void ToolChain::mouseMove(const InputState& inputState) {
109             assert(checkInvariant());
110             if (!chainEndsHere()) {
111                 m_tool->mouseMove(inputState);
112                 m_suffix->mouseMove(inputState);
113             }
114         }
115 
startMouseDrag(const InputState & inputState)116         ToolController* ToolChain::startMouseDrag(const InputState& inputState) {
117             assert(checkInvariant());
118             if (chainEndsHere())
119                 return NULL;
120             if (m_tool->startMouseDrag(inputState))
121                 return m_tool;
122             return m_suffix->startMouseDrag(inputState);
123         }
124 
dragEnter(const InputState & inputState,const String & payload)125         ToolController* ToolChain::dragEnter(const InputState& inputState, const String& payload) {
126             assert(checkInvariant());
127             if (chainEndsHere())
128                 return NULL;
129             if (m_tool->dragEnter(inputState, payload))
130                 return m_tool;
131             return m_suffix->dragEnter(inputState, payload);
132         }
133 
setRenderOptions(const InputState & inputState,Renderer::RenderContext & renderContext) const134         void ToolChain::setRenderOptions(const InputState& inputState, Renderer::RenderContext& renderContext) const {
135             assert(checkInvariant());
136             if (!chainEndsHere()) {
137                 m_tool->setRenderOptions(inputState, renderContext);
138                 m_suffix->setRenderOptions(inputState, renderContext);
139             }
140         }
141 
render(const InputState & inputState,Renderer::RenderContext & renderContext,Renderer::RenderBatch & renderBatch)142         void ToolChain::render(const InputState& inputState, Renderer::RenderContext& renderContext, Renderer::RenderBatch& renderBatch) {
143             assert(checkInvariant());
144             if (!chainEndsHere()) {
145                 m_tool->render(inputState, renderContext, renderBatch);
146                 m_suffix->render(inputState, renderContext, renderBatch);
147             }
148         }
149 
cancel()150         bool ToolChain::cancel() {
151             assert(checkInvariant());
152             if (chainEndsHere())
153                 return false;
154             if (m_tool->cancel())
155                 return true;
156             return m_suffix->cancel();
157         }
158 
checkInvariant() const159         bool ToolChain::checkInvariant() const {
160             return (m_tool == NULL) == (m_suffix == NULL);
161         }
162 
chainEndsHere() const163         bool ToolChain::chainEndsHere() const {
164             return m_tool == NULL;
165         }
166     }
167 }
168