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 }