KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pcb_base_edit_frame.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 (C) 2014 CERN
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 * @author Maciej Suminski <[email protected]>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
22#include <kiface_base.h>
23#include <kiplatform/ui.h>
25#include <pcb_base_edit_frame.h>
27#include <tool/tool_manager.h>
28#include <tools/pcb_actions.h>
31#include <pgm_base.h>
32#include <board.h>
34#include <drc/drc_engine.h>
35#include <tool/action_toolbar.h>
37#include <pcb_dimension.h>
39#include <footprint.h>
40#include <layer_pairs.h>
41#include <project.h>
49
50#include <widgets/kistatusbar.h>
52#include <id.h>
53
54
56 FRAME_T aFrameType, const wxString& aTitle,
57 const wxPoint& aPos, const wxSize& aSize, long aStyle,
58 const wxString& aFrameName ) :
59 PCB_BASE_FRAME( aKiway, aParent, aFrameType, aTitle, aPos, aSize, aStyle, aFrameName ),
60 m_undoRedoBlocked( false ),
61 m_selectionFilterPanel( nullptr ),
62 m_appearancePanel( nullptr ),
63 m_vertexEditorPane( nullptr ),
64 m_tabbedPanel( nullptr )
65{
66 m_SelLayerBox = nullptr;
67
68 // Do not register the idle event handler if we are running in headless mode.
69 if( !wxApp::GetGUIInstance() )
70 return;
71
72 Bind( wxEVT_IDLE,
73 [this]( wxIdleEvent& aEvent )
74 {
75 // Handle cursor adjustments. While we can get motion and key events through
76 // wxWidgets, we can't get modifier-key-up events.
77 if( m_toolManager )
78 {
80
81 if( selTool )
82 selTool->OnIdle( aEvent );
83 }
84 } );
85
86 Bind( wxEVT_SYS_COLOUR_CHANGED, wxSysColourChangedEventHandler( PCB_BASE_EDIT_FRAME::onDarkModeToggle ), this );
87
88 Pgm().GetBackgroundJobMonitor().RegisterStatusBar( static_cast<KISTATUSBAR*>( GetStatusBar() ) );
89}
90
91
93{
94 Unbind( wxEVT_SYS_COLOUR_CHANGED, wxSysColourChangedEventHandler( PCB_BASE_EDIT_FRAME::onDarkModeToggle ), this );
95
96 Pgm().GetBackgroundJobMonitor().UnregisterStatusBar( static_cast<KISTATUSBAR*>( GetStatusBar() ) );
98 GetCanvas()->GetView()->Clear();
99}
100
101
103{
105
106 // Close the project if we are standalone, so it gets cleaned up properly
107 if( mgr->IsProjectOpen() && Kiface().IsSingle() )
108 mgr->UnloadProject( &Prj(), false );
109}
110
111
112bool PCB_BASE_EDIT_FRAME::TryBefore( wxEvent& aEvent )
113{
114 static bool s_presetSwitcherShown = false;
115 static bool s_viewportSwitcherShown = false;
116
117 // wxWidgets generates no key events for the tab key when the ctrl key is held down. One
118 // way around this is to look at all events and inspect the keyboard state of the tab key.
119 // However, this runs into issues on some linux VMs where querying the keyboard state is
120 // very slow. Fortunately we only use ctrl-tab on Mac, so we implement this lovely hack:
121#ifdef __WXMAC__
122 if( wxGetKeyState( WXK_TAB ) )
123#else
124 if( ( aEvent.GetEventType() == wxEVT_CHAR || aEvent.GetEventType() == wxEVT_CHAR_HOOK )
125 && static_cast<wxKeyEvent&>( aEvent ).GetKeyCode() == WXK_TAB )
126#endif
127 {
128 if( !s_presetSwitcherShown && wxGetKeyState( PRESET_SWITCH_KEY ) )
129 {
130 if( m_appearancePanel && this->IsActive() )
131 {
132 const wxArrayString& mru = m_appearancePanel->GetLayerPresetsMRU();
133
134 if( mru.size() > 0 )
135 {
136 EDA_VIEW_SWITCHER switcher( this, mru, PRESET_SWITCH_KEY );
137
138 s_presetSwitcherShown = true;
139 const int switcherDialogRet = switcher.ShowModal();
140 s_presetSwitcherShown = false;
141
142 if( switcherDialogRet == wxID_OK )
143 {
144 int idx = switcher.GetSelection();
145
146 if( idx >= 0 && idx < (int) mru.size() )
147 m_appearancePanel->ApplyLayerPreset( mru[idx] );
148 }
149
150 return true;
151 }
152 }
153 }
154 else if( !s_viewportSwitcherShown && wxGetKeyState( VIEWPORT_SWITCH_KEY ) )
155 {
156 if( m_appearancePanel && this->IsActive() )
157 {
158 const wxArrayString& mru = m_appearancePanel->GetViewportsMRU();
159
160 if( mru.size() > 0 )
161 {
162 EDA_VIEW_SWITCHER switcher( this, mru, VIEWPORT_SWITCH_KEY );
163
164 s_viewportSwitcherShown = true;
165 const int switcherDialogRet = switcher.ShowModal();
166 s_viewportSwitcherShown = false;
167
168 if( switcherDialogRet == wxID_OK )
169 {
170 int idx = switcher.GetSelection();
171
172 if( idx >= 0 && idx < (int) mru.size() )
173 m_appearancePanel->ApplyViewport( mru[idx] );
174 }
175
176 return true;
177 }
178 }
179 }
180 }
181
182 return PCB_BASE_FRAME::TryBefore( aEvent );
183}
184
185
187{
188 // Return a default angle (90 degrees) used for rotate operations.
189 return ANGLE_90;
190}
191
192
199
200
202{
203 bool is_new_board = ( aBoard != m_pcb );
204
205 if( is_new_board )
206 {
207 if( m_toolManager )
209
210 wxCommandEvent e( EDA_EVT_BOARD_CHANGING );
211 ProcessEventLocally( e );
212
213 GetCanvas()->GetView()->Clear();
215 }
216
217 PCB_BASE_FRAME::SetBoard( aBoard, aReporter );
218
220
221 if( is_new_board )
222 {
224 bds.m_DRCEngine = std::make_shared<DRC_ENGINE>( aBoard, &bds );
225 }
226
227 // update the tool manager with the new board and its view.
228 if( m_toolManager )
229 {
230 GetCanvas()->DisplayBoard( aBoard, aReporter );
231
233 m_toolManager->SetEnvironment( aBoard, GetCanvas()->GetView(),
234 GetCanvas()->GetViewControls(), config(), this );
235
236 if( is_new_board )
238 }
239}
240
241
246
247
249{
251
252 if( BOARD* board = GetBoard() )
253 {
254 board->UpdateUserUnits( board, GetCanvas()->GetView() );
256 }
257
260}
261
262
264{
266
267 // Update the grid checkbox in the layer widget
269 m_appearancePanel->SetObjectVisible( LAYER_GRID, aVisible );
270}
271
272
274{
276 m_appearancePanel->SetObjectVisible( aLayer, aVisible );
277}
278
279
281{
283 return ::GetColorSettings( cfg ? cfg->m_ColorTheme : DEFAULT_THEME );
284}
285
286
287void PCB_BASE_EDIT_FRAME::handleActivateEvent( wxActivateEvent& aEvent )
288{
290
291 // The text in the collapsible pane headers need to be updated
293 m_appearancePanel->RefreshCollapsiblePanes();
294}
295
296
297void PCB_BASE_EDIT_FRAME::onDarkModeToggle( wxSysColourChangedEvent& aEvent )
298{
300 m_appearancePanel->OnDarkModeToggle();
301
303
304 if( viewer )
305 viewer->OnDarkModeToggle();
306}
307
308
310{
311 if( !m_propertiesPanel )
312 return;
313
314 bool show = !m_propertiesPanel->IsShownOnScreen();
315
316 wxAuiPaneInfo& propertiesPaneInfo = m_auimgr.GetPane( PropertiesPaneName() );
317 propertiesPaneInfo.Show( show );
318
320
321 if( show )
322 {
323 SetAuiPaneSize( m_auimgr, propertiesPaneInfo,
324 settings->m_AuiPanels.properties_panel_width, -1 );
325 }
326 else
327 {
329 m_auimgr.Update();
330 }
331}
332
333
334void PCB_BASE_EDIT_FRAME::GetContextualTextVars( BOARD_ITEM* aSourceItem, const wxString& aCrossRef,
335 wxArrayString* aTokens )
336{
337 BOARD* board = aSourceItem->GetBoard();
338
339 if( !aCrossRef.IsEmpty() )
340 {
341 for( FOOTPRINT* candidate : board->Footprints() )
342 {
343 if( candidate->GetReference() == aCrossRef )
344 {
345 candidate->GetContextualTextVars( aTokens );
346 break;
347 }
348 }
349 }
350 else
351 {
352 board->GetContextualTextVars( aTokens );
353
354 if( FOOTPRINT* footprint = aSourceItem->GetParentFootprint() )
355 footprint->GetContextualTextVars( aTokens );
356 }
357}
358
359
361{
362 // Load the toolbar configuration and base controls
364
365 // Layer selector
366 auto layerSelectorFactory =
367 [this]( ACTION_TOOLBAR* aToolbar )
368 {
369 if( !m_SelLayerBox )
370 {
372 m_SelLayerBox->SetBoardFrame( this );
373 }
374
375 m_SelLayerBox->SetToolTip( _( "+/- to switch" ) );
376 m_SelLayerBox->Resync();
377
378 aToolbar->Add( m_SelLayerBox );
379
380 // UI update handler for the control
381 aToolbar->Bind( wxEVT_UPDATE_UI,
382 [this]( wxUpdateUIEvent& aEvent )
383 {
384 if( m_SelLayerBox->GetCount()
385 && ( m_SelLayerBox->GetLayerSelection() != GetActiveLayer() ) )
386 {
387 m_SelLayerBox->SetLayerSelection( GetActiveLayer() );
388 }
389 },
390 m_SelLayerBox->GetId() );
391
392 // Event handler to respond to the user interacting with the control
393 aToolbar->Bind( wxEVT_COMBOBOX,
394 [this]( wxCommandEvent& aEvent )
395 {
396 SetActiveLayer( ToLAYER_ID( m_SelLayerBox->GetLayerSelection() ) );
397
398 if( GetDisplayOptions().m_ContrastModeDisplay != HIGH_CONTRAST_MODE::NORMAL )
399 GetCanvas()->Refresh();
400 },
401 m_SelLayerBox->GetId() );
402 };
403
405}
406
407
409{
411
412 switch( aId )
413 {
414 case ID_ON_LAYER_SELECT: m_SelLayerBox = nullptr; break;
415 }
416}
417
418
420{
421 PCB_SELECTION_FILTER_EVENT evt( aOptions );
422 wxPostEvent( this, evt );
423}
424
426{
427 return wxS( "VertexEditor" );
428}
429
431{
432 if( !m_vertexEditorPane )
433 {
435
436 wxAuiPaneInfo paneInfo = EDA_PANE().Name( VertexEditorPaneName() )
437 .Float()
438 .Caption( _( "Edit Vertices" ) )
439 .PaneBorder( true )
440 .CloseButton( true )
441 .DestroyOnClose( true )
442 .Resizable( true )
443 .MinSize( FromDIP( wxSize( 260, 200 ) ) )
444 .BestSize( FromDIP( wxSize( 260, 320 ) ) )
445 .FloatingSize( FromDIP( wxSize( 320, 360 ) ) );
446
447 m_auimgr.AddPane( m_vertexEditorPane, paneInfo );
448 m_auimgr.Update();
449 }
450
451 m_vertexEditorPane->SetItem( aItem );
452 m_vertexEditorPane->SetFocus();
453}
454
460
462{
464 m_vertexEditorPane->OnSelectionChanged( aItem );
465}
466
ARC_DRAW_MODE
Construction sequence used when interactively drawing a circular arc.
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
@ NORMAL
Inactive layers are shown normally (no high-contrast mode)
static ACTION_TOOLBAR_CONTROL layerSelector
Define the structure of a toolbar with buttons that invoke ACTIONs.
wxString m_ColorTheme
Active color theme name.
void UnregisterStatusBar(KISTATUSBAR *aStatusBar)
Removes status bar from handling.
void RegisterStatusBar(KISTATUSBAR *aStatusBar)
Add a status bar for handling.
Container for design settings for a BOARD object.
std::shared_ptr< DRC_ENGINE > m_DRCEngine
const VECTOR2I & GetGridOrigin() const
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition board_item.h:84
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
FOOTPRINT * GetParentFootprint() const
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:410
void GetContextualTextVars(wxArrayString *aVars) const
Definition board.cpp:657
const FOOTPRINTS & Footprints() const
Definition board.h:464
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition board.cpp:1301
Color settings are a bit different than most of the settings objects in that there can be more than o...
int ShowModal() override
Create and handle a window for the 3d viewer connected to a Kiway and a pcbboard.
virtual APP_SETTINGS_BASE * config() const
Return the settings object used in SaveSettings(), and is overloaded in KICAD_MANAGER_FRAME.
virtual void ClearToolbarControl(int aId)
SETTINGS_MANAGER * GetSettingsManager() const
void RegisterCustomToolbarControlFactory(const ACTION_TOOLBAR_CONTROL &aControlDesc, const ACTION_TOOLBAR_CONTROL_FACTORY &aControlFactory)
Register a creation factory for toolbar controls that are present in this frame.
virtual void configureToolbars()
wxAuiManager m_auimgr
static const wxString PropertiesPaneName()
virtual void ReCreateAuxiliaryToolbar()
virtual void SetGridVisibility(bool aVisible)
PROPERTIES_PANEL * m_propertiesPanel
virtual void UpdateProperties()
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=nullptr) override
KIGFX::GAL * GetGAL() const
Return a pointer to the GAL instance used in the panel.
Specialization of the wxAuiPaneInfo class for KiCad panels.
static const TOOL_EVENT SelectedItemsModified
Selected item had a property changed (except movement)
Definition actions.h:352
void SetGridOrigin(const VECTOR2D &aGridOrigin)
Set the origin point for the grid.
void Clear()
Remove all items from the view.
Definition view.cpp:1262
void InitPreview()
Definition view.cpp:1930
KISTATUSBAR is a wxStatusBar suitable for Kicad manager.
Definition kistatusbar.h:50
A minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the same KiCad...
Definition kiway.h:348
AUI_PANELS m_AuiPanels
static const TOOL_ACTION & DrawArcForMode(ARC_DRAW_MODE aMode)
Tool action that starts the arc tool in the given mode.
const TOOL_ACTION * drawArcAction(ARC_DRAW_MODE aMode) const override
The action that starts the arc tool in aMode, or nullptr in a frame without an arc tool.
COLOR_SETTINGS * GetColorSettings(bool aForceRefresh=false) const override
Helper to retrieve the current color settings.
void SetGridVisibility(bool aVisible) override
Override this function in the PCB_BASE_EDIT_FRAME to refill the layer widget.
virtual EDA_ANGLE GetRotationAngle() const
Return the angle used for rotate operations.
void unitsChangeRefresh() override
Called when when the units setting has changed to allow for any derived classes to handle refreshing ...
void OpenVertexEditor(BOARD_ITEM *aItem)
bool TryBefore(wxEvent &aEvent) override
static wxString VertexEditorPaneName()
PCB_LAYER_BOX_SELECTOR * m_SelLayerBox
virtual void SetBoard(BOARD *aBoard, PROGRESS_REPORTER *aReporter=nullptr) override
Set the m_pcb member in such as way as to ensure deleting any previous BOARD.
void ToggleProperties() override
void configureToolbars() override
void ClearToolbarControl(int aId) override
PCB_BASE_EDIT_FRAME(KIWAY *aKiway, wxWindow *aParent, FRAME_T aFrameType, const wxString &aTitle, const wxPoint &aPos, const wxSize &aSize, long aStyle, const wxString &aFrameName)
void HighlightSelectionFilter(const PCB_SELECTION_FILTER_OPTIONS &aOptions)
APPEARANCE_CONTROLS * m_appearancePanel
wxAuiNotebook * m_tabbedPanel
Panel with Layers and Object Inspector tabs.
void SetObjectVisible(GAL_LAYER_ID aLayer, bool aVisible=true)
PANEL_SELECTION_FILTER * m_selectionFilterPanel
void GetContextualTextVars(BOARD_ITEM *aSourceItem, const wxString &aCrossRef, wxArrayString *aTokens)
void handleActivateEvent(wxActivateEvent &aEvent) override
Handle a window activation event.
PCB_VERTEX_EDITOR_PANE * m_vertexEditorPane
void UpdateVertexEditorSelection(BOARD_ITEM *aItem)
void onDarkModeToggle(wxSysColourChangedEvent &aEvent)
void ActivateGalCanvas() override
Use to start up the GAL drawing canvas.
void OnVertexEditorPaneClosed(PCB_VERTEX_EDITOR_PANE *aPane)
const PCB_DISPLAY_OPTIONS & GetDisplayOptions() const
Display options control the way tracks, vias, outlines and other things are shown (for instance solid...
void handleActivateEvent(wxActivateEvent &aEvent) override
Handle a window activation event.
virtual void unitsChangeRefresh() override
Called when when the units setting has changed to allow for any derived classes to handle refreshing ...
PCBNEW_SETTINGS * GetPcbNewSettings() const
PCB_BASE_FRAME(KIWAY *aKiway, wxWindow *aParent, FRAME_T aFrameType, const wxString &aTitle, const wxPoint &aPos, const wxSize &aSize, long aStyle, const wxString &aFrameName)
virtual void SetActiveLayer(PCB_LAYER_ID aLayer)
PCB_DRAW_PANEL_GAL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
virtual void ActivateGalCanvas() override
Use to start up the GAL drawing canvas.
virtual void SetBoard(BOARD *aBoard, PROGRESS_REPORTER *aReporter=nullptr)
Set the m_pcb member in such as way as to ensure deleting any previous BOARD.
virtual PCB_LAYER_ID GetActiveLayer() const
BOARD * GetBoard() const
EDA_3D_VIEWER_FRAME * Get3DViewerFrame()
void UpdateColors()
Update the color settings in the painter and GAL.
virtual KIGFX::PCB_VIEW * GetView() const override
Return a pointer to the KIGFX::VIEW instance used in the panel.
void DisplayBoard(BOARD *aBoard, PROGRESS_REPORTER *aReporter=nullptr)
Add all items from the current board to the VIEW, so they can be displayed by GAL.
void SyncLayersVisibility(const BOARD *aBoard)
Update "visibility" property of each layer of a given BOARD.
Class to display a pcb layer list in a wxBitmapComboBox.
The selection tool: currently supports:
void OnIdle(wxIdleEvent &aEvent)
virtual BACKGROUND_JOBS_MONITOR & GetBackgroundJobMonitor() const
Definition pgm_base.h:129
A progress reporter interface for use in multi-threaded environments.
bool IsProjectOpen() const
Helper for checking if we have a project open.
bool UnloadProject(PROJECT *aProject, bool aSave=true)
Save, unload and unregister the given PROJECT.
TOOL_MANAGER * m_toolManager
Represent a single user action.
@ MODEL_RELOAD
Model changes (the sheet for a schematic)
Definition tool_base.h:76
#define _(s)
Declaration of the eda_3d_viewer class.
static constexpr EDA_ANGLE ANGLE_90
Definition eda_angle.h:450
#define VIEWPORT_SWITCH_KEY
#define PRESET_SWITCH_KEY
FRAME_T
The set of EDA_BASE_FRAME derivatives, typically stored in EDA_BASE_FRAME::m_Ident.
Definition frame_type.h:29
@ ID_ON_LAYER_SELECT
Definition id.h:115
PROJECT & Prj()
Definition kicad.cpp:733
GAL_LAYER_ID
GAL layers are "virtual" layers, i.e.
Definition layer_ids.h:224
@ LAYER_GRID
Definition layer_ids.h:250
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition lset.cpp:750
PGM_BASE & Pgm()
The global program "get" accessor.
see class PGM_BASE
#define DEFAULT_THEME
This file contains data structures that are saved in the project file or project local settings file ...
VECTOR2< double > VECTOR2D
Definition vector2d.h:707
Definition of file extensions used in Kicad.
void SetAuiPaneSize(wxAuiManager &aManager, wxAuiPaneInfo &aPane, int aWidth, int aHeight)
Sets the size of an AUI pane, working around http://trac.wxwidgets.org/ticket/13180.