From e7462d82bf1f5cdf2983cb83d7dfc8a6c5d02f0e Mon Sep 17 00:00:00 2001 From: Alex Shvartzkop Date: Fri, 21 Jun 2024 13:34:46 +0300 Subject: [PATCH 1/2] Fix touch gestures test navigation in event sample. Panning while scaled didn't pan by the correct amount. Combination of gesture events didn't work correctly. --- samples/event/gestures.cpp | 62 ++++++++++++++++++++++++++------------ samples/event/gestures.h | 1 + 2 files changed, 43 insertions(+), 20 deletions(-) diff --git a/samples/event/gestures.cpp b/samples/event/gestures.cpp index 021c7d664f..604b958cd8 100644 --- a/samples/event/gestures.cpp +++ b/samples/event/gestures.cpp @@ -83,7 +83,7 @@ void MyGesturePanel::OnPaint(wxPaintEvent& WXUNUSED(event)) wxGCDC dc(paintDC); dc.SetTransformMatrix(m_affineMatrix); - dc.DrawBitmap(m_bitmap, wxRound(m_translateDistance.m_x), wxRound(m_translateDistance.m_y)); + dc.DrawBitmap(m_bitmap, 0, 0); } void MyGesturePanel::OnPan(wxPanGestureEvent& event) @@ -102,13 +102,11 @@ void MyGesturePanel::OnPan(wxPanGestureEvent& event) // Transform the distance using the transpose of the matrix, // in order to translate the image to match the screen coordinates wxMatrix2D m; - m_affineMatrix.Get(&m, nullptr); + wxPoint2DDouble tr; - wxPoint2DDouble deltaD(m.m_11 * delta.x + m.m_12 * delta.y, - m.m_21 * delta.x + m.m_22 * delta.y); - - // Add it to the total translation - m_translateDistance += deltaD; + m_affineMatrix.Get(&m, &tr); + tr += event.GetDelta(); + m_affineMatrix.Set(m, tr); if ( event.IsGestureEnd() ) { @@ -125,19 +123,31 @@ void MyGesturePanel::OnZoom(wxZoomGestureEvent& event) wxLogMessage("Zoom gesture started"); m_lastZoomFactor = 1.0; + m_lastGesturePos = event.GetPosition(); } wxLogMessage("Zoom gesture performed with zoom center at (%d, %d) and zoom Factor = %f", event.GetPosition().x, event.GetPosition().y, event.GetZoomFactor()); - const wxPoint& zoomCenter = event.GetPosition(); + const wxPoint &evtPos = event.GetPosition(); + double factor = event.GetZoomFactor() / m_lastZoomFactor; - // Translate to zoom center - m_affineMatrix.Translate(zoomCenter.x, zoomCenter.y); - // Scale - m_affineMatrix.Scale(event.GetZoomFactor() / m_lastZoomFactor, event.GetZoomFactor() / m_lastZoomFactor); - // Translate back - m_affineMatrix.Translate(-zoomCenter.x, -zoomCenter.y); + wxMatrix2D m; + wxPoint2DDouble tr; + m_affineMatrix.Get(&m, &tr); + + tr -= m_lastGesturePos; + + wxAffineMatrix2D inv = m_affineMatrix; + inv.Invert(); + tr = inv.TransformDistance(tr); + m_affineMatrix.Scale(factor, factor); + tr = m_affineMatrix.TransformDistance(tr); + + tr += evtPos; + + m_affineMatrix.Get(&m, nullptr); + m_affineMatrix.Set(m, tr); if ( event.IsGestureEnd() ) { @@ -145,6 +155,7 @@ void MyGesturePanel::OnZoom(wxZoomGestureEvent& event) } m_lastZoomFactor = event.GetZoomFactor(); + m_lastGesturePos = evtPos; Refresh(); } @@ -161,14 +172,25 @@ void MyGesturePanel::OnRotate(wxRotateGestureEvent& event) wxLogMessage("Rotate gesture performed with rotation center at (%d, %d) and cumulative rotation angle = %f", event.GetPosition().x, event.GetPosition().y, event.GetRotationAngle()); - const wxPoint& rotationCenter = event.GetPosition(); + const wxPoint& evtPos = event.GetPosition(); - // Translate to rotation center - m_affineMatrix.Translate(rotationCenter.x, rotationCenter.y); - // Rotate + wxMatrix2D m; + wxPoint2DDouble tr; + + m_affineMatrix.Get(&m, &tr); + + tr -= evtPos; + + wxAffineMatrix2D inv = m_affineMatrix; + inv.Invert(); + tr = inv.TransformDistance(tr); m_affineMatrix.Rotate(event.GetRotationAngle() - m_lastRotationAngle); - // Translate back - m_affineMatrix.Translate(-rotationCenter.x, -rotationCenter.y); + tr = m_affineMatrix.TransformDistance(tr); + + tr += evtPos; + + m_affineMatrix.Get(&m, nullptr); + m_affineMatrix.Set(m, tr); if ( event.IsGestureEnd() ) { diff --git a/samples/event/gestures.h b/samples/event/gestures.h index 1b2f7f43da..991a5913e7 100644 --- a/samples/event/gestures.h +++ b/samples/event/gestures.h @@ -35,6 +35,7 @@ private: wxAffineMatrix2D m_affineMatrix; double m_lastZoomFactor; double m_lastRotationAngle; + wxPoint m_lastGesturePos; }; #endif // _WX_GESTURES_H_ From 773a773b767289ca3849fe850536ffd594a199f7 Mon Sep 17 00:00:00 2001 From: Alex Shvartzkop Date: Mon, 17 Jun 2024 16:16:44 +0300 Subject: [PATCH 2/2] Fix pinch (zoom + rotate) touch gesture on wxQt. - Fixes the zoom factor that was not set correctly. - Implements the rotate gesture call. - Minor simplification in panTriggered. --- include/wx/qt/private/winevent.h | 49 +++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/include/wx/qt/private/winevent.h b/include/wx/qt/private/winevent.h index 66e6692087..99cf0d0286 100644 --- a/include/wx/qt/private/winevent.h +++ b/include/wx/qt/private/winevent.h @@ -431,12 +431,7 @@ protected: wxPanGestureEvent evp(win->GetId()); QPoint pos = QCursor::pos(); evp.SetPosition( wxQtConvertPoint( pos ) ); - - QPoint offset = gesture->offset().toPoint(); - QPoint offset_last = gesture->lastOffset().toPoint(); - QPoint delta(offset.x() - offset_last.x(), offset.y() - offset_last.y()); - - evp.SetDelta( wxQtConvertPoint( delta ) ); + evp.SetDelta( wxQtConvertPoint( gesture->delta().toPoint() ) ); switch(gesture->state()) { @@ -462,16 +457,14 @@ protected: wxWindow *win = wxWindow::QtRetrieveWindowPointer( this ); if (win) { - - qreal this_sf = gesture->scaleFactor(); - QPoint center_point = gesture->centerPoint().toPoint(); - - wxZoomGestureEvent evp(win->GetId()); - evp.SetPosition( wxQtConvertPoint( center_point ) ); - evp.SetZoomFactor( this_sf); - - switch(gesture->state()) + if (gesture->changeFlags() & QPinchGesture::ScaleFactorChanged) { + wxZoomGestureEvent evp(win->GetId()); + evp.SetPosition(wxQtConvertPoint(gesture->centerPoint().toPoint())); + evp.SetZoomFactor(gesture->totalScaleFactor()); + + switch (gesture->state()) + { case Qt::GestureStarted: evp.SetGestureStart(); break; @@ -481,12 +474,34 @@ protected: break; default: break; + } + + win->ProcessWindowEvent(evp); } - win->ProcessWindowEvent( evp ); + if (gesture->changeFlags() & QPinchGesture::RotationAngleChanged) + { + wxRotateGestureEvent evp(win->GetId()); + evp.SetPosition(wxQtConvertPoint(gesture->centerPoint().toPoint())); + evp.SetRotationAngle(wxDegToRad(gesture->totalRotationAngle())); + + switch (gesture->state()) + { + case Qt::GestureStarted: + evp.SetGestureStart(); + break; + case Qt::GestureFinished: + case Qt::GestureCanceled: + evp.SetGestureEnd(); + break; + default: + break; + } + + win->ProcessWindowEvent(evp); + } event->accept(); - } } };