Mercurial > hg > orthanc-stone
comparison Framework/Scene2DViewport/ViewportController.cpp @ 1208:00e6bff9ea39 broker
handling of mouse interactions in ViewportController
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 03 Dec 2019 18:51:03 +0100 |
parents | f3bb9a6dd949 |
children | 644baa70373d |
comparison
equal
deleted
inserted
replaced
1207:17a92c39c633 | 1208:00e6bff9ea39 |
---|---|
22 | 22 |
23 #include "UndoStack.h" | 23 #include "UndoStack.h" |
24 #include "MeasureCommands.h" | 24 #include "MeasureCommands.h" |
25 | 25 |
26 #include "../StoneException.h" | 26 #include "../StoneException.h" |
27 #include "../Scene2D/PanSceneTracker.h" | |
28 #include "../Scene2D/RotateSceneTracker.h" | |
29 #include "../Scene2D/ZoomSceneTracker.h" | |
27 | 30 |
28 #include <boost/make_shared.hpp> | 31 #include <boost/make_shared.hpp> |
29 | 32 |
30 namespace OrthancStone | 33 namespace OrthancStone |
31 { | 34 { |
35 IFlexiblePointerTracker* DefaultViewportInteractor::CreateTracker(boost::shared_ptr<ViewportController> controller, | |
36 const PointerEvent& event) | |
37 { | |
38 switch (event.GetMouseButton()) | |
39 { | |
40 case MouseButton_Left: | |
41 return new RotateSceneTracker(controller, event); | |
42 | |
43 case MouseButton_Middle: | |
44 return new PanSceneTracker(controller, event); | |
45 | |
46 case MouseButton_Right: | |
47 { | |
48 std::auto_ptr<IViewport::ILock> lock(controller->GetViewport().Lock()); | |
49 if (lock->HasCompositor()) | |
50 { | |
51 return new ZoomSceneTracker(controller, event, lock->GetCompositor().GetCanvasWidth()); | |
52 } | |
53 else | |
54 { | |
55 return NULL; | |
56 } | |
57 } | |
58 | |
59 default: | |
60 return NULL; | |
61 } | |
62 } | |
63 | |
64 | |
32 ViewportController::ViewportController(boost::weak_ptr<UndoStack> undoStackW, | 65 ViewportController::ViewportController(boost::weak_ptr<UndoStack> undoStackW, |
33 IViewport& viewport) | 66 boost::shared_ptr<IViewport> viewport) |
34 : undoStackW_(undoStackW) | 67 : undoStackW_(undoStackW) |
35 , canvasToSceneFactor_(0.0) | |
36 , viewport_(viewport) | 68 , viewport_(viewport) |
37 { | 69 , canvasToSceneFactor_(1) |
70 { | |
71 if (viewport.get() == NULL) | |
72 { | |
73 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); | |
74 } | |
75 | |
76 interactor_.reset(new DefaultViewportInteractor); | |
38 } | 77 } |
39 | 78 |
40 ViewportController::~ViewportController() | 79 ViewportController::~ViewportController() |
41 { | 80 { |
42 | 81 } |
43 } | 82 |
44 | 83 void ViewportController::SetInteractor(boost::shared_ptr<IViewportInteractor> interactor) |
45 boost::shared_ptr<UndoStack> ViewportController::GetUndoStack() | 84 { |
46 { | 85 activeTracker_.reset(); |
47 return undoStackW_.lock(); | 86 interactor_ = interactor; |
48 } | |
49 | |
50 boost::shared_ptr<const UndoStack> ViewportController::GetUndoStack() const | |
51 { | |
52 return undoStackW_.lock(); | |
53 } | 87 } |
54 | 88 |
55 void ViewportController::PushCommand(boost::shared_ptr<MeasureCommand> command) | 89 void ViewportController::PushCommand(boost::shared_ptr<MeasureCommand> command) |
56 { | 90 { |
57 boost::shared_ptr<UndoStack> undoStack = undoStackW_.lock(); | 91 boost::shared_ptr<UndoStack> undoStack = undoStackW_.lock(); |
58 if(undoStack.get() != NULL) | 92 if (undoStack.get() != NULL) |
93 { | |
59 undoStack->PushCommand(command); | 94 undoStack->PushCommand(command); |
95 } | |
60 else | 96 else |
61 { | 97 { |
62 LOG(ERROR) << "Internal error: no undo stack in the viewport controller!"; | 98 LOG(ERROR) << "Internal error: no undo stack in the viewport controller!"; |
63 } | 99 } |
64 } | 100 } |
65 | 101 |
66 void ViewportController::Undo() | 102 void ViewportController::Undo() |
67 { | 103 { |
68 boost::shared_ptr<UndoStack> undoStack = undoStackW_.lock(); | 104 boost::shared_ptr<UndoStack> undoStack = undoStackW_.lock(); |
69 if (undoStack.get() != NULL) | 105 if (undoStack.get() != NULL) |
106 { | |
70 undoStack->Undo(); | 107 undoStack->Undo(); |
108 } | |
71 else | 109 else |
72 { | 110 { |
73 LOG(ERROR) << "Internal error: no undo stack in the viewport controller!"; | 111 LOG(ERROR) << "Internal error: no undo stack in the viewport controller!"; |
74 } | 112 } |
75 } | 113 } |
76 | 114 |
77 void ViewportController::Redo() | 115 void ViewportController::Redo() |
78 { | 116 { |
79 boost::shared_ptr<UndoStack> undoStack = undoStackW_.lock(); | 117 boost::shared_ptr<UndoStack> undoStack = undoStackW_.lock(); |
80 if (undoStack.get() != NULL) | 118 if (undoStack.get() != NULL) |
119 { | |
81 undoStack->Redo(); | 120 undoStack->Redo(); |
121 } | |
82 else | 122 else |
83 { | 123 { |
84 LOG(ERROR) << "Internal error: no undo stack in the viewport controller!"; | 124 LOG(ERROR) << "Internal error: no undo stack in the viewport controller!"; |
85 } | 125 } |
86 } | 126 } |
87 | 127 |
88 bool ViewportController::CanUndo() const | 128 bool ViewportController::CanUndo() const |
89 { | 129 { |
90 boost::shared_ptr<UndoStack> undoStack = undoStackW_.lock(); | 130 boost::shared_ptr<UndoStack> undoStack = undoStackW_.lock(); |
91 if (undoStack.get() != NULL) | 131 if (undoStack.get() != NULL) |
132 { | |
92 return undoStack->CanUndo(); | 133 return undoStack->CanUndo(); |
134 } | |
93 else | 135 else |
94 { | 136 { |
95 LOG(ERROR) << "Internal error: no undo stack in the viewport controller!"; | 137 LOG(ERROR) << "Internal error: no undo stack in the viewport controller!"; |
96 return false; | 138 return false; |
97 } | 139 } |
99 | 141 |
100 bool ViewportController::CanRedo() const | 142 bool ViewportController::CanRedo() const |
101 { | 143 { |
102 boost::shared_ptr<UndoStack> undoStack = undoStackW_.lock(); | 144 boost::shared_ptr<UndoStack> undoStack = undoStackW_.lock(); |
103 if (undoStack.get() != NULL) | 145 if (undoStack.get() != NULL) |
146 { | |
104 return undoStack->CanRedo(); | 147 return undoStack->CanRedo(); |
148 } | |
105 else | 149 else |
106 { | 150 { |
107 LOG(ERROR) << "Internal error: no undo stack in the viewport controller!"; | 151 LOG(ERROR) << "Internal error: no undo stack in the viewport controller!"; |
108 return false; | 152 return false; |
109 } | 153 } |
110 } | 154 } |
111 | 155 |
112 bool ViewportController::HandlePointerEvent(PointerEvent e) | |
113 { | |
114 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); | |
115 } | |
116 | |
117 std::vector<boost::shared_ptr<MeasureTool> > ViewportController::HitTestMeasureTools( | 156 std::vector<boost::shared_ptr<MeasureTool> > ViewportController::HitTestMeasureTools( |
118 ScenePoint2D p) | 157 ScenePoint2D p) |
119 { | 158 { |
120 std::vector<boost::shared_ptr<MeasureTool> > ret; | 159 std::vector<boost::shared_ptr<MeasureTool> > ret; |
121 | 160 |
136 } | 175 } |
137 } | 176 } |
138 | 177 |
139 OrthancStone::AffineTransform2D ViewportController::GetCanvasToSceneTransform() const | 178 OrthancStone::AffineTransform2D ViewportController::GetCanvasToSceneTransform() const |
140 { | 179 { |
141 std::auto_ptr<IViewport::ILock> lock(viewport_.Lock()); | 180 std::auto_ptr<IViewport::ILock> lock(viewport_->Lock()); |
142 return lock->GetScene().GetCanvasToSceneTransform(); | 181 return lock->GetScene().GetCanvasToSceneTransform(); |
143 } | 182 } |
144 | 183 |
145 OrthancStone::AffineTransform2D ViewportController::GetSceneToCanvasTransform() const | 184 OrthancStone::AffineTransform2D ViewportController::GetSceneToCanvasTransform() const |
146 { | 185 { |
147 std::auto_ptr<IViewport::ILock> lock(viewport_.Lock()); | 186 std::auto_ptr<IViewport::ILock> lock(viewport_->Lock()); |
148 return lock->GetScene().GetSceneToCanvasTransform(); | 187 return lock->GetScene().GetSceneToCanvasTransform(); |
149 } | 188 } |
150 | 189 |
151 void ViewportController::SetSceneToCanvasTransform( | 190 void ViewportController::SetSceneToCanvasTransform(const AffineTransform2D& transform) |
152 const AffineTransform2D& transform) | 191 { |
153 { | 192 { |
154 { | 193 std::auto_ptr<IViewport::ILock> lock(viewport_->Lock()); |
155 std::auto_ptr<IViewport::ILock> lock(viewport_.Lock()); | |
156 lock->GetScene().SetSceneToCanvasTransform(transform); | 194 lock->GetScene().SetSceneToCanvasTransform(transform); |
195 canvasToSceneFactor_ = lock->GetScene().GetCanvasToSceneTransform().ComputeZoom(); | |
157 } | 196 } |
158 | 197 |
159 BroadcastMessage(SceneTransformChanged(*this)); | 198 BroadcastMessage(SceneTransformChanged(*this)); |
160 | 199 } |
161 // update the canvas to scene factor | 200 |
162 canvasToSceneFactor_ = 0.0; | 201 void ViewportController::FitContent() |
163 canvasToSceneFactor_ = GetCanvasToSceneFactor(); | 202 { |
164 } | 203 { |
165 | 204 std::auto_ptr<IViewport::ILock> lock(viewport_->Lock()); |
166 void ViewportController::FitContent( | 205 lock->FitContent(); |
167 unsigned int canvasWidth, unsigned int canvasHeight) | 206 canvasToSceneFactor_ = lock->GetScene().GetCanvasToSceneTransform().ComputeZoom(); |
168 { | 207 } |
169 { | 208 |
170 std::auto_ptr<IViewport::ILock> lock(viewport_.Lock()); | |
171 lock->GetScene().FitContent(canvasWidth, canvasHeight); | |
172 } | |
173 | |
174 BroadcastMessage(SceneTransformChanged(*this)); | 209 BroadcastMessage(SceneTransformChanged(*this)); |
175 } | |
176 | |
177 void ViewportController::FitContent() | |
178 { | |
179 std::auto_ptr<IViewport::ILock> lock(viewport_.Lock()); | |
180 | |
181 if (lock->HasCompositor()) | |
182 { | |
183 const ICompositor& compositor = lock->GetCompositor(); | |
184 lock->GetScene().FitContent(compositor.GetCanvasWidth(), compositor.GetCanvasHeight()); | |
185 BroadcastMessage(SceneTransformChanged(*this)); | |
186 } | |
187 } | 210 } |
188 | 211 |
189 void ViewportController::AddMeasureTool(boost::shared_ptr<MeasureTool> measureTool) | 212 void ViewportController::AddMeasureTool(boost::shared_ptr<MeasureTool> measureTool) |
190 { | 213 { |
191 ORTHANC_ASSERT(std::find(measureTools_.begin(), measureTools_.end(), measureTool) | 214 ORTHANC_ASSERT(std::find(measureTools_.begin(), measureTools_.end(), measureTool) |
200 measureTools_.erase( | 223 measureTools_.erase( |
201 std::remove(measureTools_.begin(), measureTools_.end(), measureTool), | 224 std::remove(measureTools_.begin(), measureTools_.end(), measureTool), |
202 measureTools_.end()); | 225 measureTools_.end()); |
203 } | 226 } |
204 | 227 |
205 | |
206 double ViewportController::GetCanvasToSceneFactor() const | 228 double ViewportController::GetCanvasToSceneFactor() const |
207 { | 229 { |
208 if (canvasToSceneFactor_ == 0) | |
209 { | |
210 std::auto_ptr<IViewport::ILock> lock(viewport_.Lock()); | |
211 canvasToSceneFactor_ = lock->GetScene().GetCanvasToSceneTransform().ComputeZoom(); | |
212 } | |
213 return canvasToSceneFactor_; | 230 return canvasToSceneFactor_; |
214 } | 231 } |
215 | 232 |
216 double ViewportController::GetHandleSideLengthS() const | 233 double ViewportController::GetHandleSideLengthS() const |
217 { | 234 { |
230 | 247 |
231 double ViewportController::GetAngleTopTextLabelDistanceS() const | 248 double ViewportController::GetAngleTopTextLabelDistanceS() const |
232 { | 249 { |
233 return TEXT_CENTER_DISTANCE_CANVAS_COORD * GetCanvasToSceneFactor(); | 250 return TEXT_CENTER_DISTANCE_CANVAS_COORD * GetCanvasToSceneFactor(); |
234 } | 251 } |
252 | |
253 | |
254 void ViewportController::HandleMousePress(const PointerEvent& event) | |
255 { | |
256 if (activeTracker_) | |
257 { | |
258 // We are dealing with a multi-stage tracker (that is made of several interactions) | |
259 activeTracker_->PointerDown(event); | |
260 | |
261 if (!activeTracker_->IsAlive()) | |
262 { | |
263 activeTracker_.reset(); | |
264 } | |
265 } | |
266 else | |
267 { | |
268 // Check whether there is already a measure tool at that position | |
269 for (size_t i = 0; i < measureTools_.size(); ++i) | |
270 { | |
271 if (measureTools_[i]->HitTest(event.GetMainPosition())) | |
272 { | |
273 activeTracker_ = measureTools_[i]->CreateEditionTracker(event); | |
274 return; | |
275 } | |
276 } | |
277 | |
278 // No measure tool, create new tracker from the interactor | |
279 if (interactor_) | |
280 { | |
281 activeTracker_.reset(interactor_->CreateTracker(shared_from_this(), event)); | |
282 } | |
283 else | |
284 { | |
285 activeTracker_.reset(); | |
286 } | |
287 } | |
288 } | |
289 | |
290 void ViewportController::HandleMouseMove(const PointerEvent& event) | |
291 { | |
292 if (activeTracker_) | |
293 { | |
294 activeTracker_->PointerMove(event); | |
295 } | |
296 } | |
297 | |
298 void ViewportController::HandleMouseRelease(const PointerEvent& event) | |
299 { | |
300 if (activeTracker_) | |
301 { | |
302 activeTracker_->PointerUp(event); | |
303 | |
304 if (!activeTracker_->IsAlive()) | |
305 { | |
306 activeTracker_.reset(); | |
307 } | |
308 } | |
309 } | |
235 } | 310 } |