diff options
author | Caolán McNamara <caolanm@redhat.com> | 2015-03-23 21:07:10 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2015-03-26 09:14:00 +0000 |
commit | 903a420609252aff12d9481b5fd8cc8d1f1d445f (patch) | |
tree | 1b5266949021523603134c793ae4f1d286980618 /vcl | |
parent | 82f4f6b19febb607d8823923380777f27e0ab3d9 (diff) |
add GtkSwipeGesture support and implement swipe left/right to change slides
keep it simple for now.
deliver to the same target window that gets the MouseWheel events, maybe worth combining
MouseWheel and Gestures into the same thing
and use it in slideshows so swipe toward the left to advance to the next slide,
to the right to return to the previous slide.
swipes are followed by mouse up events, impress already has a similar hack
to hide an mouse-up from the (incredibly complicated) interaction with
the slideshow so simply use that
Change-Id: Ib34f6fa0f15f3aa34eef887eb9d5642de9e5cdd1
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/inc/salwtype.hxx | 10 | ||||
-rw-r--r-- | vcl/inc/unx/gtk/gtkframe.hxx | 3 | ||||
-rw-r--r-- | vcl/source/window/winproc.cxx | 83 | ||||
-rw-r--r-- | vcl/unx/gtk/window/gtksalframe.cxx | 30 |
4 files changed, 112 insertions, 14 deletions
diff --git a/vcl/inc/salwtype.hxx b/vcl/inc/salwtype.hxx index 9b394c42895d..febc4c217c86 100644 --- a/vcl/inc/salwtype.hxx +++ b/vcl/inc/salwtype.hxx @@ -78,6 +78,7 @@ class FontSelectPattern; #define SALEVENT_EXTERNALZOOM ((sal_uInt16)46) #define SALEVENT_EXTERNALSCROLL ((sal_uInt16)47) #define SALEVENT_QUERYCHARPOSITION ((sal_uInt16)48) +#define SALEVENT_SWIPE ((sal_uInt16)49) // MOUSELEAVE must send, when the pointer leave the client area and // the mouse is not captured @@ -278,6 +279,15 @@ struct SalInputContext sal_uLong mnOptions; }; +struct SalSwipeEvent +{ + double mnVelocityX; + double mnVelocityY; + long mnX; + long mnY; +}; + + typedef void (*SALTIMERPROC)( bool idle ); #endif // INCLUDED_VCL_INC_SALWTYPE_HXX diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx index d5148b757dff..53fec5834a84 100644 --- a/vcl/inc/unx/gtk/gtkframe.hxx +++ b/vcl/inc/unx/gtk/gtkframe.hxx @@ -237,6 +237,9 @@ class GtkSalFrame : public SalFrame, public X11WindowProvider static void signalStyleSet( GtkWidget*, GtkStyle* pPrevious, gpointer ); #if GTK_CHECK_VERSION(3,0,0) static gboolean signalDraw( GtkWidget*, cairo_t *cr, gpointer ); +#if GTK_CHECK_VERSION(3,14,0) + static void gestureSwipe(GtkGestureSwipe* gesture, gdouble velocity_x, gdouble velocity_y, gpointer frame); +#endif #else static gboolean signalExpose( GtkWidget*, GdkEventExpose*, gpointer ); #endif diff --git a/vcl/source/window/winproc.cxx b/vcl/source/window/winproc.cxx index e58bfe0f3ab6..bd333580a6e2 100644 --- a/vcl/source/window/winproc.cxx +++ b/vcl/source/window/winproc.cxx @@ -633,6 +633,7 @@ bool ImplHandleMouseEvent( vcl::Window* pWindow, MouseNotifyEvent nSVEvent, bool Point aChildPos = pChild->ImplFrameToOutput( aMousePos ); MouseEvent aMEvt( aChildPos, nClicks, nMode, nCode, nCode ); + // tracking window gets the mouse events if ( pSVData->maWinData.mpTrackWin ) pChild = pSVData->maWinData.mpTrackWin; @@ -1374,13 +1375,12 @@ static bool shouldReusePreviousMouseWindow(const SalWheelMouseEvent& rPrevEvt, c return (rEvt.mnX == rPrevEvt.mnX && rEvt.mnY == rPrevEvt.mnY && rEvt.mnTime-rPrevEvt.mnTime < 500/*ms*/); } -class HandleWheelEvent +class HandleGestureEvent { -private: +protected: ImplSVData* m_pSVData; vcl::Window *m_pWindow; Point m_aMousePos; - CommandWheelData m_aWheelData; public: @@ -1395,10 +1395,27 @@ public: } }; - HandleWheelEvent(vcl::Window *pWindow, const SalWheelMouseEvent& rEvt, bool bScaleDirectly) + HandleGestureEvent(vcl::Window *pWindow, const Point &rMousePos) : m_pSVData(ImplGetSVData()) , m_pWindow(pWindow) - , m_aMousePos(rEvt.mnX, rEvt.mnY) + , m_aMousePos(rMousePos) + { + } + bool Setup(); + WindowDescription FindTarget(); + vcl::Window *Dispatch(const WindowDescription& rTarget); + virtual bool CallCommand(vcl::Window *pWindow, const Point &rMousePos) = 0; + void Teardown(const WindowDescription& rTarget); + virtual ~HandleGestureEvent() {} +}; + +class HandleWheelEvent : public HandleGestureEvent +{ +private: + CommandWheelData m_aWheelData; +public: + HandleWheelEvent(vcl::Window *pWindow, const SalWheelMouseEvent& rEvt, bool bScaleDirectly) + : HandleGestureEvent(pWindow, Point(rEvt.mnX, rEvt.mnY)) { CommandWheelMode nMode; sal_uInt16 nCode = rEvt.mnCode; @@ -1421,18 +1438,14 @@ public: m_aWheelData = CommandWheelData(rEvt.mnDelta, rEvt.mnNotchDelta, rEvt.mnScrollLines, nMode, nCode, bHorz, bPixel); } - bool Setup(); - WindowDescription FindTarget(); - vcl::Window *Dispatch(const WindowDescription& rTarget); - bool CallCommand(vcl::Window *pWindow, const Point &rMousePos) + virtual bool CallCommand(vcl::Window *pWindow, const Point &rMousePos) SAL_OVERRIDE { return ImplCallWheelCommand(pWindow, rMousePos, &m_aWheelData); } bool HandleEvent(const SalWheelMouseEvent& rEvt); - void Teardown(const WindowDescription& rTarget); }; -bool HandleWheelEvent::Setup() +bool HandleGestureEvent::Setup() { ImplDelData aDogTag( m_pWindow ); @@ -1445,7 +1458,7 @@ bool HandleWheelEvent::Setup() return true; } -HandleWheelEvent::WindowDescription HandleWheelEvent::FindTarget() +HandleGestureEvent::WindowDescription HandleGestureEvent::FindTarget() { // first check any floating window ( eg. drop down listboxes) bool bIsFloat = false; @@ -1482,7 +1495,7 @@ HandleWheelEvent::WindowDescription HandleWheelEvent::FindTarget() return WindowDescription(pMouseWindow, bIsFloat); } -vcl::Window *HandleWheelEvent::Dispatch(const WindowDescription& rTarget) +vcl::Window *HandleGestureEvent::Dispatch(const WindowDescription& rTarget) { vcl::Window *pMouseWindow = rTarget.m_pMouseWindow; @@ -1524,7 +1537,7 @@ vcl::Window *HandleWheelEvent::Dispatch(const WindowDescription& rTarget) return pDispatchedTo; } -void HandleWheelEvent::Teardown(const WindowDescription& rTarget) +void HandleGestureEvent::Teardown(const WindowDescription& rTarget) { // close floaters if (!rTarget.m_bIsFloat && m_pSVData->maWinData.mpFirstFloat) @@ -1574,6 +1587,43 @@ static bool ImplHandleWheelEvent( vcl::Window* pWindow, const SalWheelMouseEvent return aHandler.HandleEvent(rEvt); } +class HandleSwipeEvent : public HandleGestureEvent +{ +private: + CommandSwipeData m_aSwipeData; +public: + HandleSwipeEvent(vcl::Window *pWindow, const SalSwipeEvent& rEvt) + : HandleGestureEvent(pWindow, Point(rEvt.mnX, rEvt.mnY)) + { + m_aSwipeData = CommandSwipeData(rEvt.mnVelocityX, rEvt.mnVelocityY); + } + virtual bool CallCommand(vcl::Window *pWindow, const Point &/*rMousePos*/) SAL_OVERRIDE + { + return ImplCallCommand(pWindow, COMMAND_SWIPE, &m_aSwipeData); + } + bool HandleEvent(); +}; + +bool HandleSwipeEvent::HandleEvent() +{ + if (!Setup()) + return false; + + WindowDescription aTarget = FindTarget(); + + bool bHandled = Dispatch(aTarget) != NULL; + + Teardown(aTarget); + + return bHandled; +} + +static bool ImplHandleSwipe(vcl::Window *pWindow, const SalSwipeEvent& rEvt) +{ + HandleSwipeEvent aHandler(pWindow, rEvt); + return aHandler.HandleEvent(); +} + #define IMPL_PAINT_CHECKRTL ((sal_uInt16)0x0020) static void ImplHandlePaint( vcl::Window* pWindow, const Rectangle& rBoundRect, bool bImmediateUpdate ) @@ -2618,6 +2668,11 @@ bool ImplWindowFrameProc( vcl::Window* pWindow, SalFrame* /*pFrame*/, case SALEVENT_QUERYCHARPOSITION: ImplHandleSalQueryCharPosition( pWindow, (SalQueryCharPositionEvent*)pEvent ); break; + + case SALEVENT_SWIPE: + nRet = ImplHandleSwipe(pWindow, *(const SalSwipeEvent*)pEvent); + break; + #ifdef DBG_UTIL default: SAL_WARN( "vcl.layout", "ImplWindowFrameProc(): unknown event (" << nEvent << ")" ); diff --git a/vcl/unx/gtk/window/gtksalframe.cxx b/vcl/unx/gtk/window/gtksalframe.cxx index b678d819283d..0c5ff07c0500 100644 --- a/vcl/unx/gtk/window/gtksalframe.cxx +++ b/vcl/unx/gtk/window/gtksalframe.cxx @@ -989,6 +989,13 @@ void GtkSalFrame::InitCommon() g_signal_connect( G_OBJECT(m_pWindow), "button-release-event", G_CALLBACK(signalButton), this ); #if GTK_CHECK_VERSION(3,0,0) g_signal_connect( G_OBJECT(m_pWindow), "draw", G_CALLBACK(signalDraw), this ); +#if GTK_CHECK_VERSION(3,14,0) + GtkGesture *pSwipe = gtk_gesture_swipe_new(m_pWindow); + g_signal_connect(pSwipe, "swipe", G_CALLBACK(gestureSwipe), this); + gtk_event_controller_set_propagation_phase(GTK_EVENT_CONTROLLER (pSwipe), GTK_PHASE_TARGET); + g_object_weak_ref(G_OBJECT(m_pWindow), (GWeakNotify)g_object_unref, pSwipe); +#endif + #else g_signal_connect( G_OBJECT(m_pWindow), "expose-event", G_CALLBACK(signalExpose), this ); #endif @@ -3170,6 +3177,7 @@ bool GtkSalFrame::Dispatch( const XEvent* pEvent ) gboolean GtkSalFrame::signalButton( GtkWidget*, GdkEventButton* pEvent, gpointer frame ) { GtkSalFrame* pThis = (GtkSalFrame*)frame; + SalMouseEvent aEvent; sal_uInt16 nEventType = 0; switch( pEvent->type ) @@ -3297,6 +3305,28 @@ gboolean GtkSalFrame::signalScroll( GtkWidget*, GdkEvent* pEvent, gpointer frame return true; } +#if GTK_CHECK_VERSION(3,14,0) +void GtkSalFrame::gestureSwipe(GtkGestureSwipe* gesture, gdouble velocity_x, gdouble velocity_y, gpointer frame) +{ + GtkSalFrame* pThis = (GtkSalFrame*)frame; + + SalSwipeEvent aEvent; + aEvent.mnVelocityX = velocity_x; + aEvent.mnVelocityY = velocity_y; + + gdouble x, y; + GdkEventSequence *sequence = gtk_gesture_single_get_current_sequence(GTK_GESTURE_SINGLE(gesture)); + //I feel I want the first point of the sequence, not the last point which + //the docs say this gives, but for the moment assume we start and end + //within the same vcl window + gtk_gesture_get_point(GTK_GESTURE(gesture), sequence, &x, &y); + aEvent.mnX = x; + aEvent.mnY = y; + + pThis->CallCallback(SALEVENT_SWIPE, &aEvent); +} +#endif + gboolean GtkSalFrame::signalMotion( GtkWidget*, GdkEventMotion* pEvent, gpointer frame ) { GtkSalFrame* pThis = (GtkSalFrame*)frame; |