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, EDA_BASE_FRAME )
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 ) );
93 icon_bundle.AddIcon( icon );
94 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_pcbcalculator_32 ) );
95 icon_bundle.AddIcon( icon );
96 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_pcbcalculator_16 ) );
97 icon_bundle.AddIcon( icon );
98
99 SetIcons( icon_bundle );
100
101 m_toolManager = new TOOL_MANAGER;
102 m_toolManager->SetEnvironment( nullptr, nullptr, nullptr, config(), this );
103
104 m_toolDispatcher = new TOOL_DISPATCHER( m_toolManager );
105
106 // Register tools
107 m_toolManager->RegisterTool( new COMMON_CONTROL );
108 m_toolManager->RegisterTool( new PCB_CALCULATOR_CONTROL );
109 m_toolManager->InitTools();
110
111 ReCreateMenuBar();
112
113 GetSizer()->SetSizeHints( this );
114
115 // Set previous size and position
116 SetSize( m_framePos.x, m_framePos.y, m_frameSize.x, m_frameSize.y );
117
118 if( m_framePos == wxDefaultPosition )
119 Centre();
120
121 // Expand treebook to show all options:
122 for( size_t pageId = 0; pageId < m_treebook->GetPageCount(); pageId++ )
123 m_treebook->ExpandNode( pageId );
124
125 // Connect Events
126 Bind( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( PCB_CALCULATOR_FRAME::OnClosePcbCalc ), this );
127 Bind( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( PCB_CALCULATOR_FRAME::OnUpdateUI ), this );
128
129 Bind( wxEVT_SYS_COLOUR_CHANGED,
130 wxSysColourChangedEventHandler( PCB_CALCULATOR_FRAME::onThemeChanged ), this );
131
132 m_treebook->Connect( wxEVT_COMMAND_TREEBOOK_PAGE_CHANGED, wxTreebookEventHandler(
133 PCB_CALCULATOR_FRAME::OnPageChanged ), nullptr, this );
134}
135
136
138{
139 m_treebook->Disconnect( wxEVT_COMMAND_TREEBOOK_PAGE_CHANGED, wxTreebookEventHandler(
140 PCB_CALCULATOR_FRAME::OnPageChanged ), nullptr, this );
141 // This needed for OSX: avoids further OnDraw processing after this destructor and before
142 // the native window is destroyed
143 this->Freeze();
144}
145
146
147void PCB_CALCULATOR_FRAME::OnExit( wxCommandEvent& aEvent )
148{
149 if( aEvent.GetId() == wxID_EXIT )
150 Kiway().OnKiCadExit();
151
152 if( aEvent.GetId() == wxID_CLOSE || Kiface().IsSingle() )
153 Close( false );
154}
155
156
158{
159 m_treebook->AddPage( nullptr, _( "General system design" ) );
160
161 AddCalculator( new PANEL_REGULATOR( m_treebook ), _( "Regulators" ) );
162 AddCalculator( new PANEL_R_CALCULATOR( m_treebook ), _( "Resistor Calculator" ) );
163
164 m_treebook->AddPage( nullptr, _( "Power, current and isolation" ) );
165
166 AddCalculator( new PANEL_ELECTRICAL_SPACING( m_treebook ), _( "Electrical Spacing" ) );
167 AddCalculator( new PANEL_VIA_SIZE( m_treebook ), _( "Via Size" ) );
168 AddCalculator( new PANEL_TRACK_WIDTH( m_treebook ), _( "Track Width" ) );
169 AddCalculator( new PANEL_FUSING_CURRENT( m_treebook ), _( "Fusing Current" ) );
170 AddCalculator( new PANEL_CABLE_SIZE( m_treebook ), _( "Cable Size" ) );
171
172 m_treebook->AddPage( nullptr, _( "High Speed" ) );
173
174 AddCalculator( new PANEL_WAVELENGTH( m_treebook ), _( "Wavelength" ) );
175 AddCalculator( new PANEL_RF_ATTENUATORS( m_treebook ), _( "RF Attenuators" ) );
176 AddCalculator( new PANEL_TRANSLINE( m_treebook ), _( "Transmission Lines") );
177
178 m_treebook->AddPage( nullptr, _( "Memo" ) );
179
180 AddCalculator( new PANEL_ESERIES_DISPLAY( m_treebook ), _( "E-Series" ) );
181 AddCalculator( new PANEL_COLOR_CODE( m_treebook ), _( "Color Code" ) );
182 AddCalculator( new PANEL_BOARD_CLASS( m_treebook ), _( "Board Classes" ) );
183 AddCalculator( new PANEL_GALVANIC_CORROSION( m_treebook ), _( "Galvanic Corrosion" ) );
184
185 LoadSettings( config() );
186
187 if( PANEL_REGULATOR* regPanel = GetCalculator<PANEL_REGULATOR>() )
188 regPanel->ReadDataFile();
189}
190
191
193{
195 EDA_BASE_FRAME* base_frame = dynamic_cast<EDA_BASE_FRAME*>( this );
196
197 // base_frame == nullptr should not happen, but it makes Coverity happy
198 wxCHECK( base_frame, /* void */ );
199
200 // wxWidgets handles the OSX Application menu behind the scenes, but that means
201 // we always have to start from scratch with a new wxMenuBar.
202 wxMenuBar* oldMenuBar = base_frame->GetMenuBar();
203 WX_MENUBAR* menuBar = new WX_MENUBAR();
204
205 //-- File menu -----------------------------------------------------------
206 //
207 ACTION_MENU* fileMenu = new ACTION_MENU( false, tool );
208
209 fileMenu->AddClose( _( "Calculator Tools" ) );
210 fileMenu->AddQuit( _( "Calculator Tools" ) );
211
212 //-- Preferences menu -----------------------------------------------
213 //
214 ACTION_MENU* prefsMenu = new ACTION_MENU( false, tool );
215
216 prefsMenu->Add( ACTIONS::openPreferences );
217
218 prefsMenu->AppendSeparator();
219 AddMenuLanguageList( prefsMenu, tool );
220
221
222 //-- Menubar -------------------------------------------------------------
223 //
224 menuBar->Append( fileMenu, _( "&File" ) );
225 menuBar->Append( prefsMenu, _( "&Preferences" ) );
226 base_frame->AddStandardHelpMenu( menuBar );
227
228 base_frame->SetMenuBar( menuBar );
229 delete oldMenuBar;
230}
231
232
234{
236
237 SetTitle( _( "Calculator Tools" ) );
238
239 SaveSettings( config() );
240 Freeze();
241
242 int page = m_treebook->GetSelection();
243 m_treebook->DeleteAllPages();
244 m_panels.clear();
245
246 loadPages();
247 Layout();
248
249 m_treebook->SetSelection( page );
250 LoadSettings( config() );
251
252 Thaw();
253 Refresh();
254}
255
256
257void PCB_CALCULATOR_FRAME::OnPageChanged ( wxTreebookEvent& aEvent )
258{
259 int page = aEvent.GetSelection();
260
261 // If the selected page is a top level page
262 if ( m_treebook->GetPageParent( page ) == wxNOT_FOUND )
263 {
264 m_treebook->ExpandNode( page );
265
266 // Select the first child
267 if( page + 1 < m_treebook->GetPageCount() )
268 m_treebook->ChangeSelection( page + 1 );
269 }
270}
271
272
273void PCB_CALCULATOR_FRAME::AddCalculator( CALCULATOR_PANEL *aPanel, const wxString& panelUIName )
274{
275 // Update internal structures
276 m_panels.push_back( aPanel );
277 m_panelTypes[ typeid( *aPanel ).hash_code() ] = aPanel;
278
279 m_treebook->AddSubPage( aPanel, panelUIName );
280}
281
282
283void PCB_CALCULATOR_FRAME::onThemeChanged( wxSysColourChangedEvent& aEvent )
284{
285 // Force the bitmaps to refresh
287
288 // Update the panels
289 for( auto& panel : m_panels )
290 panel->ThemeChanged();
291
292 aEvent.Skip();
293}
294
295
296void PCB_CALCULATOR_FRAME::OnUpdateUI( wxUpdateUIEvent& event )
297{
298 if( m_treebook->GetSelection() != m_lastNotebookPage )
299 {
300 // Kick all the things that wxWidgets can't seem to redraw on its own.
301 // This is getting seriously ridiculous....
302 PANEL_TRANSLINE* translinePanel = GetCalculator<PANEL_TRANSLINE>();
303 PANEL_RF_ATTENUATORS* attenPanel = GetCalculator<PANEL_RF_ATTENUATORS>();
304 PANEL_VIA_SIZE* viaSizePanel = GetCalculator<PANEL_VIA_SIZE>();
305 PANEL_REGULATOR* regulPanel = GetCalculator<PANEL_REGULATOR>();
306 PANEL_ELECTRICAL_SPACING* elecSpacingPanel = GetCalculator<PANEL_ELECTRICAL_SPACING>();
307
308 wxASSERT( translinePanel );
309 wxASSERT( attenPanel );
310 wxASSERT( viaSizePanel );
311 wxASSERT( regulPanel );
312 wxASSERT( elecSpacingPanel );
313
314 {
315 wxCommandEvent event2( wxEVT_RADIOBUTTON );
316 event2.SetEventObject( translinePanel->GetTranslineSelector() );
317 event2.SetInt( translinePanel->GetCurrTransLineType() );
318
319 translinePanel->GetTranslineSelector()->Command( event2 );
320 }
321
322 for( int i = 0; i < attenPanel->m_AttenuatorList.size(); ++i )
323 {
324 if( attenPanel->m_AttenuatorList[i] == attenPanel->m_CurrAttenuator )
325 {
326 wxCommandEvent event2( wxEVT_RADIOBUTTON );
327 event2.SetEventObject( attenPanel->GetAttenuatorsSelector() );
328 event2.SetInt( i );
329
330 attenPanel->GetAttenuatorsSelector()->Command( event2 );
331 break;
332 }
333 }
334
335 attenPanel->UpdateUI();
336 viaSizePanel->Layout();
337 regulPanel->Layout();
338
339 // Until it's shown on screen the above won't work; but doing it anyway at least keeps
340 // putting new OnUpdateUI events into the queue until it *is* shown on screen.
341 if( m_treebook->IsShownOnScreen() )
342 m_lastNotebookPage = m_treebook->GetSelection();
343 }
344}
345
346
347void PCB_CALCULATOR_FRAME::OnClosePcbCalc( wxCloseEvent& event )
348{
349 PANEL_REGULATOR* regPanel = GetCalculator<PANEL_REGULATOR>();
350
351 wxASSERT( regPanel );
352
353 if( regPanel->m_RegulatorListChanged )
354 {
355 wxString msg;
356 wxString title = _( "Write Data Failed" );
357
358 if( regPanel->GetDataFilename().IsEmpty() )
359 {
360 msg = _( "No data filename to save modifications.\n"
361 "Do you want to exit and abandon your changes?" );
362
363 if( wxMessageBox( msg, title, wxYES_NO | wxICON_QUESTION ) == wxNO )
364 return;
365 }
366 else
367 {
368 if( !regPanel->WriteDataFile() )
369 {
370 msg.Printf( _( "Unable to write file '%s'\n"
371 "Do you want to exit and abandon your changes?"),
372 regPanel->GetDataFilename() );
373
374 if( wxMessageBox( msg, title, wxYES_NO | wxICON_ERROR ) == wxNO )
375 return;
376 }
377 }
378 }
379
380 event.Skip();
381}
382
383
385{
386 if( aCfg == nullptr )
387 return;
388
390
391 PCB_CALCULATOR_SETTINGS* cfg = static_cast<PCB_CALCULATOR_SETTINGS*>( aCfg );
392
393 m_treebook->ChangeSelection( cfg->m_LastPage );
394
395 for( CALCULATOR_PANEL* panel : m_panels )
396 panel->LoadSettings( cfg );
397}
398
399
401{
402 if( aCfg == nullptr )
403 return;
404
406
407 // Save current parameters values in config.
408 auto cfg = dynamic_cast<PCB_CALCULATOR_SETTINGS*>( Kiface().KifaceSettings() );
409
410 if( cfg )
411 {
412 cfg->m_LastPage = m_treebook->GetSelection();
413
414 for( CALCULATOR_PANEL* panel : m_panels )
415 panel->SaveSettings( cfg );
416 }
417
418}
constexpr EDA_IU_SCALE unityScale
Definition: base_units.h:112
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:187
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:53
A wxFrame capable of the OpenProjectFiles function, meaning it can load a portion of a KiCad project.
Definition: kiway_player.h:67
A minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the same KiCad...
Definition: kiway.h:279
void OnKiCadExit()
Definition: kiway.cpp:737
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:165
Master controller class:
Definition: tool_manager.h:57
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:46
#define _HKI(x)
#define _(s)
@ FRAME_CALC
Definition: frame_type.h:63
wxFont GetControlFont(wxWindow *aWindow)
Definition: ui_common.cpp:157
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