ADDED support for simulation plot margins and GUI for Y axis locking.

This commit is contained in:
Jeff Young 2023-07-19 16:25:57 +01:00
parent 65f66755ee
commit 9c08d4febe
21 changed files with 10022 additions and 6954 deletions

View File

@ -782,6 +782,9 @@ void mpScaleX::recalculateTicks( wxDC& dc, mpWindow& w )
mpScaleBase::mpScaleBase()
{
m_rangeSet = false;
m_axisLocked = false;
m_axisMin = 0;
m_axisMax = 0;
m_nameFlags = mpALIGN_BORDER_BOTTOM;
// initialize these members mainly to avoid not initialized values
@ -870,13 +873,11 @@ void mpScaleY::computeSlaveTicks( mpWindow& w )
m_tickValues.clear();
double m;
m_absVisibleMaxV = 0;
for( unsigned int i = 0; i < m_masterScale->m_tickValues.size(); i++ )
for( double tickValue : m_masterScale->m_tickValues )
{
m = TransformFromPlot( m_masterScale->TransformToPlot( m_masterScale->m_tickValues[i] ) );
double m = TransformFromPlot( m_masterScale->TransformToPlot( tickValue ) );
m_tickValues.push_back( m );
m_tickLabels.emplace_back( m );
m_absVisibleMaxV = std::max( m_absVisibleMaxV, fabs( m ) );
@ -941,9 +942,7 @@ void mpScaleY::recalculateTicks( wxDC& dc, mpWindow& w )
// something weird happened...
if( i == iterLimit )
{
m_tickValues.clear();
}
if( zeroOffset <= bestStep )
{
@ -1383,6 +1382,7 @@ mpWindow::mpWindow() :
m_scrY( 64 ),
m_clickedX( 0 ),
m_clickedY( 0 ),
m_yLocked( false ),
m_desiredXmin( 0.0 ),
m_desiredXmax( 1.0 ),
m_desiredYmin( 0.0 ),
@ -1528,7 +1528,7 @@ void mpWindow::OnMouseWheel( wxMouseEvent& event )
SetXView( m_posX + changeUnitsX, m_desiredXmax + changeUnitsX,
m_desiredXmin + changeUnitsX );
}
else
else if( !m_yLocked )
{
SetYView( m_posY + changeUnitsY, m_desiredYmax + changeUnitsY,
m_desiredYmin + changeUnitsY );
@ -1541,7 +1541,7 @@ void mpWindow::OnMouseWheel( wxMouseEvent& event )
SetXView( m_posX + changeUnitsX, m_desiredXmax + changeUnitsX,
m_desiredXmin + changeUnitsX );
}
else
else if( !m_yLocked )
{
SetYView( m_posY + changeUnitsY, m_desiredYmax + changeUnitsY,
m_desiredYmin + changeUnitsY );
@ -1867,8 +1867,10 @@ void mpWindow::ZoomIn( const wxPoint& centerPoint, double zoomFactor )
// Baaaaad things happen when you zoom in too much..
if( newScaleX <= MAX_SCALE && newScaleY <= MAX_SCALE )
{
m_scaleX = newScaleX;
m_scaleY = newScaleY;
m_scaleX = newScaleX;
if( !m_yLocked )
m_scaleY = newScaleY;
}
else
{
@ -1876,8 +1878,10 @@ void mpWindow::ZoomIn( const wxPoint& centerPoint, double zoomFactor )
}
// Adjust the new m_posx/y:
m_posX = prior_layer_x - c.x / m_scaleX;
m_posY = prior_layer_y + c.y / m_scaleY;
m_posX = prior_layer_x - c.x / m_scaleX;
if( !m_yLocked )
m_posY = prior_layer_y + c.y / m_scaleY;
m_desiredXmin = m_posX;
m_desiredXmax = m_posX + (m_scrX - m_marginLeft - m_marginRight) / m_scaleX;
@ -1911,11 +1915,15 @@ void mpWindow::ZoomOut( const wxPoint& centerPoint, double zoomFactor )
// Zoom out:
m_scaleX = m_scaleX / zoomFactor;
m_scaleY = m_scaleY / zoomFactor;
if( !m_yLocked )
m_scaleY = m_scaleY / zoomFactor;
// Adjust the new m_posx/y:
m_posX = prior_layer_x - c.x / m_scaleX;
m_posY = prior_layer_y + c.y / m_scaleY;
m_posX = prior_layer_x - c.x / m_scaleX;
if( !m_yLocked )
m_posY = prior_layer_y + c.y / m_scaleY;
m_desiredXmin = m_posX;
m_desiredXmax = m_posX + (m_scrX - m_marginLeft - m_marginRight) / m_scaleX;
@ -1953,6 +1961,12 @@ void mpWindow::ZoomRect( wxPoint p0, wxPoint p1 )
double zoom_y_min = p0y<p1y ? p0y : p1y;
double zoom_y_max = p0y>p1y ? p0y : p1y;
if( m_yLocked )
{
zoom_y_min = m_desiredYmin;
zoom_y_max = m_desiredYmax;
}
Fit( zoom_x_min, zoom_x_max, zoom_y_min, zoom_y_max );
AdjustLimitedView();
}

View File

@ -27,7 +27,6 @@
#include <sim/spice_circuit_model.h>
#include <sim/ngspice.h>
#include <sim/simulator_frame.h>
#include <confirm.h>
#include <wx/tokenzr.h>
@ -35,8 +34,6 @@
#include <vector>
#include <utility>
/// @todo ngspice offers more types of analysis,
//so there are a few tabs missing (e.g. pole-zero, distortion, sensitivity)
// Helper function to shorten conditions
static bool empty( const wxTextEntryBase* aCtrl )
@ -124,6 +121,18 @@ DIALOG_SIM_COMMAND::DIALOG_SIM_COMMAND( SIMULATOR_FRAME* aParent,
if( !dynamic_cast<NGSPICE_SETTINGS*>( aSettings.get() ) )
m_compatibilityModeSizer->Show( false );
int minWidth = GetTextExtent( wxS( "XXX.XXXXXXX" ) ).x;
m_y1Min->SetMinSize( wxSize( minWidth, -1 ) );
m_y1Max->SetMinSize( wxSize( minWidth, -1 ) );
m_y2Min->SetMinSize( wxSize( minWidth, -1 ) );
m_y2Max->SetMinSize( wxSize( minWidth, -1 ) );
m_y3Min->SetMinSize( wxSize( minWidth, -1 ) );
m_y3Max->SetMinSize( wxSize( minWidth, -1 ) );
m_bSizerY1->Show( false );
m_bSizerY2->Show( false );
m_bSizerY3->Show( false );
SetupStandardButtons();
}
@ -135,11 +144,9 @@ bool DIALOG_SIM_COMMAND::TransferDataToWindow()
m_fixIncludePaths->SetValue( m_settings->GetFixIncludePaths() );
NGSPICE_SETTINGS* ngspiceSettings = dynamic_cast<NGSPICE_SETTINGS*>( m_settings.get() );
if( ngspiceSettings )
if( NGSPICE_SETTINGS* settings = dynamic_cast<NGSPICE_SETTINGS*>( m_settings.get() ) )
{
switch( ngspiceSettings->GetCompatibilityMode() )
switch( settings->GetCompatibilityMode() )
{
case NGSPICE_COMPATIBILITY_MODE::USER_CONFIG: m_compatibilityMode->SetSelection( 0 ); break;
case NGSPICE_COMPATIBILITY_MODE::NGSPICE: m_compatibilityMode->SetSelection( 1 ); break;
@ -147,19 +154,109 @@ bool DIALOG_SIM_COMMAND::TransferDataToWindow()
case NGSPICE_COMPATIBILITY_MODE::LTSPICE: m_compatibilityMode->SetSelection( 3 ); break;
case NGSPICE_COMPATIBILITY_MODE::LT_PSPICE: m_compatibilityMode->SetSelection( 4 ); break;
case NGSPICE_COMPATIBILITY_MODE::HSPICE: m_compatibilityMode->SetSelection( 5 ); break;
default: wxFAIL_MSG( wxString::Format( "Unknown NGSPICE_COMPATIBILITY_MODE %d.",
ngspiceSettings->GetCompatibilityMode() ) ); break;
default: wxFAIL_MSG( wxString::Format( "Unknown NGSPICE_COMPATIBILITY_MODE %d.",
settings->GetCompatibilityMode() ) ); break;
}
}
if( m_simCommand.IsEmpty() && !empty( m_customTxt ) )
parseCommand( m_customTxt->GetValue() );
refreshUIControls();
return true;
}
void DIALOG_SIM_COMMAND::OnUpdateUILockY1( wxUpdateUIEvent& event )
{
event.Enable( m_lockY1->GetValue() );
}
void DIALOG_SIM_COMMAND::OnUpdateUILockY2( wxUpdateUIEvent& event )
{
event.Enable( m_lockY2->GetValue() );
}
void DIALOG_SIM_COMMAND::OnUpdateUILockY3( wxUpdateUIEvent& event )
{
event.Enable( m_lockY3->GetValue() );
}
void DIALOG_SIM_COMMAND::SetPlotSettings( const SIM_TAB* aSimTab )
{
#define GET_STR( val ) EDA_UNIT_UTILS::UI::MessageTextFromValue( unityScale, EDA_UNITS::UNSCALED, \
val, false /* no units */ )
if( const SIM_PLOT_TAB* plotTab = dynamic_cast<const SIM_PLOT_TAB*>( aSimTab ) )
{
if( !plotTab->GetLabelY1().IsEmpty() )
{
m_bSizerY1->Show( true );
m_lockY1->SetLabel( wxString::Format( m_lockY1->GetLabel(), plotTab->GetLabelY1() ) );
m_y1MinUnits->SetLabel( plotTab->GetUnitsY1() );
m_y1MaxUnits->SetLabel( plotTab->GetUnitsY1() );
double min, max;
bool locked = plotTab->GetY1Scale( &min, &max );
m_lockY1->SetValue( locked );
if( !std::isnan( min ) )
m_y1Min->SetValue( SIM_VALUE::Normalize( min ) );
if( !std::isnan( max ) )
m_y1Max->SetValue( SIM_VALUE::Normalize( max ) );
}
/* JEY TODO: figure out how to decuple slave axes from master axis
*
if( !plotTab->GetLabelY2().IsEmpty() )
{
m_bSizerY2->Show( true );
m_lockY2->SetLabel( wxString::Format( m_lockY2->GetLabel(), plotTab->GetLabelY2() ) );
m_y2MinUnits->SetLabel( plotTab->GetUnitsY2() );
m_y2MaxUnits->SetLabel( plotTab->GetUnitsY2() );
double min, max;
bool locked = plotTab->GetY2Scale( &min, &max );
m_lockY2->SetValue( locked );
if( !std::isnan( min ) )
m_y2Min->SetValue( SIM_VALUE::Normalize( min ) );
if( !std::isnan( max ) )
m_y2Max->SetValue( SIM_VALUE::Normalize( max ) );
}
if( !plotTab->GetLabelY3().IsEmpty() )
{
m_bSizerY3->Show( true );
m_lockY3->SetLabel( wxString::Format( m_lockY3->GetLabel(), plotTab->GetLabelY3() ) );
m_y3MinUnits->SetLabel( plotTab->GetUnitsY3() );
m_y3MaxUnits->SetLabel( plotTab->GetUnitsY3() );
double min, max;
bool locked = plotTab->GetY3Scale( &min, &max );
m_lockY3->SetValue( locked );
if( !std::isnan( min ) )
m_y3Min->SetValue( SIM_VALUE::Normalize( min ) );
if( !std::isnan( max ) )
m_y3Max->SetValue( SIM_VALUE::Normalize( max ) );
}
*/
m_grid->SetValue( plotTab->IsGridShown() );
m_legend->SetValue( plotTab->IsLegendShown() );
m_dottedSecondary->SetValue( plotTab->GetDottedSecondary() );
m_marginLeft->SetValue( GET_STR( plotTab->GetPlotWin()->GetMarginLeft() ) );
m_marginTop->SetValue( GET_STR( plotTab->GetPlotWin()->GetMarginTop() ) );
m_marginRight->SetValue( GET_STR( plotTab->GetPlotWin()->GetMarginRight() ) );
m_marginBottom->SetValue( GET_STR( plotTab->GetPlotWin()->GetMarginBottom() ) );
}
}
wxString DIALOG_SIM_COMMAND::evaluateDCControls( wxChoice* aDcSource, wxTextCtrl* aDcStart,
wxTextCtrl* aDcStop, wxTextCtrl* aDcIncr )
{
@ -204,16 +301,16 @@ bool DIALOG_SIM_COMMAND::TransferDataFromWindow()
return false;
// The simulator dependent settings always get transferred.
if( NGSPICE_SETTINGS* ngspiceSettings = dynamic_cast<NGSPICE_SETTINGS*>( m_settings.get() ) )
if( NGSPICE_SETTINGS* settings = dynamic_cast<NGSPICE_SETTINGS*>( m_settings.get() ) )
{
switch( m_compatibilityMode->GetSelection() )
{
case 0: ngspiceSettings->SetCompatibilityMode( NGSPICE_COMPATIBILITY_MODE::USER_CONFIG ); break;
case 1: ngspiceSettings->SetCompatibilityMode( NGSPICE_COMPATIBILITY_MODE::NGSPICE ); break;
case 2: ngspiceSettings->SetCompatibilityMode( NGSPICE_COMPATIBILITY_MODE::PSPICE ); break;
case 3: ngspiceSettings->SetCompatibilityMode( NGSPICE_COMPATIBILITY_MODE::LTSPICE ); break;
case 4: ngspiceSettings->SetCompatibilityMode( NGSPICE_COMPATIBILITY_MODE::LT_PSPICE ); break;
case 5: ngspiceSettings->SetCompatibilityMode( NGSPICE_COMPATIBILITY_MODE::HSPICE ); break;
case 0: settings->SetCompatibilityMode( NGSPICE_COMPATIBILITY_MODE::USER_CONFIG ); break;
case 1: settings->SetCompatibilityMode( NGSPICE_COMPATIBILITY_MODE::NGSPICE ); break;
case 2: settings->SetCompatibilityMode( NGSPICE_COMPATIBILITY_MODE::PSPICE ); break;
case 3: settings->SetCompatibilityMode( NGSPICE_COMPATIBILITY_MODE::LTSPICE ); break;
case 4: settings->SetCompatibilityMode( NGSPICE_COMPATIBILITY_MODE::LT_PSPICE ); break;
case 5: settings->SetCompatibilityMode( NGSPICE_COMPATIBILITY_MODE::HSPICE ); break;
}
}
@ -387,23 +484,6 @@ bool DIALOG_SIM_COMMAND::TransferDataFromWindow()
}
else
{
if( m_simCommand.IsEmpty() )
{
KIDIALOG dlg( this, _( "No valid simulation is configured." ), _( "Warning" ),
wxOK | wxCANCEL | wxICON_EXCLAMATION | wxCENTER );
dlg.SetExtendedMessage( _( "A valid simulation can be configured by selecting a "
"simulation tab, setting the simulation parameters and "
"clicking the OK button with the tab selected." ) );
dlg.SetOKCancelLabels(
wxMessageDialog::ButtonLabel( _( "Exit Without Valid Simulation" ) ),
wxMessageDialog::ButtonLabel( _( "Configure Valid Simulation" ) ) );
dlg.DoNotShowCheckbox( __FILE__, __LINE__ );
if( dlg.ShowModal() == wxID_OK )
return true;
}
return false;
}
@ -416,6 +496,64 @@ bool DIALOG_SIM_COMMAND::TransferDataFromWindow()
}
void DIALOG_SIM_COMMAND::ApplySettings( SIM_TAB* aTab )
{
int options = NETLIST_EXPORTER_SPICE::OPTION_DEFAULT_FLAGS;
if( !m_fixIncludePaths->GetValue() )
options &= ~NETLIST_EXPORTER_SPICE::OPTION_ADJUST_INCLUDE_PATHS;
if( !m_saveAllVoltages->GetValue() )
options &= ~NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_VOLTAGES;
if( !m_saveAllCurrents->GetValue() )
options &= ~NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_CURRENTS;
if( !m_saveAllDissipations->GetValue() )
options &= ~NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_DISSIPATIONS;
aTab->SetSimOptions( options );
#define TO_INT( ctrl ) (int) EDA_UNIT_UTILS::UI::ValueFromString( unityScale, EDA_UNITS::UNSCALED, \
ctrl->GetValue() )
if( SIM_PLOT_TAB* plotTab = dynamic_cast<SIM_PLOT_TAB*>( aTab ) )
{
if( !plotTab->GetLabelY1().IsEmpty() )
{
plotTab->SetY1Scale( m_lockY1->GetValue(),
SIM_VALUE::ToDouble( m_y1Min->GetValue().ToStdString() ),
SIM_VALUE::ToDouble( m_y1Max->GetValue().ToStdString() ) );
}
if( !plotTab->GetLabelY2().IsEmpty() )
{
plotTab->SetY2Scale( m_lockY2->GetValue(),
SIM_VALUE::ToDouble( m_y2Min->GetValue().ToStdString() ),
SIM_VALUE::ToDouble( m_y2Max->GetValue().ToStdString() ) );
}
if( !plotTab->GetLabelY3().IsEmpty() )
{
plotTab->SetY3Scale( m_lockY3->GetValue(),
SIM_VALUE::ToDouble( m_y3Min->GetValue().ToStdString() ),
SIM_VALUE::ToDouble( m_y3Max->GetValue().ToStdString() ) );
}
plotTab->ShowGrid( m_grid->GetValue() );
plotTab->ShowLegend( m_legend->GetValue() );
plotTab->SetDottedSecondary( m_dottedSecondary->GetValue() );
plotTab->GetPlotWin()->SetMarginLeft( TO_INT( m_marginLeft ) );
plotTab->GetPlotWin()->SetMarginRight( TO_INT( m_marginRight ) );
plotTab->GetPlotWin()->SetMarginTop( TO_INT( m_marginTop ) );
plotTab->GetPlotWin()->SetMarginBottom( TO_INT( m_marginBottom ) );
plotTab->GetPlotWin()->UpdateAll();
}
}
void DIALOG_SIM_COMMAND::updateDCSources( wxChar aType, wxChoice* aSource )
{
wxString prevSelection;
@ -467,7 +605,7 @@ void DIALOG_SIM_COMMAND::parseCommand( const wxString& aCommand )
if( aCommand == wxT( "*" ) )
{
SetTitle( _( "New Simulation" ) );
SetTitle( _( "New Simulation Tab" ) );
m_commandType->Clear();
@ -746,8 +884,8 @@ void DIALOG_SIM_COMMAND::onSwapDCSources( wxCommandEvent& event )
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 );
updateDCUnits( type1, m_src1DCStartValUnit, m_src1DCEndValUnit, m_src1DCStepUnit );
updateDCUnits( type2, m_src2DCStartValUnit, m_src2DCEndValUnit, m_src2DCStepUnit );
}
@ -755,7 +893,7 @@ 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 );
updateDCUnits( type, m_src1DCStartValUnit, m_src1DCEndValUnit, m_src1DCStepUnit );
}
@ -763,7 +901,7 @@ 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 );
updateDCUnits( type, m_src2DCStartValUnit, m_src2DCEndValUnit, m_src2DCStepUnit );
}
@ -780,9 +918,8 @@ void DIALOG_SIM_COMMAND::onDCEnableSecondSource( wxCommandEvent& event )
}
void DIALOG_SIM_COMMAND::updateDCUnits( wxChar aType, wxChoice* aSource,
wxStaticText* aStartValUnit, wxStaticText* aEndValUnit,
wxStaticText* aStepUnit )
void DIALOG_SIM_COMMAND::updateDCUnits( wxChar aType, wxStaticText* aStartValUnit,
wxStaticText* aEndValUnit, wxStaticText* aStepUnit )
{
wxString unit;

View File

@ -36,6 +36,7 @@
class SPICE_CIRCUIT_MODEL;
class SPICE_SETTINGS;
class SIMULATOR_FRAME;
class SIM_TAB;
class DIALOG_SIM_COMMAND : public DIALOG_SIM_COMMAND_BASE
@ -57,25 +58,6 @@ public:
refreshUIControls();
}
int GetSimOptions() const
{
int options = NETLIST_EXPORTER_SPICE::OPTION_DEFAULT_FLAGS;
if( !m_fixIncludePaths->GetValue() )
options &= ~NETLIST_EXPORTER_SPICE::OPTION_ADJUST_INCLUDE_PATHS;
if( !m_saveAllVoltages->GetValue() )
options &= ~NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_VOLTAGES;
if( !m_saveAllCurrents->GetValue() )
options &= ~NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_CURRENTS;
if( !m_saveAllDissipations->GetValue() )
options &= ~NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_DISSIPATIONS;
return options;
}
void SetSimOptions( int aOptions )
{
m_fixIncludePaths->SetValue( aOptions & NETLIST_EXPORTER_SPICE::OPTION_ADJUST_INCLUDE_PATHS );
@ -84,6 +66,8 @@ public:
m_saveAllDissipations->SetValue( aOptions & NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_DISSIPATIONS );
}
void SetPlotSettings( const SIM_TAB* aSimTab );
bool TransferDataFromWindow() override;
bool TransferDataToWindow() override;
@ -96,6 +80,8 @@ public:
return true;
}
void ApplySettings( SIM_TAB* aTab );
private:
enum SCALE_TYPE
{
@ -129,8 +115,8 @@ private:
/**
* Update units on labels depending on selected source.
*/
void updateDCUnits( wxChar aType, wxChoice* aSource, wxStaticText* aStartValUnit,
wxStaticText* aEndValUnit, wxStaticText* aStepUnit );
void updateDCUnits( wxChar aType, wxStaticText* aStartValUnit, wxStaticText* aEndValUnit,
wxStaticText* aStepUnit );
virtual void onInitDlg( wxInitDialogEvent& event ) override
{
@ -158,6 +144,10 @@ private:
void onDCSource1Selected( wxCommandEvent& event ) override;
void onDCSource2Selected( wxCommandEvent& event ) override;
void OnUpdateUILockY1( wxUpdateUIEvent& event ) override;
void OnUpdateUILockY2( wxUpdateUIEvent& event ) override;
void OnUpdateUILockY3( wxUpdateUIEvent& event ) override;
static wxString scaleToString( int aOption )
{
switch( aOption )

View File

@ -18,7 +18,7 @@ DIALOG_SIM_COMMAND_BASE::DIALOG_SIM_COMMAND_BASE( wxWindow* parent, wxWindowID i
m_commandTypeSizer = new wxBoxSizer( wxHORIZONTAL );
m_commandTypeLabel = new wxStaticText( this, wxID_ANY, _("Simulation type:"), wxDefaultPosition, wxDefaultSize, 0 );
m_commandTypeLabel = new wxStaticText( this, wxID_ANY, _("Analysis type:"), wxDefaultPosition, wxDefaultSize, 0 );
m_commandTypeLabel->Wrap( -1 );
m_commandTypeSizer->Add( m_commandTypeLabel, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
@ -31,7 +31,15 @@ DIALOG_SIM_COMMAND_BASE::DIALOG_SIM_COMMAND_BASE( wxWindow* parent, wxWindowID i
bSizer1->Add( m_commandTypeSizer, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 10 );
m_simPages = new wxSimplebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
bSizer1->Add( 0, 5, 0, wxEXPAND, 5 );
m_notebook1 = new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
m_panelCommand = new wxPanel( m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bCommandSizer;
bCommandSizer = new wxBoxSizer( wxVERTICAL );
m_simPages = new wxSimplebook( m_panelCommand, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
m_pgAC = new wxPanel( m_simPages, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bSizer3;
bSizer3 = new wxBoxSizer( wxVERTICAL );
@ -620,34 +628,34 @@ DIALOG_SIM_COMMAND_BASE::DIALOG_SIM_COMMAND_BASE( wxWindow* parent, wxWindowID i
bSizer821->Fit( m_pgPZ );
m_simPages->AddPage( m_pgPZ, _("a page"), false );
bSizer1->Add( m_simPages, 1, wxEXPAND | wxALL, 5 );
bCommandSizer->Add( m_simPages, 1, wxEXPAND | wxALL, 5 );
wxBoxSizer* bSizer88;
bSizer88 = new wxBoxSizer( wxVERTICAL );
m_fixIncludePaths = new wxCheckBox( this, wxID_ANY, _("Add full path for .include library directives"), wxDefaultPosition, wxDefaultSize, 0 );
m_fixIncludePaths = new wxCheckBox( m_panelCommand, wxID_ANY, _("Add full path for .include library directives"), wxDefaultPosition, wxDefaultSize, 0 );
m_fixIncludePaths->SetValue(true);
bSizer88->Add( m_fixIncludePaths, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_saveAllVoltages = new wxCheckBox( this, wxID_ANY, _("Save all voltages"), wxDefaultPosition, wxDefaultSize, 0 );
m_saveAllVoltages = new wxCheckBox( m_panelCommand, wxID_ANY, _("Save all voltages"), wxDefaultPosition, wxDefaultSize, 0 );
bSizer88->Add( m_saveAllVoltages, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_saveAllCurrents = new wxCheckBox( this, wxID_ANY, _("Save all currents"), wxDefaultPosition, wxDefaultSize, 0 );
m_saveAllCurrents = new wxCheckBox( m_panelCommand, wxID_ANY, _("Save all currents"), wxDefaultPosition, wxDefaultSize, 0 );
bSizer88->Add( m_saveAllCurrents, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_saveAllDissipations = new wxCheckBox( this, wxID_ANY, _("Save all power dissipations"), wxDefaultPosition, wxDefaultSize, 0 );
m_saveAllDissipations = new wxCheckBox( m_panelCommand, wxID_ANY, _("Save all power dissipations"), wxDefaultPosition, wxDefaultSize, 0 );
bSizer88->Add( m_saveAllDissipations, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_compatibilityModeSizer = new wxBoxSizer( wxHORIZONTAL );
wxStaticText* compatibilityLabel;
compatibilityLabel = new wxStaticText( this, wxID_ANY, _("Compatibility mode:"), wxDefaultPosition, wxDefaultSize, 0 );
compatibilityLabel = new wxStaticText( m_panelCommand, wxID_ANY, _("Compatibility mode:"), wxDefaultPosition, wxDefaultSize, 0 );
compatibilityLabel->Wrap( -1 );
m_compatibilityModeSizer->Add( compatibilityLabel, 0, wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 8 );
wxString m_compatibilityModeChoices[] = { _("User configuration"), _("Spice"), _("PSpice"), _("LTSpice"), _("PSpice and LTSpice"), _("HSpice") };
int m_compatibilityModeNChoices = sizeof( m_compatibilityModeChoices ) / sizeof( wxString );
m_compatibilityMode = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_compatibilityModeNChoices, m_compatibilityModeChoices, 0 );
m_compatibilityMode = new wxChoice( m_panelCommand, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_compatibilityModeNChoices, m_compatibilityModeChoices, 0 );
m_compatibilityMode->SetSelection( 0 );
m_compatibilityModeSizer->Add( m_compatibilityMode, 0, wxALIGN_CENTER_VERTICAL, 5 );
@ -655,7 +663,240 @@ DIALOG_SIM_COMMAND_BASE::DIALOG_SIM_COMMAND_BASE( wxWindow* parent, wxWindowID i
bSizer88->Add( m_compatibilityModeSizer, 1, wxEXPAND|wxTOP|wxBOTTOM, 5 );
bSizer1->Add( bSizer88, 0, wxEXPAND|wxTOP|wxLEFT, 10 );
bCommandSizer->Add( bSizer88, 0, wxEXPAND|wxTOP|wxLEFT, 10 );
m_panelCommand->SetSizer( bCommandSizer );
m_panelCommand->Layout();
bCommandSizer->Fit( m_panelCommand );
m_notebook1->AddPage( m_panelCommand, _("SPICE Command"), false );
m_panelPlotSetup = new wxPanel( m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bPlotSetupSizer;
bPlotSetupSizer = new wxBoxSizer( wxVERTICAL );
m_bSizerY1 = new wxBoxSizer( wxVERTICAL );
m_lockY1 = new wxCheckBox( m_panelPlotSetup, wxID_ANY, _("Fixed %s scale"), wxDefaultPosition, wxDefaultSize, 0 );
m_bSizerY1->Add( m_lockY1, 0, wxRIGHT|wxLEFT, 5 );
m_bSizerY1->Add( 0, 2, 1, wxEXPAND, 5 );
wxFlexGridSizer* fgSizerY1;
fgSizerY1 = new wxFlexGridSizer( 0, 6, 0, 0 );
fgSizerY1->SetFlexibleDirection( wxBOTH );
fgSizerY1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_y1MinLabel = new wxStaticText( m_panelPlotSetup, wxID_ANY, _("Min:"), wxDefaultPosition, wxDefaultSize, 0 );
m_y1MinLabel->Wrap( -1 );
fgSizerY1->Add( m_y1MinLabel, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 25 );
m_y1Min = new wxTextCtrl( m_panelPlotSetup, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizerY1->Add( m_y1Min, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
m_y1MinUnits = new wxStaticText( m_panelPlotSetup, wxID_ANY, _("units"), wxDefaultPosition, wxDefaultSize, 0 );
m_y1MinUnits->Wrap( -1 );
m_y1MinUnits->SetMinSize( wxSize( 40,-1 ) );
fgSizerY1->Add( m_y1MinUnits, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 3 );
m_y1MaxLabel = new wxStaticText( m_panelPlotSetup, wxID_ANY, _("Max:"), wxDefaultPosition, wxDefaultSize, 0 );
m_y1MaxLabel->Wrap( -1 );
fgSizerY1->Add( m_y1MaxLabel, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 18 );
m_y1Max = new wxTextCtrl( m_panelPlotSetup, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizerY1->Add( m_y1Max, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
m_y1MaxUnits = new wxStaticText( m_panelPlotSetup, wxID_ANY, _("units"), wxDefaultPosition, wxDefaultSize, 0 );
m_y1MaxUnits->Wrap( -1 );
m_y1MaxUnits->SetMinSize( wxSize( 40,-1 ) );
fgSizerY1->Add( m_y1MaxUnits, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 3 );
m_bSizerY1->Add( fgSizerY1, 0, wxBOTTOM, 8 );
bPlotSetupSizer->Add( m_bSizerY1, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_bSizerY2 = new wxBoxSizer( wxVERTICAL );
m_lockY2 = new wxCheckBox( m_panelPlotSetup, wxID_ANY, _("Fixed %s scale"), wxDefaultPosition, wxDefaultSize, 0 );
m_bSizerY2->Add( m_lockY2, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
m_bSizerY2->Add( 0, 2, 1, wxEXPAND, 5 );
wxFlexGridSizer* fgSizerY2;
fgSizerY2 = new wxFlexGridSizer( 0, 6, 0, 0 );
fgSizerY2->SetFlexibleDirection( wxBOTH );
fgSizerY2->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_y2MinLabel = new wxStaticText( m_panelPlotSetup, wxID_ANY, _("Min:"), wxDefaultPosition, wxDefaultSize, 0 );
m_y2MinLabel->Wrap( -1 );
fgSizerY2->Add( m_y2MinLabel, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 25 );
m_y2Min = new wxTextCtrl( m_panelPlotSetup, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizerY2->Add( m_y2Min, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
m_y2MinUnits = new wxStaticText( m_panelPlotSetup, wxID_ANY, _("units"), wxDefaultPosition, wxDefaultSize, 0 );
m_y2MinUnits->Wrap( -1 );
m_y2MinUnits->SetMinSize( wxSize( 40,-1 ) );
fgSizerY2->Add( m_y2MinUnits, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 3 );
m_y2MaxLabel = new wxStaticText( m_panelPlotSetup, wxID_ANY, _("Max:"), wxDefaultPosition, wxDefaultSize, 0 );
m_y2MaxLabel->Wrap( -1 );
fgSizerY2->Add( m_y2MaxLabel, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 18 );
m_y2Max = new wxTextCtrl( m_panelPlotSetup, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizerY2->Add( m_y2Max, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
m_y2MaxUnits = new wxStaticText( m_panelPlotSetup, wxID_ANY, _("units"), wxDefaultPosition, wxDefaultSize, 0 );
m_y2MaxUnits->Wrap( -1 );
fgSizerY2->Add( m_y2MaxUnits, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 3 );
m_bSizerY2->Add( fgSizerY2, 0, wxBOTTOM, 8 );
bPlotSetupSizer->Add( m_bSizerY2, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_bSizerY3 = new wxBoxSizer( wxVERTICAL );
m_lockY3 = new wxCheckBox( m_panelPlotSetup, wxID_ANY, _("Fixed %s scale"), wxDefaultPosition, wxDefaultSize, 0 );
m_bSizerY3->Add( m_lockY3, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
m_bSizerY3->Add( 0, 2, 1, wxEXPAND, 5 );
wxFlexGridSizer* fgSizerY3;
fgSizerY3 = new wxFlexGridSizer( 0, 6, 0, 0 );
fgSizerY3->SetFlexibleDirection( wxBOTH );
fgSizerY3->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_y3MinLabel = new wxStaticText( m_panelPlotSetup, wxID_ANY, _("Min:"), wxDefaultPosition, wxDefaultSize, 0 );
m_y3MinLabel->Wrap( -1 );
fgSizerY3->Add( m_y3MinLabel, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 25 );
m_y3Min = new wxTextCtrl( m_panelPlotSetup, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizerY3->Add( m_y3Min, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
m_y3MinUnits = new wxStaticText( m_panelPlotSetup, wxID_ANY, _("units"), wxDefaultPosition, wxDefaultSize, 0 );
m_y3MinUnits->Wrap( -1 );
m_y3MinUnits->SetMinSize( wxSize( 40,-1 ) );
fgSizerY3->Add( m_y3MinUnits, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 3 );
m_y3MaxLabel = new wxStaticText( m_panelPlotSetup, wxID_ANY, _("Max:"), wxDefaultPosition, wxDefaultSize, 0 );
m_y3MaxLabel->Wrap( -1 );
fgSizerY3->Add( m_y3MaxLabel, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 18 );
m_y3Max = new wxTextCtrl( m_panelPlotSetup, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizerY3->Add( m_y3Max, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
m_y3MaxUnits = new wxStaticText( m_panelPlotSetup, wxID_ANY, _("units"), wxDefaultPosition, wxDefaultSize, 0 );
m_y3MaxUnits->Wrap( -1 );
m_y3MaxUnits->SetMinSize( wxSize( 40,-1 ) );
fgSizerY3->Add( m_y3MaxUnits, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 3 );
m_bSizerY3->Add( fgSizerY3, 0, wxBOTTOM, 8 );
bPlotSetupSizer->Add( m_bSizerY3, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
wxBoxSizer* bSizerCheckboxes;
bSizerCheckboxes = new wxBoxSizer( wxVERTICAL );
m_grid = new wxCheckBox( m_panelPlotSetup, wxID_ANY, _("Show grid"), wxDefaultPosition, wxDefaultSize, 0 );
m_grid->SetValue(true);
bSizerCheckboxes->Add( m_grid, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_legend = new wxCheckBox( m_panelPlotSetup, wxID_ANY, _("Show legend"), wxDefaultPosition, wxDefaultSize, 0 );
bSizerCheckboxes->Add( m_legend, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_dottedSecondary = new wxCheckBox( m_panelPlotSetup, wxID_ANY, _("Dotted current/phase"), wxDefaultPosition, wxDefaultSize, 0 );
m_dottedSecondary->SetValue(true);
bSizerCheckboxes->Add( m_dottedSecondary, 0, wxRIGHT|wxLEFT, 5 );
bPlotSetupSizer->Add( bSizerCheckboxes, 0, wxEXPAND|wxLEFT, 5 );
m_marginsLabel = new wxStaticText( m_panelPlotSetup, wxID_ANY, _("Margins:"), wxDefaultPosition, wxDefaultSize, 0 );
m_marginsLabel->Wrap( -1 );
bPlotSetupSizer->Add( m_marginsLabel, 0, wxTOP|wxRIGHT|wxLEFT, 10 );
wxBoxSizer* bSizerMargins;
bSizerMargins = new wxBoxSizer( wxHORIZONTAL );
wxBoxSizer* bSizerLeft;
bSizerLeft = new wxBoxSizer( wxHORIZONTAL );
m_marginLeftLabel = new wxStaticText( m_panelPlotSetup, wxID_ANY, _("Left:"), wxDefaultPosition, wxDefaultSize, 0 );
m_marginLeftLabel->Wrap( -1 );
bSizerLeft->Add( m_marginLeftLabel, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 20 );
m_marginLeft = new wxTextCtrl( m_panelPlotSetup, wxID_ANY, _("70"), wxDefaultPosition, wxDefaultSize, 0 );
m_marginLeft->SetMinSize( wxSize( 60,-1 ) );
bSizerLeft->Add( m_marginLeft, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
bSizerMargins->Add( bSizerLeft, 0, wxEXPAND|wxLEFT, 5 );
wxFlexGridSizer* fgSizerTopBottom;
fgSizerTopBottom = new wxFlexGridSizer( 0, 2, 4, 0 );
fgSizerTopBottom->SetFlexibleDirection( wxBOTH );
fgSizerTopBottom->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_marginTopLabel = new wxStaticText( m_panelPlotSetup, wxID_ANY, _("Top:"), wxDefaultPosition, wxDefaultSize, 0 );
m_marginTopLabel->Wrap( -1 );
fgSizerTopBottom->Add( m_marginTopLabel, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 15 );
m_marginTop = new wxTextCtrl( m_panelPlotSetup, wxID_ANY, _("35"), wxDefaultPosition, wxDefaultSize, 0 );
m_marginTop->SetMinSize( wxSize( 60,-1 ) );
fgSizerTopBottom->Add( m_marginTop, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT|wxEXPAND, 5 );
m_marginBottomLabel = new wxStaticText( m_panelPlotSetup, wxID_ANY, _("Bottom:"), wxDefaultPosition, wxDefaultSize, 0 );
m_marginBottomLabel->Wrap( -1 );
fgSizerTopBottom->Add( m_marginBottomLabel, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 15 );
m_marginBottom = new wxTextCtrl( m_panelPlotSetup, wxID_ANY, _("35"), wxDefaultPosition, wxDefaultSize, 0 );
m_marginBottom->SetMinSize( wxSize( 60,-1 ) );
fgSizerTopBottom->Add( m_marginBottom, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT|wxEXPAND, 5 );
bSizerMargins->Add( fgSizerTopBottom, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 );
wxBoxSizer* bSizerRight;
bSizerRight = new wxBoxSizer( wxHORIZONTAL );
m_marginRightLabel = new wxStaticText( m_panelPlotSetup, wxID_ANY, _("Right:"), wxDefaultPosition, wxDefaultSize, 0 );
m_marginRightLabel->Wrap( -1 );
bSizerRight->Add( m_marginRightLabel, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 15 );
m_marginRight = new wxTextCtrl( m_panelPlotSetup, wxID_ANY, _("70"), wxDefaultPosition, wxDefaultSize, 0 );
m_marginRight->SetMinSize( wxSize( 60,-1 ) );
bSizerRight->Add( m_marginRight, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
bSizerMargins->Add( bSizerRight, 0, wxEXPAND, 5 );
bPlotSetupSizer->Add( bSizerMargins, 0, wxRIGHT|wxLEFT, 5 );
m_panelPlotSetup->SetSizer( bPlotSetupSizer );
m_panelPlotSetup->Layout();
bPlotSetupSizer->Fit( m_panelPlotSetup );
m_notebook1->AddPage( m_panelPlotSetup, _("Plot Setup"), true );
bSizer1->Add( m_notebook1, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 10 );
m_sdbSizer = new wxStdDialogButtonSizer();
m_sdbSizerOK = new wxButton( this, wxID_OK );
@ -684,6 +925,24 @@ DIALOG_SIM_COMMAND_BASE::DIALOG_SIM_COMMAND_BASE( wxWindow* parent, wxWindowID i
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 );
m_pzFunctionType->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_SIM_COMMAND_BASE::onDCSource1Selected ), NULL, this );
m_y1MinLabel->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_COMMAND_BASE::OnUpdateUILockY1 ), NULL, this );
m_y1Min->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_COMMAND_BASE::OnUpdateUILockY1 ), NULL, this );
m_y1MinUnits->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_COMMAND_BASE::OnUpdateUILockY1 ), NULL, this );
m_y1MaxLabel->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_COMMAND_BASE::OnUpdateUILockY1 ), NULL, this );
m_y1Max->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_COMMAND_BASE::OnUpdateUILockY1 ), NULL, this );
m_y1MaxUnits->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_COMMAND_BASE::OnUpdateUILockY1 ), NULL, this );
m_y2MinLabel->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_COMMAND_BASE::OnUpdateUILockY2 ), NULL, this );
m_y2Min->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_COMMAND_BASE::OnUpdateUILockY2 ), NULL, this );
m_y2MinUnits->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_COMMAND_BASE::OnUpdateUILockY2 ), NULL, this );
m_y2MaxLabel->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_COMMAND_BASE::OnUpdateUILockY2 ), NULL, this );
m_y2Max->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_COMMAND_BASE::OnUpdateUILockY2 ), NULL, this );
m_y2MaxUnits->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_COMMAND_BASE::OnUpdateUILockY2 ), NULL, this );
m_y3MinLabel->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_COMMAND_BASE::OnUpdateUILockY3 ), NULL, this );
m_y3Min->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_COMMAND_BASE::OnUpdateUILockY3 ), NULL, this );
m_y3MinUnits->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_COMMAND_BASE::OnUpdateUILockY3 ), NULL, this );
m_y3MaxLabel->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_COMMAND_BASE::OnUpdateUILockY3 ), NULL, this );
m_y3Max->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_COMMAND_BASE::OnUpdateUILockY3 ), NULL, this );
m_y3MaxUnits->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_COMMAND_BASE::OnUpdateUILockY3 ), NULL, this );
}
DIALOG_SIM_COMMAND_BASE::~DIALOG_SIM_COMMAND_BASE()
@ -699,5 +958,23 @@ DIALOG_SIM_COMMAND_BASE::~DIALOG_SIM_COMMAND_BASE()
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 );
m_pzFunctionType->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_SIM_COMMAND_BASE::onDCSource1Selected ), NULL, this );
m_y1MinLabel->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_COMMAND_BASE::OnUpdateUILockY1 ), NULL, this );
m_y1Min->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_COMMAND_BASE::OnUpdateUILockY1 ), NULL, this );
m_y1MinUnits->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_COMMAND_BASE::OnUpdateUILockY1 ), NULL, this );
m_y1MaxLabel->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_COMMAND_BASE::OnUpdateUILockY1 ), NULL, this );
m_y1Max->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_COMMAND_BASE::OnUpdateUILockY1 ), NULL, this );
m_y1MaxUnits->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_COMMAND_BASE::OnUpdateUILockY1 ), NULL, this );
m_y2MinLabel->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_COMMAND_BASE::OnUpdateUILockY2 ), NULL, this );
m_y2Min->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_COMMAND_BASE::OnUpdateUILockY2 ), NULL, this );
m_y2MinUnits->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_COMMAND_BASE::OnUpdateUILockY2 ), NULL, this );
m_y2MaxLabel->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_COMMAND_BASE::OnUpdateUILockY2 ), NULL, this );
m_y2Max->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_COMMAND_BASE::OnUpdateUILockY2 ), NULL, this );
m_y2MaxUnits->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_COMMAND_BASE::OnUpdateUILockY2 ), NULL, this );
m_y3MinLabel->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_COMMAND_BASE::OnUpdateUILockY3 ), NULL, this );
m_y3Min->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_COMMAND_BASE::OnUpdateUILockY3 ), NULL, this );
m_y3MinUnits->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_COMMAND_BASE::OnUpdateUILockY3 ), NULL, this );
m_y3MaxLabel->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_COMMAND_BASE::OnUpdateUILockY3 ), NULL, this );
m_y3Max->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_COMMAND_BASE::OnUpdateUILockY3 ), NULL, this );
m_y3MaxUnits->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_COMMAND_BASE::OnUpdateUILockY3 ), NULL, this );
}

