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
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)