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