diff options
author | Tomaž Vajngerl <tomaz.vajngerl@collabora.co.uk> | 2019-03-25 18:05:35 +0900 |
---|---|---|
committer | Michael Meeks <michael.meeks@collabora.com> | 2019-08-02 15:35:51 -0400 |
commit | 0373ff970783ed9e4b9950d0199d98e1f7cfa3c5 (patch) | |
tree | 6e331771480a4c330244f4f3103c26b4c0732add | |
parent | 3e27cea44ccb2a34bd96c03ed2f279324a145ea6 (diff) |
tdf#124146 add (general) gesture event support to VCL
Change-Id: I766930bb35071442e132b91477cd3d55e8f00f48
Reviewed-on: https://gerrit.libreoffice.org/69655
Tested-by: Jenkins
Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
-rw-r--r-- | include/vcl/GestureEvent.hxx | 42 | ||||
-rw-r--r-- | include/vcl/commandevent.hxx | 24 | ||||
-rw-r--r-- | include/vcl/svapp.hxx | 3 | ||||
-rw-r--r-- | include/vcl/vclevent.hxx | 1 | ||||
-rw-r--r-- | vcl/inc/salwtype.hxx | 14 | ||||
-rw-r--r-- | vcl/source/app/svapp.cxx | 68 | ||||
-rw-r--r-- | vcl/source/window/commandevent.cxx | 9 | ||||
-rw-r--r-- | vcl/source/window/winproc.cxx | 44 |
8 files changed, 198 insertions, 7 deletions
diff --git a/include/vcl/GestureEvent.hxx b/include/vcl/GestureEvent.hxx new file mode 100644 index 000000000000..2070fc76d39a --- /dev/null +++ b/include/vcl/GestureEvent.hxx @@ -0,0 +1,42 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + */ + +#ifndef INCLUDED_VCL_GESTUREEVENT_HXX +#define INCLUDED_VCL_GESTUREEVENT_HXX + +#include <vcl/dllapi.h> + +enum class GestureEventType +{ + PanningBegin, + PanningUpdate, + PanningEnd +}; + +enum class PanningOrientation +{ + Horizontal, + Vertical +}; + +class VCL_DLLPUBLIC GestureEvent +{ +public: + sal_Int32 mnX; + sal_Int32 mnY; + GestureEventType meEventType; + + sal_Int32 mnOffset; + PanningOrientation meOrientation; +}; + +#endif // INCLUDED_VCL_GESTUREEVENT_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/vcl/commandevent.hxx b/include/vcl/commandevent.hxx index 88185efde077..a3ee2fb73c99 100644 --- a/include/vcl/commandevent.hxx +++ b/include/vcl/commandevent.hxx @@ -27,6 +27,7 @@ #include <vcl/keycodes.hxx> #include <o3tl/typed_flags_set.hxx> #include <rtl/ustring.hxx> +#include <vcl/GestureEvent.hxx> class CommandExtTextInputData; class CommandWheelData; @@ -37,6 +38,8 @@ class CommandMediaData; class CommandSelectionChangeData; class CommandSwipeData; class CommandLongPressData; +class CommandGestureData; + enum class CommandEventId; enum class ExtTextInputAttr { @@ -86,6 +89,7 @@ public: const CommandSelectionChangeData* GetSelectionChangeData() const; const CommandSwipeData* GetSwipeData() const; const CommandLongPressData* GetLongPressData() const; + const CommandGestureData* GetGestureData() const; }; class VCL_DLLPUBLIC CommandExtTextInputData @@ -300,6 +304,25 @@ public: double getY() const { return mnY; } }; +class VCL_DLLPUBLIC CommandGestureData +{ +public: + double const mfX; + double const mfY; + GestureEventType const meEventType; + + double const mfOffset; + PanningOrientation const meOrientation; + + CommandGestureData(double fX, double fY, GestureEventType eEventType, double fOffset, PanningOrientation eOrientation) + : mfX(fX) + , mfY(fY) + , meEventType(eEventType) + , mfOffset(fOffset) + , meOrientation(eOrientation) + {} +}; + enum class CommandEventId { NONE = 0, @@ -323,6 +346,7 @@ enum class CommandEventId QueryCharPosition = 20, Swipe = 21, LongPress = 22, + Gesture = 23, }; #endif // INCLUDED_VCL_COMMANDEVENT_HXX diff --git a/include/vcl/svapp.hxx b/include/vcl/svapp.hxx index 664f8ba8d56a..dce6af76262f 100644 --- a/include/vcl/svapp.hxx +++ b/include/vcl/svapp.hxx @@ -68,6 +68,7 @@ class Reflection; class NotifyEvent; class KeyEvent; class MouseEvent; +class GestureEvent; struct ImplSVEvent; struct ConvertData; @@ -756,6 +757,8 @@ public: */ static ImplSVEvent * PostMouseEvent( VclEventId nEvent, vcl::Window *pWin, MouseEvent const * pMouseEvent ); + static ImplSVEvent* PostGestureEvent(VclEventId nEvent, vcl::Window* pWin, GestureEvent const * pGestureEvent); + /** Remove mouse and keypress events from a window... any also zoom and scroll events if the platform supports it. diff --git a/include/vcl/vclevent.hxx b/include/vcl/vclevent.hxx index 698fd038bbde..575320f7639d 100644 --- a/include/vcl/vclevent.hxx +++ b/include/vcl/vclevent.hxx @@ -174,6 +174,7 @@ enum class VclEventId WindowShow, WindowStartDocking, // pData = DockingData WindowToggleFloating, + WindowGestureEvent, }; class VCL_DLLPUBLIC VclSimpleEvent diff --git a/vcl/inc/salwtype.hxx b/vcl/inc/salwtype.hxx index 342f18d3ec85..ac28793aa339 100644 --- a/vcl/inc/salwtype.hxx +++ b/vcl/inc/salwtype.hxx @@ -24,6 +24,7 @@ #include <rtl/ref.hxx> #include <rtl/ustring.hxx> #include <tools/solar.h> +#include <vcl/GestureEvent.hxx> class LogicalFontInstance; class SalGraphics; @@ -82,7 +83,9 @@ enum class SalEvent { StartReconversion, QueryCharPosition, Swipe, - LongPress + LongPress, + ExternalGesture, + Gesture, }; // MOUSELEAVE must send, when the pointer leave the client area and @@ -256,6 +259,15 @@ struct SalLongPressEvent long mnY; }; +struct SalGestureEvent +{ + GestureEventType meEventType; + PanningOrientation meOrientation; + double mfOffset; + long mnX; + long mnY; +}; + typedef void (*SALTIMERPROC)(); #endif // INCLUDED_VCL_INC_SALWTYPE_HXX diff --git a/vcl/source/app/svapp.cxx b/vcl/source/app/svapp.cxx index 626214690166..e85f28d2f1ae 100644 --- a/vcl/source/app/svapp.cxx +++ b/vcl/source/app/svapp.cxx @@ -131,11 +131,26 @@ struct ImplPostEventData ImplSVEvent * mnEventId; KeyEvent maKeyEvent; MouseEvent maMouseEvent; - - ImplPostEventData( VclEventId nEvent, vcl::Window* pWin, const KeyEvent& rKeyEvent ) : - mnEvent( nEvent ), mpWin( pWin ), mnEventId( nullptr ), maKeyEvent( rKeyEvent ) {} - ImplPostEventData( VclEventId nEvent, vcl::Window* pWin, const MouseEvent& rMouseEvent ) : - mnEvent( nEvent ), mpWin( pWin ), mnEventId( nullptr ), maMouseEvent( rMouseEvent ) {} + GestureEvent maGestureEvent; + + ImplPostEventData(VclEventId nEvent, vcl::Window* pWin, const KeyEvent& rKeyEvent) + : mnEvent(nEvent) + , mpWin(pWin) + , mnEventId(nullptr) + , maKeyEvent(rKeyEvent) + {} + ImplPostEventData(VclEventId nEvent, vcl::Window* pWin, const MouseEvent& rMouseEvent) + : mnEvent(nEvent) + , mpWin(pWin) + , mnEventId(nullptr) + , maMouseEvent(rMouseEvent) + {} + ImplPostEventData(VclEventId nEvent, vcl::Window* pWin, const GestureEvent& rGestureEvent) + : mnEvent(nEvent) + , mpWin(pWin) + , mnEventId(nullptr) + , maGestureEvent(rGestureEvent) + {} }; Application* GetpApp() @@ -829,7 +844,43 @@ ImplSVEvent * Application::PostKeyEvent( VclEventId nEvent, vcl::Window *pWin, K return nEventId; } -ImplSVEvent * Application::PostMouseEvent( VclEventId nEvent, vcl::Window *pWin, MouseEvent const * pMouseEvent ) +ImplSVEvent* Application::PostGestureEvent(VclEventId nEvent, vcl::Window* pWin, GestureEvent const * pGestureEvent) +{ + const SolarMutexGuard aGuard; + ImplSVEvent * nEventId = nullptr; + + if (pWin && pGestureEvent) + { + Point aTransformedPosition(pGestureEvent->mnX, pGestureEvent->mnY); + + aTransformedPosition.AdjustX(pWin->GetOutOffXPixel()); + aTransformedPosition.AdjustY(pWin->GetOutOffYPixel()); + + const GestureEvent aGestureEvent{ + sal_Int32(aTransformedPosition.X()), + sal_Int32(aTransformedPosition.Y()), + pGestureEvent->meEventType, + pGestureEvent->mnOffset, + pGestureEvent->meOrientation + }; + + std::unique_ptr<ImplPostEventData> pPostEventData(new ImplPostEventData(nEvent, pWin, aGestureEvent)); + + nEventId = PostUserEvent( + LINK( nullptr, Application, PostEventHandler ), + pPostEventData.get()); + + if (nEventId) + { + pPostEventData->mnEventId = nEventId; + ImplGetSVData()->maAppData.maPostedEventList.emplace_back(pWin, pPostEventData.release()); + } + } + + return nEventId; +} + +ImplSVEvent* Application::PostMouseEvent( VclEventId nEvent, vcl::Window *pWin, MouseEvent const * pMouseEvent ) { const SolarMutexGuard aGuard; ImplSVEvent * nEventId = nullptr; @@ -898,6 +949,11 @@ IMPL_STATIC_LINK( Application, PostEventHandler, void*, pCallData, void ) pEventData = &pData->maKeyEvent; break; + case VclEventId::WindowGestureEvent: + nEvent = SalEvent::ExternalGesture; + pEventData = &pData->maGestureEvent; + break; + default: nEvent = SalEvent::NONE; pEventData = nullptr; diff --git a/vcl/source/window/commandevent.cxx b/vcl/source/window/commandevent.cxx index c8b486e7fc59..06e974c9fc6a 100644 --- a/vcl/source/window/commandevent.cxx +++ b/vcl/source/window/commandevent.cxx @@ -186,4 +186,13 @@ const CommandLongPressData* CommandEvent::GetLongPressData() const return nullptr; } +const CommandGestureData* CommandEvent::GetGestureData() const +{ + if (mnCommand == CommandEventId::Gesture) + return static_cast<const CommandGestureData*>(mpData); + else + return nullptr; +} + + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/window/winproc.cxx b/vcl/source/window/winproc.cxx index 7a54ea209268..3f127e0afd08 100644 --- a/vcl/source/window/winproc.cxx +++ b/vcl/source/window/winproc.cxx @@ -28,6 +28,7 @@ #include <vcl/unohelp.hxx> #include <vcl/timer.hxx> #include <vcl/event.hxx> +#include <vcl/GestureEvent.hxx> #include <vcl/settings.hxx> #include <vcl/svapp.hxx> #include <vcl/cursor.hxx> @@ -1550,6 +1551,30 @@ static bool ImplHandleLongPress(vcl::Window *pWindow, const SalLongPressEvent& r return aHandler.HandleEvent(); } +class HandleGeneralGestureEvent : public HandleGestureEvent +{ +private: + CommandGestureData m_aGestureData; + +public: + HandleGeneralGestureEvent(vcl::Window* pWindow, const SalGestureEvent& rEvent) + : HandleGestureEvent(pWindow, Point(rEvent.mnX, rEvent.mnY)) + , m_aGestureData(rEvent.mnX, rEvent.mnY, rEvent.meEventType, rEvent.mfOffset, rEvent.meOrientation) + { + } + + virtual bool CallCommand(vcl::Window* pWindow, const Point& /*rMousePos*/) override + { + return ImplCallCommand(pWindow, CommandEventId::Gesture, &m_aGestureData); + } +}; + +static bool ImplHandleGestureEvent(vcl::Window* pWindow, const SalGestureEvent& rEvent) +{ + HandleGeneralGestureEvent aHandler(pWindow, rEvent); + return aHandler.HandleEvent(); +} + static void ImplHandlePaint( vcl::Window* pWindow, const tools::Rectangle& rBoundRect, bool bImmediateUpdate ) { // system paint events must be checked for re-mirroring @@ -2537,7 +2562,26 @@ bool ImplWindowFrameProc( vcl::Window* _pWindow, SalEvent nEvent, const void* pE bRet = ImplHandleLongPress(pWindow, *static_cast<const SalLongPressEvent*>(pEvent)); break; + case SalEvent::ExternalGesture: + { + auto const * pGestureEvent = static_cast<GestureEvent const *>(pEvent); + + SalGestureEvent aSalGestureEvent; + aSalGestureEvent.mfOffset = pGestureEvent->mnOffset; + aSalGestureEvent.mnX = pGestureEvent->mnX; + aSalGestureEvent.mnY = pGestureEvent->mnY; + aSalGestureEvent.meEventType = pGestureEvent->meEventType; + aSalGestureEvent.meOrientation = pGestureEvent->meOrientation; + bRet = ImplHandleGestureEvent(pWindow, aSalGestureEvent); + } + break; + case SalEvent::Gesture: + { + auto const * aSalGestureEvent = static_cast<SalGestureEvent const *>(pEvent); + bRet = ImplHandleGestureEvent(pWindow, *aSalGestureEvent); + } + break; default: SAL_WARN( "vcl.layout", "ImplWindowFrameProc(): unknown event (" << static_cast<int>(nEvent) << ")" ); break; |