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 The 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>
37
52#include "widgets/wx_menubar.h"
53
54
55BEGIN_EVENT_TABLE( PCB_CALCULATOR_FRAME, KIWAY_PLAYER )
56 EVT_MENU( wxID_CLOSE, PCB_CALCULATOR_FRAME::OnExit )
57 EVT_MENU( wxID_EXIT, PCB_CALCULATOR_FRAME::OnExit )
58END_EVENT_TABLE()
59
60
61PCB_CALCULATOR_FRAME::PCB_CALCULATOR_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
62 KIWAY_PLAYER( aKiway, aParent, FRAME_CALC, _( "Calculator Tools" ), wxDefaultPosition,
63 wxDefaultSize,
64 wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxFULL_REPAINT_ON_RESIZE|wxTAB_TRAVERSAL,
65 wxT( "calculator_tools" ), unityScale ),
67{
68 m_aboutTitle = _HKI( "KiCad Calculator Tools" );
69
70 SHAPE_POLY_SET dummy; // A ugly trick to force the linker to include
71 // some methods in code and avoid link errors
72
73 SetSizeHints( wxDefaultSize, wxDefaultSize );
74
75 m_mainSizer = new wxBoxSizer( wxVERTICAL );
76
77 m_treebook = new wxTreebook( this, wxID_ANY );
78 m_treebook->SetFont( KIUI::GetControlFont( this ) );
79 m_mainSizer->Add( m_treebook, 1, wxEXPAND | wxLEFT | wxTOP, 0 );
80
81 SetSizer( m_mainSizer );
82 Layout();
83 Centre( wxBOTH );
84
85 loadPages();
86
87 // Give an icon
88 wxIcon icon;
89 wxIconBundle icon_bundle;
90
91 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_pcbcalculator, 48 ) );
92 icon_bundle.AddIcon( icon );
93 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_pcbcalculator, 128 ) );
94 icon_bundle.AddIcon( icon );
95 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_pcbcalculator, 256 ) );
96 icon_bundle.AddIcon( icon );
97 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_pcbcalculator_32 ) );
98 icon_bundle.AddIcon( icon );
99 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_pcbcalculator_16 ) );
100 icon_bundle.AddIcon( icon );
101
102 SetIcons( icon_bundle );
103
105 m_toolManager->SetEnvironment( nullptr, nullptr, nullptr, config(), this );
106
108
109 // Register tools
110 m_toolManager->RegisterTool( new COMMON_CONTROL );
111 m_toolManager->InitTools();
112
115
116 GetSizer()->SetSizeHints( this );
117
118 // Set previous size and position
119 SetSize( m_framePos.x, m_framePos.y, m_frameSize.x, m_frameSize.y );
120
121 if( m_framePos == wxDefaultPosition )
122 Centre();
123
124 // Expand treebook to show all options:
125 for( size_t pageId = 0; pageId < m_treebook->GetPageCount(); pageId++ )
126 m_treebook->ExpandNode( pageId );
127
128 // Connect Events
129 Bind( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( PCB_CALCULATOR_FRAME::OnClosePcbCalc ), this );
130 Bind( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( PCB_CALCULATOR_FRAME::OnUpdateUI ), this );
131
132 Bind( wxEVT_SYS_COLOUR_CHANGED,
133 wxSysColourChangedEventHandler( PCB_CALCULATOR_FRAME::onThemeChanged ), this );
134
135 m_treebook->Connect( wxEVT_COMMAND_TREEBOOK_PAGE_CHANGED, wxTreebookEventHandler(
136 PCB_CALCULATOR_FRAME::OnPageChanged ), nullptr, this );
137}
138
139
141{
142 m_treebook->Disconnect( wxEVT_COMMAND_TREEBOOK_PAGE_CHANGED, wxTreebookEventHandler(
143 PCB_CALCULATOR_FRAME::OnPageChanged ), nullptr, this );
144 // This needed for OSX: avoids further OnDraw processing after this destructor and before
145 // the native window is destroyed
146 this->Freeze();
147
148 // Clean up the tool framework
149 delete m_toolManager;
150 delete m_toolDispatcher;
151}
152
153
154void PCB_CALCULATOR_FRAME::OnExit( wxCommandEvent& aEvent )
155{
156 Close( false );
157}
158
159
161{
162 m_treebook->AddPage( nullptr, _( "General system design" ) );
163
164 AddCalculator( new PANEL_REGULATOR( m_treebook ), _( "Regulators" ) );
165 AddCalculator( new PANEL_R_CALCULATOR( m_treebook ), _( "Resistor Calculator" ) );
166
167 m_treebook->AddPage( nullptr, _( "Power, current and isolation" ) );
168
169 AddCalculator( new PANEL_ELECTRICAL_SPACING( m_treebook ), _( "Electrical Spacing" ) );
170 AddCalculator( new PANEL_VIA_SIZE( m_treebook ), _( "Via Size" ) );
171 AddCalculator( new PANEL_TRACK_WIDTH( m_treebook ), _( "Track Width" ) );
172 AddCalculator( new PANEL_FUSING_CURRENT( m_treebook ), _( "Fusing Current" ) );
173 AddCalculator( new PANEL_CABLE_SIZE( m_treebook ), _( "Cable Size" ) );
174
175 m_treebook->AddPage( nullptr, _( "High Speed" ) );
176
177 AddCalculator( new PANEL_WAVELENGTH( m_treebook ), _( "Wavelength" ) );
178 AddCalculator( new PANEL_RF_ATTENUATORS( m_treebook ), _( "RF Attenuators" ) );
179 AddCalculator( new PANEL_TRANSLINE( m_treebook ), _( "Transmission Lines") );
180
181 m_treebook->AddPage( nullptr, _( "Memo" ) );
182
183 AddCalculator( new PANEL_ESERIES_DISPLAY( m_treebook ), _( "E-Series" ) );
184 AddCalculator( new PANEL_COLOR_CODE( m_treebook ), _( "Color Code" ) );
185 AddCalculator( new PANEL_BOARD_CLASS( m_treebook ), _( "Board Classes" ) );
186 AddCalculator( new PANEL_GALVANIC_CORROSION( m_treebook ), _( "Galvanic Corrosion" ) );
187
188 LoadSettings( config() );
189
191 regPanel->ReadDataFile();
192}
193
194
196{
197 COMMON_CONTROL* tool = m_toolManager->GetTool<COMMON_CONTROL>();
198 EDA_BASE_FRAME* base_frame = dynamic_cast<EDA_BASE_FRAME*>( this );
199
200 // base_frame == nullptr should not happen, but it makes Coverity happy
201 wxCHECK( base_frame, /* void */ );
202
203 // wxWidgets handles the OSX Application menu behind the scenes, but that means
204 // we always have to start from scratch with a new wxMenuBar.
205 wxMenuBar* oldMenuBar = base_frame->GetMenuBar();
206 WX_MENUBAR* menuBar = new WX_MENUBAR();
207
208 //-- File menu -----------------------------------------------------------
209 //
210 ACTION_MENU* fileMenu = new ACTION_MENU( false, tool );
211
212 fileMenu->AddClose( _( "Calculator Tools" ) );
213 fileMenu->AddQuit( _( "Calculator Tools" ) );
214
215 //-- Preferences menu -----------------------------------------------
216 //
217 ACTION_MENU* prefsMenu = new ACTION_MENU( false, tool );
218
219 prefsMenu->Add( ACTIONS::openPreferences );
220
221 prefsMenu->AppendSeparator();
222 AddMenuLanguageList( prefsMenu, tool );
223
224
225 //-- Menubar -------------------------------------------------------------
226 //
227 menuBar->Append( fileMenu, _( "&File" ) );
228 menuBar->Append( prefsMenu, _( "&Preferences" ) );
229 base_frame->AddStandardHelpMenu( menuBar );
230
231 base_frame->SetMenuBar( menuBar );
232 delete oldMenuBar;
233}
234
235
237{
239
240 SetTitle( _( "Calculator Tools" ) );
241
242 SaveSettings( config() );
243 Freeze();
244
245 int page = m_treebook->GetSelection();
246 m_treebook->DeleteAllPages();
247 m_panels.clear();
248
249 loadPages();
250 Layout();
251
252 m_treebook->SetSelection( page );
253 LoadSettings( config() );
254
255 Thaw();
256 Refresh();
257}
258
259
260void PCB_CALCULATOR_FRAME::OnPageChanged ( wxTreebookEvent& aEvent )
261{
262 int page = aEvent.GetSelection();
263
264 // If the selected page is a top level page
265 if ( m_treebook->GetPageParent( page ) == wxNOT_FOUND )
266 {
267 m_treebook->ExpandNode( page );
268
269 // Select the first child
270 if( page + 1 < m_treebook->GetPageCount() )
271 m_treebook->ChangeSelection( page + 1 );
272 }
273}
274
275
276void PCB_CALCULATOR_FRAME::AddCalculator( CALCULATOR_PANEL *aPanel, const wxString& panelUIName )
277{
278 // Update internal structures
279 m_panels.push_back( aPanel );
280 m_panelTypes[ typeid( *aPanel ).hash_code() ] = aPanel;
281
282 m_treebook->AddSubPage( aPanel, panelUIName );
283}
284
285
286void PCB_CALCULATOR_FRAME::onThemeChanged( wxSysColourChangedEvent& aEvent )
287{
288 // Force the bitmaps to refresh
290
291 // Update the panels
292 for( auto& panel : m_panels )
293 panel->ThemeChanged();
294
295 aEvent.Skip();
296}
297
298
299void PCB_CALCULATOR_FRAME::OnUpdateUI( wxUpdateUIEvent& event )
300{
301 if( m_treebook->GetSelection() != m_lastNotebookPage )
302 {
303 // Kick all the things that wxWidgets can't seem to redraw on its own.
304 // This is getting seriously ridiculous....
309
310 wxASSERT( translinePanel );
311 wxASSERT( attenPanel );
312 wxASSERT( viaSizePanel );
313 wxASSERT( regulPanel );
314
315 {
316 wxCommandEvent event2( wxEVT_RADIOBUTTON );
317 event2.SetEventObject( translinePanel->GetTranslineSelector() );
318 event2.SetInt( translinePanel->GetCurrTransLineType() );
319
320 translinePanel->GetTranslineSelector()->Command( event2 );
321 }
322
323 for( int i = 0; i < attenPanel->m_AttenuatorList.size(); ++i )
324 {
325 if( attenPanel->m_AttenuatorList[i] == attenPanel->m_CurrAttenuator )
326 {
327 wxCommandEvent event2( wxEVT_RADIOBUTTON );
328 event2.SetEventObject( attenPanel->GetAttenuatorsSelector() );
329 event2.SetInt( i );
330
331 attenPanel->GetAttenuatorsSelector()->Command( event2 );
332 break;
333 }
334 }
335
336 attenPanel->UpdateUI();
337 viaSizePanel->Layout();
338 regulPanel->Layout();
339
340 // Until it's shown on screen the above won't work; but doing it anyway at least keeps
341 // putting new OnUpdateUI events into the queue until it *is* shown on screen.
342 if( m_treebook->IsShownOnScreen() )
343 m_lastNotebookPage = m_treebook->GetSelection();
344 }
345}
346
347
348void PCB_CALCULATOR_FRAME::OnClosePcbCalc( wxCloseEvent& event )
349{
351
352 wxASSERT( regPanel );
353
354 if( regPanel->m_RegulatorListChanged )
355 {
356 wxString msg;
357 wxString title = _( "Write Data Failed" );
358
359 if( regPanel->GetDataFilename().IsEmpty() )
360 {
361 msg = _( "No data filename to save modifications.\n"
362 "Do you want to exit and abandon your changes?" );
363
364 if( wxMessageBox( msg, title, wxYES_NO | wxICON_QUESTION ) == wxNO )
365 return;
366 }
367 else
368 {
369 if( !regPanel->WriteDataFile() )
370 {
371 msg.Printf( _( "Unable to write file '%s'\n"
372 "Do you want to exit and abandon your changes?"),
373 regPanel->GetDataFilename() );
374
375 if( wxMessageBox( msg, title, wxYES_NO | wxICON_ERROR ) == wxNO )
376 return;
377 }
378 }
379 }
380
381 event.Skip();
382}
383
384
386{
387 if( aCfg == nullptr )
388 return;
389
391
392 PCB_CALCULATOR_SETTINGS* cfg = static_cast<PCB_CALCULATOR_SETTINGS*>( aCfg );
393
394 m_treebook->ChangeSelection( cfg->m_LastPage );
395
396 for( CALCULATOR_PANEL* panel : m_panels )
397 panel->LoadSettings( cfg );
398}
399
400
402{
403 if( aCfg == nullptr )
404 return;
405
407
408 // Save current parameters values in config.
409 auto cfg = dynamic_cast<PCB_CALCULATOR_SETTINGS*>( Kiface().KifaceSettings() );
410
411 if( cfg )
412 {
413 cfg->m_LastPage = m_treebook->GetSelection();
414
415 for( CALCULATOR_PANEL* panel : m_panels )
416 panel->SaveSettings( cfg );
417 }
418
419}
constexpr EDA_IU_SCALE unityScale
Definition base_units.h:115
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:280
Define the structure of a menu based on ACTIONs.
Definition action_menu.h:47
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.
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.
virtual APP_SETTINGS_BASE * config() const
Return 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.
virtual void setupUIConditions()
Setup the UI conditions for the various actions and their controls in this frame.
EDA_BASE_FRAME(wxWindow *aParent, FRAME_T aFrameType, const wxString &aTitle, const wxPoint &aPos, const wxSize &aSize, long aStyle, const wxString &aFrameName, KIWAY *aKiway, const EDA_IU_SCALE &aIuScale)
void AddMenuLanguageList(ACTION_MENU *aMasterMenu, TOOL_INTERACTIVE *aControlTool)
Create a menu list for language choice, and add it as submenu to MasterMenu.
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.
wxString m_aboutTitle
void ReCreateMenuBar()
Recreate the menu bar.
APP_SETTINGS_BASE * KifaceSettings() const
Definition kiface_base.h:95
A wxFrame capable of the OpenProjectFiles function, meaning it can load a portion of a KiCad project.
KIWAY_PLAYER(KIWAY *aKiway, wxWindow *aParent, FRAME_T aFrameType, const wxString &aTitle, const wxPoint &aPos, const wxSize &aSize, long aStyle, const wxString &aFrameName, const EDA_IU_SCALE &aIuScale)
A minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the same KiCad...
Definition kiway.h:294
const wxString GetDataFilename()
std::vector< ATTENUATOR * > m_AttenuatorList
wxRadioBox * GetAttenuatorsSelector()
wxRadioBox * GetTranslineSelector()
TRANSLINE_TYPE_ID GetCurrTransLineType()
PCB calculator the main frame.
void OnPageChanged(wxTreebookEvent &aEvent)
PCB_CALCULATOR_FRAME(KIWAY *aKiway, wxWindow *aParent)
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
TOOL_DISPATCHER * m_toolDispatcher
Master controller class:
Wrapper around a wxMenuBar object that prevents the accelerator table from being used.
Definition wx_menubar.h:47
#define _(s)
@ FRAME_CALC
Definition frame_type.h:63
KICOMMON_API wxFont GetControlFont(wxWindow *aWindow)
#define _HKI(x)
Definition page_info.cpp:44
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