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, you may find one here:
20 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21 * or you may search the http://www.gnu.org website for the version 2 license,
22 * or you may write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 */
25
26#include <kiface_base.h>
27#include <kiplatform/ui.h>
29#include <pcb_base_edit_frame.h>
31#include <tool/tool_manager.h>
32#include <tools/pcb_actions.h>
35#include <pgm_base.h>
36#include <board.h>
38#include <drc/drc_engine.h>
39#include <tool/action_toolbar.h>
41#include <pcb_dimension.h>
43#include <footprint.h>
44#include <layer_pairs.h>
45#include <project.h>
53
54#include <widgets/kistatusbar.h>
56#include <id.h>
57
58
60 FRAME_T aFrameType, const wxString& aTitle,
61 const wxPoint& aPos, const wxSize& aSize, long aStyle,
62 const wxString& aFrameName ) :
63 PCB_BASE_FRAME( aKiway, aParent, aFrameType, aTitle, aPos, aSize, aStyle, aFrameName ),
64 m_undoRedoBlocked( false ),
65 m_selectionFilterPanel( nullptr ),
66 m_appearancePanel( nullptr ),
67 m_vertexEditorPane( nullptr ),
68 m_tabbedPanel( nullptr )
69{
70 m_SelLayerBox = nullptr;
71
72 // Do not register the idle event handler if we are running in headless mode.
73 if( !wxApp::GetGUIInstance() )
74 return;
75
76 Bind( wxEVT_IDLE,
77 [this]( wxIdleEvent& aEvent )
78 {
79 // Handle cursor adjustments. While we can get motion and key events through
80 // wxWidgets, we can't get modifier-key-up events.
81 if( m_toolManager )
82 {
84
85 if( selTool )
86 selTool->OnIdle( aEvent );
87 }
88 } );
89
90 Bind( wxEVT_SYS_COLOUR_CHANGED, wxSysColourChangedEventHandler( PCB_BASE_EDIT_FRAME::onDarkModeToggle ), this );
91
92 Pgm().GetBackgroundJobMonitor().RegisterStatusBar( static_cast<KISTATUSBAR*>( GetStatusBar() ) );
93}
94
95
97{
98 Unbind( wxEVT_SYS_COLOUR_CHANGED, wxSysColourChangedEventHandler( PCB_BASE_EDIT_FRAME::onDarkModeToggle ), this );
99
100 Pgm().GetBackgroundJobMonitor().UnregisterStatusBar( static_cast<KISTATUSBAR*>( GetStatusBar() ) );
102 GetCanvas()->GetView()->Clear();
103}
104
105
107{
109
110 // Close the project if we are standalone, so it gets cleaned up properly
111 if( mgr->IsProjectOpen() && Kiface().IsSingle() )
112 mgr->UnloadProject( &Prj(), false );
113}
114
115
116bool PCB_BASE_EDIT_FRAME::TryBefore( wxEvent& aEvent )
117{
118 static bool s_presetSwitcherShown = false;
119 static bool s_viewportSwitcherShown = false;
120
121 // wxWidgets generates no key events for the tab key when the ctrl key is held down. One
122 // way around this is to look at all events and inspect the keyboard state of the tab key.
123 // However, this runs into issues on some linux VMs where querying the keyboard state is
124 // very slow. Fortunately we only use ctrl-tab on Mac, so we implement this lovely hack:
125#ifdef __WXMAC__
126 if( wxGetKeyState( WXK_TAB ) )
127#else
128 if( ( aEvent.GetEventType() == wxEVT_CHAR || aEvent.GetEventType() == wxEVT_CHAR_HOOK )
129 && static_cast<wxKeyEvent&>( aEvent ).GetKeyCode() == WXK_TAB )
130#endif
131 {
132 if( !s_presetSwitcherShown && wxGetKeyState( PRESET_SWITCH_KEY ) )
133 {
134 if( m_appearancePanel && this->IsActive() )
135 {
136 const wxArrayString& mru = m_appearancePanel->GetLayerPresetsMRU();
137
138 if( mru.size() > 0 )
139 {
140 EDA_VIEW_SWITCHER switcher( this, mru, PRESET_SWITCH_KEY );
141
142 s_presetSwitcherShown = true;
143 const int switcherDialogRet = switcher.ShowModal();
144 s_presetSwitcherShown = false;
145
146 if( switcherDialogRet == wxID_OK )
147 {
148 int idx = switcher.GetSelection();
149
150 if( idx >= 0 && idx < (int) mru.size() )
151 m_appearancePanel->ApplyLayerPreset( mru[idx] );
152 }
153
154 return true;
155 }
156 }
157 }
158 else if( !s_viewportSwitcherShown && wxGetKeyState( VIEWPORT_SWITCH_KEY ) )
159 {
160 if( m_appearancePanel && this->IsActive() )
161 {
162 const wxArrayString& mru = m_appearancePanel->GetViewportsMRU();
163
164 if( mru.size() > 0 )
165 {
166 EDA_VIEW_SWITCHER switcher( this, mru, VIEWPORT_SWITCH_KEY );
167
168 s_viewportSwitcherShown = true;
169 const int switcherDialogRet = switcher.ShowModal();
170 s_viewportSwitcherShown = false;
171
172 if( switcherDialogRet == wxID_OK )
173 {
174 int idx = switcher.GetSelection();
175
176 if( idx >= 0 && idx < (int) mru.size() )
177 m_appearancePanel->ApplyViewport( mru[idx] );
178 }
179
180 return true;
181 }
182 }
183 }
184 }
185
186 return PCB_BASE_FRAME::TryBefore( aEvent );
187}
188
189
191{
192 // Return a default angle (90 degrees) used for rotate operations.
193 return ANGLE_90;
194}
195
196
203
204
206{
207 bool is_new_board = ( aBoard != m_pcb );
208
209 if( is_new_board )
210 {
211 if( m_toolManager )
213
214 wxCommandEvent e( EDA_EVT_BOARD_CHANGING );
215 ProcessEventLocally( e );
216
217 GetCanvas()->GetView()->Clear();
219 }
220
221 PCB_BASE_FRAME::SetBoard( aBoard, aReporter );
222
224
225 if( is_new_board )
226 {
228 bds.m_DRCEngine = std::make_shared<DRC_ENGINE>( aBoard, &bds );
229 }
230
231 // update the tool manager with the new board and its view.
232 if( m_toolManager )
233 {
234 GetCanvas()->DisplayBoard( aBoard, aReporter );
235
237 m_toolManager->SetEnvironment( aBoard, GetCanvas()->GetView(),
238 GetCanvas()->GetViewControls(), config(), this );
239
240 if( is_new_board )
242 }
243}
244
245
247{
249
250 if( BOARD* board = GetBoard() )
251 {
252 board->UpdateUserUnits( board, GetCanvas()->GetView() );
254 }
255
258}
259
260
262{
264
265 // Update the grid checkbox in the layer widget
267 m_appearancePanel->SetObjectVisible( LAYER_GRID, aVisible );
268}
269
270
272{
274 m_appearancePanel->SetObjectVisible( aLayer, aVisible );
275}
276
277
279{
281 return ::GetColorSettings( cfg ? cfg->m_ColorTheme : DEFAULT_THEME );
282}
283
284
286{
287 if( !GetBoard() )
288 return wxEmptyString;
289
290 wxFileName fn = GetBoard()->GetFileName();
292 return Prj().AbsolutePath( fn.GetFullName() );
293}
294
295
296void PCB_BASE_EDIT_FRAME::handleActivateEvent( wxActivateEvent& aEvent )
297{
299
300 // The text in the collapsible pane headers need to be updated
302 m_appearancePanel->RefreshCollapsiblePanes();
303}
304
305
306void PCB_BASE_EDIT_FRAME::onDarkModeToggle( wxSysColourChangedEvent& aEvent )
307{
309 m_appearancePanel->OnDarkModeToggle();
310
312
313 if( viewer )
314 viewer->OnDarkModeToggle();
315}
316
317
319{
320 if( !m_propertiesPanel )
321 return;
322
323 bool show = !m_propertiesPanel->IsShownOnScreen();
324
325 wxAuiPaneInfo& propertiesPaneInfo = m_auimgr.GetPane( PropertiesPaneName() );
326 propertiesPaneInfo.Show( show );
327
329
330 if( show )
331 {
332 SetAuiPaneSize( m_auimgr, propertiesPaneInfo,
333 settings->m_AuiPanels.properties_panel_width, -1 );
334 }
335 else
336 {
338 m_auimgr.Update();
339 }
340}
341
342
343void PCB_BASE_EDIT_FRAME::GetContextualTextVars( BOARD_ITEM* aSourceItem, const wxString& aCrossRef,
344 wxArrayString* aTokens )
345{
346 BOARD* board = aSourceItem->GetBoard();
347
348 if( !aCrossRef.IsEmpty() )
349 {
350 for( FOOTPRINT* candidate : board->Footprints() )
351 {
352 if( candidate->GetReference() == aCrossRef )
353 {
354 candidate->GetContextualTextVars( aTokens );
355 break;
356 }
357 }
358 }
359 else
360 {
361 board->GetContextualTextVars( aTokens );
362
363 if( FOOTPRINT* footprint = aSourceItem->GetParentFootprint() )
364 footprint->GetContextualTextVars( aTokens );
365 }
366}
367
368
370{
371 // Load the toolbar configuration and base controls
373
374 // Layer selector
375 auto layerSelectorFactory =
376 [this]( ACTION_TOOLBAR* aToolbar )
377 {
378 if( !m_SelLayerBox )
379 {
381 m_SelLayerBox->SetBoardFrame( this );
382 }
383
384 m_SelLayerBox->SetToolTip( _( "+/- to switch" ) );
385 m_SelLayerBox->Resync();
386
387 aToolbar->Add( m_SelLayerBox );
388
389 // UI update handler for the control
390 aToolbar->Bind( wxEVT_UPDATE_UI,
391 [this]( wxUpdateUIEvent& aEvent )
392 {
393 if( m_SelLayerBox->GetCount()
394 && ( m_SelLayerBox->GetLayerSelection() != GetActiveLayer() ) )
395 {
396 m_SelLayerBox->SetLayerSelection( GetActiveLayer() );
397 }
398 },
399 m_SelLayerBox->GetId() );
400
401 // Event handler to respond to the user interacting with the control
402 aToolbar->Bind( wxEVT_COMBOBOX,
403 [this]( wxCommandEvent& aEvent )
404 {
405 SetActiveLayer( ToLAYER_ID( m_SelLayerBox->GetLayerSelection() ) );
406
407 if( GetDisplayOptions().m_ContrastModeDisplay != HIGH_CONTRAST_MODE::NORMAL )
408 GetCanvas()->Refresh();
409 },
410 m_SelLayerBox->GetId() );
411 };
412
414}
415
416
418{
420
421 switch( aId )
422 {
423 case ID_ON_LAYER_SELECT: m_SelLayerBox = nullptr; break;
424 }
425}
426
427
429{
430 PCB_SELECTION_FILTER_EVENT evt( aOptions );
431 wxPostEvent( this, evt );
432}
433
435{
436 return wxS( "VertexEditor" );
437}
438
440{
441 if( !m_vertexEditorPane )
442 {
444
445 wxAuiPaneInfo paneInfo = EDA_PANE().Name( VertexEditorPaneName() )
446 .Float()
447 .Caption( _( "Edit Vertices" ) )
448 .PaneBorder( true )
449 .CloseButton( true )
450 .DestroyOnClose( true )
451 .Resizable( true )
452 .MinSize( FromDIP( wxSize( 260, 200 ) ) )
453 .BestSize( FromDIP( wxSize( 260, 320 ) ) )
454 .FloatingSize( FromDIP( wxSize( 320, 360 ) ) );
455
456 m_auimgr.AddPane( m_vertexEditorPane, paneInfo );
457 m_auimgr.Update();
458 }
459
460 m_vertexEditorPane->SetItem( aItem );
461 m_vertexEditorPane->SetFocus();
462}
463
469
471{
473 m_vertexEditorPane->OnSelectionChanged( aItem );
474}
475
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:322
void GetContextualTextVars(wxArrayString *aVars) const
Definition board.cpp:475
const FOOTPRINTS & Footprints() const
Definition board.h:363
const wxString & GetFileName() const
Definition board.h:359
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition board.cpp:1083
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 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 items were moved, this can be very high frequency on the canvas, use with care.
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:1151
void InitPreview()
Definition view.cpp:1765
A minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the same KiCad...
Definition kiway.h:295
AUI_PANELS m_AuiPanels
COLOR_SETTINGS * GetColorSettings(bool aForceRefresh=false) const override
Helper to retrieve the current color settings.
wxString GetDesignRulesPath()
Return the absolute path to the design rules file for the currently-loaded board.
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
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
Set the #m_Pcb member in such as way as to ensure deleting any previous BOARD.
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 #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:137
A progress reporter interface for use in multi-threaded environments.
virtual const wxString AbsolutePath(const wxString &aFileName) const
Fix up aFileName if it is relative to the project's directory to be an absolute path and filename.
Definition project.cpp:401
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
@ MODEL_RELOAD
Model changes (the sheet for a schematic)
Definition tool_base.h:80
#define _(s)
Declaration of the eda_3d_viewer class.
static constexpr EDA_ANGLE ANGLE_90
Definition eda_angle.h:413
#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:33
static const std::string DesignRulesFileExtension
@ ID_ON_LAYER_SELECT
Definition id.h:118
PROJECT & Prj()
Definition kicad.cpp:642
GAL_LAYER_ID
GAL layers are "virtual" layers, i.e.
Definition layer_ids.h:228
@ LAYER_GRID
Definition layer_ids.h:254
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition lset.cpp:754
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:694
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.