29#include <fmt/format.h>
30#include <wx/wfstream.h>
31#include <wx/stdstream.h>
33#include <wx/clipbrd.h>
59 int res = (int) aFirst | (
int) aSecond;
120 void showPopupMenu( wxMenu& menu, wxGridEvent& aEvent )
override;
144 if( panel->GetSimType() ==
ST_TRAN || panel->GetSimType() ==
ST_AC
145 || panel->GetSimType() ==
ST_DC || panel->GetSimType() ==
ST_SP )
153 if( panel->GetSimType() ==
ST_AC || panel->GetSimType() ==
ST_SP )
166 if( panel->GetSimType() ==
ST_TRAN )
168 menu.AppendSeparator();
169 menu.Append(
MYID_FOURIER,
_(
"Perform Fourier Analysis..." ) );
172 menu.AppendSeparator();
175 m_grid->PopupMenu( &menu );
184 std::vector<wxString> signals;
186 wxGridCellCoordsArray cells1 =
m_grid->GetSelectionBlockTopLeft();
187 wxGridCellCoordsArray cells2 =
m_grid->GetSelectionBlockBottomRight();
189 for(
size_t i = 0; i < cells1.Count(); i++ )
193 for(
int j = cells1[i].GetRow(); j < cells2[i].GetRow() + 1; j++ )
195 signals.push_back(
m_grid->GetCellValue( j, cells1[i].GetCol() ) );
200 wxGridCellCoordsArray cells3 =
m_grid->GetSelectedCells();
202 for(
size_t i = 0; i < cells3.Count(); i++ )
205 signals.push_back(
m_grid->GetCellValue( cells3[i].GetRow(), cells3[i].GetCol() ) );
208 if( signals.size() < 1 )
211 auto addMeasurement =
212 [
this](
const wxString& cmd, wxString signal )
214 if( signal.EndsWith(
_(
" (phase)" ) ) )
217 if( signal.EndsWith(
_(
" (gain)" ) ) || signal.EndsWith(
_(
" (amplitude)" ) ) )
219 signal = signal.Left( signal.length() - 7 );
221 if( signal.Upper().StartsWith( wxS(
"V(" ) ) )
222 signal = wxS(
"vdb" ) + signal.Mid( 1 );
230 for(
const wxString& signal : signals )
231 addMeasurement( wxS(
"MIN" ), signal );
235 for(
const wxString& signal : signals )
236 addMeasurement( wxS(
"MAX" ), signal );
240 for(
const wxString& signal : signals )
241 addMeasurement( wxS(
"AVG" ), signal );
245 for(
const wxString& signal : signals )
246 addMeasurement( wxS(
"RMS" ), signal );
250 for(
const wxString& signal : signals )
251 addMeasurement( wxS(
"PP" ), signal );
255 for(
const wxString& signal : signals )
256 addMeasurement( wxS(
"MIN_AT" ), signal );
260 for(
const wxString& signal : signals )
261 addMeasurement( wxS(
"MAX_AT" ), signal );
265 for(
const wxString& signal : signals )
266 addMeasurement( wxS(
"INTEG" ), signal );
271 wxString fundamental = wxT(
"1K" );
273 if( signals.size() == 1 )
274 title.Printf(
_(
"Fourier Analysis of %s" ), signals[0] );
276 title =
_(
"Fourier Analyses of Multiple Signals" );
280 if( dlg.ShowModal() != wxID_OK )
286 for(
const wxString& signal : signals )
294 for(
const wxString& signal : signals )
302 if( wxTheClipboard->Open() )
304 wxTheClipboard->SetData(
new wxTextDataObject( txt ) );
305 wxTheClipboard->Flush();
306 wxTheClipboard->Close();
323 void showPopupMenu( wxMenu& menu, wxGridEvent& aEvent )
override;
343 menu.AppendSeparator();
353 [
this](
int row ) -> wxString
357 if( signal.EndsWith(
"[2 - 1]" ) )
358 signal = signal.Left( signal.length() - 7 );
369 if( formatDialog.ShowModal() == wxID_OK )
371 for(
int row = 0; row <
m_grid->GetNumberRows(); ++row )
373 if( getSignalName( row ) == getSignalName(
m_menuRow ) )
396 void showPopupMenu( wxMenu& menu, wxGridEvent& aEvent )
override;
422 menu.AppendSeparator();
435 if( formatDialog.ShowModal() == wxID_OK )
444 std::vector<int> measurements;
446 wxGridCellCoordsArray cells1 =
m_grid->GetSelectionBlockTopLeft();
447 wxGridCellCoordsArray cells2 =
m_grid->GetSelectionBlockBottomRight();
449 for(
size_t i = 0; i < cells1.Count(); i++ )
453 for(
int j = cells1[i].GetRow(); j < cells2[i].GetRow() + 1; j++ )
454 measurements.push_back( j );
458 wxGridCellCoordsArray cells3 =
m_grid->GetSelectedCells();
460 for(
size_t i = 0; i < cells3.Count(); i++ )
463 measurements.push_back( cells3[i].GetRow() );
466 if( measurements.size() < 1 )
471 sort( measurements.begin(), measurements.end(), std::greater<>() );
473 for(
int row : measurements )
506#define ID_SIM_REFRESH 10207
507#define REFRESH_INTERVAL 50
513 m_SuppressGridEvents( 0 ),
514 m_simulatorFrame( aSimulatorFrame ),
515 m_schematicFrame( aSchematicFrame ),
533 wxGridCellAttr* attr =
new wxGridCellAttr;
537 attr =
new wxGridCellAttr;
541 attr =
new wxGridCellAttr;
545 attr =
new wxGridCellAttr;
549 for(
int cursorId = 0; cursorId < 3; ++cursorId )
555 attr =
new wxGridCellAttr;
565 [&]( wxTimerEvent& aEvent )
574#ifndef wxHAS_NATIVE_TABART
592 for(
int ii = 0; ii < (int)
m_plotNotebook->GetPageCount(); ++ii )
596 simTab->OnLanguageChanged();
598 wxString pageTitle(
simulator()->TypeToName( simTab->GetSimType(),
true ) );
599 pageTitle.Prepend( wxString::Format(
_(
"Analysis %u - " ), ii+1 ) );
620 tuner->ShowChangedLanguage();
658 for( std::size_t i = 0; i < pageCount; ++i )
661 auto simTab =
dynamic_cast<SIM_TAB*
>( page );
662 wxASSERT( simTab !=
nullptr );
663 simTab->ApplyPreferences( aPrefs );
670 if( !
simulator()->Settings()->GetWorkbookFilename().IsEmpty() )
672 wxFileName filename =
simulator()->Settings()->GetWorkbookFilename();
676 simulator()->Settings()->SetWorkbookFilename(
"" );
680 wxString schTextSimCommand =
circuitModel()->GetSchTextSimCommand();
682 if( !schTextSimCommand.IsEmpty() )
715 std::sort( signals.begin(), signals.end(),
716 [](
const wxString& lhs,
const wxString& rhs )
719 if( lhs.Upper().StartsWith(
'V' ) && !rhs.Upper().StartsWith(
'V' ) )
721 else if( !lhs.Upper().StartsWith(
'V' ) && rhs.Upper().StartsWith(
'V' ) )
724 return StrNumCmp( lhs, rhs, true ) < 0;
741 std::vector<wxString> signals;
745 wxStringTokenizer tokenizer( plotPanel->
GetSimCommand(), wxT(
" \t\r\n" ), wxTOKEN_STRTOK );
747 while( tokenizer.HasMoreTokens() && tokenizer.GetNextToken().Lower() != wxT(
"fft" ) )
750 while( tokenizer.HasMoreTokens() )
751 signals.emplace_back( tokenizer.GetNextToken() );
758 for(
const wxString& signal :
m_signals )
759 signals.push_back( signal );
763 if( simType ==
ST_AC )
765 signals.push_back( signal +
_(
" (gain)" ) );
766 signals.push_back( signal +
_(
" (phase)" ) );
768 else if( simType ==
ST_SP )
770 signals.push_back( signal +
_(
" (amplitude)" ) );
771 signals.push_back( signal +
_(
" (phase)" ) );
775 signals.push_back( signal );
782 if( aFilter.IsEmpty() )
783 aFilter = wxS(
"*" );
788 for(
const wxString& signal : signals )
790 if( matcher.
Find( signal.Upper() ) )
799 wxGridCellAttr* attr =
new wxGridCellAttr;
800 attr->SetRenderer(
new wxGridCellBoolRenderer() );
802 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
807 attr =
new wxGridCellAttr;
812 attr =
new wxGridCellAttr;
816 attr =
new wxGridCellAttr;
824 attr =
new wxGridCellAttr;
827 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
832 attr =
new wxGridCellAttr;
833 attr->SetRenderer(
new wxGridCellBoolRenderer() );
835 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
838 attr =
new wxGridCellAttr;
839 attr->SetRenderer(
new wxGridCellBoolRenderer() );
841 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
857 wxString unconnected = wxString( wxS(
"unconnected-(" ) );
862 unconnected.Replace(
'(',
'_' );
865 [&](
const wxString& aSignalName )
867 if( simType ==
ST_AC )
869 m_signals.push_back( aSignalName +
_(
" (gain)" ) );
870 m_signals.push_back( aSignalName +
_(
" (phase)" ) );
872 else if( simType ==
ST_SP )
874 m_signals.push_back( aSignalName +
_(
" (amplitude)" ) );
875 m_signals.push_back( aSignalName +
_(
" (phase)" ) );
892 if( netname ==
"GND" || netname ==
"0" || netname.StartsWith( unconnected ) )
896 addSignal( wxString::Format( wxS(
"V(%s)" ), netname ) );
906 for(
const std::string&
name : item.model->SpiceGenerator().CurrentNames( item ) )
916 if( item.model->GetPinCount() >= 2 )
918 wxString
name = item.model->SpiceGenerator().ItemName( item );
919 addSignal( wxString::Format( wxS(
"P(%s)" ),
name ) );
926 addSignal( wxS(
"inoise_spectrum" ) );
927 addSignal( wxS(
"onoise_spectrum" ) );
930 if( simType ==
ST_SP )
932 std::vector<std::string> portnums;
936 wxString
name = item.model->SpiceGenerator().ItemName( item );
939 if( !
name.StartsWith(
"V" ) )
942 std::string portnum =
"";
944 if(
const SIM_MODEL::PARAM* portnum_param = item.model->FindParam(
"portnum" ) )
948 portnums.push_back( portnum );
951 for(
const std::string& portnum1 : portnums )
953 for(
const std::string& portnum2 : portnums )
955 addSignal( wxString::Format( wxS(
"S_%s_%s" ), portnum1, portnum2 ) );
961 for(
const wxString& directive :
circuitModel()->GetDirectives() )
963 wxStringTokenizer directivesTokenizer( directive, wxT(
"\r\n" ), wxTOKEN_STRTOK );
965 while( directivesTokenizer.HasMoreTokens() )
967 wxString line = directivesTokenizer.GetNextToken().Upper();
968 wxString directiveParams;
970 if( line.StartsWith( wxS(
".SAVE" ), &directiveParams )
971 || line.StartsWith( wxS(
".PROBE" ), &directiveParams ) )
973 wxStringTokenizer paramsTokenizer( directiveParams, wxT(
" \t" ), wxTOKEN_STRTOK );
975 while( paramsTokenizer.HasMoreTokens() )
976 addSignal( paramsTokenizer.GetNextToken() );
999 wxString pageTitle(
simulator()->TypeToName( simType,
true ) );
1000 pageTitle.Prepend( wxString::Format(
_(
"Analysis %u - " ), (
unsigned int) ++
m_plotNumber ) );
1016 wxPoint pos = aEvent.GetPosition();
1017 wxRect ctrlRect =
m_filter->GetScreenRect();
1018 int buttonWidth = ctrlRect.GetHeight();
1020 if(
m_filter->IsSearchButtonVisible() && pos.x < buttonWidth )
1021 SetCursor( wxCURSOR_ARROW );
1022 else if(
m_filter->IsCancelButtonVisible() && pos.x > ctrlRect.GetWidth() - buttonWidth )
1023 SetCursor( wxCURSOR_ARROW );
1025 SetCursor( wxCURSOR_IBEAM );
1031 return wxString::Format( wxS(
"user%d" ), aUserDefinedSignalId );
1040 const wxString& aSignalName,
1043 std::map<wxString, int> suffixes;
1059 wxUniChar firstChar = aSignalName.Upper()[0];
1061 if( firstChar ==
'V' )
1063 else if( firstChar ==
'I' )
1065 else if( firstChar ==
'P' )
1071 wxString
name = aSignalName;
1073 for(
const auto& [ candidate, type ] : suffixes )
1075 if(
name.EndsWith( candidate ) )
1077 name =
name.Left(
name.Length() - candidate.Length() );
1080 *aTraceType |= type;
1088 if(
name == signal )
1106 int row = aEvent.GetRow();
1107 int col = aEvent.GetCol();
1115 if(
text == wxS(
"1" ) )
1142 for(
int ii = 0; ii <
m_signalsGrid->GetNumberRows(); ++ii )
1148 bool enable = ii == row &&
text == wxS(
"1" );
1150 plotTab->
EnableCursor( vectorName, traceType,
id, enable, signalName );
1170 int row = aEvent.GetRow();
1171 int col = aEvent.GetCol();
1177 CURSOR* cursor1 =
nullptr;
1178 CURSOR* cursor2 =
nullptr;
1191 if( cursorName == wxS(
"1" ) && cursor1 )
1193 else if( cursorName == wxS(
"2" ) && cursor2 )
1195 else if( cursorName ==
_(
"Diff" ) && cursor1 && cursor2 )
1203 wxFAIL_MSG( wxT(
"All other columns are supposed to be read-only!" ) );
1236 int row = aEvent.GetRow();
1237 int col = aEvent.GetCol();
1248 wxFAIL_MSG( wxT(
"All other columns are supposed to be read-only!" ) );
1256 for( row = rowCount - 1; row >= 0; row-- )
1266 int killRows = emptyRows - 1;
1269 else if( emptyRows == 0 )
1280 if( plotTab->GetLegendPosition() != plotTab->m_LastLegendPosition )
1282 plotTab->m_LastLegendPosition = plotTab->GetLegendPosition();
1305 static wxRegEx measureParamsRegEx( wxT(
"^"
1309 "([a-zA-Z]*)\\(([^\\)]+)\\)" ) );
1318 if(
text.IsEmpty() )
1325 wxString resultName = wxString::Format( wxS(
"meas_result_%u" ), aRow );
1326 wxString result = wxS(
"?" );
1328 if( measureParamsRegEx.Matches(
text ) )
1330 wxString func = measureParamsRegEx.GetMatch(
text, 1 ).Upper();
1331 wxString signalType = measureParamsRegEx.GetMatch(
text, 2 ).Upper();
1332 wxString deviceName = measureParamsRegEx.GetMatch(
text, 3 );
1336 if( signalType.EndsWith( wxS(
"DB" ) ) )
1338 units = wxS(
"dB" );
1340 else if( signalType.StartsWith(
'I' ) )
1344 else if( signalType.StartsWith(
'P' ) )
1348 text = func +
" " + deviceName +
":power";
1355 if( func.EndsWith( wxS(
"_AT" ) ) )
1358 units = wxS(
"Hz" );
1362 else if( func.StartsWith( wxS(
"INTEG" ) ) )
1367 if ( signalType.StartsWith(
'P' ) )
1370 units += wxS(
".s" );
1380 units += wxS(
"·Hz" );
1388 units += wxS(
"·?" );
1401 wxString cmd = wxString::Format( wxS(
"meas %s %s %s" ), simType, resultName,
text );
1402 simulator()->Command(
"echo " + cmd.ToStdString() );
1403 simulator()->Command( cmd.ToStdString() );
1405 std::vector<double> resultVec =
simulator()->GetGainVector( resultName.ToStdString() );
1407 if( resultVec.size() > 0 )
1422 wxString ref = aSymbol->
GetRef( &aSheetPath );
1427 if( tuner->GetSymbolRef() == ref )
1453 const wxString& aRef,
const wxString& aValue )
1461 + wxString::Format(
_(
"%s not found" ), aRef ) );
1474 + wxString::Format(
_(
"%s is not tunable" ), aRef ) );
1540 wxString cmd = wxString::Format( wxS(
"fourier %s %s" ),
1544 simulator()->Command( cmd.ToStdString() );
1558 m_simConsole->AppendText(
_(
"Error: no current simulation.\n" ) );
1567 m_simConsole->AppendText(
_(
"Error: simulation type not defined.\n" ) );
1573 m_simConsole->AppendText(
_(
"Error: simulation type doesn't support plotting.\n" ) );
1580 if( simType ==
ST_AC )
1585 else if( simType ==
ST_SP )
1595 plotTab->GetPlotWin()->UpdateAll();
1617 if( aNewSignals.count(
id ) == 0 )
1622 plotTab->
DeleteTrace( vectorName, traceType | subType );
1627 plotTab->
DeleteTrace( vectorName, traceType | subType );
1640 if(
TRACE* trace = plotTab->
GetTrace( vectorName, traceType | subType ) )
1641 trace->SetName( aNewSignals.at(
id ) );
1648 if(
TRACE* trace = plotTab->
GetTrace( vectorName, traceType | subType ) )
1649 trace->SetName( aNewSignals.at(
id ) );
1654 if(
TRACE* trace = plotTab->
GetTrace( vectorName, traceType ) )
1655 trace->SetName( aNewSignals.at(
id ) );
1683 wxString simVectorName = aVectorName;
1686 simVectorName = simVectorName.AfterFirst(
'(' ).BeforeLast(
')' ) + wxS(
":power" );
1691 simulator()->Command( wxString::Format( wxT(
"print %s" ), aVectorName ).ToStdString() );
1696 std::vector<double> data_x;
1697 std::vector<double> data_y;
1699 if( !aDataX || aClearData )
1703 if( aDataX->empty() && !aClearData )
1705 wxString xAxisName(
simulator()->GetXAxis( simType ) );
1707 if( xAxisName.IsEmpty() )
1710 *aDataX =
simulator()->GetGainVector( (
const char*) xAxisName.c_str() );
1713 unsigned int size = aDataX->size();
1719 data_y =
simulator()->GetGainVector( (
const char*) simVectorName.c_str(), size );
1721 data_y =
simulator()->GetPhaseVector( (
const char*) simVectorName.c_str(), size );
1723 wxFAIL_MSG( wxT(
"Plot type missing AC_PHASE or AC_MAG bit" ) );
1728 data_y =
simulator()->GetGainVector( (
const char*) simVectorName.c_str(), size );
1730 data_y =
simulator()->GetPhaseVector( (
const char*) simVectorName.c_str(), size );
1732 wxFAIL_MSG( wxT(
"Plot type missing AC_PHASE or SPT_SP_AMP bit" ) );
1737 data_y =
simulator()->GetGainVector( (
const char*) simVectorName.c_str(), -1 );
1743 data_y =
simulator()->GetGainVector( (
const char*) simVectorName.c_str(), size );
1747 wxFAIL_MSG( wxT(
"Unhandled plot type" ) );
1752 size_t sweepSize = std::numeric_limits<size_t>::max();
1754 if( simType ==
ST_DC
1761 sweepSize = aDataX->size() / sweepCount;
1766 if( data_y.size() >= size )
1767 aPlotTab->
SetTraceData( trace, *aDataX, data_y, sweepCount, sweepSize );
1776 for(
int row = 0; row <
m_signalsGrid->GetNumberRows(); ++row )
1782 if(
TRACE* trace = plotTab ? plotTab->
GetTrace( vectorName, traceType ) :
nullptr )
1786 wxGridCellAttr* attr =
new wxGridCellAttr;
1789 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
1795 attr =
new wxGridCellAttr;
1796 attr->SetRenderer(
new wxGridCellBoolRenderer() );
1797 attr->SetReadOnly();
1798 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
1801 attr =
new wxGridCellAttr;
1802 attr->SetRenderer(
new wxGridCellBoolRenderer() );
1803 attr->SetReadOnly();
1804 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
1807 if( trace->HasCursor( 1 ) )
1812 if( trace->HasCursor( 2 ) )
1821 wxGridCellAttr* attr =
new wxGridCellAttr;
1822 attr->SetReadOnly();
1826 attr =
new wxGridCellAttr;
1827 attr->SetReadOnly();
1831 attr =
new wxGridCellAttr;
1832 attr->SetReadOnly();
1842 auto quoteNetNames =
1843 [&]( wxString aExpression ) -> wxString
1846 aExpression.Replace( netname, quotedNetname );
1853 constexpr const char* cmd =
"let user{} = {}";
1855 simulator()->Command(
"echo " + fmt::format( cmd,
id, signal.ToStdString() ) );
1856 simulator()->Command( fmt::format( cmd,
id, quoteNetNames( signal ).ToStdString() ) );
1869 wxString ref = tuner->GetSymbolRef();
1870 KIID symbolId = tuner->GetSymbol( &sheetPath );
1876 reporter.
Report( wxString::Format(
_(
"%s not found" ), ref ) );
1884 reporter.
Report( wxString::Format(
_(
"%s is not tunable" ), ref ) );
1888 double floatVal = tuner->GetValue().ToDouble();
1900 wxTextFile file( aPath );
1905 wxString firstLine = file.GetFirstLine();
1907 bool legacy = firstLine.StartsWith( wxT(
"version " ) ) || firstLine.ToLong( &
dummy );
1932 wxFileName filename( aPath );
1936 simulator()->Settings()->SetWorkbookFilename( filename.GetFullPath() );
1944 wxFFileInputStream fp( aPath, wxT(
"rt" ) );
1945 wxStdInputStream fstream( fp );
1952 nlohmann::json js = nlohmann::json::parse( fstream,
nullptr,
true,
true );
1954 std::map<SIM_PLOT_TAB*, nlohmann::json> traceInfo;
1956 for(
const nlohmann::json& tab_js : js[
"tabs" ] )
1958 wxString simCommand;
1962 for(
const nlohmann::json& cmd : tab_js[
"commands" ] )
1964 if( cmd ==
".kicad adjustpaths" )
1966 else if( cmd ==
".save all" )
1968 else if( cmd ==
".probe alli" )
1970 else if( cmd ==
".probe allp" )
1972 else if( cmd ==
".kicad esavenone" )
1975 simCommand += wxString( cmd.get<wxString>() ).Trim();
1985 if( tab_js.contains(
"traces" ) )
1986 traceInfo[plotTab] = tab_js[
"traces" ];
1988 if( tab_js.contains(
"measurements" ) )
1990 for(
const nlohmann::json& m_js : tab_js[
"measurements" ] )
1991 plotTab->
Measurements().emplace_back( m_js[
"expr" ], m_js[
"format" ] );
1995 plotTab->
ShowGrid( tab_js[
"showGrid" ] );
1997 if( tab_js.contains(
"fixedY1scale" ) )
1999 const nlohmann::json& scale_js = tab_js[
"fixedY1scale" ];
2000 plotTab->
SetY1Scale(
true, scale_js[
"min" ], scale_js[
"max" ] );
2004 if( tab_js.contains(
"fixedY2scale" ) )
2006 const nlohmann::json& scale_js = tab_js[
"fixedY2scale" ];
2007 plotTab->
SetY2Scale(
true, scale_js[
"min" ], scale_js[
"max" ] );
2011 if( tab_js.contains(
"fixedY3scale" ) )
2014 const nlohmann::json& scale_js = tab_js[
"fixedY3scale" ];
2015 plotTab->
SetY3Scale(
true, scale_js[
"min" ], scale_js[
"max" ] );
2019 if( tab_js.contains(
"legend" ) )
2021 const nlohmann::json& legend_js = tab_js[
"legend" ];
2026 if( tab_js.contains(
"margins" ) )
2028 const nlohmann::json& margins_js = tab_js[
"margins" ];
2030 margins_js[
"right" ],
2031 margins_js[
"bottom" ],
2032 margins_js[
"left" ] );
2039 if( js.contains(
"user_defined_signals" ) )
2041 for(
const nlohmann::json& signal_js : js[
"user_defined_signals" ] )
2047 int aCursorId,
const nlohmann::json& aCursor_js )
2049 if( aCursorId == 1 || aCursorId == 2 )
2053 cursor->SetName( aSignalName );
2054 cursor->SetPen( wxPen( aTrace->GetTraceColour() ) );
2055 cursor->SetCoordX( aCursor_js[
"position" ] );
2057 aTrace->SetCursor( aCursorId,
cursor );
2065 for(
const auto& [ plotTab, traces_js ] : traceInfo )
2067 for(
const nlohmann::json& trace_js : traces_js )
2069 wxString signalName = trace_js[
"signal" ];
2071 TRACE* trace = plotTab->GetOrAddTrace( vectorName, trace_js[
"trace_type" ] );
2075 if( trace_js.contains(
"cursor1" ) )
2076 addCursor( plotTab, trace, signalName, 1, trace_js[
"cursor1" ] );
2078 if( trace_js.contains(
"cursor2" ) )
2079 addCursor( plotTab, trace, signalName, 2, trace_js[
"cursor2" ] );
2081 if( trace_js.contains(
"cursorD" ) )
2082 addCursor( plotTab, trace, signalName, 3, trace_js[
"cursorD" ] );
2084 if( trace_js.contains(
"color" ) )
2087 color.Set( wxString( trace_js[
"color"].get<wxString>() ) );
2089 plotTab->UpdateTraceStyle( trace );
2094 plotTab->UpdatePlotColors();
2102 firstTab->SetLastSchTextSimCommand( js[
"last_sch_text_sim_command" ] );
2105 catch( nlohmann::json::parse_error& error )
2107 wxLogTrace(
traceSettings, wxT(
"Json parse error reading %s: %s" ), aPath, error.what() );
2111 catch( nlohmann::json::type_error& error )
2113 wxLogTrace(
traceSettings, wxT(
"Json type error reading %s: %s" ), aPath, error.what() );
2117 catch( nlohmann::json::invalid_iterator& error )
2119 wxLogTrace(
traceSettings, wxT(
"Json invalid_iterator error reading %s: %s" ), aPath, error.what() );
2123 catch( nlohmann::json::out_of_range& error )
2125 wxLogTrace(
traceSettings, wxT(
"Json out_of_range error reading %s: %s" ), aPath, error.what() );
2131 wxLogTrace(
traceSettings, wxT(
"Error reading %s" ), aPath );
2143 wxFileName filename = aPath;
2148 file.Create( filename.GetFullPath(),
true );
2150 if( !file.IsOpened() )
2153 nlohmann::json tabs_js = nlohmann::json::array();
2164 nlohmann::json commands_js = nlohmann::json::array();
2171 commands_js.push_back(
".kicad adjustpaths" );
2174 commands_js.push_back(
".save all" );
2177 commands_js.push_back(
".probe alli" );
2180 commands_js.push_back(
".probe allp" );
2183 commands_js.push_back(
".kicad esavenone" );
2185 nlohmann::json tab_js = nlohmann::json(
2187 {
"commands", commands_js } } );
2191 nlohmann::json traces_js = nlohmann::json::array();
2193 auto findSignalName =
2194 [&](
const wxString& aVectorName ) -> wxString
2196 wxString vectorName;
2199 if( aVectorName.EndsWith(
_(
" (phase)" ) ) )
2200 suffix =
_(
" (phase)" );
2201 else if( aVectorName.EndsWith(
_(
" (gain)" ) ) )
2202 suffix =
_(
" (gain)" );
2204 vectorName = aVectorName.Left( aVectorName.Length() - suffix.Length() );
2209 return signal + suffix;
2215 for(
const auto& [
name, trace] : plotTab->GetTraces() )
2217 nlohmann::json trace_js = nlohmann::json(
2218 { {
"trace_type", (int) trace->GetType() },
2219 {
"signal", findSignalName( trace->GetDisplayName() ) },
2224 trace_js[
"cursor1"] = nlohmann::json(
2225 { {
"position",
cursor->GetCoords().x },
2232 trace_js[
"cursor2"] = nlohmann::json(
2233 { {
"position",
cursor->GetCoords().x },
2238 if( trace->GetCursor( 1 ) || trace->GetCursor( 2 ) )
2240 trace_js[
"cursorD"] = nlohmann::json(
2245 traces_js.push_back( trace_js );
2248 nlohmann::json measurements_js = nlohmann::json::array();
2250 for(
const auto& [
measurement, format ] : plotTab->Measurements() )
2252 measurements_js.push_back( nlohmann::json( { {
"expr",
measurement },
2253 {
"format", format } } ) );
2256 tab_js[
"traces" ] = traces_js;
2257 tab_js[
"measurements" ] = measurements_js;
2258 tab_js[
"dottedSecondary" ] = plotTab->GetDottedSecondary();
2259 tab_js[
"showGrid" ] = plotTab->IsGridShown();
2263 if( plotTab->GetY1Scale( &min, &max ) )
2264 tab_js[
"fixedY1scale" ] = nlohmann::json( { {
"min", min }, {
"max", max } } );
2266 if( plotTab->GetY2Scale( &min, &max ) )
2267 tab_js[
"fixedY2scale" ] = nlohmann::json( { {
"min", min }, {
"max", max } } );
2269 if( plotTab->GetY3Scale( &min, &max ) )
2270 tab_js[
"fixedY3scale" ] = nlohmann::json( { {
"min", min }, {
"max", max } } );
2272 if( plotTab->IsLegendShown() )
2274 tab_js[
"legend" ] = nlohmann::json( { {
"x", plotTab->GetLegendPosition().x },
2275 {
"y", plotTab->GetLegendPosition().y } } );
2278 mpWindow* plotWin = plotTab->GetPlotWin();
2280 tab_js[
"margins" ] = nlohmann::json( { {
"left", plotWin->
GetMarginLeft() },
2286 tabs_js.push_back( tab_js );
2289 nlohmann::json userDefinedSignals_js = nlohmann::json::array();
2292 userDefinedSignals_js.push_back( signal );
2294 nlohmann::json js = nlohmann::json( { {
"version", 6 },
2295 {
"tabs", tabs_js },
2296 {
"user_defined_signals", userDefinedSignals_js } } );
2307 std::stringstream buffer;
2308 buffer << std::setw( 2 ) << js << std::endl;
2310 bool res = file.Write( buffer.str() );
2317 simulator()->Settings()->SetWorkbookFilename( filename.GetFullPath() );
2335 default: wxFAIL_MSG( wxS(
"Unhandled simulation type" ) );
return SPT_UNKNOWN;
2354 &source, &
scale, &pts, &fStart, &fStop, &saveAll );
2369 for(
size_t page = 0; page <
m_plotNotebook->GetPageCount(); page++ )
2414 std::vector<std::pair<wxString, wxString>>& measurements = plotTab->Measurements();
2416 measurements.clear();
2454 simulator()->Command(
"setplot " + simTab->GetSpicePlotName().ToStdString() );
2468 for(
const auto& [
measurement, format ] : plotTab->Measurements() )
2476 if( plotTab->GetSimType() ==
ST_TRAN || plotTab->GetSimType() ==
ST_AC
2477 || plotTab->GetSimType() ==
ST_DC || plotTab->GetSimType() ==
ST_SP )
2514 CURSOR* cursor1 =
nullptr;
2515 wxString cursor1Name;
2516 wxString cursor1Units;
2517 CURSOR* cursor2 =
nullptr;
2518 wxString cursor2Name;
2519 wxString cursor2Units;
2522 [&](
TRACE* aTrace ) -> wxString
2543 [&](
TRACE* aTrace ) -> wxString
2564 [
this](
double aValue,
int aCursorId,
int aCol ) -> wxString
2577 cursor1Name = getNameY( trace );
2578 cursor1Units = getUnitsY( trace );
2580 wxRealPoint coords =
cursor->GetCoords();
2600 cursor2Name = getNameY( trace );
2601 cursor2Units = getUnitsY( trace );
2603 wxRealPoint coords =
cursor->GetCoords();
2618 if( cursor1 && cursor2 && cursor1Units == cursor2Units )
2627 signal = wxString::Format( wxS(
"%s[2 - 1]" ), cursor2->
GetName() );
2629 signal = wxString::Format( wxS(
"%s - %s" ), cursor2->
GetName(), cursor1->
GetName() );
2641 wxString valColName =
_(
"Value" );
2643 if( !cursor1Name.IsEmpty() )
2645 if( cursor2Name.IsEmpty() || cursor1Name == cursor2Name )
2646 valColName = cursor1Name;
2648 else if( !cursor2Name.IsEmpty() )
2650 valColName = cursor2Name;
2667 plotTab->ResetScales(
true );
2687 std::vector<wxString> signals;
2689 for(
const std::string& vec :
simulator()->AllVectors() )
2690 signals.emplace_back( vec );
2698 std::vector<wxString> signals;
2700 for(
const wxString& signal :
m_signals )
2701 signals.emplace_back( signal );
2704 signals.emplace_back( signal );
2736 if( simType ==
ST_NOISE && aFinal )
2738 m_simConsole->AppendText(
_(
"\n\nSimulation results:\n\n" ) );
2745 simulator()->CurrentPlotName().Mid( 5 ).ToLong( &number );
2747 for(
const std::string& vec :
simulator()->AllVectors() )
2749 std::vector<double> val_list =
simulator()->GetRealVector( vec, 1 );
2752 msg.Printf( wxS(
"%s: %sV\n" ), vec, value );
2758 simulator()->Command( fmt::format(
"setplot noise{}", number - 1 ) );
2763 wxCHECK_RET( plotTab, wxT(
"not a SIM_PLOT_TAB" ) );
2772 std::map<TRACE*, TRACE_INFO> traceMap;
2775 traceMap[ trace ] = { wxEmptyString,
SPT_UNKNOWN,
false };
2780 for(
const wxString& signal :
m_signals )
2785 if(
TRACE* trace = plotTab->
GetTrace( vectorName, traceType ) )
2786 traceMap[ trace ] = { vectorName, traceType,
false };
2794 if( simType ==
ST_AC )
2800 if(
TRACE* trace = plotTab->
GetTrace( vectorName, subType ) )
2801 traceMap[ trace ] = { vectorName, subType, !aFinal };
2804 else if( simType ==
ST_SP )
2810 if(
TRACE* trace = plotTab->
GetTrace( vectorName, subType ) )
2811 traceMap[trace] = { vectorName, subType, !aFinal };
2816 if(
TRACE* trace = plotTab->
GetTrace( vectorName, traceType ) )
2817 traceMap[ trace ] = { vectorName, traceType, !aFinal };
2823 for(
const auto& [ trace, traceInfo ] : traceMap )
2825 if( traceInfo.Vector.IsEmpty() )
2829 for(
const auto& [ trace,
info ] : traceMap )
2831 std::vector<double> data_x;
2833 if( !
info.Vector.IsEmpty() )
2851 else if( simType ==
ST_OP && aFinal )
2853 m_simConsole->AppendText(
_(
"\n\nSimulation results:\n\n" ) );
2856 for(
const std::string& vec :
simulator()->AllVectors() )
2858 std::vector<double> val_list =
simulator()->GetRealVector( vec, 1 );
2860 if( val_list.empty() )
2867 const size_t tab = 25;
2868 size_t padding = ( signal.length() < tab ) ? ( tab - signal.length() ) : 1;
2872 case SPT_VOLTAGE: value.Append( wxS(
"V" ) );
break;
2873 case SPT_CURRENT: value.Append( wxS(
"A" ) );
break;
2874 case SPT_POWER: value.Append( wxS(
"W" ) );
break;
2875 default: value.Append( wxS(
"?" ) );
break;
2878 msg.Printf( wxT(
"%s%s\n" ),
2879 ( signal + wxT(
":" ) ).Pad( padding, wxUniChar(
' ' ) ),
2886 signal = signal.SubString( 2, signal.Length() - 2 );
2889 signal += wxS(
":power" );
2894 else if( simType ==
ST_PZ && aFinal )
2896 m_simConsole->AppendText(
_(
"\n\nSimulation results:\n\n" ) );
void showPopupMenu(wxMenu &menu, wxGridEvent &aEvent) override
void doPopupSelection(wxCommandEvent &event) override
SIMULATOR_FRAME_UI * m_parent
CURSORS_GRID_TRICKS(SIMULATOR_FRAME_UI *aParent, WX_GRID *aGrid)
The SIMULATOR_FRAME holds the main user-interface for running simulations.
const wxRealPoint & GetCoords() const
void SetCoordX(double aValue)
bool Find(const wxString &aTerm, int &aMatchersTriggered, int &aPosition)
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=nullptr) override
Add mouse and command handling (such as cut, copy, and paste) to a WX_GRID instance.
virtual void doPopupSelection(wxCommandEvent &event)
virtual void showPopupMenu(wxMenu &menu, wxGridEvent &aEvent)
WX_GRID * m_grid
I don't own the grid, but he owns me.
A color representation with 4 components: red, green, blue, alpha.
wxString ToCSSString() const
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
Hold a translatable error message and may be used when throwing exceptions containing a translated er...
const wxString What() const
void doPopupSelection(wxCommandEvent &event) override
void showPopupMenu(wxMenu &menu, wxGridEvent &aEvent) override
SIMULATOR_FRAME_UI * m_parent
MEASUREMENTS_GRID_TRICKS(SIMULATOR_FRAME_UI *aParent, WX_GRID *aGrid)
static void ConvertToSpiceMarkup(wxString *aNetName)
Remove formatting wrappers and replace illegal spice net name characters with underscores.
@ OPTION_SAVE_ALL_CURRENTS
@ OPTION_SAVE_ALL_VOLTAGES
@ OPTION_SAVE_ALL_DISSIPATIONS
@ OPTION_ADJUST_INCLUDE_PATHS
@ OPTION_ADJUST_PASSIVE_VALS
const SPICE_ITEM * FindItem(const wxString &aRefName) const
Find and return the item corresponding to aRefName.
A singleton reporter that reports to nowhere.
virtual const wxString GetProjectPath() const
Return the full path of the project.
Holds all the data relating to one schematic.
void SetOperatingPoint(const wxString &aSignal, double aValue)
Set operating points from a .op simulation.
void ClearOperatingPoints()
Clear operating points from a .op simulation.
SCH_DRAW_PANEL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
EESCHEMA_SETTINGS * eeconfig() const
Schematic editor (Eeschema) main window.
void RefreshOperatingPointDisplay()
Refresh the display of any operaintg points.
void OnModify() override
Must be called after a schematic change in order to set the "modify" flag and update other data struc...
SCHEMATIC & Schematic() const
void UpdateItem(EDA_ITEM *aItem, bool isAddOrDelete=false, bool aUpdateRtree=false) override
Mark an item for refresh.
Base class for any item which can be embedded within the SCHEMATIC container class,...
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
SCH_ITEM * GetItem(const KIID &aID) const
Fetch a SCH_ITEM by ID.
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly)
Populate a std::vector with SCH_FIELDs.
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const override
void doPopupSelection(wxCommandEvent &event) override
void showPopupMenu(wxMenu &menu, wxGridEvent &aEvent) override
SIMULATOR_FRAME_UI * m_parent
SIGNALS_GRID_TRICKS(SIMULATOR_FRAME_UI *aParent, WX_GRID *aGrid)
Class SIMULATOR_FRAME_UI_BASE.
wxBoxSizer * m_sizerTuners
WX_GRID * m_measurementsGrid
wxSplitterWindow * m_splitterLeftRight
wxSplitterWindow * m_splitterMeasurements
wxTextCtrl * m_simConsole
wxSplitterWindow * m_splitterCursors
wxSplitterWindow * m_splitterPlotAndConsole
wxSplitterWindow * m_splitterSignals
wxAuiNotebook * m_plotNotebook
The SIMULATOR_FRAME_UI holds the main user-interface for running simulations.
SIM_TAB * NewSimTab(const wxString &aSimCommand)
Create a new simulation tab for a given simulation type.
void SetUserDefinedSignals(const std::map< int, wxString > &aSignals)
void updatePlotCursors()
Update the cursor values (in the grid) and graphics (in the plot window).
void OnSimRefresh(bool aFinal)
void onPlotClose(wxAuiNotebookEvent &event) override
int m_splitterTuneValuesSashPosition
void onPlotChanged(wxAuiNotebookEvent &event) override
void rebuildSignalsGrid(wxString aFilter)
Rebuild the filtered list of signals in the signals grid.
void DoFourier(const wxString &aSignal, const wxString &aFundamental)
void rebuildMeasurementsGrid()
Rebuild the measurements grid for the current plot.
std::list< TUNER_SLIDER * > m_tuners
SPICE expressions need quoted versions of the netnames since KiCad allows '-' and '/' in netnames.
void rebuildSignalsList()
Rebuild the list of signals available from the netlist.
bool loadLegacyWorkbook(const wxString &aPath)
int m_splitterCursorsSashPosition
void UpdateMeasurement(int aRow)
Update a measurement in the measurements grid.
wxString getNoiseSource() const
std::vector< wxString > SimPlotVectors() const
unsigned int m_plotNumber
void SetSubWindowsSashSize()
void applyUserDefinedSignals()
Apply user-defined signals to the SPICE session.
std::map< wxString, wxString > m_quotedNetnames
SIM_PREFERENCES m_preferences
void DeleteMeasurement(int aRow)
Delete a row from the measurements grid.
SCH_EDIT_FRAME * m_schematicFrame
wxString vectorNameFromSignalName(SIM_PLOT_TAB *aPlotTab, const wxString &aSignalName, int *aTraceType)
Get the simulator output vector name for a given signal name and type.
void updateSignalsGrid()
Update the values in the signals grid.
int m_splitterLeftRightSashPosition
void onCursorsGridCellChanged(wxGridEvent &aEvent) override
void onPlotDragged(wxAuiNotebookEvent &event) override
std::vector< wxString > Signals() const
bool SaveWorkbook(const wxString &aPath)
Save plot, signal, cursor, measurement, etc.
std::vector< wxString > m_signals
SIM_TAB * GetCurrentSimTab() const
Return the currently opened plot panel (or NULL if there is none).
void updateMeasurementsFromGrid()
bool LoadWorkbook(const wxString &aPath)
Load plot, signal, cursor, measurement, etc.
SPICE_VALUE_FORMAT GetMeasureFormat(int aRow) const
Get/Set the format of a value in the measurements grid.
std::map< int, wxString > m_userDefinedSignals
void UpdateTunerValue(const SCH_SHEET_PATH &aSheetPath, const KIID &aSymbol, const wxString &aRef, const wxString &aValue)
Safely update a field of the associated symbol without dereferencing the symbol.
void AddTrace(const wxString &aName, SIM_TRACE_TYPE aType)
Add a new trace to the current plot.
void onPlotClosed(wxAuiNotebookEvent &event) override
void RemoveTuner(TUNER_SLIDER *aTuner)
Remove an existing tuner.
void SaveSettings(EESCHEMA_SETTINGS *aCfg)
std::shared_ptr< SPICE_CIRCUIT_MODEL > circuitModel() const
void OnFilterText(wxCommandEvent &aEvent) override
void onMeasurementsGridCellChanged(wxGridEvent &aEvent) override
void applyTuners()
Apply component values specified using tuner sliders to the current netlist.
bool loadJsonWorkbook(const wxString &aPath)
void OnFilterMouseMoved(wxMouseEvent &aEvent) override
void AddMeasurement(const wxString &aCmd)
Add a measurement to the measurements grid.
void onPlotChanging(wxAuiNotebookEvent &event) override
std::shared_ptr< SPICE_SIMULATOR > simulator() const
void onPlotCursorUpdate(wxCommandEvent &aEvent)
void onSignalsGridCellChanged(wxGridEvent &aEvent) override
void SetCursorFormat(int aCursorId, int aValueCol, const SPICE_VALUE_FORMAT &aFormat)
void InitWorkbook()
Load the currently active workbook stored in the project settings.
void ToggleDarkModePlots()
SIM_TRACE_TYPE getXAxisType(SIM_TYPE aType) const
Return X axis for a given simulation type.
void OnPlotSettingsChanged()
void SetMeasureFormat(int aRow, const SPICE_VALUE_FORMAT &aFormat)
int m_splitterSignalsSashPosition
void OnSimReport(const wxString &aMsg)
void ApplyPreferences(const SIM_PREFERENCES &aPrefs)
Called when settings are changed via the common Preferences dialog.
const SPICE_CIRCUIT_MODEL * GetExporter() const
Return the netlist exporter object used for simulations.
int m_splitterPlotAndConsoleSashPosition
SIMULATOR_FRAME * m_simulatorFrame
void ShowChangedLanguage()
void AddTuner(const SCH_SHEET_PATH &aSheetPath, SCH_SYMBOL *aSymbol)
Add a tuner for a symbol.
SPICE_VALUE_FORMAT GetCursorFormat(int aCursorId, int aValueCol) const
Get/Set the number of significant digits and the range for formatting a cursor value.
void OnUpdateUI(wxUpdateUIEvent &event) override
void updateTrace(const wxString &aVectorName, int aTraceType, SIM_PLOT_TAB *aPlotTab, std::vector< double > *aDataX=nullptr, bool aClearData=false)
Update a trace in a particular SIM_PLOT_TAB.
SIMULATOR_FRAME_UI(SIMULATOR_FRAME *aSimulatorFrame, SCH_EDIT_FRAME *aSchematicFrame)
SPICE_VALUE_FORMAT m_cursorFormats[3][2]
void LoadSettings(EESCHEMA_SETTINGS *aCfg)
The SIMULATOR_FRAME holds the main user-interface for running simulations.
bool LoadSimulator(const wxString &aSimCommand, unsigned aSimOptions)
Check and load the current netlist into the simulator.
std::shared_ptr< SPICE_CIRCUIT_MODEL > GetCircuitModel() const
SIM_TYPE GetCurrentSimType() const
void OnModify() override
Must be called after a model change in order to set the "modify" flag and do other frame-specific pro...
int GetCurrentOptions() const
std::shared_ptr< SPICE_SIMULATOR > GetSimulator() const
SIM_MODEL & CreateModel(SIM_MODEL::TYPE aType, const std::vector< SCH_PIN * > &aPins, REPORTER &aReporter)
virtual const PARAM * GetTunerParam() const
const SPICE_GENERATOR & SpiceGenerator() const
void WriteFields(std::vector< SCH_FIELD > &aFields) const
void SetParamValue(int aParamIndex, const std::string &aValue, SIM_VALUE::NOTATION aNotation=SIM_VALUE::NOTATION::SI)
static void FillDefaultColorList(bool aWhiteBg)
Fills m_colorList by a default set of colors.
bool DeleteTrace(const wxString &aVectorName, int aTraceType)
void EnableCursor(const wxString &aVectorName, int aType, int aCursorId, bool aEnable, const wxString &aSignalName)
Reset scale ranges to fit the current traces.
wxString GetLabelY1() const
mpWindow * GetPlotWin() const
void ShowGrid(bool aEnable)
wxString GetUnitsY2() const
void SetY2Scale(bool aLock, double aMin, double aMax)
TRACE * GetTrace(const wxString &aVecName, int aType) const
wxString GetLabelX() const
const std::map< wxString, TRACE * > & GetTraces() const
wxString GetLabelY3() const
void SetY1Scale(bool aLock, double aMin, double aMax)
void SetY3Scale(bool aLock, double aMin, double aMax)
std::vector< std::pair< wxString, wxString > > & Measurements()
void UpdateTraceStyle(TRACE *trace)
Update plot colors.
void SetLegendPosition(const wxPoint &aPosition)
void ResetScales(bool aIncludeX)
Update trace line style.
void ShowLegend(bool aEnable)
wxString GetLabelY2() const
void SetTraceData(TRACE *aTrace, std::vector< double > &aX, std::vector< double > &aY, int aSweepCount, size_t aSweepSize)
wxString GetUnitsX() const
void EnsureThirdYAxisExists()
TRACE * GetOrAddTrace(const wxString &aVectorName, int aType)
void SetDottedSecondary(bool aEnable)
Draw secondary signal traces (current or phase) with dotted lines.
void ApplyPreferences(const SIM_PREFERENCES &aPrefs) override
wxString GetUnitsY1() const
wxString GetUnitsY3() const
int GetSimOptions() const
SIM_TYPE GetSimType() const
const wxString & GetSimCommand() const
static bool IsPlottable(SIM_TYPE aSimType)
void SetSimOptions(int aOptions)
wxString GetLastSchTextSimCommand() const
void SetSpicePlotName(const wxString &aPlotName)
static std::string ToSpice(const std::string &aString)
Special netlist exporter flavor that allows one to override simulation commands.
static SIM_TYPE CommandToSimType(const wxString &aCmd)
Return simulation type basing on a simulation command directive.
virtual std::string TunerCommand(const SPICE_ITEM &aItem, double aValue) const
static wxString TypeToName(SIM_TYPE aType, bool aShortName)
Return a string with simulation name based on enum.
Helper class to recognize Spice formatted values.
wxString ToString() const
Return string value as when converting double to string (e.g.
wxString ToSpiceString() const
Return string value in Spice format (e.g.
~SUPPRESS_GRID_CELL_EVENTS()
SUPPRESS_GRID_CELL_EVENTS(SIMULATOR_FRAME_UI *aFrame)
SIMULATOR_FRAME_UI * m_frame
void SetTraceColour(const wxColour &aColour)
Custom widget to handle quick component values modification and simulation on the fly.
void ClearRows()
wxWidgets recently added an ASSERT which fires if the position is greater than or equal to the number...
A wrapper for reporting to a wxString object.
bool HasMessage() const override
Returns true if the reporter client is non-empty.
REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED) override
Report a string with a given severity.
A KICAD version of wxTextEntryDialog which supports the various improvements/work-arounds from DIALOG...
wxString GetValue() const
const wxString & GetName() const
Get layer name.
const wxPen & GetPen() const
Get pen set for this layer.
Canvas for plotting mpLayer implementations.
int GetMarginLeft() const
void SetMargins(int top, int right, int bottom, int left)
Set window margins, creating a blank area where some kinds of layers cannot draw.
void UpdateAll()
Refresh display.
int GetMarginRight() const
int GetMarginBottom() const
bool AddLayer(mpLayer *layer, bool refreshDisplay=true)
Add a plot layer to the canvas.
void Fit() override
Set view to fit global bounding box of all plot layers and refresh display.
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
This file is part of the common library.
Abstract pattern-matching tool and implementations.
@ GRIDTRICKS_FIRST_CLIENT_ID
static const std::string WorkbookFileExtension
KICOMMON_API wxFont GetStatusFont(wxWindow *aWindow)
SIM_TYPE
< Possible simulation types
void sortSignals(std::vector< wxString > &signals)
wxString vectorNameFromSignalId(int aUserDefinedSignalId)
MEASUREMENTS_GIRD_COLUMNS
SIM_TRACE_TYPE operator|(SIM_TRACE_TYPE aFirst, SIM_TRACE_TYPE aSecond)
@ MYID_DELETE_MEASUREMENT
std::vector< FAB_LAYER_COLOR > dummy
wxString UnescapeString(const wxString &aSource)
int measurements_panel_height
SIM_PREFERENCES preferences
Contains preferences pertaining to the simulator.
constexpr ret_type KiROUND(fp_type v, bool aQuiet=false)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition of file extensions used in Kicad.