KiCad PCB EDA Suite
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-2022 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/menu.h>
21#include <wx/msgdlg.h>
22#include <wx/treebook.h>
23#include <wx/sizer.h>
24
25#include <typeinfo>
26
27#include <bitmaps.h>
28#include <bitmap_store.h>
30#include <kiface_base.h>
31
35
49
50
52 KIWAY_PLAYER( aParent, wxID_ANY,
53 _( "Calculator Tools" ), // Window title
54 wxDefaultPosition,
55 wxSize( 646,361 ), // Default size
56 wxDEFAULT_FRAME_STYLE | wxRESIZE_BORDER | wxFULL_REPAINT_ON_RESIZE | wxTAB_TRAVERSAL,
57 wxT( "calculator_tools" ) ), // Window name
58 m_lastNotebookPage( -1 )
59{
60 SHAPE_POLY_SET dummy; // A ugly trick to force the linker to include
61 // some methods in code and avoid link errors
62
63 SetKiway( this, aKiway );
64
65 SetSizeHints( wxDefaultSize, wxDefaultSize );
66
67
68 m_mainSizer = new wxBoxSizer( wxVERTICAL );
69
70
71 m_treebook = new wxTreebook( this, wxID_ANY );
72 m_treebook->SetFont( KIUI::GetControlFont( this ) );
73 m_mainSizer->Add( m_treebook, 1, wxEXPAND | wxLEFT | wxTOP, 0 );
74
75
76 SetSizer( m_mainSizer );
77 Layout();
78 Centre( wxBOTH );
79
80 m_treebook->AddPage( nullptr, _( "General system design" ) );
81
82 AddCalculator( new PANEL_REGULATOR( m_treebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ),
83 _( "Regulators" ) );
84
85 m_treebook->AddPage( nullptr, _( "Power, current and isolation" ) );
86
87 AddCalculator( new PANEL_ELECTRICAL_SPACING( m_treebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ),
88 _( "Electrical Spacing" ) );
89 AddCalculator( new PANEL_VIA_SIZE( m_treebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ),
90 _( "Via Size" ) );
91 AddCalculator( new PANEL_TRACK_WIDTH( m_treebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ),
92 _( "Track Width" ) );
93 AddCalculator( new PANEL_FUSING_CURRENT( m_treebook, wxID_ANY, wxDefaultPosition, wxDefaultSize,
94 wxTAB_TRAVERSAL ),
95 _( "Fusing Current" ) );
96 AddCalculator( new PANEL_CABLE_SIZE( m_treebook, wxID_ANY, wxDefaultPosition, wxDefaultSize,
97 wxTAB_TRAVERSAL ),
98 _( "Cable Size" ) );
99
100 m_treebook->AddPage( nullptr, _( "High speed" ) );
101
102 AddCalculator( new PANEL_WAVELENGTH( m_treebook, wxID_ANY, wxDefaultPosition, wxDefaultSize,
103 wxTAB_TRAVERSAL ),
104 _( "Wavelength" ) );
105 AddCalculator( new PANEL_ATTENUATORS( m_treebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ),
106 _( "RF Attenuators" ) );
107 AddCalculator( new PANEL_TRANSLINE( m_treebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ),
108 _( "Transmission Lines") );
109
110 m_treebook->AddPage( nullptr, _( "Memo" ) );
111
112 AddCalculator( new PANEL_E_SERIE( m_treebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ),
113 _( "E-Series" ) );
114 AddCalculator( new PANEL_COLOR_CODE( m_treebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ),
115 _( "Color Code" ) );
116 AddCalculator( new PANEL_BOARD_CLASS( m_treebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ),
117 _("Board Classes") );
118 AddCalculator( new PANEL_CORROSION( m_treebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ),
119 _( "Galvanic Corrosion" ) );
120
121 LoadSettings( config() );
122
123 if( PANEL_REGULATOR* regPanel = GetCalculator<PANEL_REGULATOR>() )
124 regPanel->ReadDataFile();
125
126 // Give an icon
127 wxIcon icon;
128 wxIconBundle icon_bundle;
129
130 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_pcbcalculator ) );
131 icon_bundle.AddIcon( icon );
132 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_pcbcalculator_32 ) );
133 icon_bundle.AddIcon( icon );
134 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_pcbcalculator_16 ) );
135 icon_bundle.AddIcon( icon );
136
137 SetIcons( icon_bundle );
138
139 GetSizer()->SetSizeHints( this );
140
141 // Set previous size and position
142 SetSize( m_framePos.x, m_framePos.y, m_frameSize.x, m_frameSize.y );
143
144 if( m_framePos == wxDefaultPosition )
145 Centre();
146
147 // Expand treebook to show all options:
148 for( size_t pageId = 0; pageId < m_treebook->GetPageCount(); pageId++ )
149 m_treebook->ExpandNode( pageId );
150
151 // Connect Events
152 Bind( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( PCB_CALCULATOR_FRAME::OnClosePcbCalc ), this );
153 Bind( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( PCB_CALCULATOR_FRAME::OnUpdateUI ), this );
154
155 Bind( wxEVT_SYS_COLOUR_CHANGED,
156 wxSysColourChangedEventHandler( PCB_CALCULATOR_FRAME::onThemeChanged ), this );
157
158 m_treebook->Connect( wxEVT_COMMAND_TREEBOOK_PAGE_CHANGED, wxTreebookEventHandler(
160}
161
162
164{
165 m_treebook->Disconnect( wxEVT_COMMAND_TREEBOOK_PAGE_CHANGED, wxTreebookEventHandler(
167 // This needed for OSX: avoids further OnDraw processing after this destructor and before
168 // the native window is destroyed
169 this->Freeze();
170}
171
172void PCB_CALCULATOR_FRAME::OnPageChanged ( wxTreebookEvent& aEvent )
173{
174 int page = aEvent.GetSelection();
175
176 // If the selected page is a top level page
177 if ( m_treebook->GetPageParent( page ) == wxNOT_FOUND )
178 {
179 m_treebook->ExpandNode( page );
180 // Select the first child
181 m_treebook->ChangeSelection( page + 1 );
182 }
183}
184
185void PCB_CALCULATOR_FRAME::AddCalculator( CALCULATOR_PANEL *aPanel, const wxString& panelUIName )
186{
187 // Update internal structures
188 m_panels.push_back( aPanel );
189 m_panelTypes[ typeid( *aPanel ).hash_code() ] = aPanel;
190
191 m_treebook->AddSubPage( aPanel, panelUIName );
192}
193
194
195void PCB_CALCULATOR_FRAME::onThemeChanged( wxSysColourChangedEvent& aEvent )
196{
197 // Force the bitmaps to refresh
199
200 // Update the panels
201 for( auto& panel : m_panels )
202 panel->ThemeChanged();
203
204 aEvent.Skip();
205}
206
207
208void PCB_CALCULATOR_FRAME::OnUpdateUI( wxUpdateUIEvent& event )
209{
210 if( m_treebook->GetSelection() != m_lastNotebookPage )
211 {
212 // Kick all the things that wxWidgets can't seem to redraw on its own.
213 // This is getting seriously ridiculous....
214 PANEL_TRANSLINE* translinePanel = GetCalculator<PANEL_TRANSLINE>();
215 PANEL_ATTENUATORS* attenPanel = GetCalculator<PANEL_ATTENUATORS>();
216 PANEL_VIA_SIZE* viaSizePanel = GetCalculator<PANEL_VIA_SIZE>();
217 PANEL_REGULATOR* regulPanel = GetCalculator<PANEL_REGULATOR>();
218 PANEL_ELECTRICAL_SPACING* elecSpacingPanel = GetCalculator<PANEL_ELECTRICAL_SPACING>();
219
220 wxASSERT( translinePanel );
221 wxASSERT( attenPanel );
222 wxASSERT( viaSizePanel );
223 wxASSERT( regulPanel );
224 wxASSERT( elecSpacingPanel );
225
226 {
227 wxCommandEvent event2( wxEVT_RADIOBUTTON );
228 event2.SetEventObject( translinePanel->GetTranslineSelector() );
229 event2.SetInt( translinePanel->GetCurrTransLineType() );
230
231 translinePanel->GetTranslineSelector()->Command( event2 );
232 }
233
234 for( int i = 0; i < attenPanel->m_AttenuatorList.size(); ++i )
235 {
236 if( attenPanel->m_AttenuatorList[i] == attenPanel->m_CurrAttenuator )
237 {
238 wxCommandEvent event2( wxEVT_RADIOBUTTON );
239 event2.SetEventObject( attenPanel->GetAttenuatorsSelector() );
240 event2.SetInt( i );
241
242 attenPanel->GetAttenuatorsSelector()->Command( event2 );
243 break;
244 }
245 }
246
247 attenPanel->UpdateUI();
248 viaSizePanel->Layout();
249 regulPanel->Layout();
250
251 // Until it's shown on screen the above won't work; but doing it anyway at least keeps
252 // putting new OnUpdateUI events into the queue until it *is* shown on screen.
253 if( m_treebook->IsShownOnScreen() )
254 m_lastNotebookPage = m_treebook->GetSelection();
255 }
256}
257
258
259void PCB_CALCULATOR_FRAME::OnClosePcbCalc( wxCloseEvent& event )
260{
261 PANEL_REGULATOR* regPanel = GetCalculator<PANEL_REGULATOR>();
262
263 wxASSERT( regPanel );
264
265 if( regPanel->m_RegulatorListChanged )
266 {
267 wxString msg;
268 wxString title = _( "Write Data Failed" );
269
270 if( regPanel->GetDataFilename().IsEmpty() )
271 {
272 msg = _( "No data filename to save modifications.\n"
273 "Do you want to exit and abandon your changes?" );
274
275 if( wxMessageBox( msg, title, wxYES_NO | wxICON_QUESTION ) == wxNO )
276 return;
277 }
278 else
279 {
280 if( !regPanel->WriteDataFile() )
281 {
282 msg.Printf( _( "Unable to write file '%s'\n"
283 "Do you want to exit and abandon your changes?"),
284 regPanel->GetDataFilename() );
285
286 if( wxMessageBox( msg, title, wxYES_NO | wxICON_ERROR ) == wxNO )
287 return;
288 }
289 }
290 }
291
292 event.Skip();
293}
294
295
297{
298 if( aCfg == nullptr )
299 return;
300
302
303 PCB_CALCULATOR_SETTINGS* cfg = static_cast<PCB_CALCULATOR_SETTINGS*>( aCfg );
304
305 m_treebook->ChangeSelection( cfg->m_LastPage );
306
307 for( auto& panel : m_panels )
308 panel->LoadSettings( cfg );
309}
310
311
313{
314 if( aCfg == nullptr )
315 return;
316
318
319 // Save current parameters values in config.
320 auto cfg = dynamic_cast<PCB_CALCULATOR_SETTINGS*>( Kiface().KifaceSettings() );
321
322 if( cfg )
323 {
324 cfg->m_LastPage = m_treebook->GetSelection();
325
326 for( auto& panel : m_panels )
327 panel->SaveSettings( cfg );
328 }
329
330}
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:105
BITMAP_STORE * GetBitmapStore()
Definition: bitmap.cpp:93
@ icon_pcbcalculator_16
@ icon_pcbcalculator_32
@ icon_pcbcalculator
APP_SETTINGS_BASE is a settings class that should be derived for each standalone KiCad application.
Definition: app_settings.h:101
void ThemeChanged()
Notifies the store that the icon theme has been changed by the user, so caches must be invalidated.
virtual APP_SETTINGS_BASE * config() const
Returns the settings object used in SaveSettings(), and is overloaded in KICAD_MANAGER_FRAME.
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:93
void SetKiway(wxWindow *aDest, KIWAY *aKiway)
It is only used for debugging, since "this" is not a wxWindow*.
A wxFrame capable of the OpenProjectFiles function, meaning it can load a portion of a KiCad project.
Definition: kiway_player.h:66
A minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the same KiCad...
Definition: kiway.h:267
ATTENUATOR * m_CurrAttenuator
wxRadioBox * GetAttenuatorsSelector()
std::vector< ATTENUATOR * > m_AttenuatorList
const wxString GetDataFilename()
wxRadioBox * GetTranslineSelector()
TRANSLINE_TYPE_ID GetCurrTransLineType()
void OnPageChanged(wxTreebookEvent &aEvent)
PCB_CALCULATOR_FRAME(KIWAY *aKiway, wxWindow *aParent)
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 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.
#define _(s)
wxFont GetControlFont(wxWindow *aWindow)
Definition: ui_common.cpp:150
static LIB_SYMBOL * dummy()
Used to draw a dummy shape when a LIB_SYMBOL is not found in library.
Definition: sch_symbol.cpp:74