KiCad PCB EDA Suite
Loading...
Searching...
No Matches
spnav_2d_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_2d_plugin.h"
21
24#include <view/view.h>
26
27#include <wx/log.h>
28#include <wx/toplevel.h>
29#include <pgm_base.h>
31
32
34 : m_timer( this ), m_canvas( aCanvas ), m_focused( true )
35{
36 m_driver = std::make_unique<LIBSPNAV_DRIVER>();
37 m_view = aCanvas->GetView();
38 m_scale = 1.0;
39
40 if( m_driver->Connect() )
41 {
42 m_driver->SetHandler( this );
43 Bind( wxEVT_TIMER, &SPNAV_2D_PLUGIN::onPollTimer, this );
44 m_timer.Start( 10 );
45 }
46}
47
49{
50 m_timer.Stop();
51
52 if( m_driver )
53 m_driver->Disconnect();
54}
55
56void SPNAV_2D_PLUGIN::SetFocus( bool aFocus )
57{
58 m_focused = aFocus;
59}
60
62{
63 m_canvas = aCanvas;
64 m_view = aCanvas->GetView();
65}
66
67void SPNAV_2D_PLUGIN::onPollTimer( wxTimerEvent& )
68{
69 if( !m_driver || !m_focused )
70 return;
71
72 wxTopLevelWindow* topLevel = m_canvas
73 ? dynamic_cast<wxTopLevelWindow*>( wxGetTopLevelParent( m_canvas ) )
74 : nullptr;
75
76 // The Linux spnav backend drains a process-global event queue. Guard polling
77 // with the top-level window activation state so a stale focus latch cannot let
78 // an inactive editor keep consuming SpaceMouse events after another editor opens.
79 if( !topLevel || topLevel->IsActive() )
80 m_driver->Poll();
81}
82
83void SPNAV_2D_PLUGIN::OnPan( double x, double y, double z )
84{
85 const COMMON_SETTINGS* cfg = Pgm().GetCommonSettings();
86 double panFactor = cfg->m_SpaceMouse.pan_speed / 5.0;
87
88 wxLogTrace( "spacenav", "OnPan: x=%f, y=%f, z=%f", x, y, z );
89
90 if( !m_view )
91 return;
92
93 if( std::fabs( x ) > std::numeric_limits<double>::epsilon() ||
94 std::fabs( y ) > std::numeric_limits<double>::epsilon() ||
95 std::fabs( z ) > std::numeric_limits<double>::epsilon() )
96 {
97 double tx = x * panFactor;
98 double tz = z * panFactor;
99
100 if( cfg->m_SpaceMouse.reverse_pan_x )
101 tx = -tx;
102
103 if( cfg->m_SpaceMouse.reverse_pan_y )
104 tz = -tz;
105
106 VECTOR2D viewPos = m_view->GetCenter();
107 viewPos += m_view->ToWorld( VECTOR2D( tx, -tz ), false ) / 40.0;
108 m_view->SetCenter( viewPos );
109
110 double zoom = y * panFactor;
111
112 if( cfg->m_SpaceMouse.reverse_zoom )
113 zoom = -zoom;
114
115 double current_pixels = m_canvas->GetClientSize().GetWidth();
116 double current_scale = m_view->GetScale();
117 double desired_pixels = current_pixels + zoom / 10.0;
118
119 if( desired_pixels < 1 )
120 desired_pixels = 1;
121
122 double new_scale = current_scale * ( current_pixels / desired_pixels);
123
124 m_view->SetScale( new_scale, viewPos );
125
126 wxMouseEvent moveEvent( KIGFX::WX_VIEW_CONTROLS::EVT_REFRESH_MOUSE );
127 VECTOR2D msp = m_canvas->GetViewControls()->GetMousePosition( false );
128 moveEvent.SetX( msp.x );
129 moveEvent.SetY( msp.y );
130
131 m_canvas->RequestRefresh();
132 wxPostEvent( m_canvas, moveEvent );
133 }
134
135}
136
137void SPNAV_2D_PLUGIN::OnRotate( double rx, double ry, double rz )
138{
139 //Ignore the rotation
140}
141
142void SPNAV_2D_PLUGIN::OnButton( int button, bool pressed )
143{
144 // Buttons are ignored for now
145 (void) button;
146 (void) pressed;
147}
SPACEMOUSE m_SpaceMouse
virtual KIGFX::VIEW * GetView() const
Return a pointer to the #VIEW instance used in the panel.
static const wxEventType EVT_REFRESH_MOUSE
Event that forces mouse move event in the dispatcher (eg.
virtual COMMON_SETTINGS * GetCommonSettings() const
Definition pgm_base.cpp:553
KIGFX::VIEW * m_view
void SetFocus(bool aFocus=true)
void onPollTimer(wxTimerEvent &evt)
void SetCanvas(EDA_DRAW_PANEL_GAL *aCanvas)
std::unique_ptr< SPACENAV_DRIVER > m_driver
void OnButton(int button, bool pressed) override
Handle button press/release events.
EDA_DRAW_PANEL_GAL * m_canvas
SPNAV_2D_PLUGIN(EDA_DRAW_PANEL_GAL *aCanvas)
void OnPan(double x, double y, double z) override
Handle translation (pan) events.
void OnRotate(double rx, double ry, double rz) override
Handle rotational events.
PGM_BASE & Pgm()
The global program "get" accessor.
see class PGM_BASE
VECTOR2< double > VECTOR2D
Definition vector2d.h:682
WX_VIEW_CONTROLS class definition.