File diff suppressed because it is too large Load Diff

View File

@ -32,6 +32,7 @@
#include <wx/srchctrl.h>
#include <wx/checklst.h>
#include <wx/simplebook.h>
#include <wx/notebook.h>
#include <wx/dialog.h>
///////////////////////////////////////////////////////////////////////////
@ -48,6 +49,8 @@ class DIALOG_SIM_COMMAND_BASE : public DIALOG_SHIM
wxBoxSizer* m_commandTypeSizer;
wxStaticText* m_commandTypeLabel;
wxChoice* m_commandType;
wxNotebook* m_notebook1;
wxPanel* m_panelCommand;
wxSimplebook* m_simPages;
wxPanel* m_pgAC;
wxRadioBox* m_acScale;
@ -158,6 +161,43 @@ class DIALOG_SIM_COMMAND_BASE : public DIALOG_SHIM
wxCheckBox* m_saveAllDissipations;
wxBoxSizer* m_compatibilityModeSizer;
wxChoice* m_compatibilityMode;
wxPanel* m_panelPlotSetup;
wxBoxSizer* m_bSizerY1;
wxCheckBox* m_lockY1;
wxStaticText* m_y1MinLabel;
wxTextCtrl* m_y1Min;
wxStaticText* m_y1MinUnits;
wxStaticText* m_y1MaxLabel;
wxTextCtrl* m_y1Max;
wxStaticText* m_y1MaxUnits;
wxBoxSizer* m_bSizerY2;
wxCheckBox* m_lockY2;
wxStaticText* m_y2MinLabel;
wxTextCtrl* m_y2Min;
wxStaticText* m_y2MinUnits;
wxStaticText* m_y2MaxLabel;
wxTextCtrl* m_y2Max;
wxStaticText* m_y2MaxUnits;
wxBoxSizer* m_bSizerY3;
wxCheckBox* m_lockY3;
wxStaticText* m_y3MinLabel;
wxTextCtrl* m_y3Min;
wxStaticText* m_y3MinUnits;
wxStaticText* m_y3MaxLabel;
wxTextCtrl* m_y3Max;
wxStaticText* m_y3MaxUnits;
wxCheckBox* m_grid;
wxCheckBox* m_legend;
wxCheckBox* m_dottedSecondary;
wxStaticText* m_marginsLabel;
wxStaticText* m_marginLeftLabel;
wxTextCtrl* m_marginLeft;
wxStaticText* m_marginTopLabel;
wxTextCtrl* m_marginTop;
wxStaticText* m_marginBottomLabel;
wxTextCtrl* m_marginBottom;
wxStaticText* m_marginRightLabel;
wxTextCtrl* m_marginRight;
wxStdDialogButtonSizer* m_sdbSizer;
wxButton* m_sdbSizerOK;
wxButton* m_sdbSizerCancel;
@ -172,11 +212,14 @@ class DIALOG_SIM_COMMAND_BASE : public DIALOG_SHIM
virtual void OnFilterMouseMoved( wxMouseEvent& event ) { event.Skip(); }
virtual void OnFilterText( wxCommandEvent& event ) { event.Skip(); }
virtual void onLoadDirectives( wxCommandEvent& event ) { event.Skip(); }
virtual void OnUpdateUILockY1( wxUpdateUIEvent& event ) { event.Skip(); }
virtual void OnUpdateUILockY2( wxUpdateUIEvent& event ) { event.Skip(); }
virtual void OnUpdateUILockY3( wxUpdateUIEvent& event ) { event.Skip(); }
public:
DIALOG_SIM_COMMAND_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Simulation Command"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
DIALOG_SIM_COMMAND_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Simulation Analysis"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
~DIALOG_SIM_COMMAND_BASE();

