diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h index 7881df2..7f9129d 100644 --- a/src/gui/kernel/qevent.h +++ b/src/gui/kernel/qevent.h @@ -822,6 +822,48 @@ inline bool operator!=(QPointingDeviceUniqueId lhs, QPointingDeviceUniqueId rhs) { return !operator==(lhs, rhs); } Q_GUI_EXPORT uint qHash(QPointingDeviceUniqueId key, uint seed = 0) Q_DECL_NOTHROW; +// pks: apple pencil +class Q_GUI_EXPORT QApplePencilEvent : public QInputEvent +{ +public: + + class Q_GUI_EXPORT Point { + public: + + Point(QPointF p=QPointF(), qreal pressure=0.0) : _point(p), _pressure(pressure) {} + inline QPointF point() const { return _point; } + inline qreal pressure() const { return _pressure; } + + private: + QPointF _point; + qreal _pressure; + }; + + QApplePencilEvent(Qt::TouchPointState state, + const Point &touchPoint, + const QList &coalesced, + const QList &predicted, + ulong timestamp) + : QInputEvent(QEvent::User), + _state(state), + _point(touchPoint), + _coalesced(coalesced), + _predicted(predicted) + { + setTimestamp(timestamp); + } + + inline Qt::TouchPointState state() const { return _state; } + inline Point point() const { return _point; } + inline const QList &coalesced() const { return _coalesced; } + inline const QList &predicted() const { return _predicted; } + +private: + Qt::TouchPointState _state; + Point _point; + QList _coalesced; + QList _predicted; +}; class QTouchEventTouchPointPrivate; diff --git a/src/plugins/platforms/ios/quiview.mm b/src/plugins/platforms/ios/quiview.mm index 2a1444e..20fee83 100644 --- a/src/plugins/platforms/ios/quiview.mm +++ b/src/plugins/platforms/ios/quiview.mm @@ -52,6 +52,9 @@ #include #include +// pks: apple pencil +#include "../../../widgets/kernel/qapplication.h" + @implementation QUIView + (Class)layerClass @@ -348,10 +351,72 @@ } } -- (void)sendTouchEventWithTimestamp:(ulong)timeStamp +- (void)sendTouchEventWithTimestamp:(ulong)timeStamp :(UIEvent*)event { QIOSIntegration *iosIntegration = QIOSIntegration::instance(); - QWindowSystemInterface::handleTouchEvent(m_qioswindow->window(), timeStamp, iosIntegration->touchDevice(), m_activeTouches.values()); + + // pks: apple pencil + QList coalesced; + QList predicted; + QApplePencilEvent::Point touchPoint; + Qt::TouchPointState state; + bool mainTouch = false; + QPointF point; + qreal pressure; + + // get status bar height + //CGSize statusBarSize = [[UIApplication sharedApplication] statusBarFrame].size; + //return MIN(statusBarSize.width, statusBarSize.height); + + foreach (UITouch *uiTouch, m_activeTouches.keys()) { + if (uiTouch.type == UITouchTypeStylus) { + NSArray *cTouches = [event coalescedTouchesForTouch:uiTouch]; + for (UITouch *cTouch in cTouches) { + if (mainTouch == false) { + // should only be one anyway + point = QPointF::fromCGPoint([uiTouch locationInView:self]); + //qDebug() << "quiview.mm: touchPoint: " << point; + // QPoint _localViewPosition = QPointF::fromCGPoint([cTouch locationInView:self]).toPoint(); + // QPoint _globalScreenPosition = m_qioswindow->mapToGlobal(_localViewPosition); + // touchPoint.point = _globalScreenPosition; + pressure = uiTouch.force / uiTouch.maximumPossibleForce; + touchPoint = QApplePencilEvent::Point(point, pressure); + state = m_activeTouches[uiTouch].state; + mainTouch = true; + } + point = QPointF::fromCGPoint([cTouch locationInView:self]); + //qDebug() << "quiview.mm: coalesced: " << point; + // QPoint localViewPosition = QPointF::fromCGPoint([cTouch locationInView:self]).toPoint(); + // QPoint globalScreenPosition = m_qioswindow->mapToGlobal(localViewPosition); + // point.point = globalScreenPosition; + pressure = cTouch.force / cTouch.maximumPossibleForce; + //CGPoint p = [cTouch locationInView:self]; + //qDebug() << "QUIView:sendTouchEventWithTimestamp: locationInView: " << p.x << "," << p.y << " localViewPosition: " << localViewPosition << " globalScreenPosition: " << globalScreenPosition; + coalesced << QApplePencilEvent::Point(point, pressure); + } + NSArray *pTouches = [event predictedTouchesForTouch:uiTouch]; + for (UITouch *pTouch in pTouches) { + point = QPointF::fromCGPoint([pTouch locationInView:self]); + //qDebug() << "quiview.mm: predicted: " << point; + // QPoint localViewPosition = QPointF::fromCGPoint([pTouch locationInView:self]).toPoint(); + // QPoint globalScreenPosition = m_qioswindow->mapToGlobal(localViewPosition); + // point.point = globalScreenPosition; + pressure = pTouch.force / pTouch.maximumPossibleForce; + // qDebug() << "QUIView:sendTouchEventWithTimestamp: predicted: " << pTouch; + predicted << QApplePencilEvent::Point(point, pressure); + } + } + } + bool handled = false; + if (coalesced.size() > 0 || predicted.size() > 0) { + if (QApplication::instance()) { + QApplePencilEvent pencilEvent(state, touchPoint, coalesced, predicted, timeStamp); + handled = QApplication::sendEvent(QApplication::instance(), &pencilEvent); + } + } + if (!handled) { + QWindowSystemInterface::handleTouchEvent(m_qioswindow->window(), timeStamp, iosIntegration->touchDevice(), m_activeTouches.values()); + } } - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event @@ -374,19 +439,19 @@ } [self updateTouchList:touches withState:Qt::TouchPointPressed]; - [self sendTouchEventWithTimestamp:ulong(event.timestamp * 1000)]; + [self sendTouchEventWithTimestamp:ulong(event.timestamp * 1000) :event]; } - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { [self updateTouchList:touches withState:Qt::TouchPointMoved]; - [self sendTouchEventWithTimestamp:ulong(event.timestamp * 1000)]; + [self sendTouchEventWithTimestamp:ulong(event.timestamp * 1000) :event]; } - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { [self updateTouchList:touches withState:Qt::TouchPointReleased]; - [self sendTouchEventWithTimestamp:ulong(event.timestamp * 1000)]; + [self sendTouchEventWithTimestamp:ulong(event.timestamp * 1000) :event]; // Remove ended touch points from the active set: for (UITouch *touch in touches) diff --git a/src/widgets/graphicsview/qgraphicsview.cpp b/src/widgets/graphicsview/qgraphicsview.cpp index 41f5edd..7fe204a 100644 --- a/src/widgets/graphicsview/qgraphicsview.cpp +++ b/src/widgets/graphicsview/qgraphicsview.cpp @@ -2405,6 +2405,17 @@ QPointF QGraphicsView::mapToScene(const QPoint &point) const return d->identityMatrix ? p : d->matrix.inverted().map(p); } +// pks: apple pencil +QPointF QGraphicsView::mapToScene(const QPointF &point) const +{ + Q_D(const QGraphicsView); + QPointF p = point; + p.rx() += d->horizontalScroll(); + p.ry() += d->verticalScroll(); + return d->identityMatrix ? p : d->matrix.inverted().map(p); +} + + /*! \fn QGraphicsView::mapToScene(int x, int y) const diff --git a/src/widgets/graphicsview/qgraphicsview.h b/src/widgets/graphicsview/qgraphicsview.h index 327a75c..8ad88b3 100644 --- a/src/widgets/graphicsview/qgraphicsview.h +++ b/src/widgets/graphicsview/qgraphicsview.h @@ -203,6 +203,7 @@ public: inline QGraphicsItem *itemAt(int x, int y) const; QPointF mapToScene(const QPoint &point) const; + QPointF mapToScene(const QPointF &point) const; // pks: apple pencil QPolygonF mapToScene(const QRect &rect) const; QPolygonF mapToScene(const QPolygon &polygon) const; QPainterPath mapToScene(const QPainterPath &path) const;