diff --git a/include/wx/gtk/window.h b/include/wx/gtk/window.h index d9db061dc6..0e6d2633c3 100644 --- a/include/wx/gtk/window.h +++ b/include/wx/gtk/window.h @@ -77,6 +77,9 @@ public: virtual bool Reparent( wxWindowBase *newParent ) wxOVERRIDE; virtual void WarpPointer(int x, int y) wxOVERRIDE; +#ifdef __WXGTK3__ + virtual bool EnableTouchEvents(int eventsMask) wxOVERRIDE; +#endif // __WXGTK3__ virtual void Refresh( bool eraseBackground = true, const wxRect *rect = (const wxRect *) NULL ) wxOVERRIDE; diff --git a/include/wx/msw/window.h b/include/wx/msw/window.h index 7f710a5870..1a6af48f5b 100644 --- a/include/wx/msw/window.h +++ b/include/wx/msw/window.h @@ -100,6 +100,7 @@ public: virtual bool Reparent(wxWindowBase *newParent) wxOVERRIDE; virtual void WarpPointer(int x, int y) wxOVERRIDE; + virtual bool EnableTouchEvents(int eventsMask) wxOVERRIDE; virtual void Refresh( bool eraseBackground = true, const wxRect *rect = (const wxRect *) NULL ) wxOVERRIDE; diff --git a/include/wx/osx/cocoa/private.h b/include/wx/osx/cocoa/private.h index 9fd9101a84..dd20e0074e 100644 --- a/include/wx/osx/cocoa/private.h +++ b/include/wx/osx/cocoa/private.h @@ -128,6 +128,7 @@ public : void SetToolTip( wxToolTip* tooltip ); void InstallEventHandler( WXWidget control = NULL ); + bool EnableTouchEvents(int eventsMask); virtual bool ShouldHandleKeyNavigation(const wxKeyEvent &event) const; bool DoHandleKeyNavigation(const wxKeyEvent &event); diff --git a/include/wx/osx/core/private.h b/include/wx/osx/core/private.h index a372aa529a..5b012f9048 100644 --- a/include/wx/osx/core/private.h +++ b/include/wx/osx/core/private.h @@ -326,6 +326,8 @@ public : virtual void InstallEventHandler( WXWidget control = NULL ) = 0; + virtual bool EnableTouchEvents(int eventsMask) = 0; + // Mechanism used to keep track of whether a change should send an event // Do SendEvents(false) when starting actions that would trigger programmatic events // and SendEvents(true) at the end of the block. diff --git a/include/wx/osx/iphone/private.h b/include/wx/osx/iphone/private.h index b88a863a54..484e7525ee 100644 --- a/include/wx/osx/iphone/private.h +++ b/include/wx/osx/iphone/private.h @@ -105,6 +105,7 @@ public : void SetFont( const wxFont & font , const wxColour& foreground , long windowStyle, bool ignoreBlack = true ); void InstallEventHandler( WXWidget control = NULL ); + bool EnableTouchEvents(int WXUNUSED(eventsMask)) { return false; } virtual void DoNotifyFocusEvent(bool receivedFocus, wxWidgetImpl* otherWindow); diff --git a/include/wx/osx/window.h b/include/wx/osx/window.h index 7db20f4810..caee9c1659 100644 --- a/include/wx/osx/window.h +++ b/include/wx/osx/window.h @@ -77,6 +77,7 @@ public: virtual void SetFocus() wxOVERRIDE; virtual void WarpPointer( int x, int y ) wxOVERRIDE; + virtual bool EnableTouchEvents(int eventsMask) wxOVERRIDE; virtual void Refresh( bool eraseBackground = true, const wxRect *rect = NULL ) wxOVERRIDE; diff --git a/include/wx/window.h b/include/wx/window.h index 440f097a21..27a9c856cb 100644 --- a/include/wx/window.h +++ b/include/wx/window.h @@ -133,6 +133,13 @@ enum wxShowEffect wxSHOW_EFFECT_MAX }; +// Values for EnableTouchEvents() mask. +enum +{ + wxTOUCH_NONE = 0x0000, + wxTOUCH_ALL_GESTURES = 0x00ff +}; + // flags for SendSizeEvent() enum { @@ -1033,6 +1040,13 @@ public: virtual bool HasCapture() const { return (wxWindow *)this == GetCapture(); } + // enable the specified touch events for this window, return false if + // the requested events are not supported + virtual bool EnableTouchEvents(int WXUNUSED(eventsMask)) + { + return false; + } + // painting the window // ------------------- diff --git a/interface/wx/event.h b/interface/wx/event.h index 13460cf42e..ae1eaeee9a 100644 --- a/interface/wx/event.h +++ b/interface/wx/event.h @@ -3649,6 +3649,10 @@ public: /** @class wxGestureEvent This is the base class for all supported gesture events. + @note Gesture events are not generated by default, you must call + wxWindow::EnableTouchEvents() with the appropriate parameter to + request their generation. + @library{wxcore} @category{events} diff --git a/interface/wx/window.h b/interface/wx/window.h index 0fa2a58c50..b0712fb378 100644 --- a/interface/wx/window.h +++ b/interface/wx/window.h @@ -3424,6 +3424,19 @@ public: */ virtual void WarpPointer(int x, int y); + /** + Request generation of touch events for this window. + + @param eventsMask Either wxTOUCH_NONE or wxTOUCH_ALL_GESTURES to + disable or enable gesture events for this window. + + @return @true if the specified events were enabled or @false if the + current platform doesn't support touch events. + + @since 3.1.1 + */ + virtual bool EnableTouchEvents(int eventsMask); + //@} diff --git a/samples/event/gestures.cpp b/samples/event/gestures.cpp index ae32890feb..06b6cd794a 100644 --- a/samples/event/gestures.cpp +++ b/samples/event/gestures.cpp @@ -43,6 +43,13 @@ MyGesturePanel::MyGesturePanel(MyGestureFrame *parent) : wxPanel(parent, wxID_AN Bind(wxEVT_PAINT, &MyGesturePanel::OnPaint, this); } + if ( !EnableTouchEvents(wxTOUCH_ALL_GESTURES) ) + { + wxLogError("Failed to enable touch events"); + + // Still bind event handlers just in case they still work? + } + // Event handlers Bind(wxEVT_GESTURE_PAN, &MyGesturePanel::OnPan, this); Bind(wxEVT_GESTURE_ZOOM, &MyGesturePanel::OnZoom, this); diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index 36c049b5d2..26bc0734b7 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -3435,6 +3435,26 @@ wxWindowGesturesData::~wxWindowGesturesData() #endif // wxGTK_HAS_GESTURES_SUPPORT +// This method must be always defined for GTK+ 3 as it's declared in the +// header, where we can't (easily) test for wxGTK_HAS_GESTURES_SUPPORT. +#ifdef __WXGTK3__ + +bool wxWindowGTK::EnableTouchEvents(int eventsMask) +{ +#ifdef wxGTK_HAS_GESTURES_SUPPORT + // Check if gestures support is also available during run-time. + if ( gtk_check_version(3, 14, 0) == NULL ) + { + m_gesturesData = new wxWindowGesturesData(this, GetConnectWidget()); + return true; + } +#endif // wxGTK_HAS_GESTURES_SUPPORT + + return wxWindowBase::EnableTouchEvents(eventsMask); +} + +#endif // __WXGTK3__ + void wxWindowGTK::ConnectWidget( GtkWidget *widget ) { static bool isSourceAttached; @@ -3477,12 +3497,6 @@ void wxWindowGTK::ConnectWidget( GtkWidget *widget ) G_CALLBACK (gtk_window_enter_callback), this); g_signal_connect (widget, "leave_notify_event", G_CALLBACK (gtk_window_leave_callback), this); - -#ifdef wxGTK_HAS_GESTURES_SUPPORT - // Check if gestures support is also available during run-time. - if ( gtk_check_version(3, 14, 0) == NULL ) - m_gesturesData = new wxWindowGesturesData(this, widget); -#endif // wxGTK_HAS_GESTURES_SUPPORT } void wxWindowGTK::DoMoveWindow(int x, int y, int width, int height) diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 9fb00bffeb..0de02b2508 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -906,6 +906,35 @@ void wxWindowMSW::WarpPointer(int x, int y) } } +bool wxWindowMSW::EnableTouchEvents(int eventsMask) +{ +#ifdef WM_GESTURE + if ( GestureFuncs::IsOk() && eventsMask == wxTOUCH_ALL_GESTURES ) + { + // Configure to receive all gestures + GESTURECONFIG gestureConfig = {0, GC_ALLGESTURES, 0}; + + if ( !GestureFuncs::SetGestureConfig() + ( + m_hWnd, + 0, // Reserved, must be always 0. + 1, // Number of gesture configurations. + &gestureConfig, // Pointer to the first one. + sizeof(GESTURECONFIG) // Size of each configuration. + ) + ) + { + wxLogLastError("SetGestureConfig"); + return false; + } + + return true; + } +#endif // WM_GESTURE + + return wxWindowBase::EnableTouchEvents(eventsMask); +} + void wxWindowMSW::MSWUpdateUIState(int action, int state) { // we send WM_CHANGEUISTATE so if nothing needs changing then the system @@ -3814,26 +3843,6 @@ bool wxWindowMSW::MSWCreate(const wxChar *wclass, return false; } -#ifdef WM_GESTURE - if ( GestureFuncs::IsOk() ) - { - // Configure to receive all gestures - GESTURECONFIG gestureConfig = {0, GC_ALLGESTURES, 0}; - - if ( !GestureFuncs::SetGestureConfig() - ( - m_hWnd, - 0, // Reserved, must be always 0. - 1, // Number of gesture configurations. - &gestureConfig, // Pointer to the first one. - sizeof(GESTURECONFIG) // Size of each configuration. - ) - ) - { - wxLogLastError("SetGestureConfig"); - } - } -#endif // WM_GESTURE SubclassWin(m_hWnd); diff --git a/src/osx/cocoa/window.mm b/src/osx/cocoa/window.mm index 8901482c27..15abbc43b3 100644 --- a/src/osx/cocoa/window.mm +++ b/src/osx/cocoa/window.mm @@ -2240,16 +2240,6 @@ void wxOSXCocoaClassAddWXMethods(Class c) wxOSX_CLASS_ADD_METHOD(c, @selector(mouseEntered:), (IMP) wxOSX_mouseEvent, "v@:@" ) wxOSX_CLASS_ADD_METHOD(c, @selector(mouseExited:), (IMP) wxOSX_mouseEvent, "v@:@" ) -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_10 - wxOSX_CLASS_ADD_METHOD(c, @selector(handlePanGesture:), (IMP) wxOSX_panGestureEvent, "v@:@" ) - wxOSX_CLASS_ADD_METHOD(c, @selector(handleZoomGesture:), (IMP) wxOSX_zoomGestureEvent, "v@:@" ) - wxOSX_CLASS_ADD_METHOD(c, @selector(handleRotateGesture:), (IMP) wxOSX_rotateGestureEvent, "v@:@" ) - wxOSX_CLASS_ADD_METHOD(c, @selector(handleLongPressGesture:), (IMP) wxOSX_longPressEvent, "v@:@" ) - wxOSX_CLASS_ADD_METHOD(c, @selector(touchesBeganWithEvent:), (IMP) wxOSX_touchesBegan, "v@:@" ) - wxOSX_CLASS_ADD_METHOD(c, @selector(touchesMovedWithEvent:), (IMP) wxOSX_touchesMoved, "v@:@" ) - wxOSX_CLASS_ADD_METHOD(c, @selector(touchesEndedWithEvent:), (IMP) wxOSX_touchesEnded, "v@:@" ) -#endif // MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_10 - wxOSX_CLASS_ADD_METHOD(c, @selector(magnifyWithEvent:), (IMP)wxOSX_mouseEvent, "v@:@") wxOSX_CLASS_ADD_METHOD(c, @selector(cursorUpdate:), (IMP) wxOSX_cursorUpdate, "v@:@" ) @@ -2333,6 +2323,11 @@ void wxWidgetCocoaImpl::Init() m_hasEditor = false; #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_10 + m_panGestureRecognizer = nil; + m_magnificationGestureRecognizer = nil; + m_rotationGestureRecognizer = nil; + m_pressGestureRecognizer = nil; + m_touchCount = 0; m_lastTouchTime = 0; m_allowedGestures = 0; @@ -3289,23 +3284,43 @@ void wxWidgetCocoaImpl::InstallEventHandler( WXWidget control ) NSTrackingArea* area = [[NSTrackingArea alloc] initWithRect: NSZeroRect options: options owner: m_osxView userInfo: nil]; [m_osxView addTrackingArea: area]; [area release]; +} +bool wxWidgetCocoaImpl::EnableTouchEvents(int eventsMask) +{ #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_10 if ( wxPlatformInfo::Get().CheckOSVersion(10, 10) ) { if ( IsUserPane() ) { + Class cls = [m_osxView class]; + m_panGestureRecognizer = [[NSPanGestureRecognizer alloc] initWithTarget:m_osxView action: @selector(handlePanGesture:)]; + if ( !class_respondsToSelector(cls, @selector(handlePanGesture:)) ) + class_addMethod(cls, @selector(handlePanGesture:), (IMP) wxOSX_panGestureEvent, "v@:@" ); m_magnificationGestureRecognizer = [[NSMagnificationGestureRecognizer alloc] initWithTarget:m_osxView action: @selector(handleZoomGesture:)]; + if ( !class_respondsToSelector(cls, @selector(handleZoomGesture:)) ) + class_addMethod(cls, @selector(handleZoomGesture:), (IMP) wxOSX_zoomGestureEvent, "v@:@" ); m_rotationGestureRecognizer = [[NSRotationGestureRecognizer alloc] initWithTarget:m_osxView action: @selector(handleRotateGesture:)]; + if ( !class_respondsToSelector(cls, @selector(handleRotateGesture:)) ) + class_addMethod(cls, @selector(handleRotateGesture:), (IMP) wxOSX_rotateGestureEvent, "v@:@" ); m_pressGestureRecognizer = [[NSPressGestureRecognizer alloc] initWithTarget:m_osxView action: @selector(handleLongPressGesture:)]; + if ( !class_respondsToSelector(cls, @selector(handleLongPressGesture:)) ) + class_addMethod(cls, @selector(handleLongPressGesture:), (IMP) wxOSX_longPressEvent, "v@:@" ); + + if ( !class_respondsToSelector(cls, @selector(touchesBeganWithEvent:)) ) + class_addMethod(cls, @selector(touchesBeganWithEvent:), (IMP) wxOSX_touchesBegan, "v@:@" ); + if ( !class_respondsToSelector(cls, @selector(touchesMovedWithEvent:)) ) + class_addMethod(cls, @selector(touchesMovedWithEvent:), (IMP) wxOSX_touchesMoved, "v@:@" ); + if ( !class_respondsToSelector(cls, @selector(touchesEndedWithEvent:)) ) + class_addMethod(cls, @selector(touchesEndedWithEvent:), (IMP) wxOSX_touchesEnded, "v@:@" ); [m_osxView addGestureRecognizer:m_panGestureRecognizer]; [m_osxView addGestureRecognizer:m_magnificationGestureRecognizer]; @@ -3313,9 +3328,14 @@ void wxWidgetCocoaImpl::InstallEventHandler( WXWidget control ) [m_osxView addGestureRecognizer:m_pressGestureRecognizer]; [m_osxView setAcceptsTouchEvents:YES]; + + return true; } } #endif // MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_10 + + wxUnusedVar(eventsMask); + return false; } bool wxWidgetCocoaImpl::DoHandleCharEvent(NSEvent *event, NSString *text) diff --git a/src/osx/window_osx.cpp b/src/osx/window_osx.cpp index 823c0beae8..c725ef8d57 100644 --- a/src/osx/window_osx.cpp +++ b/src/osx/window_osx.cpp @@ -1429,6 +1429,11 @@ void wxWindowMac::WarpPointer(int x_pos, int y_pos) #endif } +bool wxWindowMac::EnableTouchEvents(int eventsMask) +{ + return GetPeer() ? GetPeer()->EnableTouchEvents(eventsMask) : false; +} + int wxWindowMac::GetScrollPos(int orient) const { #if wxUSE_SCROLLBAR