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