Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
QmlMitkSliderLevelWindowItem.cpp
Go to the documentation of this file.
1 /*===================================================================
2 
3  The Medical Imaging Interaction Toolkit (MITK)
4 
5  Copyright (c) German Cancer Research Center,
6  Division of Medical and Biological Informatics.
7  All rights reserved.
8 
9  This software is distributed WITHOUT ANY WARRANTY; without
10  even the implied warranty of MERCHANTABILITY or FITNESS FOR
11  A PARTICULAR PURPOSE.
12 
13  See LICENSE.txt or http://www.mitk.org for details.
14 
15  ===================================================================*/
16 
18 
19 #include <QCursor>
20 #include <QPainter>
21 #include <QToolTip>
22 #include <QMouseEvent>
23 #include <QDebug>
24 
25 #include <itkCommand.h>
26 #include <mitkRenderingManager.h>
27 
28 #include <math.h>
29 
31 mitk::DataStorage::Pointer QmlMitkSliderLevelWindowItem::storage = nullptr;
32 
34 : QQuickPaintedItem(parent)
35 {
36  m_Manager = mitk::LevelWindowManager::New();
37  m_Manager->SetDataStorage(QmlMitkSliderLevelWindowItem::storage);
38 
40  command->SetCallbackFunction(this, &QmlMitkSliderLevelWindowItem::OnPropertyModified);
41  m_ObserverTag = m_Manager->AddObserver(itk::ModifiedEvent(), command);
42  m_IsObserverTagSet = true;
43 
44  setAcceptedMouseButtons(Qt::AllButtons);
45  setAcceptHoverEvents(true);
46  setAntialiasing(true);
47 
48  m_Resize = false;
49  m_Bottom = false;
50  m_CtrlPressed = false;
51  m_MouseDown = false;
52  m_ScaleVisible = true;
53 
54  this->setEnabled(false);
55 
56  update();
57 }
58 
60 {
61  if ( m_IsObserverTagSet)
62  {
63  m_Manager->RemoveObserver(m_ObserverTag);
64  m_IsObserverTagSet = false;
65  }
66 }
67 
69 {
70  if ( m_IsObserverTagSet)
71  {
72  m_Manager->RemoveObserver(m_ObserverTag);
73  m_IsObserverTagSet = false;
74  }
75  m_Manager = levelWindowManager;
76  if ( m_Manager.IsNotNull() )
77  {
79  command->SetCallbackFunction(this, &QmlMitkSliderLevelWindowItem::OnPropertyModified);
80  m_ObserverTag = m_Manager->AddObserver(itk::ModifiedEvent(), command);
81  m_IsObserverTagSet = true;
82  }
83 }
84 
85 void QmlMitkSliderLevelWindowItem::OnPropertyModified(const itk::EventObject& )
86 {
87  try
88  {
89  m_LevelWindow = m_Manager->GetLevelWindow();
90 
91  this->m_Level = (int)m_LevelWindow.GetLevel();
92  this->m_Window = (int)m_LevelWindow.GetWindow();
93  this->setEnabled(true);
94 
95  emit this->sync();
96  update();
97  }
98  catch(...)
99  {
100  this->setEnabled(false);
101  }
102 
103  QQuickPaintedItem::update();
104 }
105 
107 {
108  return this->m_Enabled;
109 }
110 
112 {
113  this->m_Enabled = enable;
114  emit this->enabledChanged();
115 }
116 
118 {
119  return this->m_FontSize;
120 }
121 
123 {
124  this->m_FontSize = fontSize;
125  this->m_Font.setPointSize(fontSize);
126 }
127 
129 {
130  return this->m_FontColor;
131 }
132 
134 {
135  this->m_FontColor = color;
136 }
137 
139 {
140  return this->m_Color;
141 }
142 
143 void QmlMitkSliderLevelWindowItem::setColor(const QColor &color)
144 {
145  this->m_Color = color;
146 }
147 
149 {
150  return this->m_BorderColor;
151 }
152 
154 {
155  this->m_BorderColor = color;
156 }
157 
159 {
160 
161  if(level != m_LevelWindow.GetLevel())
162  {
163  m_LevelWindow.SetLevelWindow(level, m_LevelWindow.GetWindow());
164  m_Manager->SetLevelWindow(m_LevelWindow);
165 
167  }
168 
169  this->m_Level = level;
170 }
171 
173 {
174  return this->m_Level;
175 }
176 
178 {
179 
180  if(window != m_LevelWindow.GetWindow())
181  {
182  m_LevelWindow.SetLevelWindow(m_LevelWindow.GetLevel(), window);
183  m_Manager->SetLevelWindow(m_LevelWindow);
185  }
186 
187  this->m_Window = window;
188 }
189 
191 {
192  return this->m_Window;
193 }
194 
195 void QmlMitkSliderLevelWindowItem::paint( QPainter* painter )
196 {
197  if(!this->m_Enabled)
198  return;
199 
200  m_MoveHeight = boundingRect().height() - 55;
201 
202  painter->setFont( m_Font );
203  painter->setPen(this->m_BorderColor);
204 
205  painter->setBrush(this->m_Color);
206  painter->drawRoundedRect(m_Rect, 3, 3);
207 
208  painter->setPen(this->m_FontColor);
209 
210  float mr = m_LevelWindow.GetRange();
211 
212  if ( mr < 1 )
213  mr = 1;
214 
215  float fact = (float) m_MoveHeight / mr;
216 
217  //begin draw scale
218  if (m_ScaleVisible)
219  {
220  int minRange = (int)m_LevelWindow.GetRangeMin();
221  int maxRange = (int)m_LevelWindow.GetRangeMax();
222  int yValue = m_MoveHeight + (int)(minRange*fact);
223  QString s = " 0";
224  if (minRange <= 0 && maxRange >= 0)
225  {
226  painter->drawLine( 5, yValue , 15, yValue);
227  painter->drawText( 21, yValue + 3, s );
228  }
229 
230  int count = 1;
231  int k = 5;
232  bool enoughSpace = false;
233  bool enoughSpace2 = false;
234 
235  double dStepSize = pow(10,floor(log10(mr/100))+1);
236 
237  for(int i = m_MoveHeight + (int)(minRange*fact); i < m_MoveHeight;)//negative
238  {
239  if (-count*dStepSize < minRange)
240  break;
241  yValue = m_MoveHeight + (int)((minRange + count*dStepSize)*fact);
242 
243  s = QString::number(-count*dStepSize);
244  if (count % k && ((dStepSize*fact) > 2.5))
245  {
246  painter->drawLine( 8, yValue, 12, yValue);
247  enoughSpace = true;
248  }
249  else if (!(count % k))
250  {
251  if ((k*dStepSize*fact) > 7)
252  {
253  painter->drawLine( 5, yValue, 15, yValue);
254  painter->drawText( 21, yValue + 3, s );
255  enoughSpace2 = true;
256  }
257  else
258  {
259  k += 5;
260  }
261  }
262  if (enoughSpace)
263  {
264  i=yValue;
265  count++;
266  }
267  else if (enoughSpace2)
268  {
269  i=yValue;
270  count += k;
271  }
272  else
273  {
274  i=yValue;
275  count = k;
276  }
277  }
278  count = 1;
279  k = 5;
280  enoughSpace = false;
281  enoughSpace2 = false;
282 
283  for(int i = m_MoveHeight + (int)(minRange*fact); i >= 0;)
284  {
285  if (count*dStepSize > maxRange)
286  break;
287  yValue = m_MoveHeight + (int)((minRange - count*dStepSize)*fact);
288 
289  s = QString::number(count*dStepSize);
290  if(count % k && ((dStepSize*fact) > 2.5))
291  {
292  if (!(minRange > 0 && (count*dStepSize) < minRange))
293  painter->drawLine( 8, yValue, 12, yValue);
294  enoughSpace = true;
295  }
296  else if (!(count % k))
297  {
298  if ((k*dStepSize*fact) > 7)
299  {
300  if (!(minRange > 0 && (count*dStepSize) < minRange))
301  {
302  painter->drawLine( 5, yValue, 15, yValue);
303  painter->drawText( 21, yValue + 3, s );
304  }
305  enoughSpace2 = true;
306  }
307  else
308  {
309  k += 5;
310  }
311  }
312  if (enoughSpace)
313  {
314  i=yValue;
315  count++;
316  }
317  else if (enoughSpace2)
318  {
319  i=yValue;
320  count += k;
321  }
322  else
323  {
324  i=yValue;
325  count = k;
326  }
327  }
328  }
329 }
330 
331 void QmlMitkSliderLevelWindowItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
332 {
333  update();
334  QQuickPaintedItem::geometryChanged(newGeometry, oldGeometry);
335 }
336 
337 void QmlMitkSliderLevelWindowItem::hoverMoveEvent(QHoverEvent *mouseEvent)
338 {
339  if ( mouseEvent->pos().y() >= 0
340  && mouseEvent->pos().y() <= (m_Rect.topLeft().y() + 3) )
341  {
342  setCursor(Qt::SizeVerCursor);
343  m_UpperBound.setRect(m_Rect.topLeft().x(), m_Rect.topLeft().y() - 3, 17, 7);
344  //this->setToolTip("Ctrl + left click to change only upper bound");
345  m_Resize = true;
346  }
347  else if ( mouseEvent->pos().y() >= (m_Rect.bottomLeft().y() - 3) )
348  {
349  setCursor(Qt::SizeVerCursor);
350  m_LowerBound.setRect(m_Rect.bottomLeft().x(), m_Rect.bottomLeft().y() - 3, 17, 7);
351  //this->setToolTip("Ctrl + left click to change only lower bound");
352  m_Resize = true;
353  m_Bottom = true;
354  }
355  else
356  {
357  setCursor(Qt::ArrowCursor);
358  //this->setToolTip("Left click and mouse move to adjust the slider");
359  m_Resize = false;
360  m_Bottom = false;
361  }
362 }
366 void QmlMitkSliderLevelWindowItem::mouseMoveEvent( QMouseEvent* mouseEvent )
367 {
368  if(!mouseEvent && !m_MouseDown)
369  return;
370  if ( m_LevelWindow.IsFixed() )
371  return;
372 
373 
374  float fact = (float) m_MoveHeight / m_LevelWindow.GetRange();
375 
376  if ( m_Leftbutton )
377  {
378  if (m_Resize && !m_CtrlPressed)
379  {
380  double diff = (mouseEvent->pos().y()) / fact;
381  diff -= (m_StartPos.y()) / fact;
382  m_StartPos = mouseEvent->pos();
383 
384  if (diff == 0) return;
385  float value;
386  if (m_Bottom)
387  value = m_LevelWindow.GetWindow() + ( ( 2 * diff ) );
388  else
389  value = m_LevelWindow.GetWindow() - ( ( 2 * diff ) );
390 
391  if ( value < 0 )
392  value = 0;
393 
394  m_LevelWindow.SetLevelWindow( m_LevelWindow.GetLevel(), value );
395  }
396  else if(m_Resize && m_CtrlPressed)
397  {
398  if (!m_Bottom)
399  {
400  double diff = (mouseEvent->pos().y()) / fact;
401  diff -= (m_StartPos.y()) / fact;
402  m_StartPos = mouseEvent->pos();
403 
404  if (diff == 0) return;
405  float value;
406 
407  value = m_LevelWindow.GetWindow() - ( ( diff ) );
408 
409  if ( value < 0 )
410  value = 0;
411  float oldWindow;
412  float oldLevel;
413  float newLevel;
414  oldWindow = m_LevelWindow.GetWindow();
415  oldLevel = m_LevelWindow.GetLevel();
416  newLevel = oldLevel + (value - oldWindow)/2;
417  if (!((newLevel + value/2) > m_LevelWindow.GetRangeMax()))
418  m_LevelWindow.SetLevelWindow( newLevel, value );
419  }
420  else
421  {
422  double diff = (mouseEvent->pos().y()) / fact;
423  diff -= (m_StartPos.y()) / fact;
424  m_StartPos = mouseEvent->pos();
425 
426  if (diff == 0) return;
427  float value;
428 
429  value = m_LevelWindow.GetWindow() + ( ( diff ) );
430 
431  if ( value < 0 )
432  value = 0;
433  float oldWindow;
434  float oldLevel;
435  float newLevel;
436  oldWindow = m_LevelWindow.GetWindow();
437  oldLevel = m_LevelWindow.GetLevel();
438  newLevel = oldLevel - (value - oldWindow)/2;
439  if (!((newLevel - value/2) < m_LevelWindow.GetRangeMin()))
440  m_LevelWindow.SetLevelWindow( newLevel, value );
441  }
442  }
443  else
444  {
445  const float minv = m_LevelWindow.GetRangeMin();
446 
447  const float level = (m_MoveHeight - mouseEvent->pos().y()) / fact + minv;
448 
449  double diff = (mouseEvent->pos().x()) / fact;
450  diff -= (m_StartPos.x()) / fact;
451  m_StartPos = mouseEvent->pos();
452 
453  float window;
454  if (m_Bottom)
455  window = m_LevelWindow.GetWindow() + ( ( 2 * diff ) );
456  else
457  window = m_LevelWindow.GetWindow() - ( ( 2 * diff ) );
458 
459  if ( window < 0 )
460  window = 0;
461 
462  m_LevelWindow.SetLevelWindow( level, window );
463  }
464  m_Manager->SetLevelWindow(m_LevelWindow);
466  }
467 
468 }
469 
473 void QmlMitkSliderLevelWindowItem::mousePressEvent( QMouseEvent* mouseEvent ) {
474  if ( m_LevelWindow.IsFixed() )
475  return;
476  m_MouseDown = true;
477  m_StartPos = mouseEvent->pos();
478 
479  if ( mouseEvent->button() == Qt::LeftButton )
480  {
481  if (mouseEvent->modifiers() == Qt::ControlModifier || mouseEvent->modifiers() == Qt::ShiftModifier)
482  {
483  m_CtrlPressed = true;
484  }
485  else
486  {
487  m_CtrlPressed = false;
488  }
489  m_Leftbutton = true;
490  }
491  else
492  m_Leftbutton = false;
493 
494  mouseMoveEvent( mouseEvent );
495 }
496 
501 {
502  if ( m_LevelWindow.IsFixed() )
503  return;
504  m_MouseDown = false;
505 }
506 
511 {
512 
513  int rectWidth;
514  if(m_ScaleVisible)
515  {
516  rectWidth = 16;
517  }
518  else
519  {
520  rectWidth = 26;
521  }
522 
523  float mr = m_LevelWindow.GetRange();
524 
525  if ( mr < 1 )
526  mr = 1;
527 
528  float fact = (float) m_MoveHeight / mr;
529 
530  float rectHeight = m_LevelWindow.GetWindow() * fact;
531 
532  if ( rectHeight < 15 )
533  rectHeight = 15;
534 
535  if ( m_LevelWindow.GetLowerWindowBound() < 0 )
536  m_Rect.setRect( 2, (int) (m_MoveHeight - (m_LevelWindow.GetUpperWindowBound() - m_LevelWindow.GetRangeMin()) * fact) , rectWidth, (int) rectHeight );
537  else
538  m_Rect.setRect( 2, (int) (m_MoveHeight - (m_LevelWindow.GetUpperWindowBound() - m_LevelWindow.GetRangeMin()) * fact), rectWidth, (int) rectHeight );
539 
540  QQuickPaintedItem::update();
541 }
542 
543 
545 {
546  m_ScaleVisible = false;
547  update();
548 }
549 
551 {
552  m_ScaleVisible = true;
553  update();
554 }
555 
557 {
558  m_Manager->SetDataStorage(ds);
559 }
560 
562 {
563  return m_Manager.GetPointer();
564 }
565 
567 {
568  qmlRegisterType<QmlMitkSliderLevelWindowItem>("Mitk.Views", 1, 0, "LevelWindow");
569 
570  QmlMitkSliderLevelWindowItem::storage = storage;
571 }
Data management class that handles 'was created by' relations.
itk::SmartPointer< Self > Pointer
void setDataStorage(mitk::DataStorage *ds)
ScalarType GetLowerWindowBound() const
static QmlMitkSliderLevelWindowItem * instance
void setLevelWindowManager(mitk::LevelWindowManager *levelWindowManager)
void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override
bool IsFixed() const
void mouseMoveEvent(QMouseEvent *mouseEvent) override
QmlMitkSliderLevelWindowItem(QQuickPaintedItem *parent=nullptr)
static RenderingManager * GetInstance()
static void create(QQmlEngine &engine, mitk::DataStorage::Pointer storage)
ScalarType GetRangeMax() const
void mousePressEvent(QMouseEvent *mouseEvent) override
mitk::LevelWindowManager * GetManager()
void paint(QPainter *painter) override
ScalarType GetRangeMin() const
ScalarType GetUpperWindowBound() const
void mouseReleaseEvent(QMouseEvent *mouseEvent) override
void SetLevelWindow(ScalarType level, ScalarType window, bool expandRangesIfNecessary=true)
static Pointer New()
Provides access to the LevelWindowProperty object and LevelWindow of the "current" image...
ScalarType GetWindow() const
returns the current window size, i.e the range size of the current grey value interval ...
void RequestUpdateAll(RequestType type=REQUEST_UPDATE_ALL)
ScalarType GetRange() const
returns the size of the grey value range
ScalarType GetLevel() const
method that returns the level value, i.e. the center of the current grey value interval ...
void hoverMoveEvent(QHoverEvent *event) override
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.