Support touchscreen gestures (zoom/pan/rotate) in 3D viewer.

Though rotate doesn't work yet on MSW due to a wxWidgets bug.
This commit is contained in:
Alex Shvartzkop 2024-06-08 21:13:01 +03:00
parent ed0869aa0c
commit 4b96bb5d8f
4 changed files with 97 additions and 0 deletions

View File

@ -73,6 +73,11 @@ BEGIN_EVENT_TABLE( EDA_3D_CANVAS, HIDPI_GL_3D_CANVAS )
EVT_MOTION( EDA_3D_CANVAS::OnMouseMove )
EVT_MAGNIFY( EDA_3D_CANVAS::OnMagnify )
// touch gesture events
EVT_GESTURE_ZOOM( wxID_ANY, EDA_3D_CANVAS::OnZoomGesture )
EVT_GESTURE_PAN( wxID_ANY, EDA_3D_CANVAS::OnPanGesture )
EVT_GESTURE_ROTATE( wxID_ANY, EDA_3D_CANVAS::OnRotateGesture )
// other events
EVT_ERASE_BACKGROUND( EDA_3D_CANVAS::OnEraseBackground )
EVT_CUSTOM(wxEVT_REFRESH_CUSTOM_COMMAND, ID_CUSTOM_EVENT_1, EDA_3D_CANVAS::OnRefreshRequest )
@ -144,6 +149,8 @@ EDA_3D_CANVAS::EDA_3D_CANVAS( wxWindow* aParent, const wxGLAttributes& aGLAttrib
wxASSERT( a3DCachePointer != nullptr );
m_boardAdapter.Set3dCacheManager( a3DCachePointer );
EnableTouchEvents( wxTOUCH_ZOOM_GESTURE | wxTOUCH_PAN_GESTURES | wxTOUCH_ROTATE_GESTURE );
const wxEventType events[] =
{
// Binding both EVT_CHAR and EVT_CHAR_HOOK ensures that all key events,
@ -631,6 +638,75 @@ void EDA_3D_CANVAS::OnMagnify( wxMouseEvent& event )
}
void EDA_3D_CANVAS::OnZoomGesture( wxZoomGestureEvent& aEvent )
{
SetFocus();
if( aEvent.IsGestureStart() )
{
m_gestureLastZoomFactor = 1.0;
m_camera.SetCurMousePosition( aEvent.GetPosition() );
}
if( m_camera_is_moving )
return;
restart_editingTimeOut_Timer();
m_camera.Pan( aEvent.GetPosition() );
m_camera.SetCurMousePosition( aEvent.GetPosition() );
m_camera.Zoom( aEvent.GetZoomFactor() / m_gestureLastZoomFactor );
m_gestureLastZoomFactor = aEvent.GetZoomFactor();
DisplayStatus();
Request_refresh();
}
void EDA_3D_CANVAS::OnPanGesture( wxPanGestureEvent& aEvent )
{
SetFocus();
if( aEvent.IsGestureStart() )
m_camera.SetCurMousePosition( aEvent.GetPosition() );
if( m_camera_is_moving )
return;
m_camera.Pan( aEvent.GetPosition() );
m_camera.SetCurMousePosition( aEvent.GetPosition() );
DisplayStatus();
Request_refresh();
}
void EDA_3D_CANVAS::OnRotateGesture( wxRotateGestureEvent& aEvent )
{
SetFocus();
if( aEvent.IsGestureStart() )
{
m_gestureLastAngle = 0;
m_camera.SetCurMousePosition( aEvent.GetPosition() );
// We don't want to process the first angle
return;
}
if( m_camera_is_moving )
return;
m_camera.RotateScreen( m_gestureLastAngle - aEvent.GetRotationAngle() );
m_gestureLastAngle = aEvent.GetRotationAngle();
DisplayStatus();
Request_refresh();
}
void EDA_3D_CANVAS::OnMouseMove( wxMouseEvent& event )
{
if( m_3d_render && m_3d_render->IsReloadRequestPending() )

View File

@ -237,6 +237,10 @@ private:
void OnResize( wxSizeEvent& event );
void OnTimerTimeout_Redraw( wxTimerEvent& event );
void OnZoomGesture( wxZoomGestureEvent& event );
void OnPanGesture( wxPanGestureEvent& event );
void OnRotateGesture( wxRotateGestureEvent& event );
DECLARE_EVENT_TABLE()
/**
@ -324,6 +328,10 @@ private:
bool m_render3dmousePivot = false; // Render the 3dmouse pivot
SFVEC3F m_3dmousePivotPos; // The position of the 3dmouse pivot
///< Used to track gesture events.
double m_gestureLastZoomFactor = 1.0;
double m_gestureLastAngle = 0.0;
/**
* Trace mask used to enable or disable the trace output of this class.
* The debug output can be turned on by setting the WXTRACE environment variable to

View File

@ -647,6 +647,14 @@ bool CAMERA::Zoom_T1( float aFactor )
}
void CAMERA::RotateScreen( float aAngleInRadians )
{
glm::mat4 matrix = GetRotationMatrix();
SetRotationMatrix( glm::rotate( matrix, aAngleInRadians, GetDir() ) );
updateRotationMatrix();
}
void CAMERA::RotateX( float aAngleInRadians )
{
m_rotate_aux.x += aAngleInRadians;

View File

@ -236,6 +236,11 @@ public:
bool ViewCommand_T1( VIEW3D_TYPE aRequestedView );
/**
* Rotates the camera in screen plane.
*/
void RotateScreen( float aAngleInRadians );
void RotateX( float aAngleInRadians );
void RotateY( float aAngleInRadians );
void RotateZ( float aAngleInRadians );