KiCad PCB EDA Suite
tuner_slider.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) 2016 CERN
5  * Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * @author Maciej Suminski <[email protected]>
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 3
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, you may find one here:
21  * https://www.gnu.org/licenses/gpl-3.0.html
22  * or you may search the http://www.gnu.org website for the version 3 license,
23  * or you may write to the Free Software Foundation, Inc.,
24  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25  */
26 
27 #include "tuner_slider.h"
28 
29 #include <sim/sim_plot_frame.h>
30 #include <sch_symbol.h>
31 #include <template_fieldnames.h>
33 
34 TUNER_SLIDER::TUNER_SLIDER( SIM_PLOT_FRAME* aFrame, wxWindow* aParent, SCH_SYMBOL* aSymbol ) :
35  TUNER_SLIDER_BASE( aParent ),
36  m_symbol( aSymbol ),
37  m_min( 0.0 ),
38  m_max( 0.0 ),
39  m_changed( false ),
40  m_frame ( aFrame )
41 {
42  const wxString compName = aSymbol->GetField( REFERENCE_FIELD )->GetText();
43  m_name->SetLabel( compName );
44 
47  else
48  m_fieldId = aSymbol->GetField( VALUE_FIELD )->GetId();
49 
50  m_value = SPICE_VALUE( aSymbol->GetFieldById( m_fieldId )->GetText() );
51  m_spiceName = aFrame->GetExporter()->GetSpiceDevice( compName ).Lower();
52 
53  // Call Set*() methods to update fields and slider
54  m_max = SPICE_VALUE( 2.0 ) * m_value;
55  m_min = SPICE_VALUE( 0.5 ) * m_value;
56 
57  m_minText->SetValue( m_min.ToOrigString() );
58  m_maxText->SetValue( m_max.ToOrigString() );
59 
61  updateSlider();
62 
63  m_simTimer.SetOwner( this );
64  Connect( wxEVT_TIMER, wxTimerEventHandler( TUNER_SLIDER::onSimTimer ), nullptr, this );
65 }
66 
67 
69 {
70  // Get the value into the current range boundaries
71  if( aVal > m_max )
72  m_value = m_max;
73  else if( aVal < m_min )
74  m_value = m_min;
75  else
76  m_value = aVal;
77 
79  updateSlider();
81 
82  return true;
83 }
84 
85 
86 bool TUNER_SLIDER::SetMin( const SPICE_VALUE& aVal )
87 {
88  if( aVal >= m_max )
89  return false;
90 
91  m_min = aVal;
92 
93  if( m_value < aVal ) // Limit the current value
94  SetValue( aVal );
95 
96  m_minText->SetValue( aVal.ToOrigString() );
97  updateSlider();
98 
99  return true;
100 }
101 
102 
104 {
105  if( aVal <= m_min )
106  return false;
107 
108  m_max = aVal;
109 
110  if( m_value > aVal ) // Limit the current value
111  SetValue( aVal );
112 
113  m_maxText->SetValue( aVal.ToOrigString() );
114  updateSlider();
115 
116  return true;
117 }
118 
119 
121 {
122  // Start simulation in 100 ms, if the value does not change meanwhile
123  m_simTimer.StartOnce( 100 );
124 }
125 
126 
128 {
129  assert( m_max >= m_value && m_value >= m_min );
130 
131  m_slider->SetValue( ( ( m_value - m_min ) / ( m_max - m_min ) ).ToDouble() * 100.0 );
132 }
133 
134 
136 {
137  bool spiceString = m_min.IsSpiceString() || m_max.IsSpiceString();
138  m_valueText->SetValue( spiceString ? m_value.ToSpiceString() : m_value.ToString() );
139 }
140 
141 
143 {
144  try
145  {
146  SPICE_VALUE newMax( m_maxText->GetValue() );
147  SetMax( newMax );
148  }
149  catch( const KI_PARAM_ERROR& )
150  {
151  // Restore the previous value
152  m_maxText->SetValue( m_max.ToOrigString() );
153  }
154 }
155 
156 
158 {
159  try
160  {
161  SPICE_VALUE newCur( m_valueText->GetValue() );
162  SetValue( newCur );
163  m_changed = true;
164  }
165  catch( const KI_PARAM_ERROR& )
166  {
167  // Restore the previous value
168  m_valueText->SetValue( m_value.ToOrigString() );
169  }
170 }
171 
172 
174 {
175  try
176  {
177  SPICE_VALUE newMin( m_minText->GetValue() );
178  SetMin( newMin );
179  }
180  catch( const KI_PARAM_ERROR& )
181  {
182  // Restore the previous value
183  m_minText->SetValue( m_min.ToOrigString() );
184  }
185 }
186 
187 
188 void TUNER_SLIDER::onClose( wxCommandEvent& event )
189 {
190  m_frame->RemoveTuner( this );
191 }
192 
193 
194 void TUNER_SLIDER::onSave( wxCommandEvent& event )
195 {
197 }
198 
199 
200 void TUNER_SLIDER::onSliderChanged( wxScrollEvent& event )
201 {
202  m_value = m_min + ( m_max - m_min ) * SPICE_VALUE( m_slider->GetValue() / 100.0 );
203  updateValueText();
205  m_changed = true;
206 }
207 
208 
209 void TUNER_SLIDER::onMaxKillFocus( wxFocusEvent& event )
210 {
211  updateMax();
212  event.Skip(); // Mandatory in wxFocusEvent
213 }
214 
215 
216 void TUNER_SLIDER::onValueKillFocus( wxFocusEvent& event )
217 {
218  updateValue();
219  event.Skip(); // Mandatory in wxFocusEvent
220 }
221 
222 
223 void TUNER_SLIDER::onMinKillFocus( wxFocusEvent& event )
224 {
225  updateMin();
226  event.Skip(); // Mandatory in wxFocusEvent
227 }
228 
229 
230 void TUNER_SLIDER::onMaxTextEnter( wxCommandEvent& event )
231 {
232  updateMax();
233  event.Skip(); // Mandatory in wxFocusEvent
234 }
235 
236 
237 void TUNER_SLIDER::onValueTextEnter( wxCommandEvent& event )
238 {
239  updateValue();
240 }
241 
242 
243 void TUNER_SLIDER::onMinTextEnter( wxCommandEvent& event )
244 {
245  updateMin();
246 }
247 
248 
249 void TUNER_SLIDER::onSimTimer( wxTimerEvent& event )
250 {
251  if( m_changed )
252  {
253  wxQueueEvent( m_frame, new wxCommandEvent( EVT_SIM_UPDATE ) );
254  m_changed = false;
255  }
256 }
Field Reference of part, i.e. "IC21".
void onSimTimer(wxTimerEvent &event)
void updateSlider()
wxString ToSpiceString() const
Return string value in Spice format (e.g.
void RemoveTuner(TUNER_SLIDER *aTuner, bool aErase=true)
Remove an existing tuner.
SCH_FIELD * GetField(MANDATORY_FIELD_T aFieldType)
Return a mandatory field in this symbol.
Definition: sch_symbol.cpp:705
void onValueTextEnter(wxCommandEvent &event) override
wxTextCtrl * m_valueText
wxTimer m_simTimer
Definition: tuner_slider.h:102
static const wxString & GetSpiceFieldName(SPICE_FIELD aField)
Return a string used for a particular component field related to Spice simulation.
int GetId() const
Definition: sch_field.h:113
wxStaticText * m_name
wxString ToOrigString() const
Return either a normal string or Spice format string, depending on the original value format.
Definition: spice_value.h:92
void UpdateTunerValue(SCH_SYMBOL *aSymbol, int aId, const wxString &aValue)
Safely update a field of the associated symbol without dereferencing the symbol.
bool IsSpiceString() const
Return true if the object was initiated with a Spice formatted string value.
Definition: spice_value.h:100
SPICE_VALUE m_min
Definition: tuner_slider.h:107
wxString ToString() const
Return string value as when converting double to string (e.g.
wxString m_spiceName
Timer that restarts the simulation after the slider value has changed.
Definition: tuner_slider.h:99
Field Value of part, i.e. "3.3K".
< Helper class to handle Spice way of expressing values (e.g. 10.5 Meg) Helper class to recognize Spi...
Definition: spice_value.h:34
bool SetValue(const SPICE_VALUE &aVal)
Class TUNER_SLIDER_BASE.
SPICE_VALUE m_value
Definition: tuner_slider.h:107
wxString GetSpiceDevice(const wxString &aSymbol) const
Return name of Spice device corresponding to a schematic symbol.
void onSliderChanged(wxScrollEvent &event) override
SPICE_VALUE m_max
Definition: tuner_slider.h:107
Subclass of SIM_PLOT_FRAME_BASE, which is generated by wxFormBuilder.
void onMaxKillFocus(wxFocusEvent &event) override
wxTextCtrl * m_maxText
SCH_FIELD * FindField(const wxString &aFieldName, bool aIncludeDefaultFields=true)
Search for a SCH_FIELD with aFieldName.
Definition: sch_symbol.cpp:773
Implementing SIM_PLOT_FRAME_BASE.
SCH_SYMBOL * m_symbol
Definition: tuner_slider.h:104
void onClose(wxCommandEvent &event) override
void updateValue()
void onValueKillFocus(wxFocusEvent &event) override
void onSave(wxCommandEvent &event) override
void onMaxTextEnter(wxCommandEvent &event) override
Schematic symbol object.
Definition: sch_symbol.h:78
wxTextCtrl * m_minText
bool SetMin(const SPICE_VALUE &aVal)
void onMinKillFocus(wxFocusEvent &event) override
bool SetMax(const SPICE_VALUE &aVal)
TUNER_SLIDER(SIM_PLOT_FRAME *aFrame, wxWindow *aParent, SCH_SYMBOL *aSymbol)
const NETLIST_EXPORTER_PSPICE_SIM * GetExporter() const
Return the netlist exporter object used for simulations.
void onMinTextEnter(wxCommandEvent &event) override
void updateValueText()
SCH_FIELD * GetFieldById(int aFieldId)
Return a field in this symbol.
Definition: sch_symbol.cpp:717
SIM_PLOT_FRAME * m_frame
Definition: tuner_slider.h:110
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:154
void updateComponentValue()
Hold a translatable error message and may be used when throwing exceptions containing a translated er...
Definition: ki_exception.h:44