KiCad PCB EDA Suite
Loading...
Searching...
No Matches
spnav_viewer_plugin.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see CHANGELOG.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 3
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20#include "spnav_viewer_plugin.h"
21
24#include <wx/toplevel.h>
25#include <pgm_base.h>
27
29 : m_timer( this ), m_canvas( aCanvas ), m_camera( nullptr ), m_focused( true )
30{
31 m_camera = dynamic_cast<TRACK_BALL*>( aCanvas->GetCamera() );
32 m_driver = std::make_unique<LIBSPNAV_DRIVER>();
33
34 if( m_driver->Connect() )
35 {
36 m_driver->SetHandler( this );
37 Bind( wxEVT_TIMER, &SPNAV_VIEWER_PLUGIN::onPollTimer, this );
38 m_timer.Start( 10 );
39 }
40}
41
43{
44 m_timer.Stop();
45
46 if( m_driver )
47 m_driver->Disconnect();
48}
49
51{
52 m_focused = aFocus;
53}
54
56{
57 if( !m_driver || !m_focused )
58 return;
59
60 wxTopLevelWindow* topLevel = m_canvas
61 ? dynamic_cast<wxTopLevelWindow*>( wxGetTopLevelParent( m_canvas ) )
62 : nullptr;
63
64 // The Linux spnav backend drains a process-global event queue. Guard polling
65 // with the top-level window activation state so a stale focus latch cannot let
66 // an inactive editor keep consuming SpaceMouse events after another editor opens.
67 if( !topLevel || topLevel->IsActive() )
68 m_driver->Poll();
69}
70
71void SPNAV_VIEWER_PLUGIN::OnPan( double x, double y, double z )
72{
73 if( const COMMON_SETTINGS* cfg = Pgm().GetCommonSettings() )
74 {
75 float scale = 0.0005f * ( cfg->m_SpaceMouse.pan_speed / 5.0f );
76
77 if( cfg->m_SpaceMouse.reverse_pan_x )
78 x = -x;
79
80 if( cfg->m_SpaceMouse.reverse_pan_y )
81 y = -y;
82
83 if( cfg->m_SpaceMouse.reverse_zoom )
84 z = -z;
85
86 if( m_camera )
87 {
88 m_camera->Pan( SFVEC3F( x * scale, z * scale, y * scale ) );
89 m_canvas->Request_refresh();
90 }
91 }
92}
93
94void SPNAV_VIEWER_PLUGIN::OnRotate( double rx, double ry, double rz )
95{
96 if( const COMMON_SETTINGS* cfg = Pgm().GetCommonSettings() )
97 {
98 float scale = 0.001f * ( cfg->m_SpaceMouse.rotate_speed / 20.0f );
99
100 if( cfg->m_SpaceMouse.reverse_rotate )
101 scale = -scale;
102
103 if( m_camera )
104 {
105 m_camera->RotateX( rx * scale );
106 m_camera->RotateY( rz * scale );
107 m_camera->RotateZ( ry * scale );
108 m_canvas->Request_refresh();
109 }
110 }
111}
112
113void SPNAV_VIEWER_PLUGIN::OnButton( int button, bool pressed )
114{
115 // Buttons are ignored for now
116 (void) button;
117 (void) pressed;
118}
Implement a canvas based on a wxGLCanvas.
CAMERA * GetCamera()
Get the canvas camera.
void SetFocus(bool aFocus=true)
void OnRotate(double rx, double ry, double rz) override
Handle rotational events.
std::unique_ptr< SPACENAV_DRIVER > m_driver
void OnPan(double x, double y, double z) override
Handle translation (pan) events.
void onPollTimer(wxTimerEvent &evt)
SPNAV_VIEWER_PLUGIN(EDA_3D_CANVAS *aCanvas)
void OnButton(int button, bool pressed) override
Handle button press/release events.
PGM_BASE & Pgm()
The global program "get" accessor.
see class PGM_BASE
const int scale
Declaration for a track ball camera.
glm::vec3 SFVEC3F
Definition xv3d_types.h:40