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>
33#include <pgm_base.h>
34#include <board.h>
37#include <pcb_dimension.h>
39#include <footprint.h>
40#include <footprint_info_impl.h>
41#include <layer_pairs.h>
42#include <project.h>
50
51
53 FRAME_T aFrameType, const wxString& aTitle,
54 const wxPoint& aPos, const wxSize& aSize, long aStyle,
55 const wxString& aFrameName ) :
56 PCB_BASE_FRAME( aKiway, aParent, aFrameType, aTitle, aPos, aSize, aStyle, aFrameName ),
57 m_undoRedoBlocked( false ),
58 m_selectionFilterPanel( nullptr ),
59 m_appearancePanel( nullptr ),
60 m_tabbedPanel( nullptr )
61{
62 m_SelLayerBox = nullptr;
64
65 // Do not register the idle event handler if we are running in headless mode.
66 if( !wxApp::GetGUIInstance() )
67 return;
68
69 Bind( wxEVT_IDLE,
70 [this]( wxIdleEvent& aEvent )
71 {
72 // Handle cursor adjustments. While we can get motion and key events through
73 // wxWidgets, we can't get modifier-key-up events.
74 if( m_toolManager )
75 {
77
78 if( selTool )
79 selTool->OnIdle( aEvent );
80 }
81
83 {
86 }
87 } );
88}
89
90
92{
93 GetCanvas()->GetView()->Clear();
94}
95
96
98{
100 wxFileName projectName( Prj().GetProjectFullName() );
101
102 if( mgr->IsProjectOpen() && wxFileName::IsDirWritable( projectName.GetPath() )
103 && projectName.Exists() )
104 {
105 GFootprintList.WriteCacheToFile( Prj().GetProjectPath() + wxT( "fp-info-cache" ) );
106 }
107
108 // Close the project if we are standalone, so it gets cleaned up properly
109 if( mgr->IsProjectOpen() && Kiface().IsSingle() )
110 mgr->UnloadProject( &Prj(), false );
111}
112
113
114bool PCB_BASE_EDIT_FRAME::TryBefore( wxEvent& aEvent )
115{
116 static bool s_presetSwitcherShown = false;
117 static bool s_viewportSwitcherShown = false;
118
119 // wxWidgets generates no key events for the tab key when the ctrl key is held down. One
120 // way around this is to look at all events and inspect the keyboard state of the tab key.
121 // However, this runs into issues on some linux VMs where querying the keyboard state is
122 // very slow. Fortunately we only use ctrl-tab on Mac, so we implement this lovely hack:
123#ifdef __WXMAC__
124 if( wxGetKeyState( WXK_TAB ) )
125#else
126 if( ( aEvent.GetEventType() == wxEVT_CHAR || aEvent.GetEventType() == wxEVT_CHAR_HOOK )
127 && static_cast<wxKeyEvent&>( aEvent ).GetKeyCode() == WXK_TAB )
128#endif
129 {
130 if( !s_presetSwitcherShown && wxGetKeyState( PRESET_SWITCH_KEY ) )
131 {
132 if( m_appearancePanel && this->IsActive() )
133 {
134 const wxArrayString& mru = m_appearancePanel->GetLayerPresetsMRU();
135
136 if( mru.size() > 0 )
137 {
138 EDA_VIEW_SWITCHER switcher( this, mru, PRESET_SWITCH_KEY );
139
140 s_presetSwitcherShown = true;
141 const int switcherDialogRet = switcher.ShowModal();
142 s_presetSwitcherShown = false;
143
144 if( switcherDialogRet == wxID_OK )
145 {
146 int idx = switcher.GetSelection();
147
148 if( idx >= 0 && idx < (int) mru.size() )
150 }
151
152 return true;
153 }
154 }
155 }
156 else if( !s_viewportSwitcherShown && wxGetKeyState( VIEWPORT_SWITCH_KEY ) )
157 {
158 if( m_appearancePanel && this->IsActive() )
159 {
160 const wxArrayString& mru = m_appearancePanel->GetViewportsMRU();
161
162 if( mru.size() > 0 )
163 {
164 EDA_VIEW_SWITCHER switcher( this, mru, VIEWPORT_SWITCH_KEY );
165
166 s_viewportSwitcherShown = true;
167 const int switcherDialogRet = switcher.ShowModal();
168 s_viewportSwitcherShown = false;
169
170 if( switcherDialogRet == wxID_OK )
171 {
172 int idx = switcher.GetSelection();
173
174 if( idx >= 0 && idx < (int) mru.size() )
175 m_appearancePanel->ApplyViewport( mru[idx] );
176 }
177
178 return true;
179 }
180 }
181 }
182 }
183
184 return PCB_BASE_FRAME::TryBefore( aEvent );
185}
186
187
189{
190 // Return a default angle (90 degrees) used for rotate operations.
191 return ANGLE_90;
192}
193
194
196{
198
200}
201
202
204{
205 bool is_new_board = ( aBoard != m_pcb );
206
207 if( is_new_board )
208 {
209 if( m_toolManager )
211
212 GetCanvas()->GetView()->Clear();
214 }
215
216 PCB_BASE_FRAME::SetBoard( aBoard, aReporter );
217
219
220 if( is_new_board )
221 {
223 bds.m_DRCEngine = std::make_shared<DRC_ENGINE>( aBoard, &bds );
224 }
225
226 // update the tool manager with the new board and its view.
227 if( m_toolManager )
228 {
229 GetCanvas()->DisplayBoard( aBoard, aReporter );
230
232 m_toolManager->SetEnvironment( aBoard, GetCanvas()->GetView(),
233 GetCanvas()->GetViewControls(), config(), this );
234
235 if( is_new_board )
237 }
238}
239
240
242{
244
245 if( BOARD* board = GetBoard() )
246 {
247 board->UpdateUserUnits( board, GetCanvas()->GetView() );
249 }
250
253}
254
255
257{
259
260 // Update the grid checkbox in the layer widget
263}
264
265
267{
269 m_appearancePanel->SetObjectVisible( aLayer, aVisible );
270}
271
272
274{
276 return ::GetColorSettings( cfg ? cfg->m_ColorTheme : DEFAULT_THEME );
277}
278
279
281{
282 if( !GetBoard() )
283 return wxEmptyString;
284
285 wxFileName fn = GetBoard()->GetFileName();
287 return Prj().AbsolutePath( fn.GetFullName() );
288}
289
290
291void PCB_BASE_EDIT_FRAME::handleActivateEvent( wxActivateEvent& aEvent )
292{
294
295 // The text in the collapsible pane headers need to be updated
298}
299
300
302{
304
306
307 if( viewer )
308 viewer->OnDarkModeToggle();
309}
310
311
313{
314 if( !m_propertiesPanel )
315 return;
316
317 bool show = !m_propertiesPanel->IsShownOnScreen();
318
319 wxAuiPaneInfo& propertiesPaneInfo = m_auimgr.GetPane( PropertiesPaneName() );
320 propertiesPaneInfo.Show( show );
321
323
324 if( show )
325 {
326 SetAuiPaneSize( m_auimgr, propertiesPaneInfo,
327 settings->m_AuiPanels.properties_panel_width, -1 );
328 }
329 else
330 {
332 m_auimgr.Update();
333 }
334}
335
336
337void PCB_BASE_EDIT_FRAME::GetContextualTextVars( BOARD_ITEM* aSourceItem, const wxString& aCrossRef,
338 wxArrayString* aTokens )
339{
340 BOARD* board = aSourceItem->GetBoard();
341
342 if( !aCrossRef.IsEmpty() )
343 {
344 for( FOOTPRINT* candidate : board->Footprints() )
345 {
346 if( candidate->GetReference() == aCrossRef )
347 {
348 candidate->GetContextualTextVars( aTokens );
349 break;
350 }
351 }
352 }
353 else
354 {
355 board->GetContextualTextVars( aTokens );
356
357 if( FOOTPRINT* footprint = aSourceItem->GetParentFootprint() )
358 footprint->GetContextualTextVars( aTokens );
359 }
360}
361
362
364{
365 // Load the toolbar configuration and base controls
367
368 // Layer selector
369 auto layerSelectorFactory =
370 [this]( ACTION_TOOLBAR* aToolbar )
371 {
372 if( !m_SelLayerBox )
373 {
374 m_SelLayerBox = new PCB_LAYER_BOX_SELECTOR( aToolbar, wxID_ANY );
376 }
377
378 // In the footprint editor, some layers cannot be select (they are shown in the layer
379 // manager only to set the color and visibility, but not for selection)
380 // Disable them in layer box
383
384 m_SelLayerBox->SetToolTip( _( "+/- to switch" ) );
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()
395 {
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 {
406
407 if( GetDisplayOptions().m_ContrastModeDisplay != HIGH_CONTRAST_MODE::NORMAL )
408 GetCanvas()->Refresh();
409 },
410 m_SelLayerBox->GetId() );
411 };
412
414}
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
static ACTION_TOOLBAR_CONTROL layerSelector
Define the structure of a toolbar with buttons that invoke ACTIONs.
void ApplyLayerPreset(const wxString &aPresetName)
const wxArrayString & GetViewportsMRU()
void RefreshCollapsiblePanes()
Function to force a redraw of the collapsible panes in this control.
const wxArrayString & GetLayerPresetsMRU()
Return a list of viewports created by the user.
void OnDarkModeToggle()
Update the widget when the active board layer is changed.
void SetObjectVisible(GAL_LAYER_ID aLayer, bool isVisible=true)
void ApplyViewport(const wxString &aPresetName)
wxString m_ColorTheme
Active color theme name.
Definition: app_settings.h:236
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.
Definition: board_item.cpp:79
FOOTPRINT * GetParentFootprint() const
Definition: board_item.cpp:97
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:317
void GetContextualTextVars(wxArrayString *aVars) const
Definition: board.cpp:474
const FOOTPRINTS & Footprints() const
Definition: board.h:358
const wxString & GetFileName() const
Definition: board.h:354
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:1024
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
bool IsType(FRAME_T aType) const
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.
int GetSelection() const
static const TOOL_EVENT SelectedItemsModified
Selected items were moved, this can be very high frequency on the canvas, use with care.
Definition: actions.h:349
void WriteCacheToFile(const wxString &aFilePath) override
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
int SetLayerSelection(int layer)
static const LSET & ForbiddenFootprintLayers()
Layers which are not allowed within footprint definitions.
Definition: lset.cpp:726
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)
APPEARANCE_CONTROLS * m_appearancePanel
void SetObjectVisible(GAL_LAYER_ID aLayer, bool aVisible=true)
void GetContextualTextVars(BOARD_ITEM *aSourceItem, const wxString &aCrossRef, wxArrayString *aTokens)
void handleActivateEvent(wxActivateEvent &aEvent) override
Handle a window activation event.
virtual void onDarkModeToggle()
void ActivateGalCanvas() override
Set the #m_Pcb member in such as way as to ensure deleting any previous BOARD.
Base PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
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_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.
void SetBoardFrame(PCB_BASE_FRAME *aFrame)
void SetNotAllowedLayerSet(const LSET &aMask)
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:373
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
Definition: tools_holder.h:171
@ MODEL_RELOAD
Model changes (the sheet for a schematic)
Definition: tool_base.h:80
void PostEvent(const TOOL_EVENT &aEvent)
Put an event to the event queue to be processed at the end of event processing cycle.
void ResetTools(TOOL_BASE::RESET_REASON aReason)
Reset all tools (i.e.
void SetEnvironment(EDA_ITEM *aModel, KIGFX::VIEW *aView, KIGFX::VIEW_CONTROLS *aViewControls, APP_SETTINGS_BASE *aSettings, TOOLS_HOLDER *aFrame)
Set the work environment (model, view, view controls and the parent window).
#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
@ FRAME_FOOTPRINT_EDITOR
Definition: frame_type.h:43
static const std::string DesignRulesFileExtension
PROJECT & Prj()
Definition: kicad.cpp:608
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:744
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
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.