KiCad PCB EDA Suite
transline_dlg_funct.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) 2011 jean-pierre.charras
5  * Copyright (C) 1992-2021 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/choicdlg.h>
21 #include <wx/filename.h>
22 #include <wx/settings.h>
23 
24 #include <bitmaps.h>
26 #include <common_data.h>
27 #include <widgets/unit_selector.h>
28 
29 
30 extern double DoubleFromString( const wxString& TextValue );
31 
32 
33 // Display a selection of usual Er, TanD, Rho values
34 // List format is <value><space><comment>
35 
36 
37 // A helper function to find the choice in a list of values
38 // return true if a index in aList that matches aValue is found.
39 static bool findMatch( wxArrayString& aList, const wxString& aValue, int& aIdx )
40 {
41  bool success = false;
42  // Find the previous choice index:
43  aIdx = 0;
44 
45  // Some countries use comma instead of point as separator.
46  // The value can be enter with pint or comma
47  // use point for string comparisons:
48  wxString cvalue = aValue;
49  cvalue.Replace( ',', '.' );
50 
51  // First compare strings:
52  for( wxString& text: aList )
53  {
54  if( text.IsEmpty() ) // No match found: select the empty line choice
55  break;
56 
57  wxString val_str = text.BeforeFirst( ' ' );
58  val_str.Replace( ',', '.' );
59 
60  // compare string values
61  if( val_str == cvalue )
62  {
63  success = true;
64  break;
65  }
66 
67  aIdx++;
68  }
69 
70  // Due to multiple ways to write a double, if string values
71  // do not match, compare double values
72  if( !success )
73  {
74  struct lconv* lc = localeconv();
75  char localeDecimalSeparator = *lc->decimal_point;
76 
77  if( localeDecimalSeparator == ',' )
78  cvalue.Replace( '.', ',' );
79 
80  double curr_value;
81  cvalue.ToDouble( &curr_value );
82 
83  aIdx = 0;
84 
85  for( wxString& text: aList )
86  {
87  if( text.IsEmpty() ) // No match found: select the empty line choice
88  break;
89 
90  double val;
91  wxString val_str = text.BeforeFirst( ' ' );
92 
93  if( localeDecimalSeparator == ',' )
94  val_str.Replace( '.', ',' );
95 
96  val_str.ToDouble( &val );;
97 
98  if( curr_value == val )
99  {
100  success = true;
101  break;
102  }
103 
104  aIdx++;
105  }
106  }
107 
108  return success;
109 }
110 
111 
112 void PANEL_TRANSLINE::OnTranslineEpsilonR_Button( wxCommandEvent& event )
113 {
114  wxArrayString list = StandardRelativeDielectricConstantList();
115  list.Add( "" ); // Add an empty line for no selection
116 
117  // Find the previous choice index:
118  wxString prevChoiceStr = m_Value_EpsilonR->GetValue();
119  int prevChoice = 0;
120  findMatch( list, prevChoiceStr, prevChoice );
121 
122  int index = wxGetSingleChoiceIndex( wxEmptyString, _( "Relative Dielectric Constants" ),
123  list, prevChoice );
124 
125  if( index >= 0 && !list.Item( index ).IsEmpty() ) // i.e. non canceled.
126  m_Value_EpsilonR->SetValue( list.Item( index ).BeforeFirst( ' ' ) );
127 }
128 
129 
130 void PANEL_TRANSLINE::OnTranslineTanD_Button( wxCommandEvent& event )
131 {
132  wxArrayString list = StandardLossTangentList();
133  list.Add( "" ); // Add an empty line for no selection
134 
135  // Find the previous choice index:
136  wxString prevChoiceStr = m_Value_TanD->GetValue();
137  int prevChoice = 0;
138  findMatch( list, prevChoiceStr, prevChoice );
139 
140  int index = wxGetSingleChoiceIndex( wxEmptyString, _( "Dielectric Loss Factor" ), list,
141  prevChoice, nullptr );
142 
143  if( index >= 0 && !list.Item( index ).IsEmpty() ) // i.e. non canceled.
144  m_Value_TanD->SetValue( list.Item( index ).BeforeFirst( ' ' ) );
145 }
146 
147 
148 void PANEL_TRANSLINE::OnTranslineRho_Button( wxCommandEvent& event )
149 {
150  wxArrayString list = StandardResistivityList();
151  list.Add( "" ); // Add an empty line for no selection
152 
153  // Find the previous choice index:
154  wxString prevChoiceStr = m_Value_Rho->GetValue();
155  int prevChoice = 0;
156  findMatch( list, prevChoiceStr, prevChoice );
157 
158  int index = wxGetSingleChoiceIndex( wxEmptyString, _( "Specific Resistance" ), list,
159  prevChoice, nullptr );
160 
161  if( index >= 0 && !list.Item( index ).IsEmpty() ) // i.e. non canceled.
162  m_Value_Rho->SetValue( list.Item( index ).BeforeFirst( ' ' ) );
163 }
164 
165 
166 // Minor helper struct to handle dialog items for a given parameter
168 {
169  wxStaticText* name;
170  wxTextCtrl* value;
172 };
173 
174 
176 {
177  m_currTransLineType = aType;
178 
181  {
183  }
184 
185  m_translineBitmap->SetBitmap( KiBitmap( m_transline_list[m_currTransLineType]->m_BitmapName ) );
186 
187  // This helper bitmap is shown for coupled microstrip only:
190 
192  m_currTransLine = tr_ident->m_TLine;
193 
194  m_radioBtnPrm1->Show( tr_ident->m_HasPrmSelection );
195  m_radioBtnPrm2->Show( tr_ident->m_HasPrmSelection );
196 
197  // Setup messages
198  wxStaticText* left_msg_list[] =
199  {
202  };
203 
204  wxStaticText* msg_list[] =
205  {
207  };
208 
209  unsigned jj = 0;
210 
211  for( ; jj < tr_ident->m_Messages.GetCount(); jj++ )
212  {
213  if( left_msg_list[jj] == nullptr )
214  break;
215 
216  left_msg_list[jj]->SetLabel( tr_ident->m_Messages[jj] );
217  msg_list[jj]->SetLabel( wxEmptyString );
218  }
219 
220  while( left_msg_list[jj] )
221  {
222  left_msg_list[jj]->SetLabel( wxEmptyString );
223  msg_list[jj]->SetLabel( wxEmptyString );
224  jj++;
225  }
226 
227 
228  // Init parameters dialog items
229  struct DLG_PRM_DATA substrateprms[] =
230  {
231  { m_EpsilonR_label, m_Value_EpsilonR, nullptr },
232  { m_TanD_label, m_Value_TanD, nullptr },
233  { m_Rho_label, m_Value_Rho, nullptr },
240  };
241 
242 #define substrateprms_cnt (sizeof(substrateprms)/sizeof(substrateprms[0]))
243 
244  struct DLG_PRM_DATA physprms[] =
245  {
249  };
250 
251 #define physprms_cnt (sizeof(physprms)/sizeof(physprms[0]))
252 
253  struct DLG_PRM_DATA elecprms[] =
254  {
258  };
259 
260 #define elecprms_cnt (sizeof(elecprms)/sizeof(elecprms[0]))
261 
262  struct DLG_PRM_DATA frequencyprms[] =
263  {
265  };
266 
267 #define frequencyprms_cnt (sizeof(frequencyprms)/sizeof(frequencyprms[0]))
268 
269  unsigned idxsubs = 0;
270  unsigned idxphys = 0;
271  unsigned idxelec = 0;
272  unsigned idxfreq = 0;
273 
274  for( unsigned ii = 0; ii < tr_ident->GetPrmsCount(); ii++ )
275  {
276  TRANSLINE_PRM* prm = tr_ident->GetPrm( ii );
277  struct DLG_PRM_DATA * data = nullptr;
278 
279  switch( prm->m_Type )
280  {
281  case PRM_TYPE_SUBS:
282  wxASSERT( idxsubs < substrateprms_cnt );
283  data = &substrateprms[idxsubs];
284  idxsubs++;
285  break;
286 
287  case PRM_TYPE_PHYS:
288  wxASSERT( idxphys < physprms_cnt );
289  data = &physprms[idxphys];
290  idxphys++;
291  break;
292 
293  case PRM_TYPE_ELEC:
294  wxASSERT( idxelec < elecprms_cnt );
295  data = &elecprms[idxelec];
296  idxelec++;
297  break;
298 
299  case PRM_TYPE_FREQUENCY:
300  wxASSERT( idxfreq < frequencyprms_cnt );
301  data = &frequencyprms[idxfreq];
302  idxfreq++;
303  break;
304  }
305 
306  wxASSERT ( data );
307  data->name->SetToolTip( prm->m_ToolTip );
308  data->name->SetLabel( prm->m_DlgLabel != "" ? prm->m_DlgLabel + ':' : "" );
309  prm->m_ValueCtrl = data->value;
310 
311  if( prm->m_Id != DUMMY_PRM )
312  {
313  data->value->SetValue( wxString::Format( "%g", prm->m_Value ) );
314  data->value->Enable( true );
315  }
316  else
317  {
318  data->value->SetValue( wxEmptyString );
319  data->value->Enable( false );
320  }
321 
322  if( prm->m_ConvUnit )
323  prm->m_UnitCtrl = data->unit;
324 
325  if( data->unit )
326  {
327  data->unit->Show( prm->m_ConvUnit );
328  data->unit->Enable( prm->m_ConvUnit );
329  data->unit->SetSelection( prm->m_UnitSelection );
330  }
331  }
332 
333  // Clear all unused params
334  for( ; idxsubs < substrateprms_cnt; idxsubs++ )
335  {
336  substrateprms[idxsubs].name->SetLabel(wxEmptyString);
337  substrateprms[idxsubs].name->SetToolTip(wxEmptyString);
338  substrateprms[idxsubs].value->SetValue(wxEmptyString);
339  substrateprms[idxsubs].value->Enable( false );
340 
341  if( substrateprms[idxsubs].unit)
342  {
343  substrateprms[idxsubs].unit->Show( false );
344  substrateprms[idxsubs].unit->Enable( false );
345  substrateprms[idxsubs].unit->SetSelection( 0 );
346  }
347  }
348 
349  for( ; idxphys < physprms_cnt; idxphys++ )
350  {
351  physprms[idxphys].name->SetLabel(wxEmptyString);
352  physprms[idxphys].name->SetToolTip(wxEmptyString);
353  physprms[idxphys].value->SetValue(wxEmptyString);
354  physprms[idxphys].value->Enable( false );
355 
356  if( physprms[idxphys].unit)
357  {
358  physprms[idxphys].unit->Show( false );
359  physprms[idxphys].unit->Enable( false );
360  physprms[idxphys].unit->SetSelection( 0 );
361  }
362  }
363 
364  for( ; idxelec < elecprms_cnt; idxelec++)
365  {
366  elecprms[idxelec].name->SetLabel(wxEmptyString);
367  elecprms[idxelec].name->SetToolTip(wxEmptyString);
368  elecprms[idxelec].value->SetValue(wxEmptyString);
369  elecprms[idxelec].value->Enable( false );
370 
371  if( elecprms[idxelec].unit)
372  {
373  elecprms[idxelec].unit->Show( false );
374  elecprms[idxelec].unit->Enable( false );
375  elecprms[idxelec].unit->SetSelection( 0 );
376  }
377  }
378 
379  for( ; idxfreq < frequencyprms_cnt; idxfreq++ )
380  {
381  frequencyprms[idxfreq].name->SetLabel(wxEmptyString);
382  frequencyprms[idxfreq].name->SetToolTip(wxEmptyString);
383  frequencyprms[idxfreq].value->SetValue(wxEmptyString);
384  frequencyprms[idxfreq].value->Enable( false );
385 
386  if( frequencyprms[idxfreq].unit )
387  {
388  frequencyprms[idxfreq].unit->Show( false );
389  frequencyprms[idxfreq].unit->Enable( false );
390  frequencyprms[idxfreq].unit->SetSelection( 0 );
391  }
392  }
393 }
394 
395 
397 {
399 
400  for( unsigned ii = 0; ii < tr_ident->GetPrmsCount(); ii++ )
401  {
402  TRANSLINE_PRM* prm = tr_ident->GetPrm( ii );
403  wxTextCtrl * value_ctrl = (wxTextCtrl * ) prm->m_ValueCtrl;
404  wxString value_txt = value_ctrl->GetValue();
405  double value = DoubleFromString(value_txt);
406  prm->m_Value = value;
407  UNIT_SELECTOR * unit_ctrl = (UNIT_SELECTOR * ) prm->m_UnitCtrl;
408 
409  if( unit_ctrl )
410  {
411  prm->m_UnitSelection = unit_ctrl->GetSelection();
412  value *= unit_ctrl->GetUnitScale();
413  }
414 
415  prm->m_NormalizedValue = value;
416  }
417 }
418 
419 
420 void PANEL_TRANSLINE::OnTranslineSelection( wxCommandEvent& event )
421 {
422  enum TRANSLINE_TYPE_ID id = (enum TRANSLINE_TYPE_ID) event.GetSelection();
423 
425 
426  // Texts and units choice widgets can have their size modified:
427  // The new size must be taken in account
428  GetSizer()->Layout();
429  Refresh();
430 }
431 
432 
433 void PANEL_TRANSLINE::OnTransLineResetButtonClick( wxCommandEvent& event )
434 {
436  m_TranslineSelection->SetSelection( DEFAULT_TYPE );
437 
438  GetSizer()->Layout();
439  Refresh();
440 }
wxStaticText * m_left_message5
wxTextCtrl * m_Substrate_prm6_Value
void OnTranslineEpsilonR_Button(wxCommandEvent &event) override
Shows a list of current relative dielectric constant(Er) and set the selected value in main dialog fr...
TRANSLINE * m_currTransLine
wxStaticText * name
double m_NormalizedValue
wxArrayString StandardRelativeDielectricConstantList()
Definition: common_data.cpp:28
enum TRANSLINE_TYPE_ID m_currTransLineType
wxStaticText * m_left_message4
wxString m_DlgLabel
UNIT_SELECTOR_ANGLE * m_choiceUnit_ElecPrm3
wxStaticText * m_EpsilonR_label
wxTextCtrl * m_Substrate_prm7_Value
wxStaticText * m_elec_prm2_label
A class to handle one parameter of transline.
wxArrayString m_Messages
A class to handle a list of parameters of a given transline.
wxRadioBox * m_TranslineSelection
#define frequencyprms_cnt
wxStaticBitmap * m_translineBitmap
wxTextCtrl * m_Substrate_prm4_Value
wxString m_ToolTip
wxStaticText * m_left_message7
wxTextCtrl * m_Substrate_prm5_Value
wxStaticText * m_substrate_prm7_label
static bool findMatch(wxArrayString &aList, const wxString &aValue, int &aIdx)
#define elecprms_cnt
UNIT_SELECTOR_LEN * m_SubsPrm6_choiceUnit
UNIT_SELECTOR_FREQUENCY * m_choiceUnit_Frequency
wxRadioButton * m_radioBtnPrm1
void TransfDlgDataToTranslineParams()
Read values entered in dialog frame, and transfer these values in current transline parameters,...
void OnTranslineTanD_Button(wxCommandEvent &event) override
Show a list of current dielectric loss factor (tangent delta) and set the selected value in main dial...
void Refresh()
Update the board display after modifying it by a python script (note: it is automatically called by a...
wxStaticText * m_left_message8
wxStaticText * m_Frequency_label
wxArrayString StandardLossTangentList()
Definition: common_data.cpp:55
UNIT_SELECTOR_RESISTOR * m_choiceUnit_ElecPrm1
wxStaticText * m_phys_prm3_label
wxTextCtrl * m_Value_Frequency_Ctrl
#define _(s)
wxArrayString StandardResistivityList()
Definition: common_data.cpp:84
unsigned GetPrmsCount() const
wxStaticText * m_substrate_prm8_label
wxStaticText * m_substrate_prm4_label
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
wxStaticText * m_phys_prm1_label
wxTextCtrl * m_Substrate_prm9_Value
void TranslineTypeSelection(enum TRANSLINE_TYPE_ID aType)
Must be called after selection of a new transline.
TRANSLINE_TYPE_ID
wxRadioButton * m_radioBtnPrm2
UNIT_SELECTOR * unit
void OnTranslineSelection(wxCommandEvent &event) override
Called on new transmission line selection.
UNIT_SELECTOR_LEN * m_SubsPrm7_choiceUnit
wxStaticBitmap * m_bmCMicrostripZoddZeven
UNIT_SELECTOR_LEN * m_SubsPrm9_choiceUnit
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
TRANSLINE_PRM * GetPrm(unsigned aIdx) const
UNIT_SELECTOR_LEN * m_SubsPrm5_choiceUnit
wxStaticText * m_elec_prm1_label
wxStaticText * m_elec_prm3_label
TRANSLINE * m_TLine
UNIT_SELECTOR_LEN * m_choiceUnit_Param3
wxStaticText * m_left_message6
UNIT_SELECTOR_LEN * m_choiceUnit_Param2
void OnTranslineRho_Button(wxCommandEvent &event) override
Show a list of current Specific resistance list (rho) and set the selected value in main dialog frame...
wxTextCtrl * m_Substrate_prm8_Value
void OnTransLineResetButtonClick(wxCommandEvent &event) override
Called when the user clicks the reset button; sets the parameters to their default values.
#define physprms_cnt
virtual double GetUnitScale()=0
Function GetUnitScale.
wxStaticText * m_phys_prm2_label
UNIT_SELECTOR_LEN * m_SubsPrm8_choiceUnit
wxStaticText * m_substrate_prm5_label
wxStaticText * m_substrate_prm6_label
#define substrateprms_cnt
wxStaticText * m_left_message2
UNIT_SELECTOR_LEN * m_choiceUnit_Param1
wxStaticText * m_left_message3
double DoubleFromString(const wxString &TextValue)
std::vector< TRANSLINE_IDENT * > m_transline_list
UNIT_SELECTOR_RESISTOR * m_choiceUnit_ElecPrm2
wxStaticText * m_left_message1
wxStaticText * m_substrate_prm9_label
UNIT_SELECTOR_LEN * m_SubsPrm4_choiceUnit