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