View File

@ -200,9 +200,11 @@ bool SIMULATOR_FRAME_UI::loadLegacyWorkbook( const wxString& aPath )
simCommand += line + wxT( "\n" );
}
SIM_TAB* simTab = NewSimTab( simCommand, simOptions );
SIM_TAB* simTab = NewSimTab( simCommand );
SIM_PLOT_TAB* plotTab = dynamic_cast<SIM_PLOT_TAB*>( simTab );
simTab->SetSimOptions( simOptions );
if( !file.GetNextLine().ToLong( &tracesCount ) )
{
EXPECTING( _( "expecting trace count" ) );

View File

@ -401,8 +401,8 @@ void CURSOR::UpdateReference()
}
SIM_PLOT_TAB::SIM_PLOT_TAB( const wxString& aSimCommand, unsigned aSimOptions, wxWindow* parent ) :
SIM_TAB( aSimCommand, aSimOptions, parent ),
SIM_PLOT_TAB::SIM_PLOT_TAB( const wxString& aSimCommand, wxWindow* parent ) :
SIM_TAB( aSimCommand, parent ),
m_axis_x( nullptr ),
m_axis_y1( nullptr ),
m_axis_y2( nullptr ),
@ -438,6 +438,40 @@ SIM_PLOT_TAB::~SIM_PLOT_TAB()
}
void SIM_PLOT_TAB::SetY1Scale( bool aLock, double aMin, double aMax )
{
m_axis_y1->SetAxisMinMax( aLock, aMin, aMax );
if( aLock )
{
m_plotWin->Fit( m_plotWin->GetDesiredXmin(), m_plotWin->GetDesiredXmax(),
m_axis_y1->TransformToPlot( aMin ), m_axis_y1->TransformToPlot( aMax ) );
m_plotWin->LockY( true );
m_plotWin->AdjustLimitedView();
}
else
{
m_plotWin->LockY( false );
}
}
void SIM_PLOT_TAB::SetY2Scale( bool aLock, double aMin, double aMax )
{
m_axis_y2->SetAxisMinMax( aLock, aMin, aMax );
// TODO: de-couple Y2 from Y1 and independently set Y2's scale
}
void SIM_PLOT_TAB::SetY3Scale( bool aLock, double aMin, double aMax )
{
m_axis_y3->SetAxisMinMax( aLock, aMin, aMax );
// TODO: de-couple Y2 from Y1 and independently set Y2's scale
}
wxString SIM_PLOT_TAB::GetUnitsX() const
{
LOG_SCALE<mpScaleXLog>* logScale = dynamic_cast<LOG_SCALE<mpScaleXLog>*>( m_axis_x );
@ -958,4 +992,21 @@ void SIM_PLOT_TAB::ResetScales( bool aIncludeX )
}
void SIM_PLOT_TAB::FitScales()
{
GetPlotWin()->Fit();
double min, max;
if( m_axis_y1 && m_axis_y1->GetAxisMinMax( &min, &max ) )
SetY1Scale( true, min, max );
if( m_axis_y2 && m_axis_y2->GetAxisMinMax( &min, &max ) )
SetY2Scale( true, min, max );
if( m_axis_y3 && m_axis_y3->GetAxisMinMax( &min, &max ) )
SetY3Scale( true, min, max );
}
wxDEFINE_EVENT( EVT_SIM_CURSOR_UPDATE, wxCommandEvent );

