summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTibor Nagy <tibor.nagy.extern@allotropia.de>2024-07-25 02:05:09 +0200
committerNagy Tibor <tibor.nagy.extern@allotropia.de>2024-07-25 12:00:17 +0200
commit042c62954be6ca55287e64cc725e71db4ddd7d8c (patch)
treef7f0b71eb7f579acbdb55b4dd33b8a32f377e631
parent566fbd5cc3b56fdfae88274e6f01fa3451cc1b79 (diff)
tdf#85677: Add support for Windows touch gestures (panning,zooming)
Change-Id: Ib0243889621663ddb9b6789ede7643d54f06041e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170988 Tested-by: Jenkins Reviewed-by: Nagy Tibor <tibor.nagy.extern@allotropia.de>
-rw-r--r--sc/source/ui/inc/tabview.hxx1
-rw-r--r--sc/source/ui/view/gridwin.cxx8
-rw-r--r--sc/source/ui/view/tabview.cxx23
-rw-r--r--sd/source/ui/view/viewshel.cxx7
-rw-r--r--sw/inc/view.hxx1
-rw-r--r--sw/source/uibase/docvw/edtwin.cxx12
-rw-r--r--sw/source/uibase/uiview/viewport.cxx5
-rw-r--r--vcl/inc/win/salframe.h1
-rw-r--r--vcl/inc/window.h3
-rw-r--r--vcl/source/window/layout.cxx5
-rw-r--r--vcl/source/window/window.cxx3
-rw-r--r--vcl/source/window/window2.cxx48
-rw-r--r--vcl/win/window/salframe.cxx103
13 files changed, 209 insertions, 11 deletions
diff --git a/sc/source/ui/inc/tabview.hxx b/sc/source/ui/inc/tabview.hxx
index 1873a525e9dd..51dd31c7ab63 100644
--- a/sc/source/ui/inc/tabview.hxx
+++ b/sc/source/ui/inc/tabview.hxx
@@ -476,6 +476,7 @@ public:
SC_DLLPUBLIC void ScrollLines( tools::Long nDeltaX, tools::Long nDeltaY ); // active
bool ScrollCommand( const CommandEvent& rCEvt, ScSplitPos ePos );
+ bool GesturePanCommand(const CommandEvent& rCEvt);
bool GestureZoomCommand(const CommandEvent& rCEvt);
void ScrollToObject( const SdrObject* pDrawObj );
diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx
index 44edfd493736..373122a12734 100644
--- a/sc/source/ui/view/gridwin.cxx
+++ b/sc/source/ui/view/gridwin.cxx
@@ -3271,6 +3271,14 @@ void ScGridWindow::Command( const CommandEvent& rCEvt )
return;
}
+ if (nCmd == CommandEventId::GesturePan)
+ {
+ bool bDone = mrViewData.GetView()->GesturePanCommand(rCEvt);
+ if (!bDone)
+ Window::Command(rCEvt);
+ return;
+ }
+
if (nCmd == CommandEventId::GestureZoom)
{
bool bDone = mrViewData.GetView()->GestureZoomCommand(rCEvt);
diff --git a/sc/source/ui/view/tabview.cxx b/sc/source/ui/view/tabview.cxx
index 8eba950c48ce..1e999d876cfe 100644
--- a/sc/source/ui/view/tabview.cxx
+++ b/sc/source/ui/view/tabview.cxx
@@ -1015,6 +1015,29 @@ bool ScTabView::ScrollCommand( const CommandEvent& rCEvt, ScSplitPos ePos )
return bDone;
}
+bool ScTabView::GesturePanCommand(const CommandEvent& rCEvt)
+{
+ HideNoteMarker();
+
+ bool bDone = false;
+ const CommandGesturePanData* pData = rCEvt.GetGesturePanData();
+ if (!pData)
+ return false;
+
+ if (aViewData.GetViewShell()->GetViewFrame().GetFrame().IsInPlace())
+ return false;
+
+ ScSplitPos ePos = aViewData.GetActivePart();
+ ScHSplitPos eHPos = WhichH(ePos);
+ ScVSplitPos eVPos = WhichV(ePos);
+ ScrollAdaptor* pHScroll = (eHPos == SC_SPLIT_LEFT) ? aHScrollLeft.get() : aHScrollRight.get();
+ ScrollAdaptor* pVScroll = (eVPos == SC_SPLIT_TOP) ? aVScrollTop.get() : aVScrollBottom.get();
+ if (pGridWin[ePos])
+ bDone = pGridWin[ePos]->HandleScrollCommand(rCEvt, pHScroll, pVScroll);
+
+ return bDone;
+}
+
bool ScTabView::GestureZoomCommand(const CommandEvent& rCEvt)
{
HideNoteMarker();
diff --git a/sd/source/ui/view/viewshel.cxx b/sd/source/ui/view/viewshel.cxx
index 11f7a186f282..d140187d56d6 100644
--- a/sd/source/ui/view/viewshel.cxx
+++ b/sd/source/ui/view/viewshel.cxx
@@ -875,6 +875,13 @@ bool ViewShell::HandleScrollCommand(const CommandEvent& rCEvt, ::sd::Window* pWi
}
break;
+ case CommandEventId::GesturePan:
+ {
+ bDone = pWin->HandleScrollCommand(rCEvt, mpHorizontalScrollBar.get(),
+ mpVerticalScrollBar.get());
+ }
+ break;
+
case CommandEventId::GestureZoom:
{
const CommandGestureZoomData* pData = rCEvt.GetGestureZoomData();
diff --git a/sw/inc/view.hxx b/sw/inc/view.hxx
index d735e5e6e94a..c496f2ac7891 100644
--- a/sw/inc/view.hxx
+++ b/sw/inc/view.hxx
@@ -481,6 +481,7 @@ public:
bool HandleWheelCommands( const CommandEvent& );
bool HandleGestureZoomCommand(const CommandEvent&);
+ bool HandleGesturePanCommand(const CommandEvent&);
// insert frames
void InsFrameMode(sal_uInt16 nCols);
diff --git a/sw/source/uibase/docvw/edtwin.cxx b/sw/source/uibase/docvw/edtwin.cxx
index 81064a94a8f7..8a917ac2e806 100644
--- a/sw/source/uibase/docvw/edtwin.cxx
+++ b/sw/source/uibase/docvw/edtwin.cxx
@@ -5780,6 +5780,18 @@ void SwEditWin::Command( const CommandEvent& rCEvt )
break;
}
+ case CommandEventId::GesturePan:
+ {
+ if (m_pSavedOutlineFrame && rSh.GetViewOptions()->IsShowOutlineContentVisibilityButton())
+ {
+ GetFrameControlsManager().RemoveControlsByType(FrameControlType::Outline, m_pSavedOutlineFrame);
+ m_pSavedOutlineFrame = nullptr;
+ }
+ m_pShadCursor.reset();
+ bCallBase = !m_rView.HandleGesturePanCommand(rCEvt);
+ break;
+ }
+
case CommandEventId::GestureLongPress:
case CommandEventId::GestureSwipe: //nothing yet
break;
diff --git a/sw/source/uibase/uiview/viewport.cxx b/sw/source/uibase/uiview/viewport.cxx
index a7ec3f161b60..f511f4a8e354 100644
--- a/sw/source/uibase/uiview/viewport.cxx
+++ b/sw/source/uibase/uiview/viewport.cxx
@@ -1261,4 +1261,9 @@ bool SwView::HandleGestureZoomCommand(const CommandEvent& rCEvt)
return true;
}
+bool SwView::HandleGesturePanCommand(const CommandEvent& rCEvt)
+{
+ return m_pEditWin->HandleScrollCommand(rCEvt, m_pHScrollbar, m_pVScrollbar);
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/win/salframe.h b/vcl/inc/win/salframe.h
index e2f41822be0a..e465eb1350b1 100644
--- a/vcl/inc/win/salframe.h
+++ b/vcl/inc/win/salframe.h
@@ -84,6 +84,7 @@ public:
bool mbFirstClipRect;
sal_Int32 mnDisplay; // Display used for Fullscreen, 0 is primary monitor
bool mbPropertiesStored; // has values stored in the window property store
+ POINT maFirstPanGesturePt; // has value stores the start point of the panning gesture
void updateScreenNumber();
diff --git a/vcl/inc/window.h b/vcl/inc/window.h
index 199fed977c4c..69c61214ce7a 100644
--- a/vcl/inc/window.h
+++ b/vcl/inc/window.h
@@ -168,7 +168,8 @@ struct ImplFrameData
bool mbInSysObjFocusHdl; //< within a SysChildren's GetFocus handler
bool mbInSysObjToTopHdl; //< within a SysChildren's ToTop handler
bool mbSysObjFocus; //< does a SysChild have focus
- sal_Int32 mnTouchPanPosition;
+ sal_Int32 mnTouchPanPositionX;
+ sal_Int32 mnTouchPanPositionY;
css::uno::Reference< css::datatransfer::dnd::XDragSource > mxDragSource;
css::uno::Reference< css::datatransfer::dnd::XDropTarget > mxDropTarget;
diff --git a/vcl/source/window/layout.cxx b/vcl/source/window/layout.cxx
index 14c7c9ade823..d9ce06bc1ae0 100644
--- a/vcl/source/window/layout.cxx
+++ b/vcl/source/window/layout.cxx
@@ -2176,6 +2176,11 @@ bool VclScrolledWindow::EventNotify(NotifyEvent& rNEvt)
m_pVScroll->IsVisible() ? m_pVScroll : nullptr);
}
}
+ else if (rCEvt.GetCommand() == CommandEventId::GesturePan)
+ {
+ bDone = HandleScrollCommand(rCEvt, m_pHScroll->IsVisible() ? m_pHScroll : nullptr,
+ m_pVScroll->IsVisible() ? m_pVScroll : nullptr);
+ }
}
return bDone || VclBin::EventNotify( rNEvt );
diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx
index 108ad423454c..683187bb6827 100644
--- a/vcl/source/window/window.cxx
+++ b/vcl/source/window/window.cxx
@@ -812,7 +812,8 @@ ImplFrameData::ImplFrameData( vcl::Window *pWindow )
mbInBufferedPaint = false;
mnDPIX = 96;
mnDPIY = 96;
- mnTouchPanPosition = -1;
+ mnTouchPanPositionX = -1;
+ mnTouchPanPositionY = -1;
}
namespace vcl {
diff --git a/vcl/source/window/window2.cxx b/vcl/source/window/window2.cxx
index 48f4b56dde97..c9fbad68842f 100644
--- a/vcl/source/window/window2.cxx
+++ b/vcl/source/window/window2.cxx
@@ -791,21 +791,51 @@ bool Window::HandleScrollCommand( const CommandEvent& rCmd,
case CommandEventId::GesturePan:
{
- if (pVScrl)
+ const CommandGesturePanData* pData = rCmd.GetGesturePanData();
+ if (pData)
{
- const CommandGesturePanData* pData = rCmd.GetGesturePanData();
- if (pData->meEventType == GestureEventPanType::Begin)
+ if (pData && pData->meEventType == GestureEventPanType::Begin)
{
- mpWindowImpl->mpFrameData->mnTouchPanPosition = pVScrl->GetThumbPos();
+ if (pHScrl)
+ mpWindowImpl->mpFrameData->mnTouchPanPositionX = pHScrl->GetThumbPos();
+ if (pVScrl)
+ mpWindowImpl->mpFrameData->mnTouchPanPositionY = pVScrl->GetThumbPos();
}
- else if(pData->meEventType == GestureEventPanType::Update)
+ else if (pData && pData->meEventType == GestureEventPanType::Update)
{
- tools::Long nOriginalPosition = mpWindowImpl->mpFrameData->mnTouchPanPosition;
- pVScrl->DoScroll(nOriginalPosition + (pData->mfOffset / pVScrl->GetVisibleSize()));
+ bool bHorz = pData->meOrientation == PanningOrientation::Horizontal;
+ Scrollable* pScrl = bHorz ? pHScrl : pVScrl;
+ if (pScrl)
+ {
+ Point aGesturePt(pData->mfX, pData->mfY);
+ tools::Rectangle aWinRect(this->GetOutputRectPixel());
+ bool bContains = aWinRect.Contains(aGesturePt);
+ if (bContains)
+ {
+ tools::Long nOriginalPos
+ = bHorz ? mpWindowImpl->mpFrameData->mnTouchPanPositionX
+ : mpWindowImpl->mpFrameData->mnTouchPanPositionY;
+
+ tools::Long nNewPos;
+ double nOffset = pData->mfOffset;
+ tools::Long nSize = pScrl->GetVisibleSize();
+ if (aWinRect.GetSize().Width() < nSize
+ || aWinRect.GetSize().Height() < nSize)
+ {
+ sal_Int32 nVelocity = 15;
+ nNewPos = nOriginalPos - (nOffset * nVelocity);
+ }
+ else
+ nNewPos = nOriginalPos - (nOffset / nSize);
+
+ pScrl->DoScroll(nNewPos);
+ }
+ }
}
- if (pData->meEventType == GestureEventPanType::End)
+ else if (pData->meEventType == GestureEventPanType::End)
{
- mpWindowImpl->mpFrameData->mnTouchPanPosition = -1;
+ mpWindowImpl->mpFrameData->mnTouchPanPositionX = -1;
+ mpWindowImpl->mpFrameData->mnTouchPanPositionY = -1;
}
bRet = true;
}
diff --git a/vcl/win/window/salframe.cxx b/vcl/win/window/salframe.cxx
index 1cf551c00d78..6e029a5c2361 100644
--- a/vcl/win/window/salframe.cxx
+++ b/vcl/win/window/salframe.cxx
@@ -904,6 +904,7 @@ WinSalFrame::WinSalFrame()
mnDisplay = 0;
mbPropertiesStored = false;
m_pTaskbarList3 = nullptr;
+ maFirstPanGesturePt = POINT(0,0);
// get data, when making 1st frame
if ( !pSalData->mpFirstFrame )
@@ -5840,6 +5841,93 @@ static bool ImplSalWheelMousePos( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lP
return true;
}
+static bool ImplHandleGestureMsg(HWND hWnd, LPARAM lParam)
+{
+ ImplSalYieldMutexAcquireWithWait();
+
+ bool nRet = false;
+
+ WinSalFrame* pFrame = GetWindowPtr(hWnd);
+ if (pFrame)
+ {
+ GESTUREINFO gi;
+ ZeroMemory(&gi, sizeof(GESTUREINFO));
+ gi.cbSize = sizeof(GESTUREINFO);
+
+ BOOL result = GetGestureInfo((HGESTUREINFO)lParam, &gi);
+ if (!result)
+ return nRet;
+
+ switch (gi.dwID)
+ {
+ case GID_PAN:
+ {
+ SalGestureEvent aEvent;
+ POINT aPt(gi.ptsLocation.x, gi.ptsLocation.y);
+ ScreenToClient(hWnd, &aPt);
+ aEvent.mnX = aPt.x;
+ aEvent.mnY = aPt.y;
+
+ if (gi.dwFlags & GF_BEGIN)
+ {
+ pFrame->maFirstPanGesturePt.x = gi.ptsLocation.x;
+ pFrame->maFirstPanGesturePt.y = gi.ptsLocation.y;
+ aEvent.meEventType = GestureEventPanType::Begin;
+ }
+ else if (gi.dwFlags & GF_END)
+ aEvent.meEventType = GestureEventPanType::End;
+ else
+ {
+ POINT aFirstPt(pFrame->maFirstPanGesturePt.x, pFrame->maFirstPanGesturePt.y);
+ POINT aSecondPt(gi.ptsLocation.x, gi.ptsLocation.y);
+ tools::Long deltaX = (aSecondPt.x - aFirstPt.x);
+ tools::Long deltaY = (aSecondPt.y - aFirstPt.y);
+
+ if (std::abs(deltaX) > std::abs(deltaY))
+ {
+ aEvent.mfOffset = aSecondPt.x - aFirstPt.x;
+ aEvent.meOrientation = PanningOrientation::Horizontal;
+ }
+ else
+ {
+ aEvent.mfOffset = aSecondPt.y - aFirstPt.y;
+ aEvent.meOrientation = PanningOrientation::Vertical;
+ }
+
+ aEvent.meEventType = GestureEventPanType::Update;
+ }
+ nRet = pFrame->CallCallback(SalEvent::GesturePan, &aEvent);
+ }
+ break;
+
+ case GID_ZOOM:
+ {
+ SalGestureZoomEvent aEvent;
+ POINT aPt(gi.ptsLocation.x, gi.ptsLocation.y);
+ ScreenToClient(hWnd, &aPt);
+ aEvent.mnX = aPt.x;
+ aEvent.mnY = aPt.y;
+ aEvent.mfScaleDelta = gi.ullArguments;
+
+ if (gi.dwFlags & GF_BEGIN)
+ aEvent.meEventType = GestureEventZoomType::Begin;
+ else if (gi.dwFlags & GF_END)
+ aEvent.meEventType = GestureEventZoomType::End;
+ else
+ aEvent.meEventType = GestureEventZoomType::Update;
+
+ nRet = pFrame->CallCallback(SalEvent::GestureZoom, &aEvent);
+ }
+ break;
+ }
+ CloseGestureInfoHandle((HGESTUREINFO)lParam);
+ }
+
+ ImplSalYieldMutexRelease();
+
+ return nRet;
+}
+
static LRESULT CALLBACK SalFrameWndProc( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam, bool& rDef )
{
LRESULT nRet = 0;
@@ -5867,6 +5955,15 @@ static LRESULT CALLBACK SalFrameWndProc( HWND hWnd, UINT nMsg, WPARAM wParam, LP
// when messages are being sent by CreateWindow()
pFrame->mhWnd = hWnd;
pFrame->maSysData.hWnd = hWnd;
+
+ DWORD dwPanWant = GC_PAN | GC_PAN_WITH_SINGLE_FINGER_VERTICALLY
+ | GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY;
+ DWORD dwPanBlock = GC_PAN_WITH_GUTTER;
+ GESTURECONFIG gc[] = { { GID_ZOOM, GC_ZOOM, 0 },
+ { GID_ROTATE, GC_ROTATE, 0 },
+ { GID_PAN, dwPanWant, dwPanBlock } };
+ UINT uiGcs = 3;
+ SetGestureConfig(hWnd, 0, uiGcs, gc, sizeof(GESTURECONFIG));
}
return 0;
}
@@ -5885,6 +5982,12 @@ static LRESULT CALLBACK SalFrameWndProc( HWND hWnd, UINT nMsg, WPARAM wParam, LP
switch( nMsg )
{
+ case WM_GESTURE:
+ ImplSalYieldMutexAcquireWithWait();
+ rDef = !ImplHandleGestureMsg(hWnd, lParam);
+ ImplSalYieldMutexRelease();
+ break;
+
case WM_MOUSEMOVE:
case WM_LBUTTONDOWN:
case WM_MBUTTONDOWN: