comparison Framework/Deprecated/Widgets/LayoutWidget.cpp @ 732:c35e98d22764

move Deprecated classes to a separate folder
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 21 May 2019 14:27:35 +0200
parents Framework/Widgets/LayoutWidget.cpp@4f2416d519b4
children d7887f88710f 2d8ab34c8c91
comparison
equal deleted inserted replaced
729:529189f399ec 732:c35e98d22764
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-2019 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
22 #include "LayoutWidget.h"
23
24 #include <Core/Logging.h>
25 #include <Core/OrthancException.h>
26
27 #include <boost/math/special_functions/round.hpp>
28
29 namespace Deprecated
30 {
31 class LayoutWidget::LayoutMouseTracker : public IMouseTracker
32 {
33 private:
34 std::auto_ptr<IMouseTracker> tracker_;
35 int left_;
36 int top_;
37 unsigned int width_;
38 unsigned int height_;
39
40 public:
41 LayoutMouseTracker(IMouseTracker* tracker,
42 int left,
43 int top,
44 unsigned int width,
45 unsigned int height) :
46 tracker_(tracker),
47 left_(left),
48 top_(top),
49 width_(width),
50 height_(height)
51 {
52 if (tracker == NULL)
53 {
54 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
55 }
56 }
57
58 virtual void Render(Orthanc::ImageAccessor& surface)
59 {
60 Orthanc::ImageAccessor accessor;
61 surface.GetRegion(accessor, left_, top_, width_, height_);
62 tracker_->Render(accessor);
63 }
64
65 virtual void MouseUp()
66 {
67 tracker_->MouseUp();
68 }
69
70 virtual void MouseMove(int x,
71 int y,
72 const std::vector<Touch>& displayTouches)
73 {
74 std::vector<Touch> relativeTouches;
75 for (size_t t = 0; t < displayTouches.size(); t++)
76 {
77 relativeTouches.push_back(Touch(displayTouches[t].x - left_, displayTouches[t].y - top_));
78 }
79
80 tracker_->MouseMove(x - left_, y - top_, relativeTouches);
81 }
82 };
83
84
85 class LayoutWidget::ChildWidget : public boost::noncopyable
86 {
87 private:
88 std::auto_ptr<IWidget> widget_;
89 int left_;
90 int top_;
91 unsigned int width_;
92 unsigned int height_;
93
94 public:
95 ChildWidget(IWidget* widget) :
96 widget_(widget)
97 {
98 assert(widget != NULL);
99 SetEmpty();
100 }
101
102 void DoAnimation()
103 {
104 if (widget_->HasAnimation())
105 {
106 widget_->DoAnimation();
107 }
108 }
109
110 IWidget& GetWidget() const
111 {
112 return *widget_;
113 }
114
115 void SetRectangle(unsigned int left,
116 unsigned int top,
117 unsigned int width,
118 unsigned int height)
119 {
120 left_ = left;
121 top_ = top;
122 width_ = width;
123 height_ = height;
124
125 widget_->SetSize(width, height);
126 }
127
128 void SetEmpty()
129 {
130 SetRectangle(0, 0, 0, 0);
131 }
132
133 bool Contains(int x,
134 int y) const
135 {
136 return (x >= left_ &&
137 y >= top_ &&
138 x < left_ + static_cast<int>(width_) &&
139 y < top_ + static_cast<int>(height_));
140 }
141
142 bool Render(Orthanc::ImageAccessor& target)
143 {
144 if (width_ == 0 ||
145 height_ == 0)
146 {
147 return true;
148 }
149 else
150 {
151 Orthanc::ImageAccessor accessor;
152 target.GetRegion(accessor, left_, top_, width_, height_);
153 return widget_->Render(accessor);
154 }
155 }
156
157 IMouseTracker* CreateMouseTracker(OrthancStone::MouseButton button,
158 int x,
159 int y,
160 OrthancStone::KeyboardModifiers modifiers,
161 const std::vector<Touch>& touches)
162 {
163 if (Contains(x, y))
164 {
165 IMouseTracker* tracker = widget_->CreateMouseTracker(button,
166 x - left_,
167 y - top_,
168 modifiers,
169 touches);
170 if (tracker)
171 {
172 return new LayoutMouseTracker(tracker, left_, top_, width_, height_);
173 }
174 }
175
176 return NULL;
177 }
178
179 void RenderMouseOver(Orthanc::ImageAccessor& target,
180 int x,
181 int y)
182 {
183 if (Contains(x, y))
184 {
185 Orthanc::ImageAccessor accessor;
186 target.GetRegion(accessor, left_, top_, width_, height_);
187
188 widget_->RenderMouseOver(accessor, x - left_, y - top_);
189 }
190 }
191
192 void MouseWheel(OrthancStone::MouseWheelDirection direction,
193 int x,
194 int y,
195 OrthancStone::KeyboardModifiers modifiers)
196 {
197 if (Contains(x, y))
198 {
199 widget_->MouseWheel(direction, x - left_, y - top_, modifiers);
200 }
201 }
202
203 bool HasRenderMouseOver()
204 {
205 return widget_->HasRenderMouseOver();
206 }
207 };
208
209
210 void LayoutWidget::ComputeChildrenExtents()
211 {
212 if (children_.size() == 0)
213 {
214 return;
215 }
216
217 float internal = static_cast<float>(paddingInternal_);
218
219 if (width_ <= paddingLeft_ + paddingRight_ ||
220 height_ <= paddingTop_ + paddingBottom_)
221 {
222 for (size_t i = 0; i < children_.size(); i++)
223 {
224 children_[i]->SetEmpty();
225 }
226 }
227 else if (isHorizontal_)
228 {
229 unsigned int padding = paddingLeft_ + paddingRight_ + (static_cast<unsigned int>(children_.size()) - 1) * paddingInternal_;
230 float childWidth = ((static_cast<float>(width_) - static_cast<float>(padding)) /
231 static_cast<float>(children_.size()));
232
233 for (size_t i = 0; i < children_.size(); i++)
234 {
235 float left = static_cast<float>(paddingLeft_) + static_cast<float>(i) * (childWidth + internal);
236 float right = left + childWidth;
237
238 if (left >= right)
239 {
240 children_[i]->SetEmpty();
241 }
242 else
243 {
244 children_[i]->SetRectangle(static_cast<unsigned int>(left),
245 paddingTop_,
246 boost::math::iround(right - left),
247 height_ - paddingTop_ - paddingBottom_);
248 }
249 }
250 }
251 else
252 {
253 unsigned int padding = paddingTop_ + paddingBottom_ + (static_cast<unsigned int>(children_.size()) - 1) * paddingInternal_;
254 float childHeight = ((static_cast<float>(height_) - static_cast<float>(padding)) /
255 static_cast<float>(children_.size()));
256
257 for (size_t i = 0; i < children_.size(); i++)
258 {
259 float top = static_cast<float>(paddingTop_) + static_cast<float>(i) * (childHeight + internal);
260 float bottom = top + childHeight;
261
262 if (top >= bottom)
263 {
264 children_[i]->SetEmpty();
265 }
266 else
267 {
268 children_[i]->SetRectangle(paddingTop_,
269 static_cast<unsigned int>(top),
270 width_ - paddingLeft_ - paddingRight_,
271 boost::math::iround(bottom - top));
272 }
273 }
274 }
275
276 NotifyContentChanged(*this);
277 }
278
279
280 LayoutWidget::LayoutWidget(const std::string& name) :
281 WidgetBase(name),
282 isHorizontal_(true),
283 width_(0),
284 height_(0),
285 paddingLeft_(0),
286 paddingTop_(0),
287 paddingRight_(0),
288 paddingBottom_(0),
289 paddingInternal_(0)
290 {
291 }
292
293
294 LayoutWidget::~LayoutWidget()
295 {
296 for (size_t i = 0; i < children_.size(); i++)
297 {
298 delete children_[i];
299 }
300 }
301
302
303 void LayoutWidget::FitContent()
304 {
305 for (size_t i = 0; i < children_.size(); i++)
306 {
307 children_[i]->GetWidget().FitContent();
308 }
309 }
310
311
312 void LayoutWidget::NotifyContentChanged(const IWidget& widget)
313 {
314 // One of the children has changed
315 WidgetBase::NotifyContentChanged();
316 }
317
318
319 void LayoutWidget::SetHorizontal()
320 {
321 isHorizontal_ = true;
322 ComputeChildrenExtents();
323 }
324
325
326 void LayoutWidget::SetVertical()
327 {
328 isHorizontal_ = false;
329 ComputeChildrenExtents();
330 }
331
332
333 void LayoutWidget::SetPadding(unsigned int left,
334 unsigned int top,
335 unsigned int right,
336 unsigned int bottom,
337 unsigned int spacing)
338 {
339 paddingLeft_ = left;
340 paddingTop_ = top;
341 paddingRight_ = right;
342 paddingBottom_ = bottom;
343 paddingInternal_ = spacing;
344 }
345
346
347 void LayoutWidget::SetPadding(unsigned int padding)
348 {
349 paddingLeft_ = padding;
350 paddingTop_ = padding;
351 paddingRight_ = padding;
352 paddingBottom_ = padding;
353 paddingInternal_ = padding;
354 }
355
356
357 IWidget& LayoutWidget::AddWidget(IWidget* widget) // Takes ownership
358 {
359 if (widget == NULL)
360 {
361 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
362 }
363
364 if (GetStatusBar() != NULL)
365 {
366 widget->SetStatusBar(*GetStatusBar());
367 }
368
369 children_.push_back(new ChildWidget(widget));
370 widget->SetParent(*this);
371
372 ComputeChildrenExtents();
373
374 if (widget->HasAnimation())
375 {
376 hasAnimation_ = true;
377 }
378
379 return *widget;
380 }
381
382
383 void LayoutWidget::SetStatusBar(IStatusBar& statusBar)
384 {
385 WidgetBase::SetStatusBar(statusBar);
386
387 for (size_t i = 0; i < children_.size(); i++)
388 {
389 children_[i]->GetWidget().SetStatusBar(statusBar);
390 }
391 }
392
393
394 void LayoutWidget::SetSize(unsigned int width,
395 unsigned int height)
396 {
397 width_ = width;
398 height_ = height;
399 ComputeChildrenExtents();
400 }
401
402
403 bool LayoutWidget::Render(Orthanc::ImageAccessor& surface)
404 {
405 if (!WidgetBase::Render(surface))
406 {
407 return false;
408 }
409
410 for (size_t i = 0; i < children_.size(); i++)
411 {
412 if (!children_[i]->Render(surface))
413 {
414 return false;
415 }
416 }
417
418 return true;
419 }
420
421
422 IMouseTracker* LayoutWidget::CreateMouseTracker(OrthancStone::MouseButton button,
423 int x,
424 int y,
425 OrthancStone::KeyboardModifiers modifiers,
426 const std::vector<Touch>& touches)
427 {
428 for (size_t i = 0; i < children_.size(); i++)
429 {
430 IMouseTracker* tracker = children_[i]->CreateMouseTracker(button, x, y, modifiers, touches);
431 if (tracker != NULL)
432 {
433 return tracker;
434 }
435 }
436
437 return NULL;
438 }
439
440
441 void LayoutWidget::RenderMouseOver(Orthanc::ImageAccessor& target,
442 int x,
443 int y)
444 {
445 for (size_t i = 0; i < children_.size(); i++)
446 {
447 children_[i]->RenderMouseOver(target, x, y);
448 }
449 }
450
451
452 void LayoutWidget::MouseWheel(OrthancStone::MouseWheelDirection direction,
453 int x,
454 int y,
455 OrthancStone::KeyboardModifiers modifiers)
456 {
457 for (size_t i = 0; i < children_.size(); i++)
458 {
459 children_[i]->MouseWheel(direction, x, y, modifiers);
460 }
461 }
462
463
464 void LayoutWidget::KeyPressed(OrthancStone::KeyboardKeys key,
465 char keyChar,
466 OrthancStone::KeyboardModifiers modifiers)
467 {
468 for (size_t i = 0; i < children_.size(); i++)
469 {
470 children_[i]->GetWidget().KeyPressed(key, keyChar, modifiers);
471 }
472 }
473
474
475 void LayoutWidget::DoAnimation()
476 {
477 if (hasAnimation_)
478 {
479 for (size_t i = 0; i < children_.size(); i++)
480 {
481 children_[i]->DoAnimation();
482 }
483 }
484 else
485 {
486 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
487 }
488 }
489
490
491 bool LayoutWidget::HasRenderMouseOver()
492 {
493 for (size_t i = 0; i < children_.size(); i++)
494 {
495 if (children_[i]->HasRenderMouseOver())
496 {
497 return true;
498 }
499 }
500
501 return false;
502 }
503 }