KiCad PCB EDA Suite
Loading...
Searching...
No Matches
sim_property.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) 2022 Mikolaj Wielgus
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
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
21#include <wx/combo.h>
22
23// Include simulator headers after wxWidgets headers to avoid conflicts with Windows headers
24// (especially on msys2 + wxWidgets 3.0.x)
25#include <sim/sim_property.h>
26#include <sim/sim_value.h>
27#include <ki_exception.h>
28
29
35
36
37SIM_PROPERTY::SIM_PROPERTY( SIM_MODEL& aModel, int aParamIndex ) :
38 m_model( aModel ),
39 m_paramIndex( aParamIndex ),
40 m_needsEval( false ),
42 m_disabled( false )
43{
44}
45
46
48{
49 m_disabled = true;
50}
51
52
53SIM_BOOL_PROPERTY::SIM_BOOL_PROPERTY( const wxString& aLabel, const wxString& aName,
54 SIM_MODEL& aModel, int aParamIndex ) :
55 wxBoolProperty( aLabel, aName ),
56 SIM_PROPERTY( aModel, aParamIndex )
57{
58 std::string value = m_model.GetParam( m_paramIndex ).value;
59 SetValue( value == "1" );
60}
61
62
64{
65 return new SIM_VALIDATOR();
66}
67
68
70{
71 wxPGProperty::OnSetValue();
72
73 if( m_disabled )
74 return;
75
76 m_model.SetParamValue( m_paramIndex, m_value.GetBool() ? "1" : "0" );
77}
78
79
80SIM_STRING_PROPERTY::SIM_STRING_PROPERTY( const wxString& aLabel, const wxString& aName,
81 SIM_MODEL& aModel, int aParamIndex,
82 SIM_VALUE::TYPE aValueType,
83 SIM_VALUE_GRAMMAR::NOTATION aNotation ) :
84 wxStringProperty( aLabel, aName ),
85 SIM_PROPERTY( aModel, aParamIndex ),
86 m_valueType( aValueType )
87{
88 SetValueFromString( GetParam().value );
89}
90
91
92bool SIM_STRING_PROPERTY::OnEvent( wxPropertyGrid* propgrid, wxWindow* wnd_primary, wxEvent& event )
93{
94 if( event.GetEventType() == wxEVT_SET_FOCUS && allowEval() )
95 {
96 if( wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( wnd_primary ) )
97 {
98 wxString oldStr = m_eval.OriginalText();
99
100 if( oldStr.length() && oldStr != textEntry->GetValue() )
101 {
102 SetValueInEvent( oldStr );
103 textEntry->SetValue( oldStr );
104 }
105
106 m_needsEval = true;
107 return true;
108 }
109 }
110 else if( event.GetEventType() == wxEVT_KILL_FOCUS && allowEval() )
111 {
112 if( wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( wnd_primary ) )
113 {
114 wxString strValue = textEntry->GetValue();
115
116 if( !strValue.IsEmpty() && m_eval.Process( strValue ) )
117 {
118 double value = SIM_VALUE::ToDouble( m_eval.Result().ToStdString() );
119
120 if( std::isnan( value ) || SIM_VALUE::Equal( value, strValue.ToStdString() ) )
121 {
122 // Don't mess up user formatting if eval'ing didn't actually change the value.
123 }
124 else
125 {
126 SetValueInEvent( m_eval.Result() );
127 }
128 }
129
130 m_needsEval = false;
131 return true;
132 }
133 }
134 else if( event.GetEventType() == wxEVT_KEY_DOWN )
135 {
136 wxKeyEvent& keyEvent = dynamic_cast<wxKeyEvent&>( event );
137
138 if( wxPropertyGrid* propGrid = dynamic_cast<wxPropertyGrid*>( wnd_primary->GetParent() ) )
139 {
140 if( keyEvent.GetKeyCode() == WXK_TAB )
141 {
142 propGrid->CommitChangesFromEditor();
143
144 keyEvent.m_keyCode = keyEvent.ShiftDown() ? WXK_UP : WXK_DOWN;
145 keyEvent.m_shiftDown = false;
146 }
147
148#ifdef __WXMAC__
149 // This shouldn't be required, as wxPGTextCtrlEditor::OnTextCtrlEvent() should be
150 // setting the value to modified. But it doesn't on Mac (or the modified flag is
151 // cleared at some point later), and even if it is set, the changes don't get
152 // committed.
153 // (We used to have code in DIALOG_SIM_MODEL to commit things on *some* actions, but
154 // it wasn't complete and this appears to have at least a better hit rate.)
155 propGrid->CallAfter(
156 [propGrid]()
157 {
158 propGrid->EditorsValueWasModified();
159 propGrid->CommitChangesFromEditor();
160 } );
161#endif
162 }
163 }
164
165 return false;
166}
167
168
170{
171 return new SIM_VALIDATOR();
172}
173
174
180
181
182bool SIM_STRING_PROPERTY::StringToValue( wxVariant& aVariant, const wxString& aText,
183 int aArgFlags ) const
184{
185 if( m_disabled )
186 return false;
187
188 wxString text = aText;
189
190 if( allowEval() && m_needsEval && m_eval.Process( aText ) )
191 {
192 if( !aText.IsEmpty() )
193 {
194 double value = SIM_VALUE::ToDouble( m_eval.Result().ToStdString() );
195
196 if( std::isnan( value ) || SIM_VALUE::Equal( value, aText.ToStdString() ) )
197 {
198 // Don't mess up user formatting if eval'ing didn't actually change the value.
199 }
200 else
201 {
202 text = SIM_VALUE::Normalize( value );
203 }
204 }
205 }
206
207 m_model.SetParamValue( m_paramIndex, text.ToStdString() );
208 aVariant = text.ToStdString();
209 return true;
210}
211
212
213SIM_ENUM_PROPERTY::SIM_ENUM_PROPERTY( const wxString& aLabel, const wxString& aName,
214 SIM_MODEL& aModel, int aParamIndex,
215 const wxArrayString& aValues ) :
216 wxEnumProperty( aLabel, aName, aValues ),
217 SIM_PROPERTY( aModel, aParamIndex )
218{
219 for( int ii = 0; ii < (int) GetParam().info.enumValues.size(); ++ii )
220 {
221 if( GetParam().info.enumValues[ii] == GetParam().value )
222 {
223 SetValue( ii );
224 return;
225 }
226 }
227
228 SetValue( -1 );
229}
230
231
232#if wxCHECK_VERSION( 3, 3, 0 )
233bool SIM_ENUM_PROPERTY::IntToValue( wxVariant& aVariant, int aNumber,
234 wxPGPropValFormatFlags aArgFlags ) const
235#else
236bool SIM_ENUM_PROPERTY::IntToValue( wxVariant& aVariant, int aNumber, int aArgFlags ) const
237#endif
238{
239 if( m_disabled )
240 return false;
241
242 m_model.SetParamValue( m_paramIndex, m_choices.GetLabel( aNumber ).ToStdString() );
243 return wxEnumProperty::IntToValue( aVariant, aNumber, aArgFlags );
244}
SIM_BOOL_PROPERTY(const wxString &aLabel, const wxString &aName, SIM_MODEL &aModel, int aParamIndex)
void OnSetValue() override
wxValidator * DoGetValidator() const override
SIM_ENUM_PROPERTY(const wxString &aLabel, const wxString &aName, SIM_MODEL &aModel, int aParamIndex, const wxArrayString &aValues)
bool IntToValue(wxVariant &aVariant, int aNumber, int aArgFlags=0) const override
const SIM_MODEL::PARAM & GetParam() const
SIM_PROPERTY(SIM_MODEL &aModel, int aParamIndex)
wxPropertyGrid property specializations for simulator.
SIM_MODEL & m_model
bool m_disabled
If true, never access the models.
NUMERIC_EVALUATOR m_eval
wxValidator * DoGetValidator() const override
SIM_STRING_PROPERTY(const wxString &aLabel, const wxString &aName, SIM_MODEL &aModel, int aParamIndex, SIM_VALUE::TYPE aValueType=SIM_VALUE::TYPE_FLOAT, SIM_VALUE_GRAMMAR::NOTATION aNotation=SIM_VALUE_GRAMMAR::NOTATION::SI)
SIM_VALUE::TYPE m_valueType
bool OnEvent(wxPropertyGrid *propgrid, wxWindow *wnd_primary, wxEvent &event) override
bool StringToValue(wxVariant &aVariant, const wxString &aText, int aArgFlags=0) const override
wxPropertyGrid property specializations for simulator.
static std::string Normalize(double aValue)
static bool Equal(double aLH, const std::string &aRH)
static double ToDouble(const std::string &aString, double aDefault=NAN)
EDA_UNITS
Definition eda_units.h:44
static std::string strValue(double aValue)
std::vector< std::string > enumValues
Definition sim_model.h:385
const INFO & info
Definition sim_model.h:398