Kaydet (Commit) 873141fb authored tarafından Caolán McNamara's avatar Caolán McNamara

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
üst 1c782778
......@@ -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: */
......@@ -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()
......
......@@ -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 )
......
......@@ -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
......
......@@ -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();
......
......@@ -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() ) );
......
......@@ -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 );
......
......@@ -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 );
......
......@@ -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 << ")" );
......
......@@ -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 )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment