1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    QQuickVTKInteractorAdapter.cxx
5 
6   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7   All rights reserved.
8   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10   This software is distributed WITHOUT ANY WARRANTY; without even
11   the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12   PURPOSE.  See the above copyright notice for more information.
13 
14 =========================================================================*/
15 #include "QQuickVTKInteractorAdapter.h"
16 
17 // Qt includes
18 #include <QEvent>
19 #include <QQuickItem>
20 #include <QQuickWindow>
21 
22 // VTK includes
23 #include "vtkRenderWindowInteractor.h"
24 
25 //-------------------------------------------------------------------------------------------------
QQuickVTKInteractorAdapter(QObject * parent)26 QQuickVTKInteractorAdapter::QQuickVTKInteractorAdapter(QObject* parent)
27   : Superclass(parent)
28 {
29 }
30 
31 //-------------------------------------------------------------------------------------------------
setQQuickWindow(QQuickWindow * win)32 void QQuickVTKInteractorAdapter::setQQuickWindow(QQuickWindow* win)
33 {
34   m_qwindow = win;
35 }
36 
37 //-------------------------------------------------------------------------------------------------
mapEventPosition(QQuickItem * item,const QPointF & localPos)38 QPointF QQuickVTKInteractorAdapter::mapEventPosition(QQuickItem* item, const QPointF& localPos)
39 {
40   // Account for the difference in coordinate reference systems.
41   // Qt uses quadrant IV and VTK uses quadrant I. So the point should be
42   // translated to the right position along Y axis.
43   return item->mapToScene(localPos);
44 }
45 
46 //-------------------------------------------------------------------------------------------------
mapEventPositionFlipY(QQuickItem * item,const QPointF & localPos)47 QPointF QQuickVTKInteractorAdapter::mapEventPositionFlipY(QQuickItem* item, const QPointF& localPos)
48 {
49   QPointF mappedPos = QQuickVTKInteractorAdapter::mapEventPosition(item, localPos);
50   mappedPos.setY(item->window()->height() - mappedPos.y() + 1);
51   return mappedPos;
52 }
53 
54 //-------------------------------------------------------------------------------------------------
QueueHoverEvent(QQuickItem * item,QHoverEvent * e)55 void QQuickVTKInteractorAdapter::QueueHoverEvent(QQuickItem* item, QHoverEvent* e)
56 {
57   QHoverEvent* newEvent = new QHoverEvent(e->type(), this->mapEventPosition(item, e->posF()),
58     this->mapEventPosition(item, e->oldPosF()), e->modifiers());
59   QueueEvent(newEvent);
60 }
61 
62 //-------------------------------------------------------------------------------------------------
QueueKeyEvent(QQuickItem * item,QKeyEvent * e)63 void QQuickVTKInteractorAdapter::QueueKeyEvent(QQuickItem* item, QKeyEvent* e)
64 {
65   Q_UNUSED(item);
66   QKeyEvent* newEvent = new QKeyEvent(e->type(), e->key(), e->modifiers(), e->nativeScanCode(),
67     e->nativeVirtualKey(), e->nativeModifiers(), e->text(), e->isAutoRepeat(), e->count());
68   QueueEvent(newEvent);
69 }
70 
71 //-------------------------------------------------------------------------------------------------
QueueFocusEvent(QQuickItem * item,QFocusEvent * e)72 void QQuickVTKInteractorAdapter::QueueFocusEvent(QQuickItem* item, QFocusEvent* e)
73 {
74   Q_UNUSED(item);
75   QFocusEvent* newEvent = new QFocusEvent(e->type(), e->reason());
76   QueueEvent(newEvent);
77 }
78 
79 //-------------------------------------------------------------------------------------------------
QueueMouseEvent(QQuickItem * item,QMouseEvent * e)80 void QQuickVTKInteractorAdapter::QueueMouseEvent(QQuickItem* item, QMouseEvent* e)
81 {
82   QMouseEvent* newEvent = new QMouseEvent(e->type(), this->mapEventPosition(item, e->localPos()),
83     this->mapEventPosition(item, e->windowPos()), this->mapEventPosition(item, e->screenPos()),
84     e->button(), e->buttons(), e->modifiers());
85   QueueEvent(newEvent);
86 }
87 
88 //-------------------------------------------------------------------------------------------------
QueueGeometryChanged(const QRectF & newGeometry,const QRectF & oldGeometry)89 void QQuickVTKInteractorAdapter::QueueGeometryChanged(
90   const QRectF& newGeometry, const QRectF& oldGeometry)
91 {
92   QResizeEvent* newEvent =
93     new QResizeEvent(newGeometry.size().toSize(), oldGeometry.size().toSize());
94   QueueEvent(newEvent);
95 }
96 
97 //-------------------------------------------------------------------------------------------------
QueueWheelEvent(QQuickItem * item,QWheelEvent * e)98 void QQuickVTKInteractorAdapter::QueueWheelEvent(QQuickItem* item, QWheelEvent* e)
99 {
100   QPointF p, gp;
101 #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
102   p = e->position();
103   gp = e->globalPosition();
104 #else
105   p = e->posF();
106   gp = e->globalPosF();
107 #endif
108   QWheelEvent* newEvent = new QWheelEvent(this->mapEventPosition(item, p),
109     this->mapEventPosition(item, gp), e->pixelDelta(), e->angleDelta(), e->buttons(),
110     e->modifiers(), e->phase(), e->inverted(), e->source());
111   QueueEvent(newEvent);
112 }
113 
114 //-------------------------------------------------------------------------------------------------
QueueEvent(QEvent * e)115 void QQuickVTKInteractorAdapter::QueueEvent(QEvent* e)
116 {
117   m_queuedEvents << e;
118   if (m_qwindow)
119   {
120     m_qwindow->update();
121   }
122 }
123 
124 //-------------------------------------------------------------------------------------------------
ProcessEvents(vtkRenderWindowInteractor * interactor)125 void QQuickVTKInteractorAdapter::ProcessEvents(vtkRenderWindowInteractor* interactor)
126 {
127   if (interactor)
128   {
129     for (QEvent* e : this->m_queuedEvents)
130     {
131       ProcessEvent(e, interactor);
132     }
133     qDeleteAll(m_queuedEvents);
134     m_queuedEvents.clear();
135   }
136 }
137