diff --git a/eeschema/dialogs/dialog_sim_model.cpp b/eeschema/dialogs/dialog_sim_model.cpp index 38dbf54ddf..cb55c361e7 100644 --- a/eeschema/dialogs/dialog_sim_model.cpp +++ b/eeschema/dialogs/dialog_sim_model.cpp @@ -553,11 +553,9 @@ wxPGProperty* DIALOG_SIM_MODEL::newParamProperty( int aParamIndex ) const wxString paramDescription; if( param.info.description == "" ) - paramDescription = wxString::Format( "%s (%s)", - param.info.description, - param.info.name ); - else paramDescription = wxString::Format( "%s", param.info.name ); + else + paramDescription = wxString::Format( "%s (%s)", param.info.description, param.info.name ); wxPGProperty* prop = nullptr; @@ -584,8 +582,16 @@ wxPGProperty* DIALOG_SIM_MODEL::newParamProperty( int aParamIndex ) const // break; case SIM_VALUE::TYPE_STRING: - prop = new SIM_STRING_PROPERTY( paramDescription, param.info.name, m_library, - curModelSharedPtr(), aParamIndex, SIM_VALUE::TYPE_STRING ); + if( param.info.enumValues.empty() ) + { + prop = new SIM_STRING_PROPERTY( paramDescription, param.info.name, m_library, + curModelSharedPtr(), aParamIndex, SIM_VALUE::TYPE_STRING ); + } + else + { + prop = new SIM_ENUM_PROPERTY( paramDescription, param.info.name, m_library, + curModelSharedPtr(), aParamIndex, SIM_VALUE::TYPE_STRING ); + } break; default: diff --git a/eeschema/dialogs/dialog_sim_model.h b/eeschema/dialogs/dialog_sim_model.h index fb21963179..218c3f817f 100644 --- a/eeschema/dialogs/dialog_sim_model.h +++ b/eeschema/dialogs/dialog_sim_model.h @@ -57,7 +57,6 @@ public: wxString IsValid( const wxString& aStr ) const override { - //if( !IsIncluded( aStr ) ) if( m_includes.Index( aStr ) == wxNOT_FOUND ) return wxString::Format( _( "No model named '%s' in library." ), aStr ); diff --git a/eeschema/sim/sim_model.h b/eeschema/sim/sim_model.h index 185f09c8e4..e28cc3143f 100644 --- a/eeschema/sim/sim_model.h +++ b/eeschema/sim/sim_model.h @@ -27,6 +27,7 @@ #include #include +#include #include #include @@ -379,6 +380,7 @@ public: bool isInstanceParam = false; wxString spiceModelName = ""; wxString spiceInstanceName = ""; + std::vector enumValues = {}; // TODO: Stop using brace-initializers, use this constructor for all info structs. INFO( wxString aName = "", @@ -393,8 +395,9 @@ public: const wxString& aDescription = "", bool aIsSpiceInstanceParam = false, bool aIsInstanceParam = false, - wxString aSpiceModelName = "", - wxString aSpiceInstanceName = "" ) : + const wxString& aSpiceModelName = "", + const wxString& aSpiceInstanceName = "", + std::vector aEnumValues = {} ) : name( aName ), id( aId ), dir( aDir ), @@ -407,7 +410,9 @@ public: description( aDescription ), isSpiceInstanceParam( aIsSpiceInstanceParam ), isInstanceParam( aIsInstanceParam ), - spiceInstanceName( aSpiceInstanceName ) + spiceModelName( aSpiceModelName ), + spiceInstanceName( aSpiceInstanceName ), + enumValues( std::move( aEnumValues ) ) { } }; @@ -527,10 +532,6 @@ public: const PIN& GetPin( unsigned aIndex ) const { return m_pins.at( aIndex ); } std::vector> GetPins() const; - virtual std::vector> GetSpicePins() const - { - return GetPins(); - } void SetPinSymbolPinNumber( int aPinIndex, const wxString& aSymbolPinNumber ) { @@ -581,6 +582,11 @@ protected: void ParsePinsField( unsigned aSymbolPinCount, const wxString& aPinsField ); void ParseDisabledField( const wxString& aDisabledField ); + virtual std::vector> GetSpicePins() const + { + return GetPins(); + } + virtual bool SetParamFromSpiceCode( const wxString& aParamName, const wxString& aParamValue, SIM_VALUE_GRAMMAR::NOTATION aNotation = SIM_VALUE_GRAMMAR::NOTATION::SPICE ); diff --git a/eeschema/sim/sim_model_switch.cpp b/eeschema/sim/sim_model_switch.cpp index 2c72c1030c..5be86392eb 100644 --- a/eeschema/sim/sim_model_switch.cpp +++ b/eeschema/sim/sim_model_switch.cpp @@ -46,6 +46,8 @@ SIM_MODEL_SWITCH::SIM_MODEL_SWITCH( TYPE aType ) : SIM_MODEL( aType ) wxFAIL_MSG( "Unhandled SIM_MODEL type in SIM_MODEL_SWITCH" ); break; } + + SetParamValue( "ic", "none" ); } @@ -53,7 +55,12 @@ wxString SIM_MODEL_SWITCH::GenerateSpiceItemParamValuePair( const PARAM& aParam, bool& aIsFirst ) const { // The only instance param is "ic", which is positional. - return aParam.value->ToSpiceString(); + wxString value = aParam.value->ToSpiceString(); + + if( value == "none" ) + return ""; + else + return value; } @@ -94,6 +101,17 @@ wxString SIM_MODEL_SWITCH::GenerateSpiceItemLine( const wxString& aRefName, } +wxString SIM_MODEL_SWITCH::GenerateParamValuePair( const PARAM& aParam, bool& aIsFirst ) const +{ + if( aParam.info.name == "ic" && aParam.value->ToString() == "none" ) + { + return ""; + } + + return SIM_MODEL::GenerateParamValuePair( aParam, aIsFirst ); +} + + std::vector> SIM_MODEL_SWITCH::GetSpicePins() const { switch( GetType() ) @@ -124,6 +142,7 @@ const std::vector SIM_MODEL_SWITCH::makeSwVParamInfos() paramInfo.description = "Threshold voltage"; paramInfo.isSpiceInstanceParam = false; paramInfo.spiceModelName = "vt"; + paramInfo.enumValues = {}; paramInfos.push_back( paramInfo ); paramInfo.name = "his"; @@ -134,6 +153,7 @@ const std::vector SIM_MODEL_SWITCH::makeSwVParamInfos() paramInfo.description = "Hysteresis voltage"; paramInfo.isSpiceInstanceParam = false; paramInfo.spiceModelName = "vh"; + paramInfo.enumValues = {}; paramInfos.push_back( paramInfo ); paramInfo.name = "ron"; @@ -144,6 +164,7 @@ const std::vector SIM_MODEL_SWITCH::makeSwVParamInfos() paramInfo.description = "Resistance when open"; paramInfo.isSpiceInstanceParam = false; paramInfo.spiceModelName = ""; + paramInfo.enumValues = {}; paramInfos.push_back( paramInfo ); paramInfo.name = "roff"; @@ -154,6 +175,7 @@ const std::vector SIM_MODEL_SWITCH::makeSwVParamInfos() paramInfo.description = "Resistance when closed"; paramInfo.isSpiceInstanceParam = false; paramInfo.spiceModelName = ""; + paramInfo.enumValues = {}; paramInfos.push_back( paramInfo ); paramInfo.name = "ic"; @@ -161,9 +183,10 @@ const std::vector SIM_MODEL_SWITCH::makeSwVParamInfos() paramInfo.unit = ""; paramInfo.category = PARAM::CATEGORY::PRINCIPAL; paramInfo.defaultValue = "1"; - paramInfo.description = "Initial state (1=on, 0=off)"; + paramInfo.description = "Initial state"; paramInfo.isSpiceInstanceParam = true; paramInfo.spiceModelName = ""; + paramInfo.enumValues = { "none", "off", "on" }; paramInfos.push_back( paramInfo ); return paramInfos; @@ -183,6 +206,7 @@ const std::vector SIM_MODEL_SWITCH::makeSwIParamInfos() paramInfo.description = "Threshold current"; paramInfo.isSpiceInstanceParam = false; paramInfo.spiceModelName = "it"; + paramInfo.enumValues = {}; paramInfos.push_back( paramInfo ); paramInfo.name = "his"; @@ -193,6 +217,7 @@ const std::vector SIM_MODEL_SWITCH::makeSwIParamInfos() paramInfo.description = "Hysteresis current"; paramInfo.isSpiceInstanceParam = false; paramInfo.spiceModelName = "ih"; + paramInfo.enumValues = {}; paramInfos.push_back( paramInfo ); paramInfo.name = "ron"; @@ -203,6 +228,7 @@ const std::vector SIM_MODEL_SWITCH::makeSwIParamInfos() paramInfo.description = "Resistance when open"; paramInfo.isSpiceInstanceParam = false; paramInfo.spiceModelName = ""; + paramInfo.enumValues = {}; paramInfos.push_back( paramInfo ); paramInfo.name = "roff"; @@ -213,6 +239,7 @@ const std::vector SIM_MODEL_SWITCH::makeSwIParamInfos() paramInfo.description = "Resistance when closed"; paramInfo.isSpiceInstanceParam = false; paramInfo.spiceModelName = ""; + paramInfo.enumValues = {}; paramInfos.push_back( paramInfo ); paramInfo.name = "ic"; @@ -220,9 +247,10 @@ const std::vector SIM_MODEL_SWITCH::makeSwIParamInfos() paramInfo.unit = ""; paramInfo.category = PARAM::CATEGORY::PRINCIPAL; paramInfo.defaultValue = "1"; - paramInfo.description = "Initial state (1=on, 0=off)"; + paramInfo.description = "Initial state"; paramInfo.isSpiceInstanceParam = true; paramInfo.spiceModelName = ""; + paramInfo.enumValues = { "none", "off", "on" }; paramInfos.push_back( paramInfo ); return paramInfos; diff --git a/eeschema/sim/sim_model_switch.h b/eeschema/sim/sim_model_switch.h index 3c839ccfa3..47bcd1893d 100644 --- a/eeschema/sim/sim_model_switch.h +++ b/eeschema/sim/sim_model_switch.h @@ -38,6 +38,8 @@ public: const std::vector& aSymbolPinNumbers, const std::vector& aPinNetNames ) const override; +protected: + wxString GenerateParamValuePair( const PARAM& aParam, bool& aIsFirst ) const override; std::vector> GetSpicePins() const override; private: diff --git a/eeschema/sim/sim_property.cpp b/eeschema/sim/sim_property.cpp index 8710836fda..005e5f4e67 100644 --- a/eeschema/sim/sim_property.cpp +++ b/eeschema/sim/sim_property.cpp @@ -369,18 +369,19 @@ wxValidator* SIM_STRING_PROPERTY::DoGetValidator() const } -bool SIM_STRING_PROPERTY::StringToValue( wxVariant& aVariant, const wxString& aText, int aArgFlags ) const +bool SIM_STRING_PROPERTY::StringToValue( wxVariant& aVariant, const wxString& aText, + int aArgFlags ) const { - wxString paramValueStr = m_model->GetBaseParam( m_paramIndex ).value->ToString(); + wxString baseParamValue = m_model->GetBaseParam( m_paramIndex ).value->ToString(); aVariant = aText; // TODO: Don't use string comparison. - if( m_model->GetBaseModel() && ( aText == "" || aText == paramValueStr ) ) + if( m_model->GetBaseModel() && ( aText == "" || aText == baseParamValue ) ) { if( !m_model->SetParamValue( m_paramIndex, "" ) ) // Nullify. return false; - aVariant = paramValueStr; // Use the inherited value (if it exists) if null. + aVariant = baseParamValue; // Use the inherited value (if it exists) if null. } else { @@ -390,3 +391,29 @@ bool SIM_STRING_PROPERTY::StringToValue( wxVariant& aVariant, const wxString& aT return true; } + + +SIM_ENUM_PROPERTY::SIM_ENUM_PROPERTY( const wxString& aLabel, const wxString& aName, + std::shared_ptr aLibrary, + std::shared_ptr aModel, + int aParamIndex, + SIM_VALUE::TYPE aValueType, + SIM_VALUE_GRAMMAR::NOTATION aNotation ) + : wxEnumProperty( aLabel, aName, + wxArrayString( aModel->GetParam( aParamIndex ).info.enumValues.size(), + &aModel->GetParam( aParamIndex ).info.enumValues[0] ) ), + m_library( aLibrary ), + m_model( aModel ), + m_paramIndex( aParamIndex ) +{ + auto it = std::find( GetParam().info.enumValues.begin(), GetParam().info.enumValues.end(), + GetParam().value->ToString() ); + SetValue( std::distance( GetParam().info.enumValues.begin(), it ) ); +} + + +bool SIM_ENUM_PROPERTY::IntToValue( wxVariant& aVariant, int aNumber, int aArgFlags ) const +{ + m_model->SetParamValue( m_paramIndex, GetParam().info.enumValues.at( aNumber ) ); + return wxEnumProperty::IntToValue( aVariant, aNumber, aArgFlags ); +} diff --git a/eeschema/sim/sim_property.h b/eeschema/sim/sim_property.h index c89fd46851..37aa36ac13 100644 --- a/eeschema/sim/sim_property.h +++ b/eeschema/sim/sim_property.h @@ -135,4 +135,25 @@ protected: int m_paramIndex; }; + +class SIM_ENUM_PROPERTY : public wxEnumProperty +{ +public: + SIM_ENUM_PROPERTY( const wxString& aLabel, const wxString& aName, + std::shared_ptr aLibrary, + std::shared_ptr aModel, + int aParamIndex, + SIM_VALUE::TYPE aValueType = SIM_VALUE::TYPE_FLOAT, + SIM_VALUE_GRAMMAR::NOTATION aNotation = SIM_VALUE_GRAMMAR::NOTATION::SI ); + + bool IntToValue( wxVariant& aVariant, int aNumber, int aArgFlags = 0 ) const override; + + const SIM_MODEL::PARAM& GetParam() const { return m_model->GetParam( m_paramIndex ); } + +protected: + std::shared_ptr m_library; + std::shared_ptr m_model; + int m_paramIndex; +}; + #endif // SIM_PROPERTY_H diff --git a/qa/data/eeschema/spice_netlists/switches/switches.kicad_sch b/qa/data/eeschema/spice_netlists/switches/switches.kicad_sch index b74bd7c830..d2b6b94703 100644 --- a/qa/data/eeschema/spice_netlists/switches/switches.kicad_sch +++ b/qa/data/eeschema/spice_netlists/switches/switches.kicad_sch @@ -726,7 +726,7 @@ (property "Sim_Pins" "1 6 3 5" (id 6) (at 163.83 83.82 0) (effects (font (size 1.27 1.27)) hide) ) - (property "Sim_Params" "thr=500m his=0 ron=100m roff=1T ic=on" (id 7) (at 163.83 83.82 0) + (property "Sim_Params" "thr=500m his=0 ron=100m roff=1T" (id 7) (at 163.83 83.82 0) (effects (font (size 1.27 1.27)) hide) ) (pin "1" (uuid 985f68da-ac8b-4dfe-a794-ff843a4dcef6))