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 )
601 pageTitle.Prepend( wxString::Format(
_(
"Analysis %u - " ), ii+1 ) );
621 tuner->ShowChangedLanguage();
659 for( std::size_t i = 0; i < pageCount; ++i )
662 auto simTab =
dynamic_cast<SIM_TAB*
>( page );
663 wxASSERT( simTab !=
nullptr );
664 simTab->ApplyPreferences( aPrefs );
671 if( !
simulator()->Settings()->GetWorkbookFilename().IsEmpty() )
673 wxFileName filename =
simulator()->Settings()->GetWorkbookFilename();
677 simulator()->Settings()->SetWorkbookFilename(
"" );
681 wxString schTextSimCommand =
circuitModel()->GetSchTextSimCommand();
683 if( !schTextSimCommand.IsEmpty() )
716 std::sort( signals.begin(), signals.end(),
717 [](
const wxString& lhs,
const wxString& rhs )
720 if( lhs.Upper().StartsWith(
'V' ) && !rhs.Upper().StartsWith(
'V' ) )
722 else if( !lhs.Upper().StartsWith(
'V' ) && rhs.Upper().StartsWith(
'V' ) )
725 return StrNumCmp( lhs, rhs, true ) < 0;
742 std::vector<wxString> signals;
746 wxStringTokenizer tokenizer( plotPanel->
GetSimCommand(), wxT(
" \t\r\n" ), wxTOKEN_STRTOK );
748 while( tokenizer.HasMoreTokens() && tokenizer.GetNextToken().Lower() != wxT(
"fft" ) )
751 while( tokenizer.HasMoreTokens() )
752 signals.emplace_back( tokenizer.GetNextToken() );
759 for(
const wxString& signal :
m_signals )
760 signals.push_back( signal );
764 if( simType ==
ST_AC )
766 signals.push_back( signal +
_(
" (gain)" ) );
767 signals.push_back( signal +
_(
" (phase)" ) );
769 else if( simType ==
ST_SP )
771 signals.push_back( signal +
_(
" (amplitude)" ) );
772 signals.push_back( signal +
_(
" (phase)" ) );
776 signals.push_back( signal );
783 if( aFilter.IsEmpty() )
784 aFilter = wxS(
"*" );
789 for(
const wxString& signal : signals )
791 if( matcher.
Find( signal.Upper() ) )
800 wxGridCellAttr* attr =
new wxGridCellAttr;
801 attr->SetRenderer(
new wxGridCellBoolRenderer() );
803 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
808 attr =
new wxGridCellAttr;
813 attr =
new wxGridCellAttr;
817 attr =
new wxGridCellAttr;
825 attr =
new wxGridCellAttr;
828 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
833 attr =
new wxGridCellAttr;
834 attr->SetRenderer(
new wxGridCellBoolRenderer() );
836 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
839 attr =
new wxGridCellAttr;
840 attr->SetRenderer(
new wxGridCellBoolRenderer() );
842 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
858 wxString unconnected = wxString( wxS(
"unconnected-(" ) );
863 unconnected.Replace(
'(',
'_' );
866 [&](
const wxString& aSignalName )
868 if( simType ==
ST_AC )
870 m_signals.push_back( aSignalName +
_(
" (gain)" ) );
871 m_signals.push_back( aSignalName +
_(
" (phase)" ) );
873 else if( simType ==
ST_SP )
875 m_signals.push_back( aSignalName +
_(
" (amplitude)" ) );
876 m_signals.push_back( aSignalName +
_(
" (phase)" ) );
887 for(
const std::string& net :
circuitModel()->GetNets() )
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 tokenizer( directive, wxT(
"\r\n" ), wxTOKEN_STRTOK );
965 while( tokenizer.HasMoreTokens() )
967 wxString line = tokenizer.GetNextToken();
968 wxString directiveParams;
970 if( line.Upper().StartsWith( wxS(
".PROBE" ), &directiveParams ) )
971 addSignal( directiveParams.Trim(
true ).Trim(
false ) );
993 wxString pageTitle(
simulator()->TypeToName( simType,
true ) );
994 pageTitle.Prepend( wxString::Format(
_(
"Analysis %u - " ), (
unsigned int) ++
m_plotNumber ) );
1010 wxPoint pos = aEvent.GetPosition();
1011 wxRect ctrlRect =
m_filter->GetScreenRect();
1012 int buttonWidth = ctrlRect.GetHeight();
1014 if(
m_filter->IsSearchButtonVisible() && pos.x < buttonWidth )
1015 SetCursor( wxCURSOR_ARROW );
1016 else if(
m_filter->IsCancelButtonVisible() && pos.x > ctrlRect.GetWidth() - buttonWidth )
1017 SetCursor( wxCURSOR_ARROW );
1019 SetCursor( wxCURSOR_IBEAM );
1025 return wxString::Format( wxS(
"user%d" ), aUserDefinedSignalId );
1034 const wxString& aSignalName,
1037 std::map<wxString, int> suffixes;
1053 wxUniChar firstChar = aSignalName.Upper()[0];
1055 if( firstChar ==
'V' )
1057 else if( firstChar ==
'I' )
1059 else if( firstChar ==
'P' )
1065 wxString
name = aSignalName;
1067 for(
const auto& [ candidate, type ] : suffixes )
1069 if(
name.EndsWith( candidate ) )
1071 name =
name.Left(
name.Length() - candidate.Length() );
1074 *aTraceType |= type;
1082 if(
name == signal )
1100 int row = aEvent.GetRow();
1101 int col = aEvent.GetCol();
1109 if(
text == wxS(
"1" ) )
1136 for(
int ii = 0; ii <
m_signalsGrid->GetNumberRows(); ++ii )
1142 bool enable = ii == row &&
text == wxS(
"1" );
1144 plotTab->
EnableCursor( vectorName, traceType,
id, enable, signalName );
1164 int row = aEvent.GetRow();
1165 int col = aEvent.GetCol();
1171 CURSOR* cursor1 =
nullptr;
1172 CURSOR* cursor2 =
nullptr;
1185 if( cursorName == wxS(
"1" ) && cursor1 )
1187 else if( cursorName == wxS(
"2" ) && cursor2 )
1189 else if( cursorName ==
_(
"Diff" ) && cursor1 && cursor2 )
1197 wxFAIL_MSG( wxT(
"All other columns are supposed to be read-only!" ) );
1230 int row = aEvent.GetRow();
1231 int col = aEvent.GetCol();
1241 wxFAIL_MSG( wxT(
"All other columns are supposed to be read-only!" ) );
1249 for( row = rowCount - 1; row >= 0; row-- )
1259 int killRows = emptyRows - 1;
1262 else if( emptyRows == 0 )
1273 if( plotTab->GetLegendPosition() != plotTab->m_LastLegendPosition )
1275 plotTab->m_LastLegendPosition = plotTab->GetLegendPosition();
1298 static wxRegEx measureParamsRegEx( wxT(
"^"
1302 "([a-zA-Z]*)\\(([^\\)]+)\\)" ) );
1311 if(
text.IsEmpty() )
1318 wxString resultName = wxString::Format( wxS(
"meas_result_%u" ), aRow );
1319 wxString result = wxS(
"?" );
1321 if( measureParamsRegEx.Matches(
text ) )
1323 wxString func = measureParamsRegEx.GetMatch(
text, 1 ).Upper();
1324 wxString signalType = measureParamsRegEx.GetMatch(
text, 2 ).Upper();
1325 wxString deviceName = measureParamsRegEx.GetMatch(
text, 3 );
1329 if( signalType.EndsWith( wxS(
"DB" ) ) )
1331 units = wxS(
"dB" );
1333 else if( signalType.StartsWith(
'I' ) )
1337 else if( signalType.StartsWith(
'P' ) )
1341 text = func +
" " + deviceName +
":power";
1348 if( func.EndsWith( wxS(
"_AT" ) ) )
1351 units = wxS(
"Hz" );
1355 else if( func.StartsWith( wxS(
"INTEG" ) ) )
1360 if ( signalType.StartsWith(
'P' ) )
1363 units += wxS(
".s" );
1373 units += wxS(
"·Hz" );
1381 units += wxS(
"·?" );
1392 wxString cmd = wxString::Format( wxS(
"meas %s %s %s" ), simType, resultName,
text );
1393 simulator()->Command(
"echo " + cmd.ToStdString() );
1394 simulator()->Command( cmd.ToStdString() );
1396 std::vector<double> resultVec =
simulator()->GetGainVector( resultName.ToStdString() );
1398 if( resultVec.size() > 0 )
1413 wxString ref = aSymbol->
GetRef( &aSheetPath );
1418 if( tuner->GetSymbolRef() == ref )
1444 const wxString& aRef,
const wxString& aValue )
1452 + wxString::Format(
_(
"%s not found" ), aRef ) );
1465 + wxString::Format(
_(
"%s is not tunable" ), aRef ) );
1531 wxString cmd = wxString::Format( wxS(
"fourier %s %s" ),
1535 simulator()->Command( cmd.ToStdString() );
1549 m_simConsole->AppendText(
_(
"Error: no current simulation.\n" ) );
1558 m_simConsole->AppendText(
_(
"Error: simulation type not defined.\n" ) );
1564 m_simConsole->AppendText(
_(
"Error: simulation type doesn't support plotting.\n" ) );
1570 wxCHECK( plotTab, );
1572 if( simType ==
ST_AC )
1577 else if( simType ==
ST_SP )
1608 if( aNewSignals.count(
id ) == 0 )
1613 plotTab->
DeleteTrace( vectorName, traceType | subType );
1618 plotTab->
DeleteTrace( vectorName, traceType | subType );
1631 if(
TRACE* trace = plotTab->
GetTrace( vectorName, traceType | subType ) )
1632 trace->SetName( aNewSignals.at(
id ) );
1639 if(
TRACE* trace = plotTab->
GetTrace( vectorName, traceType | subType ) )
1640 trace->SetName( aNewSignals.at(
id ) );
1645 if(
TRACE* trace = plotTab->
GetTrace( vectorName, traceType ) )
1646 trace->SetName( aNewSignals.at(
id ) );
1674 wxString simVectorName = aVectorName;
1677 simVectorName = simVectorName.AfterFirst(
'(' ).BeforeLast(
')' ) + wxS(
":power" );
1682 simulator()->Command( wxString::Format( wxT(
"print %s" ), aVectorName ).ToStdString() );
1687 std::vector<double> data_x;
1688 std::vector<double> data_y;
1690 if( !aDataX || aClearData )
1694 if( aDataX->empty() && !aClearData )
1696 wxString xAxisName(
simulator()->GetXAxis( simType ) );
1698 if( xAxisName.IsEmpty() )
1701 *aDataX =
simulator()->GetGainVector( (
const char*) xAxisName.c_str() );
1704 unsigned int size = aDataX->size();
1710 data_y =
simulator()->GetGainVector( (
const char*) simVectorName.c_str(), size );
1712 data_y =
simulator()->GetPhaseVector( (
const char*) simVectorName.c_str(), size );
1714 wxFAIL_MSG( wxT(
"Plot type missing AC_PHASE or AC_MAG bit" ) );
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 SPT_SP_AMP bit" ) );
1728 data_y =
simulator()->GetGainVector( (
const char*) simVectorName.c_str(), -1 );
1734 data_y =
simulator()->GetGainVector( (
const char*) simVectorName.c_str(), size );
1738 wxFAIL_MSG( wxT(
"Unhandled plot type" ) );
1745 if( simType ==
ST_DC
1753 size_t outer = ( size_t )( ( source2.
m_vend - v ) / source2.
m_vincrement ).ToDouble();
1754 size_t inner = aDataX->size() / ( outer + 1 );
1756 wxASSERT( aDataX->size() % ( outer + 1 ) == 0 );
1758 for(
size_t idx = 0; idx <= outer; idx++ )
1762 if( data_y.size() >= size )
1764 std::vector<double> sub_x( aDataX->begin() + offset,
1765 aDataX->begin() + offset + inner );
1766 std::vector<double> sub_y( data_y.begin() + offset,
1767 data_y.begin() + offset + inner );
1779 if( data_y.size() >= size )
1789 for(
int row = 0; row <
m_signalsGrid->GetNumberRows(); ++row )
1795 if(
TRACE* trace = plotTab ? plotTab->
GetTrace( vectorName, traceType ) :
nullptr )
1799 wxGridCellAttr* attr =
new wxGridCellAttr;
1802 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
1808 attr =
new wxGridCellAttr;
1809 attr->SetRenderer(
new wxGridCellBoolRenderer() );
1810 attr->SetReadOnly();
1811 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
1814 attr =
new wxGridCellAttr;
1815 attr->SetRenderer(
new wxGridCellBoolRenderer() );
1816 attr->SetReadOnly();
1817 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
1820 if( trace->HasCursor( 1 ) )
1825 if( trace->HasCursor( 2 ) )
1834 wxGridCellAttr* attr =
new wxGridCellAttr;
1835 attr->SetReadOnly();
1839 attr =
new wxGridCellAttr;
1840 attr->SetReadOnly();
1844 attr =
new wxGridCellAttr;
1845 attr->SetReadOnly();
1855 auto quoteNetNames =
1856 [&]( wxString aExpression ) -> wxString
1859 aExpression.Replace( netname, quotedNetname );
1866 constexpr const char* cmd =
"let user{} = {}";
1868 simulator()->Command(
"echo " + fmt::format( cmd,
id, signal.ToStdString() ) );
1869 simulator()->Command( fmt::format( cmd,
id, quoteNetNames( signal ).ToStdString() ) );
1882 wxString ref = tuner->GetSymbolRef();
1883 KIID symbolId = tuner->GetSymbol( &sheetPath );
1889 reporter.
Report( wxString::Format(
_(
"%s not found" ), ref ) );
1897 reporter.
Report( wxString::Format(
_(
"%s is not tunable" ), ref ) );
1901 double floatVal = tuner->GetValue().ToDouble();
1913 wxTextFile file( aPath );
1918 wxString firstLine = file.GetFirstLine();
1920 bool legacy = firstLine.StartsWith( wxT(
"version " ) ) || firstLine.ToLong( &
dummy );
1945 wxFileName filename( aPath );
1949 simulator()->Settings()->SetWorkbookFilename( filename.GetFullPath() );
1957 wxFFileInputStream fp( aPath, wxT(
"rt" ) );
1958 wxStdInputStream fstream( fp );
1965 nlohmann::json js = nlohmann::json::parse( fstream,
nullptr,
true,
true );
1967 std::map<SIM_PLOT_TAB*, nlohmann::json> traceInfo;
1969 for(
const nlohmann::json& tab_js : js[
"tabs" ] )
1971 wxString simCommand;
1975 for(
const nlohmann::json& cmd : tab_js[
"commands" ] )
1977 if( cmd ==
".kicad adjustpaths" )
1979 else if( cmd ==
".save all" )
1981 else if( cmd ==
".probe alli" )
1983 else if( cmd ==
".probe allp" )
1985 else if( cmd ==
".kicad esavenone" )
1988 simCommand += wxString( cmd.get<wxString>() ).Trim();
1998 if( tab_js.contains(
"traces" ) )
1999 traceInfo[plotTab] = tab_js[
"traces" ];
2001 if( tab_js.contains(
"measurements" ) )
2003 for(
const nlohmann::json& m_js : tab_js[
"measurements" ] )
2004 plotTab->
Measurements().emplace_back( m_js[
"expr" ], m_js[
"format" ] );
2008 plotTab->
ShowGrid( tab_js[
"showGrid" ] );
2010 if( tab_js.contains(
"fixedY1scale" ) )
2012 const nlohmann::json& scale_js = tab_js[
"fixedY1scale" ];
2013 plotTab->
SetY1Scale(
true, scale_js[
"min" ], scale_js[
"max" ] );
2017 if( tab_js.contains(
"fixedY2scale" ) )
2019 const nlohmann::json& scale_js = tab_js[
"fixedY2scale" ];
2020 plotTab->
SetY2Scale(
true, scale_js[
"min" ], scale_js[
"max" ] );
2024 if( tab_js.contains(
"fixedY3scale" ) )
2027 const nlohmann::json& scale_js = tab_js[
"fixedY3scale" ];
2028 plotTab->
SetY3Scale(
true, scale_js[
"min" ], scale_js[
"max" ] );
2032 if( tab_js.contains(
"legend" ) )
2034 const nlohmann::json& legend_js = tab_js[
"legend" ];
2039 if( tab_js.contains(
"margins" ) )
2041 const nlohmann::json& margins_js = tab_js[
"margins" ];
2043 margins_js[
"right" ],
2044 margins_js[
"bottom" ],
2045 margins_js[
"left" ] );
2052 if( js.contains(
"user_defined_signals" ) )
2054 for(
const nlohmann::json& signal_js : js[
"user_defined_signals" ] )
2060 int aCursorId,
const nlohmann::json& aCursor_js )
2062 if( aCursorId == 1 || aCursorId == 2 )
2066 cursor->SetName( aSignalName );
2067 cursor->SetPen( wxPen( aTrace->GetTraceColour() ) );
2068 cursor->SetCoordX( aCursor_js[
"position" ] );
2070 aTrace->SetCursor( aCursorId,
cursor );
2078 for(
const auto& [ plotTab, traces_js ] : traceInfo )
2080 for(
const nlohmann::json& trace_js : traces_js )
2082 wxString signalName = trace_js[
"signal" ];
2084 TRACE* trace = plotTab->GetOrAddTrace( vectorName, trace_js[
"trace_type" ] );
2088 if( trace_js.contains(
"cursor1" ) )
2089 addCursor( plotTab, trace, signalName, 1, trace_js[
"cursor1" ] );
2091 if( trace_js.contains(
"cursor2" ) )
2092 addCursor( plotTab, trace, signalName, 2, trace_js[
"cursor2" ] );
2094 if( trace_js.contains(
"cursorD" ) )
2095 addCursor( plotTab, trace, signalName, 3, trace_js[
"cursorD" ] );
2097 if( trace_js.contains(
"color" ) )
2100 color.Set( wxString( trace_js[
"color"].get<wxString>() ) );
2102 plotTab->UpdateTraceStyle( trace );
2107 plotTab->UpdatePlotColors();
2116 wxCHECK( simTab,
false );
2118 simTab->SetLastSchTextSimCommand( js[
"last_sch_text_sim_command" ] );
2121 catch( nlohmann::json::parse_error& error )
2123 wxLogTrace(
traceSettings, wxT(
"Json parse error reading %s: %s" ), aPath, error.what() );
2136 wxFileName filename = aPath;
2141 file.Create( filename.GetFullPath(),
true );
2143 if( !file.IsOpened() )
2146 nlohmann::json tabs_js = nlohmann::json::array();
2157 nlohmann::json commands_js = nlohmann::json::array();
2164 commands_js.push_back(
".kicad adjustpaths" );
2167 commands_js.push_back(
".save all" );
2170 commands_js.push_back(
".probe alli" );
2173 commands_js.push_back(
".probe allp" );
2176 commands_js.push_back(
".kicad esavenone" );
2178 nlohmann::json tab_js = nlohmann::json(
2180 {
"commands", commands_js } } );
2184 nlohmann::json traces_js = nlohmann::json::array();
2186 auto findSignalName =
2187 [&](
const wxString& aVectorName ) -> wxString
2198 for(
const auto& [
name, trace] : plotTab->GetTraces() )
2200 nlohmann::json trace_js = nlohmann::json(
2201 { {
"trace_type", (int) trace->GetType() },
2202 {
"signal", findSignalName( trace->GetName() ) },
2207 trace_js[
"cursor1"] = nlohmann::json(
2208 { {
"position",
cursor->GetCoords().x },
2215 trace_js[
"cursor2"] = nlohmann::json(
2216 { {
"position",
cursor->GetCoords().x },
2221 if( trace->GetCursor( 1 ) || trace->GetCursor( 2 ) )
2223 trace_js[
"cursorD"] = nlohmann::json(
2228 traces_js.push_back( trace_js );
2231 nlohmann::json measurements_js = nlohmann::json::array();
2233 for(
const auto& [
measurement, format ] : plotTab->Measurements() )
2235 measurements_js.push_back( nlohmann::json( { {
"expr",
measurement },
2236 {
"format", format } } ) );
2239 tab_js[
"traces" ] = traces_js;
2240 tab_js[
"measurements" ] = measurements_js;
2241 tab_js[
"dottedSecondary" ] = plotTab->GetDottedSecondary();
2242 tab_js[
"showGrid" ] = plotTab->IsGridShown();
2246 if( plotTab->GetY1Scale( &min, &max ) )
2247 tab_js[
"fixedY1scale" ] = nlohmann::json( { {
"min", min }, {
"max", max } } );
2249 if( plotTab->GetY2Scale( &min, &max ) )
2250 tab_js[
"fixedY2scale" ] = nlohmann::json( { {
"min", min }, {
"max", max } } );
2252 if( plotTab->GetY3Scale( &min, &max ) )
2253 tab_js[
"fixedY3scale" ] = nlohmann::json( { {
"min", min }, {
"max", max } } );
2255 if( plotTab->IsLegendShown() )
2257 tab_js[
"legend" ] = nlohmann::json( { {
"x", plotTab->GetLegendPosition().x },
2258 {
"y", plotTab->GetLegendPosition().y } } );
2261 mpWindow* plotWin = plotTab->GetPlotWin();
2263 tab_js[
"margins" ] = nlohmann::json( { {
"left", plotWin->
GetMarginLeft() },
2269 tabs_js.push_back( tab_js );
2272 nlohmann::json userDefinedSignals_js = nlohmann::json::array();
2275 userDefinedSignals_js.push_back( signal );
2277 nlohmann::json js = nlohmann::json( { {
"version", 6 },
2278 {
"tabs", tabs_js },
2279 {
"user_defined_signals", userDefinedSignals_js } } );
2290 std::stringstream buffer;
2291 buffer << std::setw( 2 ) << js << std::endl;
2293 bool res = file.Write( buffer.str() );
2300 simulator()->Settings()->SetWorkbookFilename( filename.GetFullPath() );
2318 default: wxFAIL_MSG( wxS(
"Unhandled simulation type" ) );
return SPT_UNKNOWN;
2337 &source, &
scale, &pts, &fStart, &fStop, &saveAll );
2352 for(
size_t page = 0; page <
m_plotNotebook->GetPageCount(); page++ )
2397 std::vector<std::pair<wxString, wxString>>& measurements = plotTab->Measurements();
2399 measurements.clear();
2437 simulator()->Command(
"setplot " + simTab->GetSpicePlotName().ToStdString() );
2451 for(
const auto& [
measurement, format ] : plotTab->Measurements() )
2459 if( plotTab->GetSimType() ==
ST_TRAN || plotTab->GetSimType() ==
ST_AC
2460 || plotTab->GetSimType() ==
ST_DC || plotTab->GetSimType() ==
ST_SP )
2497 CURSOR* cursor1 =
nullptr;
2498 wxString cursor1Name;
2499 wxString cursor1Units;
2500 CURSOR* cursor2 =
nullptr;
2501 wxString cursor2Name;
2502 wxString cursor2Units;
2505 [&](
TRACE* aTrace ) -> wxString
2509 else if( aTrace->GetType() &
SPT_POWER )
2516 [&](
TRACE* aTrace ) -> wxString
2520 else if( aTrace->GetType() &
SPT_POWER )
2527 [
this](
double aValue,
int aCursorId,
int aCol ) -> wxString
2540 cursor1Name = getNameY( trace );
2541 cursor1Units = getUnitsY( trace );
2543 wxRealPoint coords =
cursor->GetCoords();
2563 cursor2Name = getNameY( trace );
2564 cursor2Units = getUnitsY( trace );
2566 wxRealPoint coords =
cursor->GetCoords();
2581 if( cursor1 && cursor2 && cursor1Units == cursor2Units )
2590 signal = wxString::Format( wxS(
"%s[2 - 1]" ), cursor2->
GetName() );
2592 signal = wxString::Format( wxS(
"%s - %s" ), cursor2->
GetName(), cursor1->
GetName() );
2604 wxString valColName =
_(
"Value" );
2606 if( !cursor1Name.IsEmpty() )
2608 if( cursor2Name.IsEmpty() || cursor1Name == cursor2Name )
2609 valColName = cursor1Name;
2611 else if( !cursor2Name.IsEmpty() )
2613 valColName = cursor2Name;
2630 plotTab->ResetScales(
true );
2650 std::vector<wxString> signals;
2652 for(
const std::string& vec :
simulator()->AllVectors() )
2653 signals.emplace_back( vec );
2661 std::vector<wxString> signals;
2663 for(
const wxString& signal :
m_signals )
2664 signals.emplace_back( signal );
2667 signals.emplace_back( signal );
2696 if( simType ==
ST_NOISE && aFinal )
2698 m_simConsole->AppendText(
_(
"\n\nSimulation results:\n\n" ) );
2705 simulator()->CurrentPlotName().Mid( 5 ).ToLong( &number );
2707 for(
const std::string& vec :
simulator()->AllVectors() )
2709 std::vector<double> val_list =
simulator()->GetRealVector( vec, 1 );
2712 msg.Printf( wxS(
"%s: %sV\n" ), vec, value );
2718 simulator()->Command( fmt::format(
"setplot noise{}", number - 1 ) );
2723 wxCHECK_RET( plotTab, wxT(
"not a SIM_PLOT_TAB" ) );
2732 std::map<TRACE*, TRACE_INFO> traceMap;
2735 traceMap[ trace ] = { wxEmptyString,
SPT_UNKNOWN,
false };
2740 for(
const wxString& signal :
m_signals )
2745 if(
TRACE* trace = plotTab->
GetTrace( vectorName, traceType ) )
2746 traceMap[ trace ] = { vectorName, traceType,
false };
2754 if( simType ==
ST_AC )
2760 if(
TRACE* trace = plotTab->
GetTrace( vectorName, subType ) )
2761 traceMap[ trace ] = { vectorName, subType, !aFinal };
2764 else if( simType ==
ST_SP )
2770 if(
TRACE* trace = plotTab->
GetTrace( vectorName, subType ) )
2771 traceMap[trace] = { vectorName, subType, !aFinal };
2776 if(
TRACE* trace = plotTab->
GetTrace( vectorName, traceType ) )
2777 traceMap[ trace ] = { vectorName, traceType, !aFinal };
2783 for(
const auto& [ trace, traceInfo ] : traceMap )
2785 if( traceInfo.Vector.IsEmpty() )
2789 for(
const auto& [ trace,
info ] : traceMap )
2791 std::vector<double> data_x;
2793 if( !
info.Vector.IsEmpty() )
2811 else if( simType ==
ST_OP && aFinal )
2813 m_simConsole->AppendText(
_(
"\n\nSimulation results:\n\n" ) );
2816 for(
const std::string& vec :
simulator()->AllVectors() )
2818 std::vector<double> val_list =
simulator()->GetRealVector( vec, 1 );
2820 if( val_list.empty() )
2827 const size_t tab = 25;
2828 size_t padding = ( signal.length() < tab ) ? ( tab - signal.length() ) : 1;
2832 case SPT_VOLTAGE: value.Append( wxS(
"V" ) );
break;
2833 case SPT_CURRENT: value.Append( wxS(
"A" ) );
break;
2834 case SPT_POWER: value.Append( wxS(
"W" ) );
break;
2835 default: value.Append( wxS(
"?" ) );
break;
2838 msg.Printf( wxT(
"%s%s\n" ),
2839 ( signal + wxT(
":" ) ).Pad( padding, wxUniChar(
' ' ) ),
2846 signal = signal.SubString( 2, signal.Length() - 2 );
2849 signal += wxS(
":power" );
2854 else if( simType ==
ST_PZ && aFinal )
2856 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.