diff options
author | Damien Plisson <damien.plisson@yahoo.fr> | 2010-01-11 14:14:36 +0300 |
---|---|---|
committer | Damien Plisson <damien.plisson@yahoo.fr> | 2010-01-11 14:14:36 +0300 |
commit | 4a011a99cb9f45e0d76b134d72c2c2ab150ba006 (patch) | |
tree | 6141ccea3ff99236c32e31f479ef5ba36835a629 /intern | |
parent | ebb9286fd65d3cb1aae001080dbdb7102e7b49bf (diff) |
Multitouch trackpad 2 fingers gestures implementation
- 2 fingers scroll (MOUSEPAN / GHOST_kTrackpadEventScroll event) pans/scrolls the view
- 2 fingers pinch (MOUSEZOOM / GHOST_kTrackpadEventMagnify event) zooms the view
And in 3D view:
- alt + 2 fingers scroll rotates the view
- 2 fingers rotation (MOUSEROTATE / GHOST_kTrackpadEventRotate) orbits the view.
The implementation uses a new GHOST event type: GHOST_kEventTrackpad, that is then dispatched as Blender MOUSEPAN, MOUSEZOOM
or MOUSEROTATE events.
This is currently fully implemented for OSX (GHOST Cocoa fires the new events), with auto-detection of the source peripheral, so that a regular mouse still sends MOUSEWHEEL events.
Diffstat (limited to 'intern')
-rw-r--r-- | intern/ghost/GHOST_Types.h | 23 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_EventTrackpad.h | 71 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_SystemCocoa.mm | 80 |
3 files changed, 162 insertions, 12 deletions
diff --git a/intern/ghost/GHOST_Types.h b/intern/ghost/GHOST_Types.h index 5c888e218d8..e26013c1ecd 100644 --- a/intern/ghost/GHOST_Types.h +++ b/intern/ghost/GHOST_Types.h @@ -151,6 +151,7 @@ typedef enum { GHOST_kEventButtonDown, /// Mouse button event GHOST_kEventButtonUp, /// Mouse button event GHOST_kEventWheel, /// Mouse wheel event + GHOST_kEventTrackpad, /// Trackpad event GHOST_kEventNDOFMotion, /// N degree of freedom device motion event GHOST_kEventNDOFButton, /// N degree of freedom device button event @@ -373,6 +374,28 @@ typedef struct { GHOST_TInt32 z; } GHOST_TEventWheelData; +typedef enum { + GHOST_kTrackpadEventUnknown =0, + GHOST_kTrackpadEventScroll, + GHOST_kTrackpadEventRotate, + GHOST_kTrackpadEventSwipe, /* Reserved, not used for now */ + GHOST_kTrackpadEventMagnify +} GHOST_TTrackpadEventSubTypes; + + +typedef struct { + /** The event subtype */ + GHOST_TTrackpadEventSubTypes subtype; + /** The x-location of the trackpad event */ + GHOST_TInt32 x; + /** The y-location of the trackpad event */ + GHOST_TInt32 y; + /** The x-delta or value of the trackpad event */ + GHOST_TInt32 deltaX; + /** The y-delta (currently only for scroll subtype) of the trackpad event */ + GHOST_TInt32 deltaY; +} GHOST_TEventTrackpadData; + typedef enum { GHOST_kDragnDropTypeUnknown =0, diff --git a/intern/ghost/intern/GHOST_EventTrackpad.h b/intern/ghost/intern/GHOST_EventTrackpad.h new file mode 100644 index 00000000000..c2332d8e920 --- /dev/null +++ b/intern/ghost/intern/GHOST_EventTrackpad.h @@ -0,0 +1,71 @@ +/** + * $Id$ + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): James Deery 11/2009 + * Damien Plisson 12/2009 + * + * ***** END GPL LICENSE BLOCK ***** + */ +/** + * @file GHOST_EventTrackpad.h + * Declaration of GHOST_EventTrackpad class. + */ + +#ifndef _GHOST_EVENT_TRACKPAD_H_ +#define _GHOST_EVENT_TRACKPAD_H_ + +#include "GHOST_Event.h" + +/** + * Trackpad (scroll, magnify, rotate, ...) event. + */ +class GHOST_EventTrackpad : public GHOST_Event +{ +public: + /** + * Constructor. + * @param msec The time this event was generated. + * @param type The type of this event. + * @param subtype The subtype of the event. + * @param x The x-delta of the pan event. + * @param y The y-delta of the pan event. + */ + GHOST_EventTrackpad(GHOST_TUns64 msec, GHOST_IWindow* window, GHOST_TTrackpadEventSubTypes subtype, GHOST_TInt32 x, GHOST_TInt32 y, GHOST_TInt32 deltaX, GHOST_TInt32 deltaY) + : GHOST_Event(msec, GHOST_kEventTrackpad, window) + { + m_trackpadEventData.subtype = subtype; + m_trackpadEventData.x = x; + m_trackpadEventData.y = y; + m_trackpadEventData.deltaX = deltaX; + m_trackpadEventData.deltaY = deltaY; + m_data = &m_trackpadEventData; + } + +protected: + /** The mouse pan data */ + GHOST_TEventTrackpadData m_trackpadEventData; +}; + + +#endif // _GHOST_EVENT_PAN_H_ + diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm index 1ba20315512..735efcda395 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.mm +++ b/intern/ghost/intern/GHOST_SystemCocoa.mm @@ -41,6 +41,7 @@ #include "GHOST_EventCursor.h" #include "GHOST_EventWheel.h" #include "GHOST_EventNDOF.h" +#include "GHOST_EventTrackpad.h" #include "GHOST_EventDragnDrop.h" #include "GHOST_TimerManager.h" @@ -376,6 +377,24 @@ static GHOST_TKey convertKey(int rawCode, unichar recvChar) #pragma mark defines for 10.6 api not documented in 10.5 #ifndef MAC_OS_X_VERSION_10_6 +enum { + /* The following event types are available on some hardware on 10.5.2 and later */ + NSEventTypeGesture = 29, + NSEventTypeMagnify = 30, + NSEventTypeSwipe = 31, + NSEventTypeRotate = 18, + NSEventTypeBeginGesture = 19, + NSEventTypeEndGesture = 20 +}; + +@interface NSEvent(GestureEvents) +/* This message is valid for events of type NSEventTypeMagnify, on 10.5.2 or later */ +#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 +- (float)magnification; // change in magnification. +#else +- (CGFloat)magnification; // change in magnification. +#endif +@end @interface NSEvent(SnowLeopardEvents) /* modifier keys currently down. This returns the state of devices combined @@ -596,7 +615,7 @@ GHOST_TSuccess GHOST_SystemCocoa::init() } [NSApp finishLaunching]; - + [pool drain]; } return success; @@ -846,7 +865,9 @@ bool GHOST_SystemCocoa::processEvents(bool waitForEvent) case NSScrollWheel: case NSOtherMouseDown: case NSOtherMouseUp: - case NSOtherMouseDragged: + case NSOtherMouseDragged: + case NSEventTypeMagnify: + case NSEventTypeRotate: handleMouseEvent(event); break; @@ -855,11 +876,9 @@ bool GHOST_SystemCocoa::processEvents(bool waitForEvent) handleTabletEvent(event,[event type]); break; - /* Trackpad features, will need OS X 10.6 for implementation + /* Trackpad features, fired only from OS X 10.5.2 case NSEventTypeGesture: - case NSEventTypeMagnify: case NSEventTypeSwipe: - case NSEventTypeRotate: case NSEventTypeBeginGesture: case NSEventTypeEndGesture: break; */ @@ -1316,16 +1335,53 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) case NSScrollWheel: { - GHOST_TInt32 delta; - - double deltaF = [event deltaY]; - if (deltaF == 0.0) break; //discard trackpad delta=0 events - - delta = deltaF > 0.0 ? 1 : -1; - pushEvent(new GHOST_EventWheel([event timestamp]*1000, window, delta)); + /* Send Wheel event if sent from the mouse, trackpad event otherwise */ + if ([event subtype] == NSMouseEventSubtype) { + GHOST_TInt32 delta; + + double deltaF = [event deltaY]; + if (deltaF == 0.0) break; //discard trackpad delta=0 events + + delta = deltaF > 0.0 ? 1 : -1; + pushEvent(new GHOST_EventWheel([event timestamp]*1000, window, delta)); + } + else { + NSPoint mousePos = [event locationInWindow]; + double dx = [event deltaX]; + double dy = -[event deltaY]; + + const double deltaMax = 50.0; + + if ((dx == 0) && (dy == 0)) break; + + /* Quadratic acceleration */ + dx = dx*(fabs(dx)+0.5); + if (dx<0.0) dx-=0.5; else dx+=0.5; + if (dx< -deltaMax) dx= -deltaMax; else if (dx>deltaMax) dx=deltaMax; + + dy = dy*(fabs(dy)+0.5); + if (dy<0.0) dy-=0.5; else dy+=0.5; + if (dy< -deltaMax) dy= -deltaMax; else if (dy>deltaMax) dy=deltaMax; + + pushEvent(new GHOST_EventTrackpad([event timestamp]*1000, window, GHOST_kTrackpadEventScroll, mousePos.x, mousePos.y, dx, dy)); + } } break; + case NSEventTypeMagnify: + { + NSPoint mousePos = [event locationInWindow]; + pushEvent(new GHOST_EventTrackpad([event timestamp]*1000, window, GHOST_kTrackpadEventMagnify, mousePos.x, mousePos.y, + [event magnification]*250.0 + 0.1, 0)); + } + break; + + case NSEventTypeRotate: + { + NSPoint mousePos = [event locationInWindow]; + pushEvent(new GHOST_EventTrackpad([event timestamp]*1000, window, GHOST_kTrackpadEventRotate, mousePos.x, mousePos.y, + -[event rotation] * 5.0, 0)); + } default: return GHOST_kFailure; break; |