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>
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 ),
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
106 m_toolManager->SetEnvironment( nullptr, nullptr, nullptr, config(), this );
107
109
110 // Register tools
111 m_toolManager->RegisterTool( new COMMON_CONTROL );
112 m_toolManager->RegisterTool( new PCB_CALCULATOR_CONTROL );
113 m_toolManager->InitTools();
114
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 // Clean up the tool framework
151 delete m_toolManager;
152 delete m_toolDispatcher;
153}
154
155
156void PCB_CALCULATOR_FRAME::OnExit( wxCommandEvent& aEvent )
157{
158 if( aEvent.GetId() == wxID_EXIT )
159 Kiway().OnKiCadExit();
160
161 if( aEvent.GetId() == wxID_CLOSE || Kiface().IsSingle() )
162 Close( false );
163}
164
165
167{
168 m_treebook->AddPage( nullptr, _( "General system design" ) );
169
170 AddCalculator( new PANEL_REGULATOR( m_treebook ), _( "Regulators" ) );
171 AddCalculator( new PANEL_R_CALCULATOR( m_treebook ), _( "Resistor Calculator" ) );
172
173 m_treebook->AddPage( nullptr, _( "Power, current and isolation" ) );
174
175 AddCalculator( new PANEL_ELECTRICAL_SPACING( m_treebook ), _( "Electrical Spacing" ) );
176 AddCalculator( new PANEL_VIA_SIZE( m_treebook ), _( "Via Size" ) );
177 AddCalculator( new PANEL_TRACK_WIDTH( m_treebook ), _( "Track Width" ) );
178 AddCalculator( new PANEL_FUSING_CURRENT( m_treebook ), _( "Fusing Current" ) );
179 AddCalculator( new PANEL_CABLE_SIZE( m_treebook ), _( "Cable Size" ) );
180
181 m_treebook->AddPage( nullptr, _( "High Speed" ) );
182
183 AddCalculator( new PANEL_WAVELENGTH( m_treebook ), _( "Wavelength" ) );
184 AddCalculator( new PANEL_RF_ATTENUATORS( m_treebook ), _( "RF Attenuators" ) );
185 AddCalculator( new PANEL_TRANSLINE( m_treebook ), _( "Transmission Lines") );
186
187 m_treebook->AddPage( nullptr, _( "Memo" ) );
188
189 AddCalculator( new PANEL_ESERIES_DISPLAY( m_treebook ), _( "E-Series" ) );
190 AddCalculator( new PANEL_COLOR_CODE( m_treebook ), _( "Color Code" ) );
191 AddCalculator( new PANEL_BOARD_CLASS( m_treebook ), _( "Board Classes" ) );
192 AddCalculator( new PANEL_GALVANIC_CORROSION( m_treebook ), _( "Galvanic Corrosion" ) );
193
194 LoadSettings( config() );
195
197 regPanel->ReadDataFile();
198}
199
200
202{
203 COMMON_CONTROL* tool = m_toolManager->GetTool<COMMON_CONTROL>();
204 EDA_BASE_FRAME* base_frame = dynamic_cast<EDA_BASE_FRAME*>( this );
205
206 // base_frame == nullptr should not happen, but it makes Coverity happy
207 wxCHECK( base_frame, /* void */ );
208
209 // wxWidgets handles the OSX Application menu behind the scenes, but that means
210 // we always have to start from scratch with a new wxMenuBar.
211 wxMenuBar* oldMenuBar = base_frame->GetMenuBar();
212 WX_MENUBAR* menuBar = new WX_MENUBAR();
213
214 //-- File menu -----------------------------------------------------------
215 //
216 ACTION_MENU* fileMenu = new ACTION_MENU( false, tool );
217
218 fileMenu->AddClose( _( "Calculator Tools" ) );
219 fileMenu->AddQuit( _( "Calculator Tools" ) );
220
221 //-- Preferences menu -----------------------------------------------
222 //
223 ACTION_MENU* prefsMenu = new ACTION_MENU( false, tool );
224
225 prefsMenu->Add( ACTIONS::openPreferences );
226
227 prefsMenu->AppendSeparator();
228 AddMenuLanguageList( prefsMenu, tool );
229
230
231 //-- Menubar -------------------------------------------------------------
232 //
233 menuBar->Append( fileMenu, _( "&File" ) );
234 menuBar->Append( prefsMenu, _( "&Preferences" ) );
235 base_frame->AddStandardHelpMenu( menuBar );
236
237 base_frame->SetMenuBar( menuBar );
238 delete oldMenuBar;
239}
240
241
243{
245
246 SetTitle( _( "Calculator Tools" ) );
247
248 SaveSettings( config() );
249 Freeze();
250
251 int page = m_treebook->GetSelection();
252 m_treebook->DeleteAllPages();
253 m_panels.clear();
254
255 loadPages();
256 Layout();
257
258 m_treebook->SetSelection( page );
259 LoadSettings( config() );
260
261 Thaw();
262 Refresh();
263}
264
265
266void PCB_CALCULATOR_FRAME::OnPageChanged ( wxTreebookEvent& aEvent )
267{
268 int page = aEvent.GetSelection();
269
270 // If the selected page is a top level page
271 if ( m_treebook->GetPageParent( page ) == wxNOT_FOUND )
272 {
273 m_treebook->ExpandNode( page );
274
275 // Select the first child
276 if( page + 1 < m_treebook->GetPageCount() )
277 m_treebook->ChangeSelection( page + 1 );
278 }
279}
280
281
282void PCB_CALCULATOR_FRAME::AddCalculator( CALCULATOR_PANEL *aPanel, const wxString& panelUIName )
283{
284 // Update internal structures
285 m_panels.push_back( aPanel );
286 m_panelTypes[ typeid( *aPanel ).hash_code() ] = aPanel;
287
288 m_treebook->AddSubPage( aPanel, panelUIName );
289}
290
291
292void PCB_CALCULATOR_FRAME::onThemeChanged( wxSysColourChangedEvent& aEvent )
293{
294 // Force the bitmaps to refresh
296
297 // Update the panels
298 for( auto& panel : m_panels )
299 panel->ThemeChanged();
300
301 aEvent.Skip();
302}
303
304
305void PCB_CALCULATOR_FRAME::OnUpdateUI( wxUpdateUIEvent& event )
306{
307 if( m_treebook->GetSelection() != m_lastNotebookPage )
308 {
309 // Kick all the things that wxWidgets can't seem to redraw on its own.
310 // This is getting seriously ridiculous....
315
316 wxASSERT( translinePanel );
317 wxASSERT( attenPanel );
318 wxASSERT( viaSizePanel );
319 wxASSERT( regulPanel );
320
321 {
322 wxCommandEvent event2( wxEVT_RADIOBUTTON );
323 event2.SetEventObject( translinePanel->GetTranslineSelector() );
324 event2.SetInt( translinePanel->GetCurrTransLineType() );
325
326 translinePanel->GetTranslineSelector()->Command( event2 );
327 }
328
329 for( int i = 0; i < attenPanel->m_AttenuatorList.size(); ++i )
330 {
331 if( attenPanel->m_AttenuatorList[i] == attenPanel->m_CurrAttenuator )
332 {
333 wxCommandEvent event2( wxEVT_RADIOBUTTON );
334 event2.SetEventObject( attenPanel->GetAttenuatorsSelector() );
335 event2.SetInt( i );
336
337 attenPanel->GetAttenuatorsSelector()->Command( event2 );
338 break;
339 }
340 }
341
342 attenPanel->UpdateUI();
343 viaSizePanel->Layout();
344 regulPanel->Layout();
345
346 // Until it's shown on screen the above won't work; but doing it anyway at least keeps
347 // putting new OnUpdateUI events into the queue until it *is* shown on screen.
348 if( m_treebook->IsShownOnScreen() )
349 m_lastNotebookPage = m_treebook->GetSelection();
350 }
351}
352
353
354void PCB_CALCULATOR_FRAME::OnClosePcbCalc( wxCloseEvent& event )
355{
357
358 wxASSERT( regPanel );
359
360 if( regPanel->m_RegulatorListChanged )
361 {
362 wxString msg;
363 wxString title = _( "Write Data Failed" );
364
365 if( regPanel->GetDataFilename().IsEmpty() )
366 {
367 msg = _( "No data filename to save modifications.\n"
368 "Do you want to exit and abandon your changes?" );
369
370 if( wxMessageBox( msg, title, wxYES_NO | wxICON_QUESTION ) == wxNO )
371 return;
372 }
373 else
374 {
375 if( !regPanel->WriteDataFile() )
376 {
377 msg.Printf( _( "Unable to write file '%s'\n"
378 "Do you want to exit and abandon your changes?"),
379 regPanel->GetDataFilename() );
380
381 if( wxMessageBox( msg, title, wxYES_NO | wxICON_ERROR ) == wxNO )
382 return;
383 }
384 }
385 }
386
387 event.Skip();
388}
389
390
392{
393 if( aCfg == nullptr )
394 return;
395
397
398 PCB_CALCULATOR_SETTINGS* cfg = static_cast<PCB_CALCULATOR_SETTINGS*>( aCfg );
399
400 m_treebook->ChangeSelection( cfg->m_LastPage );
401
402 for( CALCULATOR_PANEL* panel : m_panels )
403 panel->LoadSettings( cfg );
404}
405
406
408{
409 if( aCfg == nullptr )
410 return;
411
413
414 // Save current parameters values in config.
415 auto cfg = dynamic_cast<PCB_CALCULATOR_SETTINGS*>( Kiface().KifaceSettings() );
416
417 if( cfg )
418 {
419 cfg->m_LastPage = m_treebook->GetSelection();
420
421 for( CALCULATOR_PANEL* panel : m_panels )
422 panel->SaveSettings( cfg );
423 }
424
425}
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
KIWAY & Kiway() const
Return a reference to the KIWAY that this object has an opportunity to participate in.
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:292
void OnKiCadExit()
Definition kiway.cpp:756
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 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