View File

@ -191,7 +191,7 @@ protected:
class SIM_PLOT_TAB : public SIM_TAB
{
public:
SIM_PLOT_TAB( const wxString& aSimCommand, unsigned aSimOptions, wxWindow* parent );
SIM_PLOT_TAB( const wxString& aSimCommand, wxWindow* parent );
virtual ~SIM_PLOT_TAB();
@ -215,6 +215,34 @@ public:
return m_axis_y3 ? m_axis_y3->GetName() : wxString( wxS( "" ) );
}
bool GetY1Scale( double* aMin, double* aMax ) const
{
if( m_axis_y1 )
return m_axis_y1->GetAxisMinMax( aMin, aMax );
return false;
}
bool GetY2Scale( double* aMin, double* aMax ) const
{
if( m_axis_y2 )
return m_axis_y2->GetAxisMinMax( aMin, aMax );
return false;
}
bool GetY3Scale( double* aMin, double* aMax ) const
{
if( m_axis_y3 )
return m_axis_y3->GetAxisMinMax( aMin, aMax );
return false;
}
void SetY1Scale( bool aLock, double aMin, double aMax );
void SetY2Scale( bool aLock, double aMin, double aMax );
void SetY3Scale( bool aLock, double aMin, double aMax );
wxString GetUnitsX() const;
wxString GetUnitsY1() const;
wxString GetUnitsY2() const;
@ -287,8 +315,8 @@ public:
{
m_dotted_cp = aEnable;
for( const auto& tr : m_traces )
UpdateTraceStyle( tr.second );
for( const auto& [ name, trace ] : m_traces )
UpdateTraceStyle( trace );
m_plotWin->UpdateAll();
}
@ -305,6 +333,8 @@ public:
///< Reset scale ranges to fit the current traces.
void ResetScales( bool aIncludeX );
void FitScales();
///< Update trace line style
void UpdateTraceStyle( TRACE* trace );

