Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
QmlMitkTransferFunctionCanvas.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 <QColorDialog>
20 #include <QPainter>
21 
23 : QQuickPaintedItem(parent),
24 m_GrabbedHandle(-1),
25 m_Lower(0.0),
26 m_Upper(1.0),
27 m_Min(0.0),
28 m_Max(1.0),
29 m_Histogram(nullptr),
30 m_ImmediateUpdate(false),
31 m_Range(0.0f),
32 m_LineEditAvailable(false)
33 {
34  setAcceptedMouseButtons(Qt::AllButtons);
35  setAcceptHoverEvents(true);
36  setAntialiasing(true);
37 }
38 
39 
41  std::pair<double,double> functionPoint)
42 {
43  return std::make_pair((int) ((functionPoint.first - m_Lower) / (m_Upper
44  - m_Lower) * boundingRect().width()) + boundingRect().x(), (int) (boundingRect().height() * (1 - functionPoint.second)) + boundingRect().y());
45 }
46 
48  std::pair<int,int> canvasPoint)
49 {
50  return std::make_pair((canvasPoint.first - boundingRect().x()) * (m_Upper - m_Lower) / boundingRect().width()
51  + m_Lower, 1.0 - (double) (canvasPoint.second - boundingRect().y()) / boundingRect().height());
52 }
53 
55 {
56  int nearHandle = GetNearHandle(mouseEvent->pos().x(), mouseEvent->pos().y());
57  if (nearHandle != -1)
58  {
59  this->DoubleClickOnHandle(nearHandle);
60  }
61 }
62 
66 {
67  return -1;
68 }
69 
70 
72 {
73  forceActiveFocus();
74 
75  if(mouseEvent->button() == Qt::RightButton)
76  mouseEvent->setAccepted(false);
77 
78  m_GrabbedHandle = GetNearHandle(mouseEvent->pos().x(), mouseEvent->pos().y());
79 
80  if ( (mouseEvent->button() & Qt::LeftButton) && m_GrabbedHandle == -1)
81  {
82  this->AddFunctionPoint(
83  this->CanvasToFunction(std::make_pair(mouseEvent->pos().x(),
84  mouseEvent->pos().y())).first,
85  this->CanvasToFunction(std::make_pair(mouseEvent->x(), mouseEvent->y())).second);
86  m_GrabbedHandle = GetNearHandle(mouseEvent->pos().x(),
87  mouseEvent->pos().y());
89  }
90 
91  update();
92 }
93 
94 void QmlMitkTransferFunctionCanvas::mouseMoveEvent(QMouseEvent* mouseEvent)
95 {
96  if (m_GrabbedHandle != -1)
97  {
98  std::pair<double,double>
99  newPos = this->CanvasToFunction(std::make_pair(mouseEvent->x(),
100  mouseEvent->y()));
101 
102  // X Clamping
103  {
104  // Check with predecessor
105  if( m_GrabbedHandle > 0 )
106  if (newPos.first <= this->GetFunctionX(m_GrabbedHandle - 1))
107  newPos.first = this->GetFunctionX(m_GrabbedHandle);
108 
109  // Check with sucessor
110  if( m_GrabbedHandle < this->GetFunctionSize()-1 )
111  if (newPos.first >= this->GetFunctionX(m_GrabbedHandle + 1))
112  newPos.first = this->GetFunctionX(m_GrabbedHandle);
113 
114  // Clamping to histogramm
115  if (newPos.first < m_Min) newPos.first = m_Min;
116  else if (newPos.first > m_Max) newPos.first = m_Max;
117  }
118 
119  // Y Clamping
120  {
121  if (newPos.second < 0.0) newPos.second = 0.0;
122  else if (newPos.second > 1.0) newPos.second = 1.0;
123  }
124 
125  // Move selected point
126  this->MoveFunctionPoint(m_GrabbedHandle, newPos);
127 
128  update();
129 
131  }
132 }
133 
135 {
136  update();
138 }
139 
141 {
142  if(m_Histogram)
143  {
144  p->save();
145 
146  p->setPen(Qt::gray);
147 
148  int displayWidth = boundingRect().width();
149  int displayHeight = boundingRect().height();
150 
151  double windowLeft = m_Lower;
152  double windowRight = m_Upper;
153 
154  double step = (windowRight-windowLeft)/double(displayWidth);
155 
156  double pos = windowLeft;
157 
158  for (int x = 0; x < displayWidth; x++)
159  {
160  double left = pos;
161  double right = pos + step;
162 
163  float height = m_Histogram->GetRelativeBin( left , right );
164 
165  if (height >= 0)
166  p->drawLine(x, displayHeight*(1-height), x, displayHeight);
167 
168  pos += step;
169  }
170 
171  p->restore();
172  }
173 }
174 
175 
177 {
178  if( m_GrabbedHandle == -1)
179  return;
180 
181  switch(e->key())
182  {
183  case Qt::Key_Backspace:
184  if(this->GetFunctionSize() > 1)
185  {
187  m_GrabbedHandle = -1;
188  }
189  break;
190 
191  case Qt::Key_Left:
193  break;
194 
195  case Qt::Key_Right:
197  break;
198 
199  case Qt::Key_Up:
201  break;
202 
203  case Qt::Key_Down:
205  break;
206  }
207 
208  update();
210 }
211 
212 // Update immediatly while changing the transfer function
214 {
215  m_ImmediateUpdate = state;
216 }
std::pair< double, double > ValidateCoord(std::pair< double, double > x)
virtual float GetRelativeBin(double start, double end) const =0
TODO: (What should this method do?)
QmlMitkTransferFunctionCanvas(QQuickPaintedItem *parent=nullptr)
void mouseDoubleClickEvent(QMouseEvent *mouseEvent) override
void mouseMoveEvent(QMouseEvent *mouseEvent) override
std::pair< int, int > FunctionToCanvas(std::pair< double, double >)
void mousePressEvent(QMouseEvent *mouseEvent) override
virtual int GetFunctionSize()=0
virtual void DoubleClickOnHandle(int handle)=0
virtual double GetFunctionY(int index)=0
void mouseReleaseEvent(QMouseEvent *mouseEvent) override
static RenderingManager * GetInstance()
virtual int GetNearHandle(int x, int y, unsigned int maxSquaredDistance=32)=0
void keyPressEvent(QKeyEvent *event) override
virtual void RemoveFunctionPoint(double x)=0
std::pair< double, double > CanvasToFunction(std::pair< int, int >)
virtual void MoveFunctionPoint(int index, std::pair< double, double > pos)=0
virtual int AddFunctionPoint(double x, double val)=0
virtual double GetFunctionX(int index)=0
void RequestUpdateAll(RequestType type=REQUEST_UPDATE_ALL)