29#include <fmt/format.h>
30#include <wx/wfstream.h>
31#include <wx/stdstream.h>
53#include "wx/clipbrd.h"
58 int res = (int) aFirst | (
int) aSecond;
119 void showPopupMenu( wxMenu& menu, wxGridEvent& aEvent )
override;
143 if( panel->GetSimType() ==
ST_TRAN || panel->GetSimType() ==
ST_AC
144 || panel->GetSimType() ==
ST_DC || panel->GetSimType() ==
ST_SP )
152 if( panel->GetSimType() ==
ST_AC || panel->GetSimType() ==
ST_SP )
165 if( panel->GetSimType() ==
ST_TRAN )
167 menu.AppendSeparator();
168 menu.Append(
MYID_FOURIER,
_(
"Perform Fourier Analysis..." ) );
171 menu.AppendSeparator();
174 m_grid->PopupMenu( &menu );
183 std::vector<wxString> signals;
185 wxGridCellCoordsArray cells1 =
m_grid->GetSelectionBlockTopLeft();
186 wxGridCellCoordsArray cells2 =
m_grid->GetSelectionBlockBottomRight();
188 for(
size_t i = 0; i < cells1.Count(); i++ )
192 for(
int j = cells1[i].GetRow(); j < cells2[i].GetRow() + 1; j++ )
194 signals.push_back(
m_grid->GetCellValue( j, cells1[i].GetCol() ) );
199 wxGridCellCoordsArray cells3 =
m_grid->GetSelectedCells();
201 for(
size_t i = 0; i < cells3.Count(); i++ )
204 signals.push_back(
m_grid->GetCellValue( cells3[i].GetRow(), cells3[i].GetCol() ) );
207 if( signals.size() < 1 )
210 auto addMeasurement =
211 [
this](
const wxString& cmd, wxString signal )
213 if( signal.EndsWith(
_(
" (phase)" ) ) )
216 if( signal.EndsWith(
_(
" (gain)" ) ) || signal.EndsWith(
_(
" (amplitude)" ) ) )
218 signal = signal.Left( signal.length() - 7 );
220 if( signal.Upper().StartsWith( wxS(
"V(" ) ) )
221 signal = wxS(
"vdb" ) + signal.Mid( 1 );
229 for(
const wxString& signal : signals )
230 addMeasurement( wxS(
"MIN" ), signal );
234 for(
const wxString& signal : signals )
235 addMeasurement( wxS(
"MAX" ), signal );
239 for(
const wxString& signal : signals )
240 addMeasurement( wxS(
"AVG" ), signal );
244 for(
const wxString& signal : signals )
245 addMeasurement( wxS(
"RMS" ), signal );
249 for(
const wxString& signal : signals )
250 addMeasurement( wxS(
"PP" ), signal );
254 for(
const wxString& signal : signals )
255 addMeasurement( wxS(
"MIN_AT" ), signal );
259 for(
const wxString& signal : signals )
260 addMeasurement( wxS(
"MAX_AT" ), signal );
264 for(
const wxString& signal : signals )
265 addMeasurement( wxS(
"INTEG" ), signal );
270 wxString fundamental = wxT(
"1K" );
272 if( signals.size() == 1 )
273 title.Printf(
_(
"Fourier Analysis of %s" ), signals[0] );
275 title =
_(
"Fourier Analyses of Multiple Signals" );
279 if( dlg.ShowModal() != wxID_OK )
285 for(
const wxString& signal : signals )
293 for(
const wxString& signal : signals )
301 if( wxTheClipboard->Open() )
303 wxTheClipboard->SetData(
new wxTextDataObject( txt ) );
304 wxTheClipboard->Flush();
305 wxTheClipboard->Close();
322 void showPopupMenu( wxMenu& menu, wxGridEvent& aEvent )
override;
342 menu.AppendSeparator();
352 [
this](
int row ) -> wxString
356 if( signal.EndsWith(
"[2 - 1]" ) )
357 signal = signal.Left( signal.length() - 7 );
368 if( formatDialog.ShowModal() == wxID_OK )
370 for(
int row = 0; row <
m_grid->GetNumberRows(); ++row )
372 if( getSignalName( row ) == getSignalName(
m_menuRow ) )
395 void showPopupMenu( wxMenu& menu, wxGridEvent& aEvent )
override;
421 menu.AppendSeparator();
434 if( formatDialog.ShowModal() == wxID_OK )
443 std::vector<int> measurements;
445 wxGridCellCoordsArray cells1 =
m_grid->GetSelectionBlockTopLeft();
446 wxGridCellCoordsArray cells2 =
m_grid->GetSelectionBlockBottomRight();
448 for(
size_t i = 0; i < cells1.Count(); i++ )
452 for(
int j = cells1[i].GetRow(); j < cells2[i].GetRow() + 1; j++ )
453 measurements.push_back( j );
457 wxGridCellCoordsArray cells3 =
m_grid->GetSelectedCells();
459 for(
size_t i = 0; i < cells3.Count(); i++ )
462 measurements.push_back( cells3[i].GetRow() );
465 if( measurements.size() < 1 )
470 sort( measurements.begin(), measurements.end(), std::greater<>() );
472 for(
int row : measurements )
505#define ID_SIM_REFRESH 10207
506#define REFRESH_INTERVAL 50
512 m_SuppressGridEvents( 0 ),
513 m_simulatorFrame( aSimulatorFrame ),
514 m_schematicFrame( aSchematicFrame ),
532 wxGridCellAttr* attr =
new wxGridCellAttr;
536 attr =
new wxGridCellAttr;
540 attr =
new wxGridCellAttr;
544 attr =
new wxGridCellAttr;
548 for(
int cursorId = 0; cursorId < 3; ++cursorId )
554 attr =
new wxGridCellAttr;
564 [&]( wxTimerEvent& aEvent )
573#ifndef wxHAS_NATIVE_TABART
591 for(
int ii = 0; ii < (int)
m_plotNotebook->GetPageCount(); ++ii )
600 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)" ) );
886 for(
const std::string& net :
circuitModel()->GetNets() )
891 if( netname ==
"GND" || netname ==
"0" || netname.StartsWith( unconnected ) )
895 addSignal( wxString::Format( wxS(
"V(%s)" ), netname ) );
905 for(
const std::string&
name : item.model->SpiceGenerator().CurrentNames( item ) )
915 if( item.model->GetPinCount() >= 2 )
917 wxString
name = item.model->SpiceGenerator().ItemName( item );
918 addSignal( wxString::Format( wxS(
"P(%s)" ),
name ) );
925 addSignal( wxS(
"inoise_spectrum" ) );
926 addSignal( wxS(
"onoise_spectrum" ) );
929 if( simType ==
ST_SP )
931 std::vector<std::string> portnums;
935 wxString
name = item.model->SpiceGenerator().ItemName( item );
938 if( !
name.StartsWith(
"V" ) )
941 std::string portnum =
"";
943 if(
const SIM_MODEL::PARAM* portnum_param = item.model->FindParam(
"portnum" ) )
947 portnums.push_back( portnum );
950 for(
const std::string& portnum1 : portnums )
952 for(
const std::string& portnum2 : portnums )
954 addSignal( wxString::Format( wxS(
"S_%s_%s" ), portnum1, portnum2 ) );
960 for(
const wxString& directive :
circuitModel()->GetDirectives() )
962 wxStringTokenizer tokenizer( directive, wxT(
"\r\n" ), wxTOKEN_STRTOK );
964 while( tokenizer.HasMoreTokens() )
966 wxString line = tokenizer.GetNextToken();
967 wxString directiveParams;
969 if( line.Upper().StartsWith( wxS(
".PROBE" ), &directiveParams ) )
970 addSignal( directiveParams.Trim(
true ).Trim(
false ) );
992 wxString pageTitle(
simulator()->TypeToName( simType,
true ) );
993 pageTitle.Prepend( wxString::Format(
_(
"Analysis %u - " ), (
unsigned int) ++
m_plotNumber ) );
1009 wxPoint pos = aEvent.GetPosition();
1010 wxRect ctrlRect =
m_filter->GetScreenRect();
1011 int buttonWidth = ctrlRect.GetHeight();
1013 if(
m_filter->IsSearchButtonVisible() && pos.x < buttonWidth )
1014 SetCursor( wxCURSOR_ARROW );
1015 else if(
m_filter->IsCancelButtonVisible() && pos.x > ctrlRect.GetWidth() - buttonWidth )
1016 SetCursor( wxCURSOR_ARROW );
1018 SetCursor( wxCURSOR_IBEAM );
1024 return wxString::Format( wxS(
"user%d" ), aUserDefinedSignalId );
1033 const wxString& aSignalName,
1036 std::map<wxString, int> suffixes;
1052 wxUniChar firstChar = aSignalName.Upper()[0];
1054 if( firstChar ==
'V' )
1056 else if( firstChar ==
'I' )
1058 else if( firstChar ==
'P' )
1064 wxString
name = aSignalName;
1066 for(
const auto& [ candidate, type ] : suffixes )
1068 if(
name.EndsWith( candidate ) )
1070 name =
name.Left(
name.Length() - candidate.Length() );
1073 *aTraceType |= type;
1081 if(
name == signal )
1099 int row = aEvent.GetRow();
1100 int col = aEvent.GetCol();
1108 if(
text == wxS(
"1" ) )
1135 for(
int ii = 0; ii <
m_signalsGrid->GetNumberRows(); ++ii )
1141 bool enable = ii == row &&
text == wxS(
"1" );
1143 plotTab->
EnableCursor( vectorName, traceType,
id, enable, signalName );
1163 int row = aEvent.GetRow();
1164 int col = aEvent.GetCol();
1170 CURSOR* cursor1 =
nullptr;
1171 CURSOR* cursor2 =
nullptr;
1184 if( cursorName == wxS(
"1" ) && cursor1 )
1186 else if( cursorName == wxS(
"2" ) && cursor2 )
1188 else if( cursorName ==
_(
"Diff" ) && cursor1 && cursor2 )
1196 wxFAIL_MSG( wxT(
"All other columns are supposed to be read-only!" ) );
1229 int row = aEvent.GetRow();
1230 int col = aEvent.GetCol();
1240 wxFAIL_MSG( wxT(
"All other columns are supposed to be read-only!" ) );
1248 for( row = rowCount - 1; row >= 0; row-- )
1258 int killRows = emptyRows - 1;
1261 else if( emptyRows == 0 )
1272 if( plotTab->GetLegendPosition() != plotTab->m_LastLegendPosition )
1274 plotTab->m_LastLegendPosition = plotTab->GetLegendPosition();
1297 static wxRegEx measureParamsRegEx( wxT(
"^"
1301 "([a-zA-Z]*)\\(([^\\)]+)\\)" ) );
1310 if(
text.IsEmpty() )
1317 wxString resultName = wxString::Format( wxS(
"meas_result_%u" ), aRow );
1318 wxString result = wxS(
"?" );
1320 if( measureParamsRegEx.Matches(
text ) )
1322 wxString func = measureParamsRegEx.GetMatch(
text, 1 ).Upper();
1323 wxString signalType = measureParamsRegEx.GetMatch(
text, 2 ).Upper();
1324 wxString deviceName = measureParamsRegEx.GetMatch(
text, 3 );
1328 if( signalType.EndsWith( wxS(
"DB" ) ) )
1330 units = wxS(
"dB" );
1332 else if( signalType.StartsWith(
'I' ) )
1336 else if( signalType.StartsWith(
'P' ) )
1340 text = func +
" " + deviceName +
":power";
1347 if( func.EndsWith( wxS(
"_AT" ) ) )
1350 units = wxS(
"Hz" );
1354 else if( func.StartsWith( wxS(
"INTEG" ) ) )
1359 if ( signalType.StartsWith(
'P' ) )
1362 units += wxS(
".s" );
1372 units += wxS(
"·Hz" );
1380 units += wxS(
"·?" );
1391 wxString cmd = wxString::Format( wxS(
"meas %s %s %s" ), simType, resultName,
text );
1392 simulator()->Command(
"echo " + cmd.ToStdString() );
1393 simulator()->Command( cmd.ToStdString() );
1395 std::vector<double> resultVec =
simulator()->GetGainVector( resultName.ToStdString() );
1397 if( resultVec.size() > 0 )
1412 wxString ref = aSymbol->
GetRef( &aSheetPath );
1417 if( tuner->GetSymbolRef() == ref )
1443 const wxString& aRef,
const wxString& aValue )
1451 + wxString::Format(
_(
"%s not found" ), aRef ) );
1464 + wxString::Format(
_(
"%s is not tunable" ), aRef ) );
1530 wxString cmd = wxString::Format( wxS(
"fourier %s %s" ),
1534 simulator()->Command( cmd.ToStdString() );
1548 m_simConsole->AppendText(
_(
"Error: no current simulation.\n" ) );
1557 m_simConsole->AppendText(
_(
"Error: simulation type not defined.\n" ) );
1563 m_simConsole->AppendText(
_(
"Error: simulation type doesn't support plotting.\n" ) );
1569 wxCHECK( plotTab, );
1571 if( simType ==
ST_AC )
1576 else if( simType ==
ST_SP )
1607 if( aNewSignals.count(
id ) == 0 )
1612 plotTab->
DeleteTrace( vectorName, traceType | subType );
1617 plotTab->
DeleteTrace( vectorName, traceType | subType );
1630 if(
TRACE* trace = plotTab->
GetTrace( vectorName, traceType | subType ) )
1631 trace->SetName( aNewSignals.at(
id ) );
1638 if(
TRACE* trace = plotTab->
GetTrace( vectorName, traceType | subType ) )
1639 trace->SetName( aNewSignals.at(
id ) );
1644 if(
TRACE* trace = plotTab->
GetTrace( vectorName, traceType ) )
1645 trace->SetName( aNewSignals.at(
id ) );
1673 wxString simVectorName = aVectorName;
1676 simVectorName = simVectorName.AfterFirst(
'(' ).BeforeLast(
')' ) + wxS(
":power" );
1681 simulator()->Command( wxString::Format( wxT(
"print %s" ), aVectorName ).ToStdString() );
1686 std::vector<double> data_x;
1687 std::vector<double> data_y;
1689 if( !aDataX || aClearData )
1693 if( aDataX->empty() && !aClearData )
1695 wxString xAxisName(
simulator()->GetXAxis( simType ) );
1697 if( xAxisName.IsEmpty() )
1700 *aDataX =
simulator()->GetGainVector( (
const char*) xAxisName.c_str() );
1703 unsigned int size = aDataX->size();
1709 data_y =
simulator()->GetGainVector( (
const char*) simVectorName.c_str(), size );
1711 data_y =
simulator()->GetPhaseVector( (
const char*) simVectorName.c_str(), size );
1713 wxFAIL_MSG( wxT(
"Plot type missing AC_PHASE or AC_MAG bit" ) );
1718 data_y =
simulator()->GetGainVector( (
const char*) simVectorName.c_str(), size );
1720 data_y =
simulator()->GetPhaseVector( (
const char*) simVectorName.c_str(), size );
1722 wxFAIL_MSG( wxT(
"Plot type missing AC_PHASE or SPT_SP_AMP bit" ) );
1727 data_y =
simulator()->GetGainVector( (
const char*) simVectorName.c_str(), -1 );
1733 data_y =
simulator()->GetGainVector( (
const char*) simVectorName.c_str(), size );
1737 wxFAIL_MSG( wxT(
"Unhandled plot type" ) );
1744 if( simType ==
ST_DC
1752 size_t outer = ( size_t )( ( source2.
m_vend - v ) / source2.
m_vincrement ).ToDouble();
1753 size_t inner = aDataX->size() / ( outer + 1 );
1755 wxASSERT( aDataX->size() % ( outer + 1 ) == 0 );
1757 for(
size_t idx = 0; idx <= outer; idx++ )
1761 if( data_y.size() >= size )
1763 std::vector<double> sub_x( aDataX->begin() + offset,
1764 aDataX->begin() + offset + inner );
1765 std::vector<double> sub_y( data_y.begin() + offset,
1766 data_y.begin() + offset + inner );
1778 if( data_y.size() >= size )
1788 for(
int row = 0; row <
m_signalsGrid->GetNumberRows(); ++row )
1794 if(
TRACE* trace = plotTab ? plotTab->
GetTrace( vectorName, traceType ) :
nullptr )
1798 wxGridCellAttr* attr =
new wxGridCellAttr;
1801 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
1807 attr =
new wxGridCellAttr;
1808 attr->SetRenderer(
new wxGridCellBoolRenderer() );
1809 attr->SetReadOnly();
1810 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
1813 attr =
new wxGridCellAttr;
1814 attr->SetRenderer(
new wxGridCellBoolRenderer() );
1815 attr->SetReadOnly();
1816 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
1819 if( trace->HasCursor( 1 ) )
1824 if( trace->HasCursor( 2 ) )
1833 wxGridCellAttr* attr =
new wxGridCellAttr;
1834 attr->SetReadOnly();
1838 attr =
new wxGridCellAttr;
1839 attr->SetReadOnly();
1843 attr =
new wxGridCellAttr;
1844 attr->SetReadOnly();
1854 auto quoteNetNames =
1855 [&]( wxString aExpression ) -> wxString
1858 aExpression.Replace( netname, quotedNetname );
1865 constexpr const char* cmd =
"let user{} = {}";
1867 simulator()->Command(
"echo " + fmt::format( cmd,
id, signal.ToStdString() ) );
1868 simulator()->Command( fmt::format( cmd,
id, quoteNetNames( signal ).ToStdString() ) );
1881 wxString ref = tuner->GetSymbolRef();
1882 KIID symbolId = tuner->GetSymbol( &sheetPath );
1888 reporter.
Report( wxString::Format(
_(
"%s not found" ), ref ) );
1896 reporter.
Report( wxString::Format(
_(
"%s is not tunable" ), ref ) );
1900 double floatVal = tuner->GetValue().ToDouble();
1912 wxTextFile file( aPath );
1917 wxString firstLine = file.GetFirstLine();
1919 bool legacy = firstLine.StartsWith( wxT(
"version " ) ) || firstLine.ToLong( &
dummy );
1944 wxFileName filename( aPath );
1948 simulator()->Settings()->SetWorkbookFilename( filename.GetFullPath() );
1956 wxFFileInputStream fp( aPath, wxT(
"rt" ) );
1957 wxStdInputStream fstream( fp );
1964 nlohmann::json js = nlohmann::json::parse( fstream,
nullptr,
true,
true );
1966 std::map<SIM_PLOT_TAB*, nlohmann::json> traceInfo;
1968 for(
const nlohmann::json& tab_js : js[
"tabs" ] )
1970 wxString simCommand;
1973 for(
const nlohmann::json& cmd : tab_js[
"commands" ] )
1975 if( cmd ==
".kicad adjustpaths" )
1977 else if( cmd ==
".save all" )
1979 else if( cmd ==
".probe alli" )
1981 else if( cmd ==
".probe allp" )
1984 simCommand += wxString( cmd.get<wxString>() ).Trim();
1994 if( tab_js.contains(
"traces" ) )
1995 traceInfo[plotTab] = tab_js[
"traces" ];
1997 if( tab_js.contains(
"measurements" ) )
1999 for(
const nlohmann::json& m_js : tab_js[
"measurements" ] )
2000 plotTab->
Measurements().emplace_back( m_js[
"expr" ], m_js[
"format" ] );
2004 plotTab->
ShowGrid( tab_js[
"showGrid" ] );
2006 if( tab_js.contains(
"fixedY1scale" ) )
2008 const nlohmann::json& scale_js = tab_js[
"fixedY1scale" ];
2009 plotTab->
SetY1Scale(
true, scale_js[
"min" ], scale_js[
"max" ] );
2013 if( tab_js.contains(
"fixedY2scale" ) )
2015 const nlohmann::json& scale_js = tab_js[
"fixedY2scale" ];
2016 plotTab->
SetY2Scale(
true, scale_js[
"min" ], scale_js[
"max" ] );
2020 if( tab_js.contains(
"fixedY3scale" ) )
2023 const nlohmann::json& scale_js = tab_js[
"fixedY3scale" ];
2024 plotTab->
SetY3Scale(
true, scale_js[
"min" ], scale_js[
"max" ] );
2028 if( tab_js.contains(
"legend" ) )
2030 const nlohmann::json& legend_js = tab_js[
"legend" ];
2035 if( tab_js.contains(
"margins" ) )
2037 const nlohmann::json& margins_js = tab_js[
"margins" ];
2039 margins_js[
"right" ],
2040 margins_js[
"bottom" ],
2041 margins_js[
"left" ] );
2048 if( js.contains(
"user_defined_signals" ) )
2050 for(
const nlohmann::json& signal_js : js[
"user_defined_signals" ] )
2056 int aCursorId,
const nlohmann::json& aCursor_js )
2058 if( aCursorId == 1 || aCursorId == 2 )
2062 cursor->SetName( aSignalName );
2063 cursor->SetPen( wxPen( aTrace->GetTraceColour() ) );
2064 cursor->SetCoordX( aCursor_js[
"position" ] );
2066 aTrace->SetCursor( aCursorId,
cursor );
2074 for(
const auto& [ plotTab, traces_js ] : traceInfo )
2076 for(
const nlohmann::json& trace_js : traces_js )
2078 wxString signalName = trace_js[
"signal" ];
2080 TRACE* trace = plotTab->GetOrAddTrace( vectorName, trace_js[
"trace_type" ] );
2084 if( trace_js.contains(
"cursor1" ) )
2085 addCursor( plotTab, trace, signalName, 1, trace_js[
"cursor1" ] );
2087 if( trace_js.contains(
"cursor2" ) )
2088 addCursor( plotTab, trace, signalName, 2, trace_js[
"cursor2" ] );
2090 if( trace_js.contains(
"cursorD" ) )
2091 addCursor( plotTab, trace, signalName, 3, trace_js[
"cursorD" ] );
2093 if( trace_js.contains(
"color" ) )
2096 color.Set( wxString( trace_js[
"color"].get<wxString>() ) );
2098 plotTab->UpdateTraceStyle( trace );
2103 plotTab->UpdatePlotColors();
2112 wxCHECK( simTab,
false );
2114 simTab->SetLastSchTextSimCommand( js[
"last_sch_text_sim_command" ] );
2117 catch( nlohmann::json::parse_error& error )
2119 wxLogTrace(
traceSettings, wxT(
"Json parse error reading %s: %s" ), aPath, error.what() );
2132 wxFileName filename = aPath;
2137 file.Create( filename.GetFullPath(),
true );
2139 if( !file.IsOpened() )
2142 nlohmann::json tabs_js = nlohmann::json::array();
2153 nlohmann::json commands_js = nlohmann::json::array();
2160 commands_js.push_back(
".kicad adjustpaths" );
2163 commands_js.push_back(
".save all" );
2166 commands_js.push_back(
".probe alli" );
2169 commands_js.push_back(
".probe allp" );
2171 nlohmann::json tab_js = nlohmann::json(
2173 {
"commands", commands_js } } );
2177 nlohmann::json traces_js = nlohmann::json::array();
2179 auto findSignalName =
2180 [&](
const wxString& aVectorName ) -> wxString
2191 for(
const auto& [
name, trace] : plotTab->GetTraces() )
2193 nlohmann::json trace_js = nlohmann::json(
2194 { {
"trace_type", (int) trace->GetType() },
2195 {
"signal", findSignalName( trace->GetName() ) },
2200 trace_js[
"cursor1"] = nlohmann::json(
2201 { {
"position",
cursor->GetCoords().x },
2208 trace_js[
"cursor2"] = nlohmann::json(
2209 { {
"position",
cursor->GetCoords().x },
2214 if( trace->GetCursor( 1 ) || trace->GetCursor( 2 ) )
2216 trace_js[
"cursorD"] = nlohmann::json(
2221 traces_js.push_back( trace_js );
2224 nlohmann::json measurements_js = nlohmann::json::array();
2226 for(
const auto& [
measurement, format ] : plotTab->Measurements() )
2228 measurements_js.push_back( nlohmann::json( { {
"expr",
measurement },
2229 {
"format", format } } ) );
2232 tab_js[
"traces" ] = traces_js;
2233 tab_js[
"measurements" ] = measurements_js;
2234 tab_js[
"dottedSecondary" ] = plotTab->GetDottedSecondary();
2235 tab_js[
"showGrid" ] = plotTab->IsGridShown();
2239 if( plotTab->GetY1Scale( &min, &max ) )
2240 tab_js[
"fixedY1scale" ] = nlohmann::json( { {
"min", min }, {
"max", max } } );
2242 if( plotTab->GetY2Scale( &min, &max ) )
2243 tab_js[
"fixedY2scale" ] = nlohmann::json( { {
"min", min }, {
"max", max } } );
2245 if( plotTab->GetY3Scale( &min, &max ) )
2246 tab_js[
"fixedY3scale" ] = nlohmann::json( { {
"min", min }, {
"max", max } } );
2248 if( plotTab->IsLegendShown() )
2250 tab_js[
"legend" ] = nlohmann::json( { {
"x", plotTab->GetLegendPosition().x },
2251 {
"y", plotTab->GetLegendPosition().y } } );
2254 mpWindow* plotWin = plotTab->GetPlotWin();
2256 tab_js[
"margins" ] = nlohmann::json( { {
"left", plotWin->
GetMarginLeft() },
2262 tabs_js.push_back( tab_js );
2265 nlohmann::json userDefinedSignals_js = nlohmann::json::array();
2268 userDefinedSignals_js.push_back( signal );
2270 nlohmann::json js = nlohmann::json( { {
"version", 6 },
2271 {
"tabs", tabs_js },
2272 {
"user_defined_signals", userDefinedSignals_js } } );
2283 std::stringstream buffer;
2284 buffer << std::setw( 2 ) << js << std::endl;
2286 bool res = file.Write( buffer.str() );
2293 simulator()->Settings()->SetWorkbookFilename( filename.GetFullPath() );
2311 default: wxFAIL_MSG( wxS(
"Unhandled simulation type" ) );
return SPT_UNKNOWN;
2330 &source, &
scale, &pts, &fStart, &fStop, &saveAll );
2345 for(
size_t page = 0; page <
m_plotNotebook->GetPageCount(); page++ )
2390 std::vector<std::pair<wxString, wxString>>& measurements = plotTab->Measurements();
2392 measurements.clear();
2430 simulator()->Command(
"setplot " + simTab->GetSpicePlotName().ToStdString() );
2444 for(
const auto& [
measurement, format ] : plotTab->Measurements() )
2452 if( plotTab->GetSimType() ==
ST_TRAN || plotTab->GetSimType() ==
ST_AC
2453 || plotTab->GetSimType() ==
ST_DC || plotTab->GetSimType() ==
ST_SP )
2490 CURSOR* cursor1 =
nullptr;
2491 wxString cursor1Name;
2492 wxString cursor1Units;
2493 CURSOR* cursor2 =
nullptr;
2494 wxString cursor2Name;
2495 wxString cursor2Units;
2498 [&](
TRACE* aTrace ) -> wxString
2502 else if( aTrace->GetType() &
SPT_POWER )
2509 [&](
TRACE* aTrace ) -> wxString
2513 else if( aTrace->GetType() &
SPT_POWER )
2520 [
this](
double aValue,
int aCursorId,
int aCol ) -> wxString
2533 cursor1Name = getNameY( trace );
2534 cursor1Units = getUnitsY( trace );
2536 wxRealPoint coords =
cursor->GetCoords();
2556 cursor2Name = getNameY( trace );
2557 cursor2Units = getUnitsY( trace );
2559 wxRealPoint coords =
cursor->GetCoords();
2574 if( cursor1 && cursor2 && cursor1Units == cursor2Units )
2583 signal = wxString::Format( wxS(
"%s[2 - 1]" ), cursor2->
GetName() );
2585 signal = wxString::Format( wxS(
"%s - %s" ), cursor2->
GetName(), cursor1->
GetName() );
2597 wxString valColName =
_(
"Value" );
2599 if( !cursor1Name.IsEmpty() )
2601 if( cursor2Name.IsEmpty() || cursor1Name == cursor2Name )
2602 valColName = cursor1Name;
2604 else if( !cursor2Name.IsEmpty() )
2606 valColName = cursor2Name;
2623 plotTab->ResetScales(
true );
2643 std::vector<wxString> signals;
2645 for(
const std::string& vec :
simulator()->AllVectors() )
2646 signals.emplace_back( vec );
2654 std::vector<wxString> signals;
2656 for(
const wxString& signal :
m_signals )
2657 signals.emplace_back( signal );
2660 signals.emplace_back( signal );
2689 if( simType ==
ST_NOISE && aFinal )
2691 m_simConsole->AppendText(
_(
"\n\nSimulation results:\n\n" ) );
2698 simulator()->CurrentPlotName().Mid( 5 ).ToLong( &number );
2700 for(
const std::string& vec :
simulator()->AllVectors() )
2702 std::vector<double> val_list =
simulator()->GetRealVector( vec, 1 );
2705 msg.Printf( wxS(
"%s: %sV\n" ), vec, value );
2711 simulator()->Command( fmt::format(
"setplot noise{}", number - 1 ) );
2716 wxCHECK_RET( plotTab, wxT(
"not a SIM_PLOT_TAB" ) );
2725 std::map<TRACE*, TRACE_INFO> traceMap;
2728 traceMap[ trace ] = { wxEmptyString,
SPT_UNKNOWN,
false };
2733 for(
const wxString& signal :
m_signals )
2738 if(
TRACE* trace = plotTab->
GetTrace( vectorName, traceType ) )
2739 traceMap[ trace ] = { vectorName, traceType,
false };
2747 if( simType ==
ST_AC )
2753 if(
TRACE* trace = plotTab->
GetTrace( vectorName, subType ) )
2754 traceMap[ trace ] = { vectorName, subType, !aFinal };
2757 else if( simType ==
ST_SP )
2763 if(
TRACE* trace = plotTab->
GetTrace( vectorName, subType ) )
2764 traceMap[trace] = { vectorName, subType, !aFinal };
2769 if(
TRACE* trace = plotTab->
GetTrace( vectorName, traceType ) )
2770 traceMap[ trace ] = { vectorName, traceType, !aFinal };
2776 for(
const auto& [ trace, traceInfo ] : traceMap )
2778 if( traceInfo.Vector.IsEmpty() )
2782 for(
const auto& [ trace,
info ] : traceMap )
2784 std::vector<double> data_x;
2786 if( !
info.Vector.IsEmpty() )
2804 else if( simType ==
ST_OP && aFinal )
2806 m_simConsole->AppendText(
_(
"\n\nSimulation results:\n\n" ) );
2809 for(
const std::string& vec :
simulator()->AllVectors() )
2811 std::vector<double> val_list =
simulator()->GetRealVector( vec, 1 );
2813 if( val_list.empty() )
2820 const size_t tab = 25;
2821 size_t padding = ( signal.length() < tab ) ? ( tab - signal.length() ) : 1;
2825 case SPT_VOLTAGE: value.Append( wxS(
"V" ) );
break;
2826 case SPT_CURRENT: value.Append( wxS(
"A" ) );
break;
2827 case SPT_POWER: value.Append( wxS(
"W" ) );
break;
2828 default: value.Append( wxS(
"?" ) );
break;
2831 msg.Printf( wxT(
"%s%s\n" ),
2832 ( signal + wxT(
":" ) ).Pad( padding, wxUniChar(
' ' ) ),
2839 signal = signal.SubString( 2, signal.Length() - 2 );
2842 signal += wxS(
":power" );
2847 else if( simType ==
ST_PZ && aFinal )
2849 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)
@ 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 std::string &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 SetTraceData(TRACE *aTrace, std::vector< double > &aX, std::vector< double > &aY)
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
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
virtual void OnLanguageChanged()=0
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.
Definition of file extensions used in Kicad.