diff --git a/common/bitmap_info.cpp b/common/bitmap_info.cpp index 6ce70852e4..ee79a5f1e0 100644 --- a/common/bitmap_info.cpp +++ b/common/bitmap_info.cpp @@ -481,6 +481,7 @@ void BuildBitmapInfo( std::unordered_map>& aBi aBitmapInfoCache[BITMAPS::shape_3d_back].emplace_back( BITMAPS::shape_3d_back, wxT( "shape_3d_back_24.png" ), 24, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::sheetset].emplace_back( BITMAPS::sheetset, wxT( "sheetset_24.png" ), 24, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::simulator].emplace_back( BITMAPS::simulator, wxT( "simulator_24.png" ), 24, wxT( "light" ) ); + aBitmapInfoCache[BITMAPS::sim_add_plot].emplace_back( BITMAPS::sim_add_plot, wxT( "sim_add_plot_24.png" ), 24, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::sim_command].emplace_back( BITMAPS::sim_command, wxT( "sim_command_24.png" ), 24, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::sim_run].emplace_back( BITMAPS::sim_run, wxT( "sim_run_24.png" ), 24, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::sim_stop].emplace_back( BITMAPS::sim_stop, wxT( "sim_stop_24.png" ), 24, wxT( "light" ) ); diff --git a/common/widgets/mathplot.cpp b/common/widgets/mathplot.cpp index 3b715c8947..eeb888113b 100644 --- a/common/widgets/mathplot.cpp +++ b/common/widgets/mathplot.cpp @@ -1676,12 +1676,8 @@ mpWindow::mpWindow() : } } -mpWindow::mpWindow( wxWindow* parent, - wxWindowID id, - const wxPoint& pos, - const wxSize& size, - long flag ) - : wxWindow( parent, id, pos, size, flag, wxT( "mathplot" ) ) +mpWindow::mpWindow( wxWindow* parent, wxWindowID id ) : + wxWindow( parent, id, wxDefaultPosition, wxDefaultSize, 0, wxT( "mathplot" ) ) { m_zooming = false; m_scaleX = m_scaleY = 1.0; diff --git a/eeschema/dialogs/dialog_sim_command.cpp b/eeschema/dialogs/dialog_sim_command.cpp index 7c11045a1d..6b62c6c358 100644 --- a/eeschema/dialogs/dialog_sim_command.cpp +++ b/eeschema/dialogs/dialog_sim_command.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2016-2022 CERN - * Copyright (C) 2016-2022 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2016-2023 KiCad Developers, see AUTHORS.txt for contributors. * @author Maciej Suminski * * This program is free software; you can redistribute it and/or @@ -26,6 +26,7 @@ #include "dialog_sim_command.h" #include #include +#include #include @@ -56,10 +57,11 @@ static wxString getStringSelection( const wxChoice* aCtrl ) } -DIALOG_SIM_COMMAND::DIALOG_SIM_COMMAND( wxWindow* aParent, +DIALOG_SIM_COMMAND::DIALOG_SIM_COMMAND( SIMULATOR_FRAME* aParent, std::shared_ptr aCircuitModel, std::shared_ptr& aSettings ) : DIALOG_SIM_COMMAND_BASE( aParent ), + m_simulatorFrame( aParent ), m_circuitModel( aCircuitModel ), m_settings( aSettings ), m_spiceEmptyValidator( true ) @@ -91,6 +93,8 @@ DIALOG_SIM_COMMAND::DIALOG_SIM_COMMAND( wxWindow* aParent, m_transInitial->SetValidator( m_spiceEmptyValidator ); m_transMaxStep->SetValidator( m_spiceEmptyValidator ); + m_inputSignalsFilter->SetDescriptiveText( _( "Filter" ) ); + wxChar type1 = getStringSelection( m_dcSourceType1 ).Upper().GetChar( 0 ); updateDCSources( type1, m_dcSource1 ); @@ -112,15 +116,6 @@ DIALOG_SIM_COMMAND::DIALOG_SIM_COMMAND( wxWindow* aParent, m_noiseSrc->Append( item.refName ); } - 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 ) ); - m_simPages->RemovePage( m_simPages->FindPage( m_pgPoleZero ) ); - m_simPages->RemovePage( m_simPages->FindPage( m_pgSensitivity ) ); - m_simPages->RemovePage( m_simPages->FindPage( m_pgTransferFunction ) ); - if( !dynamic_cast( aSettings.get() ) ) m_compatibilityMode->Show( false ); @@ -158,6 +153,7 @@ bool DIALOG_SIM_COMMAND::TransferDataToWindow() if( m_simCommand.IsEmpty() && !empty( m_customTxt ) ) parseCommand( m_customTxt->GetValue() ); + refreshUIControls(); return true; } @@ -225,7 +221,7 @@ bool DIALOG_SIM_COMMAND::TransferDataFromWindow() wxString previousSimCommand = m_simCommand; wxWindow* page = m_simPages->GetCurrentPage(); - if( page == m_pgAC ) // AC analysis + if( page == m_pgAC ) // AC small-signal analysis { if( !m_pgAC->Validate() ) return false; @@ -236,7 +232,7 @@ bool DIALOG_SIM_COMMAND::TransferDataFromWindow() SPICE_VALUE( m_acFreqStart->GetValue() ).ToSpiceString(), SPICE_VALUE( m_acFreqStop->GetValue() ).ToSpiceString() ); } - else if( page == m_pgSP ) // S-params analysis + else if( page == m_pgSP ) // S-params analysis { if( !m_pgSP->Validate() ) return false; @@ -276,7 +272,22 @@ bool DIALOG_SIM_COMMAND::TransferDataFromWindow() m_simCommand = simCmd; } - else if( page == m_pgNoise ) // Noise analysis + else if( page == m_pgFFT ) // Fast Fourier transform + { + wxString vectors; + + for( int ii = 0; ii < (int) m_inputSignalsList->GetCount(); ++ii ) + { + if( m_inputSignalsList->IsChecked( ii ) ) + vectors += wxS( " " ) + m_inputSignalsList->GetString( ii ); + } + + if( m_linearize->IsChecked() ) + m_simCommand = wxT( "linearize" ) + vectors + wxS( "\n" ); + + m_simCommand = wxT( "fft" ) + vectors; + } + else if( page == m_pgNOISE ) // Noise analysis { wxString output = m_noiseMeas->GetStringSelection(); wxString ref = m_noiseRef->GetStringSelection(); @@ -305,9 +316,9 @@ bool DIALOG_SIM_COMMAND::TransferDataFromWindow() { m_simCommand = wxString( ".op" ); } - else if( page == m_pgTransient ) // Transient analysis + else if( page == m_pgTRAN ) // Transient analysis { - if( !m_pgTransient->Validate() ) + if( !m_pgTRAN->Validate() ) return false; const wxString spc = wxS( " " ); @@ -430,11 +441,37 @@ void DIALOG_SIM_COMMAND::parseCommand( const wxString& aCommand ) if( aCommand.IsEmpty() ) return; - wxStringTokenizer tokenizer( aCommand, " " ); + if( aCommand == wxT( "*" ) ) + { + SetTitle( _( "New Simulation" ) ); + + m_commandType->Clear(); + + for( SIM_TYPE type : { ST_AC, ST_DC, ST_NOISE, ST_OP, ST_TRAN, ST_SP, ST_FFT } ) + { + m_commandType->Append( SPICE_SIMULATOR::TypeToName( type, true ) + + wxT( " \u2014 " ) + + SPICE_SIMULATOR::TypeToName( type, false ) ); + } + + m_commandTypeSizer->Show( true ); + return; + } + + SIM_TYPE simType = NGSPICE_CIRCUIT_MODEL::CommandToSimType( aCommand ); + + SetTitle( SPICE_SIMULATOR::TypeToName( simType, true ) + + wxT( " \u2014 " ) + + SPICE_SIMULATOR::TypeToName( simType, false ) ); + + m_commandTypeSizer->Show( false ); + + wxStringTokenizer tokenizer( aCommand, wxS( " \t\n\r" ), wxTOKEN_STRTOK ); wxString token = tokenizer.GetNextToken().Lower(); - if( token == ".ac" ) + switch( simType ) { + case ST_AC: m_simPages->SetSelection( m_simPages->FindPage( m_pgAC ) ); token = tokenizer.GetNextToken().Lower(); @@ -451,9 +488,9 @@ void DIALOG_SIM_COMMAND::parseCommand( const wxString& aCommand ) m_acPointsNumber->SetValue( tokenizer.GetNextToken() ); m_acFreqStart->SetValue( SPICE_VALUE( tokenizer.GetNextToken() ).ToSpiceString() ); m_acFreqStop->SetValue( SPICE_VALUE( tokenizer.GetNextToken() ).ToSpiceString() ); - } - else if( token == ".sp" ) - { + break; + + case ST_SP: m_simPages->SetSelection( m_simPages->FindPage( m_pgSP ) ); token = tokenizer.GetNextToken().Lower(); @@ -472,11 +509,11 @@ void DIALOG_SIM_COMMAND::parseCommand( const wxString& aCommand ) m_spFreqStop->SetValue( SPICE_VALUE( tokenizer.GetNextToken() ).ToSpiceString() ); if( tokenizer.HasMoreTokens() ) - m_spDoNoise->SetValue( - SPICE_VALUE( tokenizer.GetNextToken() ).ToSpiceString() == "1" ? true - : false ); - } - else if( token == ".dc" ) + m_spDoNoise->SetValue( SPICE_VALUE( tokenizer.GetNextToken() ).ToSpiceString() == "1" ); + + break; + + case ST_DC: { m_simPages->SetSelection( m_simPages->FindPage( m_pgDC ) ); @@ -512,11 +549,12 @@ void DIALOG_SIM_COMMAND::parseCommand( const wxString& aCommand ) m_dcEnable2->SetValue( true ); } - refreshUIControls(); + break; } - else if( token == ".noise" ) + + case ST_NOISE: { - m_simPages->SetSelection( m_simPages->FindPage( m_pgNoise ) ); + m_simPages->SetSelection( m_simPages->FindPage( m_pgNOISE ) ); wxString output; wxString ref; @@ -548,10 +586,11 @@ void DIALOG_SIM_COMMAND::parseCommand( const wxString& aCommand ) m_noiseFreqStop->SetValue( fStop.ToSpiceString() ); m_saveAllNoise->SetValue( saveAll ); + break; } - else if( token == ".tran" ) - { - m_simPages->SetSelection( m_simPages->FindPage( m_pgTransient ) ); + + case ST_TRAN: + m_simPages->SetSelection( m_simPages->FindPage( m_pgTRAN ) ); // If the fields below are empty, it will be caught by the exception handler m_transStep->SetValue( SPICE_VALUE( tokenizer.GetNextToken() ).ToSpiceString() ); @@ -574,14 +613,51 @@ void DIALOG_SIM_COMMAND::parseCommand( const wxString& aCommand ) if( token.IsSameAs( wxS( "uic" ) ) ) m_useInitialConditions->SetValue( true ); - } - else if( token == ".op" ) - { + + break; + + case ST_OP: m_simPages->SetSelection( m_simPages->FindPage( m_pgOP ) ); - } - else if( !empty( m_customTxt ) ) // Custom directives + break; + + case ST_FFT: { + m_simPages->SetSelection( m_simPages->FindPage( m_pgFFT ) ); + + while( tokenizer.HasMoreTokens() ) + m_fftInputSignals.insert( tokenizer.GetNextToken() ); + + break; + } + + default: m_simPages->SetSelection( m_simPages->FindPage( m_pgCustom ) ); + break; + } +} + + +void DIALOG_SIM_COMMAND::OnCommandType( wxCommandEvent& event ) +{ + int sel = ST_UNKNOWN; + wxString str = m_commandType->GetString( event.GetSelection() ); + + for( int type = ST_UNKNOWN; type < ST_LAST; ++type ) + { + if( str.StartsWith( SPICE_SIMULATOR::TypeToName( (SIM_TYPE) type, true ) ) ) + sel = type; + } + + switch( sel ) + { + case ST_AC: m_simPages->SetSelection( m_simPages->FindPage( m_pgAC ) ); break; + case ST_SP: m_simPages->SetSelection( m_simPages->FindPage( m_pgSP ) ); break; + case ST_DC: m_simPages->SetSelection( m_simPages->FindPage( m_pgDC ) ); break; + case ST_NOISE: m_simPages->SetSelection( m_simPages->FindPage( m_pgNOISE ) ); break; + case ST_TRAN: m_simPages->SetSelection( m_simPages->FindPage( m_pgTRAN ) ); break; + case ST_OP: m_simPages->SetSelection( m_simPages->FindPage( m_pgOP ) ); break; + case ST_FFT: m_simPages->SetSelection( m_simPages->FindPage( m_pgFFT ) ); break; + default: m_simPages->SetSelection( m_simPages->FindPage( m_pgCustom ) ); break; } } @@ -619,6 +695,22 @@ void DIALOG_SIM_COMMAND::onSwapDCSources( wxCommandEvent& event ) } +void DIALOG_SIM_COMMAND::onDCSource1Selected( wxCommandEvent& event ) +{ + wxChar type = m_dcSourceType1->GetString( m_dcSourceType1->GetSelection() ).Upper()[ 0 ]; + updateDCSources( type, m_dcSource1 ); + updateDCUnits( type, m_dcSource1, m_src1DCStartValUnit, m_src1DCEndValUnit, m_src1DCStepUnit ); +} + + +void DIALOG_SIM_COMMAND::onDCSource2Selected( wxCommandEvent& event ) +{ + wxChar type = m_dcSourceType2->GetString( m_dcSourceType2->GetSelection() ).Upper()[ 0 ]; + updateDCSources( type, m_dcSource2 ); + updateDCUnits( type, m_dcSource2, m_src2DCStartValUnit, m_src2DCEndValUnit, m_src2DCStepUnit ); +} + + void DIALOG_SIM_COMMAND::onDCEnableSecondSource( wxCommandEvent& event ) { bool is2ndSrcEnabled = m_dcEnable2->IsChecked(); @@ -661,3 +753,50 @@ void DIALOG_SIM_COMMAND::loadDirectives() } +void DIALOG_SIM_COMMAND::OnFilterText( wxCommandEvent& aEvent ) +{ + for( int ii = 0; ii < (int) m_inputSignalsList->GetCount(); ++ii ) + { + if( m_inputSignalsList->IsChecked( ii ) ) + m_fftInputSignals.insert( m_inputSignalsList->GetString( ii ) ); + else + m_fftInputSignals.erase( m_inputSignalsList->GetString( ii ) ); + } + + m_inputSignalsList->Clear(); + + wxString aFilter = m_inputSignalsFilter->GetValue(); + + if( aFilter.IsEmpty() ) + aFilter = wxS( "*" ); + + EDA_COMBINED_MATCHER matcher( aFilter.Upper(), CTX_SIGNAL ); + + for( const wxString& signal : m_simulatorFrame->Signals() ) + { + if( matcher.Find( signal.Upper() ) ) + { + m_inputSignalsList->Append( signal ); + + if( m_fftInputSignals.count( signal ) ) + m_inputSignalsList->Check( m_inputSignalsList->GetCount() - 1 ); + } + } +} + + +void DIALOG_SIM_COMMAND::OnFilterMouseMoved( wxMouseEvent& aEvent ) +{ + wxPoint pos = aEvent.GetPosition(); + wxRect ctrlRect = m_inputSignalsFilter->GetScreenRect(); + int buttonWidth = ctrlRect.GetHeight(); // Presume buttons are square + + if( m_inputSignalsFilter->IsSearchButtonVisible() && pos.x < buttonWidth ) + SetCursor( wxCURSOR_ARROW ); + else if( m_inputSignalsFilter->IsCancelButtonVisible() && pos.x > ctrlRect.GetWidth() - buttonWidth ) + SetCursor( wxCURSOR_ARROW ); + else + SetCursor( wxCURSOR_IBEAM ); +} + + diff --git a/eeschema/dialogs/dialog_sim_command.h b/eeschema/dialogs/dialog_sim_command.h index dee7b272cd..d8dbc6341a 100644 --- a/eeschema/dialogs/dialog_sim_command.h +++ b/eeschema/dialogs/dialog_sim_command.h @@ -35,12 +35,13 @@ class NGSPICE_CIRCUIT_MODEL; class SPICE_SIMULATOR_SETTINGS; +class SIMULATOR_FRAME; class DIALOG_SIM_COMMAND : public DIALOG_SIM_COMMAND_BASE { public: - DIALOG_SIM_COMMAND( wxWindow* aParent, std::shared_ptr aCircuitModel, + DIALOG_SIM_COMMAND( SIMULATOR_FRAME* aParent, std::shared_ptr aCircuitModel, std::shared_ptr& aSettings ); const wxString& GetSimCommand() const @@ -52,6 +53,7 @@ public: { parseCommand( aCommand ); m_simCommand = aCommand; + refreshUIControls(); } int GetSimOptions() const @@ -107,6 +109,7 @@ private: wxQueueEvent( m_dcEnable2, new wxCommandEvent( wxEVT_CHECKBOX ) ); wxQueueEvent( m_dcSourceType1, new wxCommandEvent( wxEVT_RADIOBOX ) ); wxQueueEvent( m_dcSourceType2, new wxCommandEvent( wxEVT_RADIOBOX ) ); + wxQueueEvent( m_inputSignalsFilter, new wxCommandEvent( wxEVT_TEXT ) ); } /** @@ -151,23 +154,8 @@ private: 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 ); - } + void onDCSource1Selected( wxCommandEvent& event ) override; + void onDCSource2Selected( wxCommandEvent& event ) override; static wxString scaleToString( int aOption ) { @@ -180,15 +168,21 @@ private: } } + void OnCommandType( wxCommandEvent& event ) override; + void OnFilterMouseMoved( wxMouseEvent& event ) override; + void OnFilterText( wxCommandEvent& event ) override; + void loadDirectives(); private: + SIMULATOR_FRAME* m_simulatorFrame; wxString m_simCommand; std::shared_ptr m_circuitModel; std::shared_ptr m_settings; SPICE_VALIDATOR m_spiceValidator; SPICE_VALIDATOR m_spiceEmptyValidator; wxIntegerValidator m_posIntValidator; + std::set m_fftInputSignals; }; #endif /* DIALOG_SIM_COMMAND_H */ diff --git a/eeschema/dialogs/dialog_sim_command_base.cpp b/eeschema/dialogs/dialog_sim_command_base.cpp index cec533a98f..60542c08ab 100644 --- a/eeschema/dialogs/dialog_sim_command_base.cpp +++ b/eeschema/dialogs/dialog_sim_command_base.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version 3.10.1-88b0f50) +// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b) // http://www.wxformbuilder.org/ // // PLEASE DO *NOT* EDIT THIS FILE! @@ -16,7 +16,22 @@ DIALOG_SIM_COMMAND_BASE::DIALOG_SIM_COMMAND_BASE( wxWindow* parent, wxWindowID i wxBoxSizer* bSizer1; bSizer1 = new wxBoxSizer( wxVERTICAL ); - m_simPages = new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 ); + m_commandTypeSizer = new wxBoxSizer( wxHORIZONTAL ); + + m_commandTypeLabel = new wxStaticText( this, wxID_ANY, _("Simulation type:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_commandTypeLabel->Wrap( -1 ); + m_commandTypeSizer->Add( m_commandTypeLabel, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + wxString m_commandTypeChoices[] = { _("AC"), _("DC"), _("OP"), _("TRAN"), _("FFT"), _("NOISE"), _("SP"), _("Custom") }; + int m_commandTypeNChoices = sizeof( m_commandTypeChoices ) / sizeof( wxString ); + m_commandType = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_commandTypeNChoices, m_commandTypeChoices, 0 ); + m_commandType->SetSelection( 0 ); + m_commandTypeSizer->Add( m_commandType, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + + bSizer1->Add( m_commandTypeSizer, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 10 ); + + m_simPages = new wxSimplebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 ); m_pgAC = new wxPanel( m_simPages, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); wxBoxSizer* bSizer3; bSizer3 = new wxBoxSizer( wxVERTICAL ); @@ -75,69 +90,7 @@ DIALOG_SIM_COMMAND_BASE::DIALOG_SIM_COMMAND_BASE( wxWindow* parent, wxWindowID i m_pgAC->SetSizer( bSizer3 ); m_pgAC->Layout(); bSizer3->Fit( m_pgAC ); - m_simPages->AddPage( m_pgAC, _("AC"), false ); - m_pgSP = new wxPanel( m_simPages, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); - wxBoxSizer* bSizer31; - bSizer31 = new wxBoxSizer( wxVERTICAL ); - - wxString m_spScaleChoices[] = { _("Decade"), _("Octave"), _("Linear") }; - int m_spScaleNChoices = sizeof( m_spScaleChoices ) / sizeof( wxString ); - m_spScale = new wxRadioBox( m_pgSP, wxID_ANY, _("Frequency scale"), wxDefaultPosition, wxDefaultSize, m_spScaleNChoices, m_spScaleChoices, 1, wxRA_SPECIFY_COLS ); - m_spScale->SetSelection( 0 ); - m_spScale->Hide(); - - bSizer31->Add( m_spScale, 0, wxALL|wxEXPAND, 5 ); - - wxFlexGridSizer* fgSizer12; - fgSizer12 = new wxFlexGridSizer( 0, 3, 5, 0 ); - fgSizer12->SetFlexibleDirection( wxHORIZONTAL ); - fgSizer12->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); - - m_staticText12 = new wxStaticText( m_pgSP, wxID_ANY, _("Number of points per decade:"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText12->Wrap( -1 ); - fgSizer12->Add( m_staticText12, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); - - m_spPointsNumber = new wxTextCtrl( m_pgSP, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - fgSizer12->Add( m_spPointsNumber, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 ); - - - fgSizer12->Add( 0, 0, 1, wxEXPAND, 5 ); - - m_staticText22 = new wxStaticText( m_pgSP, wxID_ANY, _("Start frequency:"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText22->Wrap( -1 ); - fgSizer12->Add( m_staticText22, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); - - m_spFreqStart = new wxTextCtrl( m_pgSP, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_spFreqStart->SetMinSize( wxSize( 100,-1 ) ); - - fgSizer12->Add( m_spFreqStart, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 ); - - m_staticText191 = new wxStaticText( m_pgSP, wxID_ANY, _("Hz"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText191->Wrap( -1 ); - fgSizer12->Add( m_staticText191, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT, 5 ); - - m_staticText32 = new wxStaticText( m_pgSP, wxID_ANY, _("Stop frequency:"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText32->Wrap( -1 ); - fgSizer12->Add( m_staticText32, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); - - m_spFreqStop = new wxTextCtrl( m_pgSP, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - fgSizer12->Add( m_spFreqStop, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 ); - - m_staticText1101 = new wxStaticText( m_pgSP, wxID_ANY, _("Hz"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText1101->Wrap( -1 ); - fgSizer12->Add( m_staticText1101, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT, 5 ); - - m_spDoNoise = new wxCheckBox( m_pgSP, wxID_ANY, _("Compute noise current correlation matrix"), wxDefaultPosition, wxDefaultSize, 0 ); - fgSizer12->Add( m_spDoNoise, 0, wxALL, 5 ); - - - bSizer31->Add( fgSizer12, 0, wxEXPAND|wxALL, 5 ); - - - m_pgSP->SetSizer( bSizer31 ); - m_pgSP->Layout(); - bSizer31->Fit( m_pgSP ); - m_simPages->AddPage( m_pgSP, _("S-params"), false ); + m_simPages->AddPage( m_pgAC, _("a page"), false ); m_pgDC = new wxPanel( m_simPages, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); wxBoxSizer* bSizer82; bSizer82 = new wxBoxSizer( wxVERTICAL ); @@ -267,10 +220,126 @@ DIALOG_SIM_COMMAND_BASE::DIALOG_SIM_COMMAND_BASE( wxWindow* parent, wxWindowID i m_pgDC->SetSizer( bSizer82 ); m_pgDC->Layout(); bSizer82->Fit( m_pgDC ); - m_simPages->AddPage( m_pgDC, _("DC Transfer"), false ); - m_pgDistortion = new wxPanel( m_simPages, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); - m_simPages->AddPage( m_pgDistortion, _("Distortion"), false ); - m_pgNoise = new wxPanel( m_simPages, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + m_simPages->AddPage( m_pgDC, _("a page"), false ); + m_pgOP = new wxPanel( m_simPages, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + wxBoxSizer* bSizer8; + bSizer8 = new wxBoxSizer( wxVERTICAL ); + + + m_pgOP->SetSizer( bSizer8 ); + m_pgOP->Layout(); + bSizer8->Fit( m_pgOP ); + m_simPages->AddPage( m_pgOP, _("a page"), false ); + m_pgTRAN = new wxPanel( m_simPages, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + wxBoxSizer* bSizer81; + bSizer81 = new wxBoxSizer( wxVERTICAL ); + + wxGridBagSizer* gbSizer2; + gbSizer2 = new wxGridBagSizer( 4, 0 ); + gbSizer2->SetFlexibleDirection( wxBOTH ); + gbSizer2->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); + gbSizer2->SetEmptyCellSize( wxSize( -1,8 ) ); + + m_timeLabel = new wxStaticText( m_pgTRAN, wxID_ANY, _("Time step:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_timeLabel->Wrap( -1 ); + gbSizer2->Add( m_timeLabel, wxGBPosition( 0, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_transStep = new wxTextCtrl( m_pgTRAN, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_transStep->SetMinSize( wxSize( 100,-1 ) ); + + gbSizer2->Add( m_transStep, wxGBPosition( 0, 1 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + + m_timeUnits = new wxStaticText( m_pgTRAN, wxID_ANY, _("seconds"), wxDefaultPosition, wxDefaultSize, 0 ); + m_timeUnits->Wrap( -1 ); + gbSizer2->Add( m_timeUnits, wxGBPosition( 0, 2 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_transFinalLabel = new wxStaticText( m_pgTRAN, wxID_ANY, _("Final time:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_transFinalLabel->Wrap( -1 ); + gbSizer2->Add( m_transFinalLabel, wxGBPosition( 1, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_transFinal = new wxTextCtrl( m_pgTRAN, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + gbSizer2->Add( m_transFinal, wxGBPosition( 1, 1 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + + m_transFinalUnits = new wxStaticText( m_pgTRAN, wxID_ANY, _("seconds"), wxDefaultPosition, wxDefaultSize, 0 ); + m_transFinalUnits->Wrap( -1 ); + gbSizer2->Add( m_transFinalUnits, wxGBPosition( 1, 2 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_transInitialLabel = new wxStaticText( m_pgTRAN, wxID_ANY, _("Initial time:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_transInitialLabel->Wrap( -1 ); + gbSizer2->Add( m_transInitialLabel, wxGBPosition( 2, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_transInitial = new wxTextCtrl( m_pgTRAN, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + gbSizer2->Add( m_transInitial, wxGBPosition( 2, 1 ), wxGBSpan( 1, 1 ), wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + m_transInitialUnits = new wxStaticText( m_pgTRAN, wxID_ANY, _("seconds"), wxDefaultPosition, wxDefaultSize, 0 ); + m_transInitialUnits->Wrap( -1 ); + gbSizer2->Add( m_transInitialUnits, wxGBPosition( 2, 2 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_transInitialHelp = new wxStaticText( m_pgTRAN, wxID_ANY, _("(optional; default 0)"), wxDefaultPosition, wxDefaultSize, 0 ); + m_transInitialHelp->Wrap( -1 ); + gbSizer2->Add( m_transInitialHelp, wxGBPosition( 2, 3 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_maxStepLabel = new wxStaticText( m_pgTRAN, wxID_ANY, _("Max time step:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_maxStepLabel->Wrap( -1 ); + gbSizer2->Add( m_maxStepLabel, wxGBPosition( 3, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_transMaxStep = new wxTextCtrl( m_pgTRAN, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + gbSizer2->Add( m_transMaxStep, wxGBPosition( 3, 1 ), wxGBSpan( 1, 1 ), wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + m_transMaxStepUnit = new wxStaticText( m_pgTRAN, wxID_ANY, _("seconds"), wxDefaultPosition, wxDefaultSize, 0 ); + m_transMaxStepUnit->Wrap( -1 ); + gbSizer2->Add( m_transMaxStepUnit, wxGBPosition( 3, 2 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_transMaxHelp = new wxStaticText( m_pgTRAN, wxID_ANY, _("(optional; default min{tstep, (tstop-tstart)/50})"), wxDefaultPosition, wxDefaultSize, 0 ); + m_transMaxHelp->Wrap( -1 ); + gbSizer2->Add( m_transMaxHelp, wxGBPosition( 3, 3 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_useInitialConditions = new wxCheckBox( m_pgTRAN, wxID_ANY, _("Use initial conditions"), wxDefaultPosition, wxDefaultSize, 0 ); + gbSizer2->Add( m_useInitialConditions, wxGBPosition( 5, 0 ), wxGBSpan( 1, 3 ), wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + + bSizer81->Add( gbSizer2, 1, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 ); + + + m_pgTRAN->SetSizer( bSizer81 ); + m_pgTRAN->Layout(); + bSizer81->Fit( m_pgTRAN ); + m_simPages->AddPage( m_pgTRAN, _("a page"), false ); + m_pgFFT = new wxPanel( m_simPages, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + wxBoxSizer* bSizer151; + bSizer151 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer14; + bSizer14 = new wxBoxSizer( wxVERTICAL ); + + m_signalsLabel = new wxStaticText( m_pgFFT, wxID_ANY, _("Input signals:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_signalsLabel->Wrap( -1 ); + bSizer14->Add( m_signalsLabel, 0, wxBOTTOM|wxLEFT, 5 ); + + m_inputSignalsFilter = new wxSearchCtrl( m_pgFFT, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + #ifndef __WXMAC__ + m_inputSignalsFilter->ShowSearchButton( true ); + #endif + m_inputSignalsFilter->ShowCancelButton( true ); + bSizer14->Add( m_inputSignalsFilter, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 ); + + wxArrayString m_inputSignalsListChoices; + m_inputSignalsList = new wxCheckListBox( m_pgFFT, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_inputSignalsListChoices, 0 ); + bSizer14->Add( m_inputSignalsList, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + + m_linearize = new wxCheckBox( m_pgFFT, wxID_ANY, _("Linearize inputs before performing FFT"), wxDefaultPosition, wxDefaultSize, 0 ); + m_linearize->SetValue(true); + bSizer14->Add( m_linearize, 0, wxALL, 5 ); + + + bSizer151->Add( bSizer14, 1, wxTOP|wxRIGHT|wxLEFT, 5 ); + + + m_pgFFT->SetSizer( bSizer151 ); + m_pgFFT->Layout(); + bSizer151->Fit( m_pgFFT ); + m_simPages->AddPage( m_pgFFT, _("a page"), false ); + m_pgNOISE = new wxPanel( m_simPages, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); wxBoxSizer* bSizer15; bSizer15 = new wxBoxSizer( wxVERTICAL ); @@ -279,37 +348,37 @@ DIALOG_SIM_COMMAND_BASE::DIALOG_SIM_COMMAND_BASE( wxWindow* parent, wxWindowID i fgSizer7->SetFlexibleDirection( wxBOTH ); fgSizer7->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); - m_staticText14 = new wxStaticText( m_pgNoise, wxID_ANY, _("Measured node:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText14 = new wxStaticText( m_pgNOISE, wxID_ANY, _("Measured node:"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText14->Wrap( -1 ); fgSizer7->Add( m_staticText14, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); wxArrayString m_noiseMeasChoices; - m_noiseMeas = new wxChoice( m_pgNoise, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_noiseMeasChoices, 0 ); + m_noiseMeas = new wxChoice( m_pgNOISE, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_noiseMeasChoices, 0 ); m_noiseMeas->SetSelection( 0 ); fgSizer7->Add( m_noiseMeas, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT|wxEXPAND, 5 ); fgSizer7->Add( 0, 0, 1, wxEXPAND, 5 ); - m_staticText15 = new wxStaticText( m_pgNoise, wxID_ANY, _("Reference node:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText15 = new wxStaticText( m_pgNOISE, wxID_ANY, _("Reference node:"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText15->Wrap( -1 ); fgSizer7->Add( m_staticText15, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); wxArrayString m_noiseRefChoices; - m_noiseRef = new wxChoice( m_pgNoise, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_noiseRefChoices, 0 ); + m_noiseRef = new wxChoice( m_pgNOISE, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_noiseRefChoices, 0 ); m_noiseRef->SetSelection( 0 ); fgSizer7->Add( m_noiseRef, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT|wxEXPAND, 5 ); - m_staticText23 = new wxStaticText( m_pgNoise, wxID_ANY, _("(optional; default GND)"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText23 = new wxStaticText( m_pgNOISE, wxID_ANY, _("(optional; default GND)"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText23->Wrap( -1 ); fgSizer7->Add( m_staticText23, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - m_staticText16 = new wxStaticText( m_pgNoise, wxID_ANY, _("Noise source:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText16 = new wxStaticText( m_pgNOISE, wxID_ANY, _("Noise source:"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText16->Wrap( -1 ); fgSizer7->Add( m_staticText16, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); wxArrayString m_noiseSrcChoices; - m_noiseSrc = new wxChoice( m_pgNoise, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_noiseSrcChoices, 0 ); + m_noiseSrc = new wxChoice( m_pgNOISE, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_noiseSrcChoices, 0 ); m_noiseSrc->SetSelection( 0 ); fgSizer7->Add( m_noiseSrc, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT|wxEXPAND, 5 ); @@ -324,7 +393,7 @@ DIALOG_SIM_COMMAND_BASE::DIALOG_SIM_COMMAND_BASE( wxWindow* parent, wxWindowID i wxString m_noiseScaleChoices[] = { _("Decade"), _("Octave"), _("Linear") }; int m_noiseScaleNChoices = sizeof( m_noiseScaleChoices ) / sizeof( wxString ); - m_noiseScale = new wxRadioBox( m_pgNoise, wxID_ANY, _("Frequency scale"), wxDefaultPosition, wxDefaultSize, m_noiseScaleNChoices, m_noiseScaleChoices, 1, wxRA_SPECIFY_COLS ); + m_noiseScale = new wxRadioBox( m_pgNOISE, wxID_ANY, _("Frequency scale"), wxDefaultPosition, wxDefaultSize, m_noiseScaleNChoices, m_noiseScaleChoices, 1, wxRA_SPECIFY_COLS ); m_noiseScale->SetSelection( 0 ); m_noiseScale->Hide(); @@ -335,11 +404,11 @@ DIALOG_SIM_COMMAND_BASE::DIALOG_SIM_COMMAND_BASE( wxWindow* parent, wxWindowID i fgSizer11->SetFlexibleDirection( wxBOTH ); fgSizer11->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); - m_staticText11 = new wxStaticText( m_pgNoise, wxID_ANY, _("Number of points per decade:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText11 = new wxStaticText( m_pgNOISE, wxID_ANY, _("Number of points per decade:"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText11->Wrap( -1 ); fgSizer11->Add( m_staticText11, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT, 5 ); - m_noisePointsNumber = new wxTextCtrl( m_pgNoise, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_noisePointsNumber = new wxTextCtrl( m_pgNOISE, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); m_noisePointsNumber->SetMinSize( wxSize( 80,-1 ) ); fgSizer11->Add( m_noisePointsNumber, 1, wxALIGN_CENTER_VERTICAL|wxTOP, 5 ); @@ -347,29 +416,29 @@ DIALOG_SIM_COMMAND_BASE::DIALOG_SIM_COMMAND_BASE( wxWindow* parent, wxWindowID i fgSizer11->Add( 0, 0, 1, wxEXPAND, 5 ); - m_staticText21 = new wxStaticText( m_pgNoise, wxID_ANY, _("Start frequency:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText21 = new wxStaticText( m_pgNOISE, wxID_ANY, _("Start frequency:"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText21->Wrap( -1 ); fgSizer11->Add( m_staticText21, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - m_noiseFreqStart = new wxTextCtrl( m_pgNoise, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_noiseFreqStart = new wxTextCtrl( m_pgNOISE, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); m_noiseFreqStart->SetMinSize( wxSize( 80,-1 ) ); fgSizer11->Add( m_noiseFreqStart, 1, wxALIGN_CENTER_VERTICAL, 5 ); - m_noiseFreqStartUnits = new wxStaticText( m_pgNoise, wxID_ANY, _("Hz"), wxDefaultPosition, wxDefaultSize, 0 ); + m_noiseFreqStartUnits = new wxStaticText( m_pgNOISE, wxID_ANY, _("Hz"), wxDefaultPosition, wxDefaultSize, 0 ); m_noiseFreqStartUnits->Wrap( -1 ); fgSizer11->Add( m_noiseFreqStartUnits, 0, wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 ); - m_staticText31 = new wxStaticText( m_pgNoise, wxID_ANY, _("Stop frequency:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText31 = new wxStaticText( m_pgNOISE, wxID_ANY, _("Stop frequency:"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText31->Wrap( -1 ); fgSizer11->Add( m_staticText31, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); - m_noiseFreqStop = new wxTextCtrl( m_pgNoise, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_noiseFreqStop = new wxTextCtrl( m_pgNOISE, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); m_noiseFreqStop->SetMinSize( wxSize( 80,-1 ) ); fgSizer11->Add( m_noiseFreqStop, 1, wxALIGN_CENTER_VERTICAL|wxBOTTOM, 5 ); - m_noiseFreqStopUnits = new wxStaticText( m_pgNoise, wxID_ANY, _("Hz"), wxDefaultPosition, wxDefaultSize, 0 ); + m_noiseFreqStopUnits = new wxStaticText( m_pgNOISE, wxID_ANY, _("Hz"), wxDefaultPosition, wxDefaultSize, 0 ); m_noiseFreqStopUnits->Wrap( -1 ); fgSizer11->Add( m_noiseFreqStopUnits, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); @@ -379,120 +448,77 @@ DIALOG_SIM_COMMAND_BASE::DIALOG_SIM_COMMAND_BASE( wxWindow* parent, wxWindowID i bSizer15->Add( bSizer10, 0, wxEXPAND|wxTOP, 5 ); - m_saveAllNoise = new wxCheckBox( m_pgNoise, wxID_ANY, _("Save contributions from all noise generators"), wxDefaultPosition, wxDefaultSize, 0 ); + m_saveAllNoise = new wxCheckBox( m_pgNOISE, wxID_ANY, _("Save contributions from all noise generators"), wxDefaultPosition, wxDefaultSize, 0 ); + m_saveAllNoise->SetValue(true); bSizer15->Add( m_saveAllNoise, 0, wxALL, 10 ); - m_pgNoise->SetSizer( bSizer15 ); - m_pgNoise->Layout(); - bSizer15->Fit( m_pgNoise ); - m_simPages->AddPage( m_pgNoise, _("Noise"), false ); - m_pgOP = new wxPanel( m_simPages, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); - wxBoxSizer* bSizer8; - bSizer8 = new wxBoxSizer( wxVERTICAL ); + m_pgNOISE->SetSizer( bSizer15 ); + m_pgNOISE->Layout(); + bSizer15->Fit( m_pgNOISE ); + m_simPages->AddPage( m_pgNOISE, _("a page"), false ); + m_pgSP = new wxPanel( m_simPages, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + wxBoxSizer* bSizer31; + bSizer31 = new wxBoxSizer( wxVERTICAL ); + + wxString m_spScaleChoices[] = { _("Decade"), _("Octave"), _("Linear") }; + int m_spScaleNChoices = sizeof( m_spScaleChoices ) / sizeof( wxString ); + m_spScale = new wxRadioBox( m_pgSP, wxID_ANY, _("Frequency scale"), wxDefaultPosition, wxDefaultSize, m_spScaleNChoices, m_spScaleChoices, 1, wxRA_SPECIFY_COLS ); + m_spScale->SetSelection( 0 ); + m_spScale->Hide(); + + bSizer31->Add( m_spScale, 0, wxALL|wxEXPAND, 5 ); + + wxFlexGridSizer* fgSizer12; + fgSizer12 = new wxFlexGridSizer( 0, 3, 5, 0 ); + fgSizer12->SetFlexibleDirection( wxHORIZONTAL ); + fgSizer12->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); + + m_staticText12 = new wxStaticText( m_pgSP, wxID_ANY, _("Number of points per decade:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText12->Wrap( -1 ); + fgSizer12->Add( m_staticText12, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); + + m_spPointsNumber = new wxTextCtrl( m_pgSP, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + fgSizer12->Add( m_spPointsNumber, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 ); - bSizer8->Add( 0, 0, 1, wxEXPAND, 5 ); + fgSizer12->Add( 0, 0, 1, wxEXPAND, 5 ); - m_staticText13 = new wxStaticText( m_pgOP, wxID_ANY, _("This tab has no settings"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText13->Wrap( -1 ); - bSizer8->Add( m_staticText13, 0, wxALIGN_CENTER, 5 ); + m_staticText22 = new wxStaticText( m_pgSP, wxID_ANY, _("Start frequency:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText22->Wrap( -1 ); + fgSizer12->Add( m_staticText22, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); + + m_spFreqStart = new wxTextCtrl( m_pgSP, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_spFreqStart->SetMinSize( wxSize( 100,-1 ) ); + + fgSizer12->Add( m_spFreqStart, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 ); + + m_staticText191 = new wxStaticText( m_pgSP, wxID_ANY, _("Hz"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText191->Wrap( -1 ); + fgSizer12->Add( m_staticText191, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT, 5 ); + + m_staticText32 = new wxStaticText( m_pgSP, wxID_ANY, _("Stop frequency:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText32->Wrap( -1 ); + fgSizer12->Add( m_staticText32, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); + + m_spFreqStop = new wxTextCtrl( m_pgSP, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + fgSizer12->Add( m_spFreqStop, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 ); + + m_staticText1101 = new wxStaticText( m_pgSP, wxID_ANY, _("Hz"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText1101->Wrap( -1 ); + fgSizer12->Add( m_staticText1101, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT, 5 ); + + m_spDoNoise = new wxCheckBox( m_pgSP, wxID_ANY, _("Compute noise current correlation matrix"), wxDefaultPosition, wxDefaultSize, 0 ); + fgSizer12->Add( m_spDoNoise, 0, wxALL, 5 ); - bSizer8->Add( 0, 0, 1, wxEXPAND, 5 ); + bSizer31->Add( fgSizer12, 0, wxEXPAND|wxALL, 5 ); - m_pgOP->SetSizer( bSizer8 ); - m_pgOP->Layout(); - bSizer8->Fit( m_pgOP ); - m_simPages->AddPage( m_pgOP, _("Operating Point"), false ); - m_pgPoleZero = new wxPanel( m_simPages, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); - m_pgPoleZero->Hide(); - - m_simPages->AddPage( m_pgPoleZero, _("Pole-Zero"), false ); - m_pgSensitivity = new wxPanel( m_simPages, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); - m_pgSensitivity->Hide(); - - m_simPages->AddPage( m_pgSensitivity, _("Sensitivity"), false ); - m_pgTransferFunction = new wxPanel( m_simPages, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); - m_pgTransferFunction->Hide(); - - m_simPages->AddPage( m_pgTransferFunction, _("Transfer Function"), false ); - m_pgTransient = new wxPanel( m_simPages, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); - wxBoxSizer* bSizer81; - bSizer81 = new wxBoxSizer( wxVERTICAL ); - - wxGridBagSizer* gbSizer2; - gbSizer2 = new wxGridBagSizer( 4, 0 ); - gbSizer2->SetFlexibleDirection( wxBOTH ); - gbSizer2->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); - gbSizer2->SetEmptyCellSize( wxSize( -1,8 ) ); - - m_timeLabel = new wxStaticText( m_pgTransient, wxID_ANY, _("Time step:"), wxDefaultPosition, wxDefaultSize, 0 ); - m_timeLabel->Wrap( -1 ); - gbSizer2->Add( m_timeLabel, wxGBPosition( 0, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_transStep = new wxTextCtrl( m_pgTransient, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_transStep->SetMinSize( wxSize( 100,-1 ) ); - - gbSizer2->Add( m_transStep, wxGBPosition( 0, 1 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - m_timeUnits = new wxStaticText( m_pgTransient, wxID_ANY, _("seconds"), wxDefaultPosition, wxDefaultSize, 0 ); - m_timeUnits->Wrap( -1 ); - gbSizer2->Add( m_timeUnits, wxGBPosition( 0, 2 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_transFinalLabel = new wxStaticText( m_pgTransient, wxID_ANY, _("Final time:"), wxDefaultPosition, wxDefaultSize, 0 ); - m_transFinalLabel->Wrap( -1 ); - gbSizer2->Add( m_transFinalLabel, wxGBPosition( 1, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_transFinal = new wxTextCtrl( m_pgTransient, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - gbSizer2->Add( m_transFinal, wxGBPosition( 1, 1 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - m_transFinalUnits = new wxStaticText( m_pgTransient, wxID_ANY, _("seconds"), wxDefaultPosition, wxDefaultSize, 0 ); - m_transFinalUnits->Wrap( -1 ); - gbSizer2->Add( m_transFinalUnits, wxGBPosition( 1, 2 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_transInitialLabel = new wxStaticText( m_pgTransient, wxID_ANY, _("Initial time:"), wxDefaultPosition, wxDefaultSize, 0 ); - m_transInitialLabel->Wrap( -1 ); - gbSizer2->Add( m_transInitialLabel, wxGBPosition( 2, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_transInitial = new wxTextCtrl( m_pgTransient, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - gbSizer2->Add( m_transInitial, wxGBPosition( 2, 1 ), wxGBSpan( 1, 1 ), wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); - - m_transInitialUnits = new wxStaticText( m_pgTransient, wxID_ANY, _("seconds"), wxDefaultPosition, wxDefaultSize, 0 ); - m_transInitialUnits->Wrap( -1 ); - gbSizer2->Add( m_transInitialUnits, wxGBPosition( 2, 2 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_transInitialHelp = new wxStaticText( m_pgTransient, wxID_ANY, _("(optional; default 0)"), wxDefaultPosition, wxDefaultSize, 0 ); - m_transInitialHelp->Wrap( -1 ); - gbSizer2->Add( m_transInitialHelp, wxGBPosition( 2, 3 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_maxStepLabel = new wxStaticText( m_pgTransient, wxID_ANY, _("Max time step:"), wxDefaultPosition, wxDefaultSize, 0 ); - m_maxStepLabel->Wrap( -1 ); - gbSizer2->Add( m_maxStepLabel, wxGBPosition( 3, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_transMaxStep = new wxTextCtrl( m_pgTransient, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - gbSizer2->Add( m_transMaxStep, wxGBPosition( 3, 1 ), wxGBSpan( 1, 1 ), wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); - - m_transMaxStepUnit = new wxStaticText( m_pgTransient, wxID_ANY, _("seconds"), wxDefaultPosition, wxDefaultSize, 0 ); - m_transMaxStepUnit->Wrap( -1 ); - gbSizer2->Add( m_transMaxStepUnit, wxGBPosition( 3, 2 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_transMaxHelp = new wxStaticText( m_pgTransient, wxID_ANY, _("(optional; default min{tstep, (tstop-tstart)/50})"), wxDefaultPosition, wxDefaultSize, 0 ); - m_transMaxHelp->Wrap( -1 ); - gbSizer2->Add( m_transMaxHelp, wxGBPosition( 3, 3 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_useInitialConditions = new wxCheckBox( m_pgTransient, wxID_ANY, _("Use initial conditions"), wxDefaultPosition, wxDefaultSize, 0 ); - gbSizer2->Add( m_useInitialConditions, wxGBPosition( 5, 0 ), wxGBSpan( 1, 3 ), wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - - bSizer81->Add( gbSizer2, 1, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 ); - - - m_pgTransient->SetSizer( bSizer81 ); - m_pgTransient->Layout(); - bSizer81->Fit( m_pgTransient ); - m_simPages->AddPage( m_pgTransient, _("Transient"), true ); + m_pgSP->SetSizer( bSizer31 ); + m_pgSP->Layout(); + bSizer31->Fit( m_pgSP ); + m_simPages->AddPage( m_pgSP, _("a page"), false ); m_pgCustom = new wxPanel( m_simPages, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); wxBoxSizer* bSizer2; bSizer2 = new wxBoxSizer( wxVERTICAL ); @@ -513,9 +539,9 @@ DIALOG_SIM_COMMAND_BASE::DIALOG_SIM_COMMAND_BASE( wxWindow* parent, wxWindowID i m_pgCustom->SetSizer( bSizer2 ); m_pgCustom->Layout(); bSizer2->Fit( m_pgCustom ); - m_simPages->AddPage( m_pgCustom, _("Custom"), false ); + m_simPages->AddPage( m_pgCustom, _("a page"), false ); - bSizer1->Add( m_simPages, 1, wxALL|wxEXPAND, 10 ); + bSizer1->Add( m_simPages, 1, wxEXPAND | wxALL, 5 ); wxBoxSizer* bSizer88; bSizer88 = new wxBoxSizer( wxVERTICAL ); @@ -570,10 +596,13 @@ DIALOG_SIM_COMMAND_BASE::DIALOG_SIM_COMMAND_BASE( wxWindow* parent, wxWindowID i // Connect Events this->Connect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( DIALOG_SIM_COMMAND_BASE::onInitDlg ) ); + m_commandType->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_SIM_COMMAND_BASE::OnCommandType ), NULL, this ); m_dcEnable2->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_SIM_COMMAND_BASE::onDCEnableSecondSource ), NULL, this ); m_dcSourceType1->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_SIM_COMMAND_BASE::onDCSource1Selected ), NULL, this ); m_dcSourceType2->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_SIM_COMMAND_BASE::onDCSource2Selected ), NULL, this ); m_swapDCSources->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SIM_COMMAND_BASE::onSwapDCSources ), NULL, this ); + m_inputSignalsFilter->Connect( wxEVT_MOTION, wxMouseEventHandler( DIALOG_SIM_COMMAND_BASE::OnFilterMouseMoved ), NULL, this ); + m_inputSignalsFilter->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_SIM_COMMAND_BASE::OnFilterText ), NULL, this ); m_loadDirectives->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SIM_COMMAND_BASE::onLoadDirectives ), NULL, this ); } @@ -581,10 +610,13 @@ DIALOG_SIM_COMMAND_BASE::~DIALOG_SIM_COMMAND_BASE() { // Disconnect Events this->Disconnect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( DIALOG_SIM_COMMAND_BASE::onInitDlg ) ); + m_commandType->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_SIM_COMMAND_BASE::OnCommandType ), NULL, this ); m_dcEnable2->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_SIM_COMMAND_BASE::onDCEnableSecondSource ), NULL, this ); m_dcSourceType1->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_SIM_COMMAND_BASE::onDCSource1Selected ), NULL, this ); m_dcSourceType2->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_SIM_COMMAND_BASE::onDCSource2Selected ), NULL, this ); m_swapDCSources->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SIM_COMMAND_BASE::onSwapDCSources ), NULL, this ); + m_inputSignalsFilter->Disconnect( wxEVT_MOTION, wxMouseEventHandler( DIALOG_SIM_COMMAND_BASE::OnFilterMouseMoved ), NULL, this ); + m_inputSignalsFilter->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_SIM_COMMAND_BASE::OnFilterText ), NULL, this ); m_loadDirectives->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SIM_COMMAND_BASE::onLoadDirectives ), NULL, this ); } diff --git a/eeschema/dialogs/dialog_sim_command_base.fbp b/eeschema/dialogs/dialog_sim_command_base.fbp index c1544814e6..a828e01bb1 100644 --- a/eeschema/dialogs/dialog_sim_command_base.fbp +++ b/eeschema/dialogs/dialog_sim_command_base.fbp @@ -64,9 +64,146 @@ none 10 - wxALL|wxEXPAND + wxEXPAND|wxTOP|wxRIGHT|wxLEFT + 0 + + + m_commandTypeSizer + wxHORIZONTAL + protected + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Simulation type: + 0 + + 0 + + + 0 + + 1 + m_commandTypeLabel + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + "AC" "DC" "OP" "TRAN" "FFT" "NOISE" "SP" "Custom" + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_commandType + 1 + + + protected + 1 + + Resizable + 0 + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnCommandType + + + + + + 5 + wxEXPAND | wxALL 1 - + 1 1 1 @@ -77,7 +214,6 @@ - 1 0 @@ -100,7 +236,7 @@ 0 - -1,-1 + 1 m_simPages 1 @@ -112,18 +248,16 @@ Resizable 1 - - + ; ; forward_declare 0 - - - AC + + a page 0 - + 1 1 1 @@ -174,7 +308,7 @@ wxTAB_TRAVERSAL - + bSizer3 wxVERTICAL @@ -245,11 +379,11 @@ - + 5 wxEXPAND|wxALL 0 - + 3 wxHORIZONTAL @@ -773,729 +907,10 @@ - - - S-params + + a page 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - - 0 - - - 0 - - 1 - m_pgSP - 1 - - - protected - 1 - - Resizable - 1 - - - 0 - - - - wxTAB_TRAVERSAL - - - bSizer31 - wxVERTICAL - none - - 5 - wxALL|wxEXPAND - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - "Decade" "Octave" "Linear" - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 1 - wxID_ANY - Frequency scale - 1 - - 0 - - - 0 - - 1 - m_spScale - 1 - - - protected - 1 - - Resizable - 0 - 1 - - wxRA_SPECIFY_COLS - - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - 5 - wxEXPAND|wxALL - 0 - - 3 - wxHORIZONTAL - - - 0 - - fgSizer12 - wxFLEX_GROWMODE_SPECIFIED - none - 0 - 5 - - 5 - wxALIGN_CENTER_VERTICAL|wxLEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Number of points per decade: - 0 - - 0 - - - 0 - - 1 - m_staticText12 - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - - - -1 - - - - 5 - wxEXPAND|wxRIGHT|wxLEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - - 0 - - - - 0 - - 1 - m_spPointsNumber - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - wxFILTER_NUMERIC - wxTextValidator - - - - - - - - - 5 - wxEXPAND - 1 - - 0 - protected - 0 - - - - 5 - wxALIGN_CENTER_VERTICAL|wxLEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Start frequency: - 0 - - 0 - - - 0 - - 1 - m_staticText22 - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - - - -1 - - - - 5 - wxEXPAND|wxRIGHT|wxLEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - - 0 - - - - 0 - 100,-1 - 1 - m_spFreqStart - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - wxFILTER_NUMERIC - wxTextValidator - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Hz - 0 - - 0 - - - 0 - - 1 - m_staticText191 - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - - - -1 - - - - 5 - wxALIGN_CENTER_VERTICAL|wxLEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Stop frequency: - 0 - - 0 - - - 0 - - 1 - m_staticText32 - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - - - -1 - - - - 5 - wxEXPAND|wxRIGHT|wxLEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - - 0 - - - - 0 - - 1 - m_spFreqStop - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - wxFILTER_NUMERIC - wxTextValidator - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Hz - 0 - - 0 - - - 0 - - 1 - m_staticText1101 - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - - - -1 - - - - 5 - wxALL - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Compute noise current correlation matrix - - 0 - - - 0 - - 1 - m_spDoNoise - 1 - - - protected - 1 - - Resizable - 1 - - - ; ; forward_declare - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - - - - - - - DC Transfer - 0 - + 1 1 1 @@ -1546,16 +961,16 @@ wxTAB_TRAVERSAL - + bSizer82 wxVERTICAL none - + 5 wxALL 0 - + wxBOTH @@ -1898,14 +1313,14 @@ -1 - + 5 1 1 wxBOTTOM|wxRIGHT|wxLEFT 0 1 - + 1 1 1 @@ -3076,21 +2491,21 @@ - + 5 wxEXPAND 0 - + 10 protected 0 - + 10 wxALL 0 - + 1 1 1 @@ -3163,11 +2578,10 @@ - - - Distortion + + a page 0 - + 1 1 1 @@ -3202,7 +2616,7 @@ 0 1 - m_pgDistortion + m_pgOP 1 @@ -3218,13 +2632,18 @@ wxTAB_TRAVERSAL + + + bSizer8 + wxVERTICAL + none + - - - Noise + + a page 0 - + 1 1 1 @@ -3259,7 +2678,7 @@ 0 1 - m_pgNoise + m_pgTRAN 1 @@ -3275,16 +2694,1398 @@ wxTAB_TRAVERSAL - + + + bSizer81 + wxVERTICAL + none + + 5 + wxEXPAND|wxTOP|wxRIGHT|wxLEFT + 1 + + -1,8 + wxBOTH + + + 0 + -1,-1 + gbSizer2 + wxFLEX_GROWMODE_SPECIFIED + none + 4 + + 5 + 1 + 0 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 0 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Time step: + 0 + + 0 + + + 0 + + 1 + m_timeLabel + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + 5 + 1 + 1 + wxALIGN_CENTER_VERTICAL|wxEXPAND + 0 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + + 0 + 100,-1 + 1 + m_transStep + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NUMERIC + wxTextValidator + + + + + + + + + 5 + 1 + 2 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 0 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + seconds + 0 + + 0 + + + 0 + + 1 + m_timeUnits + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + 5 + 1 + 0 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 1 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Final time: + 0 + + 0 + + + 0 + + 1 + m_transFinalLabel + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + 5 + 1 + 1 + wxALIGN_CENTER_VERTICAL|wxEXPAND + 1 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + + 0 + + 1 + m_transFinal + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NUMERIC + wxTextValidator + + + + + + + + + 5 + 1 + 2 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 1 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + seconds + 0 + + 0 + + + 0 + + 1 + m_transFinalUnits + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + 5 + 1 + 0 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 2 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Initial time: + 0 + + 0 + + + 0 + + 1 + m_transInitialLabel + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + 5 + 1 + 1 + wxEXPAND|wxALIGN_CENTER_VERTICAL + 2 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + + 0 + + 1 + m_transInitial + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NUMERIC + wxTextValidator + + + + + + + + + 5 + 1 + 2 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 2 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + seconds + 0 + + 0 + + + 0 + + 1 + m_transInitialUnits + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + 5 + 1 + 3 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 2 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + (optional; default 0) + 0 + + 0 + + + 0 + + 1 + m_transInitialHelp + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + 5 + 1 + 0 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 3 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Max time step: + 0 + + 0 + + + 0 + + 1 + m_maxStepLabel + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + 1 + 1 + wxEXPAND|wxALIGN_CENTER_VERTICAL + 3 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + + 0 + + 1 + m_transMaxStep + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + 5 + 1 + 2 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 3 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + seconds + 0 + + 0 + + + 0 + + 1 + m_transMaxStepUnit + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + 1 + 3 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 3 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + (optional; default min{tstep, (tstop-tstart)/50}) + 0 + + 0 + + + 0 + + 1 + m_transMaxHelp + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + 3 + 0 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 5 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Use initial conditions + + 0 + + + 0 + + 1 + m_useInitialConditions + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + a page + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_pgFFT + 1 + + + protected + 1 + + Resizable + 1 + + ; ; forward_declare + 0 + + + + wxTAB_TRAVERSAL + + + bSizer151 + wxVERTICAL + none + + 5 + wxTOP|wxRIGHT|wxLEFT + 1 + + + bSizer14 + wxVERTICAL + none + + 5 + wxBOTTOM|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Input signals: + 0 + + 0 + + + 0 + + 1 + m_signalsLabel + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxEXPAND|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + 1 + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + -1,-1 + 1 + m_inputSignalsFilter + 1 + + + protected + 1 + + Resizable + 1 + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + OnFilterMouseMoved + OnFilterText + + + + 5 + wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_inputSignalsList + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Linearize inputs before performing FFT + + 0 + + + 0 + + 1 + m_linearize + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + a page + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_pgNOISE + 1 + + + protected + 1 + + Resizable + 1 + + + 0 + + + + wxTAB_TRAVERSAL + bSizer15 wxVERTICAL none - + 5 wxALL 0 - + 3 wxBOTH @@ -3357,11 +4158,11 @@ -1 - + 5 wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT|wxEXPAND 0 - + 1 1 1 @@ -3492,11 +4293,11 @@ -1 - + 5 wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT|wxEXPAND 0 - + 1 1 1 @@ -3678,11 +4479,11 @@ -1 - + 5 wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT|wxEXPAND 0 - + 1 1 1 @@ -3754,11 +4555,11 @@ - + 5 wxEXPAND|wxTOP 0 - + bSizer10 wxHORIZONTAL @@ -3829,11 +4630,11 @@ - + 5 wxALIGN_BOTTOM|wxTOP|wxLEFT 0 - + 3 wxBOTH @@ -3970,11 +4771,11 @@ - + 5 wxEXPAND 1 - + 0 protected 0 @@ -4105,11 +4906,11 @@ - + 5 wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL 0 - + 1 1 1 @@ -4291,11 +5092,11 @@ - + 5 wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxLEFT 0 - + 1 1 1 @@ -4356,11 +5157,11 @@ - + 10 wxALL 0 - + 1 1 1 @@ -4374,7 +5175,7 @@ 1 0 - 0 + 1 1 1 @@ -4423,11 +5224,10 @@ - - - Operating Point + + a page 0 - + 1 1 1 @@ -4462,7 +5262,7 @@ 0 1 - m_pgOP + m_pgSP 1 @@ -4478,26 +5278,16 @@ wxTAB_TRAVERSAL - + - bSizer8 + bSizer31 wxVERTICAL none 5 - wxEXPAND - 1 - - 0 - protected - 0 - - - - 5 - wxALIGN_CENTER + wxALL|wxEXPAND 0 - + 1 1 1 @@ -4511,6 +5301,7 @@ 1 0 + "Decade" "Octave" "Linear" 1 1 @@ -4523,10 +5314,10 @@ 1 0 - 0 + 1 wxID_ANY - This tab has no settings - 0 + Frequency scale + 1 0 @@ -4534,7 +5325,7 @@ 0 1 - m_staticText13 + m_spScale 1 @@ -4542,284 +5333,42 @@ 1 Resizable + 0 1 - + wxRA_SPECIFY_COLS 0 + + wxFILTER_NONE + wxDefaultValidator + - -1 5 - wxEXPAND - 1 - - 0 - protected - 0 - - - - - - - - Pole-Zero - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 1 - wxID_ANY - - 0 - - - 0 - - 1 - m_pgPoleZero - 1 - - - protected - 1 - - Resizable - 1 - - - 0 - - - - wxTAB_TRAVERSAL - - - - - Sensitivity - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 1 - wxID_ANY - - 0 - - - 0 - - 1 - m_pgSensitivity - 1 - - - protected - 1 - - Resizable - 1 - - - 0 - - - - wxTAB_TRAVERSAL - - - - - Transfer Function - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 1 - wxID_ANY - - 0 - - - 0 - - 1 - m_pgTransferFunction - 1 - - - protected - 1 - - Resizable - 1 - - - 0 - - - - wxTAB_TRAVERSAL - - - - - Transient - 1 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - - 0 - - - 0 - - 1 - m_pgTransient - 1 - - - protected - 1 - - Resizable - 1 - - - 0 - - - - wxTAB_TRAVERSAL - - - bSizer81 - wxVERTICAL - none - - 5 - wxEXPAND|wxTOP|wxRIGHT|wxLEFT - 1 - - -1,8 - wxBOTH + wxEXPAND|wxALL + 0 + + 3 + wxHORIZONTAL 0 - -1,-1 - gbSizer2 + + fgSizer12 wxFLEX_GROWMODE_SPECIFIED none - 4 - + 0 + 5 + 5 - 1 - 0 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 0 - 1 + wxALIGN_CENTER_VERTICAL|wxLEFT + 0 1 1 @@ -4848,7 +5397,7 @@ 0 0 wxID_ANY - Time step: + Number of points per decade: 0 0 @@ -4857,7 +5406,7 @@ 0 1 - m_timeLabel + m_staticText12 1 @@ -4877,13 +5426,145 @@ -1 - + 5 - 1 - 1 - wxALIGN_CENTER_VERTICAL|wxEXPAND - 0 - 1 + wxEXPAND|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + + 0 + + 1 + m_spPointsNumber + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NUMERIC + wxTextValidator + + + + + + + + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + 5 + wxALIGN_CENTER_VERTICAL|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Start frequency: + 0 + + 0 + + + 0 + + 1 + m_staticText22 + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + 5 + wxEXPAND|wxRIGHT|wxLEFT + 0 1 1 @@ -4920,7 +5601,7 @@ 0 100,-1 1 - m_transStep + m_spFreqStart 1 @@ -4944,13 +5625,10 @@ - + 5 - 1 - 2 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 0 - 1 + wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT + 0 1 1 @@ -4979,7 +5657,7 @@ 0 0 wxID_ANY - seconds + Hz 0 0 @@ -4988,7 +5666,7 @@ 0 1 - m_timeUnits + m_staticText191 1 @@ -5008,13 +5686,10 @@ -1 - + 5 - 1 - 0 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 1 - 1 + wxALIGN_CENTER_VERTICAL|wxLEFT + 0 1 1 @@ -5043,7 +5718,7 @@ 0 0 wxID_ANY - Final time: + Stop frequency: 0 0 @@ -5052,7 +5727,7 @@ 0 1 - m_transFinalLabel + m_staticText32 1 @@ -5072,13 +5747,10 @@ -1 - + 5 - 1 - 1 - wxALIGN_CENTER_VERTICAL|wxEXPAND - 1 - 1 + wxEXPAND|wxRIGHT|wxLEFT + 0 1 1 @@ -5115,7 +5787,7 @@ 0 1 - m_transFinal + m_spFreqStop 1 @@ -5139,13 +5811,10 @@ - + 5 - 1 - 2 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 1 - 1 + wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT + 0 1 1 @@ -5174,7 +5843,7 @@ 0 0 wxID_ANY - seconds + Hz 0 0 @@ -5183,7 +5852,7 @@ 0 1 - m_transFinalUnits + m_staticText1101 1 @@ -5203,532 +5872,11 @@ -1 - + 5 - 1 - 0 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 2 - 1 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Initial time: - 0 - - 0 - - - 0 - - 1 - m_transInitialLabel - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - - - -1 - - - - 5 - 1 - 1 - wxEXPAND|wxALIGN_CENTER_VERTICAL - 2 - 1 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - - 0 - - - - 0 - - 1 - m_transInitial - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - wxFILTER_NUMERIC - wxTextValidator - - - - - - - - - 5 - 1 - 2 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 2 - 1 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - seconds - 0 - - 0 - - - 0 - - 1 - m_transInitialUnits - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - - - -1 - - - - 5 - 1 - 3 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 2 - 1 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - (optional; default 0) - 0 - - 0 - - - 0 - - 1 - m_transInitialHelp - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - - - -1 - - - - 5 - 1 - 0 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 3 - 1 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Max time step: - 0 - - 0 - - - 0 - - 1 - m_maxStepLabel - 1 - - - protected - 1 - - Resizable - 1 - - - ; ; forward_declare - 0 - - - - - -1 - - - - 5 - 1 - 1 - wxEXPAND|wxALIGN_CENTER_VERTICAL - 3 - 1 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - - 0 - - - - 0 - - 1 - m_transMaxStep - 1 - - - protected - 1 - - Resizable - 1 - - - ; ; forward_declare - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - - 5 - 1 - 2 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 3 - 1 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - seconds - 0 - - 0 - - - 0 - - 1 - m_transMaxStepUnit - 1 - - - protected - 1 - - Resizable - 1 - - - ; ; forward_declare - 0 - - - - - -1 - - - - 5 - 1 - 3 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 3 - 1 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - (optional; default min{tstep, (tstop-tstart)/50}) - 0 - - 0 - - - 0 - - 1 - m_transMaxHelp - 1 - - - protected - 1 - - Resizable - 1 - - - ; ; forward_declare - 0 - - - - - -1 - - - - 5 - 3 - 0 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 5 - 1 - + wxALL + 0 + 1 1 1 @@ -5757,7 +5905,7 @@ 0 0 wxID_ANY - Use initial conditions + Compute noise current correlation matrix 0 @@ -5765,7 +5913,7 @@ 0 1 - m_useInitialConditions + m_spDoNoise 1 @@ -5793,11 +5941,10 @@ - - - Custom + + a page 0 - + 1 1 1 @@ -5848,7 +5995,7 @@ wxTAB_TRAVERSAL - + bSizer2 wxVERTICAL diff --git a/eeschema/dialogs/dialog_sim_command_base.h b/eeschema/dialogs/dialog_sim_command_base.h index 7f1d12e465..76fe44efc5 100644 --- a/eeschema/dialogs/dialog_sim_command_base.h +++ b/eeschema/dialogs/dialog_sim_command_base.h @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version 3.10.1-88b0f50) +// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b) // http://www.wxformbuilder.org/ // // PLEASE DO *NOT* EDIT THIS FILE! @@ -12,24 +12,26 @@ #include #include "dialog_shim.h" #include -#include +#include #include #include #include #include -#include +#include +#include +#include #include #include -#include #include +#include +#include +#include #include #include #include -#include -#include -#include -#include -#include +#include +#include +#include #include /////////////////////////////////////////////////////////////////////////// @@ -43,7 +45,10 @@ class DIALOG_SIM_COMMAND_BASE : public DIALOG_SHIM private: protected: - wxNotebook* m_simPages; + wxBoxSizer* m_commandTypeSizer; + wxStaticText* m_commandTypeLabel; + wxChoice* m_commandType; + wxSimplebook* m_simPages; wxPanel* m_pgAC; wxRadioBox* m_acScale; wxStaticText* m_staticText1; @@ -54,17 +59,6 @@ class DIALOG_SIM_COMMAND_BASE : public DIALOG_SHIM wxStaticText* m_staticText3; wxTextCtrl* m_acFreqStop; wxStaticText* m_staticText110; - wxPanel* m_pgSP; - wxRadioBox* m_spScale; - wxStaticText* m_staticText12; - wxTextCtrl* m_spPointsNumber; - wxStaticText* m_staticText22; - wxTextCtrl* m_spFreqStart; - wxStaticText* m_staticText191; - wxStaticText* m_staticText32; - wxTextCtrl* m_spFreqStop; - wxStaticText* m_staticText1101; - wxCheckBox* m_spDoNoise; wxPanel* m_pgDC; wxCheckBox* m_dcEnable2; wxChoice* m_dcSourceType1; @@ -90,8 +84,29 @@ class DIALOG_SIM_COMMAND_BASE : public DIALOG_SHIM wxTextCtrl* m_dcIncr2; wxStaticText* m_src2DCStepUnit; wxButton* m_swapDCSources; - wxPanel* m_pgDistortion; - wxPanel* m_pgNoise; + wxPanel* m_pgOP; + wxPanel* m_pgTRAN; + wxStaticText* m_timeLabel; + wxTextCtrl* m_transStep; + wxStaticText* m_timeUnits; + wxStaticText* m_transFinalLabel; + wxTextCtrl* m_transFinal; + wxStaticText* m_transFinalUnits; + wxStaticText* m_transInitialLabel; + wxTextCtrl* m_transInitial; + wxStaticText* m_transInitialUnits; + wxStaticText* m_transInitialHelp; + wxStaticText* m_maxStepLabel; + wxTextCtrl* m_transMaxStep; + wxStaticText* m_transMaxStepUnit; + wxStaticText* m_transMaxHelp; + wxCheckBox* m_useInitialConditions; + wxPanel* m_pgFFT; + wxStaticText* m_signalsLabel; + wxSearchCtrl* m_inputSignalsFilter; + wxCheckListBox* m_inputSignalsList; + wxCheckBox* m_linearize; + wxPanel* m_pgNOISE; wxStaticText* m_staticText14; wxChoice* m_noiseMeas; wxStaticText* m_staticText15; @@ -109,27 +124,17 @@ class DIALOG_SIM_COMMAND_BASE : public DIALOG_SHIM wxTextCtrl* m_noiseFreqStop; wxStaticText* m_noiseFreqStopUnits; wxCheckBox* m_saveAllNoise; - wxPanel* m_pgOP; - wxStaticText* m_staticText13; - wxPanel* m_pgPoleZero; - wxPanel* m_pgSensitivity; - wxPanel* m_pgTransferFunction; - wxPanel* m_pgTransient; - wxStaticText* m_timeLabel; - wxTextCtrl* m_transStep; - wxStaticText* m_timeUnits; - wxStaticText* m_transFinalLabel; - wxTextCtrl* m_transFinal; - wxStaticText* m_transFinalUnits; - wxStaticText* m_transInitialLabel; - wxTextCtrl* m_transInitial; - wxStaticText* m_transInitialUnits; - wxStaticText* m_transInitialHelp; - wxStaticText* m_maxStepLabel; - wxTextCtrl* m_transMaxStep; - wxStaticText* m_transMaxStepUnit; - wxStaticText* m_transMaxHelp; - wxCheckBox* m_useInitialConditions; + wxPanel* m_pgSP; + wxRadioBox* m_spScale; + wxStaticText* m_staticText12; + wxTextCtrl* m_spPointsNumber; + wxStaticText* m_staticText22; + wxTextCtrl* m_spFreqStart; + wxStaticText* m_staticText191; + wxStaticText* m_staticText32; + wxTextCtrl* m_spFreqStop; + wxStaticText* m_staticText1101; + wxCheckBox* m_spDoNoise; wxPanel* m_pgCustom; wxStaticText* m_staticText18; wxTextCtrl* m_customTxt; @@ -146,10 +151,13 @@ class DIALOG_SIM_COMMAND_BASE : public DIALOG_SHIM // Virtual event handlers, override them in your derived class virtual void onInitDlg( wxInitDialogEvent& event ) { event.Skip(); } + virtual void OnCommandType( wxCommandEvent& 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 OnFilterMouseMoved( wxMouseEvent& event ) { event.Skip(); } + virtual void OnFilterText( wxCommandEvent& event ) { event.Skip(); } virtual void onLoadDirectives( wxCommandEvent& event ) { event.Skip(); } diff --git a/eeschema/dialogs/dialog_symbol_fields_table.cpp b/eeschema/dialogs/dialog_symbol_fields_table.cpp index 7ba97d905c..5c9c661630 100644 --- a/eeschema/dialogs/dialog_symbol_fields_table.cpp +++ b/eeschema/dialogs/dialog_symbol_fields_table.cpp @@ -743,6 +743,7 @@ void DIALOG_SYMBOL_FIELDS_TABLE::OnFilterMouseMoved( wxMouseEvent& aEvent ) SetCursor( wxCURSOR_IBEAM ); } + void DIALOG_SYMBOL_FIELDS_TABLE::OnFieldsCtrlSelectionChanged( wxDataViewEvent& event ) { int row = m_fieldsCtrl->GetSelectedRow(); diff --git a/eeschema/dialogs/dialog_user_defined_signals.cpp b/eeschema/dialogs/dialog_user_defined_signals.cpp index f96d37d9eb..3dbe448109 100644 --- a/eeschema/dialogs/dialog_user_defined_signals.cpp +++ b/eeschema/dialogs/dialog_user_defined_signals.cpp @@ -143,7 +143,7 @@ void DIALOG_USER_DEFINED_SIGNALS::onScintillaCharAdded( wxStyledTextEvent &aEven wxStyledTextCtrl* textCtrl = aTricks->Scintilla(); wxArrayString tokens; - for( const wxString& signal : m_frame->Signals() ) + for( const wxString& signal : m_frame->SimPlotVectors() ) tokens.push_back( signal ); tokens.push_back( wxS( "sqrt(x)" ) ); diff --git a/eeschema/netlist_exporters/netlist_exporter_spice.cpp b/eeschema/netlist_exporters/netlist_exporter_spice.cpp index 2aa8358a38..e941fbc29c 100644 --- a/eeschema/netlist_exporters/netlist_exporter_spice.cpp +++ b/eeschema/netlist_exporters/netlist_exporter_spice.cpp @@ -106,32 +106,32 @@ bool NETLIST_EXPORTER_SPICE::WriteNetlist( const wxString& aOutFileName, unsigne { m_libMgr.SetReporter( &aReporter ); FILE_OUTPUTFORMATTER formatter( aOutFileName, wxT( "wt" ), '\'' ); - return DoWriteNetlist( formatter, aNetlistOptions, aReporter ); + return DoWriteNetlist( wxEmptyString, aNetlistOptions, formatter, aReporter ); } -bool NETLIST_EXPORTER_SPICE::DoWriteNetlist( OUTPUTFORMATTER& aFormatter, unsigned aNetlistOptions, - REPORTER& aReporter ) +bool NETLIST_EXPORTER_SPICE::DoWriteNetlist( const wxString& aSimCommand, unsigned aSimOptions, + OUTPUTFORMATTER& aFormatter, REPORTER& aReporter ) { LOCALE_IO dummy; // Cleanup list to avoid duplicate if the netlist exporter is run more than once. m_rawIncludes.clear(); - bool result = ReadSchematicAndLibraries( aNetlistOptions, aReporter ); + bool result = ReadSchematicAndLibraries( aSimOptions, aReporter ); - WriteHead( aFormatter, aNetlistOptions ); + WriteHead( aFormatter, aSimOptions ); - writeIncludes( aFormatter, aNetlistOptions ); + writeIncludes( aFormatter, aSimOptions ); writeModels( aFormatter ); // Skip this if there is no netlist to avoid an ngspice segfault if( !m_items.empty() ) - WriteDirectives( aFormatter, aNetlistOptions ); + WriteDirectives( aSimCommand, aSimOptions, aFormatter ); writeItems( aFormatter ); - WriteTail( aFormatter, aNetlistOptions ); + WriteTail( aFormatter, aSimOptions ); return result; } @@ -588,16 +588,16 @@ void NETLIST_EXPORTER_SPICE::writeItems( OUTPUTFORMATTER& aFormatter ) } -void NETLIST_EXPORTER_SPICE::WriteDirectives( OUTPUTFORMATTER& aFormatter, - unsigned aNetlistOptions ) const +void NETLIST_EXPORTER_SPICE::WriteDirectives( const wxString& aSimCommand, unsigned aSimOptions, + OUTPUTFORMATTER& aFormatter ) const { - if( aNetlistOptions & OPTION_SAVE_ALL_VOLTAGES ) + if( aSimOptions & OPTION_SAVE_ALL_VOLTAGES ) aFormatter.Print( 0, ".save all\n" ); - if( aNetlistOptions & OPTION_SAVE_ALL_CURRENTS ) + if( aSimOptions & OPTION_SAVE_ALL_CURRENTS ) aFormatter.Print( 0, ".probe alli\n" ); - if( aNetlistOptions & OPTION_SAVE_ALL_DISSIPATIONS ) + if( aSimOptions & OPTION_SAVE_ALL_DISSIPATIONS ) { for( const SPICE_ITEM& item : m_items ) { @@ -638,7 +638,7 @@ void NETLIST_EXPORTER_SPICE::WriteDirectives( OUTPUTFORMATTER& aFormatter, || isSimCommand( candidate, wxS( ".TF" ) ) ); } - if( !simCommand || ( aNetlistOptions & OPTION_SIM_COMMAND ) ) + if( !simCommand || ( aSimOptions & OPTION_SIM_COMMAND ) ) aFormatter.Print( 0, "%s\n", UTF8( directive ).c_str() ); } } diff --git a/eeschema/netlist_exporters/netlist_exporter_spice.h b/eeschema/netlist_exporters/netlist_exporter_spice.h index 1b62d76e6b..2ac03d7b84 100644 --- a/eeschema/netlist_exporters/netlist_exporter_spice.h +++ b/eeschema/netlist_exporters/netlist_exporter_spice.h @@ -76,8 +76,8 @@ public: /** * Write the netlist in aFormatter. */ - bool DoWriteNetlist( OUTPUTFORMATTER& aFormatter, unsigned aNetlistOptions, - REPORTER& aReporter ); + bool DoWriteNetlist( const wxString& aSimCommand, unsigned aSimOptions, + OUTPUTFORMATTER& aFormatter, REPORTER& aReporter ); /** * Write the netlist head (title and so on). @@ -132,7 +132,8 @@ public: protected: void ReadDirectives( unsigned aNetlistOptions ); - virtual void WriteDirectives( OUTPUTFORMATTER& candidate, unsigned aNetlistOptions ) const; + virtual void WriteDirectives( const wxString& aSimCommand, unsigned aSimOptions, + OUTPUTFORMATTER& candidate ) const; virtual std::string GenerateItemPinNetName( const std::string& aNetName, int& aNcCounter ) const; diff --git a/eeschema/sim/ngspice.cpp b/eeschema/sim/ngspice.cpp index c1bd773d0c..56857e1145 100644 --- a/eeschema/sim/ngspice.cpp +++ b/eeschema/sim/ngspice.cpp @@ -251,23 +251,21 @@ std::vector NGSPICE::GetPhaseVector( const std::string& aName, int aMaxL } -bool NGSPICE::Attach( const std::shared_ptr& aModel, REPORTER& aReporter ) +bool NGSPICE::Attach( const std::shared_ptr& aModel, const wxString& aSimCommand, + unsigned aSimOptions, REPORTER& aReporter ) { NGSPICE_CIRCUIT_MODEL* model = dynamic_cast( aModel.get() ); - STRING_FORMATTER formatter; + STRING_FORMATTER formatter; - if( model && model->GetNetlist( &formatter, aReporter ) ) + if( model && model->GetNetlist( aSimCommand, aSimOptions, &formatter, aReporter ) ) { - SIMULATOR::Attach( aModel, aReporter ); - + SIMULATOR::Attach( aModel, aSimCommand, aSimOptions, aReporter ); LoadNetlist( formatter.GetString() ); - return true; } else { - SIMULATOR::Attach( nullptr, aReporter ); - + SIMULATOR::Attach( nullptr, wxEmptyString, 0, aReporter ); return false; } } @@ -335,11 +333,10 @@ wxString NGSPICE::GetXAxis( SIM_TYPE aType ) const switch( aType ) { case ST_AC: - case ST_S_PARAM: - return wxS( "frequency" ); - + case ST_SP: case ST_NOISE: - return wxS( "noise1.frequency" ); + case ST_FFT: + return wxS( "frequency" ); case ST_DC: // find plot, which ends with "-sweep" @@ -351,7 +348,7 @@ wxString NGSPICE::GetXAxis( SIM_TYPE aType ) const return wxS( "sweep" ); - case ST_TRANSIENT: + case ST_TRAN: return wxS( "time" ); default: diff --git a/eeschema/sim/ngspice.h b/eeschema/sim/ngspice.h index 827d3e81bd..73b66da5c1 100644 --- a/eeschema/sim/ngspice.h +++ b/eeschema/sim/ngspice.h @@ -59,8 +59,8 @@ public: void Init( const SPICE_SIMULATOR_SETTINGS* aSettings = nullptr ) override final; ///< @copydoc SPICE_SIMULATOR::Attach() - bool Attach( const std::shared_ptr& aModel, - REPORTER& aReporter ) override final; + bool Attach( const std::shared_ptr& aModel, const wxString& aSimCommand, + unsigned aSimOptions, REPORTER& aReporter ) override final; ///< Load a netlist for the simulation bool LoadNetlist( const std::string& aNetlist ) override final; diff --git a/eeschema/sim/ngspice_circuit_model.cpp b/eeschema/sim/ngspice_circuit_model.cpp index 4fe09e90b3..42aa8d3671 100644 --- a/eeschema/sim/ngspice_circuit_model.cpp +++ b/eeschema/sim/ngspice_circuit_model.cpp @@ -84,13 +84,7 @@ wxString NGSPICE_CIRCUIT_MODEL::GetSchTextSimCommand() simCmd += wxString::Format( wxT( "%s\r\n" ), directive ); } - return simCmd; -} - - -SIM_TYPE NGSPICE_CIRCUIT_MODEL::GetSimType() -{ - return CommandToSimType( GetSimCommand() ); + return simCmd.Trim(); } @@ -98,28 +92,18 @@ SIM_TYPE NGSPICE_CIRCUIT_MODEL::CommandToSimType( const wxString& aCmd ) { wxString cmd = aCmd.Lower().Trim(); - if( cmd.StartsWith( wxT( ".ac" ) ) ) - return ST_AC; - else if( cmd.StartsWith( wxT( ".dc" ) ) ) - return ST_DC; - else if( cmd.StartsWith( wxT( ".tran" ) ) ) - return ST_TRANSIENT; - else if( cmd == wxT( ".op" ) ) - return ST_OP; - else if( cmd.StartsWith( wxT( ".disto" ) ) ) - return ST_DISTORTION; - else if( cmd.StartsWith( wxT( ".noise" ) ) ) - return ST_NOISE; - else if( cmd.StartsWith( wxT( ".pz" ) ) ) - return ST_POLE_ZERO; - else if( cmd.StartsWith( wxT( ".sens" ) ) ) - return ST_SENSITIVITY; - else if( cmd.StartsWith( wxT( ".sp" ) ) ) - return ST_S_PARAM; - else if( cmd.StartsWith( wxT( ".tf" ) ) ) - return ST_TRANS_FUNC; - else - return ST_UNKNOWN; + if( cmd == wxT( ".op" ) ) return ST_OP; + else if( cmd.StartsWith( wxT( ".ac" ) ) ) return ST_AC; + else if( cmd.StartsWith( wxT( ".dc" ) ) ) return ST_DC; + else if( cmd.StartsWith( wxT( ".tran" ) ) ) return ST_TRAN; + else if( cmd.StartsWith( wxT( ".disto" ) ) ) return ST_DISTO; + else if( cmd.StartsWith( wxT( ".noise" ) ) ) return ST_NOISE; + else if( cmd.StartsWith( wxT( ".pz" ) ) ) return ST_PZ; + else if( cmd.StartsWith( wxT( ".sens" ) ) ) return ST_SENS; + else if( cmd.StartsWith( wxT( ".sp" ) ) ) return ST_SP; + else if( cmd.StartsWith( wxT( ".tf" ) ) ) return ST_TF; + else if( cmd.StartsWith( wxT( "fft" ) ) ) return ST_FFT; + else return ST_UNKNOWN; } @@ -211,14 +195,14 @@ bool NGSPICE_CIRCUIT_MODEL::ParseNoiseCommand( const wxString& aCmd, wxString* a } -void NGSPICE_CIRCUIT_MODEL::WriteDirectives( OUTPUTFORMATTER& aFormatter, - unsigned aNetlistOptions ) const +void NGSPICE_CIRCUIT_MODEL::WriteDirectives( const wxString& aSimCommand, unsigned aSimOptions, + OUTPUTFORMATTER& aFormatter ) const { - if( GetSimCommandOverride().IsEmpty() ) - aNetlistOptions |= OPTION_SIM_COMMAND; + if( aSimCommand.IsEmpty() ) + aSimOptions |= OPTION_SIM_COMMAND; - NETLIST_EXPORTER_SPICE::WriteDirectives( aFormatter, aNetlistOptions ); + NETLIST_EXPORTER_SPICE::WriteDirectives( aSimCommand, aSimOptions, aFormatter ); - if( !GetSimCommandOverride().IsEmpty() ) - aFormatter.Print( 0, "%s\n", TO_UTF8( GetSimCommandOverride() ) ); + if( !aSimCommand.IsEmpty() ) + aFormatter.Print( 0, "%s\n", TO_UTF8( aSimCommand ) ); } diff --git a/eeschema/sim/ngspice_circuit_model.h b/eeschema/sim/ngspice_circuit_model.h index 45bf1adfeb..79945d21de 100644 --- a/eeschema/sim/ngspice_circuit_model.h +++ b/eeschema/sim/ngspice_circuit_model.h @@ -48,8 +48,7 @@ class NGSPICE_CIRCUIT_MODEL : public NETLIST_EXPORTER_SPICE, public SIMULATION_M { public: NGSPICE_CIRCUIT_MODEL( SCHEMATIC_IFACE* aSchematic, wxWindow* aDialogParent = nullptr ) : - NETLIST_EXPORTER_SPICE( aSchematic, aDialogParent ), - m_options( NETLIST_EXPORTER_SPICE::OPTION_DEFAULT_FLAGS ) + NETLIST_EXPORTER_SPICE( aSchematic, aDialogParent ) {} virtual ~NGSPICE_CIRCUIT_MODEL() {} @@ -64,60 +63,18 @@ public: */ SIM_TRACE_TYPE VectorToSignal( const std::string& aVector, wxString& aSignal ) const; - void SetSimOptions( int aOptions ) { m_options = aOptions; } - int GetSimOptions() const { return m_options; } - - bool GetNetlist( OUTPUTFORMATTER* aFormatter, REPORTER& aReporter ) + bool GetNetlist( const wxString& aSimCommand, unsigned aSimOptions, + OUTPUTFORMATTER* aFormatter, REPORTER& aReporter ) { - return NGSPICE_CIRCUIT_MODEL::DoWriteNetlist( *aFormatter, m_options, aReporter ); + return NGSPICE_CIRCUIT_MODEL::DoWriteNetlist( aSimCommand, aSimOptions, *aFormatter, + aReporter ); } - /** - * Override the simulation command directive. - */ - void SetSimCommandOverride( const wxString& aCmd ) - { - if( aCmd != m_simCommand ) - { - m_lastSchTextSimCommand = GetSchTextSimCommand(); - m_simCommand = aCmd; - } - } - - /** - * Return the command directive that is in use (either from the sheet or from m_simCommand) - * @return - */ - wxString GetSimCommand() - { - return m_simCommand.IsEmpty() ? GetSchTextSimCommand() : m_simCommand; - } - - /** - * Return the simulation command directive if stored separately (not as a sheet directive). - */ - wxString GetSimCommandOverride() const { return m_simCommand; } - - /** - * Return simulation type basing on the simulation command directives. - * - * Simulation directives set using SetSimCommandOverride() have priority over the ones placed in - * schematic sheets. - */ - SIM_TYPE GetSimType(); - /** * Return simulation command directives placed in schematic sheets (if any). */ wxString GetSchTextSimCommand(); - /** - * Return the sim command present as a sheet directive when the sim command override was last - * updated. - * @return - */ - wxString GetLastSchTextSimCommand() const { return m_lastSchTextSimCommand; } - /** * Parse a two-source .dc command directive into its symbols. * @@ -145,16 +102,8 @@ public: static SIM_TYPE CommandToSimType( const wxString& aCmd ); protected: - void WriteDirectives( OUTPUTFORMATTER& aFormatter, unsigned aNetlistOptions ) const override; - -private: - ///< Custom simulation command (has priority over the schematic sheet simulation commands) - wxString m_simCommand; - - ///< Value of schematic sheet simulation command when override was last updated - wxString m_lastSchTextSimCommand; - - int m_options; + void WriteDirectives( const wxString& aSimCommand, unsigned aSimOptions, + OUTPUTFORMATTER& aFormatter ) const override; }; #endif /* NGSPICE_CIRCUIT_MODEL_H */ diff --git a/eeschema/sim/sim_plot_panel.cpp b/eeschema/sim/sim_plot_panel.cpp index 927a5a4520..0aacd1682c 100644 --- a/eeschema/sim/sim_plot_panel.cpp +++ b/eeschema/sim/sim_plot_panel.cpp @@ -405,10 +405,9 @@ void CURSOR::UpdateReference() } -SIM_PLOT_PANEL::SIM_PLOT_PANEL( const wxString& aCommand, int aOptions, wxWindow* parent, - wxWindowID id, const wxPoint& pos, const wxSize& size, long style, - const wxString& name ) : - SIM_PLOT_PANEL_BASE( aCommand, aOptions, parent, id, pos, size, style, name ), +SIM_PLOT_PANEL::SIM_PLOT_PANEL( const wxString& aSimCommand, unsigned aSimOptions, + wxWindow* parent ) : + SIM_PLOT_PANEL_BASE( aSimCommand, aSimOptions, parent ), m_axis_x( nullptr ), m_axis_y1( nullptr ), m_axis_y2( nullptr ), @@ -416,7 +415,7 @@ SIM_PLOT_PANEL::SIM_PLOT_PANEL( const wxString& aCommand, int aOptions, wxWindow m_dotted_cp( false ) { m_sizer = new wxBoxSizer( wxVERTICAL ); - m_plotWin = new mpWindow( this, wxID_ANY, pos, size, style ); + m_plotWin = new mpWindow( this, wxID_ANY ); m_plotWin->LimitView( true ); m_plotWin->SetMargins( 35, 70, 35, 70 ); @@ -517,7 +516,7 @@ void SIM_PLOT_PANEL::updateAxes( int aNewTraceType ) m_axis_y2->SetName( _( "Phase" ) ); break; - case ST_S_PARAM: + case ST_SP: if( !m_axis_x ) { m_axis_x = new LOG_SCALE( wxEmptyString, wxT( "Hz" ), mpALIGN_BOTTOM ); @@ -574,7 +573,23 @@ void SIM_PLOT_PANEL::updateAxes( int aNewTraceType ) break; - case ST_TRANSIENT: + case ST_FFT: + if( !m_axis_x ) + { + m_axis_x = new LOG_SCALE( wxEmptyString, wxT( "Hz" ), mpALIGN_BOTTOM ); + m_axis_x->SetNameAlign( mpALIGN_BOTTOM ); + m_plotWin->AddLayer( m_axis_x ); + + m_axis_y1 = new LIN_SCALE( wxEmptyString, wxT( "dB" ), mpALIGN_LEFT ); + m_axis_y1->SetNameAlign( mpALIGN_LEFT ); + m_plotWin->AddLayer( m_axis_y1 ); + } + + m_axis_x->SetName( _( "Frequency" ) ); + m_axis_y1->SetName( _( "Intensity" ) ); + break; + + case ST_TRAN: if( !m_axis_x ) { m_axis_x = new TIME_SCALE( wxEmptyString, wxT( "s" ), mpALIGN_BOTTOM ); @@ -777,7 +792,7 @@ TRACE* SIM_PLOT_PANEL::AddTrace( const wxString& aVectorName, int aType ) { updateAxes( aType ); - if( GetSimType() == ST_TRANSIENT || GetSimType() == ST_DC ) + if( GetSimType() == ST_TRAN || GetSimType() == ST_DC ) { bool hasVoltageTraces = false; @@ -815,27 +830,37 @@ TRACE* SIM_PLOT_PANEL::AddTrace( const wxString& aVectorName, int aType ) void SIM_PLOT_PANEL::SetTraceData( TRACE* trace, unsigned int aPoints, const double* aX, const double* aY ) { - std::vector tmp( aY, aY + aPoints ); + std::vector x( aX, aX + aPoints ); + std::vector y( aY, aY + aPoints ); - if( GetSimType() == ST_AC ) + if( GetSimType() == ST_AC || GetSimType() == ST_SP || GetSimType() == ST_FFT ) + { + // log( 0 ) is not valid. + { + x.erase( x.begin() ); + y.erase( y.begin() ); + } + } + + if( GetSimType() == ST_AC || GetSimType() == ST_FFT ) { if( trace->GetType() & SPT_AC_PHASE ) { for( unsigned int i = 0; i < aPoints; i++ ) - tmp[i] = tmp[i] * 180.0 / M_PI; // convert to degrees + y[i] = y[i] * 180.0 / M_PI; // convert to degrees } else { for( unsigned int i = 0; i < aPoints; i++ ) { // log( 0 ) is not valid. - if( tmp[i] != 0 ) - tmp[i] = 20 * log( tmp[i] ) / log( 10.0 ); // convert to dB + if( y[i] != 0 ) + y[i] = 20 * log( y[i] ) / log( 10.0 ); // convert to dB } } } - trace->SetData( std::vector( aX, aX + aPoints ), tmp ); + trace->SetData( x, y ); if( ( trace->GetType() & SPT_AC_PHASE ) || ( trace->GetType() & SPT_CURRENT ) ) trace->SetScale( m_axis_x, m_axis_y2 ); diff --git a/eeschema/sim/sim_plot_panel.h b/eeschema/sim/sim_plot_panel.h index ada4980694..9d028aa420 100644 --- a/eeschema/sim/sim_plot_panel.h +++ b/eeschema/sim/sim_plot_panel.h @@ -194,9 +194,7 @@ protected: class SIM_PLOT_PANEL : public SIM_PLOT_PANEL_BASE { public: - SIM_PLOT_PANEL( const wxString& aCommand, int aOptions, wxWindow* parent, wxWindowID id, - const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, - long style = 0, const wxString& name = wxPanelNameStr ); + SIM_PLOT_PANEL( const wxString& aSimCommand, unsigned aSimOptions, wxWindow* parent ); virtual ~SIM_PLOT_PANEL(); @@ -239,10 +237,18 @@ public: void ShowGrid( bool aEnable ) { - m_axis_x->SetTicks( !aEnable ); - m_axis_y1->SetTicks( !aEnable ); - m_axis_y2->SetTicks( !aEnable ); - m_axis_y3->SetTicks( !aEnable ); + if( m_axis_x ) + m_axis_x->SetTicks( !aEnable ); + + if( m_axis_y1 ) + m_axis_y1->SetTicks( !aEnable ); + + if( m_axis_y2 ) + m_axis_y2->SetTicks( !aEnable ); + + if( m_axis_y3 ) + m_axis_y3->SetTicks( !aEnable ); + m_plotWin->UpdateAll(); } @@ -320,6 +326,8 @@ public: bool DeleteTrace( const wxString& aVectorName, int aTraceType ); void DeleteTrace( TRACE* aTrace ); + std::vector>& Measurements() { return m_measurements; } + private: wxString getTraceId( const wxString& aVectorName, int aType ) const { @@ -349,6 +357,9 @@ private: mpInfoLegend* m_legend; bool m_dotted_cp; + + // Measurements (and their format strings) + std::vector> m_measurements; }; wxDECLARE_EVENT( EVT_SIM_CURSOR_UPDATE, wxCommandEvent ); diff --git a/eeschema/sim/sim_plot_panel_base.cpp b/eeschema/sim/sim_plot_panel_base.cpp index e9a61fd9a5..5f31d780df 100644 --- a/eeschema/sim/sim_plot_panel_base.cpp +++ b/eeschema/sim/sim_plot_panel_base.cpp @@ -37,12 +37,11 @@ SIM_PLOT_PANEL_BASE::SIM_PLOT_PANEL_BASE() : } -SIM_PLOT_PANEL_BASE::SIM_PLOT_PANEL_BASE( const wxString& aCommand, int aOptions, 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 ), - m_simOptions( aOptions ) +SIM_PLOT_PANEL_BASE::SIM_PLOT_PANEL_BASE( const wxString& aSimCommand, unsigned aSimOptions, + wxWindow* parent ) : + wxWindow( parent, wxID_ANY ), + m_simCommand( aSimCommand ), + m_simOptions( aSimOptions ) { } @@ -58,9 +57,10 @@ bool SIM_PLOT_PANEL_BASE::IsPlottable( SIM_TYPE aSimType ) { case ST_AC: case ST_DC: - case ST_S_PARAM: - case ST_TRANSIENT: + case ST_SP: + case ST_TRAN: case ST_NOISE: + case ST_FFT: return true; default: @@ -75,10 +75,9 @@ SIM_TYPE SIM_PLOT_PANEL_BASE::GetSimType() const } -SIM_NOPLOT_PANEL::SIM_NOPLOT_PANEL( const wxString& aCommand, int aOptions, wxWindow* parent, - wxWindowID id, const wxPoint& pos, const wxSize& size, - long style, const wxString& name ) : - SIM_PLOT_PANEL_BASE( aCommand, aOptions, parent, id, pos, size, style, name ) +SIM_NOPLOT_PANEL::SIM_NOPLOT_PANEL( const wxString& aSimCommand, unsigned aSimOptions, + wxWindow* parent ) : + SIM_PLOT_PANEL_BASE( aSimCommand, aSimOptions, parent ) { m_sizer = new wxBoxSizer( wxVERTICAL ); m_sizer->Add( 0, 1, 1, wxEXPAND, 5 ); diff --git a/eeschema/sim/sim_plot_panel_base.h b/eeschema/sim/sim_plot_panel_base.h index e7ae89bad2..286717ce12 100644 --- a/eeschema/sim/sim_plot_panel_base.h +++ b/eeschema/sim/sim_plot_panel_base.h @@ -26,8 +26,8 @@ #ifndef __SIM_PLOT_PANEL_BASE_H #define __SIM_PLOT_PANEL_BASE_H -#include "sim_types.h" -#include "ngspice_circuit_model.h" +#include +#include #include #include #include @@ -37,9 +37,7 @@ class SIM_PLOT_PANEL_BASE : public wxWindow { public: SIM_PLOT_PANEL_BASE(); - SIM_PLOT_PANEL_BASE( const wxString& aCommand, int aOptions, wxWindow* parent, wxWindowID id, - const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, - long style = 0, const wxString& name = wxPanelNameStr ); + SIM_PLOT_PANEL_BASE( const wxString& aSimCommand, unsigned aSimOptions, wxWindow* parent ); virtual ~SIM_PLOT_PANEL_BASE(); static bool IsPlottable( SIM_TYPE aSimType ); @@ -49,29 +47,29 @@ public: SIM_TYPE GetSimType() const; const wxString& GetSimCommand() const { return m_simCommand; } - void SetSimCommand( const wxString& aSimCommand ) - { - wxCHECK_RET( GetSimType() == NGSPICE_CIRCUIT_MODEL::CommandToSimType( aSimCommand ), - "Cannot change the type of simulation of the existing plot panel" ); - - m_simCommand = aSimCommand; - } + void SetSimCommand( const wxString& aSimCommand ) { m_simCommand = aSimCommand; } int GetSimOptions() const { return m_simOptions; } void SetSimOptions( int aOptions ) { m_simOptions = aOptions; } + wxString GetLastSchTextSimCommand() const { return m_lastSchTextSimCommand; } + void SetLastSchTextSimCommand( const wxString& aCmd ) { m_lastSchTextSimCommand = aCmd; } + + const wxString& GetSpicePlotName() const { return m_spicePlotName; } + void SetSpicePlotName( const wxString& aPlotName ) { m_spicePlotName = aPlotName; } + private: wxString m_simCommand; - int m_simOptions; + unsigned m_simOptions; + wxString m_lastSchTextSimCommand; + wxString m_spicePlotName; }; class SIM_NOPLOT_PANEL : public SIM_PLOT_PANEL_BASE { public: - SIM_NOPLOT_PANEL( const wxString& aCommand, int aOptions, wxWindow* parent, wxWindowID id, - const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, - long style = 0, const wxString& name = wxPanelNameStr ); + SIM_NOPLOT_PANEL( const wxString& aSimCommand, unsigned aSimOptions, wxWindow* parent ); virtual ~SIM_NOPLOT_PANEL(); diff --git a/eeschema/sim/sim_types.h b/eeschema/sim/sim_types.h index 9ad2b07c45..737610a70f 100644 --- a/eeschema/sim/sim_types.h +++ b/eeschema/sim/sim_types.h @@ -33,14 +33,16 @@ enum SIM_TYPE ST_UNKNOWN, ST_AC, ST_DC, - ST_DISTORTION, + ST_DISTO, ST_NOISE, ST_OP, - ST_POLE_ZERO, - ST_SENSITIVITY, - ST_TRANS_FUNC, - ST_TRANSIENT, - ST_S_PARAM + ST_PZ, + ST_SENS, + ST_TF, + ST_TRAN, + ST_SP, + ST_FFT, + ST_LAST }; ///< Possible trace types diff --git a/eeschema/sim/simulator.h b/eeschema/sim/simulator.h index 0330f7754a..8ff88ea48d 100644 --- a/eeschema/sim/simulator.h +++ b/eeschema/sim/simulator.h @@ -58,7 +58,8 @@ public: * * @return True in case of success, false otherwise. */ - virtual bool Attach( const std::shared_ptr& aModel, REPORTER& aReporter ) + virtual bool Attach( const std::shared_ptr& aModel, + const wxString& aSimCommand, unsigned aSimOptions, REPORTER& aReporter ) { m_simModel = aModel; return true; diff --git a/eeschema/sim/simulator_frame.cpp b/eeschema/sim/simulator_frame.cpp index c211eba432..67891a3671 100644 --- a/eeschema/sim/simulator_frame.cpp +++ b/eeschema/sim/simulator_frame.cpp @@ -113,7 +113,6 @@ SIMULATOR_FRAME::SIMULATOR_FRAME( KIWAY* aKiway, wxWindow* aParent ) : m_schematicFrame( nullptr ), m_toolBar( nullptr ), m_panel( nullptr ), - m_lastSimPlot( nullptr ), m_simFinished( false ), m_workbookModified( false ) { @@ -168,7 +167,7 @@ SIMULATOR_FRAME::SIMULATOR_FRAME( KIWAY* aKiway, wxWindow* aParent ) : Bind( wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( SIMULATOR_FRAME::onExit ), this, wxID_EXIT ); - Bind( EVT_SIM_UPDATE, &SIMULATOR_FRAME::onSimUpdate, this ); + Bind( EVT_SIM_UPDATE, &SIMULATOR_FRAME::onUpdateSim, this ); Bind( EVT_SIM_REPORT, &SIMULATOR_FRAME::onSimReport, this ); Bind( EVT_SIM_STARTED, &SIMULATOR_FRAME::onSimStarted, this ); Bind( EVT_SIM_FINISHED, &SIMULATOR_FRAME::onSimFinished, this ); @@ -196,7 +195,7 @@ SIMULATOR_FRAME::~SIMULATOR_FRAME() { NULL_REPORTER devnull; - m_simulator->Attach( nullptr, devnull ); + m_simulator->Attach( nullptr, wxEmptyString, 0, devnull ); m_simulator->SetReporter( nullptr ); delete m_reporter; } @@ -285,8 +284,8 @@ WINDOW_SETTINGS* SIMULATOR_FRAME::GetWindowSettings( APP_SETTINGS_BASE* aCfg ) wxString SIMULATOR_FRAME::GetCurrentSimCommand() const { - if( m_panel->GetCurrentPlotWindow() ) - return m_panel->GetCurrentPlotWindow()->GetSimCommand(); + if( m_panel->GetCurrentPlotPanel() ) + return m_panel->GetCurrentPlotPanel()->GetSimCommand(); else return m_circuitModel->GetSchTextSimCommand(); } @@ -300,10 +299,10 @@ SIM_TYPE SIMULATOR_FRAME::GetCurrentSimType() const int SIMULATOR_FRAME::GetCurrentOptions() const { - if( m_panel->GetCurrentPlotWindow() ) - return m_panel->GetCurrentPlotWindow()->GetSimOptions(); + if( SIM_PLOT_PANEL_BASE* plotPanel = m_panel->GetCurrentPlotPanel() ) + return plotPanel->GetSimOptions(); else - return m_circuitModel->GetSimOptions(); + return NETLIST_EXPORTER_SPICE::OPTION_DEFAULT_FLAGS; } @@ -338,7 +337,7 @@ void SIMULATOR_FRAME::UpdateTitle() -bool SIMULATOR_FRAME::LoadSimulator() +bool SIMULATOR_FRAME::LoadSimulator( const wxString& aSimCommand, unsigned aSimOptions ) { wxString errors; WX_STRING_REPORTER reporter( &errors ); @@ -350,7 +349,7 @@ bool SIMULATOR_FRAME::LoadSimulator() if( ADVANCED_CFG::GetCfg().m_IncrementalConnectivity ) m_schematicFrame->RecalculateConnections( nullptr, GLOBAL_CLEANUP ); - if( !m_simulator->Attach( m_circuitModel, reporter ) ) + if( !m_simulator->Attach( m_circuitModel, aSimCommand, aSimOptions, reporter ) ) { DisplayErrorMessage( this, _( "Errors during netlist generation.\n\n" ) + errors ); return false; @@ -362,56 +361,69 @@ bool SIMULATOR_FRAME::LoadSimulator() void SIMULATOR_FRAME::StartSimulation() { - if( m_circuitModel->CommandToSimType( GetCurrentSimCommand() ) == ST_UNKNOWN ) + SIM_PLOT_PANEL_BASE* plotPanel = m_panel->GetCurrentPlotPanel(); + + if( !plotPanel ) + return; + + if( plotPanel->GetSimCommand().Upper().StartsWith( wxT( "FFT" ) ) ) { - if( !EditSimCommand() ) - return; + wxString tranSpicePlot; - if( m_circuitModel->CommandToSimType( GetCurrentSimCommand() ) == ST_UNKNOWN ) - return; - } + if( SIM_PLOT_PANEL_BASE* tranPlotPanel = m_panel->GetPlotPanel( ST_TRAN ) ) + tranSpicePlot = tranPlotPanel->GetSpicePlotName(); - wxString schTextSimCommand = m_circuitModel->GetSchTextSimCommand(); - SIM_TYPE schTextSimType = NGSPICE_CIRCUIT_MODEL::CommandToSimType( schTextSimCommand ); - SIM_PLOT_PANEL_BASE* plotWindow = m_panel->GetCurrentPlotWindow(); + if( tranSpicePlot.IsEmpty() ) + { + DisplayErrorMessage( this, _( "You must run a TRAN simulation first; its results" + "will be used for the fast Fourier transform." ) ); + } + else + { + m_simulator->Command( "setplot " + tranSpicePlot.ToStdString() ); - if( !plotWindow ) - { - NewPlotPanel( schTextSimCommand, m_circuitModel->GetSimOptions() ); - OnModify(); + wxArrayString commands = wxSplit( plotPanel->GetSimCommand(), '\n' ); + + for( const wxString& command : commands ) + { + wxBusyCursor wait; + m_simulator->Command( command.ToStdString() ); + } + + plotPanel->SetSpicePlotName( m_simulator->CurrentPlotName() ); + m_panel->OnSimRefresh( true ); + +#if 0 + m_simulator->Command( "setplot" ); // Print available plots to console + m_simulator->Command( "display" ); // Print vectors in current plot to console +#endif + } + + return; } else { - m_circuitModel->SetSimCommandOverride( plotWindow->GetSimCommand() ); - - if( plotWindow->GetSimType() == schTextSimType - && schTextSimCommand != m_circuitModel->GetLastSchTextSimCommand() ) + if( m_panel->GetPlotIndex( plotPanel ) == 0 + && m_circuitModel->GetSchTextSimCommand() != plotPanel->GetLastSchTextSimCommand() ) { if( IsOK( this, _( "Schematic sheet simulation command directive has changed. " "Do you wish to update the Simulation Command?" ) ) ) { - m_circuitModel->SetSimCommandOverride( wxEmptyString ); - plotWindow->SetSimCommand( schTextSimCommand ); + plotPanel->SetSimCommand( m_circuitModel->GetSchTextSimCommand() ); + plotPanel->SetLastSchTextSimCommand( plotPanel->GetSimCommand() ); OnModify(); } } } - m_circuitModel->SetSimOptions( GetCurrentOptions() ); - - if( !LoadSimulator() ) + if( !LoadSimulator( plotPanel->GetSimCommand(), plotPanel->GetSimOptions() ) ) return; std::unique_lock simulatorLock( m_simulator->GetMutex(), std::try_to_lock ); if( simulatorLock.owns_lock() ) { - wxBusyCursor toggle; - m_panel->OnSimUpdate(); - - // Prevents memory leak on succeding simulations by deleting old vectors - m_simulator->Clean(); m_simulator->Run(); } else @@ -421,12 +433,18 @@ void SIMULATOR_FRAME::StartSimulation() } -void SIMULATOR_FRAME::NewPlotPanel( const wxString& aSimCommand, int aOptions ) +void SIMULATOR_FRAME::NewPlotPanel( const wxString& aSimCommand, unsigned aOptions ) { m_panel->NewPlotPanel( aSimCommand, aOptions ); } +const std::vector SIMULATOR_FRAME::SimPlotVectors() +{ + return m_panel->SimPlotVectors(); +} + + const std::vector SIMULATOR_FRAME::Signals() { return m_panel->Signals(); @@ -463,9 +481,9 @@ void SIMULATOR_FRAME::AddTuner( const SCH_SHEET_PATH& aSheetPath, SCH_SYMBOL* aS } -SIM_PLOT_PANEL* SIMULATOR_FRAME::GetCurrentPlot() const +SIM_PLOT_PANEL_BASE* SIMULATOR_FRAME::GetCurrentPlotPanel() const { - return m_panel->GetCurrentPlot(); + return m_panel->GetCurrentPlotPanel(); } @@ -511,11 +529,14 @@ void SIMULATOR_FRAME::ToggleDarkModePlots() bool SIMULATOR_FRAME::EditSimCommand() { - SIM_PLOT_PANEL_BASE* plotPanelWindow = m_panel->GetCurrentPlotWindow(); + SIM_PLOT_PANEL_BASE* plotPanel = m_panel->GetCurrentPlotPanel(); DIALOG_SIM_COMMAND dlg( this, m_circuitModel, m_simulator->Settings() ); wxString errors; WX_STRING_REPORTER reporter( &errors ); + if( !plotPanel ) + return false; + if( !m_circuitModel->ReadSchematicAndLibraries( NETLIST_EXPORTER_SPICE::OPTION_DEFAULT_FLAGS, reporter ) ) { @@ -523,55 +544,15 @@ bool SIMULATOR_FRAME::EditSimCommand() + errors ); } - if( m_panel->GetPlotIndex( plotPanelWindow ) != wxNOT_FOUND ) - { - dlg.SetSimCommand( plotPanelWindow->GetSimCommand() ); - dlg.SetSimOptions( plotPanelWindow->GetSimOptions() ); - } - else - { - dlg.SetSimOptions( NETLIST_EXPORTER_SPICE::OPTION_DEFAULT_FLAGS ); - } + dlg.SetSimCommand( plotPanel->GetSimCommand() ); + dlg.SetSimOptions( plotPanel->GetSimOptions() ); if( dlg.ShowModal() == wxID_OK ) { - wxString oldCommand; - - if( m_panel->GetPlotIndex( plotPanelWindow ) != wxNOT_FOUND ) - oldCommand = plotPanelWindow->GetSimCommand(); - else - oldCommand = wxString(); - - const wxString& newCommand = dlg.GetSimCommand(); - int newOptions = dlg.GetSimOptions(); - SIM_TYPE newSimType = NGSPICE_CIRCUIT_MODEL::CommandToSimType( newCommand ); - - if( !plotPanelWindow ) - { - m_circuitModel->SetSimCommandOverride( newCommand ); - m_circuitModel->SetSimOptions( newOptions ); - NewPlotPanel( newCommand, newOptions ); - } - // If it is a new simulation type, open a new plot. For the DC sim, check if sweep - // source type has changed (char 4 will contain 'v', 'i', 'r' or 't'. - else if( plotPanelWindow->GetSimType() != newSimType - || ( newSimType == ST_DC - && oldCommand.Lower().GetChar( 4 ) != newCommand.Lower().GetChar( 4 ) ) ) - { - NewPlotPanel( newCommand, newOptions ); - } - else - { - if( m_panel->GetPlotIndex( plotPanelWindow ) == 0 ) - m_circuitModel->SetSimCommandOverride( newCommand ); - - // Update simulation command in the current plot - plotPanelWindow->SetSimCommand( newCommand ); - plotPanelWindow->SetSimOptions( newOptions ); - } - + plotPanel->SetSimCommand( dlg.GetSimCommand() ); + plotPanel->SetSimOptions( dlg.GetSimOptions() ); + m_panel->OnPlotSettingsChanged(); OnModify(); - m_simulator->Init(); return true; } @@ -633,22 +614,22 @@ void SIMULATOR_FRAME::setupUIConditions() auto showGridCondition = [this]( const SELECTION& aSel ) { - SIM_PLOT_PANEL* plot = GetCurrentPlot(); - return plot && plot->IsGridShown(); + SIM_PLOT_PANEL* plotPanel = dynamic_cast( GetCurrentPlotPanel() ); + return plotPanel && plotPanel->IsGridShown(); }; auto showLegendCondition = [this]( const SELECTION& aSel ) { - SIM_PLOT_PANEL* plot = GetCurrentPlot(); - return plot && plot->IsLegendShown(); + SIM_PLOT_PANEL* plotPanel = dynamic_cast( GetCurrentPlotPanel() ); + return plotPanel && plotPanel->IsLegendShown(); }; auto showDottedCondition = [this]( const SELECTION& aSel ) { - SIM_PLOT_PANEL* plot = GetCurrentPlot(); - return plot && plot->GetDottedSecondary(); + SIM_PLOT_PANEL* plotPanel = dynamic_cast( GetCurrentPlotPanel() ); + return plotPanel && plotPanel->GetDottedSecondary(); }; auto darkModePlotCondition = @@ -669,10 +650,16 @@ void SIMULATOR_FRAME::setupUIConditions() return m_simFinished; }; + auto haveSim = + [this]( const SELECTION& aSel ) + { + return GetCurrentPlotPanel() != nullptr; + }; + auto havePlot = [this]( const SELECTION& aSel ) { - return GetCurrentPlot() != nullptr; + return dynamic_cast( GetCurrentPlotPanel() ) != nullptr; }; #define ENABLE( x ) ACTION_CONDITIONS().Enable( x ) @@ -690,7 +677,8 @@ void SIMULATOR_FRAME::setupUIConditions() mgr->SetConditions( EE_ACTIONS::toggleDottedSecondary, CHECK( showDottedCondition ) ); mgr->SetConditions( EE_ACTIONS::toggleDarkModePlots, CHECK( darkModePlotCondition ) ); - mgr->SetConditions( EE_ACTIONS::simCommand, ENABLE( SELECTION_CONDITIONS::ShowAlways ) ); + mgr->SetConditions( EE_ACTIONS::newPlot, ENABLE( SELECTION_CONDITIONS::ShowAlways ) ); + mgr->SetConditions( EE_ACTIONS::simCommand, ENABLE( haveSim ) ); mgr->SetConditions( EE_ACTIONS::runSimulation, ENABLE( !simRunning ) ); mgr->SetConditions( EE_ACTIONS::stopSimulation, ENABLE( simRunning ) ); mgr->SetConditions( EE_ACTIONS::simProbe, ENABLE( simFinished ) ); @@ -710,13 +698,6 @@ void SIMULATOR_FRAME::onSimStarted( wxCommandEvent& aEvent ) void SIMULATOR_FRAME::onSimFinished( wxCommandEvent& aEvent ) { - SetCursor( wxCURSOR_ARROW ); - - SIM_TYPE simType = m_circuitModel->GetSimType(); - - if( simType == ST_UNKNOWN ) - return; - // Sometimes (for instance with a directive like wrdata my_file.csv "my_signal") // the simulator is in idle state (simulation is finished), but still running, during // the time the file is written. So gives a slice of time to fully finish the work: @@ -745,12 +726,10 @@ void SIMULATOR_FRAME::onSimFinished( wxCommandEvent& aEvent ) m_schematicFrame->RefreshOperatingPointDisplay(); m_schematicFrame->GetCanvas()->Refresh(); - - m_lastSimPlot = m_panel->GetCurrentPlotWindow(); } -void SIMULATOR_FRAME::onSimUpdate( wxCommandEvent& aEvent ) +void SIMULATOR_FRAME::onUpdateSim( wxCommandEvent& aEvent ) { static bool updateInProgress = false; @@ -763,25 +742,16 @@ void SIMULATOR_FRAME::onSimUpdate( wxCommandEvent& aEvent ) if( m_simulator->IsRunning() ) m_simulator->Stop(); - if( m_panel->GetCurrentPlotWindow() != m_lastSimPlot ) + std::unique_lock simulatorLock( m_simulator->GetMutex(), std::try_to_lock ); + + if( simulatorLock.owns_lock() ) { - // We need to rerun simulation, as the simulator currently stores results for another - // plot - StartSimulation(); + m_panel->OnSimUpdate(); + m_simulator->Run(); } else { - std::unique_lock simulatorLock( m_simulator->GetMutex(), std::try_to_lock ); - - if( simulatorLock.owns_lock() ) - { - m_panel->OnSimUpdate(); - m_simulator->Run(); - } - else - { - DisplayErrorMessage( this, _( "Another simulation is already running." ) ); - } + DisplayErrorMessage( this, _( "Another simulation is already running." ) ); } updateInProgress = false; diff --git a/eeschema/sim/simulator_frame.h b/eeschema/sim/simulator_frame.h index 1c825f868c..06e305be23 100644 --- a/eeschema/sim/simulator_frame.h +++ b/eeschema/sim/simulator_frame.h @@ -77,7 +77,7 @@ public: * Check and load the current netlist into the simulator. * @return true if document is fully annotated and netlist was loaded successfully. */ - bool LoadSimulator(); + bool LoadSimulator( const wxString& aSimCommand, unsigned aSimOptions ); void StartSimulation(); @@ -87,7 +87,7 @@ public: * @param aSimCommand is requested simulation command. * @param aSimOptions netlisting options */ - void NewPlotPanel( const wxString& aSimCommand, int aSimOptions ); + void NewPlotPanel( const wxString& aSimCommand, unsigned aSimOptions ); /** * Shows a dialog for editing the current tab's simulation command, or creating a new tab @@ -96,7 +96,12 @@ public: bool EditSimCommand(); /** - * @return the list of signals in the current simulation results. + * @return the list of vectors (signals) in the current simulation results. + */ + const std::vector SimPlotVectors(); + + /** + * @return the list of schematic signals + any user defined signals. */ const std::vector Signals(); @@ -127,7 +132,7 @@ public: /** * Return the current tab (or NULL if there is none). */ - SIM_PLOT_PANEL* GetCurrentPlot() const; + SIM_PLOT_PANEL_BASE* GetCurrentPlotPanel() const; /** * Toggle dark-mode of the plot tabs. @@ -187,7 +192,7 @@ private: bool canCloseWindow( wxCloseEvent& aEvent ) override; void doCloseWindow() override; - void onSimUpdate( wxCommandEvent& aEvent ); + void onUpdateSim( wxCommandEvent& aEvent ); void onSimReport( wxCommandEvent& aEvent ); void onSimStarted( wxCommandEvent& aEvent ); void onSimFinished( wxCommandEvent& aEvent ); @@ -203,7 +208,6 @@ private: SIM_THREAD_REPORTER* m_reporter; std::shared_ptr m_circuitModel; - SIM_PLOT_PANEL_BASE* m_lastSimPlot; bool m_simFinished; bool m_workbookModified; }; diff --git a/eeschema/sim/simulator_panel.cpp b/eeschema/sim/simulator_panel.cpp index efe47669ed..caaf73e9cf 100644 --- a/eeschema/sim/simulator_panel.cpp +++ b/eeschema/sim/simulator_panel.cpp @@ -37,13 +37,12 @@ #include #include #include -#include "ngspice.h" -#include "simulator_panel.h" +#include #include #include #include #include "fmt/format.h" -#include "dialogs/dialog_text_entry.h" +#include #include #include @@ -135,26 +134,29 @@ void SIGNALS_GRID_TRICKS::showPopupMenu( wxMenu& menu, wxGridEvent& aEvent ) m_grid->SetGridCursor( m_menuRow, m_menuCol ); - wxString msg = m_grid->GetCellValue( m_menuRow, m_menuCol ); - - menu.Append( MYID_MEASURE_MIN, _( "Measure Min" ) ); - menu.Append( MYID_MEASURE_MAX, _( "Measure Max" ) ); - menu.Append( MYID_MEASURE_AVG, _( "Measure Average" ) ); - menu.Append( MYID_MEASURE_RMS, _( "Measure RMS" ) ); - menu.Append( MYID_MEASURE_PP, _( "Measure Peak-to-peak" ) ); - menu.Append( MYID_MEASURE_MIN_AT, _( "Measure Time of Min" ) ); - menu.Append( MYID_MEASURE_MAX_AT, _( "Measure Time of Max" ) ); - menu.Append( MYID_MEASURE_INTEGRAL, _( "Measure Integral" ) ); - - SIM_PLOT_PANEL* panel = m_parent->GetCurrentPlot(); - - if( panel && panel->GetSimType() == ST_TRANSIENT ) + if( SIM_PLOT_PANEL_BASE* panel = m_parent->GetCurrentPlotPanel() ) { - menu.AppendSeparator(); - menu.Append( MYID_FOURIER, _( "Perform Fourier Analysis..." ) ); - } + if( panel->GetSimType() == ST_TRAN || panel->GetSimType() == ST_AC + || panel->GetSimType() == ST_DC || panel->GetSimType() == ST_SP ) + { + menu.Append( MYID_MEASURE_MIN, _( "Measure Min" ) ); + menu.Append( MYID_MEASURE_MAX, _( "Measure Max" ) ); + menu.Append( MYID_MEASURE_AVG, _( "Measure Average" ) ); + menu.Append( MYID_MEASURE_RMS, _( "Measure RMS" ) ); + menu.Append( MYID_MEASURE_PP, _( "Measure Peak-to-peak" ) ); + menu.Append( MYID_MEASURE_MIN_AT, _( "Measure Time of Min" ) ); + menu.Append( MYID_MEASURE_MAX_AT, _( "Measure Time of Max" ) ); + menu.Append( MYID_MEASURE_INTEGRAL, _( "Measure Integral" ) ); - menu.AppendSeparator(); + if( panel->GetSimType() == ST_TRAN ) + { + menu.AppendSeparator(); + menu.Append( MYID_FOURIER, _( "Perform Fourier Analysis..." ) ); + } + + menu.AppendSeparator(); + } + } } GRID_TRICKS::showPopupMenu( menu, aEvent ); @@ -588,10 +590,12 @@ void SIMULATOR_PANEL::InitWorkbook() if( !LoadWorkbook( filename.GetFullPath() ) ) simulator()->Settings()->SetWorkbookFilename( "" ); } - else if( m_simulatorFrame->LoadSimulator() ) + else if( m_simulatorFrame->LoadSimulator( wxEmptyString, 0 ) ) { - if( !circuitModel()->GetSchTextSimCommand().IsEmpty() ) - NewPlotPanel( circuitModel()->GetSchTextSimCommand(), circuitModel()->GetSimOptions() ); + wxString schTextSimCommand = circuitModel()->GetSchTextSimCommand(); + + if( !schTextSimCommand.IsEmpty() ) + NewPlotPanel( schTextSimCommand, NETLIST_EXPORTER_SPICE::OPTION_DEFAULT_FLAGS ); rebuildSignalsList(); rebuildSignalsGrid( m_filter->GetValue() ); @@ -627,16 +631,34 @@ void SIMULATOR_PANEL::rebuildSignalsGrid( wxString aFilter ) if( aFilter.IsEmpty() ) aFilter = wxS( "*" ); - EDA_COMBINED_MATCHER matcher( aFilter, CTX_SIGNAL ); - SIM_PLOT_PANEL* plotPanel = GetCurrentPlot(); - int row = 0; + EDA_COMBINED_MATCHER matcher( aFilter.Upper(), CTX_SIGNAL ); + SIM_PLOT_PANEL* plotPanel = dynamic_cast( GetCurrentPlotPanel() ); + std::vector signals; + int row = 0; - for( const wxString& signal : m_signals ) + wxCHECK( plotPanel, /* void */ ); + + if( plotPanel->GetSimType() == ST_FFT ) { - if( matcher.StartsWith( signal ) ) + wxStringTokenizer tokenizer( plotPanel->GetSimCommand(), wxT( " \t\r\n" ), wxTOKEN_STRTOK ); + + while( tokenizer.HasMoreTokens() && tokenizer.GetNextToken().Lower() != wxT( "fft" ) ) + {}; + + while( tokenizer.HasMoreTokens() ) + signals.emplace_back( tokenizer.GetNextToken() ); + } + else + { + signals.insert( signals.end(), m_signals.begin(), m_signals.end() ); + } + + for( const wxString& signal : signals ) + { + if( matcher.Find( signal.Upper() ) ) { int traceType = SPT_UNKNOWN; - wxString vectorName = vectorNameFromSignalName( signal, &traceType ); + wxString vectorName = vectorNameFromSignalName( plotPanel, signal, &traceType ); TRACE* trace = plotPanel ? plotPanel->GetTrace( vectorName, traceType ) : nullptr; m_signalsGrid->AppendRows( 1 ); @@ -714,7 +736,7 @@ void SIMULATOR_PANEL::rebuildSignalsList() wxString unconnected = wxString( wxS( "unconnected-(" ) ); if( simType == ST_UNKNOWN ) - simType = ST_TRANSIENT; + simType = ST_TRAN; unconnected.Replace( '(', '_' ); // Convert to SPICE markup @@ -726,7 +748,7 @@ void SIMULATOR_PANEL::rebuildSignalsList() m_signals.push_back( aSignalName + _( " (gain)" ) ); m_signals.push_back( aSignalName + _( " (phase)" ) ); } - else if( simType == ST_S_PARAM ) + else if( simType == ST_SP ) { m_signals.push_back( aSignalName + _( " (amplitude)" ) ); m_signals.push_back( aSignalName + _( " (phase)" ) ); @@ -738,7 +760,7 @@ void SIMULATOR_PANEL::rebuildSignalsList() }; if( ( options & NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_VOLTAGES ) - && ( simType == ST_TRANSIENT || simType == ST_DC || simType == ST_AC ) ) + && ( simType == ST_TRAN || simType == ST_DC || simType == ST_AC || simType == ST_FFT) ) { for( const std::string& net : circuitModel()->GetNets() ) { @@ -754,7 +776,7 @@ void SIMULATOR_PANEL::rebuildSignalsList() } if( ( options & NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_CURRENTS ) - && ( simType == ST_TRANSIENT || simType == ST_DC ) ) + && ( simType == ST_TRAN || simType == ST_DC ) ) { for( const SPICE_ITEM& item : circuitModel()->GetItems() ) { @@ -765,7 +787,7 @@ void SIMULATOR_PANEL::rebuildSignalsList() } if( ( options & NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_DISSIPATIONS ) - && ( simType == ST_TRANSIENT || simType == ST_DC ) ) + && ( simType == ST_TRAN || simType == ST_DC ) ) { for( const SPICE_ITEM& item : circuitModel()->GetItems() ) { @@ -783,7 +805,7 @@ void SIMULATOR_PANEL::rebuildSignalsList() addSignal( wxS( "onoise_spectrum" ) ); } - if( simType == ST_S_PARAM ) + if( simType == ST_SP ) { std::vector portnums; @@ -845,14 +867,15 @@ void SIMULATOR_PANEL::rebuildSignalsList() } -SIM_PLOT_PANEL_BASE* SIMULATOR_PANEL::NewPlotPanel( const wxString& aSimCommand, int aOptions ) +SIM_PLOT_PANEL_BASE* SIMULATOR_PANEL::NewPlotPanel( const wxString& aSimCommand, + unsigned aSimOptions ) { SIM_PLOT_PANEL_BASE* plotPanel = nullptr; SIM_TYPE simType = NGSPICE_CIRCUIT_MODEL::CommandToSimType( aSimCommand ); if( SIM_PLOT_PANEL_BASE::IsPlottable( simType ) ) { - SIM_PLOT_PANEL* panel = new SIM_PLOT_PANEL( aSimCommand, aOptions, m_plotNotebook, wxID_ANY ); + SIM_PLOT_PANEL* panel = new SIM_PLOT_PANEL( aSimCommand, aSimOptions, m_plotNotebook ); plotPanel = panel; COMMON_SETTINGS::INPUT cfg = Pgm().GetCommonSettings()->m_Input; @@ -860,7 +883,7 @@ SIM_PLOT_PANEL_BASE* SIMULATOR_PANEL::NewPlotPanel( const wxString& aSimCommand, } else { - plotPanel = new SIM_NOPLOT_PANEL( aSimCommand, aOptions, m_plotNotebook, wxID_ANY ); + plotPanel = new SIM_NOPLOT_PANEL( aSimCommand, aSimOptions, m_plotNotebook ); } wxString pageTitle( simulator()->TypeToName( simType, true ) ); @@ -904,7 +927,8 @@ wxString vectorNameFromSignalId( int aUserDefinedSignalId ) * For user-defined signals we display the user-oriented signal name such as "V(out)-V(in)", * but the simulator vector we actually have to plot will be "user0" or some-such. */ -wxString SIMULATOR_PANEL::vectorNameFromSignalName( const wxString& aSignalName, int* aTraceType ) +wxString SIMULATOR_PANEL::vectorNameFromSignalName( SIM_PLOT_PANEL* aPlotPanel, + const wxString& aSignalName, int* aTraceType ) { std::map suffixes; suffixes[ _( " (amplitude)" ) ] = SPT_SP_AMP; @@ -913,7 +937,7 @@ wxString SIMULATOR_PANEL::vectorNameFromSignalName( const wxString& aSignalName, if( aTraceType ) { - if( circuitModel()->GetSimType() == ST_NOISE ) + if( aPlotPanel && aPlotPanel->GetSimType() == ST_NOISE ) { if( getNoiseSource().Upper().StartsWith( 'I' ) ) *aTraceType = SPT_CURRENT; @@ -967,17 +991,17 @@ void SIMULATOR_PANEL::onSignalsGridCellChanged( wxGridEvent& aEvent ) int row = aEvent.GetRow(); int col = aEvent.GetCol(); wxString text = m_signalsGrid->GetCellValue( row, col ); - SIM_PLOT_PANEL* plot = GetCurrentPlot(); + SIM_PLOT_PANEL* plotPanel = dynamic_cast( GetCurrentPlotPanel() ); wxString signalName = m_signalsGrid->GetCellValue( row, COL_SIGNAL_NAME ); int traceType = SPT_UNKNOWN; - wxString vectorName = vectorNameFromSignalName( signalName, &traceType ); + wxString vectorName = vectorNameFromSignalName( plotPanel, signalName, &traceType ); if( col == COL_SIGNAL_SHOW ) { if( text == wxS( "1" ) ) - updateTrace( vectorName, traceType, plot ); + updateTrace( vectorName, traceType, plotPanel ); else - plot->DeleteTrace( vectorName, traceType ); + plotPanel->DeleteTrace( vectorName, traceType ); // Update enabled/visible states of other controls updateSignalsGrid(); @@ -987,13 +1011,13 @@ void SIMULATOR_PANEL::onSignalsGridCellChanged( wxGridEvent& aEvent ) else if( col == COL_SIGNAL_COLOR ) { KIGFX::COLOR4D color( m_signalsGrid->GetCellValue( row, COL_SIGNAL_COLOR ) ); - TRACE* trace = plot->GetTrace( vectorName, traceType ); + TRACE* trace = plotPanel->GetTrace( vectorName, traceType ); if( trace ) { trace->SetTraceColour( color.ToColour() ); - plot->UpdateTraceStyle( trace ); - plot->UpdatePlotColors(); + plotPanel->UpdateTraceStyle( trace ); + plotPanel->UpdatePlotColors(); m_simulatorFrame->OnModify(); } } @@ -1002,12 +1026,12 @@ void SIMULATOR_PANEL::onSignalsGridCellChanged( wxGridEvent& aEvent ) for( int ii = 0; ii < m_signalsGrid->GetNumberRows(); ++ii ) { signalName = m_signalsGrid->GetCellValue( ii, COL_SIGNAL_NAME ); - vectorName = vectorNameFromSignalName( signalName, &traceType ); + vectorName = vectorNameFromSignalName( plotPanel, signalName, &traceType ); int id = col == COL_CURSOR_1 ? 1 : 2; bool enable = ii == row && text == wxS( "1" ); - plot->EnableCursor( vectorName, traceType, id, enable, signalName ); + plotPanel->EnableCursor( vectorName, traceType, id, enable, signalName ); m_simulatorFrame->OnModify(); } @@ -1022,7 +1046,7 @@ void SIMULATOR_PANEL::onCursorsGridCellChanged( wxGridEvent& aEvent ) if( m_SuppressGridEvents > 0 ) return; - SIM_PLOT_PANEL* plotPanel = GetCurrentPlot(); + SIM_PLOT_PANEL* plotPanel = dynamic_cast( GetCurrentPlotPanel() ); if( !plotPanel ) return; @@ -1092,7 +1116,7 @@ void SIMULATOR_PANEL::DeleteMeasurement( int aRow ) void SIMULATOR_PANEL::onMeasurementsGridCellChanged( wxGridEvent& aEvent ) { - SIM_PLOT_PANEL* plotPanel = GetCurrentPlot(); + SIM_PLOT_PANEL* plotPanel = dynamic_cast( GetCurrentPlotPanel() ); if( !plotPanel ) return; @@ -1158,7 +1182,7 @@ void SIMULATOR_PANEL::UpdateMeasurement( int aRow ) " +" "([a-zA-Z])\\(([^\\)]+)\\)" ) ); - SIM_PLOT_PANEL* plotPanel = GetCurrentPlot(); + SIM_PLOT_PANEL* plotPanel = dynamic_cast( GetCurrentPlotPanel() ); if( !plotPanel ) return; @@ -1200,23 +1224,24 @@ void SIMULATOR_PANEL::UpdateMeasurement( int aRow ) { switch( plotPanel->GetSimType() ) { - case SIM_TYPE::ST_TRANSIENT: + case SIM_TYPE::ST_TRAN: if ( signalType == 'P' ) units = wxS( "J" ); else units += wxS( ".s" ); break; case SIM_TYPE::ST_AC: - case SIM_TYPE::ST_S_PARAM: - case SIM_TYPE::ST_DISTORTION: + case SIM_TYPE::ST_SP: + case SIM_TYPE::ST_DISTO: case SIM_TYPE::ST_NOISE: - case SIM_TYPE::ST_SENSITIVITY: // If there is a vector, it is frequency + case SIM_TYPE::ST_FFT: + case SIM_TYPE::ST_SENS: // If there is a vector, it is frequency units += wxS( "·Hz" ); break; case SIM_TYPE::ST_DC: // Could be a lot of things : V, A, deg C, ohm, ... case SIM_TYPE::ST_OP: // There is no vector for integration - case SIM_TYPE::ST_POLE_ZERO: // There is no vector for integration - case SIM_TYPE::ST_TRANS_FUNC: // There is no vector for integration + case SIM_TYPE::ST_PZ: // There is no vector for integration + case SIM_TYPE::ST_TF: // There is no vector for integration default: units += wxS( "·?" ); @@ -1246,7 +1271,7 @@ void SIMULATOR_PANEL::UpdateMeasurement( int aRow ) void SIMULATOR_PANEL::AddTuner( const SCH_SHEET_PATH& aSheetPath, SCH_SYMBOL* aSymbol ) { - SIM_PLOT_PANEL_BASE* plotPanel = GetCurrentPlotWindow(); + SIM_PLOT_PANEL* plotPanel = dynamic_cast( GetCurrentPlotPanel() ); if( !plotPanel ) return; @@ -1332,7 +1357,7 @@ void SIMULATOR_PANEL::AddMeasurement( const wxString& aCmd ) return; // Don't create duplicates } - SIM_PLOT_PANEL* plotPanel = GetCurrentPlot(); + SIM_PLOT_PANEL* plotPanel = dynamic_cast( GetCurrentPlotPanel() ); if( !plotPanel ) return; @@ -1384,16 +1409,14 @@ const NGSPICE_CIRCUIT_MODEL* SIMULATOR_PANEL::GetExporter() const void SIMULATOR_PANEL::AddTrace( const wxString& aName, SIM_TRACE_TYPE aType ) { - SIM_PLOT_PANEL* plotPanel = GetCurrentPlot(); - - if( !plotPanel ) + if( !GetCurrentPlotPanel() ) { m_simConsole->AppendText( _( "Error: no current simulation.\n" ) ); m_simConsole->SetInsertionPointEnd(); return; } - SIM_TYPE simType = NGSPICE_CIRCUIT_MODEL::CommandToSimType( plotPanel->GetSimCommand() ); + SIM_TYPE simType = NGSPICE_CIRCUIT_MODEL::CommandToSimType( GetCurrentPlotPanel()->GetSimCommand() ); if( simType == ST_UNKNOWN ) { @@ -1408,12 +1431,15 @@ void SIMULATOR_PANEL::AddTrace( const wxString& aName, SIM_TRACE_TYPE aType ) return; } + SIM_PLOT_PANEL* plotPanel = dynamic_cast( GetCurrentPlotPanel() ); + wxCHECK( plotPanel, /* void */ ); + if( simType == ST_AC ) { updateTrace( aName, aType | SPT_AC_GAIN, plotPanel ); updateTrace( aName, aType | SPT_AC_PHASE, plotPanel ); } - if( simType == ST_S_PARAM ) + else if( simType == ST_SP ) { updateTrace( aName, aType | SPT_AC_GAIN, plotPanel ); updateTrace( aName, aType | SPT_AC_PHASE, plotPanel ); @@ -1440,7 +1466,7 @@ void SIMULATOR_PANEL::SetUserDefinedSignals( const std::map& aNew for( const auto& [ id, existingSignal ] : m_userDefinedSignals ) { int traceType = SPT_UNKNOWN; - wxString vectorName = vectorNameFromSignalName( existingSignal, &traceType ); + wxString vectorName = vectorNameFromSignalName( plotPanel, existingSignal, &traceType ); if( aNewSignals.count( id ) == 0 ) { @@ -1449,7 +1475,7 @@ void SIMULATOR_PANEL::SetUserDefinedSignals( const std::map& aNew for( int subType : { SPT_AC_GAIN, SPT_AC_PHASE } ) plotPanel->DeleteTrace( vectorName, traceType | subType ); } - else if( plotPanel->GetSimType() == ST_S_PARAM ) + else if( plotPanel->GetSimType() == ST_SP ) { for( int subType : { SPT_SP_AMP, SPT_AC_PHASE } ) plotPanel->DeleteTrace( vectorName, traceType | subType ); @@ -1469,7 +1495,7 @@ void SIMULATOR_PANEL::SetUserDefinedSignals( const std::map& aNew trace->SetName( aNewSignals.at( id ) ); } } - else if( plotPanel->GetSimType() == ST_S_PARAM ) + else if( plotPanel->GetSimType() == ST_SP ) { for( int subType : { SPT_SP_AMP, SPT_AC_PHASE } ) { @@ -1542,7 +1568,7 @@ void SIMULATOR_PANEL::updateTrace( const wxString& aVectorName, int aTraceType, wxFAIL_MSG( wxT( "Plot type missing AC_PHASE or AC_MAG bit" ) ); break; - case ST_S_PARAM: + case ST_SP: if( aTraceType & SPT_SP_AMP ) data_y = simulator()->GetGainVector( (const char*) simVectorName.c_str() ); else if( aTraceType & SPT_AC_PHASE ) @@ -1554,7 +1580,8 @@ void SIMULATOR_PANEL::updateTrace( const wxString& aVectorName, int aTraceType, case ST_NOISE: case ST_DC: - case ST_TRANSIENT: + case ST_TRAN: + case ST_FFT: data_y = simulator()->GetGainVector( (const char*) simVectorName.c_str() ); break; @@ -1569,7 +1596,7 @@ void SIMULATOR_PANEL::updateTrace( const wxString& aVectorName, int aTraceType, SPICE_DC_PARAMS source1, source2; if( simType == ST_DC - && circuitModel()->ParseDCCommand( circuitModel()->GetSimCommand(), &source1, &source2 ) + && circuitModel()->ParseDCCommand( aPlotPanel->GetSimCommand(), &source1, &source2 ) && !source2.m_source.IsEmpty() ) { // Source 1 is the inner loop, so lets add traces for each Source 2 (outer loop) step @@ -1610,15 +1637,15 @@ void SIMULATOR_PANEL::updateTrace( const wxString& aVectorName, int aTraceType, void SIMULATOR_PANEL::updateSignalsGrid() { - SIM_PLOT_PANEL* plot = GetCurrentPlot(); + SIM_PLOT_PANEL* plotPanel = dynamic_cast( GetCurrentPlotPanel() ); for( int row = 0; row < m_signalsGrid->GetNumberRows(); ++row ) { wxString signalName = m_signalsGrid->GetCellValue( row, COL_SIGNAL_NAME ); int traceType = SPT_UNKNOWN; - wxString vectorName = vectorNameFromSignalName( signalName, &traceType ); + wxString vectorName = vectorNameFromSignalName( plotPanel, signalName, &traceType ); - if( TRACE* trace = plot ? plot->GetTrace( vectorName, traceType ) : nullptr ) + if( TRACE* trace = plotPanel ? plotPanel->GetTrace( vectorName, traceType ) : nullptr ) { m_signalsGrid->SetCellValue( row, COL_SIGNAL_SHOW, wxS( "1" ) ); @@ -1941,26 +1968,30 @@ bool SIMULATOR_PANEL::LoadWorkbook( const wxString& aPath ) if( plotPanel ) traceInfo[ plotPanel ].emplace_back( std::make_tuple( traceType, name, param ) ); } + + if( version > 4 ) + { + long measurementCount; + + file.GetNextLine().ToLong( &measurementCount ); + + for( int ii = 0; ii < (int) measurementCount; ++ ii ) + { + wxString measurement = file.GetNextLine(); + wxString format = file.GetNextLine(); + + if( plotPanel ) + plotPanel->Measurements().emplace_back( measurement, format ); + } + } } long userDefinedSignalCount; - long measurementCount; if( file.GetNextLine().ToLong( &userDefinedSignalCount ) ) { for( int ii = 0; ii < (int) userDefinedSignalCount; ++ii ) m_userDefinedSignals[ ii ] = file.GetNextLine(); - - file.GetNextLine().ToLong( &measurementCount ); - - m_measurementsGrid->ClearRows(); - m_measurementsGrid->AppendRows( (int) measurementCount + 1 /* empty row at end */ ); - - for( int row = 0; row < (int) measurementCount; ++row ) - { - m_measurementsGrid->SetCellValue( row, COL_MEASUREMENT, file.GetNextLine() ); - m_measurementsGrid->SetCellValue( row, COL_MEASUREMENT_FORMAT, file.GetNextLine() ); - } } for( const auto& [ plotPanel, traceInfoVector ] : traceInfo ) @@ -1985,7 +2016,7 @@ bool SIMULATOR_PANEL::LoadWorkbook( const wxString& aPath ) } else { - wxString vectorName = vectorNameFromSignalName( signalName, nullptr ); + wxString vectorName = vectorNameFromSignalName( plotPanel, signalName, nullptr ); TRACE* trace = plotPanel->AddTrace( vectorName, (int) traceType ); if( version >= 4 && trace ) @@ -1996,35 +2027,15 @@ bool SIMULATOR_PANEL::LoadWorkbook( const wxString& aPath ) plotPanel->UpdatePlotColors(); } - m_simulatorFrame->LoadSimulator(); - - wxString schTextSimCommand = circuitModel()->GetSchTextSimCommand().Lower(); - SIM_TYPE schTextSimType = NGSPICE_CIRCUIT_MODEL::CommandToSimType( schTextSimCommand ); - - if( schTextSimType != ST_UNKNOWN ) + if( SIM_PLOT_PANEL_BASE* plotPanel = GetCurrentPlotPanel() ) { - bool found = false; + m_simulatorFrame->LoadSimulator( plotPanel->GetSimCommand(), plotPanel->GetSimOptions() ); - for( int ii = 0; ii < (int) m_plotNotebook->GetPageCount(); ++ii ) + if( version >= 5 ) { - auto* plot = dynamic_cast( m_plotNotebook->GetPage( ii ) ); - - if( plot && plot->GetSimType() == schTextSimType ) - { - if( schTextSimType == ST_DC ) - { - wxString plotSimCommand = plot->GetSimCommand().Lower(); - found = plotSimCommand.GetChar( 4 ) == schTextSimCommand.GetChar( 4 ); - } - else - { - found = true; - } - } + plotPanel = dynamic_cast( m_plotNotebook->GetPage( 0 ) ); + plotPanel->SetLastSchTextSimCommand( file.GetNextLine() ); } - - if( !found ) - NewPlotPanel( schTextSimCommand, circuitModel()->GetSimOptions() ); } rebuildSignalsList(); @@ -2032,6 +2043,7 @@ bool SIMULATOR_PANEL::LoadWorkbook( const wxString& aPath ) rebuildSignalsGrid( m_filter->GetValue() ); updateSignalsGrid(); updatePlotCursors(); + rebuildMeasurementsGrid(); file.Close(); @@ -2064,13 +2076,13 @@ bool SIMULATOR_PANEL::SaveWorkbook( const wxString& aPath ) file.Create(); } - file.AddLine( wxT( "version 4" ) ); + file.AddLine( wxT( "version 5" ) ); file.AddLine( wxString::Format( wxT( "%llu" ), m_plotNotebook->GetPageCount() ) ); for( size_t i = 0; i < m_plotNotebook->GetPageCount(); i++ ) { - auto* basePanel = dynamic_cast( m_plotNotebook->GetPage( i ) ); + auto* basePanel = dynamic_cast( m_plotNotebook->GetPage( i ) ); if( !basePanel ) { @@ -2097,7 +2109,7 @@ bool SIMULATOR_PANEL::SaveWorkbook( const wxString& aPath ) file.AddLine( EscapeString( command, CTX_LINE ) ); - const SIM_PLOT_PANEL* plotPanel = dynamic_cast( basePanel ); + SIM_PLOT_PANEL* plotPanel = dynamic_cast( basePanel ); if( !plotPanel ) { @@ -2171,6 +2183,14 @@ bool SIMULATOR_PANEL::SaveWorkbook( const wxString& aPath ) plotPanel->GetLegendPosition().x, plotPanel->GetLegendPosition().y - 40 ) ); } + + file.AddLine( wxString::Format( wxT( "%llu" ), plotPanel->Measurements().size() ) ); + + for( const auto& [ measurement, format ] : plotPanel->Measurements() ) + { + file.AddLine( measurement ); + file.AddLine( format ); + } } file.AddLine( wxString::Format( wxT( "%llu" ), m_userDefinedSignals.size() ) ); @@ -2178,25 +2198,18 @@ bool SIMULATOR_PANEL::SaveWorkbook( const wxString& aPath ) for( const auto& [ id, signal ] : m_userDefinedSignals ) file.AddLine( signal ); - std::vector measurements; - std::vector formats; + // Store the value of any simulation command found on the schematic sheet in a SCH_TEXT + // object. If this changes we want to warn the user and ask them if they want to update + // the corresponding panel's sim command. + wxString lastSchTextSimCommand; - for( int i = 0; i < m_measurementsGrid->GetNumberRows(); ++i ) + if( m_plotNotebook->GetPageCount() > 0 ) { - if( !m_measurementsGrid->GetCellValue( i, COL_MEASUREMENT ).IsEmpty() ) - { - measurements.push_back( m_measurementsGrid->GetCellValue( i, COL_MEASUREMENT ) ); - formats.push_back( m_measurementsGrid->GetCellValue( i, COL_MEASUREMENT_FORMAT ) ); - } + auto* basePanel = dynamic_cast( m_plotNotebook->GetPage( 0 ) ); + lastSchTextSimCommand = basePanel->GetLastSchTextSimCommand(); } - file.AddLine( wxString::Format( wxT( "%llu" ), measurements.size() ) ); - - for( size_t i = 0; i < measurements.size(); i++ ) - { - file.AddLine( measurements[i] ); - file.AddLine( formats[i] ); - } + file.AddLine( lastSchTextSimCommand ); bool res = file.Write(); file.Close(); @@ -2217,12 +2230,13 @@ SIM_TRACE_TYPE SIMULATOR_PANEL::getXAxisType( SIM_TYPE aType ) const switch( aType ) { /// @todo SPT_LOG_FREQUENCY - case ST_AC: return SPT_LIN_FREQUENCY; - case ST_S_PARAM: return SPT_LIN_FREQUENCY; - case ST_DC: return SPT_SWEEP; - case ST_TRANSIENT: return SPT_TIME; - case ST_NOISE: return SPT_LIN_FREQUENCY; - default: wxFAIL_MSG( wxS( "Unhandled simulation type" ) ); return SPT_UNKNOWN; + case ST_AC: return SPT_LIN_FREQUENCY; + case ST_SP: return SPT_LIN_FREQUENCY; + case ST_FFT: return SPT_LIN_FREQUENCY; + case ST_DC: return SPT_SWEEP; + case ST_TRAN: return SPT_TIME; + case ST_NOISE: return SPT_LIN_FREQUENCY; + default: wxFAIL_MSG( wxS( "Unhandled simulation type" ) ); return SPT_UNKNOWN; } } @@ -2238,8 +2252,11 @@ wxString SIMULATOR_PANEL::getNoiseSource() const SPICE_VALUE fStop; bool saveAll; - circuitModel()->ParseNoiseCommand( circuitModel()->GetSimCommand(), &output, &ref, &source, - &scale, &pts, &fStart, &fStop, &saveAll ); + if( GetCurrentPlotPanel() ) + { + circuitModel()->ParseNoiseCommand( GetCurrentPlotPanel()->GetSimCommand(), &output, &ref, + &source, &scale, &pts, &fStart, &fStop, &saveAll ); + } return source; } @@ -2280,7 +2297,7 @@ void SIMULATOR_PANEL::onPlotClosed( wxAuiNotebookEvent& event ) rebuildSignalsGrid( m_filter->GetValue() ); updatePlotCursors(); - SIM_PLOT_PANEL_BASE* panel = GetCurrentPlotWindow(); + SIM_PLOT_PANEL_BASE* panel = GetCurrentPlotPanel(); if( !panel || panel->GetSimType() != ST_OP ) { @@ -2293,11 +2310,72 @@ void SIMULATOR_PANEL::onPlotClosed( wxAuiNotebookEvent& event ) } -void SIMULATOR_PANEL::onPlotChanged( wxAuiNotebookEvent& event ) +void SIMULATOR_PANEL::onPlotChanging( wxAuiNotebookEvent& event ) +{ + if( SIM_PLOT_PANEL* plotPanel = dynamic_cast( GetCurrentPlotPanel() ) ) + { + std::vector>& measurements = plotPanel->Measurements(); + + measurements.clear(); + + for( int row = 0; row < m_measurementsGrid->GetNumberRows(); ++row ) + { + if( !m_measurementsGrid->GetCellValue( row, COL_MEASUREMENT ).IsEmpty() ) + { + measurements.emplace_back( m_measurementsGrid->GetCellValue( row, COL_MEASUREMENT ), + m_measurementsGrid->GetCellValue( row, COL_MEASUREMENT_FORMAT ) ); + } + } + } + + event.Skip(); +} + + +void SIMULATOR_PANEL::OnPlotSettingsChanged() { rebuildSignalsList(); rebuildSignalsGrid( m_filter->GetValue() ); updatePlotCursors(); + + rebuildMeasurementsGrid(); + + for( int row = 0; row < m_measurementsGrid->GetNumberRows(); ++row ) + UpdateMeasurement( row ); +} + + +void SIMULATOR_PANEL::onPlotChanged( wxAuiNotebookEvent& event ) +{ + if( SIM_PLOT_PANEL_BASE* plotWindow = GetCurrentPlotPanel() ) + simulator()->Command( "setplot " + plotWindow->GetSpicePlotName().ToStdString() ); + + OnPlotSettingsChanged(); + + event.Skip(); +} + + +void SIMULATOR_PANEL::rebuildMeasurementsGrid() +{ + m_measurementsGrid->ClearRows(); + + if( SIM_PLOT_PANEL* plotPanel = dynamic_cast( GetCurrentPlotPanel() ) ) + { + for( const auto& [ measurement, format ] : plotPanel->Measurements() ) + { + int row = m_measurementsGrid->GetNumberRows(); + m_measurementsGrid->AppendRows(); + m_measurementsGrid->SetCellValue( row, COL_MEASUREMENT, measurement ); + m_measurementsGrid->SetCellValue( row, COL_MEASUREMENT_FORMAT, format ); + } + + if( plotPanel->GetSimType() == ST_TRAN || plotPanel->GetSimType() == ST_AC + || plotPanel->GetSimType() == ST_DC || plotPanel->GetSimType() == ST_SP ) + { + m_measurementsGrid->AppendRows(); // Empty row at end + } + } } @@ -2331,7 +2409,7 @@ void SIMULATOR_PANEL::updatePlotCursors() m_cursorsGrid->ClearRows(); - SIM_PLOT_PANEL* plotPanel = GetCurrentPlot(); + SIM_PLOT_PANEL* plotPanel = dynamic_cast( GetCurrentPlotPanel() ); if( !plotPanel ) return; @@ -2469,7 +2547,7 @@ void SIMULATOR_PANEL::onPlotCursorUpdate( wxCommandEvent& aEvent ) void SIMULATOR_PANEL::OnSimUpdate() { - if( SIM_PLOT_PANEL* plotPanel = dynamic_cast( GetCurrentPlotWindow() ) ) + if( SIM_PLOT_PANEL* plotPanel = dynamic_cast( GetCurrentPlotPanel() ) ) plotPanel->ResetScales( true ); m_simConsole->Clear(); @@ -2488,7 +2566,7 @@ void SIMULATOR_PANEL::OnSimReport( const wxString& aMsg ) } -std::vector SIMULATOR_PANEL::Signals() const +std::vector SIMULATOR_PANEL::SimPlotVectors() const { std::vector signals; @@ -2499,20 +2577,32 @@ std::vector SIMULATOR_PANEL::Signals() const } +std::vector SIMULATOR_PANEL::Signals() const +{ + std::vector signals; + + for( const wxString& signal : m_signals ) + signals.emplace_back( signal ); + + for( const auto& [ id, signal ] : m_userDefinedSignals ) + signals.emplace_back( signal ); + + return signals; +} + + void SIMULATOR_PANEL::OnSimRefresh( bool aFinal ) { - SIM_TYPE simType = circuitModel()->GetSimType(); - SIM_PLOT_PANEL_BASE* plotPanelWindow = GetCurrentPlotWindow(); + SIM_PLOT_PANEL_BASE* plotPanelBase = GetCurrentPlotPanel(); - if( !plotPanelWindow || plotPanelWindow->GetSimType() != simType ) - { - plotPanelWindow = NewPlotPanel( circuitModel()->GetSimCommand(), - circuitModel()->GetSimOptions() ); - } + if( !plotPanelBase ) + return; + SIM_TYPE simType = plotPanelBase->GetSimType(); std::vector oldSignals = m_signals; wxString msg; + plotPanelBase->SetSpicePlotName( simulator()->CurrentPlotName() ); applyUserDefinedSignals(); rebuildSignalsList(); @@ -2527,7 +2617,8 @@ void SIMULATOR_PANEL::OnSimRefresh( bool aFinal ) // The simulator will create noise1 & noise2 on the first run, noise3 and noise4 // on the second, etc. The first plot for each run contains the spectral density // noise vectors and second contains the integrated noise. - simulator()->Command( "setplot noise2" ); + long number; + simulator()->CurrentPlotName().Mid( 5 ).ToLong( &number ); for( const std::string& vec : simulator()->AllVectors() ) { @@ -2540,10 +2631,11 @@ void SIMULATOR_PANEL::OnSimRefresh( bool aFinal ) m_simConsole->SetInsertionPointEnd(); } - simulator()->Command( "setplot noise1" ); + simulator()->Command( fmt::format( "setplot noise{}", number - 1 ) ); + plotPanelBase->SetSpicePlotName( simulator()->CurrentPlotName() ); } - SIM_PLOT_PANEL* plotPanel = dynamic_cast( plotPanelWindow ); + SIM_PLOT_PANEL* plotPanel = dynamic_cast( plotPanelBase ); wxCHECK_RET( plotPanel, wxT( "not a SIM_PLOT_PANEL" ) ); // Map of TRACE* to { vectorName, traceType } @@ -2555,7 +2647,7 @@ void SIMULATOR_PANEL::OnSimRefresh( bool aFinal ) for( const wxString& signal : m_signals ) { int traceType = SPT_UNKNOWN; - wxString vectorName = vectorNameFromSignalName( signal, &traceType ); + wxString vectorName = vectorNameFromSignalName( plotPanel, signal, &traceType ); if( simType == ST_AC ) { @@ -2565,7 +2657,7 @@ void SIMULATOR_PANEL::OnSimRefresh( bool aFinal ) traceMap[ trace ] = { vectorName, traceType }; } } - if( simType == ST_S_PARAM ) + else if( simType == ST_SP ) { for( int subType : { SPT_SP_AMP, SPT_AC_PHASE } ) { @@ -2603,6 +2695,11 @@ void SIMULATOR_PANEL::OnSimRefresh( bool aFinal ) plotPanel->ResetScales( true ); plotPanel->GetPlotWin()->Fit(); + + updatePlotCursors(); + + for( int row = 0; row < m_measurementsGrid->GetNumberRows(); ++row ) + UpdateMeasurement( row ); } else if( simType == ST_OP ) { @@ -2634,11 +2731,6 @@ void SIMULATOR_PANEL::OnSimRefresh( bool aFinal ) m_schematicFrame->Schematic().SetOperatingPoint( signal, val_list.at( 0 ) ); } } - - updatePlotCursors(); - - for( int row = 0; row < m_measurementsGrid->GetNumberRows(); ++row ) - UpdateMeasurement( row ); } diff --git a/eeschema/sim/simulator_panel.h b/eeschema/sim/simulator_panel.h index 911ba2d88f..50b830d51e 100644 --- a/eeschema/sim/simulator_panel.h +++ b/eeschema/sim/simulator_panel.h @@ -79,7 +79,9 @@ public: * @param aSimOptions netlisting options * @return The new plot panel. */ - SIM_PLOT_PANEL_BASE* NewPlotPanel( const wxString& aSimCommand, int aSimOptions ); + SIM_PLOT_PANEL_BASE* NewPlotPanel( const wxString& aSimCommand, unsigned aSimOptions ); + + std::vector SimPlotVectors() const; std::vector Signals() const; @@ -194,23 +196,22 @@ public: /** * Return the currently opened plot panel (or NULL if there is none). */ - SIM_PLOT_PANEL_BASE* GetCurrentPlotWindow() const + SIM_PLOT_PANEL_BASE* GetCurrentPlotPanel() const { return dynamic_cast( m_plotNotebook->GetCurrentPage() ); } - /** - * Return the current tab (or NULL if there is none). - */ - SIM_PLOT_PANEL* GetCurrentPlot() const + SIM_PLOT_PANEL_BASE* GetPlotPanel( SIM_TYPE aType ) const { - SIM_PLOT_PANEL_BASE* plotWindow = GetCurrentPlotWindow(); + for( int ii = 0; ii < (int) m_plotNotebook->GetPageCount(); ++ii ) + { + auto* candidate = dynamic_cast( m_plotNotebook->GetPage( ii ) ); - if( !plotWindow ) - return nullptr; + if( candidate && candidate->GetSimType() == aType ) + return candidate; + } - return plotWindow->GetSimType() == ST_UNKNOWN ? nullptr - : dynamic_cast( plotWindow ); + return nullptr; } int GetPlotIndex( SIM_PLOT_PANEL_BASE* aPlot ) const @@ -218,6 +219,8 @@ public: return m_plotNotebook->GetPageIndex( aPlot ); } + void OnPlotSettingsChanged(); + void OnSimUpdate(); void OnSimReport( const wxString& aMsg ); void OnSimRefresh( bool aFinal ); @@ -226,7 +229,8 @@ private: /** * Get the simulator output vector name for a given signal name and type. */ - wxString vectorNameFromSignalName( const wxString& aSignalName, int* aTraceType ); + wxString vectorNameFromSignalName( SIM_PLOT_PANEL* aPlotPanel, const wxString& aSignalName, + int* aTraceType ); /** * Update a trace in a particular SIM_PLOT_PANEL. If the panel does not contain the given @@ -265,6 +269,11 @@ private: */ void applyUserDefinedSignals(); + /** + * Rebuild the measurements grid for the current plot. + */ + void rebuildMeasurementsGrid(); + /** * Apply component values specified using tuner sliders to the current netlist. */ @@ -286,6 +295,7 @@ private: // Event handlers void onPlotClose( wxAuiNotebookEvent& event ) override; void onPlotClosed( wxAuiNotebookEvent& event ) override; + void onPlotChanging( wxAuiNotebookEvent& event ) override; void onPlotChanged( wxAuiNotebookEvent& event ) override; void onPlotDragged( wxAuiNotebookEvent& event ) override; diff --git a/eeschema/sim/simulator_panel_base.cpp b/eeschema/sim/simulator_panel_base.cpp index 908e024b30..cd6ad26b30 100644 --- a/eeschema/sim/simulator_panel_base.cpp +++ b/eeschema/sim/simulator_panel_base.cpp @@ -280,6 +280,7 @@ SIMULATOR_PANEL_BASE::SIMULATOR_PANEL_BASE( wxWindow* parent, wxWindowID id, con // Connect Events m_plotNotebook->Connect( wxEVT_COMMAND_AUINOTEBOOK_END_DRAG, wxAuiNotebookEventHandler( SIMULATOR_PANEL_BASE::onPlotDragged ), NULL, this ); m_plotNotebook->Connect( wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED, wxAuiNotebookEventHandler( SIMULATOR_PANEL_BASE::onPlotChanged ), NULL, this ); + m_plotNotebook->Connect( wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING, wxAuiNotebookEventHandler( SIMULATOR_PANEL_BASE::onPlotChanging ), NULL, this ); m_plotNotebook->Connect( wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSE, wxAuiNotebookEventHandler( SIMULATOR_PANEL_BASE::onPlotClose ), NULL, this ); m_plotNotebook->Connect( wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSED, wxAuiNotebookEventHandler( SIMULATOR_PANEL_BASE::onPlotClosed ), NULL, this ); m_filter->Connect( wxEVT_MOTION, wxMouseEventHandler( SIMULATOR_PANEL_BASE::OnFilterMouseMoved ), NULL, this ); @@ -294,6 +295,7 @@ SIMULATOR_PANEL_BASE::~SIMULATOR_PANEL_BASE() // Disconnect Events m_plotNotebook->Disconnect( wxEVT_COMMAND_AUINOTEBOOK_END_DRAG, wxAuiNotebookEventHandler( SIMULATOR_PANEL_BASE::onPlotDragged ), NULL, this ); m_plotNotebook->Disconnect( wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED, wxAuiNotebookEventHandler( SIMULATOR_PANEL_BASE::onPlotChanged ), NULL, this ); + m_plotNotebook->Disconnect( wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING, wxAuiNotebookEventHandler( SIMULATOR_PANEL_BASE::onPlotChanging ), NULL, this ); m_plotNotebook->Disconnect( wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSE, wxAuiNotebookEventHandler( SIMULATOR_PANEL_BASE::onPlotClose ), NULL, this ); m_plotNotebook->Disconnect( wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSED, wxAuiNotebookEventHandler( SIMULATOR_PANEL_BASE::onPlotClosed ), NULL, this ); m_filter->Disconnect( wxEVT_MOTION, wxMouseEventHandler( SIMULATOR_PANEL_BASE::OnFilterMouseMoved ), NULL, this ); diff --git a/eeschema/sim/simulator_panel_base.fbp b/eeschema/sim/simulator_panel_base.fbp index 76bbf5c639..1f954d0883 100644 --- a/eeschema/sim/simulator_panel_base.fbp +++ b/eeschema/sim/simulator_panel_base.fbp @@ -118,8 +118,8 @@ wxBORDER_NONE - - + + 1 1 1 @@ -170,16 +170,16 @@ wxTAB_TRAVERSAL - + -1,-1 m_sizer11 wxVERTICAL protected - + 5 wxEXPAND 1 - + 1 1 1 @@ -236,8 +236,8 @@ - - + + 1 1 1 @@ -288,7 +288,7 @@ wxTAB_TRAVERSAL - + m_sizerPlot wxHORIZONTAL @@ -353,6 +353,7 @@ onPlotDragged onPlotChanged + onPlotChanging onPlotClose onPlotClosed diff --git a/eeschema/sim/simulator_panel_base.h b/eeschema/sim/simulator_panel_base.h index dad1021adf..f0ddc5e6a1 100644 --- a/eeschema/sim/simulator_panel_base.h +++ b/eeschema/sim/simulator_panel_base.h @@ -67,6 +67,7 @@ class SIMULATOR_PANEL_BASE : public wxPanel // Virtual event handlers, override them in your derived class virtual void onPlotDragged( wxAuiNotebookEvent& event ) { event.Skip(); } virtual void onPlotChanged( wxAuiNotebookEvent& event ) { event.Skip(); } + virtual void onPlotChanging( wxAuiNotebookEvent& event ) { event.Skip(); } virtual void onPlotClose( wxAuiNotebookEvent& event ) { event.Skip(); } virtual void onPlotClosed( wxAuiNotebookEvent& event ) { event.Skip(); } virtual void OnFilterMouseMoved( wxMouseEvent& event ) { event.Skip(); } diff --git a/eeschema/sim/spice_simulator.cpp b/eeschema/sim/spice_simulator.cpp index d064b2b3f5..d159caae73 100644 --- a/eeschema/sim/spice_simulator.cpp +++ b/eeschema/sim/spice_simulator.cpp @@ -54,18 +54,19 @@ wxString SPICE_SIMULATOR::TypeToName( SIM_TYPE aType, bool aShortName ) { switch( aType ) { - case ST_OP: return aShortName ? wxString( wxT( "OP" ) ) : _( "Operating Point" ); - case ST_AC: return aShortName ? wxString( wxT( "AC" ) ) : _( "AC" ); - case ST_DC: return aShortName ? wxString( wxT( "DC" ) ) : _( "DC Sweep" ); - case ST_TRANSIENT: return aShortName ? wxString( wxT( "TRAN" ) ) : _( "Transient" ); - case ST_DISTORTION: return aShortName ? wxString( wxT( "DISTO" ) ) : _( "Distortion" ); - case ST_NOISE: return aShortName ? wxString( wxT( "NOISE" ) ) : _( "Noise" ); - case ST_POLE_ZERO: return aShortName ? wxString( wxT( "PZ" ) ) : _( "Pole-zero" ); - case ST_SENSITIVITY: return aShortName ? wxString( wxT( "SENS" ) ) : _( "Sensitivity" ); - case ST_TRANS_FUNC: return aShortName ? wxString( wxT( "TF" ) ) : _( "Transfer function" ); - case ST_S_PARAM: return aShortName ? wxString( wxT( "SP" ) ) : _( "S-Parameters" ); + case ST_OP: return aShortName ? wxString( wxT( "OP" ) ) : _( "DC Operating Point" ); + case ST_AC: return aShortName ? wxString( wxT( "AC" ) ) : _( "Small-Signal Analysis" ); + case ST_DC: return aShortName ? wxString( wxT( "DC" ) ) : _( "DC Sweep Analysis" ); + case ST_TRAN: return aShortName ? wxString( wxT( "TRAN" ) ) : _( "Transient Analysis" ); + case ST_DISTO: return aShortName ? wxString( wxT( "DISTO" ) ) : _( "Small-Signal Distortion Analysis" ); + case ST_NOISE: return aShortName ? wxString( wxT( "NOISE" ) ) : _( "Noise Analysis" ); + case ST_PZ: return aShortName ? wxString( wxT( "PZ" ) ) : _( "Pole-Zero Analysis" ); + case ST_SENS: return aShortName ? wxString( wxT( "SENS" ) ) : _( "Sensitivity Analysis" ); + case ST_TF: return aShortName ? wxString( wxT( "TF" ) ) : _( "Transfer Function Analysis" ); + case ST_SP: return aShortName ? wxString( wxT( "SP" ) ) : _( "S-Parameter Analysis" ); + case ST_FFT: return aShortName ? wxString( wxT( "FFT" ) ) : _( "Frequency Content Analysis" ); default: - case ST_UNKNOWN: return aShortName ? wxString( wxT( "??" ) ) : _( "Unknown" ); + case ST_UNKNOWN: return aShortName ? wxString( wxT( "??" ) ) : _( "Unknown" ); } } diff --git a/eeschema/sim/toolbars_simulator_frame.cpp b/eeschema/sim/toolbars_simulator_frame.cpp index 19087d53ae..187120d3b0 100644 --- a/eeschema/sim/toolbars_simulator_frame.cpp +++ b/eeschema/sim/toolbars_simulator_frame.cpp @@ -49,6 +49,7 @@ void SIMULATOR_FRAME::ReCreateHToolbar() m_toolBar->Add( EE_ACTIONS::saveWorkbook ); m_toolBar->AddScaledSeparator( this ); + m_toolBar->Add( EE_ACTIONS::newPlot ); m_toolBar->Add( EE_ACTIONS::simCommand ); m_toolBar->AddScaledSeparator( this ); @@ -134,6 +135,7 @@ void SIMULATOR_FRAME::doReCreateMenuBar() simulationMenu->Add( EE_ACTIONS::simTune ); simulationMenu->AppendSeparator(); + simulationMenu->Add( EE_ACTIONS::editUserDefinedSignals ); simulationMenu->Add( EE_ACTIONS::showNetlist ); diff --git a/eeschema/sim/user_defined_signals_help_md.h b/eeschema/sim/user_defined_signals_help_md.h index 1d47c428b6..89f71de85b 100644 --- a/eeschema/sim/user_defined_signals_help_md.h +++ b/eeschema/sim/user_defined_signals_help_md.h @@ -1,5 +1,7 @@ // Do not edit this file, it is autogenerated by CMake from the .md file -_HKI( " sqrt(x)\n" +_HKI( "SPICE functions:\n" +"\n" +" sqrt(x)\n" " sin(x)\n" " cos(x)\n" " tan(x)\n" diff --git a/eeschema/tools/ee_actions.cpp b/eeschema/tools/ee_actions.cpp index 1eb32b3e5e..a10e34e65d 100644 --- a/eeschema/tools/ee_actions.cpp +++ b/eeschema/tools/ee_actions.cpp @@ -1121,7 +1121,7 @@ TOOL_ACTION EE_ACTIONS::newPlot( "eeschema.Simulation.newPlot", AS_GLOBAL, MD_CTRL + 'N', LEGACY_HK_NAME( "New" ), _( "New Plot" ), "", - BITMAPS::new_generic ); + BITMAPS::sim_add_plot ); TOOL_ACTION EE_ACTIONS::openWorkbook( "eeschema.Simulation.openWorkbook", AS_GLOBAL, @@ -1201,12 +1201,6 @@ TOOL_ACTION EE_ACTIONS::editUserDefinedSignals( "eeschema.Simulation.editUserDef _( "Add, edit or delete user-defined simulation signals" ), BITMAPS::sim_add_signal ); -TOOL_ACTION EE_ACTIONS::showFFT( "eeschema.Simulation.showFFT", - AS_GLOBAL, 0, "", - _( "Show FFT" ), - _( "Show frequency distribution of transient analysis data using fast Fourier transform" ), - BITMAPS::mw_add_shape ); - TOOL_ACTION EE_ACTIONS::showNetlist( "eeschema.Simulation.showNetlist", AS_GLOBAL, 0, "", _( "Show SPICE Netlist" ), "", diff --git a/eeschema/tools/ee_actions.h b/eeschema/tools/ee_actions.h index ac689538cc..67a2fa06ed 100644 --- a/eeschema/tools/ee_actions.h +++ b/eeschema/tools/ee_actions.h @@ -277,7 +277,6 @@ public: static TOOL_ACTION runSimulation; static TOOL_ACTION stopSimulation; static TOOL_ACTION editUserDefinedSignals; - static TOOL_ACTION showFFT; static TOOL_ACTION showNetlist; // Net highlighting diff --git a/eeschema/tools/simulator_control.cpp b/eeschema/tools/simulator_control.cpp index 47e12d8bfc..91058b0ac6 100644 --- a/eeschema/tools/simulator_control.cpp +++ b/eeschema/tools/simulator_control.cpp @@ -62,14 +62,23 @@ void SIMULATOR_CONTROL::Reset( RESET_REASON aReason ) int SIMULATOR_CONTROL::NewPlot( const TOOL_EVENT& aEvent ) { - SIM_TYPE type = m_circuitModel->GetSimType(); + DIALOG_SIM_COMMAND dlg( m_simulatorFrame, m_circuitModel, m_simulator->Settings() ); + wxString errors; + WX_STRING_REPORTER reporter( &errors ); - if( SIM_PLOT_PANEL_BASE::IsPlottable( type ) ) + if( !m_circuitModel->ReadSchematicAndLibraries( NETLIST_EXPORTER_SPICE::OPTION_DEFAULT_FLAGS, + reporter ) ) { - m_simulatorFrame->NewPlotPanel( m_circuitModel->GetSimCommand(), - m_circuitModel->GetSimOptions() ); + DisplayErrorMessage( m_simulatorFrame, + _( "Errors during netlist generation.\n\n" ) + errors ); } + dlg.SetSimCommand( wxS( "*" ) ); + dlg.SetSimOptions( NETLIST_EXPORTER_SPICE::OPTION_DEFAULT_FLAGS ); + + if( dlg.ShowModal() == wxID_OK ) + m_simulatorFrame->NewPlotPanel( dlg.GetSimCommand(), dlg.GetSimOptions() ); + return 0; } @@ -145,71 +154,77 @@ int SIMULATOR_CONTROL::SaveWorkbook( const TOOL_EVENT& aEvent ) int SIMULATOR_CONTROL::ExportPlotAsPNG( const TOOL_EVENT& aEvent ) { - if( !m_simulatorFrame->GetCurrentPlot() ) - return -1; + if( SIM_PLOT_PANEL* plotPanel = GetCurrentPlotPanel() ) + { + wxFileDialog saveDlg( m_simulatorFrame, _( "Save Plot as Image" ), "", "", + PngFileWildcard(), wxFD_SAVE | wxFD_OVERWRITE_PROMPT ); - wxFileDialog saveDlg( m_simulatorFrame, _( "Save Plot as Image" ), "", "", PngFileWildcard(), - wxFD_SAVE | wxFD_OVERWRITE_PROMPT ); + if( saveDlg.ShowModal() == wxID_CANCEL ) + return -1; - if( saveDlg.ShowModal() == wxID_CANCEL ) - return -1; - - m_simulatorFrame->GetCurrentPlot()->GetPlotWin()->SaveScreenshot( saveDlg.GetPath(), - wxBITMAP_TYPE_PNG ); + plotPanel->GetPlotWin()->SaveScreenshot( saveDlg.GetPath(), wxBITMAP_TYPE_PNG ); + } return 0; } +SIM_PLOT_PANEL* SIMULATOR_CONTROL::GetCurrentPlotPanel() +{ + return dynamic_cast( m_simulatorFrame->GetCurrentPlotPanel() ); +} + + int SIMULATOR_CONTROL::ExportPlotAsCSV( const TOOL_EVENT& aEvent ) { - if( !m_simulatorFrame->GetCurrentPlot() ) - return -1; - - const wxChar SEPARATOR = ';'; - - wxFileDialog saveDlg( m_simulatorFrame, _( "Save Plot Data" ), "", "", CsvFileWildcard(), - wxFD_SAVE | wxFD_OVERWRITE_PROMPT ); - - if( saveDlg.ShowModal() == wxID_CANCEL ) - return -1; - - wxFFile out( saveDlg.GetPath(), "wb" ); - - std::map traces = m_simulatorFrame->GetCurrentPlot()->GetTraces(); - - if( traces.size() == 0 ) - return -1; - - SIM_TYPE simType = m_circuitModel->GetSimType(); - - std::size_t rowCount = traces.begin()->second->GetDataX().size(); - - // write column header names on the first row - wxString xAxisName( m_simulator->GetXAxis( simType ) ); - out.Write( wxString::Format( wxT( "%s%c" ), xAxisName, SEPARATOR ) ); - - for( const auto& [name, trace] : traces ) - out.Write( wxString::Format( wxT( "%s%c" ), name, SEPARATOR ) ); - - out.Write( wxS( "\r\n" ) ); - - // write each row's numerical value - for ( std::size_t curRow=0; curRow < rowCount; curRow++ ) + if( SIM_PLOT_PANEL* plotPanel = GetCurrentPlotPanel() ) { - double xAxisValue = traces.begin()->second->GetDataX().at( curRow ); - out.Write( wxString::Format( wxT( "%g%c" ), xAxisValue, SEPARATOR ) ); + const wxChar SEPARATOR = ';'; + + wxFileDialog saveDlg( m_simulatorFrame, _( "Save Plot Data" ), "", "", CsvFileWildcard(), + wxFD_SAVE | wxFD_OVERWRITE_PROMPT ); + + if( saveDlg.ShowModal() == wxID_CANCEL ) + return -1; + + wxFFile out( saveDlg.GetPath(), "wb" ); + + std::map traces = plotPanel->GetTraces(); + + if( traces.size() == 0 ) + return -1; + + SIM_TYPE simType = plotPanel->GetSimType(); + + std::size_t rowCount = traces.begin()->second->GetDataX().size(); + + // write column header names on the first row + wxString xAxisName( m_simulator->GetXAxis( simType ) ); + out.Write( wxString::Format( wxT( "%s%c" ), xAxisName, SEPARATOR ) ); for( const auto& [name, trace] : traces ) - { - double yAxisValue = trace->GetDataY().at( curRow ); - out.Write( wxString::Format( wxT( "%g%c" ), yAxisValue, SEPARATOR ) ); - } + out.Write( wxString::Format( wxT( "%s%c" ), name, SEPARATOR ) ); out.Write( wxS( "\r\n" ) ); + + // write each row's numerical value + for ( std::size_t curRow=0; curRow < rowCount; curRow++ ) + { + double xAxisValue = traces.begin()->second->GetDataX().at( curRow ); + out.Write( wxString::Format( wxT( "%g%c" ), xAxisValue, SEPARATOR ) ); + + for( const auto& [name, trace] : traces ) + { + double yAxisValue = trace->GetDataY().at( curRow ); + out.Write( wxString::Format( wxT( "%g%c" ), yAxisValue, SEPARATOR ) ); + } + + out.Write( wxS( "\r\n" ) ); + } + + out.Close(); } - out.Close(); return 0; } @@ -223,14 +238,11 @@ int SIMULATOR_CONTROL::Close( const TOOL_EVENT& aEvent ) int SIMULATOR_CONTROL::Zoom( const TOOL_EVENT& aEvent ) { - if( m_simulatorFrame->GetCurrentPlot() ) + if( SIM_PLOT_PANEL* plotPanel = GetCurrentPlotPanel() ) { - if( aEvent.IsAction( &ACTIONS::zoomInCenter ) ) - m_simulatorFrame->GetCurrentPlot()->GetPlotWin()->ZoomIn(); - else if( aEvent.IsAction( &ACTIONS::zoomOutCenter ) ) - m_simulatorFrame->GetCurrentPlot()->GetPlotWin()->ZoomOut(); - else if( aEvent.IsAction( &ACTIONS::zoomFitScreen ) ) - m_simulatorFrame->GetCurrentPlot()->GetPlotWin()->Fit(); + if( aEvent.IsAction( &ACTIONS::zoomInCenter ) ) plotPanel->GetPlotWin()->ZoomIn(); + else if( aEvent.IsAction( &ACTIONS::zoomOutCenter ) ) plotPanel->GetPlotWin()->ZoomOut(); + else if( aEvent.IsAction( &ACTIONS::zoomFitScreen ) ) plotPanel->GetPlotWin()->Fit(); } return 0; @@ -239,11 +251,9 @@ int SIMULATOR_CONTROL::Zoom( const TOOL_EVENT& aEvent ) int SIMULATOR_CONTROL::ToggleGrid( const TOOL_EVENT& aEvent ) { - SIM_PLOT_PANEL* plot = m_simulatorFrame->GetCurrentPlot(); - - if( plot ) + if( SIM_PLOT_PANEL* plotPanel = GetCurrentPlotPanel() ) { - plot->ShowGrid( !plot->IsGridShown() ); + plotPanel->ShowGrid( !plotPanel->IsGridShown() ); m_simulatorFrame->OnModify(); } @@ -253,11 +263,9 @@ int SIMULATOR_CONTROL::ToggleGrid( const TOOL_EVENT& aEvent ) int SIMULATOR_CONTROL::ToggleLegend( const TOOL_EVENT& aEvent ) { - SIM_PLOT_PANEL* plot = m_simulatorFrame->GetCurrentPlot(); - - if( plot ) + if( SIM_PLOT_PANEL* plotPanel = GetCurrentPlotPanel() ) { - plot->ShowLegend( !plot->IsLegendShown() ); + plotPanel->ShowLegend( !plotPanel->IsLegendShown() ); m_simulatorFrame->OnModify(); } @@ -267,11 +275,9 @@ int SIMULATOR_CONTROL::ToggleLegend( const TOOL_EVENT& aEvent ) int SIMULATOR_CONTROL::ToggleDottedSecondary( const TOOL_EVENT& aEvent ) { - SIM_PLOT_PANEL* plot = m_simulatorFrame->GetCurrentPlot(); - - if( plot ) + if( SIM_PLOT_PANEL* plotPanel = GetCurrentPlotPanel() ) { - plot->SetDottedSecondary( !plot->GetDottedSecondary() ); + plotPanel->SetDottedSecondary( !plotPanel->GetDottedSecondary() ); m_simulatorFrame->OnModify(); } @@ -296,9 +302,18 @@ int SIMULATOR_CONTROL::EditSimCommand( const TOOL_EVENT& aEvent ) int SIMULATOR_CONTROL::RunSimulation( const TOOL_EVENT& aEvent ) { if( m_simulator->IsRunning() ) + { m_simulator->Stop(); - else - m_simulatorFrame->StartSimulation(); + return 0; + } + + if( !GetCurrentPlotPanel() ) + NewPlot( aEvent ); + + if( !GetCurrentPlotPanel() ) + return 0; + + m_simulatorFrame->StartSimulation(); return 0; } @@ -444,8 +459,9 @@ int SIMULATOR_CONTROL::ShowNetlist( const TOOL_EVENT& aEvent ) STRING_FORMATTER formatter; NETLIST_VIEW_DIALOG dlg( m_simulatorFrame ); - m_circuitModel->SetSimOptions( m_simulatorFrame->GetCurrentOptions() ); - m_circuitModel->GetNetlist( &formatter, *dlg.GetReporter() ); + m_circuitModel->GetNetlist( m_simulatorFrame->GetCurrentSimCommand(), + m_simulatorFrame->GetCurrentOptions(), + &formatter, *dlg.GetReporter() ); dlg.SetNetlist( wxString( formatter.GetString() ) ); dlg.ShowModal(); diff --git a/eeschema/tools/simulator_control.h b/eeschema/tools/simulator_control.h index 9978229640..5de83e3feb 100644 --- a/eeschema/tools/simulator_control.h +++ b/eeschema/tools/simulator_control.h @@ -30,6 +30,7 @@ class SIMULATOR_FRAME; class NGSPICE_CIRCUIT_MODEL; class SPICE_SIMULATOR; +class SIM_PLOT_PANEL; /** @@ -84,6 +85,8 @@ private: */ wxString getDefaultPath(); + SIM_PLOT_PANEL* GetCurrentPlotPanel(); + ///< Set up handlers for various events. void setTransitions() override; diff --git a/include/bitmaps/bitmaps_list.h b/include/bitmaps/bitmaps_list.h index f40b1863aa..73a5c560d5 100644 --- a/include/bitmaps/bitmaps_list.h +++ b/include/bitmaps/bitmaps_list.h @@ -525,6 +525,7 @@ enum class BITMAPS : unsigned int show_zone_outline_only, show_zone_triangulation, showtrack, + sim_add_plot, sim_add_signal, sim_command, sim_probe, diff --git a/include/widgets/mathplot.h b/include/widgets/mathplot.h index 0bae6ef16c..2a64ed848e 100644 --- a/include/widgets/mathplot.h +++ b/include/widgets/mathplot.h @@ -1060,10 +1060,7 @@ class WXDLLIMPEXP_MATHPLOT mpWindow : public wxWindow { public: mpWindow(); - mpWindow( wxWindow* parent, wxWindowID id, - const wxPoint& pos = wxDefaultPosition, - const wxSize& size = wxDefaultSize, - long flags = 0 ); + mpWindow( wxWindow* parent, wxWindowID id ); ~mpWindow(); /** Get reference to context menu of the plot canvas. diff --git a/qa/tests/spice/test_ngspice_helpers.cpp b/qa/tests/spice/test_ngspice_helpers.cpp index 342a2e963b..db24489cd5 100644 --- a/qa/tests/spice/test_ngspice_helpers.cpp +++ b/qa/tests/spice/test_ngspice_helpers.cpp @@ -83,8 +83,8 @@ BOOST_AUTO_TEST_CASE( CommandToSimType ) std::vector testData = { { ".op", ST_OP }, { ".option TEMP=27", ST_UNKNOWN }, - { ".tran 0 1 0.1", ST_TRANSIENT }, - { ".tran 0 1 0.1 UIC", ST_TRANSIENT }, + { ".tran 0 1 0.1", ST_TRAN }, + { ".tran 0 1 0.1 UIC", ST_TRAN }, { ".ac dec 10 1 10K", ST_AC }, { ".ac dec 10 1K 100MEG", ST_AC }, { ".ac lin 100 1 100HZ", ST_AC }, @@ -93,18 +93,18 @@ BOOST_AUTO_TEST_CASE( CommandToSimType ) { ".dc VCE 0 10 .25 IB 0 10u 1u", ST_DC }, { ".dc RLoad 1k 2k 100", ST_DC }, { ".dc TEMP -15 75 5", ST_DC }, - { ".disto dec 10 1kHz 100MEG", ST_DISTORTION }, - { ".disto dec 10 1kHz 100MEG 0.9", ST_DISTORTION }, + { ".disto dec 10 1kHz 100MEG", ST_DISTO }, + { ".disto dec 10 1kHz 100MEG 0.9", ST_DISTO }, { ".noise v(5) VIN dec 10 1kHz 100MEG", ST_NOISE }, { ".noise v(5,3) V1 oct 8 1.0 1.0e6 1", ST_NOISE }, - { ".pz 1 0 3 0 cur pol", ST_POLE_ZERO }, - { ".pz 2 3 5 0 vol zer", ST_POLE_ZERO }, - { ".pz 4 1 4 1 cur pz", ST_POLE_ZERO }, - { ".SENS V(1,OUT)", ST_SENSITIVITY }, - { ".SENS V(OUT) AC DEC 10 100 100k", ST_SENSITIVITY }, - { ".SENS I(VTEST)", ST_SENSITIVITY }, - { ".tf v(5, 3) VIN", ST_TRANS_FUNC }, - { ".tf i(VLOAD) VIN", ST_TRANS_FUNC }, + { ".pz 1 0 3 0 cur pol", ST_PZ }, + { ".pz 2 3 5 0 vol zer", ST_PZ }, + { ".pz 4 1 4 1 cur pz", ST_PZ }, + { ".SENS V(1,OUT)", ST_SENS }, + { ".SENS V(OUT) AC DEC 10 100 100k", ST_SENS }, + { ".SENS I(VTEST)", ST_SENS }, + { ".tf v(5, 3) VIN", ST_TF }, + { ".tf i(VLOAD) VIN", ST_TF }, }; for( auto& step : testData ) diff --git a/resources/bitmaps_png/CMakeLists.txt b/resources/bitmaps_png/CMakeLists.txt index c10191ba1f..cafb926077 100644 --- a/resources/bitmaps_png/CMakeLists.txt +++ b/resources/bitmaps_png/CMakeLists.txt @@ -458,6 +458,7 @@ set( BMAPS_MID shape_3d_back sheetset simulator + sim_add_plot sim_command sim_run sim_stop diff --git a/resources/bitmaps_png/png/sim_add_plot_24.png b/resources/bitmaps_png/png/sim_add_plot_24.png new file mode 100644 index 0000000000..b964484f40 Binary files /dev/null and b/resources/bitmaps_png/png/sim_add_plot_24.png differ diff --git a/resources/bitmaps_png/sources/light/sim_add_plot.svg b/resources/bitmaps_png/sources/light/sim_add_plot.svg new file mode 100644 index 0000000000..1d30627069 --- /dev/null +++ b/resources/bitmaps_png/sources/light/sim_add_plot.svg @@ -0,0 +1,148 @@ + + + + + + + + + + image/svg+xml + + simulator + + + + + + + + + + + + + + + simulator + + + + + + + + + + + +