comparison OrthancStone/Sources/Scene2DViewport/ViewportController.cpp @ 1512:244ad1e4e76a

reorganization of folders
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 07 Jul 2020 16:21:02 +0200
parents Framework/Scene2DViewport/ViewportController.cpp@ab81ee8fce1f
children 82279abb92d0
comparison
equal deleted inserted replaced
1511:9dfeee74c1e6 1512:244ad1e4e76a
1 /**
2 * Stone of Orthanc
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
4 * Department, University Hospital of Liege, Belgium
5 * Copyright (C) 2017-2020 Osimis S.A., Belgium
6 *
7 * This program is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU Affero General Public License
9 * as published by the Free Software Foundation, either version 3 of
10 * the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Affero General Public License for more details.
16 *
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 **/
20
21 #include "ViewportController.h"
22
23 #include "UndoStack.h"
24 #include "MeasureCommands.h"
25
26 #include "../StoneException.h"
27 #include "../Scene2D/PanSceneTracker.h"
28 #include "../Scene2D/RotateSceneTracker.h"
29 #include "../Scene2D/ZoomSceneTracker.h"
30
31 #include <boost/make_shared.hpp>
32
33 namespace OrthancStone
34 {
35 IFlexiblePointerTracker* DefaultViewportInteractor::CreateTracker(
36 boost::shared_ptr<IViewport> viewport,
37 const PointerEvent& event,
38 unsigned int viewportWidth,
39 unsigned int viewportHeight)
40 {
41 switch (event.GetMouseButton())
42 {
43 case MouseButton_Left:
44 return new RotateSceneTracker(viewport, event);
45
46 case MouseButton_Middle:
47 return new PanSceneTracker(viewport, event);
48
49 case MouseButton_Right:
50 {
51 if (viewportWidth != 0)
52 {
53 return new ZoomSceneTracker(viewport, event, viewportWidth);
54 }
55 else
56 {
57 return NULL;
58 }
59 }
60
61 default:
62 return NULL;
63 }
64 }
65
66 ViewportController::ViewportController(boost::shared_ptr<IViewport> viewport)
67 : viewport_(viewport)
68 , scene_(new Scene2D)
69 , canvasToSceneFactor_(1)
70 {
71 // undoStack_ is not default-initialized, which basically means empty.
72 // The controller must be able to cope with this.
73 }
74
75 ViewportController::~ViewportController()
76 {
77 }
78
79 void ViewportController::PushCommand(
80 boost::shared_ptr<MeasureCommand> command)
81 {
82 boost::shared_ptr<UndoStack> undoStack = undoStackW_.lock();
83 if (undoStack.get() != NULL)
84 {
85 undoStack->PushCommand(command);
86 }
87 else
88 {
89 LOG(ERROR) << "Internal error: no undo stack!";
90 }
91 }
92
93 void ViewportController::Undo()
94 {
95 boost::shared_ptr<UndoStack> undoStack = undoStackW_.lock();
96 if (undoStack.get() != NULL)
97 {
98 undoStack->Undo();
99 }
100 else
101 {
102 LOG(ERROR) << "Internal error: no undo stack!";
103 }
104 }
105
106 void ViewportController::Redo()
107 {
108 boost::shared_ptr<UndoStack> undoStack = undoStackW_.lock();
109 if (undoStack.get() != NULL)
110 {
111 undoStack->Redo();
112 }
113 else
114 {
115 LOG(ERROR) << "Internal error: no undo stack!";
116 }
117 }
118
119 bool ViewportController::CanUndo() const
120 {
121 boost::shared_ptr<UndoStack> undoStack = undoStackW_.lock();
122 if (undoStack.get() != NULL)
123 {
124 return undoStack->CanUndo();
125 }
126 else
127 {
128 LOG(ERROR) << "Internal error: no undo stack!";
129 return false;
130 }
131 }
132
133 bool ViewportController::CanRedo() const
134 {
135 boost::shared_ptr<UndoStack> undoStack = undoStackW_.lock();
136 if (undoStack.get() != NULL)
137 {
138 return undoStack->CanRedo();
139 }
140 else
141 {
142 LOG(ERROR) << "Internal error: no undo stack!";
143 return false;
144 }
145 }
146
147 std::vector<boost::shared_ptr<MeasureTool> >
148 ViewportController::HitTestMeasureTools(ScenePoint2D p)
149 {
150 std::vector<boost::shared_ptr<MeasureTool> > ret;
151
152 for (size_t i = 0; i < measureTools_.size(); ++i)
153 {
154 if (measureTools_[i]->HitTest(p))
155 ret.push_back(measureTools_[i]);
156 }
157 return ret;
158 }
159
160 void ViewportController::ResetMeasuringToolsHighlight()
161 {
162 for (size_t i = 0; i < measureTools_.size(); ++i)
163 {
164 measureTools_[i]->ResetHighlightState();
165 }
166 }
167
168 OrthancStone::AffineTransform2D
169 ViewportController::GetCanvasToSceneTransform() const
170 {
171 return scene_->GetCanvasToSceneTransform();
172 }
173
174 OrthancStone::AffineTransform2D
175 ViewportController::GetSceneToCanvasTransform() const
176 {
177 return scene_->GetSceneToCanvasTransform();
178 }
179
180 void ViewportController::SetSceneToCanvasTransform(
181 const AffineTransform2D& transform)
182 {
183 scene_->SetSceneToCanvasTransform(transform);
184
185 canvasToSceneFactor_ = scene_->GetCanvasToSceneTransform().ComputeZoom();
186 BroadcastMessage(SceneTransformChanged(*this));
187 }
188
189 void ViewportController::FitContent(unsigned int viewportWidth,
190 unsigned int viewportHeight)
191 {
192 scene_->FitContent(viewportWidth, viewportHeight);
193 canvasToSceneFactor_ = scene_->GetCanvasToSceneTransform().ComputeZoom();
194 BroadcastMessage(SceneTransformChanged(*this));
195 }
196
197 void ViewportController::AddMeasureTool(
198 boost::shared_ptr<MeasureTool> measureTool)
199 {
200 ORTHANC_ASSERT(std::find(measureTools_.begin(),
201 measureTools_.end(),
202 measureTool) == measureTools_.end(),
203 "Duplicate measure tool");
204 measureTools_.push_back(measureTool);
205 }
206
207 void ViewportController::RemoveMeasureTool(
208 boost::shared_ptr<MeasureTool> measureTool)
209 {
210 ORTHANC_ASSERT(std::find(measureTools_.begin(),
211 measureTools_.end(),
212 measureTool) != measureTools_.end(),
213 "Measure tool not found");
214 measureTools_.erase(
215 std::remove(measureTools_.begin(), measureTools_.end(), measureTool),
216 measureTools_.end());
217 }
218
219 double ViewportController::GetCanvasToSceneFactor() const
220 {
221 return canvasToSceneFactor_;
222 }
223
224 double ViewportController::GetHandleSideLengthS() const
225 {
226 return HANDLE_SIDE_LENGTH_CANVAS_COORD * GetCanvasToSceneFactor();
227 }
228
229 double ViewportController::GetAngleToolArcRadiusS() const
230 {
231 return ARC_RADIUS_CANVAS_COORD * GetCanvasToSceneFactor();
232 }
233
234 double ViewportController::GetHitTestMaximumDistanceS() const
235 {
236 return HIT_TEST_MAX_DISTANCE_CANVAS_COORD * GetCanvasToSceneFactor();
237 }
238
239 double ViewportController::GetAngleTopTextLabelDistanceS() const
240 {
241 return TEXT_CENTER_DISTANCE_CANVAS_COORD * GetCanvasToSceneFactor();
242 }
243
244
245 void ViewportController::HandleMousePress(
246 OrthancStone::IViewportInteractor& interactor,
247 const PointerEvent& event,
248 unsigned int viewportWidth,
249 unsigned int viewportHeight)
250 {
251 if (activeTracker_)
252 {
253 // We are dealing with a multi-stage tracker (that is made of several
254 // interactions)
255 activeTracker_->PointerDown(event);
256
257 if (!activeTracker_->IsAlive())
258 {
259 activeTracker_.reset();
260 }
261 }
262 else
263 {
264 // Check whether there is already a measure tool at that position
265 for (size_t i = 0; i < measureTools_.size(); ++i)
266 {
267 if (measureTools_[i]->HitTest(event.GetMainPosition()))
268 {
269 activeTracker_ = measureTools_[i]->CreateEditionTracker(event);
270 return;
271 }
272 }
273
274 // No measure tool, create new tracker from the interactor
275 activeTracker_.reset(interactor.CreateTracker(viewport_,
276 event,
277 viewportWidth,
278 viewportHeight));
279 }
280 }
281
282 bool ViewportController::HandleMouseMove(const PointerEvent& event)
283 {
284 if (activeTracker_)
285 {
286 activeTracker_->PointerMove(event);
287 return true;
288 }
289 else
290 {
291 return false;
292 }
293 }
294
295 void ViewportController::HandleMouseRelease(const PointerEvent& event)
296 {
297 if (activeTracker_)
298 {
299 activeTracker_->PointerUp(event);
300
301 if (!activeTracker_->IsAlive())
302 {
303 activeTracker_.reset();
304 }
305 }
306 }
307 }