comparison Framework/Viewport/WidgetViewport.cpp @ 0:351ab0da0150

initial commit
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 14 Oct 2016 15:34:11 +0200
parents
children ff1e935768e7
comparison
equal deleted inserted replaced
-1:000000000000 0:351ab0da0150
1 /**
2 * Stone of Orthanc
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
4 * Department, University Hospital of Liege, Belgium
5 *
6 * This program is free software: you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, either version 3 of the
9 * License, or (at your option) any later version.
10 *
11 * In addition, as a special exception, the copyright holders of this
12 * program give permission to link the code of its release with the
13 * OpenSSL project's "OpenSSL" library (or with modified versions of it
14 * that use the same license as the "OpenSSL" library), and distribute
15 * the linked executables. You must obey the GNU General Public License
16 * in all respects for all of the code used other than "OpenSSL". If you
17 * modify file(s) with this exception, you may extend this exception to
18 * your version of the file(s), but you are not obligated to do so. If
19 * you do not wish to do so, delete this exception statement from your
20 * version. If you delete this exception statement from all source files
21 * in the program, then also delete it here.
22 *
23 * This program is distributed in the hope that it will be useful, but
24 * WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
26 * General Public License for more details.
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with this program. If not, see <http://www.gnu.org/licenses/>.
30 **/
31
32
33 #include "WidgetViewport.h"
34
35 #include "../Orthanc/Core/Images/ImageProcessing.h"
36 #include "../Orthanc/Core/OrthancException.h"
37
38 namespace OrthancStone
39 {
40 void WidgetViewport::UnregisterCentralWidget()
41 {
42 mouseTracker_.reset(NULL);
43
44 if (centralWidget_.get() != NULL)
45 {
46 centralWidget_->Unregister(*this);
47 }
48 }
49
50
51 WidgetViewport::WidgetViewport() :
52 statusBar_(NULL),
53 isMouseOver_(false),
54 lastMouseX_(0),
55 lastMouseY_(0),
56 backgroundChanged_(false),
57 started_(false)
58 {
59 }
60
61
62 void WidgetViewport::SetStatusBar(IStatusBar& statusBar)
63 {
64 boost::mutex::scoped_lock lock(mutex_);
65
66 statusBar_ = &statusBar;
67
68 if (centralWidget_.get() != NULL)
69 {
70 centralWidget_->SetStatusBar(statusBar);
71 }
72 }
73
74
75 void WidgetViewport::ResetStatusBar()
76 {
77 boost::mutex::scoped_lock lock(mutex_);
78
79 statusBar_ = NULL;
80
81 if (centralWidget_.get() != NULL)
82 {
83 centralWidget_->ResetStatusBar();
84 }
85 }
86
87
88 IWidget& WidgetViewport::SetCentralWidget(IWidget* widget)
89 {
90 if (started_)
91 {
92 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
93 }
94
95 boost::mutex::scoped_lock lock(mutex_);
96
97 if (widget == NULL)
98 {
99 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
100 }
101
102 UnregisterCentralWidget();
103
104 centralWidget_.reset(widget);
105 centralWidget_->Register(*this);
106
107 if (statusBar_ == NULL)
108 {
109 centralWidget_->ResetStatusBar();
110 }
111 else
112 {
113 centralWidget_->SetStatusBar(*statusBar_);
114 }
115
116 backgroundChanged_ = true;
117
118 return *widget;
119 }
120
121
122 void WidgetViewport::NotifyChange(const IWidget& widget)
123 {
124 backgroundChanged_ = true;
125 observers_.NotifyChange(this);
126 }
127
128
129 void WidgetViewport::Start()
130 {
131 boost::mutex::scoped_lock lock(mutex_);
132
133 if (centralWidget_.get() != NULL)
134 {
135 centralWidget_->Start();
136 }
137
138 started_ = true;
139 }
140
141
142 void WidgetViewport::Stop()
143 {
144 boost::mutex::scoped_lock lock(mutex_);
145
146 started_ = false;
147
148 if (centralWidget_.get() != NULL)
149 {
150 centralWidget_->Stop();
151 }
152 }
153
154
155 void WidgetViewport::SetSize(unsigned int width,
156 unsigned int height)
157 {
158 boost::mutex::scoped_lock lock(mutex_);
159
160 background_.SetSize(width, height);
161
162 if (centralWidget_.get() != NULL)
163 {
164 centralWidget_->SetSize(width, height);
165 }
166
167 observers_.NotifyChange(this);
168 }
169
170
171 bool WidgetViewport::Render(Orthanc::ImageAccessor& surface)
172 {
173 boost::mutex::scoped_lock lock(mutex_);
174
175 if (!started_ ||
176 centralWidget_.get() == NULL)
177 {
178 return false;
179 }
180
181 if (backgroundChanged_)
182 {
183 Orthanc::ImageAccessor accessor = background_.GetAccessor();
184 if (!centralWidget_->Render(accessor))
185 {
186 return false;
187 }
188 }
189
190 Orthanc::ImageProcessing::Copy(surface, background_.GetAccessor());
191
192 if (mouseTracker_.get() != NULL)
193 {
194 mouseTracker_->Render(surface);
195 }
196 else if (isMouseOver_)
197 {
198 centralWidget_->RenderMouseOver(surface, lastMouseX_, lastMouseY_);
199 }
200
201 return true;
202 }
203
204
205 void WidgetViewport::MouseDown(MouseButton button,
206 int x,
207 int y,
208 KeyboardModifiers modifiers)
209 {
210 boost::mutex::scoped_lock lock(mutex_);
211
212 if (!started_)
213 {
214 return;
215 }
216
217 lastMouseX_ = x;
218 lastMouseY_ = y;
219
220 if (centralWidget_.get() != NULL)
221 {
222 mouseTracker_.reset(centralWidget_->CreateMouseTracker(button, x, y, modifiers));
223 }
224 else
225 {
226 mouseTracker_.reset(NULL);
227 }
228
229 observers_.NotifyChange(this);;
230 }
231
232
233 void WidgetViewport::MouseUp()
234 {
235 boost::mutex::scoped_lock lock(mutex_);
236
237 if (!started_)
238 {
239 return;
240 }
241
242 if (mouseTracker_.get() != NULL)
243 {
244 mouseTracker_->MouseUp();
245 mouseTracker_.reset(NULL);
246 observers_.NotifyChange(this);;
247 }
248 }
249
250
251 void WidgetViewport::MouseMove(int x,
252 int y)
253 {
254 boost::mutex::scoped_lock lock(mutex_);
255
256 if (!started_)
257 {
258 return;
259 }
260
261 lastMouseX_ = x;
262 lastMouseY_ = y;
263
264 if (mouseTracker_.get() != NULL)
265 {
266 mouseTracker_->MouseMove(x, y);
267 }
268
269 // The scene must be repainted
270 observers_.NotifyChange(this);
271 }
272
273
274 void WidgetViewport::MouseEnter()
275 {
276 boost::mutex::scoped_lock lock(mutex_);
277 isMouseOver_ = true;
278 observers_.NotifyChange(this);
279 }
280
281
282 void WidgetViewport::MouseLeave()
283 {
284 boost::mutex::scoped_lock lock(mutex_);
285 isMouseOver_ = false;
286 observers_.NotifyChange(this);
287 }
288
289
290 void WidgetViewport::MouseWheel(MouseWheelDirection direction,
291 int x,
292 int y,
293 KeyboardModifiers modifiers)
294 {
295 boost::mutex::scoped_lock lock(mutex_);
296
297 if (!started_)
298 {
299 return;
300 }
301
302 if (centralWidget_.get() != NULL &&
303 mouseTracker_.get() == NULL)
304 {
305 centralWidget_->MouseWheel(direction, x, y, modifiers);
306 }
307 }
308
309
310 void WidgetViewport::KeyPressed(char key,
311 KeyboardModifiers modifiers)
312 {
313 boost::mutex::scoped_lock lock(mutex_);
314
315 if (centralWidget_.get() != NULL &&
316 mouseTracker_.get() == NULL)
317 {
318 centralWidget_->KeyPressed(key, modifiers);
319 }
320 }
321 }