iOS: Add support for hover feature for Apple Pencil 2nd gen or later
Add UIHoverGestureRecognizer to support Hover feature. Task-number: QTBUG-128473 Change-Id: I73bbd1b8cca1ffcb8fcc27f6c26cb4ab8830c690 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
This commit is contained in:
parent
cf674f3845
commit
2429c73cc9
@ -59,6 +59,9 @@ inline ulong getTimeStamp(UIEvent *event)
|
|||||||
UIPanGestureRecognizer *m_scrollGestureRecognizer;
|
UIPanGestureRecognizer *m_scrollGestureRecognizer;
|
||||||
CGPoint m_lastScrollCursorPos;
|
CGPoint m_lastScrollCursorPos;
|
||||||
CGPoint m_lastScrollDelta;
|
CGPoint m_lastScrollDelta;
|
||||||
|
#if QT_CONFIG(tabletevent)
|
||||||
|
UIHoverGestureRecognizer *m_hoverGestureRecognizer;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (Class)layerClass
|
+ (Class)layerClass
|
||||||
@ -99,6 +102,13 @@ inline ulong getTimeStamp(UIEvent *event)
|
|||||||
m_lastScrollCursorPos = CGPointZero;
|
m_lastScrollCursorPos = CGPointZero;
|
||||||
[self addGestureRecognizer:m_scrollGestureRecognizer];
|
[self addGestureRecognizer:m_scrollGestureRecognizer];
|
||||||
|
|
||||||
|
#if QT_CONFIG(tabletevent)
|
||||||
|
m_hoverGestureRecognizer = [[UIHoverGestureRecognizer alloc]
|
||||||
|
initWithTarget:self
|
||||||
|
action:@selector(handleHover:)];
|
||||||
|
[self addGestureRecognizer:m_hoverGestureRecognizer];
|
||||||
|
#endif
|
||||||
|
|
||||||
// Set up layer
|
// Set up layer
|
||||||
if ([self.layer isKindOfClass:CAMetalLayer.class]) {
|
if ([self.layer isKindOfClass:CAMetalLayer.class]) {
|
||||||
QWindow *window = self.platformWindow->window();
|
QWindow *window = self.platformWindow->window();
|
||||||
@ -362,6 +372,39 @@ inline ulong getTimeStamp(UIEvent *event)
|
|||||||
return [super pointInside:point withEvent:event];
|
return [super pointInside:point withEvent:event];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if QT_CONFIG(tabletevent)
|
||||||
|
- (void)handlePencilEventForLocationInView:(CGPoint)locationInView withState:(QEventPoint::State)state withTimestamp:(ulong)timeStamp
|
||||||
|
withForce:(CGFloat)force withMaximumPossibleForce:(CGFloat)maximumPossibleForce withZOffset:(CGFloat)zOffset
|
||||||
|
withAzimuthUnitVector:(CGVector)azimuth withAltitudeAngleRadian:(CGFloat)altitudeAngleRadian
|
||||||
|
{
|
||||||
|
QIOSIntegration *iosIntegration = QIOSIntegration::instance();
|
||||||
|
|
||||||
|
QPointF localViewPosition = QPointF::fromCGPoint(locationInView);
|
||||||
|
QPoint localViewPositionI = localViewPosition.toPoint();
|
||||||
|
QPointF globalScreenPosition = self.platformWindow->mapToGlobal(localViewPositionI) +
|
||||||
|
(localViewPosition - localViewPositionI);
|
||||||
|
qreal pressure = 0;
|
||||||
|
if (force != 0 && maximumPossibleForce != 0)
|
||||||
|
pressure = force / maximumPossibleForce;
|
||||||
|
// azimuth unit vector: +x to the right, +y going downwards
|
||||||
|
// altitudeAngleRadian given in radians, pi / 2 is with the stylus perpendicular to the iPad, smaller values mean more tilted, but never negative.
|
||||||
|
// Convert to degrees with zero being perpendicular.
|
||||||
|
qreal altitudeAngle = 90 - qRadiansToDegrees(altitudeAngleRadian);
|
||||||
|
qreal xTilt = qBound(-60.0, altitudeAngle * azimuth.dx, 60.0);
|
||||||
|
qreal yTilt = qBound(-60.0, altitudeAngle * azimuth.dy, 60.0);
|
||||||
|
|
||||||
|
qCDebug(lcQpaTablet) << ":" << timeStamp << localViewPosition << pressure << state << "azimuth" << azimuth.dx << azimuth.dy
|
||||||
|
<< "altitude" << altitudeAngleRadian << "xTilt" << xTilt << "yTilt" << yTilt;
|
||||||
|
QWindowSystemInterface::handleTabletEvent(self.platformWindow->window(), timeStamp,
|
||||||
|
// device, local, global
|
||||||
|
iosIntegration->pencilDevice(), localViewPosition, globalScreenPosition,
|
||||||
|
// buttons
|
||||||
|
state == QEventPoint::State::Released ? Qt::NoButton : Qt::LeftButton,
|
||||||
|
// pressure, xTilt, yTilt, tangentialPressure, rotation, z, modifiers
|
||||||
|
pressure, xTilt, yTilt, 0, 0, zOffset, Qt::NoModifier);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
- (void)handleTouches:(NSSet *)touches withEvent:(UIEvent *)event withState:(QEventPoint::State)state withTimestamp:(ulong)timeStamp
|
- (void)handleTouches:(NSSet *)touches withEvent:(UIEvent *)event withState:(QEventPoint::State)state withTimestamp:(ulong)timeStamp
|
||||||
{
|
{
|
||||||
QIOSIntegration *iosIntegration = QIOSIntegration::instance();
|
QIOSIntegration *iosIntegration = QIOSIntegration::instance();
|
||||||
@ -370,30 +413,11 @@ inline ulong getTimeStamp(UIEvent *event)
|
|||||||
#if QT_CONFIG(tabletevent)
|
#if QT_CONFIG(tabletevent)
|
||||||
if (m_activePencilTouch && [touches containsObject:m_activePencilTouch]) {
|
if (m_activePencilTouch && [touches containsObject:m_activePencilTouch]) {
|
||||||
NSArray<UITouch *> *cTouches = [event coalescedTouchesForTouch:m_activePencilTouch];
|
NSArray<UITouch *> *cTouches = [event coalescedTouchesForTouch:m_activePencilTouch];
|
||||||
int i = 0;
|
|
||||||
for (UITouch *cTouch in cTouches) {
|
for (UITouch *cTouch in cTouches) {
|
||||||
QPointF localViewPosition = QPointF::fromCGPoint([cTouch preciseLocationInView:self]);
|
[self handlePencilEventForLocationInView:[cTouch preciseLocationInView:self] withState:state withTimestamp:timeStamp
|
||||||
QPoint localViewPositionI = localViewPosition.toPoint();
|
withForce:cTouch.force withMaximumPossibleForce:cTouch.maximumPossibleForce withZOffset:0
|
||||||
QPointF globalScreenPosition = self.platformWindow->mapToGlobal(localViewPositionI) +
|
withAzimuthUnitVector:[cTouch azimuthUnitVectorInView:self]
|
||||||
(localViewPosition - localViewPositionI);
|
withAltitudeAngleRadian:cTouch.altitudeAngle];
|
||||||
qreal pressure = cTouch.force / cTouch.maximumPossibleForce;
|
|
||||||
// azimuth unit vector: +x to the right, +y going downwards
|
|
||||||
CGVector azimuth = [cTouch azimuthUnitVectorInView:self];
|
|
||||||
// altitudeAngle given in radians, pi / 2 is with the stylus perpendicular to the iPad, smaller values mean more tilted, but never negative.
|
|
||||||
// Convert to degrees with zero being perpendicular.
|
|
||||||
qreal altitudeAngle = 90 - qRadiansToDegrees(cTouch.altitudeAngle);
|
|
||||||
qreal xTilt = qBound(-60.0, altitudeAngle * azimuth.dx, 60.0);
|
|
||||||
qreal yTilt = qBound(-60.0, altitudeAngle * azimuth.dy, 60.0);
|
|
||||||
qCDebug(lcQpaTablet) << i << ":" << timeStamp << localViewPosition << pressure << state << "azimuth" << azimuth.dx << azimuth.dy
|
|
||||||
<< "altitude" << cTouch.altitudeAngle << "xTilt" << xTilt << "yTilt" << yTilt;
|
|
||||||
QWindowSystemInterface::handleTabletEvent(self.platformWindow->window(), timeStamp,
|
|
||||||
// device, local, global
|
|
||||||
iosIntegration->pencilDevice(), localViewPosition, globalScreenPosition,
|
|
||||||
// buttons
|
|
||||||
state == QEventPoint::State::Released ? Qt::NoButton : Qt::LeftButton,
|
|
||||||
// pressure, xTilt, yTilt, tangentialPressure, rotation, z, modifiers
|
|
||||||
pressure, xTilt, yTilt, 0, 0, 0, Qt::NoModifier);
|
|
||||||
++i;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -759,6 +783,28 @@ inline ulong getTimeStamp(UIEvent *event)
|
|||||||
}
|
}
|
||||||
#endif // QT_CONFIG(wheelevent)
|
#endif // QT_CONFIG(wheelevent)
|
||||||
|
|
||||||
|
#if QT_CONFIG(tabletevent)
|
||||||
|
- (void)handleHover:(UIHoverGestureRecognizer *)recognizer
|
||||||
|
{
|
||||||
|
ulong timeStamp = [[NSProcessInfo processInfo] systemUptime] * 1000;
|
||||||
|
|
||||||
|
CGFloat zOffset = 0;
|
||||||
|
if (@available(ios 16.1, *))
|
||||||
|
zOffset = [recognizer zOffset];
|
||||||
|
|
||||||
|
CGVector azimuth;
|
||||||
|
CGFloat altitudeAngleRadian = 0;
|
||||||
|
if (@available(ios 16.4, *)) {
|
||||||
|
azimuth = [recognizer azimuthUnitVectorInView:self];
|
||||||
|
altitudeAngleRadian = recognizer.altitudeAngle;
|
||||||
|
}
|
||||||
|
|
||||||
|
[self handlePencilEventForLocationInView:[recognizer locationInView:self] withState:QEventPoint::State::Released
|
||||||
|
withTimestamp:timeStamp withForce:0 withMaximumPossibleForce:0 withZOffset:zOffset
|
||||||
|
withAzimuthUnitVector:azimuth withAltitudeAngleRadian:altitudeAngleRadian];
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation UIView (QtHelpers)
|
@implementation UIView (QtHelpers)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user