View File

@ -37,10 +37,10 @@ SIM_TAB::SIM_TAB() :
}
SIM_TAB::SIM_TAB( const wxString& aSimCommand, unsigned aSimOptions, wxWindow* parent ) :
SIM_TAB::SIM_TAB( const wxString& aSimCommand, wxWindow* parent ) :
wxWindow( parent, wxID_ANY ),
m_simCommand( aSimCommand ),
m_simOptions( aSimOptions )
m_simOptions( NETLIST_EXPORTER_SPICE::OPTION_DEFAULT_FLAGS )
{
}
@ -74,9 +74,8 @@ SIM_TYPE SIM_TAB::GetSimType() const
}
SIM_NOPLOT_TAB::SIM_NOPLOT_TAB( const wxString& aSimCommand, unsigned aSimOptions,
wxWindow* parent ) :
SIM_TAB( aSimCommand, aSimOptions, parent )
SIM_NOPLOT_TAB::SIM_NOPLOT_TAB( const wxString& aSimCommand, wxWindow* parent ) :
SIM_TAB( aSimCommand, parent )
{
m_sizer = new wxBoxSizer( wxVERTICAL );
m_sizer->Add( 0, 1, 1, wxEXPAND, 5 );

View File

@ -37,7 +37,7 @@ class SIM_TAB : public wxWindow
{
public:
SIM_TAB();
SIM_TAB( const wxString& aSimCommand, unsigned aSimOptions, wxWindow* parent );
SIM_TAB( const wxString& aSimCommand, wxWindow* parent );
virtual ~SIM_TAB();
static bool IsPlottable( SIM_TYPE aSimType );
@ -69,7 +69,7 @@ private:
class SIM_NOPLOT_TAB : public SIM_TAB
{
public:
SIM_NOPLOT_TAB( const wxString& aSimCommand, unsigned aSimOptions, wxWindow* parent );
SIM_NOPLOT_TAB( const wxString& aSimCommand, wxWindow* parent );
virtual ~SIM_NOPLOT_TAB();

View File

@ -433,9 +433,9 @@ void SIMULATOR_FRAME::StartSimulation()
}
void SIMULATOR_FRAME::NewPlotPanel( const wxString& aSimCommand, unsigned aOptions )
SIM_TAB* SIMULATOR_FRAME::NewSimTab( const wxString& aSimCommand )
{
m_ui->NewSimTab( aSimCommand, aOptions );
return m_ui->NewSimTab( aSimCommand );
}
@ -527,7 +527,7 @@ void SIMULATOR_FRAME::ToggleDarkModePlots()
}
bool SIMULATOR_FRAME::EditSimCommand()
bool SIMULATOR_FRAME::EditAnalysis()
{
SIM_TAB* simTab = m_ui->GetCurrentSimTab();
DIALOG_SIM_COMMAND dlg( this, m_circuitModel, m_simulator->Settings() );
@ -546,11 +546,12 @@ bool SIMULATOR_FRAME::EditSimCommand()
dlg.SetSimCommand( simTab->GetSimCommand() );
dlg.SetSimOptions( simTab->GetSimOptions() );
dlg.SetPlotSettings( simTab );
if( dlg.ShowModal() == wxID_OK )
{
simTab->SetSimCommand( dlg.GetSimCommand() );
simTab->SetSimOptions( dlg.GetSimOptions() );
dlg.ApplySettings( simTab );
m_ui->OnPlotSettingsChanged();
OnModify();
return true;
@ -677,8 +678,8 @@ void SIMULATOR_FRAME::setupUIConditions()
mgr->SetConditions( EE_ACTIONS::toggleDottedSecondary, CHECK( showDottedCondition ) );
mgr->SetConditions( EE_ACTIONS::toggleDarkModePlots, CHECK( darkModePlotCondition ) );
mgr->SetConditions( EE_ACTIONS::newPlot, ENABLE( SELECTION_CONDITIONS::ShowAlways ) );
mgr->SetConditions( EE_ACTIONS::simCommand, ENABLE( haveSim ) );
mgr->SetConditions( EE_ACTIONS::newAnalysisTab, ENABLE( SELECTION_CONDITIONS::ShowAlways ) );
mgr->SetConditions( EE_ACTIONS::simAnalysisProperties, ENABLE( haveSim ) );
mgr->SetConditions( EE_ACTIONS::runSimulation, ENABLE( !simRunning ) );
mgr->SetConditions( EE_ACTIONS::stopSimulation, ENABLE( simRunning ) );
mgr->SetConditions( EE_ACTIONS::simProbe, ENABLE( simFinished ) );

View File

@ -85,15 +85,14 @@ public:
* Create a new plot tab for a given simulation type.
*
* @param aSimCommand is requested simulation command.
* @param aSimOptions netlisting options
*/
void NewPlotPanel( const wxString& aSimCommand, unsigned aSimOptions );
SIM_TAB* NewSimTab( const wxString& aSimCommand );
/**
* Shows a dialog for editing the current tab's simulation command, or creating a new tab
* with a different simulation command type.
*/
bool EditSimCommand();
bool EditAnalysis();
/**
* @return the list of vectors (signals) in the current simulation results.

View File

@ -535,7 +535,7 @@ void SIMULATOR_FRAME_UI::ShowChangedLanguage()
simTab->OnLanguageChanged();
wxString pageTitle( simulator()->TypeToName( simTab->GetSimType(), true ) );
pageTitle.Prepend( wxString::Format( _( "Plot%u - " ), ii+1 /* 1-based */ ) );
pageTitle.Prepend( wxString::Format( _( "Analysis %u - " ), ii+1 /* 1-based */ ) );
m_plotNotebook->SetPageText( ii, pageTitle );
}
@ -597,7 +597,10 @@ void SIMULATOR_FRAME_UI::InitWorkbook()
wxString schTextSimCommand = circuitModel()->GetSchTextSimCommand();
if( !schTextSimCommand.IsEmpty() )
NewSimTab( schTextSimCommand, NETLIST_EXPORTER_SPICE::OPTION_DEFAULT_FLAGS );
{
SIM_TAB* simTab = NewSimTab( schTextSimCommand );
simTab->SetSimOptions( NETLIST_EXPORTER_SPICE::OPTION_DEFAULT_FLAGS );
}
rebuildSignalsList();
rebuildSignalsGrid( m_filter->GetValue() );
@ -872,14 +875,14 @@ void SIMULATOR_FRAME_UI::rebuildSignalsList()
}
SIM_TAB* SIMULATOR_FRAME_UI::NewSimTab( const wxString& aSimCommand, unsigned aSimOptions )
SIM_TAB* SIMULATOR_FRAME_UI::NewSimTab( const wxString& aSimCommand )
{
SIM_TAB* simTab = nullptr;
SIM_TYPE simType = SPICE_CIRCUIT_MODEL::CommandToSimType( aSimCommand );
if( SIM_TAB::IsPlottable( simType ) )
{
SIM_PLOT_TAB* panel = new SIM_PLOT_TAB( aSimCommand, aSimOptions, m_plotNotebook );
SIM_PLOT_TAB* panel = new SIM_PLOT_TAB( aSimCommand, m_plotNotebook );
simTab = panel;
COMMON_SETTINGS::INPUT cfg = Pgm().GetCommonSettings()->m_Input;
@ -887,11 +890,11 @@ SIM_TAB* SIMULATOR_FRAME_UI::NewSimTab( const wxString& aSimCommand, unsigned aS
}
else
{
simTab = new SIM_NOPLOT_TAB( aSimCommand, aSimOptions, m_plotNotebook );
simTab = new SIM_NOPLOT_TAB( aSimCommand, m_plotNotebook );
}
wxString pageTitle( simulator()->TypeToName( simType, true ) );
pageTitle.Prepend( wxString::Format( _( "Plot%u - " ), (unsigned int) ++m_plotNumber ) );
pageTitle.Prepend( wxString::Format( _( "Analysis %u - " ), (unsigned int) ++m_plotNumber ) );
m_plotNotebook->AddPage( simTab, pageTitle, true );
@ -1843,9 +1846,11 @@ bool SIMULATOR_FRAME_UI::loadJsonWorkbook( const wxString& aPath )
simCommand += wxString( cmd ) + wxT( "\n" );
}
SIM_TAB* simTab = NewSimTab( simCommand, simOptions );
SIM_TAB* simTab = NewSimTab( simCommand );
SIM_PLOT_TAB* plotTab = dynamic_cast<SIM_PLOT_TAB*>( simTab );
simTab->SetSimOptions( simOptions );
if( plotTab )
{
if( tab_js.contains( "traces" ) )
@ -1860,12 +1865,39 @@ bool SIMULATOR_FRAME_UI::loadJsonWorkbook( const wxString& aPath )
plotTab->SetDottedSecondary( tab_js[ "dottedSecondary" ] );
plotTab->ShowGrid( tab_js[ "showGrid" ] );
if( tab_js.contains( "fixedY1scale" ) )
{
const nlohmann::json& scale_js = tab_js[ "fixedY1scale" ];
plotTab->SetY1Scale( true, scale_js[ "min" ], scale_js[ "max" ] );
}
if( tab_js.contains( "fixedY2scale" ) )
{
const nlohmann::json& scale_js = tab_js[ "fixedY2scale" ];
plotTab->SetY2Scale( true, scale_js[ "min" ], scale_js[ "max" ] );
}
if( tab_js.contains( "fixedY3scale" ) )
{
const nlohmann::json& scale_js = tab_js[ "fixedY3scale" ];
plotTab->SetY3Scale( true, scale_js[ "min" ], scale_js[ "max" ] );
}
if( tab_js.contains( "legend" ) )
{
const nlohmann::json& legend_js = tab_js[ "legend" ];
plotTab->SetLegendPosition( wxPoint( legend_js[ "x" ], legend_js[ "y" ] ) );
plotTab->ShowLegend( true );
}
if( tab_js.contains( "margins" ) )
{
const nlohmann::json& margins_js = tab_js[ "margins" ];
plotTab->GetPlotWin()->SetMargins( margins_js[ "top" ],
margins_js[ "right" ],
margins_js[ "bottom" ],
margins_js[ "left" ] );
}
}
}
@ -2055,11 +2087,29 @@ bool SIMULATOR_FRAME_UI::SaveWorkbook( const wxString& aPath )
tab_js[ "dottedSecondary" ] = plotTab->GetDottedSecondary();
tab_js[ "showGrid" ] = plotTab->IsGridShown();
double min, max;
if( plotTab->GetY1Scale( &min, &max ) )
tab_js[ "fixedY1scale" ] = nlohmann::json( { { "min", min }, { "max", max } } );
if( plotTab->GetY2Scale( &min, &max ) )
tab_js[ "fixedY2scale" ] = nlohmann::json( { { "min", min }, { "max", max } } );
if( plotTab->GetY3Scale( &min, &max ) )
tab_js[ "fixedY3scale" ] = nlohmann::json( { { "min", min }, { "max", max } } );
if( plotTab->IsLegendShown() )
{
tab_js[ "legend" ] = nlohmann::json( { { "x", plotTab->GetLegendPosition().x },
{ "y", plotTab->GetLegendPosition().y } } );
}
mpWindow* plotWin = plotTab->GetPlotWin();
tab_js[ "margins" ] = nlohmann::json( { { "left", plotWin->GetMarginLeft() },
{ "right", plotWin->GetMarginRight() },
{ "top", plotWin->GetMarginTop() },
{ "bottom", plotWin->GetMarginBottom() } } );
}
tabs_js.push_back( tab_js );
@ -2569,7 +2619,7 @@ void SIMULATOR_FRAME_UI::OnSimRefresh( bool aFinal )
if( aFinal )
plotTab->ResetScales( true );
plotTab->GetPlotWin()->Fit();
plotTab->FitScales();
updatePlotCursors();

