Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
QmitkRenderWindow.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 
17 #include "QmitkRenderWindow.h"
18 
20 #include "mitkInternalEvent.h"
22 #include "mitkMouseMoveEvent.h"
23 #include "mitkMousePressEvent.h"
24 #include "mitkMouseReleaseEvent.h"
25 #include "mitkMouseWheelEvent.h"
26 #include <QCursor>
27 #include <QDragEnterEvent>
28 #include <QDropEvent>
29 #include <QKeyEvent>
30 #include <QMouseEvent>
31 #include <QResizeEvent>
32 #include <QSurfaceFormat>
33 #include <QTimer>
34 #include <QWheelEvent>
35 #include <QWindow>
36 
37 #include "QmitkMimeTypes.h"
38 #include "QmitkRenderWindowMenu.h"
39 
41  QString name,
42  mitk::VtkPropRenderer * /*renderer*/,
43  mitk::RenderingManager *renderingManager,
45  : QVTKWidget(parent), m_ResendQtEvents(true), m_MenuWidget(NULL), m_MenuWidgetActivated(false), m_LayoutIndex(0)
46 {
47  // Needed if QVTKWidget2 is used instead of QVTKWidget
48  // this will be fixed in VTK source if change 18864 is accepted
49  /*QGLFormat newform = this->format();
50  newform.setSamples(8);
51  this->setFormat(newform);*/
52 
53  QSurfaceFormat surfaceFormat = windowHandle()->format();
54  surfaceFormat.setStencilBufferSize(8);
55  windowHandle()->setFormat(surfaceFormat);
56 
58  {
59  GetRenderWindow()->SetMultiSamples(0);
60  GetRenderWindow()->SetAlphaBitPlanes(1);
61  }
62  else if (renderingMode == mitk::BaseRenderer::RenderingMode::MultiSampling)
63  {
64  GetRenderWindow()->SetMultiSamples(8);
65  }
66  else if (renderingMode == mitk::BaseRenderer::RenderingMode::Standard)
67  {
68  GetRenderWindow()->SetMultiSamples(0);
69  }
70 
71  Initialize(renderingManager, name.toStdString().c_str(), renderingMode); // Initialize mitkRenderWindowBase
72 
73  setFocusPolicy(Qt::StrongFocus);
74  setMouseTracking(true);
75 }
76 
78 {
79  Destroy(); // Destroy mitkRenderWindowBase
80 }
81 
83 {
84  m_ResendQtEvents = resend;
85 }
86 
87 void QmitkRenderWindow::SetLayoutIndex(unsigned int layoutIndex)
88 {
89  m_LayoutIndex = layoutIndex;
90  if (m_MenuWidget)
91  m_MenuWidget->SetLayoutIndex(layoutIndex);
92 }
93 
95 {
96  if (m_MenuWidget)
97  return m_MenuWidget->GetLayoutIndex();
98  else
99  return 0;
100 }
101 
103 {
104  if (m_MenuWidget)
105  m_MenuWidget->UpdateLayoutDesignList(layoutDesignIndex);
106 }
107 
109 {
110  // Get mouse position in vtk display coordinate system. me contains qt display infos...
111  mitk::Point2D displayPos = GetMousePosition(me);
112 
113  mitk::MousePressEvent::Pointer mPressEvent =
114  mitk::MousePressEvent::New(m_Renderer, displayPos, GetButtonState(me), GetModifiers(me), GetEventButton(me));
115 
116  if (!this->HandleEvent(mPressEvent.GetPointer()))
117  {
118  QVTKWidget::mousePressEvent(me);
119  }
120 
121  if (m_ResendQtEvents)
122  me->ignore();
123 }
124 
126 {
127  mitk::Point2D displayPos = GetMousePosition(me);
129  mitk::MouseDoubleClickEvent::New(m_Renderer, displayPos, GetButtonState(me), GetModifiers(me), GetEventButton(me));
130 
131  if (!this->HandleEvent(mPressEvent.GetPointer()))
132  {
133  QVTKWidget::mousePressEvent(me);
134  }
135 
136  if (m_ResendQtEvents)
137  me->ignore();
138 }
139 
141 {
142  mitk::Point2D displayPos = GetMousePosition(me);
143  mitk::MouseReleaseEvent::Pointer mReleaseEvent =
144  mitk::MouseReleaseEvent::New(m_Renderer, displayPos, GetButtonState(me), GetModifiers(me), GetEventButton(me));
145 
146  if (!this->HandleEvent(mReleaseEvent.GetPointer()))
147  {
148  QVTKWidget::mouseReleaseEvent(me);
149  }
150 
151  if (m_ResendQtEvents)
152  me->ignore();
153 }
154 
156 {
157  mitk::Point2D displayPos = GetMousePosition(me);
158 
159  this->AdjustRenderWindowMenuVisibility(me->pos());
160 
161  mitk::MouseMoveEvent::Pointer mMoveEvent =
162  mitk::MouseMoveEvent::New(m_Renderer, displayPos, GetButtonState(me), GetModifiers(me));
163 
164  if (!this->HandleEvent(mMoveEvent.GetPointer()))
165  {
166  QVTKWidget::mouseMoveEvent(me);
167  }
168 }
169 
170 void QmitkRenderWindow::wheelEvent(QWheelEvent *we)
171 {
172  mitk::Point2D displayPos = GetMousePosition(we);
173  mitk::MouseWheelEvent::Pointer mWheelEvent =
174  mitk::MouseWheelEvent::New(m_Renderer, displayPos, GetButtonState(we), GetModifiers(we), GetDelta(we));
175 
176  if (!this->HandleEvent(mWheelEvent.GetPointer()))
177  {
178  QVTKWidget::wheelEvent(we);
179  }
180 
181  if (m_ResendQtEvents)
182  we->ignore();
183 }
184 
186 {
187  mitk::InteractionEvent::ModifierKeys modifiers = GetModifiers(ke);
188  std::string key = GetKeyLetter(ke);
189 
191  if (!this->HandleEvent(keyEvent.GetPointer()))
192  {
193  QVTKWidget::keyPressEvent(ke);
194  }
195 
196  if (m_ResendQtEvents)
197  ke->ignore();
198 }
199 
201 {
202  // TODO implement new event
203  QVTKWidget::enterEvent(e);
204 }
205 
207 {
208  MITK_DEBUG << "QmitkRenderWindow::DeferredHideMenu";
209 
210  if (m_MenuWidget)
211  m_MenuWidget->HideMenu();
212 }
213 
215 {
216  mitk::InternalEvent::Pointer internalEvent = mitk::InternalEvent::New(this->m_Renderer, NULL, "LeaveRenderWindow");
217 
218  this->HandleEvent(internalEvent.GetPointer());
219 
220  if (m_MenuWidget)
221  m_MenuWidget->smoothHide();
222 
223  QVTKWidget::leaveEvent(e);
224 }
225 
226 void QmitkRenderWindow::paintEvent(QPaintEvent * /*event*/)
227 {
228  // We are using our own interaction and thus have to call the rendering manually.
229  this->GetRenderer()->GetRenderingManager()->RequestUpdate(GetRenderWindow());
230 }
231 
232 void QmitkRenderWindow::moveEvent(QMoveEvent *event)
233 {
234  QVTKWidget::moveEvent(event);
235 
236  // after a move the overlays need to be positioned
237  emit moved();
238 }
239 
240 void QmitkRenderWindow::showEvent(QShowEvent *event)
241 {
242  QVTKWidget::showEvent(event);
243 
244  // this singleshot is necessary to have the overlays positioned correctly after initial show
245  // simple call of moved() is no use here!!
246  QTimer::singleShot(0, this, SIGNAL(moved()));
247 }
248 
250 {
251  m_MenuWidgetActivated = state;
252 
253  if (!m_MenuWidgetActivated && m_MenuWidget)
254  {
255  // disconnect Signal/Slot Connection
256  disconnect(m_MenuWidget, SIGNAL(SignalChangeLayoutDesign(int)), this, SLOT(OnChangeLayoutDesign(int)));
257  disconnect(m_MenuWidget, SIGNAL(ResetView()), this, SIGNAL(ResetView()));
258  disconnect(m_MenuWidget, SIGNAL(ChangeCrosshairRotationMode(int)), this, SIGNAL(ChangeCrosshairRotationMode(int)));
259 
260  delete m_MenuWidget;
261  m_MenuWidget = 0;
262  }
263  else if (m_MenuWidgetActivated && !m_MenuWidget)
264  {
265  // create render window MenuBar for split, close Window or set new setting.
266  m_MenuWidget = new QmitkRenderWindowMenu(this, 0, m_Renderer, stdMultiWidget);
267  m_MenuWidget->SetLayoutIndex(m_LayoutIndex);
268 
269  // create Signal/Slot Connection
270  connect(m_MenuWidget, SIGNAL(SignalChangeLayoutDesign(int)), this, SLOT(OnChangeLayoutDesign(int)));
271  connect(m_MenuWidget, SIGNAL(ResetView()), this, SIGNAL(ResetView()));
272  connect(m_MenuWidget, SIGNAL(ChangeCrosshairRotationMode(int)), this, SIGNAL(ChangeCrosshairRotationMode(int)));
273  }
274 }
275 
277 {
278  if (m_MenuWidget)
279  {
280  m_MenuWidget->ShowMenu();
281  m_MenuWidget->MoveWidgetToCorrectPos(1.0f);
282  }
283 }
284 
286 {
287  // DEPRECATED METHOD
288 }
289 
290 void QmitkRenderWindow::OnChangeLayoutDesign(int layoutDesignIndex)
291 {
292  emit SignalLayoutDesignChanged(layoutDesignIndex);
293 }
294 
296 {
297  if (m_MenuWidget)
298  m_MenuWidget->NotifyNewWidgetPlanesMode(mode);
299 }
300 
302 {
303  if (m_MenuWidget)
304  m_MenuWidget->ChangeFullScreenMode(state);
305 }
306 
307 void QmitkRenderWindow::dragEnterEvent(QDragEnterEvent *event)
308 {
309  if (event->mimeData()->hasFormat("application/x-mitk-datanodes"))
310  {
311  event->accept();
312  }
313 }
314 
315 void QmitkRenderWindow::dropEvent(QDropEvent *event)
316 {
317  QList<mitk::DataNode *> dataNodeList = QmitkMimeTypes::ToDataNodePtrList(event->mimeData());
318  if (!dataNodeList.empty())
319  {
320  emit NodesDropped(this, dataNodeList.toVector().toStdVector());
321  }
322 }
323 
324 mitk::Point2D QmitkRenderWindow::GetMousePosition(QMouseEvent *me) const
325 {
326  mitk::Point2D point;
327  point[0] = me->x();
328  // We need to convert the y component, as the display and vtk have other definitions for the y direction
329  point[1] = m_Renderer->GetSizeY() - me->y();
330  return point;
331 }
332 
333 mitk::Point2D QmitkRenderWindow::GetMousePosition(QWheelEvent *we) const
334 {
335  mitk::Point2D point;
336  point[0] = we->x();
337  // We need to convert the y component, as the display and vtk have other definitions for the y direction
338  point[1] = m_Renderer->GetSizeY() - we->y();
339  return point;
340 }
341 
342 mitk::InteractionEvent::MouseButtons QmitkRenderWindow::GetEventButton(QMouseEvent *me) const
343 {
345  switch (me->button())
346  {
347  case Qt::LeftButton:
349  break;
350  case Qt::RightButton:
352  break;
353  case Qt::MidButton:
355  break;
356  default:
357  eventButton = mitk::InteractionEvent::NoButton;
358  break;
359  }
360  return eventButton;
361 }
362 
363 mitk::InteractionEvent::MouseButtons QmitkRenderWindow::GetButtonState(QMouseEvent *me) const
364 {
366 
367  if (me->buttons() & Qt::LeftButton)
368  {
369  buttonState = buttonState | mitk::InteractionEvent::LeftMouseButton;
370  }
371  if (me->buttons() & Qt::RightButton)
372  {
373  buttonState = buttonState | mitk::InteractionEvent::RightMouseButton;
374  }
375  if (me->buttons() & Qt::MidButton)
376  {
377  buttonState = buttonState | mitk::InteractionEvent::MiddleMouseButton;
378  }
379  return buttonState;
380 }
381 
382 mitk::InteractionEvent::ModifierKeys QmitkRenderWindow::GetModifiers(QInputEvent *me) const
383 {
385 
386  if (me->modifiers() & Qt::ALT)
387  {
388  modifiers = modifiers | mitk::InteractionEvent::AltKey;
389  }
390  if (me->modifiers() & Qt::CTRL)
391  {
392  modifiers = modifiers | mitk::InteractionEvent::ControlKey;
393  }
394  if (me->modifiers() & Qt::SHIFT)
395  {
396  modifiers = modifiers | mitk::InteractionEvent::ShiftKey;
397  }
398  return modifiers;
399 }
400 
401 mitk::InteractionEvent::MouseButtons QmitkRenderWindow::GetButtonState(QWheelEvent *we) const
402 {
404 
405  if (we->buttons() & Qt::LeftButton)
406  {
407  buttonState = buttonState | mitk::InteractionEvent::LeftMouseButton;
408  }
409  if (we->buttons() & Qt::RightButton)
410  {
411  buttonState = buttonState | mitk::InteractionEvent::RightMouseButton;
412  }
413  if (we->buttons() & Qt::MidButton)
414  {
415  buttonState = buttonState | mitk::InteractionEvent::MiddleMouseButton;
416  }
417  return buttonState;
418 }
419 
420 std::string QmitkRenderWindow::GetKeyLetter(QKeyEvent *ke) const
421 {
422  // Converting Qt Key Event to string element.
423  std::string key = "";
424  int tkey = ke->key();
425  if (tkey < 128)
426  { // standard ascii letter
427  key = (char)toupper(tkey);
428  }
429  else
430  { // special keys
431  switch (tkey)
432  {
433  case Qt::Key_Return:
435  break;
436  case Qt::Key_Enter:
438  break;
439  case Qt::Key_Escape:
441  break;
442  case Qt::Key_Delete:
444  break;
445  case Qt::Key_Up:
447  break;
448  case Qt::Key_Down:
450  break;
451  case Qt::Key_Left:
453  break;
454  case Qt::Key_Right:
456  break;
457 
458  case Qt::Key_F1:
460  break;
461  case Qt::Key_F2:
463  break;
464  case Qt::Key_F3:
466  break;
467  case Qt::Key_F4:
469  break;
470  case Qt::Key_F5:
472  break;
473  case Qt::Key_F6:
475  break;
476  case Qt::Key_F7:
478  break;
479  case Qt::Key_F8:
481  break;
482  case Qt::Key_F9:
484  break;
485  case Qt::Key_F10:
487  break;
488  case Qt::Key_F11:
490  break;
491  case Qt::Key_F12:
493  break;
494 
495  case Qt::Key_End:
497  break;
498  case Qt::Key_Home:
500  break;
501  case Qt::Key_Insert:
503  break;
504  case Qt::Key_PageDown:
506  break;
507  case Qt::Key_PageUp:
509  break;
510  case Qt::Key_Space:
512  break;
513  }
514  }
515  return key;
516 }
517 
518 int QmitkRenderWindow::GetDelta(QWheelEvent *we) const
519 {
520  return we->delta();
521 }
static const std::string KeyF1
static const std::string KeyF12
virtual bool HandleEvent(InteractionEvent *interactionEvent)
void LayoutDesignListChanged(int layoutDesignIndex)
static const std::string KeyF9
void FullScreenMode(bool state)
virtual void dropEvent(QDropEvent *event) override
If the dropped type is application/x-mitk-datanodes we process the request by converting to mitk::Dat...
static const std::string KeyF4
The QmitkRenderWindowMenu is a popup Widget which shows up when the mouse curser enter a QmitkRenderW...
void ChangeCrosshairRotationMode(int)
static Pointer New(BaseRenderer *_arga, const Point2D &_argb, MouseButtons _argc, ModifierKeys _argd, MouseButtons _arge)
static const std::string KeyPos1
virtual void dragEnterEvent(QDragEnterEvent *event) override
Simply says we accept the event type.
static const std::string KeyF10
static const std::string KeyEsc
static const std::string KeyArrowLeft
static const std::string KeySpace
void SignalLayoutDesignChanged(int layoutDesignIndex)
QmitkRenderWindow(QWidget *parent=0, QString name="unnamed renderwindow", mitk::VtkPropRenderer *renderer=NULL, mitk::RenderingManager *renderingManager=NULL, mitk::BaseRenderer::RenderingMode::Type renderingMode=mitk::BaseRenderer::RenderingMode::Standard)
static Pointer New(BaseRenderer *_arga, const Point2D &_argb, MouseButtons _argc, ModifierKeys _argd, MouseButtons _arge)
void SetLayoutIndex(unsigned int layoutIndex)
#define MITK_DEBUG
Definition: mitkLogMacros.h:26
static QList< mitk::DataNode * > ToDataNodePtrList(const QByteArray &ba)
void UpdateLayoutDesignList(int layoutDesignIndex)
static const std::string KeyEnd
virtual void mouseReleaseEvent(QMouseEvent *event) override
void OnWidgetPlaneModeChanged(int)
virtual void leaveEvent(QEvent *) override
static const std::string KeyArrowRight
static const std::string KeyEnter
void showEvent(QShowEvent *event) override
static const std::string KeyF7
void NotifyNewWidgetPlanesMode(int mode)
static Pointer New(BaseRenderer *_arga, const Point2D &_argb, MouseButtons _argc, ModifierKeys _argd, int _arge)
static const std::string KeyArrowDown
static const std::string KeyF2
static const std::string KeyF11
static Pointer New(BaseRenderer *_arga, const std::string &_argb, ModifierKeys _argc)
virtual void enterEvent(QEvent *) override
virtual mitk::RenderingManager * GetRenderingManager() const
Setter for the RenderingManager that handles this instance of BaseRenderer.
Manager for coordinating the rendering process.
mitk::VtkPropRenderer::Pointer m_Renderer
virtual void paintEvent(QPaintEvent *event) override
static const std::string KeyInsert
virtual void wheelEvent(QWheelEvent *) override
virtual void SetResendQtEvents(bool resend)
Whether Qt events should be passed to parent (default: true)
virtual void mouseDoubleClickEvent(QMouseEvent *event) override
static Pointer New(BaseRenderer *_arga, const Point2D &_argb, MouseButtons _argc, ModifierKeys _argd)
virtual mitk::VtkPropRenderer * GetRenderer()
virtual void keyPressEvent(QKeyEvent *event) override
static const std::string KeyDelete
void SetLayoutIndex(unsigned int layoutIndex)
static const std::string KeyF5
void RequestUpdate(vtkRenderWindow *renderWindow)
static Pointer New(BaseRenderer *_arga, const Point2D &_argb, MouseButtons _argc, ModifierKeys _argd, MouseButtons _arge)
virtual void moveEvent(QMoveEvent *event) override
virtual void mouseMoveEvent(QMouseEvent *event) override
void OnChangeLayoutDesign(int layoutDesignIndex)
void Initialize(mitk::RenderingManager *renderingManager=NULL, const char *name="unnamed renderer", mitk::BaseRenderer::RenderingMode::Type renderingMode=mitk::BaseRenderer::RenderingMode::Standard)
void NodesDropped(QmitkRenderWindow *thisWindow, std::vector< mitk::DataNode * > nodes)
Emits a signal to say that this window has had the following nodes dropped on it. ...
unsigned int GetLayoutIndex()
static Pointer New(BaseRenderer *_arga, DataInteractor *_argb, const std::string &_argc)
void ActivateMenuWidget(bool state, QmitkStdMultiWidget *stdMultiWidget=0)
static const std::string KeyF6
virtual void mousePressEvent(QMouseEvent *event) override
static const std::string KeyF3
static const std::string KeyF8
static const std::string KeyPageDown
static const std::string KeyReturn
static const std::string KeyArrowUp
void AdjustRenderWindowMenuVisibility(const QPoint &pos)
void ChangeFullScreenMode(bool state)
static const std::string KeyPageUp