simulator: update dialog to handle R, I & TEMP DC sweeps
Fixes https://gitlab.com/kicad/code/kicad/-/issues/2370 Fixes https://gitlab.com/kicad/code/kicad/-/issues/6195 Fixes https://gitlab.com/kicad/code/kicad/-/issues/2386
This commit is contained in:
parent
96af236493
commit
6a48e21eb2
|
@ -28,6 +28,9 @@
|
|||
|
||||
#include <wx/tokenzr.h>
|
||||
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
|
||||
/// @todo ngspice offers more types of analysis,
|
||||
//so there are a few tabs missing (e.g. pole-zero, distortion, sensitivity)
|
||||
|
||||
|
@ -63,6 +66,8 @@ DIALOG_SIM_SETTINGS::DIALOG_SIM_SETTINGS( wxWindow* aParent )
|
|||
m_transFinal->SetValidator( m_spiceValidator );
|
||||
m_transInitial->SetValidator( m_spiceEmptyValidator );
|
||||
|
||||
refreshUIControls();
|
||||
|
||||
// Hide pages that aren't fully implemented yet
|
||||
// wxPanel::Hide() isn't enough on some platforms
|
||||
m_simPages->RemovePage( m_simPages->FindPage( m_pgDistortion ) );
|
||||
|
@ -76,6 +81,59 @@ DIALOG_SIM_SETTINGS::DIALOG_SIM_SETTINGS( wxWindow* aParent )
|
|||
|
||||
}
|
||||
|
||||
wxString DIALOG_SIM_SETTINGS::evaluateDCControls( wxChoice* aDcSource, wxTextCtrl* aDcStart,
|
||||
wxTextCtrl* aDcStop, wxTextCtrl* aDcIncr )
|
||||
{
|
||||
wxString dcSource = aDcSource->GetString( aDcSource->GetSelection() );
|
||||
wxWindow* ctrlWithError = nullptr;
|
||||
|
||||
if( dcSource.IsEmpty() )
|
||||
{
|
||||
DisplayError( this, _( "You need to select DC source" ) );
|
||||
ctrlWithError = aDcSource;
|
||||
}
|
||||
/// @todo for some reason it does not trigger the assigned SPICE_VALIDATOR,
|
||||
// hence try..catch below
|
||||
else if( !aDcStart->Validate() )
|
||||
ctrlWithError = aDcStart;
|
||||
else if( !aDcStop->Validate() )
|
||||
ctrlWithError = aDcStop;
|
||||
else if( !aDcIncr->Validate() )
|
||||
ctrlWithError = aDcIncr;
|
||||
|
||||
if( ctrlWithError )
|
||||
{
|
||||
ctrlWithError->SetFocus();
|
||||
return wxEmptyString;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// pick device name from exporter when something different than temperature is selected
|
||||
if( dcSource.Cmp( "TEMP" ) )
|
||||
dcSource = m_exporter->GetSpiceDevice( dcSource );
|
||||
|
||||
return wxString::Format( "%s %s %s %s", dcSource,
|
||||
SPICE_VALUE( aDcStart->GetValue() ).ToSpiceString(),
|
||||
SPICE_VALUE( aDcStop->GetValue() ).ToSpiceString(),
|
||||
SPICE_VALUE( aDcIncr->GetValue() ).ToSpiceString() );
|
||||
}
|
||||
catch( std::exception& e )
|
||||
{
|
||||
DisplayError( this, e.what() );
|
||||
return wxEmptyString;
|
||||
}
|
||||
catch( const KI_PARAM_ERROR& e )
|
||||
{
|
||||
DisplayError( this, e.What() );
|
||||
return wxEmptyString;
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
return wxEmptyString;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool DIALOG_SIM_SETTINGS::TransferDataFromWindow()
|
||||
{
|
||||
|
@ -101,101 +159,27 @@ bool DIALOG_SIM_SETTINGS::TransferDataFromWindow()
|
|||
// DC transfer analysis
|
||||
else if( page == m_pgDC )
|
||||
{
|
||||
// At least one source has to be enabled
|
||||
if( !m_dcEnable1->IsChecked() && !m_dcEnable2->IsChecked() )
|
||||
{
|
||||
DisplayError( this, _( "You need to enable at least one source" ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
wxString simCmd = wxString( ".dc " );
|
||||
|
||||
if( m_dcEnable1->IsChecked() )
|
||||
{
|
||||
if( empty( m_dcSource1 ) )
|
||||
{
|
||||
DisplayError( this, _( "You need to select DC source (sweep 1)" ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
/// @todo for some reason it does not trigger the assigned SPICE_VALIDATOR,
|
||||
// hence try..catch below
|
||||
if( !m_dcStart1->Validate() || !m_dcStop1->Validate() || !m_dcIncr1->Validate() )
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
wxString dcSource = m_exporter->GetSpiceDevice( m_dcSource1->GetValue() );
|
||||
|
||||
simCmd += wxString::Format( "%s %s %s %s",
|
||||
dcSource,
|
||||
SPICE_VALUE( m_dcStart1->GetValue() ).ToSpiceString(),
|
||||
SPICE_VALUE( m_dcStop1->GetValue() ).ToSpiceString(),
|
||||
SPICE_VALUE( m_dcIncr1->GetValue() ).ToSpiceString() );
|
||||
}
|
||||
catch( std::exception& e )
|
||||
{
|
||||
DisplayError( this, e.what() );
|
||||
return false;
|
||||
}
|
||||
catch( const KI_PARAM_ERROR& e )
|
||||
{
|
||||
DisplayError( this, e.What() );
|
||||
return false;
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
wxString src1 = evaluateDCControls( m_dcSource1, m_dcStart1, m_dcStop1, m_dcIncr1 );
|
||||
if( src1.IsEmpty() )
|
||||
return false;
|
||||
else
|
||||
simCmd += src1;
|
||||
|
||||
if( m_dcEnable2->IsChecked() )
|
||||
{
|
||||
if( empty( m_dcSource2 ) )
|
||||
{
|
||||
DisplayError( this, _( "You need to select DC source (sweep 2)" ) );
|
||||
wxString src2 = evaluateDCControls( m_dcSource2, m_dcStart2, m_dcStop2, m_dcIncr2 );
|
||||
if( src2.IsEmpty() )
|
||||
return false;
|
||||
}
|
||||
else
|
||||
simCmd += " " + src2;
|
||||
|
||||
if( m_dcEnable1->IsChecked() && m_dcSource1->GetValue() == m_dcSource2->GetValue() )
|
||||
if( m_dcSource1->GetSelection() == m_dcSource2->GetSelection() )
|
||||
{
|
||||
DisplayError( this, _( "Source 1 and Source 2 must be different" ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
/// @todo for some reason it does not trigger the assigned SPICE_VALIDATOR,
|
||||
// hence try..catch below
|
||||
if( !m_dcStart2->Validate() || !m_dcStop2->Validate() || !m_dcIncr2->Validate() )
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
wxString dcSource = m_exporter->GetSpiceDevice( m_dcSource2->GetValue() );
|
||||
|
||||
if( m_dcEnable1->IsChecked() )
|
||||
simCmd += " ";
|
||||
|
||||
simCmd += wxString::Format( "%s %s %s %s",
|
||||
dcSource,
|
||||
SPICE_VALUE( m_dcStart2->GetValue() ).ToSpiceString(),
|
||||
SPICE_VALUE( m_dcStop2->GetValue() ).ToSpiceString(),
|
||||
SPICE_VALUE( m_dcIncr2->GetValue() ).ToSpiceString() );
|
||||
}
|
||||
catch( std::exception& e )
|
||||
{
|
||||
DisplayError( this, e.what() );
|
||||
return false;
|
||||
}
|
||||
catch( const KI_PARAM_ERROR& e )
|
||||
{
|
||||
DisplayError( this, e.What() );
|
||||
return false;
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
m_simCommand = simCmd;
|
||||
|
@ -310,36 +294,52 @@ int DIALOG_SIM_SETTINGS::ShowModal()
|
|||
c.first->SetSelection( idx );
|
||||
}
|
||||
|
||||
return DIALOG_SIM_SETTINGS_BASE::ShowModal();
|
||||
}
|
||||
|
||||
// Fill out comboboxes that allows one to select power sources
|
||||
std::map<wxComboBox*, wxString> cmbSrc = {
|
||||
{ m_dcSource1, m_dcSource1->GetStringSelection() },
|
||||
{ m_dcSource2, m_dcSource2->GetStringSelection() },
|
||||
{ m_noiseSrc, m_noiseSrc->GetStringSelection() },
|
||||
};
|
||||
void DIALOG_SIM_SETTINGS::updateDCSources( wxChar aType, wxChoice* aSource )
|
||||
{
|
||||
wxString prevSelection = aSource->GetString( aSource->GetSelection() );
|
||||
std::vector<wxString> sourcesList;
|
||||
bool enableSrcSelection = true;
|
||||
|
||||
for( auto c : cmbSrc )
|
||||
c.first->Clear();
|
||||
|
||||
for( const auto& item : m_exporter->GetSpiceItems() )
|
||||
if( aType != 'T' )
|
||||
{
|
||||
if( item.m_primitive == 'V' )
|
||||
for( const auto& item : m_exporter->GetSpiceItems() )
|
||||
{
|
||||
for( auto c : cmbSrc )
|
||||
c.first->Append( item.m_refName );
|
||||
if( item.m_primitive == aType )
|
||||
{
|
||||
sourcesList.push_back( item.m_refName );
|
||||
}
|
||||
}
|
||||
|
||||
std::sort( sourcesList.begin(), sourcesList.end(),
|
||||
[](wxString& a, wxString& b) -> bool
|
||||
{
|
||||
return a.Len() < b.Len() || b.Cmp( a ) > 0;
|
||||
} );
|
||||
|
||||
if( aSource == m_dcSource2 && !m_dcEnable2->IsChecked() )
|
||||
enableSrcSelection = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
prevSelection = wxT( "TEMP" );
|
||||
sourcesList.push_back( prevSelection );
|
||||
enableSrcSelection = false;
|
||||
}
|
||||
|
||||
aSource->Enable( enableSrcSelection );
|
||||
|
||||
aSource->Clear();
|
||||
for( auto& src : sourcesList )
|
||||
aSource->Append( src );
|
||||
|
||||
// Try to restore the previous selection, if possible
|
||||
for( auto c : cmbSrc )
|
||||
{
|
||||
int idx = c.first->FindString( c.second );
|
||||
int idx = aSource->FindString( prevSelection );
|
||||
|
||||
if( idx != wxNOT_FOUND )
|
||||
c.first->SetSelection( idx );
|
||||
}
|
||||
|
||||
return DIALOG_SIM_SETTINGS_BASE::ShowModal();
|
||||
if( idx != wxNOT_FOUND )
|
||||
aSource->SetSelection( idx );
|
||||
}
|
||||
|
||||
|
||||
|
@ -375,39 +375,43 @@ bool DIALOG_SIM_SETTINGS::parseCommand( const wxString& aCommand )
|
|||
|
||||
else if( tkn == ".dc" )
|
||||
{
|
||||
SPICE_DC_PARAMS src1, src2;
|
||||
src2.m_vincrement = SPICE_VALUE( -1 );
|
||||
if( !m_exporter->ParseDCCommand( aCommand, &src1, &src2 ) )
|
||||
return false;
|
||||
|
||||
m_simPages->SetSelection( m_simPages->FindPage( m_pgDC ) );
|
||||
|
||||
tkn = tokenizer.GetNextToken();
|
||||
if( !src1.m_source.IsSameAs( wxT( "TEMP" ), false ) == 0 )
|
||||
m_dcSourceType1->SetSelection( m_dcSourceType1->FindString( src1.m_source ) );
|
||||
else
|
||||
m_dcSourceType1->SetSelection(
|
||||
m_dcSourceType1->FindString( src1.m_source.GetChar( 0 ) ) );
|
||||
|
||||
if( !tkn.IsEmpty() )
|
||||
updateDCSources( src1.m_source.GetChar( 0 ), m_dcSource1 );
|
||||
m_dcSource1->SetSelection( m_dcSource1->FindString( src1.m_source ) );
|
||||
m_dcStart1->SetValue( src1.m_vstart.ToSpiceString() );
|
||||
m_dcStop1->SetValue( src1.m_vend.ToSpiceString() );
|
||||
m_dcIncr1->SetValue( src1.m_vincrement.ToSpiceString() );
|
||||
|
||||
if( src2.m_vincrement.ToDouble() != -1 )
|
||||
{
|
||||
m_dcSource1->SetValue( tkn );
|
||||
m_dcStart1->SetValue( SPICE_VALUE( tokenizer.GetNextToken() ).ToSpiceString() );
|
||||
m_dcStop1->SetValue( SPICE_VALUE( tokenizer.GetNextToken() ).ToSpiceString() );
|
||||
m_dcIncr1->SetValue( SPICE_VALUE( tokenizer.GetNextToken() ).ToSpiceString() );
|
||||
if( !src2.m_source.IsSameAs( wxT( "TEMP" ), false ) == 0 )
|
||||
m_dcSourceType2->SetSelection( m_dcSourceType2->FindString( src2.m_source ) );
|
||||
else
|
||||
m_dcSourceType2->SetSelection(
|
||||
m_dcSourceType2->FindString( src2.m_source.GetChar( 0 ) ) );
|
||||
|
||||
// Check the 'Enabled' field, if all values are filled
|
||||
m_dcEnable1->SetValue( !empty( m_dcSource1 ) && !empty( m_dcStart1 )
|
||||
&& !empty( m_dcStop1 ) && !empty( m_dcIncr1 ) );
|
||||
updateDCSources( src2.m_source.GetChar( 0 ), m_dcSource2 );
|
||||
m_dcSource2->SetSelection( m_dcSource2->FindString( src2.m_source ) );
|
||||
m_dcStart2->SetValue( src2.m_vstart.ToSpiceString() );
|
||||
m_dcStop2->SetValue( src2.m_vend.ToSpiceString() );
|
||||
m_dcIncr2->SetValue( src2.m_vincrement.ToSpiceString() );
|
||||
|
||||
m_dcEnable2->SetValue( true );
|
||||
}
|
||||
|
||||
tkn = tokenizer.GetNextToken();
|
||||
|
||||
if( !tkn.IsEmpty() )
|
||||
{
|
||||
m_dcSource2->SetValue( tkn );
|
||||
m_dcStart2->SetValue( SPICE_VALUE( tokenizer.GetNextToken() ).ToSpiceString() );
|
||||
m_dcStop2->SetValue( SPICE_VALUE( tokenizer.GetNextToken() ).ToSpiceString() );
|
||||
m_dcIncr2->SetValue( SPICE_VALUE( tokenizer.GetNextToken() ).ToSpiceString() );
|
||||
|
||||
// Check the 'Enabled' field, if all values are filled
|
||||
m_dcEnable2->SetValue( !empty( m_dcSource2 ) && !empty( m_dcStart2 )
|
||||
&& !empty( m_dcStop2 ) && !empty( m_dcIncr2 ) );
|
||||
}
|
||||
|
||||
// Check if the directive is complete
|
||||
if( !m_dcEnable1->IsChecked() || !m_dcEnable2->IsChecked() )
|
||||
return false;
|
||||
refreshUIControls();
|
||||
}
|
||||
|
||||
else if( tkn == ".tran" )
|
||||
|
@ -425,6 +429,11 @@ bool DIALOG_SIM_SETTINGS::parseCommand( const wxString& aCommand )
|
|||
m_transInitial->SetValue( SPICE_VALUE( tkn ).ToSpiceString() );
|
||||
}
|
||||
|
||||
else if( tkn == ".op" )
|
||||
{
|
||||
m_simPages->SetSelection( m_simPages->FindPage( m_pgOP ) );
|
||||
}
|
||||
|
||||
// Custom directives
|
||||
else if( !empty( m_customTxt ) )
|
||||
{
|
||||
|
@ -441,6 +450,77 @@ bool DIALOG_SIM_SETTINGS::parseCommand( const wxString& aCommand )
|
|||
}
|
||||
|
||||
|
||||
void DIALOG_SIM_SETTINGS::onSwapDCSources( wxCommandEvent& event )
|
||||
{
|
||||
std::vector<std::pair<wxTextEntry*, wxTextEntry*>> textCtrl = { { m_dcStart1, m_dcStart2 },
|
||||
{ m_dcStop1, m_dcStop2 },
|
||||
{ m_dcIncr1, m_dcIncr2 } };
|
||||
|
||||
for( auto& couple : textCtrl )
|
||||
{
|
||||
wxString tmp = couple.first->GetValue();
|
||||
couple.first->SetValue( couple.second->GetValue() );
|
||||
couple.second->SetValue( tmp );
|
||||
}
|
||||
|
||||
int src1 = m_dcSource1->GetSelection();
|
||||
int src2 = m_dcSource2->GetSelection();
|
||||
|
||||
int sel = m_dcSourceType1->GetSelection();
|
||||
m_dcSourceType1->SetSelection( m_dcSourceType2->GetSelection() );
|
||||
m_dcSourceType2->SetSelection( sel );
|
||||
|
||||
wxChar type1 =
|
||||
m_dcSourceType1->GetString( m_dcSourceType1->GetSelection() ).Upper().GetChar( 0 );
|
||||
updateDCSources( type1, m_dcSource1 );
|
||||
wxChar type2 =
|
||||
m_dcSourceType2->GetString( m_dcSourceType2->GetSelection() ).Upper().GetChar( 0 );
|
||||
updateDCSources( type2, m_dcSource2 );
|
||||
|
||||
m_dcSource1->SetSelection( src2 );
|
||||
m_dcSource2->SetSelection( src1 );
|
||||
|
||||
updateDCUnits( type1, m_dcSource1, m_src1DCStartValUnit, m_src1DCEndValUnit, m_src1DCStepUnit );
|
||||
updateDCUnits( type2, m_dcSource2, m_src2DCStartValUnit, m_src2DCEndValUnit, m_src2DCStepUnit );
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_SIM_SETTINGS::onDCEnableSecondSource( wxCommandEvent& event )
|
||||
{
|
||||
bool is2ndSrcEnabled = m_dcEnable2->IsChecked();
|
||||
wxChar type =
|
||||
m_dcSourceType2->GetString( m_dcSourceType2->GetSelection() ).Upper().GetChar( 0 );
|
||||
|
||||
m_dcSourceType2->Enable( is2ndSrcEnabled );
|
||||
m_dcSource2->Enable( is2ndSrcEnabled && type != 'T' );
|
||||
m_dcStart2->Enable( is2ndSrcEnabled );
|
||||
m_dcStop2->Enable( is2ndSrcEnabled );
|
||||
m_dcIncr2->Enable( is2ndSrcEnabled );
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_SIM_SETTINGS::updateDCUnits( wxChar aType, wxChoice* aSource,
|
||||
wxStaticText* aStartValUnit, wxStaticText* aEndValUnit,
|
||||
wxStaticText* aStepUnit )
|
||||
{
|
||||
wxString unit;
|
||||
|
||||
switch( aType )
|
||||
{
|
||||
case 'V': unit = _( "Volts" ); break;
|
||||
case 'I': unit = _( "Amperes" ); break;
|
||||
case 'R': unit = _( "Ohms" ); break;
|
||||
case 'T': unit = wxT( "\u00B0C" ); break;
|
||||
}
|
||||
aStartValUnit->SetLabel( unit );
|
||||
aEndValUnit->SetLabel( unit );
|
||||
aStepUnit->SetLabel( unit );
|
||||
|
||||
m_pgDC->Fit();
|
||||
m_pgDC->Refresh();
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_SIM_SETTINGS::loadDirectives()
|
||||
{
|
||||
if( m_exporter )
|
||||
|
|
|
@ -84,6 +84,32 @@ private:
|
|||
LINEAR
|
||||
};
|
||||
|
||||
///!> Generates events to update UI state
|
||||
void refreshUIControls()
|
||||
{
|
||||
wxQueueEvent( m_dcEnable2, new wxCommandEvent( wxEVT_CHECKBOX ) );
|
||||
wxQueueEvent( m_dcSourceType1, new wxCommandEvent( wxEVT_RADIOBOX ) );
|
||||
wxQueueEvent( m_dcSourceType2, new wxCommandEvent( wxEVT_RADIOBOX ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reads values from one DC sweep source to form a part of sim command
|
||||
* @return string of four SPICE values if values are correct, empty string upon error.
|
||||
*/
|
||||
wxString evaluateDCControls( wxChoice* aDcSource, wxTextCtrl* aDcStart, wxTextCtrl* aDcStop,
|
||||
wxTextCtrl* aDcIncr );
|
||||
|
||||
/**
|
||||
* @brief Updates DC sweep source with components from schematic
|
||||
*/
|
||||
void updateDCSources( wxChar aType, wxChoice* aSource );
|
||||
|
||||
/**
|
||||
* @brief Updates units on labels depending on selected source
|
||||
*/
|
||||
void updateDCUnits( wxChar aType, wxChoice* aSource, wxStaticText* aStartValUnit,
|
||||
wxStaticText* aEndValUnit, wxStaticText* aStepUnit );
|
||||
|
||||
virtual void onInitDlg( wxInitDialogEvent& event ) override
|
||||
{
|
||||
// Call the default wxDialog handler of a wxInitDialogEvent
|
||||
|
@ -105,6 +131,26 @@ private:
|
|||
loadDirectives();
|
||||
}
|
||||
|
||||
void onDCEnableSecondSource( wxCommandEvent& event ) override;
|
||||
void onSwapDCSources( wxCommandEvent& event ) override;
|
||||
void onDCSource1Selected( wxCommandEvent& event ) override
|
||||
{
|
||||
wxChar type =
|
||||
m_dcSourceType1->GetString( m_dcSourceType1->GetSelection() ).Upper().GetChar( 0 );
|
||||
updateDCSources( type, m_dcSource1 );
|
||||
updateDCUnits( type, m_dcSource1, m_src1DCStartValUnit, m_src1DCEndValUnit,
|
||||
m_src1DCStepUnit );
|
||||
}
|
||||
|
||||
void onDCSource2Selected( wxCommandEvent& event ) override
|
||||
{
|
||||
wxChar type =
|
||||
m_dcSourceType2->GetString( m_dcSourceType2->GetSelection() ).Upper().GetChar( 0 );
|
||||
updateDCSources( type, m_dcSource2 );
|
||||
updateDCUnits( type, m_dcSource2, m_src2DCStartValUnit, m_src2DCEndValUnit,
|
||||
m_src2DCStepUnit );
|
||||
}
|
||||
|
||||
static wxString scaleToString( int aOption )
|
||||
{
|
||||
switch( aOption )
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 3.9.0 Jun 18 2020)
|
||||
// C++ code generated with wxFormBuilder (version 3.9.0 Sep 3 2020)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
|
@ -86,138 +86,127 @@ DIALOG_SIM_SETTINGS_BASE::DIALOG_SIM_SETTINGS_BASE( wxWindow* parent, wxWindowID
|
|||
bSizer3->Fit( m_pgAC );
|
||||
m_simPages->AddPage( m_pgAC, _("AC"), false );
|
||||
m_pgDC = new wxPanel( m_simPages, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
|
||||
wxBoxSizer* bSizer4;
|
||||
bSizer4 = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
wxStaticBoxSizer* sbSizer21;
|
||||
sbSizer21 = new wxStaticBoxSizer( new wxStaticBox( m_pgDC, wxID_ANY, _("DC Sweep Source 1") ), wxVERTICAL );
|
||||
|
||||
m_dcEnable1 = new wxCheckBox( sbSizer21->GetStaticBox(), wxID_ANY, _("Enable"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_dcEnable1->SetValue(true);
|
||||
sbSizer21->Add( m_dcEnable1, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5 );
|
||||
|
||||
wxFlexGridSizer* fgSizer21;
|
||||
fgSizer21 = new wxFlexGridSizer( 0, 3, 0, 0 );
|
||||
fgSizer21->SetFlexibleDirection( wxBOTH );
|
||||
fgSizer21->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
|
||||
|
||||
m_staticText41 = new wxStaticText( sbSizer21->GetStaticBox(), wxID_ANY, _("DC source:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText41->Wrap( -1 );
|
||||
fgSizer21->Add( m_staticText41, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||
|
||||
m_dcSource1 = new wxComboBox( sbSizer21->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 );
|
||||
fgSizer21->Add( m_dcSource1, 0, wxALL, 5 );
|
||||
wxBoxSizer* bSizer82;
|
||||
bSizer82 = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
|
||||
fgSizer21->Add( 0, 0, 1, wxEXPAND, 5 );
|
||||
bSizer82->Add( 0, 0, 1, wxEXPAND, 5 );
|
||||
|
||||
m_staticText51 = new wxStaticText( sbSizer21->GetStaticBox(), wxID_ANY, _("Starting voltage:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText51->Wrap( -1 );
|
||||
fgSizer21->Add( m_staticText51, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||
|
||||
m_dcStart1 = new wxTextCtrl( sbSizer21->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
fgSizer21->Add( m_dcStart1, 0, wxALL, 5 );
|
||||
|
||||
m_staticText511 = new wxStaticText( sbSizer21->GetStaticBox(), wxID_ANY, _("Volts"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText511->Wrap( -1 );
|
||||
fgSizer21->Add( m_staticText511, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT, 5 );
|
||||
|
||||
m_staticText61 = new wxStaticText( sbSizer21->GetStaticBox(), wxID_ANY, _("Final voltage:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText61->Wrap( -1 );
|
||||
fgSizer21->Add( m_staticText61, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||
|
||||
m_dcStop1 = new wxTextCtrl( sbSizer21->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
fgSizer21->Add( m_dcStop1, 0, wxALL, 5 );
|
||||
|
||||
m_staticText512 = new wxStaticText( sbSizer21->GetStaticBox(), wxID_ANY, _("Volts"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText512->Wrap( -1 );
|
||||
fgSizer21->Add( m_staticText512, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT, 5 );
|
||||
|
||||
m_staticText71 = new wxStaticText( sbSizer21->GetStaticBox(), wxID_ANY, _("Increment step:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText71->Wrap( -1 );
|
||||
fgSizer21->Add( m_staticText71, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||
|
||||
m_dcIncr1 = new wxTextCtrl( sbSizer21->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
fgSizer21->Add( m_dcIncr1, 0, wxALL, 5 );
|
||||
|
||||
m_staticText513 = new wxStaticText( sbSizer21->GetStaticBox(), wxID_ANY, _("Volts"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText513->Wrap( -1 );
|
||||
fgSizer21->Add( m_staticText513, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT, 5 );
|
||||
wxBoxSizer* bSizer151;
|
||||
bSizer151 = new wxBoxSizer( wxHORIZONTAL );
|
||||
|
||||
|
||||
sbSizer21->Add( fgSizer21, 1, wxALIGN_CENTER_HORIZONTAL, 5 );
|
||||
bSizer151->Add( 0, 0, 1, wxEXPAND, 5 );
|
||||
|
||||
wxGridBagSizer* gbSizer1;
|
||||
gbSizer1 = new wxGridBagSizer( 0, 0 );
|
||||
gbSizer1->SetFlexibleDirection( wxBOTH );
|
||||
gbSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
|
||||
|
||||
bSizer4->Add( sbSizer21, 0, wxEXPAND, 5 );
|
||||
m_dcEnable2 = new wxCheckBox( m_pgDC, wxID_ANY, _("Enable second source"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
gbSizer1->Add( m_dcEnable2, wxGBPosition( 0, 3 ), wxGBSpan( 1, 2 ), wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 5 );
|
||||
|
||||
wxStaticBoxSizer* sbSizer2;
|
||||
sbSizer2 = new wxStaticBoxSizer( new wxStaticBox( m_pgDC, wxID_ANY, _("DC Sweep Source 2") ), wxVERTICAL );
|
||||
wxString m_dcSourceType1Choices[] = { _("V"), _("I"), _("R"), _("TEMP") };
|
||||
int m_dcSourceType1NChoices = sizeof( m_dcSourceType1Choices ) / sizeof( wxString );
|
||||
m_dcSourceType1 = new wxRadioBox( m_pgDC, wxID_ANY, _("Type"), wxDefaultPosition, wxDefaultSize, m_dcSourceType1NChoices, m_dcSourceType1Choices, 4, wxRA_SPECIFY_COLS );
|
||||
m_dcSourceType1->SetSelection( 0 );
|
||||
gbSizer1->Add( m_dcSourceType1, wxGBPosition( 1, 1 ), wxGBSpan( 1, 2 ), wxALL, 5 );
|
||||
|
||||
m_dcEnable2 = new wxCheckBox( sbSizer2->GetStaticBox(), wxID_ANY, _("Enable"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
sbSizer2->Add( m_dcEnable2, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5 );
|
||||
wxString m_dcSourceType2Choices[] = { _("V"), _("I"), _("R"), _("TEMP") };
|
||||
int m_dcSourceType2NChoices = sizeof( m_dcSourceType2Choices ) / sizeof( wxString );
|
||||
m_dcSourceType2 = new wxRadioBox( m_pgDC, wxID_ANY, _("Type"), wxDefaultPosition, wxDefaultSize, m_dcSourceType2NChoices, m_dcSourceType2Choices, 4, wxRA_SPECIFY_COLS );
|
||||
m_dcSourceType2->SetSelection( 0 );
|
||||
gbSizer1->Add( m_dcSourceType2, wxGBPosition( 1, 3 ), wxGBSpan( 1, 2 ), wxALL, 5 );
|
||||
|
||||
wxFlexGridSizer* fgSizer2;
|
||||
fgSizer2 = new wxFlexGridSizer( 0, 3, 0, 0 );
|
||||
fgSizer2->SetFlexibleDirection( wxBOTH );
|
||||
fgSizer2->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
|
||||
|
||||
m_staticText4 = new wxStaticText( sbSizer2->GetStaticBox(), wxID_ANY, _("DC source:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText4 = new wxStaticText( m_pgDC, wxID_ANY, _("DC source:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText4->Wrap( -1 );
|
||||
fgSizer2->Add( m_staticText4, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||
gbSizer1->Add( m_staticText4, wxGBPosition( 2, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||
|
||||
m_dcSource2 = new wxComboBox( sbSizer2->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 );
|
||||
fgSizer2->Add( m_dcSource2, 0, wxALL, 5 );
|
||||
wxArrayString m_dcSource1Choices;
|
||||
m_dcSource1 = new wxChoice( m_pgDC, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_dcSource1Choices, 0 );
|
||||
m_dcSource1->SetSelection( 0 );
|
||||
gbSizer1->Add( m_dcSource1, wxGBPosition( 2, 1 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||
|
||||
wxArrayString m_dcSource2Choices;
|
||||
m_dcSource2 = new wxChoice( m_pgDC, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_dcSource2Choices, 0 );
|
||||
m_dcSource2->SetSelection( 0 );
|
||||
gbSizer1->Add( m_dcSource2, wxGBPosition( 2, 3 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||
|
||||
fgSizer2->Add( 0, 0, 1, wxEXPAND, 5 );
|
||||
|
||||
m_staticText5 = new wxStaticText( sbSizer2->GetStaticBox(), wxID_ANY, _("Starting voltage:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText5 = new wxStaticText( m_pgDC, wxID_ANY, _("Starting value:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText5->Wrap( -1 );
|
||||
fgSizer2->Add( m_staticText5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||
gbSizer1->Add( m_staticText5, wxGBPosition( 3, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||
|
||||
m_dcStart2 = new wxTextCtrl( sbSizer2->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
fgSizer2->Add( m_dcStart2, 0, wxALL, 5 );
|
||||
m_dcStart1 = new wxTextCtrl( m_pgDC, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
gbSizer1->Add( m_dcStart1, wxGBPosition( 3, 1 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||
|
||||
m_staticText52 = new wxStaticText( sbSizer2->GetStaticBox(), wxID_ANY, _("Volts"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText52->Wrap( -1 );
|
||||
fgSizer2->Add( m_staticText52, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT, 5 );
|
||||
m_src1DCStartValUnit = new wxStaticText( m_pgDC, wxID_ANY, _("Volts"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_src1DCStartValUnit->Wrap( -1 );
|
||||
gbSizer1->Add( m_src1DCStartValUnit, wxGBPosition( 3, 2 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||
|
||||
m_staticText6 = new wxStaticText( sbSizer2->GetStaticBox(), wxID_ANY, _("Final voltage:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_dcStart2 = new wxTextCtrl( m_pgDC, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
gbSizer1->Add( m_dcStart2, wxGBPosition( 3, 3 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||
|
||||
m_src2DCStartValUnit = new wxStaticText( m_pgDC, wxID_ANY, _("Volts"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_src2DCStartValUnit->Wrap( -1 );
|
||||
gbSizer1->Add( m_src2DCStartValUnit, wxGBPosition( 3, 4 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||
|
||||
m_staticText6 = new wxStaticText( m_pgDC, wxID_ANY, _("Final value:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText6->Wrap( -1 );
|
||||
fgSizer2->Add( m_staticText6, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||
gbSizer1->Add( m_staticText6, wxGBPosition( 4, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||
|
||||
m_dcStop2 = new wxTextCtrl( sbSizer2->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
fgSizer2->Add( m_dcStop2, 0, wxALL, 5 );
|
||||
m_dcStop1 = new wxTextCtrl( m_pgDC, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
gbSizer1->Add( m_dcStop1, wxGBPosition( 4, 1 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||
|
||||
m_staticText53 = new wxStaticText( sbSizer2->GetStaticBox(), wxID_ANY, _("Volts"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText53->Wrap( -1 );
|
||||
fgSizer2->Add( m_staticText53, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT, 5 );
|
||||
m_src1DCEndValUnit = new wxStaticText( m_pgDC, wxID_ANY, _("Volts"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_src1DCEndValUnit->Wrap( -1 );
|
||||
gbSizer1->Add( m_src1DCEndValUnit, wxGBPosition( 4, 2 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||
|
||||
m_staticText7 = new wxStaticText( sbSizer2->GetStaticBox(), wxID_ANY, _("Increment step:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_dcStop2 = new wxTextCtrl( m_pgDC, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
gbSizer1->Add( m_dcStop2, wxGBPosition( 4, 3 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||
|
||||
m_src2DCEndValUnit = new wxStaticText( m_pgDC, wxID_ANY, _("Volts"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_src2DCEndValUnit->Wrap( -1 );
|
||||
gbSizer1->Add( m_src2DCEndValUnit, wxGBPosition( 4, 4 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||
|
||||
m_staticText7 = new wxStaticText( m_pgDC, wxID_ANY, _("Increment step:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText7->Wrap( -1 );
|
||||
fgSizer2->Add( m_staticText7, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||
gbSizer1->Add( m_staticText7, wxGBPosition( 5, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||
|
||||
m_dcIncr2 = new wxTextCtrl( sbSizer2->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
fgSizer2->Add( m_dcIncr2, 0, wxALL, 5 );
|
||||
m_dcIncr1 = new wxTextCtrl( m_pgDC, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
gbSizer1->Add( m_dcIncr1, wxGBPosition( 5, 1 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||
|
||||
m_staticText54 = new wxStaticText( sbSizer2->GetStaticBox(), wxID_ANY, _("Volts"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText54->Wrap( -1 );
|
||||
fgSizer2->Add( m_staticText54, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT, 5 );
|
||||
m_src1DCStepUnit = new wxStaticText( m_pgDC, wxID_ANY, _("Volts"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_src1DCStepUnit->Wrap( -1 );
|
||||
gbSizer1->Add( m_src1DCStepUnit, wxGBPosition( 5, 2 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||
|
||||
m_dcIncr2 = new wxTextCtrl( m_pgDC, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
gbSizer1->Add( m_dcIncr2, wxGBPosition( 5, 3 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||
|
||||
m_src2DCStepUnit = new wxStaticText( m_pgDC, wxID_ANY, _("Volts"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_src2DCStepUnit->Wrap( -1 );
|
||||
gbSizer1->Add( m_src2DCStepUnit, wxGBPosition( 5, 4 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||
|
||||
m_swapDCSources = new wxButton( m_pgDC, wxID_ANY, _("Swap sources"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
gbSizer1->Add( m_swapDCSources, wxGBPosition( 6, 0 ), wxGBSpan( 1, 5 ), wxALL|wxEXPAND, 5 );
|
||||
|
||||
|
||||
sbSizer2->Add( fgSizer2, 1, wxALIGN_CENTER_HORIZONTAL, 5 );
|
||||
bSizer151->Add( gbSizer1, 1, wxEXPAND, 5 );
|
||||
|
||||
|
||||
bSizer4->Add( sbSizer2, 0, wxEXPAND, 5 );
|
||||
bSizer151->Add( 0, 0, 1, wxEXPAND, 5 );
|
||||
|
||||
|
||||
m_pgDC->SetSizer( bSizer4 );
|
||||
bSizer82->Add( bSizer151, 0, wxALIGN_CENTER_HORIZONTAL, 5 );
|
||||
|
||||
|
||||
bSizer82->Add( 0, 0, 1, wxEXPAND, 5 );
|
||||
|
||||
|
||||
m_pgDC->SetSizer( bSizer82 );
|
||||
m_pgDC->Layout();
|
||||
bSizer4->Fit( m_pgDC );
|
||||
bSizer82->Fit( m_pgDC );
|
||||
m_simPages->AddPage( m_pgDC, _("DC Transfer"), true );
|
||||
m_pgDistortion = new wxPanel( m_simPages, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
|
||||
m_pgDistortion->Hide();
|
||||
|
||||
m_simPages->AddPage( m_pgDistortion, _("Distortion"), false );
|
||||
m_pgNoise = new wxPanel( m_simPages, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
|
||||
m_pgNoise->Hide();
|
||||
|
@ -468,6 +457,10 @@ DIALOG_SIM_SETTINGS_BASE::DIALOG_SIM_SETTINGS_BASE( wxWindow* parent, wxWindowID
|
|||
|
||||
// Connect Events
|
||||
this->Connect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( DIALOG_SIM_SETTINGS_BASE::onInitDlg ) );
|
||||
m_dcEnable2->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_SIM_SETTINGS_BASE::onDCEnableSecondSource ), NULL, this );
|
||||
m_dcSourceType1->Connect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_SIM_SETTINGS_BASE::onDCSource1Selected ), NULL, this );
|
||||
m_dcSourceType2->Connect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_SIM_SETTINGS_BASE::onDCSource2Selected ), NULL, this );
|
||||
m_swapDCSources->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SIM_SETTINGS_BASE::onSwapDCSources ), NULL, this );
|
||||
m_loadDirectives->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SIM_SETTINGS_BASE::onLoadDirectives ), NULL, this );
|
||||
}
|
||||
|
||||
|
@ -475,6 +468,10 @@ DIALOG_SIM_SETTINGS_BASE::~DIALOG_SIM_SETTINGS_BASE()
|
|||
{
|
||||
// Disconnect Events
|
||||
this->Disconnect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( DIALOG_SIM_SETTINGS_BASE::onInitDlg ) );
|
||||
m_dcEnable2->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_SIM_SETTINGS_BASE::onDCEnableSecondSource ), NULL, this );
|
||||
m_dcSourceType1->Disconnect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_SIM_SETTINGS_BASE::onDCSource1Selected ), NULL, this );
|
||||
m_dcSourceType2->Disconnect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_SIM_SETTINGS_BASE::onDCSource2Selected ), NULL, this );
|
||||
m_swapDCSources->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SIM_SETTINGS_BASE::onSwapDCSources ), NULL, this );
|
||||
m_loadDirectives->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SIM_SETTINGS_BASE::onLoadDirectives ), NULL, this );
|
||||
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,5 +1,5 @@
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 3.9.0 Jun 18 2020)
|
||||
// C++ code generated with wxFormBuilder (version 3.9.0 Sep 3 2020)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
|
@ -26,9 +26,10 @@
|
|||
#include <wx/image.h>
|
||||
#include <wx/icon.h>
|
||||
#include <wx/checkbox.h>
|
||||
#include <wx/combobox.h>
|
||||
#include <wx/statbox.h>
|
||||
#include <wx/choice.h>
|
||||
#include <wx/button.h>
|
||||
#include <wx/gbsizer.h>
|
||||
#include <wx/combobox.h>
|
||||
#include <wx/notebook.h>
|
||||
#include <wx/dialog.h>
|
||||
|
||||
|
@ -55,30 +56,28 @@ class DIALOG_SIM_SETTINGS_BASE : public DIALOG_SHIM
|
|||
wxTextCtrl* m_acFreqStop;
|
||||
wxStaticText* m_staticText110;
|
||||
wxPanel* m_pgDC;
|
||||
wxCheckBox* m_dcEnable1;
|
||||
wxStaticText* m_staticText41;
|
||||
wxComboBox* m_dcSource1;
|
||||
wxStaticText* m_staticText51;
|
||||
wxTextCtrl* m_dcStart1;
|
||||
wxStaticText* m_staticText511;
|
||||
wxStaticText* m_staticText61;
|
||||
wxTextCtrl* m_dcStop1;
|
||||
wxStaticText* m_staticText512;
|
||||
wxStaticText* m_staticText71;
|
||||
wxTextCtrl* m_dcIncr1;
|
||||
wxStaticText* m_staticText513;
|
||||
wxCheckBox* m_dcEnable2;
|
||||
wxRadioBox* m_dcSourceType1;
|
||||
wxRadioBox* m_dcSourceType2;
|
||||
wxStaticText* m_staticText4;
|
||||
wxComboBox* m_dcSource2;
|
||||
wxChoice* m_dcSource1;
|
||||
wxChoice* m_dcSource2;
|
||||
wxStaticText* m_staticText5;
|
||||
wxTextCtrl* m_dcStart1;
|
||||
wxStaticText* m_src1DCStartValUnit;
|
||||
wxTextCtrl* m_dcStart2;
|
||||
wxStaticText* m_staticText52;
|
||||
wxStaticText* m_src2DCStartValUnit;
|
||||
wxStaticText* m_staticText6;
|
||||
wxTextCtrl* m_dcStop1;
|
||||
wxStaticText* m_src1DCEndValUnit;
|
||||
wxTextCtrl* m_dcStop2;
|
||||
wxStaticText* m_staticText53;
|
||||
wxStaticText* m_src2DCEndValUnit;
|
||||
wxStaticText* m_staticText7;
|
||||
wxTextCtrl* m_dcIncr1;
|
||||
wxStaticText* m_src1DCStepUnit;
|
||||
wxTextCtrl* m_dcIncr2;
|
||||
wxStaticText* m_staticText54;
|
||||
wxStaticText* m_src2DCStepUnit;
|
||||
wxButton* m_swapDCSources;
|
||||
wxPanel* m_pgDistortion;
|
||||
wxPanel* m_pgNoise;
|
||||
wxStaticText* m_staticText14;
|
||||
|
@ -123,6 +122,10 @@ class DIALOG_SIM_SETTINGS_BASE : public DIALOG_SHIM
|
|||
|
||||
// Virtual event handlers, overide them in your derived class
|
||||
virtual void onInitDlg( wxInitDialogEvent& event ) { event.Skip(); }
|
||||
virtual void onDCEnableSecondSource( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void onDCSource1Selected( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void onDCSource2Selected( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void onSwapDCSources( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void onLoadDirectives( wxCommandEvent& event ) { event.Skip(); }
|
||||
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ void NGSPICE::Init()
|
|||
}
|
||||
|
||||
|
||||
vector<string> NGSPICE::AllPlots()
|
||||
vector<string> NGSPICE::AllPlots() const
|
||||
{
|
||||
LOCALE_IO c_locale; // ngspice works correctly only with C locale
|
||||
char* currentPlot = m_ngSpice_CurPlot();
|
||||
|
@ -293,20 +293,28 @@ string NGSPICE::GetXAxis( SIM_TYPE aType ) const
|
|||
case ST_AC:
|
||||
case ST_NOISE:
|
||||
return string( "frequency" );
|
||||
break;
|
||||
|
||||
case ST_DC:
|
||||
return string( "v-sweep" );
|
||||
// find plot, which ends with "-sweep"
|
||||
for( auto& plot : AllPlots() )
|
||||
{
|
||||
const string sweepEnding = "-sweep";
|
||||
unsigned int len = sweepEnding.length();
|
||||
|
||||
if( plot.length() > len
|
||||
&& plot.substr( plot.length() - len, len ).compare( sweepEnding ) == 0 )
|
||||
{
|
||||
return string( plot );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ST_TRANSIENT:
|
||||
return string( "time" );
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return string( "" );
|
||||
}
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ public:
|
|||
std::string GetXAxis( SIM_TYPE aType ) const override;
|
||||
|
||||
///> @copydoc SPICE_SIMULATOR::AllPlots()
|
||||
std::vector<std::string> AllPlots() override;
|
||||
std::vector<std::string> AllPlots() const override;
|
||||
|
||||
///> @copydoc SPICE_SIMULATOR::GetPlot()
|
||||
std::vector<COMPLEX> GetPlot( const std::string& aName, int aMaxLen = -1 ) override;
|
||||
|
|
|
@ -25,23 +25,24 @@
|
|||
#include "sim_panel_base.h"
|
||||
|
||||
#include "sim_plot_frame.h"
|
||||
|
||||
#include <wx/sizer.h>
|
||||
#include "netlist_exporter_pspice_sim.h"
|
||||
|
||||
|
||||
SIM_PANEL_BASE::SIM_PANEL_BASE() : m_type( ST_UNKNOWN )
|
||||
SIM_PANEL_BASE::SIM_PANEL_BASE() : m_simCommand( wxEmptyString )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SIM_PANEL_BASE::SIM_PANEL_BASE( SIM_TYPE aType ) : m_type( aType )
|
||||
SIM_PANEL_BASE::SIM_PANEL_BASE( wxString aCommand ) : m_simCommand( aCommand )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SIM_PANEL_BASE::SIM_PANEL_BASE( SIM_TYPE aType, wxWindow* parent, wxWindowID id,
|
||||
const wxPoint& pos, const wxSize& size, long style, const wxString& name )
|
||||
: wxWindow( parent, id, pos, size, style, name ), m_type( aType )
|
||||
SIM_PANEL_BASE::SIM_PANEL_BASE( wxString aCommand, wxWindow* parent, wxWindowID id,
|
||||
const wxPoint& pos, const wxSize& size, long style,
|
||||
const wxString& name ) :
|
||||
wxWindow( parent, id, pos, size, style, name ),
|
||||
m_simCommand( aCommand )
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -66,9 +67,16 @@ bool SIM_PANEL_BASE::IsPlottable( SIM_TYPE aSimType )
|
|||
}
|
||||
|
||||
|
||||
SIM_NOPLOT_PANEL::SIM_NOPLOT_PANEL( SIM_TYPE aType, wxWindow* parent, wxWindowID id,
|
||||
const wxPoint& pos, const wxSize& size, long style, const wxString& name )
|
||||
: SIM_PANEL_BASE( aType, parent, id, pos, size, style, name )
|
||||
SIM_TYPE SIM_PANEL_BASE::GetType() const
|
||||
{
|
||||
return NETLIST_EXPORTER_PSPICE_SIM::CommandToSimType( m_simCommand );
|
||||
}
|
||||
|
||||
|
||||
SIM_NOPLOT_PANEL::SIM_NOPLOT_PANEL( wxString aCommand, wxWindow* parent, wxWindowID id,
|
||||
const wxPoint& pos, const wxSize& size, long style,
|
||||
const wxString& name ) :
|
||||
SIM_PANEL_BASE( aCommand, parent, id, pos, size, style, name )
|
||||
{
|
||||
m_sizer = new wxBoxSizer( wxVERTICAL );
|
||||
m_sizer->Add( 0, 1, 1, wxEXPAND, 5 );
|
||||
|
@ -81,9 +89,10 @@ SIM_NOPLOT_PANEL::SIM_NOPLOT_PANEL( SIM_TYPE aType, wxWindow* parent, wxWindowID
|
|||
|
||||
//ST_UNKNOWN serves purpose of a welcome panel
|
||||
m_textInfo->SetLabel(
|
||||
( aType == ST_UNKNOWN ) ?
|
||||
_( "Start the simulation by clicking the Run Simulation button" ) :
|
||||
_( "This simulation provide no plots. Please refer to console window for results" ) );
|
||||
( GetType() == ST_UNKNOWN )
|
||||
? _( "Start the simulation by clicking the Run Simulation button" )
|
||||
: _( "This simulation provide no plots. Please refer to console window for "
|
||||
"results" ) );
|
||||
|
||||
m_sizer->Add( m_textInfo, 1, wxALL | wxEXPAND, 5 );
|
||||
m_sizer->Add( 0, 1, 1, wxEXPAND, 5 );
|
||||
|
|
|
@ -36,30 +36,27 @@ class SIM_PANEL_BASE : public wxWindow
|
|||
{
|
||||
public:
|
||||
SIM_PANEL_BASE();
|
||||
SIM_PANEL_BASE( SIM_TYPE );
|
||||
SIM_PANEL_BASE( SIM_TYPE aType, wxWindow* parent, wxWindowID id,
|
||||
const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
|
||||
long style = 0, const wxString& name = wxPanelNameStr );
|
||||
SIM_PANEL_BASE( wxString aCommand );
|
||||
SIM_PANEL_BASE( wxString aCommand, wxWindow* parent, wxWindowID id,
|
||||
const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
|
||||
long style = 0, const wxString& name = wxPanelNameStr );
|
||||
virtual ~SIM_PANEL_BASE();
|
||||
|
||||
static bool IsPlottable( SIM_TYPE aSimType );
|
||||
|
||||
SIM_TYPE GetType() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
SIM_TYPE GetType() const;
|
||||
|
||||
private:
|
||||
const SIM_TYPE m_type;
|
||||
protected:
|
||||
const wxString m_simCommand;
|
||||
};
|
||||
|
||||
|
||||
class SIM_NOPLOT_PANEL : public SIM_PANEL_BASE
|
||||
{
|
||||
public:
|
||||
SIM_NOPLOT_PANEL( SIM_TYPE aType, wxWindow* parent, wxWindowID id,
|
||||
const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
|
||||
long style = 0, const wxString& name = wxPanelNameStr );
|
||||
SIM_NOPLOT_PANEL( wxString aCommand, wxWindow* parent, wxWindowID id,
|
||||
const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
|
||||
long style = 0, const wxString& name = wxPanelNameStr );
|
||||
|
||||
virtual ~SIM_NOPLOT_PANEL();
|
||||
|
||||
|
|
|
@ -207,7 +207,7 @@ SIM_PLOT_FRAME::SIM_PLOT_FRAME( KIWAY* aKiway, wxWindow* aParent )
|
|||
|
||||
m_toolBar->Realize();
|
||||
|
||||
m_welcomePanel = new SIM_PANEL_BASE( ST_UNKNOWN, m_plotNotebook, wxID_ANY );
|
||||
m_welcomePanel = new SIM_PANEL_BASE( wxEmptyString, m_plotNotebook, wxID_ANY );
|
||||
m_plotNotebook->AddPage( m_welcomePanel, _( "Welcome!" ), 1, true );
|
||||
|
||||
// the settings dialog will be created later, on demand.
|
||||
|
@ -476,14 +476,15 @@ bool SIM_PLOT_FRAME::IsSimulationRunning()
|
|||
}
|
||||
|
||||
|
||||
SIM_PANEL_BASE* SIM_PLOT_FRAME::NewPlotPanel( SIM_TYPE aSimType )
|
||||
SIM_PANEL_BASE* SIM_PLOT_FRAME::NewPlotPanel( wxString aSimCommand )
|
||||
{
|
||||
SIM_PANEL_BASE* plotPanel;
|
||||
SIM_TYPE simType = NETLIST_EXPORTER_PSPICE_SIM::CommandToSimType( aSimCommand );
|
||||
|
||||
if( SIM_PANEL_BASE::IsPlottable( aSimType ) )
|
||||
if( SIM_PANEL_BASE::IsPlottable( simType ) )
|
||||
{
|
||||
SIM_PLOT_PANEL* panel;
|
||||
panel = new SIM_PLOT_PANEL( aSimType, m_plotNotebook, this, wxID_ANY );
|
||||
panel = new SIM_PLOT_PANEL( aSimCommand, m_plotNotebook, this, wxID_ANY );
|
||||
|
||||
panel->GetPlotWin()->EnableMouseWheelPan(
|
||||
Pgm().GetCommonSettings()->m_Input.scroll_modifier_zoom != 0 );
|
||||
|
@ -493,7 +494,7 @@ SIM_PANEL_BASE* SIM_PLOT_FRAME::NewPlotPanel( SIM_TYPE aSimType )
|
|||
else
|
||||
{
|
||||
SIM_NOPLOT_PANEL* panel;
|
||||
panel = new SIM_NOPLOT_PANEL( aSimType, m_plotNotebook, wxID_ANY );
|
||||
panel = new SIM_NOPLOT_PANEL( aSimCommand, m_plotNotebook, wxID_ANY );
|
||||
plotPanel = dynamic_cast<SIM_PANEL_BASE*>( panel );
|
||||
}
|
||||
|
||||
|
@ -503,7 +504,7 @@ SIM_PANEL_BASE* SIM_PLOT_FRAME::NewPlotPanel( SIM_TYPE aSimType )
|
|||
m_welcomePanel = nullptr;
|
||||
}
|
||||
|
||||
wxString pageTitle( m_simulator->TypeToName( aSimType, true ) );
|
||||
wxString pageTitle( m_simulator->TypeToName( simType, true ) );
|
||||
pageTitle.Prepend( wxString::Format( _( "Plot%u - " ), (unsigned int) ++m_plotNumber ) );
|
||||
|
||||
m_plotNotebook->AddPage( dynamic_cast<wxWindow*>( plotPanel ), pageTitle, true );
|
||||
|
@ -612,7 +613,8 @@ void SIM_PLOT_FRAME::addPlot( const wxString& aName, SIM_PLOT_TYPE aType, const
|
|||
SIM_PLOT_PANEL* plotPanel = CurrentPlot();
|
||||
|
||||
if( !plotPanel || plotPanel->GetType() != simType )
|
||||
plotPanel = dynamic_cast<SIM_PLOT_PANEL*>( NewPlotPanel( simType ) );
|
||||
plotPanel =
|
||||
dynamic_cast<SIM_PLOT_PANEL*>( NewPlotPanel( m_exporter->GetUsedSimCommand() ) );
|
||||
|
||||
wxASSERT( plotPanel );
|
||||
|
||||
|
@ -920,8 +922,9 @@ bool SIM_PLOT_FRAME::loadWorkbook( const wxString& aPath )
|
|||
if( !file.GetNextLine().ToLong( &plotType ) )
|
||||
return false;
|
||||
|
||||
SIM_PANEL_BASE* plotPanel = NewPlotPanel( (SIM_TYPE) plotType );
|
||||
m_plots[plotPanel].m_simCommand = file.GetNextLine();
|
||||
wxString simCommand = file.GetNextLine();
|
||||
SIM_PANEL_BASE* plotPanel = NewPlotPanel( simCommand );
|
||||
m_plots[plotPanel].m_simCommand = simCommand;
|
||||
StartSimulation( m_plots[plotPanel].m_simCommand );
|
||||
|
||||
// Perform simulation, so plots can be added with values
|
||||
|
@ -1031,7 +1034,8 @@ void SIM_PLOT_FRAME::menuNewPlot( wxCommandEvent& aEvent )
|
|||
if( SIM_PANEL_BASE::IsPlottable( type ) )
|
||||
{
|
||||
SIM_PLOT_PANEL* prevPlot = CurrentPlot();
|
||||
SIM_PLOT_PANEL* newPlot = dynamic_cast<SIM_PLOT_PANEL*>( NewPlotPanel( type ) );
|
||||
SIM_PLOT_PANEL* newPlot =
|
||||
dynamic_cast<SIM_PLOT_PANEL*>( NewPlotPanel( m_exporter->GetUsedSimCommand() ) );
|
||||
|
||||
// If the previous plot had the same type, copy the simulation command
|
||||
if( prevPlot )
|
||||
|
@ -1314,13 +1318,18 @@ void SIM_PLOT_FRAME::onSettings( wxCommandEvent& event )
|
|||
|
||||
if( m_settingsDlg->ShowModal() == wxID_OK )
|
||||
{
|
||||
wxString oldCommand = m_plots[plotPanelWindow].m_simCommand;
|
||||
wxString newCommand = m_settingsDlg->GetSimCommand();
|
||||
SIM_TYPE newSimType = NETLIST_EXPORTER_PSPICE_SIM::CommandToSimType( newCommand );
|
||||
|
||||
// If it is a new simulation type, open a new plot
|
||||
if( !plotPanelWindow || ( plotPanelWindow && plotPanelWindow->GetType() != newSimType ) )
|
||||
// For the DC sim, check if sweep source type has changed (char 4 will contain 'v', 'i', 'r' or 't'
|
||||
if( !plotPanelWindow
|
||||
|| ( plotPanelWindow && plotPanelWindow->GetType() != newSimType )
|
||||
|| ( newSimType == ST_DC
|
||||
&& oldCommand.Lower().GetChar( 4 ) != newCommand.Lower().GetChar( 4 ) ) )
|
||||
{
|
||||
plotPanelWindow = NewPlotPanel( newSimType );
|
||||
plotPanelWindow = NewPlotPanel( newCommand );
|
||||
}
|
||||
|
||||
m_plots[plotPanelWindow].m_simCommand = newCommand;
|
||||
|
@ -1501,7 +1510,7 @@ void SIM_PLOT_FRAME::onSimFinished( wxCommandEvent& aEvent )
|
|||
SIM_PANEL_BASE* plotPanelWindow = currentPlotWindow();
|
||||
|
||||
if( !plotPanelWindow || plotPanelWindow->GetType() != simType )
|
||||
plotPanelWindow = NewPlotPanel( simType );
|
||||
plotPanelWindow = NewPlotPanel( m_exporter->GetUsedSimCommand() );
|
||||
|
||||
if( IsSimulationRunning() )
|
||||
return;
|
||||
|
|
|
@ -136,10 +136,10 @@ public:
|
|||
/**
|
||||
* @brief Creates a new plot panel for a given simulation type and adds it to the main
|
||||
* notebook.
|
||||
* @param aSimType is requested simulation type.
|
||||
* @param aSimCommand is the SPICE command used for simulation.
|
||||
* @return The new plot panel.
|
||||
*/
|
||||
SIM_PANEL_BASE* NewPlotPanel( SIM_TYPE aSimType );
|
||||
SIM_PANEL_BASE* NewPlotPanel( wxString aSimCommand );
|
||||
|
||||
/**
|
||||
* @brief Adds a voltage plot for a given net name.
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
#include <algorithm>
|
||||
#include <limits>
|
||||
|
||||
#include <wx/regex.h>
|
||||
|
||||
static wxString formatFloat( double x, int nDigits )
|
||||
{
|
||||
wxString rv, fmt;
|
||||
|
@ -120,145 +122,66 @@ static int countDecimalDigits( double x, int maxDigits )
|
|||
}
|
||||
|
||||
|
||||
static void formatSILabels( mpScaleBase* scale, const wxString& aUnit, int nDigits )
|
||||
template <typename parent>
|
||||
class LIN_SCALE : public parent
|
||||
{
|
||||
double maxVis = scale->AbsVisibleMaxValue();
|
||||
private:
|
||||
const wxString m_unit;
|
||||
|
||||
wxString suffix;
|
||||
int power, digits = 0;
|
||||
|
||||
getSISuffix( maxVis, aUnit, power, suffix );
|
||||
|
||||
double sf = pow( 10.0, power );
|
||||
|
||||
for( auto &l : scale->TickLabels() )
|
||||
{
|
||||
int k = countDecimalDigits( l.pos / sf, nDigits );
|
||||
|
||||
digits = std::max( digits, k );
|
||||
}
|
||||
|
||||
for( auto &l : scale->TickLabels() )
|
||||
{
|
||||
l.label = formatFloat ( l.pos / sf, digits ) + suffix;
|
||||
l.visible = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class FREQUENCY_LOG_SCALE : public mpScaleXLog
|
||||
{
|
||||
public:
|
||||
FREQUENCY_LOG_SCALE( wxString name, int flags ) :
|
||||
mpScaleXLog( name, flags ) {};
|
||||
LIN_SCALE( wxString name, wxString unit, int flags ) : parent( name, flags ), m_unit( unit ){};
|
||||
|
||||
void formatLabels() override
|
||||
{
|
||||
const wxString unit = wxT( "Hz" );
|
||||
double maxVis = parent::AbsVisibleMaxValue();
|
||||
|
||||
wxString suffix;
|
||||
int power;
|
||||
int power, digits = 0;
|
||||
int constexpr DIGITS = 3;
|
||||
|
||||
for( auto &l : TickLabels() )
|
||||
getSISuffix( maxVis, m_unit, power, suffix );
|
||||
|
||||
double sf = pow( 10.0, power );
|
||||
|
||||
for( auto& l : parent::TickLabels() )
|
||||
{
|
||||
getSISuffix( l.pos, unit, power, suffix );
|
||||
double sf = pow( 10.0, power );
|
||||
int k = countDecimalDigits( l.pos / sf, 3 );
|
||||
int k = countDecimalDigits( l.pos / sf, DIGITS );
|
||||
|
||||
l.label = formatFloat( l.pos / sf, k ) + suffix;
|
||||
digits = std::max( digits, k );
|
||||
}
|
||||
|
||||
for( auto& l : parent::TickLabels() )
|
||||
{
|
||||
l.label = formatFloat( l.pos / sf, digits ) + suffix;
|
||||
l.visible = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class FREQUENCY_LIN_SCALE : public mpScaleX
|
||||
template <typename parent>
|
||||
class LOG_SCALE : public parent
|
||||
{
|
||||
private:
|
||||
const wxString m_unit;
|
||||
|
||||
public:
|
||||
FREQUENCY_LIN_SCALE( wxString name, int flags ) :
|
||||
mpScaleX( name, flags, false , 0 ) {};
|
||||
LOG_SCALE( wxString name, wxString unit, int flags ) : parent( name, flags ), m_unit( unit ){};
|
||||
|
||||
void formatLabels() override
|
||||
{
|
||||
formatSILabels( this, wxT( "Hz" ), 3 );
|
||||
}
|
||||
};
|
||||
wxString suffix;
|
||||
int power;
|
||||
|
||||
for( auto& l : parent::TickLabels() )
|
||||
{
|
||||
getSISuffix( l.pos, m_unit, power, suffix );
|
||||
double sf = pow( 10.0, power );
|
||||
int k = countDecimalDigits( l.pos / sf, 3 );
|
||||
|
||||
class TIME_SCALE : public mpScaleX
|
||||
{
|
||||
public:
|
||||
TIME_SCALE( wxString name, int flags ) :
|
||||
mpScaleX( name, flags, false, 0 ) {};
|
||||
|
||||
void formatLabels() override
|
||||
{
|
||||
formatSILabels( this, wxT( "s" ), 3 );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class VOLTAGE_SCALE_X : public mpScaleX
|
||||
{
|
||||
public:
|
||||
VOLTAGE_SCALE_X( wxString name, int flags ) :
|
||||
mpScaleX( name, flags, false, 0 ) {};
|
||||
|
||||
void formatLabels() override
|
||||
{
|
||||
formatSILabels( this, wxT( "V" ), 3 );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class GAIN_SCALE : public mpScaleY
|
||||
{
|
||||
public:
|
||||
GAIN_SCALE( wxString name, int flags ) :
|
||||
mpScaleY( name, flags, false ) {};
|
||||
|
||||
void formatLabels() override
|
||||
{
|
||||
formatSILabels( this, wxT( "dBV" ), 3 );
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
class PHASE_SCALE : public mpScaleY
|
||||
{
|
||||
public:
|
||||
PHASE_SCALE( wxString name, int flags ) :
|
||||
mpScaleY( name, flags, false ) {};
|
||||
|
||||
void formatLabels() override
|
||||
{
|
||||
formatSILabels( this, wxT( "\u00B0" ), 3 ); // degree sign
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class VOLTAGE_SCALE_Y : public mpScaleY
|
||||
{
|
||||
public:
|
||||
VOLTAGE_SCALE_Y( wxString name, int flags ) :
|
||||
mpScaleY( name, flags, false ) {};
|
||||
|
||||
void formatLabels() override
|
||||
{
|
||||
formatSILabels( this, wxT( "V" ), 3 );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class CURRENT_SCALE : public mpScaleY
|
||||
{
|
||||
public:
|
||||
CURRENT_SCALE( wxString name, int flags ) :
|
||||
mpScaleY( name, flags, false ) {};
|
||||
|
||||
void formatLabels() override
|
||||
{
|
||||
formatSILabels( this, wxT( "A" ), 3 );
|
||||
l.label = formatFloat( l.pos / sf, k ) + suffix;
|
||||
l.visible = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -363,9 +286,9 @@ void CURSOR::UpdateReference()
|
|||
}
|
||||
|
||||
|
||||
SIM_PLOT_PANEL::SIM_PLOT_PANEL( SIM_TYPE aType, wxWindow* parent, SIM_PLOT_FRAME* aMainFrame,
|
||||
SIM_PLOT_PANEL::SIM_PLOT_PANEL( wxString aCommand, wxWindow* parent, SIM_PLOT_FRAME* aMainFrame,
|
||||
wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name )
|
||||
: SIM_PANEL_BASE( aType, parent, id, pos, size, style, name ),
|
||||
: SIM_PANEL_BASE( aCommand, parent, id, pos, size, style, name ),
|
||||
m_colorIdx( 0 ),
|
||||
m_axis_x( nullptr ),
|
||||
m_axis_y1( nullptr ),
|
||||
|
@ -385,27 +308,26 @@ SIM_PLOT_PANEL::SIM_PLOT_PANEL( SIM_TYPE aType, wxWindow* parent, SIM_PLOT_FRAME
|
|||
switch( GetType() )
|
||||
{
|
||||
case ST_AC:
|
||||
m_axis_x = new FREQUENCY_LOG_SCALE( _( "Frequency" ), mpALIGN_BOTTOM );
|
||||
m_axis_y1 = new GAIN_SCALE( _( "Gain" ), mpALIGN_LEFT );
|
||||
m_axis_y2 = new PHASE_SCALE( _( "Phase" ), mpALIGN_RIGHT );
|
||||
m_axis_x = new LOG_SCALE<mpScaleXLog>( _( "Frequency" ), wxT( "Hz" ), mpALIGN_BOTTOM );
|
||||
m_axis_y1 = new LIN_SCALE<mpScaleY>( _( "Gain" ), wxT( "dBV" ), mpALIGN_LEFT );
|
||||
m_axis_y2 = new LIN_SCALE<mpScaleY>( _( "Phase" ), wxT( "\u00B0" ),
|
||||
mpALIGN_RIGHT ); // degree sign
|
||||
m_axis_y2->SetMasterScale( m_axis_y1 );
|
||||
break;
|
||||
|
||||
case ST_DC:
|
||||
m_axis_x = new VOLTAGE_SCALE_X( _( "Voltage (swept)" ), mpALIGN_BOTTOM );
|
||||
m_axis_y1 = new VOLTAGE_SCALE_Y( _( "Voltage (measured)" ), mpALIGN_LEFT );
|
||||
m_axis_y2 = new CURRENT_SCALE( _( "Current" ), mpALIGN_RIGHT );
|
||||
prepareDCAxes();
|
||||
break;
|
||||
|
||||
case ST_NOISE:
|
||||
m_axis_x = new FREQUENCY_LOG_SCALE( _( "Frequency" ), mpALIGN_BOTTOM );
|
||||
m_axis_x = new LOG_SCALE<mpScaleXLog>( _( "Frequency" ), wxT( "Hz" ), mpALIGN_BOTTOM );
|
||||
m_axis_y1 = new mpScaleY( _( "noise [(V or A)^2/Hz]" ), mpALIGN_LEFT );
|
||||
break;
|
||||
|
||||
case ST_TRANSIENT:
|
||||
m_axis_x = new TIME_SCALE( _( "Time" ), mpALIGN_BOTTOM );
|
||||
m_axis_y1 = new VOLTAGE_SCALE_Y( _( "Voltage" ), mpALIGN_LEFT );
|
||||
m_axis_y2 = new CURRENT_SCALE( _( "Current" ), mpALIGN_RIGHT );
|
||||
m_axis_x = new LIN_SCALE<mpScaleX>( _( "Time" ), wxT( "s" ), mpALIGN_BOTTOM );
|
||||
m_axis_y1 = new LIN_SCALE<mpScaleY>( _( "Voltage" ), wxT( "V" ), mpALIGN_LEFT );
|
||||
m_axis_y2 = new LIN_SCALE<mpScaleY>( _( "Current" ), wxT( "A" ), mpALIGN_RIGHT );
|
||||
m_axis_y2->SetMasterScale( m_axis_y1 );
|
||||
break;
|
||||
|
||||
|
@ -455,6 +377,38 @@ SIM_PLOT_PANEL::~SIM_PLOT_PANEL()
|
|||
}
|
||||
|
||||
|
||||
void SIM_PLOT_PANEL::prepareDCAxes()
|
||||
{
|
||||
wxRegEx simCmd( "^.dc[[:space:]]+([[:alnum:]]+\\M).*", wxRE_ADVANCED | wxRE_ICASE );
|
||||
|
||||
if( simCmd.Matches( m_simCommand ) )
|
||||
{
|
||||
switch( static_cast<char>( simCmd.GetMatch( m_simCommand.Lower(), 1 ).GetChar( 0 ) ) )
|
||||
{
|
||||
case 'v':
|
||||
m_axis_x =
|
||||
new LIN_SCALE<mpScaleX>( _( "Voltage (swept)" ), wxT( "V" ), mpALIGN_BOTTOM );
|
||||
break;
|
||||
case 'i':
|
||||
m_axis_x =
|
||||
new LIN_SCALE<mpScaleX>( _( "Current (swept)" ), wxT( "A" ), mpALIGN_BOTTOM );
|
||||
break;
|
||||
case 'r':
|
||||
m_axis_x = new LIN_SCALE<mpScaleX>( _( "Resistance (swept)" ), wxT( "\u03A9" ),
|
||||
mpALIGN_BOTTOM );
|
||||
break;
|
||||
case 't':
|
||||
m_axis_x = new LIN_SCALE<mpScaleX>( _( "Temperature (swept)" ), wxT( "\u00B0C" ),
|
||||
mpALIGN_BOTTOM );
|
||||
break;
|
||||
}
|
||||
|
||||
m_axis_y1 = new LIN_SCALE<mpScaleY>( _( "Voltage (measured)" ), wxT( "V" ), mpALIGN_LEFT );
|
||||
m_axis_y2 = new LIN_SCALE<mpScaleY>( _( "Current" ), wxT( "A" ), mpALIGN_RIGHT );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SIM_PLOT_PANEL::UpdatePlotColors()
|
||||
{
|
||||
// Update bg and fg colors:
|
||||
|
|
|
@ -168,9 +168,9 @@ protected:
|
|||
class SIM_PLOT_PANEL : public SIM_PANEL_BASE
|
||||
{
|
||||
public:
|
||||
SIM_PLOT_PANEL( SIM_TYPE aType, wxWindow* parent, SIM_PLOT_FRAME* aMainFrame,
|
||||
wxWindowID id, const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxDefaultSize, long style = 0, const wxString& name = wxPanelNameStr );
|
||||
SIM_PLOT_PANEL( wxString aCommand, wxWindow* parent, SIM_PLOT_FRAME* aMainFrame, wxWindowID id,
|
||||
const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
|
||||
long style = 0, const wxString& name = wxPanelNameStr );
|
||||
|
||||
virtual ~SIM_PLOT_PANEL();
|
||||
|
||||
|
@ -296,6 +296,9 @@ private:
|
|||
///> @return a new color from the palette
|
||||
wxColour generateColor();
|
||||
|
||||
///> @brief Constructs the plot axes for DC simulation plot
|
||||
void prepareDCAxes();
|
||||
|
||||
// Color index to get a new color from the palette
|
||||
unsigned int m_colorIdx;
|
||||
|
||||
|
|
|
@ -95,7 +95,7 @@ public:
|
|||
* @param none
|
||||
* @return List of vector names. ?May not match to the net name elements.
|
||||
*/
|
||||
virtual std::vector<std::string> AllPlots() = 0;
|
||||
virtual std::vector<std::string> AllPlots() const = 0;
|
||||
|
||||
/**
|
||||
* @brief Returns a requested vector with complex values. If the vector is real, then
|
||||
|
|
Loading…
Reference in New Issue