View File

@ -76,10 +76,8 @@ public:
* Create a new simulation tab for a given simulation type.
*
* @param aSimCommand is requested simulation command.
* @param aSimOptions netlisting options
* @return The new plot panel.
*/
SIM_TAB* NewSimTab( const wxString& aSimCommand, unsigned aSimOptions );
SIM_TAB* NewSimTab( const wxString& aSimCommand );
std::vector<wxString> SimPlotVectors() const;

View File

@ -49,8 +49,8 @@ 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->Add( EE_ACTIONS::newAnalysisTab );
m_toolBar->Add( EE_ACTIONS::simAnalysisProperties );
m_toolBar->AddScaledSeparator( this );
m_toolBar->Add( EE_ACTIONS::runSimulation );
@ -93,7 +93,7 @@ void SIMULATOR_FRAME::doReCreateMenuBar()
//
ACTION_MENU* fileMenu = new ACTION_MENU( false, tool );
fileMenu->Add( EE_ACTIONS::newPlot );
fileMenu->Add( EE_ACTIONS::newAnalysisTab );
fileMenu->AppendSeparator();
fileMenu->Add( EE_ACTIONS::openWorkbook );
@ -127,8 +127,8 @@ void SIMULATOR_FRAME::doReCreateMenuBar()
//
ACTION_MENU* simulationMenu = new ACTION_MENU( false, tool );
simulationMenu->Add( EE_ACTIONS::newPlot );
simulationMenu->Add( EE_ACTIONS::simCommand );
simulationMenu->Add( EE_ACTIONS::newAnalysisTab );
simulationMenu->Add( EE_ACTIONS::simAnalysisProperties );
simulationMenu->Add( EE_ACTIONS::runSimulation );
simulationMenu->AppendSeparator();

