Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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)