KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pcb_calculator_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) 1992-2015 jean-pierre.charras
5 * Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 3
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20#include <wx/msgdlg.h>
21#include <wx/treebook.h>
22#include <wx/sizer.h>
23
24#include <typeinfo>
25
26#include <bitmaps.h>
27#include <bitmap_store.h>
29#include <kiface_base.h>
30#include <tool/actions.h>
31#include <tool/tool_manager.h>
33#include <tool/common_control.h>
38
53#include "widgets/wx_menubar.h"
54
55
56BEGIN_EVENT_TABLE( PCB_CALCULATOR_FRAME, KIWAY_PLAYER )
57 EVT_MENU( wxID_CLOSE, PCB_CALCULATOR_FRAME::OnExit )
58 EVT_MENU( wxID_EXIT, PCB_CALCULATOR_FRAME::OnExit )
59END_EVENT_TABLE()
60
61
62PCB_CALCULATOR_FRAME::PCB_CALCULATOR_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
63 KIWAY_PLAYER( aKiway, aParent, FRAME_CALC, _( "Calculator Tools" ), wxDefaultPosition,
64 wxDefaultSize,
65 wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxFULL_REPAINT_ON_RESIZE|wxTAB_TRAVERSAL,
66 wxT( "calculator_tools" ), unityScale ),
67 m_lastNotebookPage( -1 )
68{
69 m_aboutTitle = _HKI( "KiCad Calculator Tools" );
70
71 SHAPE_POLY_SET dummy; // A ugly trick to force the linker to include
72 // some methods in code and avoid link errors
73
74 SetSizeHints( wxDefaultSize, wxDefaultSize );
75
76 m_mainSizer = new wxBoxSizer( wxVERTICAL );
77
78 m_treebook = new wxTreebook( this, wxID_ANY );
79 m_treebook->SetFont( KIUI::GetControlFont( this ) );
80 m_mainSizer->Add( m_treebook, 1, wxEXPAND | wxLEFT | wxTOP, 0 );
81
82 SetSizer( m_mainSizer );
83 Layout();
84 Centre( wxBOTH );
85
86 loadPages();
87
88 // Give an icon
89 wxIcon icon;
90 wxIconBundle icon_bundle;
91
92 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_pcbcalculator, 48 ) );
93 icon_bundle.AddIcon( icon );
94 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_pcbcalculator, 128 ) );
95 icon_bundle.AddIcon( icon );
96 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_pcbcalculator, 256 ) );
97 icon_bundle.AddIcon( icon );
98 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_pcbcalculator_32 ) );
99 icon_bundle.AddIcon( icon );
100 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_pcbcalculator_16 ) );
101 icon_bundle.AddIcon( icon );
102
103 SetIcons( icon_bundle );
104
105 m_toolManager = new TOOL_MANAGER;
106 m_toolManager->SetEnvironment( nullptr, nullptr, nullptr, config(), this );
107
108 m_toolDispatcher = new TOOL_DISPATCHER( m_toolManager );
109
110 // Register tools
111 m_toolManager->RegisterTool( new COMMON_CONTROL );
112 m_toolManager->RegisterTool( new PCB_CALCULATOR_CONTROL );
113 m_toolManager->InitTools();
114
115 ReCreateMenuBar();
116 setupUIConditions();
117
118 GetSizer()->SetSizeHints( this );
119
120 // Set previous size and position
121 SetSize( m_framePos.x, m_framePos.y, m_frameSize.x, m_frameSize.y );
122
123 if( m_framePos == wxDefaultPosition )
124 Centre();
125
126 // Expand treebook to show all options:
127 for( size_t pageId = 0; pageId < m_treebook->GetPageCount(); pageId++ )
128 m_treebook->ExpandNode( pageId );
129
130 // Connect Events
131 Bind( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( PCB_CALCULATOR_FRAME::OnClosePcbCalc ), this );
132 Bind( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( PCB_CALCULATOR_FRAME::OnUpdateUI ), this );
133
134 Bind( wxEVT_SYS_COLOUR_CHANGED,
135 wxSysColourChangedEventHandler( PCB_CALCULATOR_FRAME::onThemeChanged ), this );
136
137 m_treebook->Connect( wxEVT_COMMAND_TREEBOOK_PAGE_CHANGED, wxTreebookEventHandler(
138 PCB_CALCULATOR_FRAME::OnPageChanged ), nullptr, this );
139}
140
141
143{
144 m_treebook->Disconnect( wxEVT_COMMAND_TREEBOOK_PAGE_CHANGED, wxTreebookEventHandler(
145 PCB_CALCULATOR_FRAME::OnPageChanged ), nullptr, this );
146 // This needed for OSX: avoids further OnDraw processing after this destructor and before
147 // the native window is destroyed
148 this->Freeze();
149}
150
151
152void PCB_CALCULATOR_FRAME::OnExit( wxCommandEvent& aEvent )
153{
154 if( aEvent.GetId() == wxID_EXIT )
155 Kiway().OnKiCadExit();
156
157 if( aEvent.GetId() == wxID_CLOSE || Kiface().IsSingle() )
158 Close( false );
159}
160
161
163{
164 m_treebook->AddPage( nullptr, _( "General system design" ) );
165
166 AddCalculator( new PANEL_REGULATOR( m_treebook ), _( "Regulators" ) );
167 AddCalculator( new PANEL_R_CALCULATOR( m_treebook ), _( "Resistor Calculator" ) );
168
169 m_treebook->AddPage( nullptr, _( "Power, current and isolation" ) );
170
171 AddCalculator( new PANEL_ELECTRICAL_SPACING( m_treebook ), _( "Electrical Spacing" ) );
172 AddCalculator( new PANEL_VIA_SIZE( m_treebook ), _( "Via Size" ) );
173 AddCalculator( new PANEL_TRACK_WIDTH( m_treebook ), _( "Track Width" ) );
174 AddCalculator( new PANEL_FUSING_CURRENT( m_treebook ), _( "Fusing Current" ) );
175 AddCalculator( new PANEL_CABLE_SIZE( m_treebook ), _( "Cable Size" ) );
176
177 m_treebook->AddPage( nullptr, _( "High Speed" ) );
178
179 AddCalculator( new PANEL_WAVELENGTH( m_treebook ), _( "Wavelength" ) );
180 AddCalculator( new PANEL_RF_ATTENUATORS( m_treebook ), _( "RF Attenuators" ) );
181 AddCalculator( new PANEL_TRANSLINE( m_treebook ), _( "Transmission Lines") );
182
183 m_treebook->AddPage( nullptr, _( "Memo" ) );
184
185 AddCalculator( new PANEL_ESERIES_DISPLAY( m_treebook ), _( "E-Series" ) );
186 AddCalculator( new PANEL_COLOR_CODE( m_treebook ), _( "Color Code" ) );
187 AddCalculator( new PANEL_BOARD_CLASS( m_treebook ), _( "Board Classes" ) );
188 AddCalculator( new PANEL_GALVANIC_CORROSION( m_treebook ), _( "Galvanic Corrosion" ) );
189
190 LoadSettings( config() );
191
192 if( PANEL_REGULATOR* regPanel = GetCalculator<PANEL_REGULATOR>() )
193 regPanel->ReadDataFile();
194}
195
196
198{
200 EDA_BASE_FRAME* base_frame = dynamic_cast<EDA_BASE_FRAME*>( this );
201
202 // base_frame == nullptr should not happen, but it makes Coverity happy
203 wxCHECK( base_frame, /* void */ );
204
205 // wxWidgets handles the OSX Application menu behind the scenes, but that means
206 // we always have to start from scratch with a new wxMenuBar.
207 wxMenuBar* oldMenuBar = base_frame->GetMenuBar();
208 WX_MENUBAR* menuBar = new WX_MENUBAR();
209
210 //-- File menu -----------------------------------------------------------
211 //
212 ACTION_MENU* fileMenu = new ACTION_MENU( false, tool );
213
214 fileMenu->AddClose( _( "Calculator Tools" ) );
215 fileMenu->AddQuit( _( "Calculator Tools" ) );
216
217 //-- Preferences menu -----------------------------------------------
218 //
219 ACTION_MENU* prefsMenu = new ACTION_MENU( false, tool );
220
221 prefsMenu->Add( ACTIONS::openPreferences );
222
223 prefsMenu->AppendSeparator();
224 AddMenuLanguageList( prefsMenu, tool );
225
226
227 //-- Menubar -------------------------------------------------------------
228 //
229 menuBar->Append( fileMenu, _( "&File" ) );
230 menuBar->Append( prefsMenu, _( "&Preferences" ) );
231 base_frame->AddStandardHelpMenu( menuBar );
232
233 base_frame->SetMenuBar( menuBar );
234 delete oldMenuBar;
235}
236
237
239{
241
242 SetTitle( _( "Calculator Tools" ) );
243
244 SaveSettings( config() );
245 Freeze();
246
247 int page = m_treebook->GetSelection();
248 m_treebook->DeleteAllPages();
249 m_panels.clear();
250
251 loadPages();
252 Layout();
253
254 m_treebook->SetSelection( page );
255 LoadSettings( config() );
256
257 Thaw();
258 Refresh();
259}
260
261
262void PCB_CALCULATOR_FRAME::OnPageChanged ( wxTreebookEvent& aEvent )
263{
264 int page = aEvent.GetSelection();
265
266 // If the selected page is a top level page
267 if ( m_treebook->GetPageParent( page ) == wxNOT_FOUND )
268 {
269 m_treebook->ExpandNode( page );
270
271 // Select the first child
272 if( page + 1 < m_treebook->GetPageCount() )
273 m_treebook->ChangeSelection( page + 1 );
274 }
275}
276
277
278void PCB_CALCULATOR_FRAME::AddCalculator( CALCULATOR_PANEL *aPanel, const wxString& panelUIName )
279{
280 // Update internal structures
281 m_panels.push_back( aPanel );
282 m_panelTypes[ typeid( *aPanel ).hash_code() ] = aPanel;
283
284 m_treebook->AddSubPage( aPanel, panelUIName );
285}
286
287
288void PCB_CALCULATOR_FRAME::onThemeChanged( wxSysColourChangedEvent& aEvent )
289{
290 // Force the bitmaps to refresh
292
293 // Update the panels
294 for( auto& panel : m_panels )
295 panel->ThemeChanged();
296
297 aEvent.Skip();
298}
299
300
301void PCB_CALCULATOR_FRAME::OnUpdateUI( wxUpdateUIEvent& event )
302{
303 if( m_treebook->GetSelection() != m_lastNotebookPage )
304 {
305 // Kick all the things that wxWidgets can't seem to redraw on its own.
306 // This is getting seriously ridiculous....
307 PANEL_TRANSLINE* translinePanel = GetCalculator<PANEL_TRANSLINE>();
308 PANEL_RF_ATTENUATORS* attenPanel = GetCalculator<PANEL_RF_ATTENUATORS>();
309 PANEL_VIA_SIZE* viaSizePanel = GetCalculator<PANEL_VIA_SIZE>();
310 PANEL_REGULATOR* regulPanel = GetCalculator<PANEL_REGULATOR>();
311 PANEL_ELECTRICAL_SPACING* elecSpacingPanel = GetCalculator<PANEL_ELECTRICAL_SPACING>();
312
313 wxASSERT( translinePanel );
314 wxASSERT( attenPanel );
315 wxASSERT( viaSizePanel );
316 wxASSERT( regulPanel );
317 wxASSERT( elecSpacingPanel );
318
319 {
320 wxCommandEvent event2( wxEVT_RADIOBUTTON );
321 event2.SetEventObject( translinePanel->GetTranslineSelector() );
322 event2.SetInt( translinePanel->GetCurrTransLineType() );
323
324 translinePanel->GetTranslineSelector()->Command( event2 );
325 }
326
327 for( int i = 0; i < attenPanel->m_AttenuatorList.size(); ++i )
328 {
329 if( attenPanel->m_AttenuatorList[i] == attenPanel->m_CurrAttenuator )
330 {
331 wxCommandEvent event2( wxEVT_RADIOBUTTON );
332 event2.SetEventObject( attenPanel->GetAttenuatorsSelector() );
333 event2.SetInt( i );
334
335 attenPanel->GetAttenuatorsSelector()->Command( event2 );
336 break;
337 }
338 }
339
340 attenPanel->UpdateUI();
341 viaSizePanel->Layout();
342 regulPanel->Layout();
343
344 // Until it's shown on screen the above won't work; but doing it anyway at least keeps
345 // putting new OnUpdateUI events into the queue until it *is* shown on screen.
346 if( m_treebook->IsShownOnScreen() )
347 m_lastNotebookPage = m_treebook->GetSelection();
348 }
349}
350
351
352void PCB_CALCULATOR_FRAME::OnClosePcbCalc( wxCloseEvent& event )
353{
354 PANEL_REGULATOR* regPanel = GetCalculator<PANEL_REGULATOR>();
355
356 wxASSERT( regPanel );
357
358 if( regPanel->m_RegulatorListChanged )
359 {
360 wxString msg;
361 wxString title = _( "Write Data Failed" );
362
363 if( regPanel->GetDataFilename().IsEmpty() )
364 {
365 msg = _( "No data filename to save modifications.\n"
366 "Do you want to exit and abandon your changes?" );
367
368 if( wxMessageBox( msg, title, wxYES_NO | wxICON_QUESTION ) == wxNO )
369 return;
370 }
371 else
372 {
373 if( !regPanel->WriteDataFile() )
374 {
375 msg.Printf( _( "Unable to write file '%s'\n"
376 "Do you want to exit and abandon your changes?"),
377 regPanel->GetDataFilename() );
378
379 if( wxMessageBox( msg, title, wxYES_NO | wxICON_ERROR ) == wxNO )
380 return;
381 }
382 }
383 }
384
385 event.Skip();
386}
387
388
390{
391 if( aCfg == nullptr )
392 return;
393
395
396 PCB_CALCULATOR_SETTINGS* cfg = static_cast<PCB_CALCULATOR_SETTINGS*>( aCfg );
397
398 m_treebook->ChangeSelection( cfg->m_LastPage );
399
400 for( CALCULATOR_PANEL* panel : m_panels )
401 panel->LoadSettings( cfg );
402}
403
404
406{
407 if( aCfg == nullptr )
408 return;
409
411
412 // Save current parameters values in config.
413 auto cfg = dynamic_cast<PCB_CALCULATOR_SETTINGS*>( Kiface().KifaceSettings() );
414
415 if( cfg )
416 {
417 cfg->m_LastPage = m_treebook->GetSelection();
418
419 for( CALCULATOR_PANEL* panel : m_panels )
420 panel->SaveSettings( cfg );
421 }
422
423}
constexpr EDA_IU_SCALE unityScale
Definition: base_units.h:111
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
wxBitmap KiBitmap(BITMAPS aBitmap, int aHeightTag)
Construct a wxBitmap from an image identifier Returns the image from the active theme if the image ha...
Definition: bitmap.cpp:104
BITMAP_STORE * GetBitmapStore()
Definition: bitmap.cpp:92
@ icon_pcbcalculator_16
@ icon_pcbcalculator_32
@ icon_pcbcalculator
static TOOL_ACTION openPreferences
Definition: actions.h:211
Defines the structure of a menu based on ACTIONs.
Definition: action_menu.h:49
void AddClose(const wxString &aAppname="")
Add a standard close item to the menu with the accelerator key CTRL-W.
void AddQuit(const wxString &aAppname="")
Add a standard Quit item to the menu.
wxMenuItem * Add(const wxString &aLabel, int aId, BITMAPS aIcon)
Add a wxWidgets-style entry to the menu.
APP_SETTINGS_BASE is a settings class that should be derived for each standalone KiCad application.
Definition: app_settings.h:92
void ThemeChanged()
Notifies the store that the icon theme has been changed by the user, so caches must be invalidated.
Handle actions that are shared between different applications.
The base frame for deriving all KiCad main window classes.
virtual APP_SETTINGS_BASE * config() const
Returns the settings object used in SaveSettings(), and is overloaded in KICAD_MANAGER_FRAME.
void ShowChangedLanguage() override
Redraw the menus and what not in current language.
void AddMenuLanguageList(ACTION_MENU *aMasterMenu, TOOL_INTERACTIVE *aControlTool)
Function AddMenuLanguageList creates a menu list for language choice, and add it as submenu to Master...
virtual void LoadSettings(APP_SETTINGS_BASE *aCfg)
Load common frame parameters from a configuration file.
virtual void SaveSettings(APP_SETTINGS_BASE *aCfg)
Save common frame parameters to a configuration data file.
APP_SETTINGS_BASE * KifaceSettings() const
Definition: kiface_base.h:95
KIWAY & Kiway() const
Return a reference to the KIWAY that this object has an opportunity to participate in.
Definition: kiway_holder.h:55
A wxFrame capable of the OpenProjectFiles function, meaning it can load a portion of a KiCad project.
Definition: kiway_player.h:65
A minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the same KiCad...
Definition: kiway.h:279
void OnKiCadExit()
Definition: kiway.cpp:717
const wxString GetDataFilename()
std::vector< ATTENUATOR * > m_AttenuatorList
wxRadioBox * GetAttenuatorsSelector()
wxRadioBox * GetTranslineSelector()
TRANSLINE_TYPE_ID GetCurrTransLineType()
Handle actions for the various symbol editor and viewers.
PCB calculator the main frame.
void doReCreateMenuBar() override
void OnPageChanged(wxTreebookEvent &aEvent)
void ShowChangedLanguage() override
Redraw the menus and what not in current language.
std::vector< CALCULATOR_PANEL * > m_panels
void OnUpdateUI(wxUpdateUIEvent &event)
void onThemeChanged(wxSysColourChangedEvent &aEvent)
void LoadSettings(APP_SETTINGS_BASE *aCfg) override
Load common frame parameters from a configuration file.
void OnExit(wxCommandEvent &aEvent)
Event handler for the wxID_EXIT and wxID_CLOSE events.
void OnClosePcbCalc(wxCloseEvent &event)
void AddCalculator(CALCULATOR_PANEL *aPanel, const wxString &panelUIName)
void SaveSettings(APP_SETTINGS_BASE *aCfg) override
Save common frame parameters to a configuration data file.
std::map< std::size_t, CALCULATOR_PANEL * > m_panelTypes
Represent a set of closed polygons.
TOOL_MANAGER * m_toolManager
Definition: tools_holder.h:167
Master controller class:
Definition: tool_manager.h:62
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).
Wrapper around a wxMenuBar object that prevents the accelerator table from being used.
Definition: wx_menubar.h:47
#define _HKI(x)
#define _(s)
@ FRAME_CALC
Definition: frame_type.h:63
KICOMMON_API wxFont GetControlFont(wxWindow *aWindow)
Definition: ui_common.cpp:160
void Refresh()
Update the board display after modifying it by a python script (note: it is automatically called by a...
std::vector< FAB_LAYER_COLOR > dummy