View File

@ -1109,10 +1109,10 @@ TOOL_ACTION EE_ACTIONS::ddAppendFile( "eeschema.EditorControl.ddAppendFile",
AS_GLOBAL );
// SIMULATOR
TOOL_ACTION EE_ACTIONS::newPlot( "eeschema.Simulation.newPlot",
TOOL_ACTION EE_ACTIONS::newAnalysisTab( "eeschema.Simulation.newAnalysisTab",
AS_GLOBAL,
MD_CTRL + 'N', LEGACY_HK_NAME( "New" ),
_( "New Plot" ), "",
_( "New Analysis Tab..." ), "",
BITMAPS::sim_add_plot );
TOOL_ACTION EE_ACTIONS::openWorkbook( "eeschema.Simulation.openWorkbook",
@ -1158,10 +1158,10 @@ TOOL_ACTION EE_ACTIONS::toggleDarkModePlots( "eeschema.Simulator.toggleDarkModeP
_( "Dark Mode Plots" ),
_( "Draw plots with a black background" ) );
TOOL_ACTION EE_ACTIONS::simCommand( "eeschema.Simulation.simCommand",
TOOL_ACTION EE_ACTIONS::simAnalysisProperties( "eeschema.Simulation.simAnalysisProperties",
AS_GLOBAL, 0, "",
_( "Edit Simulation Command..." ),
_( "Edit the simulation command for the current plot tab" ),
_( "Edit Analysis Tab..." ),
_( "Edit the SPICE command and plot setup for the current analysis tab" ),
BITMAPS::sim_command );
TOOL_ACTION EE_ACTIONS::runSimulation( "eeschema.Simulation.runSimulation",

View File

@ -259,7 +259,7 @@ public:
static TOOL_ACTION toggleAnnotateAuto;
// SPICE
static TOOL_ACTION newPlot;
static TOOL_ACTION newAnalysisTab;
static TOOL_ACTION openWorkbook;
static TOOL_ACTION saveWorkbook;
static TOOL_ACTION saveWorkbookAs;
@ -271,7 +271,7 @@ public:
static TOOL_ACTION toggleLegend;
static TOOL_ACTION toggleDottedSecondary;
static TOOL_ACTION toggleDarkModePlots;
static TOOL_ACTION simCommand;
static TOOL_ACTION simAnalysisProperties;
static TOOL_ACTION runSimulation;
static TOOL_ACTION stopSimulation;
static TOOL_ACTION editUserDefinedSignals;

View File

@ -60,7 +60,7 @@ void SIMULATOR_CONTROL::Reset( RESET_REASON aReason )
}
int SIMULATOR_CONTROL::NewPlot( const TOOL_EVENT& aEvent )
int SIMULATOR_CONTROL::NewAnalysisTab( const TOOL_EVENT& aEvent )
{
DIALOG_SIM_COMMAND dlg( m_simulatorFrame, m_circuitModel, m_simulator->Settings() );
wxString errors;
@ -77,7 +77,10 @@ int SIMULATOR_CONTROL::NewPlot( const TOOL_EVENT& aEvent )
dlg.SetSimOptions( NETLIST_EXPORTER_SPICE::OPTION_DEFAULT_FLAGS );
if( dlg.ShowModal() == wxID_OK )
m_simulatorFrame->NewPlotPanel( dlg.GetSimCommand(), dlg.GetSimOptions() );
{
SIM_TAB* tab = m_simulatorFrame->NewSimTab( dlg.GetSimCommand() );
dlg.ApplySettings( tab );
}
return 0;
}
@ -154,7 +157,7 @@ int SIMULATOR_CONTROL::SaveWorkbook( const TOOL_EVENT& aEvent )
int SIMULATOR_CONTROL::ExportPlotAsPNG( const TOOL_EVENT& aEvent )
{
if( SIM_PLOT_TAB* plotPanel = dynamic_cast<SIM_PLOT_TAB*>( GetCurrentPlotPanel() ) )
if( SIM_PLOT_TAB* plotTab = dynamic_cast<SIM_PLOT_TAB*>( getCurrentSimTab() ) )
{
wxFileDialog saveDlg( m_simulatorFrame, _( "Save Plot as Image" ), "", "",
PngFileWildcard(), wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
@ -162,14 +165,14 @@ int SIMULATOR_CONTROL::ExportPlotAsPNG( const TOOL_EVENT& aEvent )
if( saveDlg.ShowModal() == wxID_CANCEL )
return -1;
plotPanel->GetPlotWin()->SaveScreenshot( saveDlg.GetPath(), wxBITMAP_TYPE_PNG );
plotTab->GetPlotWin()->SaveScreenshot( saveDlg.GetPath(), wxBITMAP_TYPE_PNG );
}
return 0;
}
SIM_TAB* SIMULATOR_CONTROL::GetCurrentPlotPanel()
SIM_TAB* SIMULATOR_CONTROL::getCurrentSimTab()
{
return m_simulatorFrame->GetCurrentSimTab();
}
@ -177,7 +180,7 @@ SIM_TAB* SIMULATOR_CONTROL::GetCurrentPlotPanel()
int SIMULATOR_CONTROL::ExportPlotAsCSV( const TOOL_EVENT& aEvent )
{
if( SIM_PLOT_TAB* plotPanel = dynamic_cast<SIM_PLOT_TAB*>( GetCurrentPlotPanel() ) )
if( SIM_PLOT_TAB* plotTab = dynamic_cast<SIM_PLOT_TAB*>( getCurrentSimTab() ) )
{
const wxChar SEPARATOR = ';';
@ -189,12 +192,12 @@ int SIMULATOR_CONTROL::ExportPlotAsCSV( const TOOL_EVENT& aEvent )
wxFFile out( saveDlg.GetPath(), "wb" );
std::map<wxString, TRACE*> traces = plotPanel->GetTraces();
std::map<wxString, TRACE*> traces = plotTab->GetTraces();
if( traces.size() == 0 )
return -1;
SIM_TYPE simType = plotPanel->GetSimType();
SIM_TYPE simType = plotTab->GetSimType();
std::size_t rowCount = traces.begin()->second->GetDataX().size();
@ -238,11 +241,14 @@ int SIMULATOR_CONTROL::Close( const TOOL_EVENT& aEvent )
int SIMULATOR_CONTROL::Zoom( const TOOL_EVENT& aEvent )
{
if( SIM_PLOT_TAB* plotPanel = dynamic_cast<SIM_PLOT_TAB*>( GetCurrentPlotPanel() ) )
if( SIM_PLOT_TAB* plotTab = dynamic_cast<SIM_PLOT_TAB*>( getCurrentSimTab() ) )
{
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();
if( aEvent.IsAction( &ACTIONS::zoomInCenter ) )
plotTab->GetPlotWin()->ZoomIn();
else if( aEvent.IsAction( &ACTIONS::zoomOutCenter ) )
plotTab->GetPlotWin()->ZoomOut();
else if( aEvent.IsAction( &ACTIONS::zoomFitScreen ) )
plotTab->GetPlotWin()->Fit();
}
return 0;
@ -251,9 +257,9 @@ int SIMULATOR_CONTROL::Zoom( const TOOL_EVENT& aEvent )
int SIMULATOR_CONTROL::ToggleGrid( const TOOL_EVENT& aEvent )
{
if( SIM_PLOT_TAB* plotPanel = dynamic_cast<SIM_PLOT_TAB*>( GetCurrentPlotPanel() ) )
if( SIM_PLOT_TAB* plotTab = dynamic_cast<SIM_PLOT_TAB*>( getCurrentSimTab() ) )
{
plotPanel->ShowGrid( !plotPanel->IsGridShown() );
plotTab->ShowGrid( !plotTab->IsGridShown() );
m_simulatorFrame->OnModify();
}
@ -263,9 +269,9 @@ int SIMULATOR_CONTROL::ToggleGrid( const TOOL_EVENT& aEvent )
int SIMULATOR_CONTROL::ToggleLegend( const TOOL_EVENT& aEvent )
{
if( SIM_PLOT_TAB* plotPanel = dynamic_cast<SIM_PLOT_TAB*>( GetCurrentPlotPanel() ) )
if( SIM_PLOT_TAB* plotTab = dynamic_cast<SIM_PLOT_TAB*>( getCurrentSimTab() ) )
{
plotPanel->ShowLegend( !plotPanel->IsLegendShown() );
plotTab->ShowLegend( !plotTab->IsLegendShown() );
m_simulatorFrame->OnModify();
}
@ -275,9 +281,9 @@ int SIMULATOR_CONTROL::ToggleLegend( const TOOL_EVENT& aEvent )
int SIMULATOR_CONTROL::ToggleDottedSecondary( const TOOL_EVENT& aEvent )
{
if( SIM_PLOT_TAB* plotPanel = dynamic_cast<SIM_PLOT_TAB*>( GetCurrentPlotPanel() ) )
if( SIM_PLOT_TAB* plotTab = dynamic_cast<SIM_PLOT_TAB*>( getCurrentSimTab() ) )
{
plotPanel->SetDottedSecondary( !plotPanel->GetDottedSecondary() );
plotTab->SetDottedSecondary( !plotTab->GetDottedSecondary() );
m_simulatorFrame->OnModify();
}
@ -292,9 +298,9 @@ int SIMULATOR_CONTROL::ToggleDarkModePlots( const TOOL_EVENT& aEvent )
}
int SIMULATOR_CONTROL::EditSimCommand( const TOOL_EVENT& aEvent )
int SIMULATOR_CONTROL::EditAnalysisTab( const TOOL_EVENT& aEvent )
{
m_simulatorFrame->EditSimCommand();
m_simulatorFrame->EditAnalysis();
return 0;
}
@ -307,10 +313,10 @@ int SIMULATOR_CONTROL::RunSimulation( const TOOL_EVENT& aEvent )
return 0;
}
if( !GetCurrentPlotPanel() )
NewPlot( aEvent );
if( !getCurrentSimTab() )
NewAnalysisTab( aEvent );
if( !GetCurrentPlotPanel() )
if( !getCurrentSimTab() )
return 0;
m_simulatorFrame->StartSimulation();
@ -472,7 +478,7 @@ int SIMULATOR_CONTROL::ShowNetlist( const TOOL_EVENT& aEvent )
void SIMULATOR_CONTROL::setTransitions()
{
Go( &SIMULATOR_CONTROL::NewPlot, EE_ACTIONS::newPlot.MakeEvent() );
Go( &SIMULATOR_CONTROL::NewAnalysisTab, EE_ACTIONS::newAnalysisTab.MakeEvent() );
Go( &SIMULATOR_CONTROL::OpenWorkbook, EE_ACTIONS::openWorkbook.MakeEvent() );
Go( &SIMULATOR_CONTROL::SaveWorkbook, EE_ACTIONS::saveWorkbook.MakeEvent() );
Go( &SIMULATOR_CONTROL::SaveWorkbook, EE_ACTIONS::saveWorkbookAs.MakeEvent() );
@ -488,7 +494,7 @@ void SIMULATOR_CONTROL::setTransitions()
Go( &SIMULATOR_CONTROL::ToggleDottedSecondary, EE_ACTIONS::toggleDottedSecondary.MakeEvent() );
Go( &SIMULATOR_CONTROL::ToggleDarkModePlots, EE_ACTIONS::toggleDarkModePlots.MakeEvent() );
Go( &SIMULATOR_CONTROL::EditSimCommand, EE_ACTIONS::simCommand.MakeEvent() );
Go( &SIMULATOR_CONTROL::EditAnalysisTab, EE_ACTIONS::simAnalysisProperties.MakeEvent() );
Go( &SIMULATOR_CONTROL::RunSimulation, EE_ACTIONS::runSimulation.MakeEvent() );
Go( &SIMULATOR_CONTROL::RunSimulation, EE_ACTIONS::stopSimulation.MakeEvent() );
Go( &SIMULATOR_CONTROL::Probe, EE_ACTIONS::simProbe.MakeEvent() );

View File

@ -53,7 +53,7 @@ public:
/// @copydoc TOOL_INTERACTIVE::Reset()
void Reset( RESET_REASON aReason ) override;
int NewPlot( const TOOL_EVENT& aEvent );
int NewAnalysisTab( const TOOL_EVENT& aEvent );
int OpenWorkbook( const TOOL_EVENT& aEvent );
int SaveWorkbook( const TOOL_EVENT& aEvent );
int ExportPlotAsPNG( const TOOL_EVENT& aEvent );
@ -66,7 +66,7 @@ public:
int ToggleDottedSecondary( const TOOL_EVENT& aEvent );
int ToggleDarkModePlots( const TOOL_EVENT& aEvent );
int EditSimCommand( const TOOL_EVENT& aEvent );
int EditAnalysisTab( const TOOL_EVENT& aEvent );
int RunSimulation( const TOOL_EVENT& aEvent );
int Probe( const TOOL_EVENT& aEvent );
int Tune( const TOOL_EVENT& aEvent );
@ -85,7 +85,7 @@ private:
*/
wxString getDefaultPath();
SIM_TAB* GetCurrentPlotPanel();
SIM_TAB* getCurrentSimTab();
///< Set up handlers for various events.
void setTransitions() override;

View File

@ -678,13 +678,6 @@ public:
// virtual double X2p( mpWindow &w, double x ) = 0;
// virtual double P2x( mpWindow &w, double x ) = 0;
void SetDataRange( double minV, double maxV )
{
m_rangeSet = true;
m_minV = minV;
m_maxV = maxV;
}
void GetDataRange( double& minV, double& maxV ) const
{
minV = m_minV;
@ -727,6 +720,29 @@ public:
return m_absVisibleMaxV;
}
void SetAxisMinMax( bool lock, double minV, double maxV )
{
m_axisLocked = lock;
m_axisMin = minV;
m_axisMax = maxV;
}
bool GetAxisMinMax( double* minV, double* maxV )
{
if( m_axisLocked )
{
*minV = m_axisMin;
*maxV = m_axisMax;
}
else if( !m_tickValues.empty() )
{
*minV = m_tickValues.front();
*maxV = m_tickValues.back();
}
return m_axisLocked;
}
virtual double TransformToPlot( double x ) const { return 0.0; };
virtual double TransformFromPlot( double xplot ) const { return 0.0; };
@ -755,12 +771,12 @@ protected:
int tickCount() const
{
return m_tickValues.size();
return (int) m_tickValues.size();
}
virtual int labelCount() const
{
return m_tickLabels.size();
return (int) m_tickLabels.size();
}
virtual const wxString formatLabel( double value, int nDigits ) { return wxT( "" ); }
@ -781,18 +797,22 @@ protected:
return m_tickLabels[n].label;
}
std::vector<double> m_tickValues;
protected:
std::vector<double> m_tickValues;
std::vector<TickLabel> m_tickLabels;
double m_offset, m_scale;
double m_absVisibleMaxV;
int m_flags; // !< Flag for axis alignment
int m_nameFlags;
bool m_ticks; // !< Flag to toggle between ticks or grid
double m_minV, m_maxV;
bool m_rangeSet;
int m_maxLabelHeight;
int m_maxLabelWidth;
double m_offset, m_scale;
double m_absVisibleMaxV;
int m_flags; // !< Flag for axis alignment
int m_nameFlags;
bool m_ticks; // !< Flag to toggle between ticks or grid
double m_minV, m_maxV;
bool m_rangeSet;
bool m_axisLocked;
double m_axisMin;
double m_axisMax;
int m_maxLabelHeight;
int m_maxLabelWidth;
};
class WXDLLIMPEXP_MATHPLOT mpScaleXBase : public mpScaleBase
@ -1058,29 +1078,25 @@ public:
* See @ref mpLayer::Plot "rules for coordinate transformation"
* @return Scale
*/
double GetXscl() const { return m_scaleX; }
double GetScaleX( void ) const { return m_scaleX; }; // Schaling's method: maybe another method exists with the same name
double GetScaleX() const { return m_scaleX; };
/** Get current view's Y scale.
* See @ref mpLayer::Plot "rules for coordinate transformation"
* @return Scale
*/
double GetYscl() const { return m_scaleY; }
double GetScaleY( void ) const { return m_scaleY; } // Schaling's method: maybe another method exists with the same name
double GetScaleY() const { return m_scaleY; }
/** Get current view's X position.
* See @ref mpLayer::Plot "rules for coordinate transformation"
* @return X Position in layer coordinate system, that corresponds to the center point of the view.
*/
double GetXpos() const { return m_posX; }
double GetPosX( void ) const { return m_posX; }
double GetPosX() const { return m_posX; }
/** Get current view's Y position.
* See @ref mpLayer::Plot "rules for coordinate transformation"
* @return Y Position in layer coordinate system, that corresponds to the center point of the view.
*/
double GetYpos() const { return m_posY; }
double GetPosY( void ) const { return m_posY; }
double GetPosY() const { return m_posY; }
/** Get current view's X dimension in device context units.
* Usually this is equal to wxDC::GetSize, but it might differ thus mpLayer
@ -1088,8 +1104,8 @@ public:
* See @ref mpLayer::Plot "rules for coordinate transformation"
* @return X dimension.
*/
int GetScrX( void ) const { return m_scrX; }
int GetXScreen( void ) const { return m_scrX; }
int GetScrX() const { return m_scrX; }
int GetXScreen() const { return m_scrX; }
/** Get current view's Y dimension in device context units.
* Usually this is equal to wxDC::GetSize, but it might differ thus mpLayer
@ -1097,8 +1113,8 @@ public:
* See @ref mpLayer::Plot "rules for coordinate transformation"
* @return Y dimension.
*/
int GetScrY( void ) const { return m_scrY; }
int GetYScreen( void ) const { return m_scrY; }
int GetScrY() const { return m_scrY; }
int GetYScreen() const { return m_scrY; }
/** Set current view's X scale and refresh display.
* @param scaleX New scale, must not be 0.
@ -1338,6 +1354,10 @@ public:
m_enableLimitedView = aEnable;
}
void LockY( bool aLock ) { m_yLocked = aLock; }
void AdjustLimitedView();
protected:
void OnPaint( wxPaintEvent& event ); // !< Paint handler, will plot all attached layers
void OnSize( wxSizeEvent& event ); // !< Size handler, will update scroll bar sizes
@ -1376,8 +1396,6 @@ protected:
|| desiredMin < m_minY + m_marginTop / m_scaleY) );
}
void AdjustLimitedView();
/** Recalculate global layer bounding box, and save it in m_minX,...
* \return true if there is any valid BBox information.
*/
@ -1413,6 +1431,8 @@ protected:
int m_clickedX; // !< Last mouse click X position, for centering and zooming the view
int m_clickedY; // !< Last mouse click Y position, for centering and zooming the view
bool m_yLocked;
/** These are updated in Fit() only, and may be different from the real borders
* (layer coordinates) only if lock aspect ratio is true.
*/
@ -1429,8 +1449,6 @@ protected:
bool m_enableLimitedView;
wxPoint m_mouseMClick; // !< For the middle button "drag" feature
wxPoint m_mouseLClick; // !< Starting coords for rectangular zoom selection
bool m_enableScrollBars;
wxPoint m_scroll;
mpInfoLayer* m_movingInfoLayer; // !< For moving info layers over the window area
bool m_zooming;
wxRect m_zoomRect;