Mercurial > hg > orthanc-stone
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 } |