diff options
author | Caolán McNamara <caolanm@redhat.com> | 2015-03-26 10:20:34 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2015-03-26 14:48:13 +0000 |
commit | 873141fb5be5fa49b56ea413bc912af33f758a0b (patch) | |
tree | e996d17f50a08c82bb469448886d0198a065d2b4 | |
parent | 1c78277801f377458e8cb1d04fae0578a60c69b7 (diff) |
add GtkLongPressGesture support and implement long-press in slideshow
so a long press shows the context menu to e.g. allow switching on/off
draw-on-slide mode
Change-Id: Icd6ea52d2172217794f4fc802246ccf13020e134
-rw-r--r-- | include/vcl/cmdevt.hxx | 30 | ||||
-rw-r--r-- | sd/source/ui/inc/slideshow.hxx | 2 | ||||
-rw-r--r-- | sd/source/ui/slideshow/slideshow.cxx | 5 | ||||
-rw-r--r-- | sd/source/ui/slideshow/slideshowimpl.cxx | 13 | ||||
-rw-r--r-- | sd/source/ui/slideshow/slideshowimpl.hxx | 1 | ||||
-rw-r--r-- | sd/source/ui/view/viewshel.cxx | 11 | ||||
-rw-r--r-- | vcl/inc/salwtype.hxx | 6 | ||||
-rw-r--r-- | vcl/inc/unx/gtk/gtkframe.hxx | 1 | ||||
-rw-r--r-- | vcl/source/window/winproc.cxx | 150 | ||||
-rw-r--r-- | vcl/unx/gtk/window/gtksalframe.cxx | 22 |
10 files changed, 183 insertions, 58 deletions
diff --git a/include/vcl/cmdevt.hxx b/include/vcl/cmdevt.hxx index 8e62e256fa73..851c5d9aec1e 100644 --- a/include/vcl/cmdevt.hxx +++ b/include/vcl/cmdevt.hxx @@ -355,6 +355,26 @@ public: double getVelocityY() const { return mnVelocityY; } }; +class VCL_DLLPUBLIC CommandLongPressData +{ + double mnX; + double mnY; +public: + CommandLongPressData() + : mnX(0) + , mnY(0) + { + } + CommandLongPressData(double nX, double nY) + : mnX(nX) + , mnY(nY) + { + } + double getX() const { return mnX; } + double getY() const { return mnY; } +}; + + // - CommandEvent - #define COMMAND_CONTEXTMENU ((sal_uInt16)1) #define COMMAND_STARTDRAG ((sal_uInt16)2) @@ -376,6 +396,7 @@ public: #define COMMAND_PREPARERECONVERSION ((sal_uInt16)19) #define COMMAND_QUERYCHARPOSITION ((sal_uInt16)20) #define COMMAND_SWIPE ((sal_uInt16)21) +#define COMMAND_LONGPRESS ((sal_uInt16)22) class VCL_DLLPUBLIC CommandEvent { @@ -404,6 +425,7 @@ public: CommandMediaData* GetMediaData() const; const CommandSelectionChangeData* GetSelectionChangeData() const; const CommandSwipeData* GetSwipeData() const; + const CommandLongPressData* GetLongPressData() const; }; inline CommandEvent::CommandEvent() @@ -494,6 +516,14 @@ inline const CommandSwipeData* CommandEvent::GetSwipeData() const return NULL; } +inline const CommandLongPressData* CommandEvent::GetLongPressData() const +{ + if( mnCommand == COMMAND_LONGPRESS ) + return (const CommandLongPressData*)(mpData); + else + return NULL; +} + #endif // INCLUDED_VCL_CMDEVT_HXX /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/inc/slideshow.hxx b/sd/source/ui/inc/slideshow.hxx index d6ef3ae77717..2f19ca0e3ff1 100644 --- a/sd/source/ui/inc/slideshow.hxx +++ b/sd/source/ui/inc/slideshow.hxx @@ -53,6 +53,7 @@ namespace vcl { class Window; } class SfxRequest; class WorkWindow; class CommandSwipeData; +class CommandLongPressData; struct ImplSVEvent; // TODO: Remove @@ -156,6 +157,7 @@ public: !!!! This should only be called by the SdShowWindow !!!!*/ bool pause( bool bPause ); bool swipe(const CommandSwipeData &rSwipeData); + bool longpress(const CommandLongPressData& rLongPressData); // settings bool isFullScreen(); // a.k.a. FuSlideShow::IsFullScreen() diff --git a/sd/source/ui/slideshow/slideshow.cxx b/sd/source/ui/slideshow/slideshow.cxx index cfcf5e36fc35..b21680eb9714 100644 --- a/sd/source/ui/slideshow/slideshow.cxx +++ b/sd/source/ui/slideshow/slideshow.cxx @@ -1064,6 +1064,11 @@ bool SlideShow::swipe(const CommandSwipeData& rSwipeData) return mxController.is() && mxController->swipe(rSwipeData); } +bool SlideShow::longpress(const CommandLongPressData& rLongPressData) +{ + return mxController.is() && mxController->longpress(rLongPressData); +} + void SlideShow::StartInPlacePresentationConfigurationCallback() { if( mnInPlaceConfigEvent != 0 ) diff --git a/sd/source/ui/slideshow/slideshowimpl.cxx b/sd/source/ui/slideshow/slideshowimpl.cxx index 4e9959bf978e..38eee1f0f680 100644 --- a/sd/source/ui/slideshow/slideshowimpl.cxx +++ b/sd/source/ui/slideshow/slideshowimpl.cxx @@ -1235,7 +1235,7 @@ void SlideshowImpl::slideEnded(const bool bReverse) bool SlideshowImpl::swipe(const CommandSwipeData &rSwipeData) { - if (mbUsePen) + if (mbUsePen || mnContextMenuEvent) return false; double nVelocityX = rSwipeData.getVelocityX(); @@ -1253,6 +1253,17 @@ bool SlideshowImpl::swipe(const CommandSwipeData &rSwipeData) return true; } +bool SlideshowImpl::longpress(const CommandLongPressData &rLongPressData) +{ + if (mnContextMenuEvent) + return false; + + maPopupMousePos = Point(rLongPressData.getX(), rLongPressData.getY()); + mnContextMenuEvent = Application::PostUserEvent( LINK( this, SlideshowImpl, ContextMenuHdl ) ); + + return true; +} + void SlideshowImpl::removeShapeEvents() { if( mxShow.is() && mxListenerProxy.is() ) try diff --git a/sd/source/ui/slideshow/slideshowimpl.hxx b/sd/source/ui/slideshow/slideshowimpl.hxx index 97fe5e3342f3..b39c4ede6c9a 100644 --- a/sd/source/ui/slideshow/slideshowimpl.hxx +++ b/sd/source/ui/slideshow/slideshowimpl.hxx @@ -219,6 +219,7 @@ public: void hyperLinkClicked(const OUString & hyperLink) throw (css::uno::RuntimeException); void click(const css::uno::Reference< css::drawing::XShape > & xShape, const css::awt::MouseEvent & aOriginalEvent); bool swipe(const CommandSwipeData &rSwipeData); + bool longpress(const CommandLongPressData& rLongPressData); /// ends the presentation async void endPresentation(); diff --git a/sd/source/ui/view/viewshel.cxx b/sd/source/ui/view/viewshel.cxx index 22fc056d9345..91efc8ff0c8f 100644 --- a/sd/source/ui/view/viewshel.cxx +++ b/sd/source/ui/view/viewshel.cxx @@ -651,6 +651,17 @@ bool ViewShell::HandleScrollCommand(const CommandEvent& rCEvt, ::sd::Window* pWi } } break; + case COMMAND_LONGPRESS: + { + rtl::Reference< SlideShow > xSlideShow( SlideShow::GetSlideShow( GetViewShellBase() ) ); + if (xSlideShow.is()) + { + const CommandLongPressData* pLongPressData = rCEvt.GetLongPressData(); + bDone = xSlideShow->longpress(*pLongPressData); + } + } + break; + case COMMAND_WHEEL: { Reference< XSlideShowController > xSlideShowController( SlideShow::GetSlideShowController(GetViewShellBase() ) ); diff --git a/vcl/inc/salwtype.hxx b/vcl/inc/salwtype.hxx index febc4c217c86..67ad505b2fd7 100644 --- a/vcl/inc/salwtype.hxx +++ b/vcl/inc/salwtype.hxx @@ -79,6 +79,7 @@ class FontSelectPattern; #define SALEVENT_EXTERNALSCROLL ((sal_uInt16)47) #define SALEVENT_QUERYCHARPOSITION ((sal_uInt16)48) #define SALEVENT_SWIPE ((sal_uInt16)49) +#define SALEVENT_LONGPRESS ((sal_uInt16)50) // MOUSELEAVE must send, when the pointer leave the client area and // the mouse is not captured @@ -287,6 +288,11 @@ struct SalSwipeEvent long mnY; }; +struct SalLongPressEvent +{ + long mnX; + long mnY; +}; typedef void (*SALTIMERPROC)( bool idle ); diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx index 53fec5834a84..d51441100f04 100644 --- a/vcl/inc/unx/gtk/gtkframe.hxx +++ b/vcl/inc/unx/gtk/gtkframe.hxx @@ -239,6 +239,7 @@ class GtkSalFrame : public SalFrame, public X11WindowProvider 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); + static void gestureLongPress(GtkGestureLongPress* gesture, gpointer frame); #endif #else static gboolean signalExpose( GtkWidget*, GdkEventExpose*, gpointer ); diff --git a/vcl/source/window/winproc.cxx b/vcl/source/window/winproc.cxx index bd333580a6e2..5f1ebc3e5a6f 100644 --- a/vcl/source/window/winproc.cxx +++ b/vcl/source/window/winproc.cxx @@ -1375,7 +1375,7 @@ static bool shouldReusePreviousMouseWindow(const SalWheelMouseEvent& rPrevEvt, c return (rEvt.mnX == rPrevEvt.mnX && rEvt.mnY == rPrevEvt.mnY && rEvt.mnTime-rPrevEvt.mnTime < 500/*ms*/); } -class HandleGestureEvent +class HandleGestureEventBase { protected: ImplSVData* m_pSVData; @@ -1395,7 +1395,7 @@ public: } }; - HandleGestureEvent(vcl::Window *pWindow, const Point &rMousePos) + HandleGestureEventBase(vcl::Window *pWindow, const Point &rMousePos) : m_pSVData(ImplGetSVData()) , m_pWindow(pWindow) , m_aMousePos(rMousePos) @@ -1406,46 +1406,10 @@ public: vcl::Window *Dispatch(const WindowDescription& rTarget); virtual bool CallCommand(vcl::Window *pWindow, const Point &rMousePos) = 0; void Teardown(const WindowDescription& rTarget); - virtual ~HandleGestureEvent() {} + virtual ~HandleGestureEventBase() {} }; -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; - bool bHorz = rEvt.mbHorz; - bool bPixel = rEvt.mbDeltaIsPixel; - if (bScaleDirectly) - nMode = CommandWheelMode::ZOOM_SCALE; - else if ( nCode & KEY_MOD1 ) - nMode = CommandWheelMode::ZOOM; - else if ( nCode & KEY_MOD2 ) - nMode = CommandWheelMode::DATAZOOM; - else - { - nMode = CommandWheelMode::SCROLL; - // #i85450# interpret shift-wheel as horizontal wheel action - if( (nCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD3)) == KEY_SHIFT ) - bHorz = true; - } - - m_aWheelData = CommandWheelData(rEvt.mnDelta, rEvt.mnNotchDelta, rEvt.mnScrollLines, nMode, nCode, bHorz, bPixel); - - } - virtual bool CallCommand(vcl::Window *pWindow, const Point &rMousePos) SAL_OVERRIDE - { - return ImplCallWheelCommand(pWindow, rMousePos, &m_aWheelData); - } - bool HandleEvent(const SalWheelMouseEvent& rEvt); -}; - -bool HandleGestureEvent::Setup() +bool HandleGestureEventBase::Setup() { ImplDelData aDogTag( m_pWindow ); @@ -1458,7 +1422,7 @@ bool HandleGestureEvent::Setup() return true; } -HandleGestureEvent::WindowDescription HandleGestureEvent::FindTarget() +HandleGestureEventBase::WindowDescription HandleGestureEventBase::FindTarget() { // first check any floating window ( eg. drop down listboxes) bool bIsFloat = false; @@ -1495,7 +1459,7 @@ HandleGestureEvent::WindowDescription HandleGestureEvent::FindTarget() return WindowDescription(pMouseWindow, bIsFloat); } -vcl::Window *HandleGestureEvent::Dispatch(const WindowDescription& rTarget) +vcl::Window *HandleGestureEventBase::Dispatch(const WindowDescription& rTarget) { vcl::Window *pMouseWindow = rTarget.m_pMouseWindow; @@ -1537,7 +1501,7 @@ vcl::Window *HandleGestureEvent::Dispatch(const WindowDescription& rTarget) return pDispatchedTo; } -void HandleGestureEvent::Teardown(const WindowDescription& rTarget) +void HandleGestureEventBase::Teardown(const WindowDescription& rTarget) { // close floaters if (!rTarget.m_bIsFloat && m_pSVData->maWinData.mpFirstFloat) @@ -1554,6 +1518,42 @@ void HandleGestureEvent::Teardown(const WindowDescription& rTarget) } } +class HandleWheelEvent : public HandleGestureEventBase +{ +private: + CommandWheelData m_aWheelData; +public: + HandleWheelEvent(vcl::Window *pWindow, const SalWheelMouseEvent& rEvt, bool bScaleDirectly) + : HandleGestureEventBase(pWindow, Point(rEvt.mnX, rEvt.mnY)) + { + CommandWheelMode nMode; + sal_uInt16 nCode = rEvt.mnCode; + bool bHorz = rEvt.mbHorz; + bool bPixel = rEvt.mbDeltaIsPixel; + if (bScaleDirectly) + nMode = CommandWheelMode::ZOOM_SCALE; + else if ( nCode & KEY_MOD1 ) + nMode = CommandWheelMode::ZOOM; + else if ( nCode & KEY_MOD2 ) + nMode = CommandWheelMode::DATAZOOM; + else + { + nMode = CommandWheelMode::SCROLL; + // #i85450# interpret shift-wheel as horizontal wheel action + if( (nCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD3)) == KEY_SHIFT ) + bHorz = true; + } + + m_aWheelData = CommandWheelData(rEvt.mnDelta, rEvt.mnNotchDelta, rEvt.mnScrollLines, nMode, nCode, bHorz, bPixel); + + } + virtual bool CallCommand(vcl::Window *pWindow, const Point &rMousePos) SAL_OVERRIDE + { + return ImplCallWheelCommand(pWindow, rMousePos, &m_aWheelData); + } + bool HandleEvent(const SalWheelMouseEvent& rEvt); +}; + bool HandleWheelEvent::HandleEvent(const SalWheelMouseEvent& rEvt) { static SalWheelMouseEvent aPreviousEvent; @@ -1581,6 +1581,30 @@ bool HandleWheelEvent::HandleEvent(const SalWheelMouseEvent& rEvt) return pPreviousWindow != NULL; } +class HandleGestureEvent : public HandleGestureEventBase +{ +public: + HandleGestureEvent(vcl::Window *pWindow, const Point &rMousePos) + : HandleGestureEventBase(pWindow, rMousePos) + { + } + bool HandleEvent(); +}; + +bool HandleGestureEvent::HandleEvent() +{ + if (!Setup()) + return false; + + WindowDescription aTarget = FindTarget(); + + bool bHandled = Dispatch(aTarget) != NULL; + + Teardown(aTarget); + + return bHandled; +} + static bool ImplHandleWheelEvent( vcl::Window* pWindow, const SalWheelMouseEvent& rEvt, bool scaleDirectly = false ) { HandleWheelEvent aHandler(pWindow, rEvt, scaleDirectly); @@ -1601,26 +1625,33 @@ public: { return ImplCallCommand(pWindow, COMMAND_SWIPE, &m_aSwipeData); } - bool HandleEvent(); }; -bool HandleSwipeEvent::HandleEvent() +static bool ImplHandleSwipe(vcl::Window *pWindow, const SalSwipeEvent& rEvt) { - if (!Setup()) - return false; - - WindowDescription aTarget = FindTarget(); - - bool bHandled = Dispatch(aTarget) != NULL; - - Teardown(aTarget); - - return bHandled; + HandleSwipeEvent aHandler(pWindow, rEvt); + return aHandler.HandleEvent(); } -static bool ImplHandleSwipe(vcl::Window *pWindow, const SalSwipeEvent& rEvt) +class HandleLongPressEvent : public HandleGestureEvent { - HandleSwipeEvent aHandler(pWindow, rEvt); +private: + CommandLongPressData m_aLongPressData; +public: + HandleLongPressEvent(vcl::Window *pWindow, const SalLongPressEvent& rEvt) + : HandleGestureEvent(pWindow, Point(rEvt.mnX, rEvt.mnY)) + { + m_aLongPressData = CommandLongPressData(rEvt.mnX, rEvt.mnY); + } + virtual bool CallCommand(vcl::Window *pWindow, const Point &/*rMousePos*/) SAL_OVERRIDE + { + return ImplCallCommand(pWindow, COMMAND_LONGPRESS, &m_aLongPressData); + } +}; + +static bool ImplHandleLongPress(vcl::Window *pWindow, const SalLongPressEvent& rEvt) +{ + HandleLongPressEvent aHandler(pWindow, rEvt); return aHandler.HandleEvent(); } @@ -2673,6 +2704,11 @@ bool ImplWindowFrameProc( vcl::Window* pWindow, SalFrame* /*pFrame*/, nRet = ImplHandleSwipe(pWindow, *(const SalSwipeEvent*)pEvent); break; + case SALEVENT_LONGPRESS: + nRet = ImplHandleLongPress(pWindow, *(const SalLongPressEvent*)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 36a780b850d1..aa94c26e924c 100644 --- a/vcl/unx/gtk/window/gtksalframe.cxx +++ b/vcl/unx/gtk/window/gtksalframe.cxx @@ -994,6 +994,12 @@ void GtkSalFrame::InitCommon() 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), reinterpret_cast<GWeakNotify>(g_object_unref), pSwipe); + + GtkGesture *pLongPress = gtk_gesture_long_press_new(m_pWindow); + g_signal_connect(pLongPress, "pressed", G_CALLBACK(gestureLongPress), this); + gtk_event_controller_set_propagation_phase(GTK_EVENT_CONTROLLER (pLongPress), GTK_PHASE_TARGET); + g_object_weak_ref(G_OBJECT(m_pWindow), reinterpret_cast<GWeakNotify>(g_object_unref), pLongPress); + #endif #else @@ -3325,6 +3331,22 @@ void GtkSalFrame::gestureSwipe(GtkGestureSwipe* gesture, gdouble velocity_x, gdo pThis->CallCallback(SALEVENT_SWIPE, &aEvent); } + +void GtkSalFrame::gestureLongPress(GtkGestureLongPress* gesture, gpointer frame) +{ + GtkSalFrame* pThis = (GtkSalFrame*)frame; + + SalLongPressEvent aEvent; + + gdouble x, y; + GdkEventSequence *sequence = gtk_gesture_single_get_current_sequence(GTK_GESTURE_SINGLE(gesture)); + gtk_gesture_get_point(GTK_GESTURE(gesture), sequence, &x, &y); + aEvent.mnX = x; + aEvent.mnY = y; + + pThis->CallCallback(SALEVENT_LONGPRESS, &aEvent); +} + #endif gboolean GtkSalFrame::signalMotion( GtkWidget*, GdkEventMotion* pEvent, gpointer frame ) |