Sim: Implement loading Spice library files
Implement parsing and loading Spice libraries into KiCad. This is done without any involvement of Ngspice -- we create our own in-tree parser using PEGTL -- because Ngspice doesn't offer any intermediate output we could plug ourselves into. We don't parse everything -- just the library content, so this won't be that much effort. We implement some basic Spice code preview to give the user a hint what Spice code eir model will correspond to.
This commit is contained in:
parent
978f01553b
commit
ce84a48037
|
@ -320,6 +320,8 @@ if( KICAD_SPICE )
|
|||
sim/sim_plot_panel.cpp
|
||||
sim/sim_property.cpp
|
||||
sim/sim_workbook.cpp
|
||||
sim/sim_library.cpp
|
||||
sim/sim_library_spice.cpp
|
||||
sim/sim_model.cpp
|
||||
sim/sim_model_behavioral.cpp
|
||||
sim/sim_model_codemodel.cpp
|
||||
|
|
|
@ -24,10 +24,12 @@
|
|||
|
||||
#include <dialog_spice_model.h>
|
||||
#include <sim/sim_property.h>
|
||||
#include <sim/sim_library_spice.h>
|
||||
#include <widgets/wx_grid.h>
|
||||
#include <kiplatform/ui.h>
|
||||
#include <confirm.h>
|
||||
#include <locale_io.h>
|
||||
#include <wx/filedlg.h>
|
||||
|
||||
using TYPE = SIM_VALUE_BASE::TYPE;
|
||||
using CATEGORY = SIM_MODEL::PARAM::CATEGORY;
|
||||
|
@ -42,26 +44,18 @@ DIALOG_SPICE_MODEL<T>::DIALOG_SPICE_MODEL( wxWindow* aParent, SCH_SYMBOL& aSymbo
|
|||
: DIALOG_SPICE_MODEL_BASE( aParent ),
|
||||
m_symbol( aSymbol ),
|
||||
m_fields( aFields ),
|
||||
m_library( std::make_shared<SIM_LIBRARY_SPICE>() ),
|
||||
m_prevModel( nullptr ),
|
||||
m_firstCategory( nullptr )
|
||||
{
|
||||
try
|
||||
{
|
||||
SIM_MODEL::TYPE typeFromFields = SIM_MODEL::ReadTypeFromFields( aFields );
|
||||
|
||||
for( SIM_MODEL::TYPE type : SIM_MODEL::TYPE_ITERATOR() )
|
||||
{
|
||||
if( type == typeFromFields )
|
||||
{
|
||||
m_models.push_back( SIM_MODEL::Create( type, m_symbol.GetAllPins().size(),
|
||||
&aFields ) );
|
||||
m_curModelType = type;
|
||||
}
|
||||
else
|
||||
m_models.push_back( SIM_MODEL::Create( type, m_symbol.GetAllPins().size() ) );
|
||||
m_models.push_back( SIM_MODEL::Create( type, m_symbol.GetAllPins().size() ) );
|
||||
|
||||
SIM_MODEL::DEVICE_TYPE deviceType = SIM_MODEL::TypeInfo( type ).deviceType;
|
||||
|
||||
// By default choose the first model type of each device type.
|
||||
|
||||
if( !m_curModelTypeOfDeviceType.count( deviceType ) )
|
||||
m_curModelTypeOfDeviceType[deviceType] = type;
|
||||
}
|
||||
|
@ -114,30 +108,40 @@ DIALOG_SPICE_MODEL<T>::DIALOG_SPICE_MODEL( wxWindow* aParent, SCH_SYMBOL& aSymbo
|
|||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
bool DIALOG_SPICE_MODEL<T>::TransferDataFromWindow()
|
||||
{
|
||||
if( !DIALOG_SPICE_MODEL_BASE::TransferDataFromWindow() )
|
||||
return false;
|
||||
|
||||
getCurModel().WriteFields( m_fields );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
bool DIALOG_SPICE_MODEL<T>::TransferDataToWindow()
|
||||
{
|
||||
try
|
||||
wxString libraryFilename = SIM_MODEL::GetFieldValue( &m_fields, LIBRARY_FIELD );
|
||||
|
||||
if( !libraryFilename.IsEmpty() )
|
||||
{
|
||||
m_models.at( static_cast<int>( SIM_MODEL::ReadTypeFromFields( m_fields ) ) )
|
||||
= SIM_MODEL::Create( m_symbol.GetAllPins().size(), m_fields );
|
||||
// The model is sourced from a library, optionally with instance overrides.
|
||||
loadLibrary( libraryFilename );
|
||||
|
||||
// Must be set before curModel() is used since the latter checks the combobox value.
|
||||
m_modelNameCombobox->SetStringSelection( SIM_MODEL::GetFieldValue( &m_fields, NAME_FIELD ) );
|
||||
|
||||
curModel().ReadDataFields( m_symbol.GetAllPins().size(), &m_fields );
|
||||
|
||||
m_overrideCheckbox->SetValue( curModel().HasNonPrincipalOverrides() );
|
||||
}
|
||||
catch( KI_PARAM_ERROR& e )
|
||||
else
|
||||
{
|
||||
DisplayErrorMessage( this, e.What() );
|
||||
return DIALOG_SPICE_MODEL_BASE::TransferDataToWindow();
|
||||
// The model is sourced from the instance.
|
||||
SIM_MODEL::TYPE type = SIM_MODEL::ReadTypeFromFields( m_fields );
|
||||
|
||||
try
|
||||
{
|
||||
m_models.at( static_cast<int>( SIM_MODEL::ReadTypeFromFields( m_fields ) ) )
|
||||
= SIM_MODEL::Create( m_symbol.GetAllPins().size(), m_fields );
|
||||
}
|
||||
catch( KI_PARAM_ERROR& e )
|
||||
{
|
||||
DisplayErrorMessage( this, e.What() );
|
||||
return DIALOG_SPICE_MODEL_BASE::TransferDataToWindow();
|
||||
}
|
||||
|
||||
m_curModelType = type;
|
||||
}
|
||||
|
||||
updateWidgets();
|
||||
|
@ -146,94 +150,145 @@ bool DIALOG_SPICE_MODEL<T>::TransferDataToWindow()
|
|||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
bool DIALOG_SPICE_MODEL<T>::TransferDataFromWindow()
|
||||
{
|
||||
if( !DIALOG_SPICE_MODEL_BASE::TransferDataFromWindow() )
|
||||
return false;
|
||||
|
||||
if( m_useLibraryModelRadioButton->GetValue() )
|
||||
{
|
||||
SIM_MODEL::SetFieldValue( m_fields, NAME_FIELD, m_modelNameCombobox->GetValue() );
|
||||
SIM_MODEL::SetFieldValue( m_fields, LIBRARY_FIELD, m_library->GetFilename() );
|
||||
}
|
||||
|
||||
curModel().WriteFields( m_fields );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void DIALOG_SPICE_MODEL<T>::updateWidgets()
|
||||
{
|
||||
updateModelParamsTab();
|
||||
updateModelCodeTab();
|
||||
updatePinAssignmentsTab();
|
||||
|
||||
m_prevModel = &curModel();
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void DIALOG_SPICE_MODEL<T>::updateModelParamsTab()
|
||||
{
|
||||
SIM_MODEL::DEVICE_TYPE deviceType = SIM_MODEL::TypeInfo( m_curModelType ).deviceType;
|
||||
|
||||
m_deviceTypeChoice->SetSelection( static_cast<int>( deviceType ) );
|
||||
|
||||
m_typeChoice->Clear();
|
||||
|
||||
for( SIM_MODEL::TYPE type : SIM_MODEL::TYPE_ITERATOR() )
|
||||
if( &curModel() != m_prevModel )
|
||||
{
|
||||
if( SIM_MODEL::TypeInfo( type ).deviceType == deviceType )
|
||||
SIM_MODEL::DEVICE_TYPE deviceType = SIM_MODEL::TypeInfo( curModel().GetType() ).deviceType;
|
||||
m_deviceTypeChoice->SetSelection( static_cast<int>( deviceType ) );
|
||||
|
||||
m_typeChoice->Clear();
|
||||
|
||||
for( SIM_MODEL::TYPE type : SIM_MODEL::TYPE_ITERATOR() )
|
||||
{
|
||||
wxString description = SIM_MODEL::TypeInfo( type ).description;
|
||||
if( SIM_MODEL::TypeInfo( type ).deviceType == deviceType )
|
||||
{
|
||||
wxString description = SIM_MODEL::TypeInfo( type ).description;
|
||||
|
||||
if( !description.IsEmpty() )
|
||||
m_typeChoice->Append( description );
|
||||
if( !description.IsEmpty() )
|
||||
m_typeChoice->Append( description );
|
||||
|
||||
if( type == m_curModelType )
|
||||
m_typeChoice->SetSelection( m_typeChoice->GetCount() - 1 );
|
||||
if( type == curModel().GetType() )
|
||||
m_typeChoice->SetSelection( m_typeChoice->GetCount() - 1 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// This wxPropertyGridManager column and header stuff has to be here because it segfaults in
|
||||
// the constructor.
|
||||
|
||||
m_paramGridMgr->SetColumnCount( static_cast<int>( PARAM_COLUMN::END_ ) );
|
||||
|
||||
m_paramGridMgr->SetColumnTitle( static_cast<int>( PARAM_COLUMN::UNIT ), "Unit" );
|
||||
m_paramGridMgr->SetColumnTitle( static_cast<int>( PARAM_COLUMN::DEFAULT ), "Default" );
|
||||
m_paramGridMgr->SetColumnTitle( static_cast<int>( PARAM_COLUMN::TYPE ), "Type" );
|
||||
|
||||
m_paramGridMgr->ShowHeader();
|
||||
|
||||
|
||||
m_paramGrid->Clear();
|
||||
|
||||
m_firstCategory = m_paramGrid->Append( new wxPropertyCategory( "DC" ) );
|
||||
m_paramGrid->HideProperty( "DC" );
|
||||
|
||||
m_paramGrid->Append( new wxPropertyCategory( "Temperature" ) );
|
||||
m_paramGrid->HideProperty( "Temperature" );
|
||||
|
||||
m_paramGrid->Append( new wxPropertyCategory( "Noise" ) );
|
||||
m_paramGrid->HideProperty( "Noise" );
|
||||
|
||||
m_paramGrid->Append( new wxPropertyCategory( "Distributed Quantities" ) );
|
||||
m_paramGrid->HideProperty( "Distributed Quantities" );
|
||||
|
||||
m_paramGrid->Append( new wxPropertyCategory( "Geometry" ) );
|
||||
m_paramGrid->HideProperty( "Geometry" );
|
||||
|
||||
m_paramGrid->Append( new wxPropertyCategory( "Limiting Values" ) );
|
||||
m_paramGrid->HideProperty( "Limiting Values" );
|
||||
|
||||
m_paramGrid->Append( new wxPropertyCategory( "Advanced" ) );
|
||||
m_paramGrid->HideProperty( "Advanced" );
|
||||
|
||||
m_paramGrid->Append( new wxPropertyCategory( "Flags" ) );
|
||||
m_paramGrid->HideProperty( "Flags" );
|
||||
|
||||
for( int i = 0; i < curModel().GetParamCount(); ++i )
|
||||
addParamPropertyIfRelevant( i );
|
||||
|
||||
m_paramGrid->CollapseAll();
|
||||
}
|
||||
|
||||
// Either enable all properties or disable all except the principal ones.
|
||||
for( wxPropertyGridIterator it = m_paramGrid->GetIterator(); !it.AtEnd(); ++it )
|
||||
{
|
||||
SIM_PROPERTY* prop = dynamic_cast<SIM_PROPERTY*>( *it );
|
||||
|
||||
// This wxPropertyGridManager stuff has to be here because it segfaults in the constructor.
|
||||
if( !prop ) // Not all properties are SIM_PROPERTY yet. TODO.
|
||||
continue;
|
||||
|
||||
m_paramGridMgr->SetColumnCount( static_cast<int>( PARAM_COLUMN::END_ ) );
|
||||
// Model values other than the currently edited value may have changed. Update them.
|
||||
// This feature is called "autofill" and present only in certain models. Don't do it for
|
||||
// models that don't have it for performance reasons.
|
||||
if( curModel().HasAutofill() )
|
||||
prop->SetValueFromString( prop->GetParam().value->ToString() );
|
||||
|
||||
m_paramGridMgr->SetColumnTitle( static_cast<int>( PARAM_COLUMN::UNIT ), "Unit" );
|
||||
m_paramGridMgr->SetColumnTitle( static_cast<int>( PARAM_COLUMN::DEFAULT ), "Default" );
|
||||
m_paramGridMgr->SetColumnTitle( static_cast<int>( PARAM_COLUMN::TYPE ), "Type" );
|
||||
|
||||
m_paramGridMgr->ShowHeader();
|
||||
|
||||
|
||||
m_paramGrid->Clear();
|
||||
|
||||
m_firstCategory = m_paramGrid->Append( new wxPropertyCategory( "DC" ) );
|
||||
m_paramGrid->HideProperty( "DC" );
|
||||
|
||||
m_paramGrid->Append( new wxPropertyCategory( "Temperature" ) );
|
||||
m_paramGrid->HideProperty( "Temperature" );
|
||||
|
||||
m_paramGrid->Append( new wxPropertyCategory( "Noise" ) );
|
||||
m_paramGrid->HideProperty( "Noise" );
|
||||
|
||||
m_paramGrid->Append( new wxPropertyCategory( "Distributed Quantities" ) );
|
||||
m_paramGrid->HideProperty( "Distributed Quantities" );
|
||||
|
||||
m_paramGrid->Append( new wxPropertyCategory( "Geometry" ) );
|
||||
m_paramGrid->HideProperty( "Geometry" );
|
||||
|
||||
m_paramGrid->Append( new wxPropertyCategory( "Limiting Values" ) );
|
||||
m_paramGrid->HideProperty( "Limiting Values" );
|
||||
|
||||
m_paramGrid->Append( new wxPropertyCategory( "Advanced" ) );
|
||||
m_paramGrid->HideProperty( "Advanced" );
|
||||
|
||||
m_paramGrid->Append( new wxPropertyCategory( "Flags" ) );
|
||||
m_paramGrid->HideProperty( "Flags" );
|
||||
|
||||
for( const SIM_MODEL::PARAM& param : getCurModel().Params() )
|
||||
addParamPropertyIfRelevant( param );
|
||||
|
||||
m_paramGrid->CollapseAll();
|
||||
// Most of the values are disabled when the override checkbox is unchecked.
|
||||
prop->Enable( m_useInstanceModelRadioButton->GetValue()
|
||||
|| prop->GetParam().info.category == CATEGORY::PRINCIPAL
|
||||
|| m_overrideCheckbox->GetValue() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void DIALOG_SPICE_MODEL<T>::updateModelCodeTab()
|
||||
{
|
||||
wxString modelName = m_modelNameCombobox->GetStringSelection();
|
||||
|
||||
if( m_useInstanceModelRadioButton->GetValue() || modelName.IsEmpty() )
|
||||
modelName = m_fields.at( REFERENCE_FIELD ).GetText();
|
||||
|
||||
m_codePreview->SetText( curModel().GenerateSpicePreview( modelName ) );
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void DIALOG_SPICE_MODEL<T>::updatePinAssignmentsTab()
|
||||
{
|
||||
m_pinAssignmentsGrid->ClearRows();
|
||||
if( &curModel() == m_prevModel )
|
||||
return;
|
||||
|
||||
m_pinAssignmentsGrid->ClearRows();
|
||||
std::vector<SCH_PIN*> pinList = m_symbol.GetAllPins();
|
||||
|
||||
m_pinAssignmentsGrid->AppendRows( static_cast<int>( pinList.size() ) );
|
||||
|
@ -254,9 +309,9 @@ void DIALOG_SPICE_MODEL<T>::updatePinAssignmentsTab()
|
|||
"Not Connected" );
|
||||
}
|
||||
|
||||
for( unsigned int i = 0; i < getCurModel().Pins().size(); ++i )
|
||||
for( int i = 0; i < curModel().GetPinCount(); ++i )
|
||||
{
|
||||
int symbolPinNumber = getCurModel().Pins().at( i ).symbolPinNumber;
|
||||
int symbolPinNumber = curModel().GetPin( i ).symbolPinNumber;
|
||||
|
||||
if( symbolPinNumber == SIM_MODEL::PIN::NOT_CONNECTED )
|
||||
continue;
|
||||
|
@ -282,9 +337,9 @@ void DIALOG_SPICE_MODEL<T>::updatePinAssignmentsGridEditors()
|
|||
wxString modelPinChoicesString = "";
|
||||
bool isFirst = true;
|
||||
|
||||
for( unsigned int i = 0; i < getCurModel().Pins().size(); ++i )
|
||||
for( int i = 0; i < curModel().GetPinCount(); ++i )
|
||||
{
|
||||
const SIM_MODEL::PIN& modelPin = getCurModel().Pins().at( i );
|
||||
const SIM_MODEL::PIN& modelPin = curModel().GetPin( i );
|
||||
int modelPinNumber = static_cast<int>( i + 1 );
|
||||
|
||||
if( modelPin.symbolPinNumber != SIM_MODEL::PIN::NOT_CONNECTED )
|
||||
|
@ -329,62 +384,78 @@ void DIALOG_SPICE_MODEL<T>::updatePinAssignmentsGridEditors()
|
|||
|
||||
|
||||
template <typename T>
|
||||
void DIALOG_SPICE_MODEL<T>::addParamPropertyIfRelevant( const SIM_MODEL::PARAM& aParam )
|
||||
void DIALOG_SPICE_MODEL<T>::loadLibrary( const wxString& aFilePath )
|
||||
{
|
||||
if( aParam.info.dir == SIM_MODEL::PARAM::DIR::OUT )
|
||||
m_library->ReadFile( aFilePath );
|
||||
m_libraryFilenameInput->SetValue( aFilePath );
|
||||
|
||||
m_libraryModels.clear();
|
||||
for( const SIM_MODEL& baseModel : m_library->GetModels() )
|
||||
m_libraryModels.push_back( SIM_MODEL::Create( baseModel ) );
|
||||
|
||||
m_modelNameCombobox->Clear();
|
||||
for( const wxString& name : m_library->GetModelNames() )
|
||||
m_modelNameCombobox->Append( name );
|
||||
|
||||
m_useLibraryModelRadioButton->SetValue( true );
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void DIALOG_SPICE_MODEL<T>::addParamPropertyIfRelevant( int aParamIndex )
|
||||
{
|
||||
if( curModel().GetParam( aParamIndex ).info.dir == SIM_MODEL::PARAM::DIR::OUT )
|
||||
return;
|
||||
|
||||
switch( aParam.info.category )
|
||||
switch( curModel().GetParam( aParamIndex ).info.category )
|
||||
{
|
||||
case CATEGORY::DC:
|
||||
m_paramGrid->HideProperty( "DC", false );
|
||||
m_paramGrid->AppendIn( "DC", newParamProperty( aParam ) );
|
||||
m_paramGrid->AppendIn( "DC", newParamProperty( aParamIndex ) );
|
||||
break;
|
||||
|
||||
case CATEGORY::CAPACITANCE:
|
||||
m_paramGrid->HideProperty( "Capacitance", false );
|
||||
m_paramGrid->AppendIn( "Capacitance", newParamProperty( aParam ) );
|
||||
m_paramGrid->AppendIn( "Capacitance", newParamProperty( aParamIndex ) );
|
||||
break;
|
||||
|
||||
case CATEGORY::TEMPERATURE:
|
||||
m_paramGrid->HideProperty( "Temperature", false );
|
||||
m_paramGrid->AppendIn( "Temperature", newParamProperty( aParam ) );
|
||||
m_paramGrid->AppendIn( "Temperature", newParamProperty( aParamIndex ) );
|
||||
break;
|
||||
|
||||
case CATEGORY::NOISE:
|
||||
m_paramGrid->HideProperty( "Noise", false );
|
||||
m_paramGrid->AppendIn( "Noise", newParamProperty( aParam ) );
|
||||
m_paramGrid->AppendIn( "Noise", newParamProperty( aParamIndex ) );
|
||||
break;
|
||||
|
||||
case CATEGORY::DISTRIBUTED_QUANTITIES:
|
||||
m_paramGrid->HideProperty( "Distributed Quantities", false );
|
||||
m_paramGrid->AppendIn( "Distributed Quantities", newParamProperty( aParam ) );
|
||||
m_paramGrid->AppendIn( "Distributed Quantities", newParamProperty( aParamIndex ) );
|
||||
break;
|
||||
|
||||
case CATEGORY::GEOMETRY:
|
||||
m_paramGrid->HideProperty( "Geometry", false );
|
||||
m_paramGrid->AppendIn( "Geometry", newParamProperty( aParam ) );
|
||||
m_paramGrid->AppendIn( "Geometry", newParamProperty( aParamIndex ) );
|
||||
break;
|
||||
|
||||
case CATEGORY::LIMITING_VALUES:
|
||||
m_paramGrid->HideProperty( "Limiting Values", false );
|
||||
m_paramGrid->AppendIn( "Limiting Values", newParamProperty( aParam ) );
|
||||
m_paramGrid->AppendIn( "Limiting Values", newParamProperty( aParamIndex ) );
|
||||
break;
|
||||
|
||||
case CATEGORY::ADVANCED:
|
||||
m_paramGrid->HideProperty( "Advanced", false );
|
||||
m_paramGrid->AppendIn( "Advanced", newParamProperty( aParam ) );
|
||||
m_paramGrid->AppendIn( "Advanced", newParamProperty( aParamIndex ) );
|
||||
break;
|
||||
|
||||
case CATEGORY::FLAGS:
|
||||
m_paramGrid->HideProperty( "Flags", false );
|
||||
m_paramGrid->AppendIn( "Flags", newParamProperty( aParam ) );
|
||||
m_paramGrid->AppendIn( "Flags", newParamProperty( aParamIndex ) );
|
||||
break;
|
||||
|
||||
default:
|
||||
//m_paramGrid->AppendIn( nullptr, newParamProperty( aParam ) );
|
||||
m_paramGrid->Insert( m_firstCategory, newParamProperty( aParam ) );
|
||||
//m_paramGrid->Append( newParamProperty( aParam ) );
|
||||
m_paramGrid->Insert( m_firstCategory, newParamProperty( aParamIndex ) );
|
||||
break;
|
||||
|
||||
case CATEGORY::INITIAL_CONDITIONS:
|
||||
|
@ -394,46 +465,47 @@ void DIALOG_SPICE_MODEL<T>::addParamPropertyIfRelevant( const SIM_MODEL::PARAM&
|
|||
}
|
||||
|
||||
template <typename T>
|
||||
wxPGProperty* DIALOG_SPICE_MODEL<T>::newParamProperty( const SIM_MODEL::PARAM& aParam ) const
|
||||
wxPGProperty* DIALOG_SPICE_MODEL<T>::newParamProperty( int aParamIndex ) const
|
||||
{
|
||||
const SIM_MODEL::PARAM& param = curModel().GetParam( aParamIndex );
|
||||
wxString paramDescription = wxString::Format( "%s (%s)",
|
||||
aParam.info.description,
|
||||
aParam.info.name );
|
||||
param.info.description,
|
||||
param.info.name );
|
||||
wxPGProperty* prop = nullptr;
|
||||
|
||||
switch( aParam.info.type )
|
||||
switch( param.info.type )
|
||||
{
|
||||
case TYPE::INT:
|
||||
prop = new SIM_PROPERTY( paramDescription,aParam.info.name, *aParam.value,
|
||||
SIM_VALUE_BASE::TYPE::INT );
|
||||
prop = new SIM_PROPERTY( paramDescription, param.info.name, m_library, curModelSharedPtr(),
|
||||
aParamIndex, SIM_VALUE_BASE::TYPE::INT );
|
||||
break;
|
||||
|
||||
case TYPE::FLOAT:
|
||||
prop = new SIM_PROPERTY( paramDescription,aParam.info.name, *aParam.value,
|
||||
SIM_VALUE_BASE::TYPE::FLOAT );
|
||||
prop = new SIM_PROPERTY( paramDescription, param.info.name, m_library, curModelSharedPtr(),
|
||||
aParamIndex, SIM_VALUE_BASE::TYPE::FLOAT );
|
||||
break;
|
||||
|
||||
case TYPE::BOOL:
|
||||
prop = new wxBoolProperty( paramDescription, aParam.info.name );
|
||||
prop = new wxBoolProperty( paramDescription, param.info.name );
|
||||
prop->SetAttribute( wxPG_BOOL_USE_CHECKBOX, true );
|
||||
break;
|
||||
|
||||
default:
|
||||
prop = new wxStringProperty( paramDescription, aParam.info.name );
|
||||
prop = new wxStringProperty( paramDescription, param.info.name );
|
||||
break;
|
||||
}
|
||||
|
||||
prop->SetAttribute( wxPG_ATTR_UNITS, aParam.info.unit );
|
||||
prop->SetAttribute( wxPG_ATTR_UNITS, param.info.unit );
|
||||
|
||||
// Legacy due to the way we extracted the parameters from Ngspice.
|
||||
if( aParam.isOtherVariant )
|
||||
prop->SetCell( 3, aParam.info.defaultValueOfOtherVariant );
|
||||
if( param.isOtherVariant )
|
||||
prop->SetCell( 3, param.info.defaultValueOfOtherVariant );
|
||||
else
|
||||
prop->SetCell( 3, aParam.info.defaultValue );
|
||||
prop->SetCell( 3, param.info.defaultValue );
|
||||
|
||||
wxString typeStr;
|
||||
|
||||
switch( aParam.info.type )
|
||||
switch( param.info.type )
|
||||
{
|
||||
case TYPE::BOOL: typeStr = wxString( "Bool" ); break;
|
||||
case TYPE::INT: typeStr = wxString( "Int" ); break;
|
||||
|
@ -448,14 +520,34 @@ wxPGProperty* DIALOG_SPICE_MODEL<T>::newParamProperty( const SIM_MODEL::PARAM& a
|
|||
|
||||
prop->SetCell( static_cast<int>( PARAM_COLUMN::TYPE ), typeStr );
|
||||
|
||||
if( m_useLibraryModelRadioButton->GetValue()
|
||||
&& !m_overrideCheckbox->GetValue()
|
||||
&& param.info.category != SIM_MODEL::PARAM::CATEGORY::PRINCIPAL )
|
||||
{
|
||||
prop->Enable( false );
|
||||
}
|
||||
|
||||
return prop;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
SIM_MODEL& DIALOG_SPICE_MODEL<T>::getCurModel() const
|
||||
SIM_MODEL& DIALOG_SPICE_MODEL<T>::curModel() const
|
||||
{
|
||||
return *m_models.at( static_cast<int>( m_curModelType ) );
|
||||
return *curModelSharedPtr();
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
std::shared_ptr<SIM_MODEL> DIALOG_SPICE_MODEL<T>::curModelSharedPtr() const
|
||||
{
|
||||
if( m_useLibraryModelRadioButton->GetValue()
|
||||
&& m_modelNameCombobox->GetSelection() != wxNOT_FOUND )
|
||||
{
|
||||
return m_libraryModels.at( m_modelNameCombobox->GetSelection() );
|
||||
}
|
||||
else
|
||||
return m_models.at( static_cast<int>( m_curModelType ) );
|
||||
}
|
||||
|
||||
|
||||
|
@ -480,7 +572,7 @@ wxString DIALOG_SPICE_MODEL<T>::getSymbolPinString( int symbolPinNumber ) const
|
|||
template <typename T>
|
||||
wxString DIALOG_SPICE_MODEL<T>::getModelPinString( int modelPinNumber ) const
|
||||
{
|
||||
const wxString& pinName = getCurModel().Pins().at( modelPinNumber - 1 ).name;
|
||||
const wxString& pinName = curModel().GetPin( modelPinNumber - 1 ).name;
|
||||
|
||||
LOCALE_IO toggle;
|
||||
|
||||
|
@ -509,6 +601,39 @@ int DIALOG_SPICE_MODEL<T>::getModelPinNumber( const wxString& aModelPinString )
|
|||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void DIALOG_SPICE_MODEL<T>::onRadioButton( wxCommandEvent& aEvent )
|
||||
{
|
||||
updateWidgets();
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void DIALOG_SPICE_MODEL<T>::onBrowseButtonClick( wxCommandEvent& aEvent )
|
||||
{
|
||||
wxFileDialog dlg( this, _( "Browse Models" ) );
|
||||
|
||||
if( dlg.ShowModal() == wxID_CANCEL )
|
||||
return;
|
||||
|
||||
loadLibrary( dlg.GetPath() );
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void DIALOG_SPICE_MODEL<T>::onModelNameCombobox( wxCommandEvent& aEvent )
|
||||
{
|
||||
updateWidgets();
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void DIALOG_SPICE_MODEL<T>::onOverrideCheckbox( wxCommandEvent& aEvent )
|
||||
{
|
||||
updateWidgets();
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void DIALOG_SPICE_MODEL<T>::onDeviceTypeChoice( wxCommandEvent& aEvent )
|
||||
{
|
||||
|
@ -543,6 +668,13 @@ void DIALOG_SPICE_MODEL<T>::onTypeChoice( wxCommandEvent& aEvent )
|
|||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void DIALOG_SPICE_MODEL<T>::onParamGridChanged( wxPropertyGridEvent& aEvent )
|
||||
{
|
||||
updateWidgets();
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void DIALOG_SPICE_MODEL<T>::onPinAssignmentsGridCellChange( wxGridEvent& aEvent )
|
||||
{
|
||||
|
@ -552,11 +684,10 @@ void DIALOG_SPICE_MODEL<T>::onPinAssignmentsGridCellChange( wxGridEvent& aEvent
|
|||
m_pinAssignmentsGrid->GetCellValue( aEvent.GetRow(), aEvent.GetCol() ) );
|
||||
|
||||
if( oldModelPinNumber != SIM_MODEL::PIN::NOT_CONNECTED )
|
||||
getCurModel().Pins().at( oldModelPinNumber - 1 ).symbolPinNumber =
|
||||
SIM_MODEL::PIN::NOT_CONNECTED;
|
||||
curModel().SetPinSymbolPinNumber( oldModelPinNumber - 1, SIM_MODEL::PIN::NOT_CONNECTED );
|
||||
|
||||
if( modelPinNumber != SIM_MODEL::PIN::NOT_CONNECTED )
|
||||
getCurModel().Pins().at( modelPinNumber - 1 ).symbolPinNumber = symbolPinNumber;
|
||||
curModel().SetPinSymbolPinNumber( modelPinNumber - 1, symbolPinNumber );
|
||||
|
||||
updatePinAssignmentsGridEditors();
|
||||
|
||||
|
@ -577,6 +708,48 @@ void DIALOG_SPICE_MODEL<T>::onPinAssignmentsGridSize( wxSizeEvent& aEvent )
|
|||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void DIALOG_SPICE_MODEL<T>::onLibraryFilenameInputUpdate( wxUpdateUIEvent& aEvent )
|
||||
{
|
||||
aEvent.Enable( m_useLibraryModelRadioButton->GetValue() );
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void DIALOG_SPICE_MODEL<T>::onBrowseButtonUpdate( wxUpdateUIEvent& aEvent )
|
||||
{
|
||||
aEvent.Enable( m_useLibraryModelRadioButton->GetValue() );
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void DIALOG_SPICE_MODEL<T>::onModelNameComboboxUpdate( wxUpdateUIEvent& aEvent )
|
||||
{
|
||||
aEvent.Enable( m_useLibraryModelRadioButton->GetValue() );
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void DIALOG_SPICE_MODEL<T>::onOverrideCheckboxUpdate( wxUpdateUIEvent& aEvent )
|
||||
{
|
||||
aEvent.Enable( m_useLibraryModelRadioButton->GetValue() );
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void DIALOG_SPICE_MODEL<T>::onDeviceTypeChoiceUpdate( wxUpdateUIEvent& aEvent )
|
||||
{
|
||||
aEvent.Enable( m_useInstanceModelRadioButton->GetValue() );
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void DIALOG_SPICE_MODEL<T>::onTypeChoiceUpdate( wxUpdateUIEvent& aEvent )
|
||||
{
|
||||
aEvent.Enable( m_useInstanceModelRadioButton->GetValue() );
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void DIALOG_SPICE_MODEL<T>::onSelectionChange( wxPropertyGridEvent& aEvent )
|
||||
{
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <scintilla_tricks.h>
|
||||
|
||||
#include <sim/sim_model.h>
|
||||
#include <sim/sim_library.h>
|
||||
#include <sch_symbol.h>
|
||||
|
||||
// Some probable wxWidgets bugs encountered when writing this class:
|
||||
|
@ -41,44 +42,68 @@ template <typename T>
|
|||
class DIALOG_SPICE_MODEL : public DIALOG_SPICE_MODEL_BASE
|
||||
{
|
||||
public:
|
||||
static constexpr auto LIBRARY_FIELD = "Model_Library";
|
||||
static constexpr auto NAME_FIELD = "Model_Name";
|
||||
|
||||
enum class PARAM_COLUMN : int { DESCRIPTION, VALUE, UNIT, DEFAULT, TYPE, END_ };
|
||||
enum class PIN_COLUMN : int { SYMBOL, MODEL };
|
||||
|
||||
DIALOG_SPICE_MODEL( wxWindow* aParent, SCH_SYMBOL& aSymbol, std::vector<T>& aSchFields );
|
||||
|
||||
private:
|
||||
bool TransferDataFromWindow() override;
|
||||
bool TransferDataToWindow() override;
|
||||
bool TransferDataFromWindow() override;
|
||||
|
||||
void updateWidgets();
|
||||
void updateModelParamsTab();
|
||||
void updateModelCodeTab();
|
||||
void updatePinAssignmentsTab();
|
||||
void updatePinAssignmentsGridEditors();
|
||||
|
||||
void addParamPropertyIfRelevant( const SIM_MODEL::PARAM& aParam );
|
||||
wxPGProperty* newParamProperty( const SIM_MODEL::PARAM& aParam ) const;
|
||||
|
||||
SIM_MODEL& getCurModel() const;
|
||||
void loadLibrary( const wxString& aFilePath );
|
||||
|
||||
void addParamPropertyIfRelevant( int aParamIndex );
|
||||
wxPGProperty* newParamProperty( int aParamIndex ) const;
|
||||
|
||||
SIM_MODEL& curModel() const;
|
||||
std::shared_ptr<SIM_MODEL> curModelSharedPtr() const;
|
||||
|
||||
wxString getSymbolPinString( int aSymbolPinNumber ) const;
|
||||
wxString getModelPinString( int aModelPinNumber ) const;
|
||||
int getModelPinNumber( const wxString& aModelPinString ) const;
|
||||
|
||||
void onRadioButton( wxCommandEvent& aEvent ) override;
|
||||
void onBrowseButtonClick( wxCommandEvent& aEvent ) override;
|
||||
void onModelNameCombobox( wxCommandEvent& aEvent ) override;
|
||||
void onOverrideCheckbox( wxCommandEvent& aEvent ) override;
|
||||
void onDeviceTypeChoice( wxCommandEvent& aEvent ) override;
|
||||
void onTypeChoice( wxCommandEvent& aEvent ) override;
|
||||
void onParamGridChanged( wxPropertyGridEvent& aEvent ) override;
|
||||
void onPinAssignmentsGridCellChange( wxGridEvent& aEvent ) override;
|
||||
void onPinAssignmentsGridSize( wxSizeEvent& aEvent ) override;
|
||||
|
||||
void onLibraryFilenameInputUpdate( wxUpdateUIEvent& aEvent ) override;
|
||||
void onBrowseButtonUpdate( wxUpdateUIEvent& aEvent ) override;
|
||||
void onModelNameComboboxUpdate( wxUpdateUIEvent& aEvent ) override;
|
||||
void onOverrideCheckboxUpdate( wxUpdateUIEvent& aEvent ) override;
|
||||
void onDeviceTypeChoiceUpdate( wxUpdateUIEvent& aEvent ) override;
|
||||
void onTypeChoiceUpdate( wxUpdateUIEvent& aEvent ) override;
|
||||
|
||||
virtual void onSelectionChange( wxPropertyGridEvent& aEvent );
|
||||
//void onPropertyChanged( wxPropertyGridEvent& aEvent ) override;
|
||||
|
||||
|
||||
SCH_SYMBOL& m_symbol;
|
||||
std::vector<T>& m_fields;
|
||||
|
||||
std::vector<std::unique_ptr<SIM_MODEL>> m_models;
|
||||
std::vector<std::shared_ptr<SIM_MODEL>> m_models;
|
||||
std::map<SIM_MODEL::DEVICE_TYPE, SIM_MODEL::TYPE> m_curModelTypeOfDeviceType;
|
||||
SIM_MODEL::TYPE m_curModelType = SIM_MODEL::TYPE::NONE;
|
||||
|
||||
std::shared_ptr<SIM_LIBRARY> m_library;
|
||||
std::vector<std::shared_ptr<SIM_MODEL>> m_libraryModels;
|
||||
const SIM_MODEL* m_prevModel;
|
||||
|
||||
wxPGProperty* m_firstCategory; // Used to add principal parameters to root (any better ideas?)
|
||||
std::unique_ptr<SCINTILLA_TRICKS> m_scintillaTricks;
|
||||
};
|
||||
|
|
|
@ -24,31 +24,38 @@ DIALOG_SPICE_MODEL_BASE::DIALOG_SPICE_MODEL_BASE( wxWindow* parent, wxWindowID i
|
|||
bSizer9 = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
wxStaticBoxSizer* sbSizer4;
|
||||
sbSizer4 = new wxStaticBoxSizer( new wxStaticBox( m_modelPanel, wxID_ANY, wxT("Properties") ), wxVERTICAL );
|
||||
sbSizer4 = new wxStaticBoxSizer( new wxStaticBox( m_modelPanel, wxID_ANY, wxT("Source") ), wxVERTICAL );
|
||||
|
||||
wxFlexGridSizer* fgSizer15;
|
||||
fgSizer15 = new wxFlexGridSizer( 0, 3, 0, 0 );
|
||||
fgSizer15->AddGrowableCol( 1 );
|
||||
fgSizer15 = new wxFlexGridSizer( 0, 4, 0, 0 );
|
||||
fgSizer15->AddGrowableCol( 2 );
|
||||
fgSizer15->SetFlexibleDirection( wxBOTH );
|
||||
fgSizer15->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
|
||||
|
||||
m_staticText122 = new wxStaticText( sbSizer4->GetStaticBox(), wxID_ANY, wxT("Model Name:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText122->Wrap( -1 );
|
||||
fgSizer15->Add( m_staticText122, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||
m_useInstanceModelRadioButton = new wxRadioButton( sbSizer4->GetStaticBox(), wxID_ANY, wxT("Instance"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP );
|
||||
fgSizer15->Add( m_useInstanceModelRadioButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||
|
||||
m_modelName = new wxTextCtrl( sbSizer4->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
fgSizer15->Add( m_modelName, 0, wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 5 );
|
||||
m_useLibraryModelRadioButton = new wxRadioButton( sbSizer4->GetStaticBox(), wxID_ANY, wxT("Library:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
fgSizer15->Add( m_useLibraryModelRadioButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||
|
||||
m_browseButton = new wxButton( sbSizer4->GetStaticBox(), wxID_ANY, wxT("Browse..."), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
fgSizer15->Add( m_browseButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||
m_libraryFilenameInput = new wxTextCtrl( sbSizer4->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
fgSizer15->Add( m_libraryFilenameInput, 0, wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 5 );
|
||||
|
||||
m_staticText124 = new wxStaticText( sbSizer4->GetStaticBox(), wxID_ANY, wxT("Location:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText124->Wrap( -1 );
|
||||
fgSizer15->Add( m_staticText124, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||
m_browseButton = new wxBitmapButton( sbSizer4->GetStaticBox(), wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
|
||||
fgSizer15->Add( m_browseButton, 0, wxALL, 5 );
|
||||
|
||||
m_staticText125 = new wxStaticText( sbSizer4->GetStaticBox(), wxID_ANY, wxT("etc/kicad-sim/diodes.lib"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText125->Wrap( -1 );
|
||||
fgSizer15->Add( m_staticText125, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||
|
||||
fgSizer15->Add( 0, 0, 1, wxEXPAND, 5 );
|
||||
|
||||
m_modelNameLabel = new wxStaticText( sbSizer4->GetStaticBox(), wxID_ANY, wxT("Model:"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT );
|
||||
m_modelNameLabel->Wrap( -1 );
|
||||
fgSizer15->Add( m_modelNameLabel, 0, wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 5 );
|
||||
|
||||
m_modelNameCombobox = new wxComboBox( sbSizer4->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 );
|
||||
fgSizer15->Add( m_modelNameCombobox, 0, wxALL|wxEXPAND, 5 );
|
||||
|
||||
m_overrideCheckbox = new wxCheckBox( sbSizer4->GetStaticBox(), wxID_ANY, wxT("Override"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
fgSizer15->Add( m_overrideCheckbox, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||
|
||||
|
||||
sbSizer4->Add( fgSizer15, 1, wxEXPAND, 5 );
|
||||
|
@ -59,9 +66,6 @@ DIALOG_SPICE_MODEL_BASE::DIALOG_SPICE_MODEL_BASE( wxWindow* parent, wxWindowID i
|
|||
wxStaticBoxSizer* sbSizer5;
|
||||
sbSizer5 = new wxStaticBoxSizer( new wxStaticBox( m_modelPanel, wxID_ANY, wxT("Model") ), wxVERTICAL );
|
||||
|
||||
m_checkBox2 = new wxCheckBox( sbSizer5->GetStaticBox(), wxID_ANY, wxT("Change parameters for this symbol"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
sbSizer5->Add( m_checkBox2, 0, wxALL, 5 );
|
||||
|
||||
m_notebook4 = new wxNotebook( sbSizer5->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_parametersPanel = new wxPanel( m_notebook4, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
|
||||
wxBoxSizer* bSizer12;
|
||||
|
@ -226,9 +230,20 @@ DIALOG_SPICE_MODEL_BASE::DIALOG_SPICE_MODEL_BASE( wxWindow* parent, wxWindowID i
|
|||
this->Centre( wxBOTH );
|
||||
|
||||
// Connect Events
|
||||
m_useInstanceModelRadioButton->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_SPICE_MODEL_BASE::onRadioButton ), NULL, this );
|
||||
m_useLibraryModelRadioButton->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_SPICE_MODEL_BASE::onRadioButton ), NULL, this );
|
||||
m_libraryFilenameInput->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SPICE_MODEL_BASE::onLibraryFilenameInputUpdate ), NULL, this );
|
||||
m_browseButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SPICE_MODEL_BASE::onBrowseButtonClick ), NULL, this );
|
||||
m_browseButton->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SPICE_MODEL_BASE::onBrowseButtonUpdate ), NULL, this );
|
||||
m_modelNameCombobox->Connect( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler( DIALOG_SPICE_MODEL_BASE::onModelNameCombobox ), NULL, this );
|
||||
m_modelNameCombobox->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SPICE_MODEL_BASE::onModelNameComboboxUpdate ), NULL, this );
|
||||
m_overrideCheckbox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_SPICE_MODEL_BASE::onOverrideCheckbox ), NULL, this );
|
||||
m_overrideCheckbox->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SPICE_MODEL_BASE::onOverrideCheckboxUpdate ), NULL, this );
|
||||
m_deviceTypeChoice->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_SPICE_MODEL_BASE::onDeviceTypeChoice ), NULL, this );
|
||||
m_deviceTypeChoice->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SPICE_MODEL_BASE::onDeviceTypeChoiceUpdate ), NULL, this );
|
||||
m_typeChoice->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_SPICE_MODEL_BASE::onTypeChoice ), NULL, this );
|
||||
m_paramGridMgr->Connect( wxEVT_PG_CHANGED, wxPropertyGridEventHandler( DIALOG_SPICE_MODEL_BASE::onPropertyChanged ), NULL, this );
|
||||
m_typeChoice->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SPICE_MODEL_BASE::onTypeChoiceUpdate ), NULL, this );
|
||||
m_paramGridMgr->Connect( wxEVT_PG_CHANGED, wxPropertyGridEventHandler( DIALOG_SPICE_MODEL_BASE::onParamGridChanged ), NULL, this );
|
||||
m_pinAssignmentsGrid->Connect( wxEVT_GRID_CELL_CHANGED, wxGridEventHandler( DIALOG_SPICE_MODEL_BASE::onPinAssignmentsGridCellChange ), NULL, this );
|
||||
m_pinAssignmentsGrid->Connect( wxEVT_SIZE, wxSizeEventHandler( DIALOG_SPICE_MODEL_BASE::onPinAssignmentsGridSize ), NULL, this );
|
||||
}
|
||||
|
@ -236,9 +251,20 @@ DIALOG_SPICE_MODEL_BASE::DIALOG_SPICE_MODEL_BASE( wxWindow* parent, wxWindowID i
|
|||
DIALOG_SPICE_MODEL_BASE::~DIALOG_SPICE_MODEL_BASE()
|
||||
{
|
||||
// Disconnect Events
|
||||
m_useInstanceModelRadioButton->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_SPICE_MODEL_BASE::onRadioButton ), NULL, this );
|
||||
m_useLibraryModelRadioButton->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_SPICE_MODEL_BASE::onRadioButton ), NULL, this );
|
||||
m_libraryFilenameInput->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SPICE_MODEL_BASE::onLibraryFilenameInputUpdate ), NULL, this );
|
||||
m_browseButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SPICE_MODEL_BASE::onBrowseButtonClick ), NULL, this );
|
||||
m_browseButton->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SPICE_MODEL_BASE::onBrowseButtonUpdate ), NULL, this );
|
||||
m_modelNameCombobox->Disconnect( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler( DIALOG_SPICE_MODEL_BASE::onModelNameCombobox ), NULL, this );
|
||||
m_modelNameCombobox->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SPICE_MODEL_BASE::onModelNameComboboxUpdate ), NULL, this );
|
||||
m_overrideCheckbox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_SPICE_MODEL_BASE::onOverrideCheckbox ), NULL, this );
|
||||
m_overrideCheckbox->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SPICE_MODEL_BASE::onOverrideCheckboxUpdate ), NULL, this );
|
||||
m_deviceTypeChoice->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_SPICE_MODEL_BASE::onDeviceTypeChoice ), NULL, this );
|
||||
m_deviceTypeChoice->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SPICE_MODEL_BASE::onDeviceTypeChoiceUpdate ), NULL, this );
|
||||
m_typeChoice->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_SPICE_MODEL_BASE::onTypeChoice ), NULL, this );
|
||||
m_paramGridMgr->Disconnect( wxEVT_PG_CHANGED, wxPropertyGridEventHandler( DIALOG_SPICE_MODEL_BASE::onPropertyChanged ), NULL, this );
|
||||
m_typeChoice->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SPICE_MODEL_BASE::onTypeChoiceUpdate ), NULL, this );
|
||||
m_paramGridMgr->Disconnect( wxEVT_PG_CHANGED, wxPropertyGridEventHandler( DIALOG_SPICE_MODEL_BASE::onParamGridChanged ), NULL, this );
|
||||
m_pinAssignmentsGrid->Disconnect( wxEVT_GRID_CELL_CHANGED, wxGridEventHandler( DIALOG_SPICE_MODEL_BASE::onPinAssignmentsGridCellChange ), NULL, this );
|
||||
m_pinAssignmentsGrid->Disconnect( wxEVT_SIZE, wxSizeEventHandler( DIALOG_SPICE_MODEL_BASE::onPinAssignmentsGridSize ), NULL, this );
|
||||
|
||||
|
|
|
@ -184,7 +184,7 @@
|
|||
<property name="proportion">0</property>
|
||||
<object class="wxStaticBoxSizer" expanded="1">
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Properties</property>
|
||||
<property name="label">Source</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">sbSizer4</property>
|
||||
<property name="orient">wxVERTICAL</property>
|
||||
|
@ -195,9 +195,9 @@
|
|||
<property name="flag">wxEXPAND</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="wxFlexGridSizer" expanded="1">
|
||||
<property name="cols">3</property>
|
||||
<property name="cols">4</property>
|
||||
<property name="flexible_direction">wxBOTH</property>
|
||||
<property name="growablecols">1</property>
|
||||
<property name="growablecols">2</property>
|
||||
<property name="growablerows"></property>
|
||||
<property name="hgap">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
|
@ -206,11 +206,11 @@
|
|||
<property name="permission">none</property>
|
||||
<property name="rows">0</property>
|
||||
<property name="vgap">0</property>
|
||||
<object class="sizeritem" expanded="0">
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxStaticText" expanded="0">
|
||||
<object class="wxRadioButton" expanded="1">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
|
@ -238,8 +238,7 @@
|
|||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Model Name:</property>
|
||||
<property name="markup">0</property>
|
||||
<property name="label">Instance</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
|
@ -247,7 +246,72 @@
|
|||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_staticText122</property>
|
||||
<property name="name">m_useInstanceModelRadioButton</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style">wxRB_GROUP</property>
|
||||
<property name="subclass">; ; forward_declare</property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="validator_data_type"></property>
|
||||
<property name="validator_style">wxFILTER_NONE</property>
|
||||
<property name="validator_type">wxDefaultValidator</property>
|
||||
<property name="validator_variable"></property>
|
||||
<property name="value">0</property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<event name="OnRadioButton">onRadioButton</event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxRadioButton" expanded="1">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer"></property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Library:</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_useLibraryModelRadioButton</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
|
@ -261,10 +325,15 @@
|
|||
<property name="subclass">; ; forward_declare</property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="validator_data_type"></property>
|
||||
<property name="validator_style">wxFILTER_NONE</property>
|
||||
<property name="validator_type">wxDefaultValidator</property>
|
||||
<property name="validator_variable"></property>
|
||||
<property name="value">0</property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<property name="wrap">-1</property>
|
||||
<event name="OnRadioButton">onRadioButton</event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="0">
|
||||
|
@ -307,7 +376,7 @@
|
|||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_modelName</property>
|
||||
<property name="name">m_libraryFilenameInput</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
|
@ -329,13 +398,14 @@
|
|||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<event name="OnUpdateUI">onLibraryFilenameInputUpdate</event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="0">
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
|
||||
<property name="flag">wxALL</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxButton" expanded="0">
|
||||
<object class="wxBitmapButton" expanded="1">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
|
@ -369,7 +439,7 @@
|
|||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Browse...</property>
|
||||
<property name="label">MyButton</property>
|
||||
<property name="margins"></property>
|
||||
<property name="markup">0</property>
|
||||
<property name="max_size"></property>
|
||||
|
@ -402,11 +472,23 @@
|
|||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<event name="OnButtonClick">onBrowseButtonClick</event>
|
||||
<event name="OnUpdateUI">onBrowseButtonUpdate</event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="spacer" expanded="1">
|
||||
<property name="height">0</property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="width">0</property>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="0">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxStaticText" expanded="0">
|
||||
<property name="BottomDockable">1</property>
|
||||
|
@ -436,7 +518,7 @@
|
|||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Location:</property>
|
||||
<property name="label">Model:</property>
|
||||
<property name="markup">0</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
|
@ -445,7 +527,7 @@
|
|||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_staticText124</property>
|
||||
<property name="name">m_modelNameLabel</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
|
@ -455,7 +537,7 @@
|
|||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
<property name="style">wxALIGN_RIGHT</property>
|
||||
<property name="subclass">; ; forward_declare</property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
|
@ -465,11 +547,11 @@
|
|||
<property name="wrap">-1</property>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="0">
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
|
||||
<property name="flag">wxALL|wxEXPAND</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxStaticText" expanded="0">
|
||||
<object class="wxComboBox" expanded="1">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
|
@ -483,6 +565,7 @@
|
|||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="choices"></property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
|
@ -497,8 +580,6 @@
|
|||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">etc/kicad-sim/diodes.lib</property>
|
||||
<property name="markup">0</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
|
@ -506,7 +587,75 @@
|
|||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_staticText125</property>
|
||||
<property name="name">m_modelNameCombobox</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="selection">-1</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass">; ; forward_declare</property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="validator_data_type"></property>
|
||||
<property name="validator_style">wxFILTER_NONE</property>
|
||||
<property name="validator_type">wxDefaultValidator</property>
|
||||
<property name="validator_variable"></property>
|
||||
<property name="value"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<event name="OnCombobox">onModelNameCombobox</event>
|
||||
<event name="OnUpdateUI">onModelNameComboboxUpdate</event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxCheckBox" expanded="1">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer"></property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="checked">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Override</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_overrideCheckbox</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
|
@ -520,10 +669,15 @@
|
|||
<property name="subclass">; ; forward_declare</property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="validator_data_type"></property>
|
||||
<property name="validator_style">wxFILTER_NONE</property>
|
||||
<property name="validator_type">wxDefaultValidator</property>
|
||||
<property name="validator_variable"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<property name="wrap">-1</property>
|
||||
<event name="OnCheckBox">onOverrideCheckbox</event>
|
||||
<event name="OnUpdateUI">onOverrideCheckboxUpdate</event>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
|
@ -542,70 +696,6 @@
|
|||
<property name="orient">wxVERTICAL</property>
|
||||
<property name="parent">1</property>
|
||||
<property name="permission">none</property>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALL</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxCheckBox" expanded="1">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer"></property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="checked">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Change parameters for this symbol</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_checkBox2</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass">; ; forward_declare</property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="validator_data_type"></property>
|
||||
<property name="validator_style">wxFILTER_NONE</property>
|
||||
<property name="validator_type">wxDefaultValidator</property>
|
||||
<property name="validator_variable"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND | wxALL</property>
|
||||
|
@ -863,6 +953,7 @@
|
|||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<event name="OnChoice">onDeviceTypeChoice</event>
|
||||
<event name="OnUpdateUI">onDeviceTypeChoiceUpdate</event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
|
@ -989,6 +1080,7 @@
|
|||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<event name="OnChoice">onTypeChoice</event>
|
||||
<event name="OnUpdateUI">onTypeChoiceUpdate</event>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
|
@ -1051,7 +1143,7 @@
|
|||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<event name="OnPropertyGridChanged">onPropertyChanged</event>
|
||||
<event name="OnPropertyGridChanged">onParamGridChanged</event>
|
||||
<object class="propGridPage" expanded="1">
|
||||
<property name="bitmap"></property>
|
||||
<property name="label">Page</property>
|
||||
|
|
|
@ -12,19 +12,22 @@
|
|||
class WX_GRID;
|
||||
|
||||
#include <wx/string.h>
|
||||
#include <wx/stattext.h>
|
||||
#include <wx/radiobut.h>
|
||||
#include <wx/gdicmn.h>
|
||||
#include <wx/font.h>
|
||||
#include <wx/colour.h>
|
||||
#include <wx/settings.h>
|
||||
#include <wx/textctrl.h>
|
||||
#include <wx/button.h>
|
||||
#include <wx/bmpbuttn.h>
|
||||
#include <wx/bitmap.h>
|
||||
#include <wx/image.h>
|
||||
#include <wx/icon.h>
|
||||
#include <wx/button.h>
|
||||
#include <wx/stattext.h>
|
||||
#include <wx/combobox.h>
|
||||
#include <wx/checkbox.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/statbox.h>
|
||||
#include <wx/checkbox.h>
|
||||
#include <wx/choice.h>
|
||||
#include <wx/propgrid/propgrid.h>
|
||||
#include <wx/propgrid/manager.h>
|
||||
|
@ -49,12 +52,13 @@ class DIALOG_SPICE_MODEL_BASE : public wxDialog
|
|||
protected:
|
||||
wxNotebook* m_notebook;
|
||||
wxPanel* m_modelPanel;
|
||||
wxStaticText* m_staticText122;
|
||||
wxTextCtrl* m_modelName;
|
||||
wxButton* m_browseButton;
|
||||
wxStaticText* m_staticText124;
|
||||
wxStaticText* m_staticText125;
|
||||
wxCheckBox* m_checkBox2;
|
||||
wxRadioButton* m_useInstanceModelRadioButton;
|
||||
wxRadioButton* m_useLibraryModelRadioButton;
|
||||
wxTextCtrl* m_libraryFilenameInput;
|
||||
wxBitmapButton* m_browseButton;
|
||||
wxStaticText* m_modelNameLabel;
|
||||
wxComboBox* m_modelNameCombobox;
|
||||
wxCheckBox* m_overrideCheckbox;
|
||||
wxNotebook* m_notebook4;
|
||||
wxPanel* m_parametersPanel;
|
||||
wxStaticText* m_staticText127;
|
||||
|
@ -74,9 +78,19 @@ class DIALOG_SPICE_MODEL_BASE : public wxDialog
|
|||
wxButton* m_sdbSizer1Cancel;
|
||||
|
||||
// Virtual event handlers, override them in your derived class
|
||||
virtual void onRadioButton( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void onLibraryFilenameInputUpdate( wxUpdateUIEvent& event ) { event.Skip(); }
|
||||
virtual void onBrowseButtonClick( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void onBrowseButtonUpdate( wxUpdateUIEvent& event ) { event.Skip(); }
|
||||
virtual void onModelNameCombobox( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void onModelNameComboboxUpdate( wxUpdateUIEvent& event ) { event.Skip(); }
|
||||
virtual void onOverrideCheckbox( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void onOverrideCheckboxUpdate( wxUpdateUIEvent& event ) { event.Skip(); }
|
||||
virtual void onDeviceTypeChoice( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void onDeviceTypeChoiceUpdate( wxUpdateUIEvent& event ) { event.Skip(); }
|
||||
virtual void onTypeChoice( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void onPropertyChanged( wxPropertyGridEvent& event ) { event.Skip(); }
|
||||
virtual void onTypeChoiceUpdate( wxUpdateUIEvent& event ) { event.Skip(); }
|
||||
virtual void onParamGridChanged( wxPropertyGridEvent& event ) { event.Skip(); }
|
||||
virtual void onPinAssignmentsGridCellChange( wxGridEvent& event ) { event.Skip(); }
|
||||
virtual void onPinAssignmentsGridSize( wxSizeEvent& event ) { event.Skip(); }
|
||||
|
||||
|
|
|
@ -148,6 +148,7 @@ LIB_SYMBOL::LIB_SYMBOL( const LIB_SYMBOL& aSymbol, SYMBOL_LIB* aLibrary ) :
|
|||
catch( ... )
|
||||
{
|
||||
wxFAIL_MSG( "Failed to clone LIB_ITEM." );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2022 Mikolaj Wielgus
|
||||
* Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 3
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* https://www.gnu.org/licenses/gpl-3.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 3 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <sim/sim_library.h>
|
||||
|
||||
|
||||
bool SIM_LIBRARY::ReadFile( const wxString& aFilename )
|
||||
{
|
||||
m_filename = aFilename;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
std::vector<std::reference_wrapper<SIM_MODEL>> SIM_LIBRARY::GetModels()
|
||||
{
|
||||
std::vector<std::reference_wrapper<SIM_MODEL>> ret;
|
||||
|
||||
for( const std::unique_ptr<SIM_MODEL>& model : m_models )
|
||||
ret.emplace_back( *model );
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2022 Mikolaj Wielgus
|
||||
* Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 3
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* https://www.gnu.org/licenses/gpl-3.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 3 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef SIM_LIBRARY_H
|
||||
#define SIM_LIBRARY_H
|
||||
|
||||
#include <sim/sim_model.h>
|
||||
|
||||
|
||||
class SIM_LIBRARY
|
||||
{
|
||||
public:
|
||||
virtual ~SIM_LIBRARY() = default;
|
||||
SIM_LIBRARY() = default;
|
||||
|
||||
virtual bool ReadFile( const wxString& aFilename ) = 0;
|
||||
virtual void WriteFile( const wxString& aFilename ) = 0;
|
||||
|
||||
std::vector<std::reference_wrapper<SIM_MODEL>> GetModels();
|
||||
const std::vector<wxString>& GetModelNames() { return m_modelNames; }
|
||||
|
||||
wxString GetFilename() const { return m_filename; }
|
||||
wxString GetErrorMessage() const { return m_errorMessage; }
|
||||
|
||||
protected:
|
||||
std::vector<std::unique_ptr<SIM_MODEL>> m_models;
|
||||
std::vector<wxString> m_modelNames;
|
||||
|
||||
wxString m_filename;
|
||||
wxString m_errorMessage;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // SIM_LIBRARY_H
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2022 Mikolaj Wielgus
|
||||
* Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 3
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* https://www.gnu.org/licenses/gpl-3.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 3 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <sim/sim_library_spice.h>
|
||||
#include <sim/spice_grammar.h>
|
||||
#include <locale_io.h>
|
||||
#include <pegtl.hpp>
|
||||
#include <pegtl/contrib/parse_tree.hpp>
|
||||
|
||||
|
||||
namespace SIM_LIBRARY_SPICE_PARSER
|
||||
{
|
||||
using namespace SPICE_GRAMMAR;
|
||||
|
||||
struct unknownLine : until<newline> {};
|
||||
|
||||
struct library : star<sor<spiceUnit,
|
||||
unknownLine>> {};
|
||||
|
||||
struct libraryGrammar : must<library, eof> {};
|
||||
|
||||
|
||||
template <typename Rule> struct librarySelector : std::false_type {};
|
||||
|
||||
template <> struct librarySelector<modelUnit> : std::true_type {};
|
||||
template <> struct librarySelector<modelName> : std::true_type {};
|
||||
|
||||
// For debugging.
|
||||
template <> struct librarySelector<unknownLine> : std::true_type {};
|
||||
};
|
||||
|
||||
|
||||
bool SIM_LIBRARY_SPICE::ReadFile( const wxString& aFilename )
|
||||
{
|
||||
if( !SIM_LIBRARY::ReadFile( aFilename ) )
|
||||
return false;
|
||||
|
||||
LOCALE_IO toggle;
|
||||
|
||||
tao::pegtl::file_input in( aFilename.ToStdString() );
|
||||
std::unique_ptr<tao::pegtl::parse_tree::node> root;
|
||||
|
||||
try
|
||||
{
|
||||
root = tao::pegtl::parse_tree::parse<SIM_LIBRARY_SPICE_PARSER::libraryGrammar,
|
||||
SIM_LIBRARY_SPICE_PARSER::librarySelector>
|
||||
( in );
|
||||
}
|
||||
catch( tao::pegtl::parse_error& e )
|
||||
{
|
||||
m_errorMessage = wxString::Format( "Parsing failed: %s", e.what() );
|
||||
return false;
|
||||
}
|
||||
|
||||
wxASSERT( root );
|
||||
|
||||
for( const auto& node : root->children )
|
||||
{
|
||||
if( node->is_type<SIM_LIBRARY_SPICE_PARSER::modelUnit>() )
|
||||
{
|
||||
m_models.push_back( SIM_MODEL::Create( node->string() ) );
|
||||
|
||||
if( node->children.size() != 1 )
|
||||
{
|
||||
m_errorMessage = wxString::Format(
|
||||
"Captured %d name tokens, expected one", node->children.size() );
|
||||
return false;
|
||||
}
|
||||
|
||||
m_modelNames.emplace_back( node->children.at( 0 )->string() );
|
||||
}
|
||||
else if( node->is_type<SIM_LIBRARY_SPICE_PARSER::unknownLine>() )
|
||||
{
|
||||
// Do nothing.
|
||||
}
|
||||
else
|
||||
{
|
||||
m_errorMessage = wxString::Format( "Unhandled parse tree node: '%s'", node->string() );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void SIM_LIBRARY_SPICE::WriteFile( const wxString& aFileName )
|
||||
{
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2022 Mikolaj Wielgus
|
||||
* Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 3
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* https://www.gnu.org/licenses/gpl-3.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 3 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef SIM_LIBRARY_SPICE_H
|
||||
#define SIM_LIBRARY_SPICE_H
|
||||
|
||||
#include <sim/sim_library.h>
|
||||
|
||||
|
||||
class SIM_LIBRARY_SPICE : public SIM_LIBRARY
|
||||
{
|
||||
// We'll make SIM_LIBRARY have no subclasses probably.
|
||||
|
||||
public:
|
||||
bool ReadFile( const wxString& aFilename ) override;
|
||||
void WriteFile( const wxString& aFilename ) override;
|
||||
};
|
||||
|
||||
#endif // SIM_LIBRARY_SPICE_H
|
File diff suppressed because it is too large
Load Diff
|
@ -25,22 +25,46 @@
|
|||
#ifndef SIM_MODEL_H
|
||||
#define SIM_MODEL_H
|
||||
|
||||
#include <sim/spice_grammar.h>
|
||||
#include <enum_vector.h>
|
||||
#include <sch_field.h>
|
||||
#include <lib_field.h>
|
||||
#include <sim/sim_value.h>
|
||||
#include <wx/string.h>
|
||||
#include <map>
|
||||
#include <stdexcept>
|
||||
|
||||
class SIM_LIBRARY;
|
||||
|
||||
|
||||
namespace SIM_MODEL_GRAMMAR
|
||||
{
|
||||
using namespace SPICE_GRAMMAR;
|
||||
|
||||
|
||||
struct pinNumber : sor<digits, one<'X'>> {};
|
||||
struct pinSequence : seq<opt<pinNumber,
|
||||
star<sep,
|
||||
pinNumber>>> {};
|
||||
|
||||
struct pinSequenceGrammar : must<opt<sep>,
|
||||
pinSequence,
|
||||
opt<sep>,
|
||||
eof> {};
|
||||
|
||||
template <NOTATION Notation>
|
||||
struct paramValuePairsGrammar : must<opt<sep>,
|
||||
paramValuePairs<Notation>,
|
||||
opt<sep>,
|
||||
eof> {};
|
||||
}
|
||||
|
||||
|
||||
class SIM_MODEL
|
||||
{
|
||||
public:
|
||||
static constexpr auto DEVICE_TYPE_FIELD = "Model_Device";
|
||||
static constexpr auto TYPE_FIELD = "Model_Type";
|
||||
static constexpr auto FILE_FIELD = "Model_File";
|
||||
static constexpr auto PIN_SEQUENCE_FIELD = "Model_Pin_Sequence";
|
||||
static constexpr auto PINS_FIELD = "Model_Pins";
|
||||
static constexpr auto PARAMS_FIELD = "Model_Params";
|
||||
|
||||
|
||||
|
@ -238,6 +262,17 @@ public:
|
|||
};
|
||||
|
||||
|
||||
struct SPICE_INFO
|
||||
{
|
||||
wxString itemType;
|
||||
wxString typeString = "";
|
||||
wxString inlineTypeString = "";
|
||||
int level = 0;
|
||||
bool hasExpression = false;
|
||||
wxString version = "";
|
||||
};
|
||||
|
||||
|
||||
struct PIN
|
||||
{
|
||||
static constexpr auto NOT_CONNECTED = 0;
|
||||
|
@ -278,41 +313,52 @@ public:
|
|||
{
|
||||
wxString name;
|
||||
unsigned int id = 0; // Legacy.
|
||||
DIR dir;
|
||||
DIR dir = DIR::INOUT;
|
||||
SIM_VALUE_BASE::TYPE type;
|
||||
FLAGS flags = {}; // Legacy
|
||||
wxString unit;
|
||||
CATEGORY category;
|
||||
wxString unit = "";
|
||||
CATEGORY category = CATEGORY::PRINCIPAL;
|
||||
wxString defaultValue = "";
|
||||
wxString defaultValueOfOtherVariant = ""; // Legacy.
|
||||
wxString description;
|
||||
wxString description = "";
|
||||
};
|
||||
|
||||
std::unique_ptr<SIM_VALUE_BASE> value;
|
||||
const INFO& info;
|
||||
bool isOtherVariant = false; // Legacy.
|
||||
|
||||
PARAM( const INFO& aInfo ) :
|
||||
value( SIM_VALUE_BASE::Create( aInfo.type ) ),
|
||||
info( aInfo )
|
||||
PARAM( const INFO& aInfo, bool aIsOtherVariant = false )
|
||||
: value( SIM_VALUE_BASE::Create( aInfo.type ) ),
|
||||
info( aInfo ),
|
||||
isOtherVariant( aIsOtherVariant )
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
static DEVICE_INFO DeviceTypeInfo( DEVICE_TYPE aDeviceType );
|
||||
static INFO TypeInfo( TYPE aType );
|
||||
static SPICE_INFO SpiceInfo( TYPE aType );
|
||||
|
||||
|
||||
static TYPE ReadTypeFromSpiceCode( const std::string& aSpiceCode );
|
||||
|
||||
template <typename T>
|
||||
static TYPE ReadTypeFromFields( const std::vector<T>& aFields );
|
||||
|
||||
|
||||
template <typename T>
|
||||
static std::unique_ptr<SIM_MODEL> Create( int symbolPinCount, const std::vector<T>& aFields );
|
||||
static std::unique_ptr<SIM_MODEL> Create( TYPE aType, int aSymbolPinCount = 0 );
|
||||
static std::unique_ptr<SIM_MODEL> Create( const std::string& aSpiceCode );
|
||||
static std::unique_ptr<SIM_MODEL> Create( const SIM_MODEL& aBaseModel );
|
||||
|
||||
template <typename T = void>
|
||||
static std::unique_ptr<SIM_MODEL> Create( TYPE aType,
|
||||
int symbolPinCount,
|
||||
const std::vector<T>* aFields = nullptr );
|
||||
template <typename T>
|
||||
static std::unique_ptr<SIM_MODEL> Create( int aSymbolPinCount, const std::vector<T>& aFields );
|
||||
|
||||
template <typename T>
|
||||
static wxString GetFieldValue( const std::vector<T>* aFields, const wxString& aFieldName );
|
||||
|
||||
template <typename T>
|
||||
static void SetFieldValue( std::vector<T>& aFields, const wxString& aFieldName,
|
||||
const wxString& aValue );
|
||||
|
||||
|
||||
// Move semantics.
|
||||
|
@ -321,17 +367,17 @@ public:
|
|||
SIM_MODEL() = delete;
|
||||
SIM_MODEL( const SIM_MODEL& aOther ) = delete;
|
||||
SIM_MODEL( SIM_MODEL&& aOther ) = default;
|
||||
SIM_MODEL& operator=(SIM_MODEL&& aOther ) = default;
|
||||
SIM_MODEL& operator=(SIM_MODEL&& aOther ) = delete;
|
||||
|
||||
SIM_MODEL( TYPE aType );
|
||||
|
||||
virtual bool ReadSpiceCode( const std::string& aSpiceCode );
|
||||
|
||||
template <typename T>
|
||||
void ReadDataFields( int symbolPinCount, const std::vector<T>* aFields );
|
||||
void ReadDataFields( int aSymbolPinCount, const std::vector<T>* aFields );
|
||||
|
||||
// C++ doesn't allow virtual template methods, so we do this:
|
||||
virtual void ReadDataSchFields( int symbolPinCount, const std::vector<SCH_FIELD>* aFields );
|
||||
virtual void ReadDataLibFields( int symbolPinCount, const std::vector<LIB_FIELD>* aFields );
|
||||
virtual void ReadDataSchFields( int aSymbolPinCount, const std::vector<SCH_FIELD>* aFields );
|
||||
virtual void ReadDataLibFields( int aSymbolPinCount, const std::vector<LIB_FIELD>* aFields );
|
||||
|
||||
|
||||
template <typename T>
|
||||
|
@ -341,46 +387,83 @@ public:
|
|||
virtual void WriteDataSchFields( std::vector<SCH_FIELD>& aFields );
|
||||
virtual void WriteDataLibFields( std::vector<LIB_FIELD>& aFields );
|
||||
|
||||
virtual void WriteCode( wxString& aCode ) = 0;
|
||||
|
||||
virtual wxString GenerateSpiceIncludeLine( const wxString& aLibraryFilename ) const;
|
||||
virtual wxString GenerateSpiceModelLine( const wxString& aModelName ) const;
|
||||
|
||||
virtual SPICE_INFO GetSpiceInfo() const;
|
||||
|
||||
wxString GenerateSpiceItemLine( const wxString& aRefName, const wxString& aModelName ) const;
|
||||
virtual wxString GenerateSpiceItemLine( const wxString& aRefName,
|
||||
const wxString& aModelName,
|
||||
const std::vector<wxString>& aPinNetNames ) const;
|
||||
|
||||
virtual wxString GenerateSpicePreview( const wxString& aModelName ) const;
|
||||
|
||||
|
||||
TYPE GetType() { return m_type; }
|
||||
void AddParam( const PARAM::INFO& aInfo, bool aIsOtherVariant = false );
|
||||
|
||||
virtual wxString GetFile() { return m_file; }
|
||||
virtual void SetFile( const wxString& aFile ) { m_file = aFile; }
|
||||
TYPE GetType() const { return m_type; }
|
||||
|
||||
std::vector<PIN>& Pins() { return m_pins; }
|
||||
std::vector<PARAM>& Params() { return m_params; }
|
||||
const SIM_MODEL* GetBaseModel() const { return m_baseModel; }
|
||||
void SetBaseModel( const SIM_MODEL& aBaseModel ) { m_baseModel = &aBaseModel; }
|
||||
|
||||
int GetPinCount() const { return static_cast<int>( m_pins.size() ); }
|
||||
const PIN& GetPin( int aIndex ) const { return m_pins.at( aIndex ); }
|
||||
|
||||
void SetPinSymbolPinNumber( int aIndex, int aSymbolPinNumber )
|
||||
{
|
||||
m_pins.at( aIndex ).symbolPinNumber = aSymbolPinNumber;
|
||||
}
|
||||
|
||||
|
||||
int GetParamCount() const { return static_cast<int>( m_params.size() ); }
|
||||
const PARAM& GetParam( int aParamIndex ) const; // Return base parameter unless it's overridden.
|
||||
const PARAM& GetUnderlyingParam( int aParamIndex ) const; // Return the actual parameter.
|
||||
const PARAM& GetBaseParam( int aParamIndex ) const; // Always return base parameter if it exists.
|
||||
virtual bool SetParamValue( int aParamIndex, const wxString& aValue );
|
||||
|
||||
bool HasOverrides() const;
|
||||
bool HasNonPrincipalOverrides() const;
|
||||
|
||||
// Can modifying a model parameter also modify other parameters?
|
||||
virtual bool HasAutofill() const { return false; }
|
||||
|
||||
protected:
|
||||
SIM_MODEL( TYPE aType );
|
||||
|
||||
private:
|
||||
TYPE m_type;
|
||||
wxString m_file;
|
||||
static std::unique_ptr<SIM_MODEL> create( TYPE aType );
|
||||
static TYPE readTypeFromSpiceTypeString( const std::string& aTypeString );
|
||||
|
||||
wxString m_spiceCode;
|
||||
const SIM_MODEL* m_baseModel;
|
||||
|
||||
const TYPE m_type;
|
||||
std::vector<PIN> m_pins;
|
||||
std::vector<PARAM> m_params;
|
||||
|
||||
|
||||
template <typename T>
|
||||
void doReadDataFields( int symbolPinCount, const std::vector<T>* aFields );
|
||||
void doReadDataFields( int aSymbolPinCount, const std::vector<T>* aFields );
|
||||
|
||||
template <typename T>
|
||||
void doWriteFields( std::vector<T>& aFields );
|
||||
|
||||
|
||||
template <typename T>
|
||||
static wxString getFieldValue( const std::vector<T>* aFields, const wxString& aFieldName );
|
||||
virtual std::vector<wxString> getPinNames() const { return {}; }
|
||||
|
||||
template <typename T>
|
||||
static void setFieldValue( std::vector<T>& aFields, const wxString& aFieldName,
|
||||
const wxString& aValue );
|
||||
wxString generateDeviceTypeField() const;
|
||||
wxString generateTypeField() const;
|
||||
|
||||
virtual std::vector<wxString> getPinNames() { return {}; }
|
||||
wxString generatePinsField() const;
|
||||
void parsePinsField( int aSymbolPinCount, const wxString& aPinsField );
|
||||
|
||||
wxString generatePinSequence();
|
||||
void parsePinSequence( int symbolPinCount, const wxString& aPinSequence );
|
||||
|
||||
wxString generateParamsField( const wxString& aPairSeparator ) const;
|
||||
void parseParamsField( const wxString& aParamsField );
|
||||
|
||||
virtual wxString generateParamValuePairs();
|
||||
virtual void parseParamValuePairs( const wxString& aParamValuePairs );
|
||||
virtual bool setParamFromSpiceCode( const wxString& aParamName, const wxString& aParamValue );
|
||||
};
|
||||
|
||||
#endif // SIM_MODEL_H
|
||||
|
|
|
@ -23,18 +23,10 @@
|
|||
*/
|
||||
|
||||
#include <sim/sim_model_behavioral.h>
|
||||
#include <locale_io.h>
|
||||
|
||||
|
||||
template SIM_MODEL_BEHAVIORAL::SIM_MODEL_BEHAVIORAL( TYPE aType, int symbolPinCount,
|
||||
const std::vector<void>* aFields );
|
||||
template SIM_MODEL_BEHAVIORAL::SIM_MODEL_BEHAVIORAL( TYPE aType, int symbolPinCount,
|
||||
const std::vector<SCH_FIELD>* aFields );
|
||||
template SIM_MODEL_BEHAVIORAL::SIM_MODEL_BEHAVIORAL( TYPE aType, int symbolPinCount,
|
||||
const std::vector<LIB_FIELD>* aFields );
|
||||
|
||||
template <typename T>
|
||||
SIM_MODEL_BEHAVIORAL::SIM_MODEL_BEHAVIORAL( TYPE aType, int symbolPinCount,
|
||||
const std::vector<T>* aFields )
|
||||
SIM_MODEL_BEHAVIORAL::SIM_MODEL_BEHAVIORAL( TYPE aType )
|
||||
: SIM_MODEL( aType )
|
||||
{
|
||||
static PARAM::INFO resistor = makeParamInfo( "r", "Expression for resistance", "ohm" );
|
||||
|
@ -45,22 +37,62 @@ SIM_MODEL_BEHAVIORAL::SIM_MODEL_BEHAVIORAL( TYPE aType, int symbolPinCount,
|
|||
|
||||
switch( aType )
|
||||
{
|
||||
case TYPE::RESISTOR_BEHAVIORAL: Params().emplace_back( resistor ); break;
|
||||
case TYPE::CAPACITOR_BEHAVIORAL: Params().emplace_back( capacitor ); break;
|
||||
case TYPE::INDUCTOR_BEHAVIORAL: Params().emplace_back( inductor ); break;
|
||||
case TYPE::VSOURCE_BEHAVIORAL: Params().emplace_back( vsource ); break;
|
||||
case TYPE::ISOURCE_BEHAVIORAL: Params().emplace_back( isource ); break;
|
||||
case TYPE::RESISTOR_BEHAVIORAL: AddParam( resistor ); break;
|
||||
case TYPE::CAPACITOR_BEHAVIORAL: AddParam( capacitor ); break;
|
||||
case TYPE::INDUCTOR_BEHAVIORAL: AddParam( inductor ); break;
|
||||
case TYPE::VSOURCE_BEHAVIORAL: AddParam( vsource ); break;
|
||||
case TYPE::ISOURCE_BEHAVIORAL: AddParam( isource ); break;
|
||||
default:
|
||||
wxFAIL_MSG( "Unhandled SIM_MODEL type in SIM_MODEL_IDEAL" );
|
||||
}
|
||||
|
||||
ReadDataFields( symbolPinCount, aFields );
|
||||
}
|
||||
|
||||
|
||||
void SIM_MODEL_BEHAVIORAL::WriteCode( wxString& aCode )
|
||||
wxString SIM_MODEL_BEHAVIORAL::GenerateSpiceIncludeLine( const wxString& aLibraryFilename ) const
|
||||
{
|
||||
// TODO
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
wxString SIM_MODEL_BEHAVIORAL::GenerateSpiceModelLine( const wxString& aModelName ) const
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
wxString SIM_MODEL_BEHAVIORAL::GenerateSpiceItemLine( const wxString& aRefName,
|
||||
const wxString& aModelName,
|
||||
const std::vector<wxString>& aPinNetNames ) const
|
||||
{
|
||||
LOCALE_IO toggle;
|
||||
|
||||
switch( GetType() )
|
||||
{
|
||||
case TYPE::RESISTOR_BEHAVIORAL:
|
||||
case TYPE::CAPACITOR_BEHAVIORAL:
|
||||
case TYPE::INDUCTOR_BEHAVIORAL:
|
||||
return SIM_MODEL::GenerateSpiceItemLine( aRefName,
|
||||
GetParam( 0 ).value->ToString(),
|
||||
aPinNetNames );
|
||||
|
||||
case TYPE::VSOURCE_BEHAVIORAL:
|
||||
return SIM_MODEL::GenerateSpiceItemLine( aRefName,
|
||||
wxString::Format( "V=%s", GetParam( 0 ).value->ToString() ), aPinNetNames );
|
||||
|
||||
case TYPE::ISOURCE_BEHAVIORAL:
|
||||
return SIM_MODEL::GenerateSpiceItemLine( aRefName,
|
||||
wxString::Format( "I=%s", GetParam( 0 ).value->ToString() ), aPinNetNames );
|
||||
|
||||
default:
|
||||
wxFAIL_MSG( "Unhandled SIM_MODEL type in SIM_MODEL_BEHAVIORAL" );
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::vector<wxString> SIM_MODEL_BEHAVIORAL::getPinNames() const
|
||||
{
|
||||
return { "+", "-" };
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -31,12 +31,17 @@
|
|||
class SIM_MODEL_BEHAVIORAL : public SIM_MODEL
|
||||
{
|
||||
public:
|
||||
template <typename T = void>
|
||||
SIM_MODEL_BEHAVIORAL( TYPE aType, int symbolPinCount, const std::vector<T>* aFields = nullptr );
|
||||
SIM_MODEL_BEHAVIORAL( TYPE aType );
|
||||
|
||||
void WriteCode( wxString& aCode ) override;
|
||||
wxString GenerateSpiceIncludeLine( const wxString& aLibraryFilename ) const override;
|
||||
wxString GenerateSpiceModelLine( const wxString& aModelName ) const override;
|
||||
wxString GenerateSpiceItemLine( const wxString& aRefName,
|
||||
const wxString& aModelName,
|
||||
const std::vector<wxString>& aPinNetNames ) const override;
|
||||
|
||||
private:
|
||||
std::vector<wxString> getPinNames() const override;
|
||||
|
||||
static PARAM::INFO makeParamInfo( wxString name, wxString description, wxString unit );
|
||||
};
|
||||
|
||||
|
|
|
@ -25,22 +25,7 @@
|
|||
#include <sim/sim_model_codemodel.h>
|
||||
|
||||
|
||||
template SIM_MODEL_CODEMODEL::SIM_MODEL_CODEMODEL( TYPE aType, int symbolPinCount,
|
||||
const std::vector<void>* aFields );
|
||||
template SIM_MODEL_CODEMODEL::SIM_MODEL_CODEMODEL( TYPE aType, int symbolPinCount,
|
||||
const std::vector<SCH_FIELD>* aFields );
|
||||
template SIM_MODEL_CODEMODEL::SIM_MODEL_CODEMODEL( TYPE aType, int symbolPinCount,
|
||||
const std::vector<LIB_FIELD>* aFields );
|
||||
|
||||
template <typename T>
|
||||
SIM_MODEL_CODEMODEL::SIM_MODEL_CODEMODEL( TYPE aType, int symbolPinCount,
|
||||
const std::vector<T>* aFields )
|
||||
SIM_MODEL_CODEMODEL::SIM_MODEL_CODEMODEL( TYPE aType )
|
||||
: SIM_MODEL( aType )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void SIM_MODEL_CODEMODEL::WriteCode( wxString& aCode )
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
|
|
@ -31,10 +31,7 @@
|
|||
class SIM_MODEL_CODEMODEL : public SIM_MODEL
|
||||
{
|
||||
public:
|
||||
template <typename T = void>
|
||||
SIM_MODEL_CODEMODEL( TYPE aType, int symbolPinCount, const std::vector<T>* aFields = nullptr );
|
||||
|
||||
void WriteCode( wxString& aCode ) override;
|
||||
SIM_MODEL_CODEMODEL( TYPE aType );
|
||||
};
|
||||
|
||||
#endif // SIM_MODEL_CODEMODEL_H
|
||||
|
|
|
@ -27,16 +27,7 @@
|
|||
using PARAM = SIM_MODEL::PARAM;
|
||||
|
||||
|
||||
template SIM_MODEL_IDEAL::SIM_MODEL_IDEAL( TYPE aType, int symbolPinCount,
|
||||
const std::vector<void>* aFields );
|
||||
template SIM_MODEL_IDEAL::SIM_MODEL_IDEAL( TYPE aType, int symbolPinCount,
|
||||
const std::vector<SCH_FIELD>* aFields );
|
||||
template SIM_MODEL_IDEAL::SIM_MODEL_IDEAL( TYPE aType, int symbolPinCount,
|
||||
const std::vector<LIB_FIELD>* aFields );
|
||||
|
||||
template <typename T>
|
||||
SIM_MODEL_IDEAL::SIM_MODEL_IDEAL( TYPE aType, int symbolPinCount,
|
||||
const std::vector<T>* aFields )
|
||||
SIM_MODEL_IDEAL::SIM_MODEL_IDEAL( TYPE aType )
|
||||
: SIM_MODEL( aType )
|
||||
{
|
||||
static PARAM::INFO resistor = makeParamInfo( "r", "Resistance", "ohm" );
|
||||
|
@ -45,24 +36,37 @@ SIM_MODEL_IDEAL::SIM_MODEL_IDEAL( TYPE aType, int symbolPinCount,
|
|||
|
||||
switch( aType )
|
||||
{
|
||||
case TYPE::RESISTOR_IDEAL: Params().emplace_back( resistor ); break;
|
||||
case TYPE::CAPACITOR_IDEAL: Params().emplace_back( capacitor ); break;
|
||||
case TYPE::INDUCTOR_IDEAL: Params().emplace_back( inductor ); break;
|
||||
case TYPE::RESISTOR_IDEAL: AddParam( resistor ); break;
|
||||
case TYPE::CAPACITOR_IDEAL: AddParam( capacitor ); break;
|
||||
case TYPE::INDUCTOR_IDEAL: AddParam( inductor ); break;
|
||||
default:
|
||||
wxFAIL_MSG( "Unhandled SIM_MODEL type in SIM_MODEL_IDEAL" );
|
||||
}
|
||||
|
||||
ReadDataFields( symbolPinCount, aFields );
|
||||
}
|
||||
|
||||
|
||||
void SIM_MODEL_IDEAL::WriteCode( wxString& aCode )
|
||||
wxString SIM_MODEL_IDEAL::GenerateSpiceIncludeLine( const wxString& aLibraryFilename ) const
|
||||
{
|
||||
// TODO
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
std::vector<wxString> SIM_MODEL_IDEAL::getPinNames()
|
||||
wxString SIM_MODEL_IDEAL::GenerateSpiceModelLine( const wxString& aModelName ) const
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
wxString SIM_MODEL_IDEAL::GenerateSpiceItemLine( const wxString& aRefName,
|
||||
const wxString& aModelName,
|
||||
const std::vector<wxString>& aPinNetNames ) const
|
||||
{
|
||||
return SIM_MODEL::GenerateSpiceItemLine( aRefName, GetParam( 0 ).value->ToString(),
|
||||
aPinNetNames );
|
||||
}
|
||||
|
||||
|
||||
std::vector<wxString> SIM_MODEL_IDEAL::getPinNames() const
|
||||
{
|
||||
return { "+", "-" };
|
||||
}
|
||||
|
|
|
@ -31,13 +31,16 @@
|
|||
class SIM_MODEL_IDEAL : public SIM_MODEL
|
||||
{
|
||||
public:
|
||||
template <typename T = void>
|
||||
SIM_MODEL_IDEAL( TYPE aType, int symbolPinCount, const std::vector<T>* aFields = nullptr );
|
||||
SIM_MODEL_IDEAL( TYPE aType );
|
||||
|
||||
void WriteCode( wxString& aCode ) override;
|
||||
wxString GenerateSpiceIncludeLine( const wxString& aLibraryFilename ) const override;
|
||||
wxString GenerateSpiceModelLine( const wxString& aModelName ) const override;
|
||||
wxString GenerateSpiceItemLine( const wxString& aRefName,
|
||||
const wxString& aModelName,
|
||||
const std::vector<wxString>& aPinNetNames ) const override;
|
||||
|
||||
private:
|
||||
std::vector<wxString> getPinNames() override;
|
||||
std::vector<wxString> getPinNames() const override;
|
||||
|
||||
static PARAM::INFO makeParamInfo( wxString aName, wxString aDescription, wxString aUnit );
|
||||
};
|
||||
|
|
|
@ -27,49 +27,26 @@
|
|||
using TYPE = SIM_MODEL::TYPE;
|
||||
|
||||
|
||||
template SIM_MODEL_NGSPICE::SIM_MODEL_NGSPICE( TYPE aType, int symbolPinCount,
|
||||
const std::vector<void>* aFields );
|
||||
template SIM_MODEL_NGSPICE::SIM_MODEL_NGSPICE( TYPE aType, int symbolPinCount,
|
||||
const std::vector<SCH_FIELD>* aFields );
|
||||
template SIM_MODEL_NGSPICE::SIM_MODEL_NGSPICE( TYPE aType, int symbolPinCount,
|
||||
const std::vector<LIB_FIELD>* aFields );
|
||||
|
||||
template <typename T>
|
||||
SIM_MODEL_NGSPICE::SIM_MODEL_NGSPICE( TYPE aType, int symbolPinCount,
|
||||
const std::vector<T>* aFields )
|
||||
SIM_MODEL_NGSPICE::SIM_MODEL_NGSPICE( TYPE aType )
|
||||
: SIM_MODEL( aType )
|
||||
{
|
||||
const NGSPICE::MODEL_INFO& modelInfo = NGSPICE::ModelInfo( getModelType() );
|
||||
|
||||
for( const SIM_MODEL::PARAM::INFO& paramInfo : modelInfo.modelParams )
|
||||
{
|
||||
Params().emplace_back( paramInfo );
|
||||
Params().back().isOtherVariant = getIsOtherVariant();
|
||||
}
|
||||
AddParam( paramInfo, getIsOtherVariant() );
|
||||
|
||||
for( const SIM_MODEL::PARAM::INFO& paramInfo : modelInfo.instanceParams )
|
||||
{
|
||||
Params().emplace_back( paramInfo );
|
||||
Params().back().isOtherVariant = getIsOtherVariant();
|
||||
}
|
||||
|
||||
ReadDataFields( symbolPinCount, aFields );
|
||||
AddParam( paramInfo, getIsOtherVariant() );
|
||||
}
|
||||
|
||||
|
||||
void SIM_MODEL_NGSPICE::WriteCode( wxString& aCode )
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
|
||||
std::vector<wxString> SIM_MODEL_NGSPICE::getPinNames()
|
||||
std::vector<wxString> SIM_MODEL_NGSPICE::getPinNames() const
|
||||
{
|
||||
return NGSPICE::ModelInfo( getModelType() ).pinNames;
|
||||
}
|
||||
|
||||
|
||||
NGSPICE::MODEL_TYPE SIM_MODEL_NGSPICE::getModelType()
|
||||
NGSPICE::MODEL_TYPE SIM_MODEL_NGSPICE::getModelType() const
|
||||
{
|
||||
switch( GetType() )
|
||||
{
|
||||
|
|
|
@ -32,15 +32,12 @@
|
|||
class SIM_MODEL_NGSPICE : public SIM_MODEL
|
||||
{
|
||||
public:
|
||||
template <typename T = void>
|
||||
SIM_MODEL_NGSPICE( TYPE aType, int symbolPinCount, const std::vector<T>* aFields = nullptr );
|
||||
|
||||
void WriteCode( wxString& aCode ) override;
|
||||
SIM_MODEL_NGSPICE( TYPE aType );
|
||||
|
||||
private:
|
||||
std::vector<wxString> getPinNames() override;
|
||||
std::vector<wxString> getPinNames() const override;
|
||||
|
||||
NGSPICE::MODEL_TYPE getModelType();
|
||||
NGSPICE::MODEL_TYPE getModelType() const;
|
||||
bool getIsOtherVariant();
|
||||
};
|
||||
|
||||
|
|
|
@ -23,25 +23,49 @@
|
|||
*/
|
||||
|
||||
#include <sim/sim_model_rawspice.h>
|
||||
#include <pegtl.hpp>
|
||||
#include <pegtl/contrib/parse_tree.hpp>
|
||||
|
||||
|
||||
template SIM_MODEL_RAWSPICE::SIM_MODEL_RAWSPICE( TYPE aType, int symbolPinCount,
|
||||
const std::vector<void>* aFields );
|
||||
template SIM_MODEL_RAWSPICE::SIM_MODEL_RAWSPICE( TYPE aType, int symbolPinCount,
|
||||
const std::vector<SCH_FIELD>* aFields );
|
||||
template SIM_MODEL_RAWSPICE::SIM_MODEL_RAWSPICE( TYPE aType, int symbolPinCount,
|
||||
const std::vector<LIB_FIELD>* aFields );
|
||||
|
||||
template <typename T>
|
||||
SIM_MODEL_RAWSPICE::SIM_MODEL_RAWSPICE( TYPE aType, int symbolPinCount,
|
||||
const std::vector<T>* aFields )
|
||||
SIM_MODEL_RAWSPICE::SIM_MODEL_RAWSPICE( TYPE aType )
|
||||
: SIM_MODEL( aType )
|
||||
{
|
||||
ReadDataFields( symbolPinCount, aFields );
|
||||
}
|
||||
|
||||
|
||||
void SIM_MODEL_RAWSPICE::WriteCode( wxString& aCode )
|
||||
bool SIM_MODEL_RAWSPICE::setParamFromSpiceCode( const wxString& aParamName,
|
||||
const wxString& aParamValue )
|
||||
{
|
||||
// TODO
|
||||
int i = 0;
|
||||
|
||||
for(; i < GetParamCount(); ++i )
|
||||
{
|
||||
if( GetParam( i ).info.name == aParamName.Lower() )
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if( i == GetParamCount() )
|
||||
{
|
||||
// No parameter with this name found. Create a new one.
|
||||
std::unique_ptr<PARAM::INFO> paramInfo = std::make_unique<PARAM::INFO>();
|
||||
|
||||
paramInfo->name = aParamName.Lower();
|
||||
paramInfo->type = SIM_VALUE_BASE::TYPE::STRING;
|
||||
m_paramInfos.push_back( std::move( paramInfo ) );
|
||||
|
||||
AddParam( *m_paramInfos.back() );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
GetParam( i ).value->FromString( wxString( aParamValue ) );
|
||||
}
|
||||
catch( KI_PARAM_ERROR& e )
|
||||
{
|
||||
// Shouldn't happen since it's TYPE::STRING.
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -31,10 +31,14 @@
|
|||
class SIM_MODEL_RAWSPICE : public SIM_MODEL
|
||||
{
|
||||
public:
|
||||
template <typename T = void>
|
||||
SIM_MODEL_RAWSPICE( TYPE aType, int symbolPinCount, const std::vector<T>* aFields = nullptr );
|
||||
SIM_MODEL_RAWSPICE( TYPE aType );
|
||||
|
||||
void WriteCode( wxString& aCode ) override;
|
||||
//bool ReadSpiceCode( const std::string& aSpiceCode ) override;
|
||||
|
||||
private:
|
||||
bool setParamFromSpiceCode( const wxString& aParamName, const wxString& aParamValue ) override;
|
||||
|
||||
std::vector<std::unique_ptr<PARAM::INFO>> m_paramInfos;
|
||||
};
|
||||
|
||||
#endif // SIM_MODEL_RAWSPICE_H
|
||||
|
|
|
@ -27,21 +27,38 @@
|
|||
using PARAM = SIM_MODEL::PARAM;
|
||||
|
||||
|
||||
template SIM_MODEL_SOURCE::SIM_MODEL_SOURCE( TYPE aType, int symbolPinCount,
|
||||
const std::vector<void>* aFields );
|
||||
template SIM_MODEL_SOURCE::SIM_MODEL_SOURCE( TYPE aType, int symbolPinCount,
|
||||
const std::vector<SCH_FIELD>* aFields );
|
||||
template SIM_MODEL_SOURCE::SIM_MODEL_SOURCE( TYPE aType, int symbolPinCount,
|
||||
const std::vector<LIB_FIELD>* aFields );
|
||||
|
||||
template <typename T>
|
||||
SIM_MODEL_SOURCE::SIM_MODEL_SOURCE( TYPE aType, int symbolPinCount, const std::vector<T>* aFields )
|
||||
SIM_MODEL_SOURCE::SIM_MODEL_SOURCE( TYPE aType )
|
||||
: SIM_MODEL( aType )
|
||||
{
|
||||
for( const PARAM::INFO& paramInfo : makeParams( aType ) )
|
||||
Params().emplace_back( paramInfo );
|
||||
AddParam( paramInfo );
|
||||
}
|
||||
|
||||
ReadDataFields( symbolPinCount, aFields );
|
||||
|
||||
wxString SIM_MODEL_SOURCE::GenerateSpiceIncludeLine( const wxString& aLibraryFilename ) const
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
wxString SIM_MODEL_SOURCE::GenerateSpiceModelLine( const wxString& aModelName ) const
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
wxString SIM_MODEL_SOURCE::GenerateSpiceItemLine( const wxString& aRefName,
|
||||
const wxString& aModelName,
|
||||
const std::vector<wxString>& aPinNetNames ) const
|
||||
{
|
||||
wxString argList = "";
|
||||
|
||||
for( int i = 0; i < GetParamCount(); ++i )
|
||||
argList << GetParam( i ).value->ToString() << " ";
|
||||
|
||||
wxString model = wxString::Format( GetSpiceInfo().inlineTypeString + "( %s)", argList );
|
||||
|
||||
return SIM_MODEL::GenerateSpiceItemLine( aRefName, model, aPinNetNames );
|
||||
}
|
||||
|
||||
|
||||
|
@ -122,9 +139,31 @@ const std::vector<PARAM::INFO>& SIM_MODEL_SOURCE::makeParams( TYPE aType )
|
|||
}
|
||||
|
||||
|
||||
void SIM_MODEL_SOURCE::WriteCode( wxString& aCode )
|
||||
bool SIM_MODEL_SOURCE::SetParamValue( int aParamIndex, const wxString& aValue )
|
||||
{
|
||||
// TODO
|
||||
// Sources are special. All preceding parameter values must be filled. If they are not, fill
|
||||
// them out automatically. If a value is nulled, delete everything after it.
|
||||
if( aValue.IsEmpty() )
|
||||
{
|
||||
for( int i = aParamIndex; i < GetParamCount(); ++i )
|
||||
SIM_MODEL::SetParamValue( i, "" );
|
||||
}
|
||||
else
|
||||
{
|
||||
for( int i = 0; i < aParamIndex; ++i )
|
||||
{
|
||||
if( GetParam( i ).value->ToString().IsEmpty() )
|
||||
SIM_MODEL::SetParamValue( i, "0" );
|
||||
}
|
||||
}
|
||||
|
||||
return SIM_MODEL::SetParamValue( aParamIndex, aValue );
|
||||
}
|
||||
|
||||
|
||||
std::vector<wxString> SIM_MODEL_SOURCE::getPinNames() const
|
||||
{
|
||||
return { "+", "-" };
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -31,12 +31,21 @@
|
|||
class SIM_MODEL_SOURCE : public SIM_MODEL
|
||||
{
|
||||
public:
|
||||
template <typename T = void>
|
||||
SIM_MODEL_SOURCE( TYPE aType, int symbolPinCount, const std::vector<T>* aFields = nullptr );
|
||||
SIM_MODEL_SOURCE( TYPE aType );
|
||||
|
||||
void WriteCode( wxString& aCode ) override;
|
||||
wxString GenerateSpiceIncludeLine( const wxString& aLibraryFilename ) const override;
|
||||
wxString GenerateSpiceModelLine( const wxString& aModelName ) const override;
|
||||
wxString GenerateSpiceItemLine( const wxString& aRefName,
|
||||
const wxString& aModelName,
|
||||
const std::vector<wxString>& aPinNetNames ) const override;
|
||||
|
||||
bool SetParamValue( int aParamIndex, const wxString& aValue ) override;
|
||||
|
||||
bool HasAutofill() const override { return true; }
|
||||
|
||||
private:
|
||||
std::vector<wxString> getPinNames() const override;
|
||||
|
||||
static const std::vector<PARAM::INFO>& makeParams( TYPE aType );
|
||||
|
||||
static std::vector<PARAM::INFO> makePulse( wxString aPrefix, wxString aUnit );
|
||||
|
|
|
@ -25,23 +25,7 @@
|
|||
#include <sim/sim_model_subcircuit.h>
|
||||
|
||||
|
||||
template SIM_MODEL_SUBCIRCUIT::SIM_MODEL_SUBCIRCUIT( TYPE aType, int symbolPinCount,
|
||||
const std::vector<void>* aFields );
|
||||
template SIM_MODEL_SUBCIRCUIT::SIM_MODEL_SUBCIRCUIT( TYPE aType, int symbolPinCount,
|
||||
const std::vector<SCH_FIELD>* aFields );
|
||||
template SIM_MODEL_SUBCIRCUIT::SIM_MODEL_SUBCIRCUIT( TYPE aType, int symbolPinCount,
|
||||
const std::vector<LIB_FIELD>* aFields );
|
||||
|
||||
template <typename T>
|
||||
SIM_MODEL_SUBCIRCUIT::SIM_MODEL_SUBCIRCUIT( TYPE aType, int symbolPinCount,
|
||||
const std::vector<T>* aFields )
|
||||
SIM_MODEL_SUBCIRCUIT::SIM_MODEL_SUBCIRCUIT( TYPE aType )
|
||||
: SIM_MODEL( aType )
|
||||
{
|
||||
ReadDataFields( symbolPinCount, aFields );
|
||||
}
|
||||
|
||||
|
||||
void SIM_MODEL_SUBCIRCUIT::WriteCode( wxString& aCode )
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
|
|
@ -31,10 +31,7 @@
|
|||
class SIM_MODEL_SUBCIRCUIT : public SIM_MODEL
|
||||
{
|
||||
public:
|
||||
template <typename T = void>
|
||||
SIM_MODEL_SUBCIRCUIT( TYPE aType, int symbolPinCount, const std::vector<T>* aFields = nullptr );
|
||||
|
||||
void WriteCode( wxString& aCode ) override;
|
||||
SIM_MODEL_SUBCIRCUIT( TYPE aType );
|
||||
};
|
||||
|
||||
#endif // SIM_MODEL_SUBCIRCUIT_H
|
||||
|
|
|
@ -38,7 +38,7 @@ wxEND_EVENT_TABLE()
|
|||
|
||||
|
||||
SIM_VALIDATOR::SIM_VALIDATOR( SIM_VALUE_BASE::TYPE aValueType,
|
||||
SIM_VALUE_PARSER::NOTATION aNotation )
|
||||
SIM_VALUE_GRAMMAR::NOTATION aNotation )
|
||||
: wxValidator(),
|
||||
m_valueType( aValueType ),
|
||||
m_notation( aNotation )
|
||||
|
@ -85,7 +85,7 @@ bool SIM_VALIDATOR::TransferFromWindow()
|
|||
|
||||
bool SIM_VALIDATOR::isValid( const wxString& aString )
|
||||
{
|
||||
return SIM_VALUE_PARSER::IsValid( aString, m_valueType, m_notation );
|
||||
return SIM_VALUE_GRAMMAR::IsValid( aString, m_valueType, m_notation );
|
||||
}
|
||||
|
||||
|
||||
|
@ -151,14 +151,19 @@ void SIM_VALIDATOR::onMouse( wxMouseEvent& aEvent )
|
|||
|
||||
|
||||
SIM_PROPERTY::SIM_PROPERTY( const wxString& aLabel, const wxString& aName,
|
||||
SIM_VALUE_BASE& aValue,
|
||||
std::shared_ptr<SIM_LIBRARY> aLibrary,
|
||||
std::shared_ptr<SIM_MODEL> aModel,
|
||||
int aParamIndex,
|
||||
SIM_VALUE_BASE::TYPE aValueType,
|
||||
SIM_VALUE_PARSER::NOTATION aNotation )
|
||||
: wxStringProperty( aLabel, aName, aValue.ToString() ),
|
||||
SIM_VALUE_GRAMMAR::NOTATION aNotation )
|
||||
: wxStringProperty( aLabel, aName ),
|
||||
m_valueType( aValueType ),
|
||||
m_notation( aNotation ),
|
||||
m_value( aValue )
|
||||
m_library( aLibrary ),
|
||||
m_model( aModel ),
|
||||
m_paramIndex( aParamIndex )
|
||||
{
|
||||
SetValueFromString( GetParam().value->ToString() );
|
||||
}
|
||||
|
||||
|
||||
|
@ -172,7 +177,19 @@ bool SIM_PROPERTY::StringToValue( wxVariant& aVariant, const wxString& aText, in
|
|||
{
|
||||
try
|
||||
{
|
||||
m_value.FromString( aText );
|
||||
wxString paramValueStr = m_model->GetBaseParam( m_paramIndex ).value->ToString();
|
||||
|
||||
// TODO: Don't use string comparison.
|
||||
if( m_model->GetBaseModel() && ( aText.IsEmpty() || aText == paramValueStr ) )
|
||||
{
|
||||
m_model->SetParamValue( m_paramIndex, "" ); // Nullify.
|
||||
aVariant = paramValueStr; // Use the inherited value (if it exists) if null.
|
||||
}
|
||||
else
|
||||
{
|
||||
m_model->SetParamValue( m_paramIndex, aText );
|
||||
aVariant = GetParam().value->ToString();
|
||||
}
|
||||
}
|
||||
catch( KI_PARAM_ERROR& e )
|
||||
{
|
||||
|
@ -180,6 +197,5 @@ bool SIM_PROPERTY::StringToValue( wxVariant& aVariant, const wxString& aText, in
|
|||
return false;
|
||||
}
|
||||
|
||||
aVariant = m_value.ToString();
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -25,14 +25,14 @@
|
|||
#ifndef SIM_PROPERTY_H
|
||||
#define SIM_PROPERTY_H
|
||||
|
||||
#include <sim/sim_value.h>
|
||||
#include <sim/sim_model.h>
|
||||
#include <wx/propgrid/props.h>
|
||||
|
||||
|
||||
class SIM_VALIDATOR : public wxValidator
|
||||
{
|
||||
public:
|
||||
SIM_VALIDATOR( SIM_VALUE_BASE::TYPE aValueType, SIM_VALUE_PARSER::NOTATION aNotation );
|
||||
SIM_VALIDATOR( SIM_VALUE_BASE::TYPE aValueType, SIM_VALUE_GRAMMAR::NOTATION aNotation );
|
||||
SIM_VALIDATOR( const SIM_VALIDATOR& aValidator ) = default;
|
||||
|
||||
wxObject* Clone() const override;
|
||||
|
@ -51,7 +51,7 @@ private:
|
|||
void onMouse( wxMouseEvent& aEvent );
|
||||
|
||||
SIM_VALUE_BASE::TYPE m_valueType;
|
||||
SIM_VALUE_PARSER::NOTATION m_notation;
|
||||
SIM_VALUE_GRAMMAR::NOTATION m_notation;
|
||||
wxString m_prevText;
|
||||
long m_prevInsertionPoint;
|
||||
|
||||
|
@ -62,19 +62,28 @@ private:
|
|||
class SIM_PROPERTY : public wxStringProperty
|
||||
{
|
||||
public:
|
||||
SIM_PROPERTY( const wxString& aLabel, const wxString& aName, SIM_VALUE_BASE& aValue,
|
||||
// We pass shared_ptrs because we need to make sure they are destroyed only after the last time
|
||||
// SIM_PROPERTY uses them.
|
||||
SIM_PROPERTY( const wxString& aLabel, const wxString& aName,
|
||||
std::shared_ptr<SIM_LIBRARY> aLibrary,
|
||||
std::shared_ptr<SIM_MODEL> aModel,
|
||||
int aParamIndex,
|
||||
SIM_VALUE_BASE::TYPE aValueType = SIM_VALUE_BASE::TYPE::FLOAT,
|
||||
SIM_VALUE_PARSER::NOTATION aNotation = SIM_VALUE_PARSER::NOTATION::SI );
|
||||
SIM_VALUE_GRAMMAR::NOTATION aNotation = SIM_VALUE_GRAMMAR::NOTATION::SI );
|
||||
|
||||
wxValidator* DoGetValidator() const override;
|
||||
|
||||
bool StringToValue( wxVariant& aVariant, const wxString& aText, int aArgFlags = 0 )
|
||||
const override;
|
||||
|
||||
const SIM_MODEL::PARAM& GetParam() const { return m_model->GetParam( m_paramIndex ); }
|
||||
|
||||
protected:
|
||||
SIM_VALUE_BASE::TYPE m_valueType;
|
||||
SIM_VALUE_PARSER::NOTATION m_notation;
|
||||
SIM_VALUE_BASE& m_value;
|
||||
SIM_VALUE_BASE::TYPE m_valueType;
|
||||
SIM_VALUE_GRAMMAR::NOTATION m_notation;
|
||||
std::shared_ptr<SIM_LIBRARY> m_library;
|
||||
std::shared_ptr<SIM_MODEL> m_model;
|
||||
int m_paramIndex;
|
||||
};
|
||||
|
||||
#endif // SIM_PROPERTY_H
|
||||
|
|
|
@ -71,13 +71,56 @@
|
|||
}
|
||||
|
||||
|
||||
namespace SIM_VALUE_PARSER
|
||||
{
|
||||
using namespace SIM_VALUE_GRAMMAR;
|
||||
|
||||
template <typename Rule>
|
||||
struct numberSelector : std::false_type {};
|
||||
|
||||
template <> struct numberSelector<SIM_VALUE_GRAMMAR::significand<SIM_VALUE_BASE::TYPE::INT>>
|
||||
: std::true_type {};
|
||||
template <> struct numberSelector<SIM_VALUE_GRAMMAR::significand<SIM_VALUE_BASE::TYPE::FLOAT>>
|
||||
: std::true_type {};
|
||||
template <> struct numberSelector<intPart> : std::true_type {};
|
||||
template <> struct numberSelector<fracPart> : std::true_type {};
|
||||
template <> struct numberSelector<exponent> : std::true_type {};
|
||||
template <> struct numberSelector<metricSuffix<SIM_VALUE_BASE::TYPE::INT, NOTATION::SI>>
|
||||
: std::true_type {};
|
||||
template <> struct numberSelector<metricSuffix<SIM_VALUE_BASE::TYPE::INT, NOTATION::SPICE>>
|
||||
: std::true_type {};
|
||||
template <> struct numberSelector<metricSuffix<SIM_VALUE_BASE::TYPE::FLOAT, NOTATION::SI>>
|
||||
: std::true_type {};
|
||||
template <> struct numberSelector<metricSuffix<SIM_VALUE_BASE::TYPE::FLOAT, NOTATION::SPICE>>
|
||||
: std::true_type {};
|
||||
|
||||
struct PARSE_RESULT
|
||||
{
|
||||
bool isEmpty = true;
|
||||
std::string significand;
|
||||
OPT<long> intPart;
|
||||
OPT<long> fracPart;
|
||||
OPT<long> exponent;
|
||||
OPT<long> metricSuffixExponent;
|
||||
};
|
||||
|
||||
PARSE_RESULT Parse( const wxString& aString,
|
||||
SIM_VALUE_BASE::TYPE aValueType = SIM_VALUE_BASE::TYPE::FLOAT,
|
||||
NOTATION aNotation = NOTATION::SI );
|
||||
|
||||
long MetricSuffixToExponent( std::string aMetricSuffix, NOTATION aNotation = NOTATION::SI );
|
||||
wxString ExponentToMetricSuffix( double aExponent, long& aReductionExponent,
|
||||
NOTATION aNotation = NOTATION::SI );
|
||||
}
|
||||
|
||||
|
||||
template <SIM_VALUE_BASE::TYPE ValueType, SIM_VALUE_PARSER::NOTATION Notation>
|
||||
static inline void doIsValid( tao::pegtl::string_input<>& aIn )
|
||||
{
|
||||
tao::pegtl::parse<SIM_VALUE_PARSER::numberGrammar<ValueType, Notation>>( aIn );
|
||||
}
|
||||
|
||||
bool SIM_VALUE_PARSER::IsValid( const wxString& aString,
|
||||
bool SIM_VALUE_GRAMMAR::IsValid( const wxString& aString,
|
||||
SIM_VALUE_BASE::TYPE aValueType,
|
||||
NOTATION aNotation )
|
||||
{
|
||||
|
@ -163,7 +206,9 @@ SIM_VALUE_PARSER::PARSE_RESULT SIM_VALUE_PARSER::Parse( const wxString& aString,
|
|||
try
|
||||
{
|
||||
for( const auto& node : root->children )
|
||||
{
|
||||
CALL_INSTANCE( aValueType, aNotation, handleNodeForParse, *node, result );
|
||||
}
|
||||
}
|
||||
catch( std::invalid_argument& e )
|
||||
{
|
||||
|
@ -482,14 +527,19 @@ wxString SIM_VALUE<long>::ToString() const
|
|||
|
||||
if( m_value.has_value() )
|
||||
{
|
||||
double exponent = std::log10( *m_value );
|
||||
long reductionExponent = 0;
|
||||
long value = *m_value;
|
||||
long exponent = 0;
|
||||
|
||||
wxString metricSuffix = SIM_VALUE_PARSER::ExponentToMetricSuffix( exponent,
|
||||
reductionExponent );
|
||||
long reducedValue = *m_value / static_cast<long>( std::pow( 10, reductionExponent ) );
|
||||
while( value % 1000 == 0 )
|
||||
{
|
||||
exponent += 3;
|
||||
value /= 1000;
|
||||
}
|
||||
|
||||
return wxString::Format( "%d%s", reducedValue, metricSuffix );
|
||||
long dummy = 0;
|
||||
wxString metricSuffix = SIM_VALUE_PARSER::ExponentToMetricSuffix(
|
||||
static_cast<double>( exponent ), dummy );
|
||||
return wxString::Format( "%d%s", value, metricSuffix );
|
||||
}
|
||||
|
||||
return "";
|
||||
|
|
|
@ -86,7 +86,7 @@ private:
|
|||
};
|
||||
|
||||
|
||||
namespace SIM_VALUE_PARSER
|
||||
namespace SIM_VALUE_GRAMMAR
|
||||
{
|
||||
using namespace tao::pegtl;
|
||||
|
||||
|
@ -100,7 +100,6 @@ namespace SIM_VALUE_PARSER
|
|||
wxString allowedIntChars;
|
||||
|
||||
|
||||
struct spaces : plus<space> {};
|
||||
struct digits : plus<tao::pegtl::digit> {}; // For some reason it fails on just "digit".
|
||||
|
||||
struct sign : one<'+', '-'> {};
|
||||
|
@ -165,43 +164,9 @@ namespace SIM_VALUE_PARSER
|
|||
struct numberGrammar : must<opt<number<ValueType, Notation>>, eof> {};
|
||||
|
||||
|
||||
template <typename Rule>
|
||||
struct numberSelector : std::false_type {};
|
||||
|
||||
template <> struct numberSelector<significand<SIM_VALUE_BASE::TYPE::INT>> : std::true_type {};
|
||||
template <> struct numberSelector<significand<SIM_VALUE_BASE::TYPE::FLOAT>> : std::true_type {};
|
||||
template <> struct numberSelector<intPart> : std::true_type {};
|
||||
template <> struct numberSelector<fracPart> : std::true_type {};
|
||||
template <> struct numberSelector<exponent> : std::true_type {};
|
||||
template <> struct numberSelector<metricSuffix<SIM_VALUE_BASE::TYPE::INT, NOTATION::SI>>
|
||||
: std::true_type {};
|
||||
template <> struct numberSelector<metricSuffix<SIM_VALUE_BASE::TYPE::INT, NOTATION::SPICE>>
|
||||
: std::true_type {};
|
||||
template <> struct numberSelector<metricSuffix<SIM_VALUE_BASE::TYPE::FLOAT, NOTATION::SI>>
|
||||
: std::true_type {};
|
||||
template <> struct numberSelector<metricSuffix<SIM_VALUE_BASE::TYPE::FLOAT, NOTATION::SPICE>>
|
||||
: std::true_type {};
|
||||
|
||||
struct PARSE_RESULT
|
||||
{
|
||||
bool isEmpty = true;
|
||||
std::string significand;
|
||||
OPT<long> intPart;
|
||||
OPT<long> fracPart;
|
||||
OPT<long> exponent;
|
||||
OPT<long> metricSuffixExponent;
|
||||
};
|
||||
|
||||
bool IsValid( const wxString& aString,
|
||||
SIM_VALUE_BASE::TYPE aValueType = SIM_VALUE_BASE::TYPE::FLOAT,
|
||||
NOTATION aNotation = NOTATION::SI );
|
||||
PARSE_RESULT Parse( const wxString& aString,
|
||||
SIM_VALUE_BASE::TYPE aValueType = SIM_VALUE_BASE::TYPE::FLOAT,
|
||||
NOTATION aNotation = NOTATION::SI );
|
||||
|
||||
long MetricSuffixToExponent( std::string aMetricSuffix, NOTATION aNotation = NOTATION::SI );
|
||||
wxString ExponentToMetricSuffix( double aExponent, long& aReductionExponent,
|
||||
NOTATION aNotation = NOTATION::SI );
|
||||
}
|
||||
|
||||
#endif // SIM_VALUE_H
|
||||
|
|
|
@ -0,0 +1,156 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2022 Mikolaj Wielgus
|
||||
* Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 3
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* https://www.gnu.org/licenses/gpl-3.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 3 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef SPICE_GRAMMAR_H
|
||||
#define SPICE_GRAMMAR_H
|
||||
|
||||
#include <sim/sim_value.h>
|
||||
|
||||
|
||||
namespace SPICE_GRAMMAR
|
||||
{
|
||||
using namespace SIM_VALUE_GRAMMAR;
|
||||
|
||||
|
||||
struct eolComment : seq<one<';'>, until<eol>> {};
|
||||
struct commentLine : seq<one<'*', ';'>, until<eol>> {};
|
||||
|
||||
|
||||
struct linespaces : plus<not_at<eol>,
|
||||
space> {};
|
||||
struct newline : seq<sor<eol,
|
||||
eolComment>,
|
||||
not_at<one<'+'>>> {};
|
||||
|
||||
struct continuation : seq<opt<linespaces>,
|
||||
sor<eol,
|
||||
eolComment>,
|
||||
star<commentLine>,
|
||||
one<'+'>,
|
||||
opt<linespaces>> {};
|
||||
|
||||
struct sep : sor<continuation,
|
||||
linespaces> {};
|
||||
|
||||
|
||||
struct param : plus<alnum> {};
|
||||
|
||||
template <SIM_VALUE_BASE::TYPE Type, NOTATION Notation>
|
||||
struct paramValuePair : seq<param,
|
||||
opt<sep>,
|
||||
one<'='>,
|
||||
opt<sep>,
|
||||
number<Type, Notation>> {};
|
||||
|
||||
template <NOTATION Notation>
|
||||
struct paramValuePairs : seq<opt<paramValuePair<SIM_VALUE_BASE::TYPE::FLOAT,
|
||||
Notation>,
|
||||
star<sep,
|
||||
paramValuePair<SIM_VALUE_BASE::TYPE::FLOAT,
|
||||
Notation>>>> {};
|
||||
|
||||
|
||||
struct modelName : plus<alnum,
|
||||
star<sor<alnum,
|
||||
one<'!', '#', '$', '%', '[', ']', '_'>>>> {};
|
||||
/*seq<alpha,
|
||||
star<sor<alnum,
|
||||
one<'!', '#', '$', '%', '[', ']', '_'>>>> {};*/
|
||||
|
||||
|
||||
struct dotModelType : sor<TAO_PEGTL_ISTRING( "R" ),
|
||||
TAO_PEGTL_ISTRING( "C" ),
|
||||
TAO_PEGTL_ISTRING( "L" ),
|
||||
TAO_PEGTL_ISTRING( "SW" ),
|
||||
TAO_PEGTL_ISTRING( "CSW" ),
|
||||
TAO_PEGTL_ISTRING( "URC" ),
|
||||
TAO_PEGTL_ISTRING( "LTRA" ),
|
||||
TAO_PEGTL_ISTRING( "D" ),
|
||||
TAO_PEGTL_ISTRING( "NPN" ),
|
||||
TAO_PEGTL_ISTRING( "PNP" ),
|
||||
TAO_PEGTL_ISTRING( "NJF" ),
|
||||
TAO_PEGTL_ISTRING( "PJF" ),
|
||||
TAO_PEGTL_ISTRING( "NMOS" ),
|
||||
TAO_PEGTL_ISTRING( "PMOS" ),
|
||||
TAO_PEGTL_ISTRING( "NMF" ),
|
||||
TAO_PEGTL_ISTRING( "PMF" ),
|
||||
TAO_PEGTL_ISTRING( "VDMOS" )> {};
|
||||
|
||||
struct dotModel : seq<opt<sep>,
|
||||
TAO_PEGTL_ISTRING( ".model" ),
|
||||
sep,
|
||||
modelName,
|
||||
sep,
|
||||
dotModelType,
|
||||
sor<seq<opt<sep>,
|
||||
one<'('>,
|
||||
opt<sep>,
|
||||
paramValuePairs<NOTATION::SPICE>,
|
||||
opt<sep>,
|
||||
// Ngspice doesn't require the parentheses to match, though.
|
||||
one<')'>>,
|
||||
seq<sep,
|
||||
paramValuePairs<NOTATION::SPICE>>>,
|
||||
opt<sep>,
|
||||
newline> {};
|
||||
|
||||
|
||||
struct dotSubcktPinNumber : digits {};
|
||||
struct dotSubcktPinSequence : seq<opt<sep>,
|
||||
opt<dotSubcktPinNumber,
|
||||
star<sep,
|
||||
dotSubcktPinNumber>>,
|
||||
opt<sep>> {};
|
||||
|
||||
struct dotSubcktEnd : seq<TAO_PEGTL_ISTRING( ".ends" ),
|
||||
opt<sep>,
|
||||
newline> {};
|
||||
|
||||
struct dotSubckt : seq<opt<sep>,
|
||||
TAO_PEGTL_ISTRING( ".subckt" ),
|
||||
sep,
|
||||
modelName,
|
||||
sep,
|
||||
dotSubcktPinSequence,
|
||||
opt<sep>,
|
||||
newline,
|
||||
until<dotSubcktEnd>> {};
|
||||
|
||||
struct modelUnit : sor<dotModel,
|
||||
dotSubckt> {};
|
||||
|
||||
struct dotLine : seq<opt<sep>,
|
||||
one<'.'>,
|
||||
until<newline>> {};
|
||||
|
||||
struct unknownLine : until<newline> {};
|
||||
|
||||
struct spiceUnit : sor<modelUnit,
|
||||
dotLine,
|
||||
unknownLine> {};
|
||||
|
||||
struct spiceUnitGrammar : must<spiceUnit, eof> {};
|
||||
}
|
||||
|
||||
#endif // SPICE_GRAMMAR_H
|
Loading…
Reference in New Issue