From 041b809a62f1992d630bc98f1fac66d50b831274 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 22 Jun 2011 13:57:35 +0200 Subject: [PATCH] Cocoa: implement support for wheel events --- src/plugins/platforms/cocoa/qnsview.mm | 97 +++++++++++++++++++++++++++------- 1 file changed, 79 insertions(+), 18 deletions(-) diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 5d7fd05..be50dda 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -39,12 +39,18 @@ ** ****************************************************************************/ -#include "qnsview.h" +#include +#include "qnsview.h" #include - #include +@interface NSEvent (Qt_Compile_Leopard_DeviceDelta) + - (CGFloat)deviceDeltaX; + - (CGFloat)deviceDeltaY; + - (CGFloat)deviceDeltaZ; +@end + @implementation QNSView - (id) init @@ -170,48 +176,103 @@ { [self handleMouseEvent:theEvent]; } + - (void)mouseEntered:(NSEvent *)theEvent { - Q_UNUSED(theEvent); - QWindowSystemInterface::handleEnterEvent(m_window); + Q_UNUSED(theEvent); + QWindowSystemInterface::handleEnterEvent(m_window); } + - (void)mouseExited:(NSEvent *)theEvent { - Q_UNUSED(theEvent); - QWindowSystemInterface::handleLeaveEvent(m_window); + Q_UNUSED(theEvent); + QWindowSystemInterface::handleLeaveEvent(m_window); } + - (void)rightMouseDown:(NSEvent *)theEvent { - m_buttons |= Qt::RightButton; + m_buttons |= Qt::RightButton; [self handleMouseEvent:theEvent]; } + - (void)rightMouseDragged:(NSEvent *)theEvent { - if (!(m_buttons & Qt::LeftButton)) - qWarning("Internal Mousebutton tracking invalid(missing Qt::LeftButton"); - [self handleMouseEvent:theEvent]; + if (!(m_buttons & Qt::LeftButton)) + qWarning("Internal Mousebutton tracking invalid(missing Qt::LeftButton"); + [self handleMouseEvent:theEvent]; } + - (void)rightMouseUp:(NSEvent *)theEvent { - m_buttons &= QFlag(~int(Qt::RightButton)); - [self handleMouseEvent:theEvent]; + m_buttons &= QFlag(~int(Qt::RightButton)); + [self handleMouseEvent:theEvent]; } + - (void)otherMouseDown:(NSEvent *)theEvent { - m_buttons |= Qt::RightButton; + m_buttons |= Qt::RightButton; [self handleMouseEvent:theEvent]; } + - (void)otherMouseDragged:(NSEvent *)theEvent { - if (!(m_buttons & Qt::LeftButton)) - qWarning("Internal Mousebutton tracking invalid(missing Qt::LeftButton"); - [self handleMouseEvent:theEvent]; + if (!(m_buttons & Qt::LeftButton)) + qWarning("Internal Mousebutton tracking invalid(missing Qt::LeftButton"); + [self handleMouseEvent:theEvent]; } + - (void)otherMouseUp:(NSEvent *)theEvent { - m_buttons &= QFlag(~int(Qt::MiddleButton)); - [self handleMouseEvent:theEvent]; + m_buttons &= QFlag(~int(Qt::MiddleButton)); + [self handleMouseEvent:theEvent]; +} + +#ifndef QT_NO_WHEELEVENT +- (void)scrollWheel:(NSEvent *)theEvent +{ + int deltaX = 0; + int deltaY = 0; + int deltaZ = 0; + + const EventRef carbonEvent = (EventRef)[theEvent eventRef]; + const UInt32 carbonEventKind = carbonEvent ? ::GetEventKind(carbonEvent) : 0; + const bool scrollEvent = carbonEventKind == kEventMouseScroll; + + if (scrollEvent) { + // The mouse device containts pixel scroll wheel support (Mighty Mouse, Trackpad). + // Since deviceDelta is delivered as pixels rather than degrees, we need to + // convert from pixels to degrees in a sensible manner. + // It looks like 1/4 degrees per pixel behaves most native. + // (NB: Qt expects the unit for delta to be 8 per degree): + const int pixelsToDegrees = 2; // 8 * 1/4 + deltaX = [theEvent deviceDeltaX] * pixelsToDegrees; + deltaY = [theEvent deviceDeltaY] * pixelsToDegrees; + deltaZ = [theEvent deviceDeltaZ] * pixelsToDegrees; + } else { + // carbonEventKind == kEventMouseWheelMoved + // Remove acceleration, and use either -120 or 120 as delta: + deltaX = qBound(-120, int([theEvent deltaX] * 10000), 120); + deltaY = qBound(-120, int([theEvent deltaY] * 10000), 120); + deltaZ = qBound(-120, int([theEvent deltaZ] * 10000), 120); + } + + NSPoint windowPoint = [self convertPoint: [theEvent locationInWindow] fromView: nil]; + QPoint qt_windowPoint(windowPoint.x, windowPoint.y); + NSTimeInterval timestamp = [theEvent timestamp]; + ulong qt_timestamp = timestamp * 1000; + + if (deltaX != 0) + QWindowSystemInterface::handleWheelEvent(m_window, qt_timestamp, qt_windowPoint, qt_windowPoint, deltaX, Qt::Horizontal); + + if (deltaY != 0) + QWindowSystemInterface::handleWheelEvent(m_window, qt_timestamp, qt_windowPoint, qt_windowPoint, deltaY, Qt::Vertical); + + if (deltaZ != 0) + // Qt doesn't explicitly support wheels with a Z component. In a misguided attempt to + // try to be ahead of the pack, I'm adding this extra value. + QWindowSystemInterface::handleWheelEvent(m_window, qt_timestamp, qt_windowPoint, qt_windowPoint, deltaY, (Qt::Orientation)3); } +#endif //QT_NO_WHEELEVENT - (int) convertKeyCode : (QChar)keyChar { -- 2.7.4