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>
28#include <pcb_base_edit_frame.h>
30#include <tool/tool_manager.h>
31#include <tools/pcb_actions.h>
34#include <pgm_base.h>
35#include <board.h>
38#include <pcb_dimension.h>
40#include <footprint.h>
41#include <footprint_info_impl.h>
42#include <layer_pairs.h>
43#include <project.h>
51
52
54 FRAME_T aFrameType, const wxString& aTitle,
55 const wxPoint& aPos, const wxSize& aSize, long aStyle,
56 const wxString& aFrameName ) :
57 PCB_BASE_FRAME( aKiway, aParent, aFrameType, aTitle, aPos, aSize, aStyle, aFrameName ),
58 m_undoRedoBlocked( false ),
59 m_selectionFilterPanel( nullptr ),
60 m_appearancePanel( nullptr ),
61 m_tabbedPanel( nullptr )
62{
63 m_SelLayerBox = nullptr;
65
66 // Do not register the idle event handler if we are running in headless mode.
67 if( !wxApp::GetGUIInstance() )
68 return;
69
70 Bind( wxEVT_IDLE,
71 [this]( wxIdleEvent& aEvent )
72 {
73 // Handle cursor adjustments. While we can get motion and key events through
74 // wxWidgets, we can't get modifier-key-up events.
75 if( m_toolManager )
76 {
78
79 if( selTool )
80 selTool->OnIdle( aEvent );
81 }
82
84 {
87 }
88 } );
89}
90
91
96
97
99{
101 wxFileName projectName( Prj().GetProjectFullName() );
102
103 if( mgr->IsProjectOpen() && wxFileName::IsDirWritable( projectName.GetPath() )
104 && projectName.Exists() )
105 {
106 GFootprintList.WriteCacheToFile( Prj().GetProjectPath() + wxT( "fp-info-cache" ) );
107 }
108
109 // Close the project if we are standalone, so it gets cleaned up properly
110 if( mgr->IsProjectOpen() && Kiface().IsSingle() )
111 mgr->UnloadProject( &Prj(), false );
112}
113
114
115bool PCB_BASE_EDIT_FRAME::TryBefore( wxEvent& aEvent )
116{
117 static bool s_presetSwitcherShown = false;
118 static bool s_viewportSwitcherShown = false;
119
120 // wxWidgets generates no key events for the tab key when the ctrl key is held down. One
121 // way around this is to look at all events and inspect the keyboard state of the tab key.
122 // However, this runs into issues on some linux VMs where querying the keyboard state is
123 // very slow. Fortunately we only use ctrl-tab on Mac, so we implement this lovely hack:
124#ifdef __WXMAC__
125 if( wxGetKeyState( WXK_TAB ) )
126#else
127 if( ( aEvent.GetEventType() == wxEVT_CHAR || aEvent.GetEventType() == wxEVT_CHAR_HOOK )
128 && static_cast<wxKeyEvent&>( aEvent ).GetKeyCode() == WXK_TAB )
129#endif
130 {
131 if( !s_presetSwitcherShown && wxGetKeyState( PRESET_SWITCH_KEY ) )
132 {
133 if( m_appearancePanel && this->IsActive() )
134 {
135 const wxArrayString& mru = m_appearancePanel->GetLayerPresetsMRU();
136
137 if( mru.size() > 0 )
138 {
139 EDA_VIEW_SWITCHER switcher( this, mru, PRESET_SWITCH_KEY );
140
141 s_presetSwitcherShown = true;
142 const int switcherDialogRet = switcher.ShowModal();
143 s_presetSwitcherShown = false;
144
145 if( switcherDialogRet == wxID_OK )
146 {
147 int idx = switcher.GetSelection();
148
149 if( idx >= 0 && idx < (int) mru.size() )
150 m_appearancePanel->ApplyLayerPreset( mru[idx] );
151 }
152
153 return true;
154 }
155 }
156 }
157 else if( !s_viewportSwitcherShown && wxGetKeyState( VIEWPORT_SWITCH_KEY ) )
158 {
159 if( m_appearancePanel && this->IsActive() )
160 {
161 const wxArrayString& mru = m_appearancePanel->GetViewportsMRU();
162
163 if( mru.size() > 0 )
164 {
165 EDA_VIEW_SWITCHER switcher( this, mru, VIEWPORT_SWITCH_KEY );
166
167 s_viewportSwitcherShown = true;
168 const int switcherDialogRet = switcher.ShowModal();
169 s_viewportSwitcherShown = false;
170
171 if( switcherDialogRet == wxID_OK )
172 {
173 int idx = switcher.GetSelection();
174
175 if( idx >= 0 && idx < (int) mru.size() )
176 m_appearancePanel->ApplyViewport( mru[idx] );
177 }
178
179 return true;
180 }
181 }
182 }
183 }
184
185 return PCB_BASE_FRAME::TryBefore( aEvent );
186}
187
188
190{
191 // Return a default angle (90 degrees) used for rotate operations.
192 return ANGLE_90;
193}
194
195
202
203
205{
206 bool is_new_board = ( aBoard != m_pcb );
207
208 if( is_new_board )
209 {
210 if( m_toolManager )
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
243{
245
246 if( BOARD* board = GetBoard() )
247 {
248 board->UpdateUserUnits( board, GetCanvas()->GetView() );
250 }
251
254}
255
256
258{
260
261 // Update the grid checkbox in the layer widget
263 m_appearancePanel->SetObjectVisible( LAYER_GRID, aVisible );
264}
265
266
268{
270 m_appearancePanel->SetObjectVisible( aLayer, aVisible );
271}
272
273
275{
277 return ::GetColorSettings( cfg ? cfg->m_ColorTheme : DEFAULT_THEME );
278}
279
280
282{
283 if( !GetBoard() )
284 return wxEmptyString;
285
286 wxFileName fn = GetBoard()->GetFileName();
288 return Prj().AbsolutePath( fn.GetFullName() );
289}
290
291
292void PCB_BASE_EDIT_FRAME::handleActivateEvent( wxActivateEvent& aEvent )
293{
295
296 // The text in the collapsible pane headers need to be updated
298 m_appearancePanel->RefreshCollapsiblePanes();
299}
300
301
303{
304 m_appearancePanel->OnDarkModeToggle();
305
307
308 if( viewer )
309 viewer->OnDarkModeToggle();
310}
311
312
314{
315 if( !m_propertiesPanel )
316 return;
317
318 bool show = !m_propertiesPanel->IsShownOnScreen();
319
320 wxAuiPaneInfo& propertiesPaneInfo = m_auimgr.GetPane( PropertiesPaneName() );
321 propertiesPaneInfo.Show( show );
322
324
325 if( show )
326 {
327 SetAuiPaneSize( m_auimgr, propertiesPaneInfo,
328 settings->m_AuiPanels.properties_panel_width, -1 );
329 }
330 else
331 {
333 m_auimgr.Update();
334 }
335}
336
337
338void PCB_BASE_EDIT_FRAME::GetContextualTextVars( BOARD_ITEM* aSourceItem, const wxString& aCrossRef,
339 wxArrayString* aTokens )
340{
341 BOARD* board = aSourceItem->GetBoard();
342
343 if( !aCrossRef.IsEmpty() )
344 {
345 for( FOOTPRINT* candidate : board->Footprints() )
346 {
347 if( candidate->GetReference() == aCrossRef )
348 {
349 candidate->GetContextualTextVars( aTokens );
350 break;
351 }
352 }
353 }
354 else
355 {
356 board->GetContextualTextVars( aTokens );
357
358 if( FOOTPRINT* footprint = aSourceItem->GetParentFootprint() )
359 footprint->GetContextualTextVars( aTokens );
360 }
361}
362
363
365{
366 // Load the toolbar configuration and base controls
368
369 // Layer selector
370 auto layerSelectorFactory =
371 [this]( ACTION_TOOLBAR* aToolbar )
372 {
373 if( !m_SelLayerBox )
374 {
375 m_SelLayerBox = new PCB_LAYER_BOX_SELECTOR( aToolbar, wxID_ANY );
376 m_SelLayerBox->SetBoardFrame( this );
377 }
378
379 m_SelLayerBox->SetToolTip( _( "+/- to switch" ) );
380 m_SelLayerBox->Resync();
381
382 aToolbar->Add( m_SelLayerBox );
383
384 // UI update handler for the control
385 aToolbar->Bind( wxEVT_UPDATE_UI,
386 [this]( wxUpdateUIEvent& aEvent )
387 {
388 if( m_SelLayerBox->GetCount()
389 && ( m_SelLayerBox->GetLayerSelection() != GetActiveLayer() ) )
390 {
391 m_SelLayerBox->SetLayerSelection( GetActiveLayer() );
392 }
393 },
394 m_SelLayerBox->GetId() );
395
396 // Event handler to respond to the user interacting with the control
397 aToolbar->Bind( wxEVT_COMBOBOX,
398 [this]( wxCommandEvent& aEvent )
399 {
400 SetActiveLayer( ToLAYER_ID( m_SelLayerBox->GetLayerSelection() ) );
401
402 if( GetDisplayOptions().m_ContrastModeDisplay != HIGH_CONTRAST_MODE::NORMAL )
403 GetCanvas()->Refresh();
404 },
405 m_SelLayerBox->GetId() );
406 };
407
409}
410
411
413{
414 PCB_SELECTION_FILTER_EVENT evt( aOptions );
415 wxPostEvent( this, evt );
416}
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.
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:79
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:317
void GetContextualTextVars(wxArrayString *aVars) const
Definition board.cpp:476
const FOOTPRINTS & Footprints() const
Definition board.h:358
const wxString & GetFileName() const
Definition board.h:354
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition board.cpp:1040
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.
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.
static const TOOL_EVENT SelectedItemsModified
Selected items were moved, this can be very high frequency on the canvas, use with care.
Definition actions.h:353
void SetGridOrigin(const VECTOR2D &aGridOrigin)
Set the origin point for the grid.
void Clear()
Remove all items from the view.
Definition view.cpp:1143
void InitPreview()
Definition view.cpp:1722
A minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the same KiCad...
Definition kiway.h:286
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.
bool m_darkMode
Panel with Layers and Object Inspector tabs.
void doCloseWindow() override
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 ...
bool TryBefore(wxEvent &aEvent) override
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
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.
void ActivateGalCanvas() override
Set the #m_Pcb member in such as way as to ensure deleting any previous BOARD.
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
virtual PCB_LAYER_ID GetActiveLayer() 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)
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.
BOARD * GetBoard() const
EDA_3D_VIEWER_FRAME * Get3DViewerFrame()
virtual void SetActiveLayer(PCB_LAYER_ID aLayer)
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)
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:386
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
FOOTPRINT_LIST_IMPL GFootprintList
The global footprint info table.
Definition cvpcb.cpp:156
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
PROJECT & Prj()
Definition kicad.cpp:612
GAL_LAYER_ID
GAL layers are "virtual" layers, i.e.
Definition layer_ids.h:228
@ LAYER_GRID
Definition layer_ids.h:253
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition lset.cpp:737
bool IsDarkTheme()
Determine if the desktop interface is currently using a dark theme or a light theme.
Definition wxgtk/ui.cpp:48
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.