Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
QmitkColorPropertyEditor.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 ===================================================================*/
17 
18 #include <QApplication>
19 #include <QCloseEvent>
20 #include <QDesktopWidget>
21 #include <QLayout>
22 #include <QMouseEvent>
23 #include <QPainter>
24 #include <mitkRenderingManager.h>
25 
26 //----- QmitkPopupColorChooser ---------------------------------------------------------
27 
28 QmitkPopupColorChooser::QmitkPopupColorChooser(QWidget *parent, unsigned int steps, unsigned int size)
29  : QFrame(parent, Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::Tool | Qt::X11BypassWindowManagerHint),
30  my_parent(parent)
31 {
32  setSteps(steps);
33 
34  setLineWidth(2);
35  setMouseTracking(true);
36 
37  setFrameStyle(QFrame::Panel | QFrame::Raised);
38  setLineWidth(1);
39  ensurePolished();
40  resize(size, size);
41 
42  hide();
43 }
44 
46 {
47 }
48 
50 {
51  m_Steps = steps;
52  m_Steps2 = m_Steps / 2;
53  m_HStep = 360 / m_Steps;
54  m_SStep = 512 / m_Steps;
55  m_VStep = 512 / m_Steps;
56 }
57 
59 {
60  emit colorSelected(m_OriginalColor);
61  close();
62 }
63 
65 {
66  double x(e->pos().x());
67  double y(e->pos().y());
68  x /= width();
69 
70  if (x >= 0.0)
71  {
72  x = (int)(x * (float)(m_Steps - 1)) / (float)(m_Steps - 1);
73  if (x > 1.0)
74  x = 1.0;
75  if (x < 0.0)
76  x = 0.0;
77  }
78 
79  y /= height();
80  if (y >= 1.0)
81  y = 0.9;
82  if (y < 0.0)
83  y = 0.0;
84  y = (int)(y * (float)m_Steps) / (float)m_Steps;
85 
86  m_H = static_cast<int>(y * 359.0);
87  if (x >= 0.5)
88  {
89  m_S = static_cast<int>((1.0 - x) * 511.0);
90  if (m_S > 255)
91  m_S = 255;
92  m_V = 255;
93  }
94  else
95  {
96  m_S = 255;
97  if (x < 0.0)
98  m_V = 0;
99  else
100  {
101  m_V = static_cast<int>(x * 511.0 + 511.0 / (float)(m_Steps - 1));
102  if (m_V > 255)
103  m_V = 255;
104  }
105  }
106 
107  QColor color;
108  color.setHsv(m_H, m_S, m_V);
109 
110  emit colorSelected(color);
111 }
112 
114 {
115  close();
116 }
117 
119 {
120  e->accept();
121 
122  releaseKeyboard();
123  releaseMouse();
124 
125  if (!m_popupParent)
126  return;
127 
128  // remember that we (as a popup) might recieve the mouse release
129  // event instead of the popupParent. This is due to the fact that
130  // the popupParent popped us up in its mousePressEvent handler. To
131  // avoid the button remaining in pressed state we simply send a
132  // faked mouse button release event to it.
133  // Maleike: parent should not pop us on MouseRelease!
134  QMouseEvent me(QEvent::MouseButtonRelease, QPoint(0, 0), QPoint(0, 0), Qt::LeftButton, Qt::NoButton, Qt::NoModifier);
135  QApplication::sendEvent(m_popupParent, &me);
136 }
137 
138 void QmitkPopupColorChooser::popup(QWidget *parent, const QPoint &point, const mitk::Color *color)
139 {
140  m_popupParent = parent;
141  if (m_popupParent)
142  {
143  QPoint newPos;
144 
145  if (color)
146  {
147  QColor qcolor((int)((*color)[0] * 255.0), (int)((*color)[1] * 255.0), (int)((*color)[2] * 255.0));
148  int h, s, v;
149  qcolor.getHsv(&h, &s, &v);
150 
151  if (h == -1) // set by Qt if color is achromatic ( but this widget does not display grays )
152  h = 10; // red
153 
154  int x, y;
155  float cellwidth = (float)width() / (float)(m_Steps);
156 
157  if (s > v) // restrict to the colors we can display
158  { // left side, ramp from v = 255/m_Steps to v = 255
159  s = 255;
160  x = (int)((((float)v / 255.0) * ((float)m_Steps2) - 1.0) * cellwidth + cellwidth / 2);
161  }
162  else
163  {
164  v = 255;
165  x = (int)(((1.0 - ((float)s / 255.0)) * ((float)m_Steps2)) * cellwidth + cellwidth / 2
166 
167  +
168  width() / 2);
169  }
170 
171  y = (int)((float)h / 360.0 * (float)m_Steps * cellwidth);
172 
173  m_OriginalColor.setHsv(h, s, v);
174 
175  // move to color
176  newPos.setX(point.x() - x);
177  newPos.setY(point.y() - y);
178  }
179  else
180  {
181  // center widget
182  m_OriginalColor.setHsv(-1, 0, 0);
183 
184  newPos.setX(point.x() - width() / 2);
185  newPos.setY(point.y() - height() / 2);
186  }
187  move(m_popupParent->mapToGlobal(newPos));
188  }
189 
190  show();
191  raise();
192  grabMouse();
193  grabKeyboard();
194 }
195 
197 {
198  QPainter painter(this);
199  drawGradient(&painter);
200 }
201 
203 {
204  p->setWindow(0, 0, m_Steps - 1, m_Steps); // defines coordinate system
205  p->setPen(Qt::NoPen);
206 
207  QColor c;
208  for (unsigned int h = 0; h < m_Steps; ++h)
209  {
210  for (unsigned int v = 1; v < m_Steps2; ++v)
211  {
212  c.setHsv(h * m_HStep, 255, v * m_VStep); // rainbow effect
213  p->setBrush(c); // solid fill with color c
214  p->drawRect(v - 1, h, m_Steps2, m_Steps); // draw the rectangle
215  }
216  for (unsigned int s = 0; s < m_Steps2; ++s)
217  {
218  c.setHsv(h * m_HStep, 255 - s * m_SStep, 255); // rainbow effect
219  p->setBrush(c); // solid fill with color c
220  p->drawRect(m_Steps2 + s - 1, h, m_Steps2, m_Steps); // draw the rectangle
221  }
222  }
223 }
224 
225 //----- QmitkColorPropertyEditor --------------------------------------------------
226 
227 // initialization of static pointer to color picker widget
230 
232  : QmitkColorPropertyView(property, parent)
233 {
234  // our popup belongs to the whole screen, so it could be drawn outside the toplevel window's borders
235  int scr;
236  if (QApplication::desktop()->isVirtualDesktop())
237  scr = QApplication::desktop()->screenNumber(parent->mapToGlobal(pos()));
238  else
239  scr = QApplication::desktop()->screenNumber(parent);
240 
241  if (colorChooserRefCount == 0)
242  {
243  colorChooser = new QmitkPopupColorChooser(QApplication::desktop()->screen(scr), 50);
244  }
246 }
247 
249 {
252  {
253  delete colorChooser;
254  colorChooser = nullptr;
255  }
256 }
257 
259 {
260  connect(colorChooser, SIGNAL(colorSelected(QColor)), this, SLOT(onColorSelected(QColor)));
261  if (m_ColorProperty)
262  {
263  colorChooser->popup(this, e->pos(), &(m_ColorProperty->GetColor()));
264  }
265 }
266 
268 {
269  disconnect(colorChooser, SIGNAL(colorSelected(QColor)), this, SLOT(onColorSelected(QColor)));
270 }
271 
273 {
274  if (m_ColorProperty)
275  {
276  int r, g, b;
277  c.getRgb(&r, &g, &b);
278  const_cast<mitk::ColorProperty *>(m_ColorProperty)->SetColor(r / 255.0, g / 255.0, b / 255.0);
279  const_cast<mitk::ColorProperty *>(m_ColorProperty)->Modified();
280 
282  }
283 }
QmitkPopupColorChooser(QWidget *parent=nullptr, unsigned int steps=16, unsigned int size=150)
virtual void keyReleaseEvent(QKeyEvent *) override
virtual void mouseReleaseEvent(QMouseEvent *) override
The ColorProperty class RGB color property.
virtual void mouseReleaseEvent(QMouseEvent *) override
virtual void mousePressEvent(QMouseEvent *) override
static RenderingManager * GetInstance()
virtual void paintEvent(QPaintEvent *) override
static QmitkPopupColorChooser * colorChooser
void colorSelected(QColor)
Call to popup this widget. parent determines popup position.
virtual void popup(QWidget *parent, const QPoint &point, const mitk::Color *=nullptr)
virtual void mouseMoveEvent(QMouseEvent *) override
QmitkColorPropertyEditor(const mitk::ColorProperty *, QWidget *parent)
const mitk::Color & GetColor() const
itk::RGBPixel< float > Color
Color Standard RGB color typedef (float)
const mitk::ColorProperty * m_ColorProperty
virtual void closeEvent(QCloseEvent *) override
void RequestUpdateAll(RequestType type=REQUEST_UPDATE_ALL)