diff --git a/common/bitmap_info.cpp b/common/bitmap_info.cpp index f4ec8fc2fb..5450ec008b 100644 --- a/common/bitmap_info.cpp +++ b/common/bitmap_info.cpp @@ -481,6 +481,7 @@ void BuildBitmapInfo( std::unordered_map>& aBi aBitmapInfoCache[BITMAPS::shape_3d_back].emplace_back( BITMAPS::shape_3d_back, wxT( "shape_3d_back_24.png" ), 24, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::sheetset].emplace_back( BITMAPS::sheetset, wxT( "sheetset_24.png" ), 24, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::simulator].emplace_back( BITMAPS::simulator, wxT( "simulator_24.png" ), 24, wxT( "light" ) ); + aBitmapInfoCache[BITMAPS::sim_command].emplace_back( BITMAPS::sim_command, wxT( "sim_command_24.png" ), 24, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::sim_run].emplace_back( BITMAPS::sim_run, wxT( "sim_run_24.png" ), 24, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::sim_stop].emplace_back( BITMAPS::sim_stop, wxT( "sim_stop_24.png" ), 24, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::sim_tune].emplace_back( BITMAPS::sim_tune, wxT( "sim_tune_24.png" ), 24, wxT( "light" ) ); diff --git a/eeschema/CMakeLists.txt b/eeschema/CMakeLists.txt index 92fcfd145f..e872e547b0 100644 --- a/eeschema/CMakeLists.txt +++ b/eeschema/CMakeLists.txt @@ -351,6 +351,7 @@ if( KICAD_SPICE ) dialogs/dialog_sim_command_base.cpp dialogs/dialog_sim_model.cpp dialogs/dialog_sim_model_base.cpp + tools/simulator_control.cpp sim/ngspice_circuit_model.cpp sim/ngspice.cpp sim/sim_panel_base.cpp @@ -362,6 +363,7 @@ if( KICAD_SPICE ) sim/sim_workbook.cpp sim/spice_simulator.cpp sim/spice_value.cpp + sim/toolbars_sim_plot_frame.cpp widgets/tuner_slider.cpp widgets/tuner_slider_base.cpp ) diff --git a/eeschema/menubar.cpp b/eeschema/menubar.cpp index 7302603727..4f7d318e66 100644 --- a/eeschema/menubar.cpp +++ b/eeschema/menubar.cpp @@ -253,7 +253,7 @@ void SCH_EDIT_FRAME::doReCreateMenuBar() #ifdef KICAD_SPICE inspectMenu->AppendSeparator(); - inspectMenu->Add( EE_ACTIONS::runSimulation ); + inspectMenu->Add( EE_ACTIONS::showSimulator ); #endif diff --git a/eeschema/sch_edit_frame.cpp b/eeschema/sch_edit_frame.cpp index ce9872abb9..4b7d9fadfd 100644 --- a/eeschema/sch_edit_frame.cpp +++ b/eeschema/sch_edit_frame.cpp @@ -769,9 +769,7 @@ bool SCH_EDIT_FRAME::canCloseWindow( wxCloseEvent& aEvent ) } } - SIM_PLOT_FRAME* simFrame = (SIM_PLOT_FRAME*) Kiway().Player( FRAME_SIMULATOR, false ); - - if( simFrame && !simFrame->Close() ) // Can close the simulator? + if( !Kiway().PlayerClose( FRAME_SIMULATOR, false ) ) // Can close the simulator? return false; // We may have gotten multiple events; don't clean up twice diff --git a/eeschema/sim/sim_plot_colors.cpp b/eeschema/sim/sim_plot_colors.cpp index c45db69c79..ac1076b637 100644 --- a/eeschema/sim/sim_plot_colors.cpp +++ b/eeschema/sim/sim_plot_colors.cpp @@ -2,7 +2,8 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2021 Sylwester Kocjan - * Copyright (C) 2016-2021 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2023 CERN + * Copyright (C) 2016-2023 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -91,24 +92,24 @@ wxColour SIM_PLOT_COLORS::GetPlotColor( COLOR_SET aColorId ) } -void SIM_PLOT_COLORS::FillDefaultColorList( bool aWhiteBg ) +void SIM_PLOT_COLORS::FillDefaultColorList( bool aDarkMode ) { m_colorList.clear(); - if( aWhiteBg ) - { - m_colorList.emplace_back( 255, 255, 255 ); // Bg color - m_colorList.emplace_back( 0, 0, 0 ); // Fg color (texts) - m_colorList.emplace_back( 130, 130, 130 ); // Axis color - m_colorList.emplace_back( 0, 0, 0 ); // cursors color - } - else + if( aDarkMode ) { m_colorList.emplace_back( 0, 0, 0 ); // Bg color m_colorList.emplace_back( 255, 255, 255 ); // Fg color (texts) m_colorList.emplace_back( 130, 130, 130 ); // Axis color m_colorList.emplace_back( 255, 255, 255 ); // cursors color } + else + { + m_colorList.emplace_back( 255, 255, 255 ); // Bg color + m_colorList.emplace_back( 0, 0, 0 ); // Fg color (texts) + m_colorList.emplace_back( 130, 130, 130 ); // Axis color + m_colorList.emplace_back( 0, 0, 0 ); // cursors color + } // Add a list of color for traces, starting at index SIM_TRACE_COLOR m_colorList.emplace_back( 0xE4, 0x1A, 0x1C ); diff --git a/eeschema/sim/sim_plot_frame.cpp b/eeschema/sim/sim_plot_frame.cpp index deef90b88f..013499866d 100644 --- a/eeschema/sim/sim_plot_frame.cpp +++ b/eeschema/sim/sim_plot_frame.cpp @@ -1,7 +1,7 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2016-2022 CERN + * Copyright (C) 2016-2023 CERN * Copyright (C) 2016-2023 KiCad Developers, see AUTHORS.txt for contributors. * @author Tomasz Wlostowski * @author Maciej Suminski @@ -25,7 +25,6 @@ */ #include -#include // For some obscure reason, needed on msys2 with some wxWidgets versions (3.0) to avoid // undefined symbol at link stage (due to use of #include ) @@ -34,15 +33,19 @@ #include #include -#include #include #include #include #include #include -#include -#include -#include "string_utils.h" +#include +#include +#include +#include +#include +#include +#include +#include #include #include "ngspice.h" #include "sim_plot_frame.h" @@ -50,12 +53,9 @@ #include "spice_simulator.h" #include "spice_reporter.h" #include -#include -#include #include -#include -#include -#include + +#include SIM_PLOT_TYPE operator|( SIM_PLOT_TYPE aFirst, SIM_PLOT_TYPE aSecond ) @@ -109,6 +109,7 @@ private: SIM_PLOT_FRAME::SIM_PLOT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : SIM_PLOT_FRAME_BASE( aParent ), m_lastSimPlot( nullptr ), + m_darkMode( true ), m_plotNumber( 0 ), m_simFinished( false ) { @@ -116,9 +117,7 @@ SIM_PLOT_FRAME::SIM_PLOT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : m_signalsIconColorList = nullptr; m_schematicFrame = (SCH_EDIT_FRAME*) Kiway().Player( FRAME_SCH, false ); - - if( m_schematicFrame == nullptr ) - throw std::runtime_error( "There is no schematic window" ); + wxASSERT( m_schematicFrame ); // Give an icon wxIcon icon; @@ -126,30 +125,28 @@ SIM_PLOT_FRAME::SIM_PLOT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : SetIcon( icon ); m_simulator = SIMULATOR::CreateInstance( "ngspice" ); - - if( !m_simulator ) - { - throw std::runtime_error( "Could not create simulator instance" ); - return; - } + wxASSERT( m_simulator ); // Get the previous size and position of windows: LoadSettings( config() ); // Prepare the color list to plot traces - SIM_PLOT_COLORS::FillDefaultColorList( GetPlotBgOpt() ); - - // Give icons to menuitems - setIconsForMenuItems(); + SIM_PLOT_COLORS::FillDefaultColorList( m_darkMode ); m_simulator->Init(); m_reporter = new SIM_THREAD_REPORTER( this ); m_simulator->SetReporter( m_reporter ); - m_circuitModel.reset( new NGSPICE_CIRCUIT_MODEL( &m_schematicFrame->Schematic(), this ) ); + m_circuitModel = std::make_shared( &m_schematicFrame->Schematic(), this ); - Bind( wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( SIM_PLOT_FRAME::menuExit ), this, + setupTools(); + setupUIConditions(); + + ReCreateHToolbar(); + ReCreateMenuBar(); + + Bind( wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( SIM_PLOT_FRAME::onExit ), this, wxID_EXIT ); Bind( EVT_SIM_UPDATE, &SIM_PLOT_FRAME::onSimUpdate, this ); @@ -158,56 +155,11 @@ SIM_PLOT_FRAME::SIM_PLOT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : Bind( EVT_SIM_FINISHED, &SIM_PLOT_FRAME::onSimFinished, this ); Bind( EVT_SIM_CURSOR_UPDATE, &SIM_PLOT_FRAME::onCursorUpdate, this ); - // Toolbar buttons - m_toolSimulate = m_toolBar->AddTool( ID_SIM_RUN, _( "Run/Stop Simulation" ), - KiBitmap( BITMAPS::sim_run ), _( "Run Simulation" ), wxITEM_NORMAL ); - m_toolAddSignals = m_toolBar->AddTool( ID_SIM_ADD_SIGNALS, _( "Add Signals" ), - KiBitmap( BITMAPS::sim_add_signal ), _( "Add signals to plot" ), wxITEM_NORMAL ); - m_toolProbe = m_toolBar->AddTool( ID_SIM_PROBE, _( "Probe" ), - KiBitmap( BITMAPS::sim_probe ), _( "Probe signals on the schematic" ), wxITEM_NORMAL ); - m_toolTune = m_toolBar->AddTool( ID_SIM_TUNE, _( "Tune" ), - KiBitmap( BITMAPS::sim_tune ), _( "Tune component values" ), wxITEM_NORMAL ); - m_toolSettings = m_toolBar->AddTool( wxID_ANY, _( "Sim Command" ), - KiBitmap( BITMAPS::config ), _( "Simulation command and settings" ), wxITEM_NORMAL ); - - // Start all toolbar buttons except settings as disabled - m_toolSimulate->Enable( false ); - m_toolAddSignals->Enable( false ); - m_toolProbe->Enable( false ); - m_toolTune->Enable( false ); - m_toolSettings->Enable( true ); - - Bind( wxEVT_UPDATE_UI, &SIM_PLOT_FRAME::menuSimulateUpdate, this, m_toolSimulate->GetId() ); - Bind( wxEVT_UPDATE_UI, &SIM_PLOT_FRAME::menuAddSignalsUpdate, this, - m_toolAddSignals->GetId() ); - Bind( wxEVT_UPDATE_UI, &SIM_PLOT_FRAME::menuProbeUpdate, this, m_toolProbe->GetId() ); - Bind( wxEVT_UPDATE_UI, &SIM_PLOT_FRAME::menuTuneUpdate, this, m_toolTune->GetId() ); - - Bind( wxEVT_COMMAND_TOOL_CLICKED, &SIM_PLOT_FRAME::onSimulate, this, m_toolSimulate->GetId() ); - Bind( wxEVT_COMMAND_TOOL_CLICKED, &SIM_PLOT_FRAME::onAddSignal, this, - m_toolAddSignals->GetId() ); - Bind( wxEVT_COMMAND_TOOL_CLICKED, &SIM_PLOT_FRAME::onProbe, this, m_toolProbe->GetId() ); - Bind( wxEVT_COMMAND_TOOL_CLICKED, &SIM_PLOT_FRAME::onTune, this, m_toolTune->GetId() ); - Bind( wxEVT_COMMAND_TOOL_CLICKED, &SIM_PLOT_FRAME::onSettings, this, m_toolSettings->GetId() ); - Bind( EVT_WORKBOOK_MODIFIED, &SIM_PLOT_FRAME::onWorkbookModified, this ); Bind( EVT_WORKBOOK_CLR_MODIFIED, &SIM_PLOT_FRAME::onWorkbookClrModified, this ); - // Bind toolbar buttons event to existing menu event handlers, so they behave the same - Bind( wxEVT_COMMAND_MENU_SELECTED, &SIM_PLOT_FRAME::onSimulate, this, - m_runSimulation->GetId() ); - Bind( wxEVT_COMMAND_MENU_SELECTED, &SIM_PLOT_FRAME::onAddSignal, this, m_addSignals->GetId() ); - Bind( wxEVT_COMMAND_MENU_SELECTED, &SIM_PLOT_FRAME::onProbe, this, m_probeSignals->GetId() ); - Bind( wxEVT_COMMAND_MENU_SELECTED, &SIM_PLOT_FRAME::onTune, this, m_tuneValue->GetId() ); - Bind( wxEVT_COMMAND_MENU_SELECTED, &SIM_PLOT_FRAME::onShowNetlist, this, - m_showNetlist->GetId() ); - Bind( wxEVT_COMMAND_MENU_SELECTED, &SIM_PLOT_FRAME::onSettings, this, - m_boardAdapter->GetId() ); - - m_toolBar->Realize(); - #ifndef wxHAS_NATIVE_TABART - // Non-native default tab art has ugly gradients we don't want + // Default non-native tab art has ugly gradients we don't want m_workbook->SetArtProvider( new wxAuiSimpleTabArt() ); #endif @@ -241,6 +193,25 @@ SIM_PLOT_FRAME::~SIM_PLOT_FRAME() } +void SIM_PLOT_FRAME::setupTools() +{ + // Create the manager + m_toolManager = new TOOL_MANAGER; + m_toolManager->SetEnvironment( nullptr, nullptr, nullptr, config(), this ); + + m_toolDispatcher = new TOOL_DISPATCHER( m_toolManager ); + + // Attach the events to the tool dispatcher + Bind( wxEVT_CHAR, &TOOL_DISPATCHER::DispatchWxEvent, m_toolDispatcher ); + Bind( wxEVT_CHAR_HOOK, &TOOL_DISPATCHER::DispatchWxEvent, m_toolDispatcher ); + + // Register tools + m_toolManager->RegisterTool( new COMMON_CONTROL ); + m_toolManager->RegisterTool( new SIMULATOR_CONTROL ); + m_toolManager->InitTools(); +} + + void SIM_PLOT_FRAME::LoadSettings( APP_SETTINGS_BASE* aCfg ) { EESCHEMA_SETTINGS* cfg = dynamic_cast( aCfg ); @@ -255,7 +226,7 @@ void SIM_PLOT_FRAME::LoadSettings( APP_SETTINGS_BASE* aCfg ) m_splitterPlotAndConsoleSashPosition = cfg->m_Simulator.plot_panel_height; m_splitterSignalsSashPosition = cfg->m_Simulator.signal_panel_height; m_splitterTuneValuesSashPosition = cfg->m_Simulator.cursors_panel_height; - m_plotUseWhiteBg = cfg->m_Simulator.white_background; + m_darkMode = !cfg->m_Simulator.white_background; } PROJECT_FILE& project = Prj().GetProjectFile(); @@ -280,7 +251,7 @@ void SIM_PLOT_FRAME::SaveSettings( APP_SETTINGS_BASE* aCfg ) cfg->m_Simulator.plot_panel_height = m_splitterPlotAndConsole->GetSashPosition(); cfg->m_Simulator.signal_panel_height = m_splitterSignals->GetSashPosition(); cfg->m_Simulator.cursors_panel_height = m_splitterTuneValues->GetSashPosition(); - cfg->m_Simulator.white_background = m_plotUseWhiteBg; + cfg->m_Simulator.white_background = !m_darkMode; } if( !m_isNonUserClose ) // If we're exiting the project has already been released. @@ -357,78 +328,6 @@ void SIM_PLOT_FRAME::updateTitle() } -// A small helper struct to handle bitmaps initialization in menus -struct BM_MENU_INIT_ITEM -{ - int m_MenuId; - BITMAPS m_Bitmap; -}; - - -void SIM_PLOT_FRAME::setIconsForMenuItems() -{ - // Give icons to menuitems of the main menubar - BM_MENU_INIT_ITEM bm_list[] - { - // File menu: - { wxID_NEW, BITMAPS::simulator }, - { wxID_OPEN, BITMAPS::directory_open }, - { wxID_SAVE, BITMAPS::save }, - { wxID_CLOSE, BITMAPS::exit }, - - // simulator menu: - { ID_MENU_RUN_SIM, BITMAPS::sim_run }, - { ID_MENU_ADD_SIGNAL, BITMAPS::sim_add_signal }, - { ID_MENU_PROBE_SIGNALS, BITMAPS::sim_probe }, - { ID_MENU_TUNE_SIGNALS, BITMAPS::sim_tune }, - { ID_MENU_SHOW_NETLIST, BITMAPS::netlist }, - { ID_MENU_SET_SIMUL, BITMAPS::config }, - - // View menu - { wxID_ZOOM_IN, BITMAPS::zoom_in }, - { wxID_ZOOM_OUT, BITMAPS::zoom_out }, - { wxID_ZOOM_FIT, BITMAPS::zoom_fit_in_page }, - { ID_MENU_SHOW_GRID, BITMAPS::grid }, - { ID_MENU_SHOW_LEGEND, BITMAPS::text }, - { ID_MENU_DOTTED, BITMAPS::add_dashed_line }, - { ID_MENU_WHITE_BG, BITMAPS::swap_layer }, - - { 0, BITMAPS::INVALID_BITMAP } // Sentinel - }; - - // wxMenuItems are already created and attached to the m_mainMenu wxMenuBar. - // A problem is the fact setting bitmaps in wxMenuItems after they are attached - // to a wxMenu do not work in all cases. - // So the trick is: - // Remove the wxMenuItem from its wxMenu - // Set the bitmap - // Insert the modified wxMenuItem to its previous place - for( int ii = 0; bm_list[ii].m_MenuId; ++ii ) - { - wxMenuItem* item = m_mainMenu->FindItem( bm_list[ii].m_MenuId ); - - if( !item || ( bm_list[ii].m_Bitmap == BITMAPS::INVALID_BITMAP ) ) - continue; - - wxMenu* menu = item->GetMenu(); - - // Calculate the initial index of item inside the wxMenu parent. - wxMenuItemList& mlist = menu->GetMenuItems(); - int mpos = mlist.IndexOf( item ); - - if( mpos >= 0 ) // Should be always the case - { - // Modify the bitmap - menu->Remove( item ); - AddBitmapToMenuItem( item, KiBitmap( bm_list[ii].m_Bitmap ) ); - - // Insert item to its the initial index - menu->Insert( mpos, item ); - } - } -} - - void SIM_PLOT_FRAME::setSubWindowsSashSize() { if( m_splitterLeftRightSashPosition > 0 ) @@ -447,7 +346,7 @@ void SIM_PLOT_FRAME::setSubWindowsSashSize() void SIM_PLOT_FRAME::StartSimulation( const wxString& aSimCommand ) { - wxCHECK_RET( m_circuitModel->CommandToSimType( getCurrentSimCommand() ) != ST_UNKNOWN, + wxCHECK_RET( m_circuitModel->CommandToSimType( GetCurrentSimCommand() ) != ST_UNKNOWN, wxT( "Unknown simulation type" ) ); m_simConsole->Clear(); @@ -455,7 +354,7 @@ void SIM_PLOT_FRAME::StartSimulation( const wxString& aSimCommand ) if( aSimCommand != wxEmptyString ) m_circuitModel->SetSimCommandOverride( aSimCommand ); - m_circuitModel->SetSimOptions( getCurrentOptions() ); + m_circuitModel->SetSimOptions( GetCurrentOptions() ); wxString errors; WX_STRING_REPORTER reporter( &errors ); @@ -516,7 +415,7 @@ SIM_PANEL_BASE* SIM_PLOT_FRAME::NewPlotPanel( wxString aSimCommand, int aOptions if( SIM_PANEL_BASE::IsPlottable( simType ) ) { SIM_PLOT_PANEL* panel; - panel = new SIM_PLOT_PANEL( aSimCommand, aOptions, m_workbook, this, wxID_ANY ); + panel = new SIM_PLOT_PANEL( aSimCommand, aOptions, m_workbook, wxID_ANY ); panel->GetPlotWin()->EnableMouseWheelPan( Pgm().GetCommonSettings()->m_Input.scroll_modifier_zoom != 0 ); @@ -935,7 +834,7 @@ void SIM_PLOT_FRAME::applyTuners() } -bool SIM_PLOT_FRAME::loadWorkbook( const wxString& aPath ) +bool SIM_PLOT_FRAME::LoadWorkbook( const wxString& aPath ) { m_workbook->DeleteAllPages(); @@ -1087,7 +986,7 @@ bool SIM_PLOT_FRAME::loadWorkbook( const wxString& aPath ) } -bool SIM_PLOT_FRAME::saveWorkbook( const wxString& aPath ) +bool SIM_PLOT_FRAME::SaveWorkbook( const wxString& aPath ) { wxFileName filename = aPath; filename.SetExt( WorkbookFileExtension ); @@ -1169,37 +1068,6 @@ bool SIM_PLOT_FRAME::saveWorkbook( const wxString& aPath ) } -wxString SIM_PLOT_FRAME::getDefaultFilename() -{ - wxFileName filename = m_simulator->Settings()->GetWorkbookFilename(); - - if( filename.GetName().IsEmpty() ) - { - if( Prj().GetProjectName().IsEmpty() ) - { - filename.SetName( _( "noname" ) ); - filename.SetExt( WorkbookFileExtension ); - } - else - { - filename.SetName( Prj().GetProjectName() ); - filename.SetExt( WorkbookFileExtension ); - } - } - - return filename.GetFullName(); -} - - -wxString SIM_PLOT_FRAME::getDefaultPath() -{ - wxFileName path = m_simulator->Settings()->GetWorkbookFilename(); - - path.Normalize( FN_NORMALIZE_FLAGS | wxPATH_NORM_ENV_VARS, Prj().GetProjectPath() ); - return path.GetPath(); -} - - SIM_PLOT_TYPE SIM_PLOT_FRAME::getXAxisType( SIM_TYPE aType ) const { switch( aType ) @@ -1215,200 +1083,12 @@ SIM_PLOT_TYPE SIM_PLOT_FRAME::getXAxisType( SIM_TYPE aType ) const } -void SIM_PLOT_FRAME::menuNewPlot( wxCommandEvent& aEvent ) +void SIM_PLOT_FRAME::ToggleDarkModePlots() { - SIM_TYPE type = m_circuitModel->GetSimType(); - - if( SIM_PANEL_BASE::IsPlottable( type ) ) - NewPlotPanel( m_circuitModel->GetSimCommand(), m_circuitModel->GetSimOptions() ); -} - - -void SIM_PLOT_FRAME::menuOpenWorkbook( wxCommandEvent& event ) -{ - wxFileDialog openDlg( this, _( "Open simulation workbook" ), getDefaultPath(), "", - WorkbookFileWildcard(), wxFD_OPEN | wxFD_FILE_MUST_EXIST ); - - if( openDlg.ShowModal() == wxID_CANCEL ) - return; - - loadWorkbook( openDlg.GetPath() ); -} - - -void SIM_PLOT_FRAME::menuSaveWorkbook( wxCommandEvent& event ) -{ - if( !m_workbook->IsModified() ) - return; - - wxString filename = m_simulator->Settings()->GetWorkbookFilename(); - - if( filename.IsEmpty() ) - { - menuSaveWorkbookAs( event ); - return; - } - - saveWorkbook( Prj().AbsolutePath( m_simulator->Settings()->GetWorkbookFilename() ) ); -} - - -void SIM_PLOT_FRAME::menuSaveWorkbookAs( wxCommandEvent& event ) -{ - wxFileDialog saveAsDlg( this, _( "Save Simulation Workbook As" ), getDefaultPath(), - getDefaultFilename(), WorkbookFileWildcard(), - wxFD_SAVE | wxFD_OVERWRITE_PROMPT ); - - if( saveAsDlg.ShowModal() == wxID_CANCEL ) - return; - - saveWorkbook( Prj().AbsolutePath( saveAsDlg.GetPath() ) ); -} - -void SIM_PLOT_FRAME::menuSaveImage( wxCommandEvent& event ) -{ - if( !GetCurrentPlot() ) - return; - - wxFileDialog saveDlg( this, _( "Save Plot as Image" ), "", "", PngFileWildcard(), - wxFD_SAVE | wxFD_OVERWRITE_PROMPT ); - - if( saveDlg.ShowModal() == wxID_CANCEL ) - return; - - GetCurrentPlot()->GetPlotWin()->SaveScreenshot( saveDlg.GetPath(), wxBITMAP_TYPE_PNG ); -} - - -void SIM_PLOT_FRAME::menuSaveCsv( wxCommandEvent& event ) -{ - if( !GetCurrentPlot() ) - return; - - const wxChar SEPARATOR = ';'; - - wxFileDialog saveDlg( this, _( "Save Plot Data" ), "", "", CsvFileWildcard(), - wxFD_SAVE | wxFD_OVERWRITE_PROMPT ); - - if( saveDlg.ShowModal() == wxID_CANCEL ) - return; - - wxFFile out( saveDlg.GetPath(), "wb" ); - - std::map traces = GetCurrentPlot()->GetTraces(); - - if( traces.size() == 0 ) - return; - - SIM_TYPE simType = m_circuitModel->GetSimType(); - - std::size_t rowCount = traces.begin()->second->GetDataX().size(); - - // write column header names on the first row - wxString xAxisName( m_simulator->GetXAxis( simType ) ); - out.Write( wxString::Format( wxT( "%s%c" ), xAxisName, SEPARATOR ) ); - - for( const auto& [name, trace] : traces ) - out.Write( wxString::Format( wxT( "%s%c" ), name, SEPARATOR ) ); - - out.Write( wxS( "\r\n" ) ); - - // write each row's numerical value - for ( std::size_t curRow=0; curRow < rowCount; curRow++ ) - { - double xAxisValue = traces.begin()->second->GetDataX().at( curRow ); - out.Write( wxString::Format( wxT( "%g%c" ), xAxisValue, SEPARATOR ) ); - - for( const auto& [name, trace] : traces ) - { - double yAxisValue = trace->GetDataY().at( curRow ); - out.Write( wxString::Format( wxT( "%g%c" ), yAxisValue, SEPARATOR ) ); - } - - out.Write( wxS( "\r\n" ) ); - } - - out.Close(); -} - - -void SIM_PLOT_FRAME::menuZoomIn( wxCommandEvent& event ) -{ - if( GetCurrentPlot() ) - GetCurrentPlot()->GetPlotWin()->ZoomIn(); -} - - -void SIM_PLOT_FRAME::menuZoomOut( wxCommandEvent& event ) -{ - if( GetCurrentPlot() ) - GetCurrentPlot()->GetPlotWin()->ZoomOut(); -} - - -void SIM_PLOT_FRAME::menuZoomFit( wxCommandEvent& event ) -{ - if( GetCurrentPlot() ) - GetCurrentPlot()->GetPlotWin()->Fit(); -} - - -void SIM_PLOT_FRAME::menuShowGrid( wxCommandEvent& event ) -{ - SIM_PLOT_PANEL* plot = GetCurrentPlot(); - - if( plot ) - plot->ShowGrid( !plot->IsGridShown() ); -} - - -void SIM_PLOT_FRAME::menuShowGridUpdate( wxUpdateUIEvent& event ) -{ - SIM_PLOT_PANEL* plot = GetCurrentPlot(); - - event.Check( plot ? plot->IsGridShown() : false ); -} - - -void SIM_PLOT_FRAME::menuShowLegend( wxCommandEvent& event ) -{ - SIM_PLOT_PANEL* plot = GetCurrentPlot(); - - if( plot ) - plot->ShowLegend( !plot->IsLegendShown() ); -} - - -void SIM_PLOT_FRAME::menuShowLegendUpdate( wxUpdateUIEvent& event ) -{ - SIM_PLOT_PANEL* plot = GetCurrentPlot(); - event.Check( plot ? plot->IsLegendShown() : false ); -} - - -void SIM_PLOT_FRAME::menuShowDotted( wxCommandEvent& event ) -{ - SIM_PLOT_PANEL* plot = GetCurrentPlot(); - - if( plot ) - plot->SetDottedCurrentPhase( !plot->GetDottedCurrentPhase() ); -} - - -void SIM_PLOT_FRAME::menuShowDottedUpdate( wxUpdateUIEvent& event ) -{ - SIM_PLOT_PANEL* plot = GetCurrentPlot(); - - event.Check( plot ? plot->GetDottedCurrentPhase() : false ); -} - - -void SIM_PLOT_FRAME::menuWhiteBackground( wxCommandEvent& event ) -{ - m_plotUseWhiteBg = not m_plotUseWhiteBg; + m_darkMode = !m_darkMode; // Rebuild the color list to plot traces - SIM_PLOT_COLORS::FillDefaultColorList( GetPlotBgOpt() ); + SIM_PLOT_COLORS::FillDefaultColorList( m_darkMode ); // Now send changes to all SIM_PLOT_PANEL for( size_t page = 0; page < m_workbook->GetPageCount(); page++ ) @@ -1425,30 +1105,6 @@ void SIM_PLOT_FRAME::menuWhiteBackground( wxCommandEvent& event ) } -void SIM_PLOT_FRAME::menuSimulateUpdate( wxUpdateUIEvent& event ) -{ - event.Enable( m_circuitModel->CommandToSimType( getCurrentSimCommand() ) != ST_UNKNOWN ); -} - - -void SIM_PLOT_FRAME::menuAddSignalsUpdate( wxUpdateUIEvent& event ) -{ - event.Enable( m_simFinished ); -} - - -void SIM_PLOT_FRAME::menuProbeUpdate( wxUpdateUIEvent& event ) -{ - event.Enable( m_simFinished ); -} - - -void SIM_PLOT_FRAME::menuTuneUpdate( wxUpdateUIEvent& event ) -{ - event.Enable( m_simFinished ); -} - - void SIM_PLOT_FRAME::onPlotClose( wxAuiNotebookEvent& event ) { } @@ -1541,16 +1197,7 @@ void SIM_PLOT_FRAME::onWorkbookClrModified( wxCommandEvent& event ) } -void SIM_PLOT_FRAME::onSimulate( wxCommandEvent& event ) -{ - if( m_simulator->IsRunning() ) - m_simulator->Stop(); - else - StartSimulation(); -} - - -void SIM_PLOT_FRAME::onSettings( wxCommandEvent& event ) +void SIM_PLOT_FRAME::EditSimCommand() { SIM_PANEL_BASE* plotPanelWindow = getCurrentPlotWindow(); DIALOG_SIM_COMMAND dlg( this, m_circuitModel, m_simulator->Settings() ); @@ -1617,128 +1264,6 @@ void SIM_PLOT_FRAME::onSettings( wxCommandEvent& event ) } -void SIM_PLOT_FRAME::onAddSignal( wxCommandEvent& event ) -{ - wxCHECK_RET( m_simFinished, wxT( "No simulation results available" ) ); - - SIM_PLOT_PANEL* plotPanel = GetCurrentPlot(); - - if( !plotPanel || !m_circuitModel || plotPanel->GetType() != m_circuitModel->GetSimType() ) - { - DisplayInfoMessage( this, _( "You need to run plot-providing simulation first." ) ); - return; - } - - DIALOG_SIGNAL_LIST dialog( this, m_circuitModel.get() ); - dialog.ShowModal(); -} - - -void SIM_PLOT_FRAME::onProbe( wxCommandEvent& event ) -{ - wxCHECK_RET( m_simFinished, wxT( "No simulation results available" ) ); - - if( m_schematicFrame == nullptr ) - return; - - wxWindow* blocking_dialog = m_schematicFrame->Kiway().GetBlockingDialog(); - - if( blocking_dialog ) - blocking_dialog->Close( true ); - - m_schematicFrame->GetToolManager()->RunAction( EE_ACTIONS::simProbe ); - m_schematicFrame->Raise(); -} - - -void SIM_PLOT_FRAME::onTune( wxCommandEvent& event ) -{ - wxCHECK_RET( m_simFinished, wxT( "No simulation results available" ) ); - - if( m_schematicFrame == nullptr ) - return; - - wxWindow* blocking_dialog = m_schematicFrame->Kiway().GetBlockingDialog(); - - if( blocking_dialog ) - blocking_dialog->Close( true ); - - m_schematicFrame->GetToolManager()->RunAction( EE_ACTIONS::simTune ); - m_schematicFrame->Raise(); -} - - -class NETLIST_VIEW_DIALOG : public DIALOG_SHIM -{ -public: - enum - { - MARGIN_LINE_NUMBERS - }; - - void onClose( wxCloseEvent& evt ) - { - wxPostEvent( this, wxCommandEvent( wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL ) ); - } - - NETLIST_VIEW_DIALOG( wxWindow* parent, const wxString& source) : - DIALOG_SHIM( parent, wxID_ANY, _( "SPICE Netlist" ), wxDefaultPosition, - wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER ) - { - wxStyledTextCtrl* textCtrl = new wxStyledTextCtrl( this, wxID_ANY ); - textCtrl->SetMinSize( wxSize( 600, 400 ) ); - - textCtrl->SetMarginWidth( MARGIN_LINE_NUMBERS, 50 ); - textCtrl->StyleSetForeground( wxSTC_STYLE_LINENUMBER, wxColour( 75, 75, 75 ) ); - textCtrl->StyleSetBackground( wxSTC_STYLE_LINENUMBER, wxColour( 220, 220, 220 ) ); - textCtrl->SetMarginType( MARGIN_LINE_NUMBERS, wxSTC_MARGIN_NUMBER ); - - wxFont fixedFont = KIUI::GetMonospacedUIFont(); - - for( int i = 0; i < wxSTC_STYLE_MAX; ++i ) - textCtrl->StyleSetFont( i, fixedFont ); - - textCtrl->StyleClearAll(); // Addresses a bug in wx3.0 where styles are not correctly set - - textCtrl->SetWrapMode( wxSTC_WRAP_WORD ); - - textCtrl->SetText( source ); - - textCtrl->SetLexer( wxSTC_LEX_SPICE ); - - wxBoxSizer* sizer = new wxBoxSizer( wxVERTICAL ); - sizer->Add( textCtrl, 1, wxEXPAND | wxALL, 5 ); - SetSizer( sizer ); - - Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( NETLIST_VIEW_DIALOG::onClose ), - nullptr, this ); - - m_scintillaTricks = std::make_unique( textCtrl, wxT( "{}" ), false ); - - finishDialogSettings(); - } - - std::unique_ptr m_scintillaTricks; -}; - - -void SIM_PLOT_FRAME::onShowNetlist( wxCommandEvent& event ) -{ - if( m_schematicFrame == nullptr || m_simulator == nullptr ) - return; - - wxString errors; - WX_STRING_REPORTER reporter( &errors ); - STRING_FORMATTER formatter; - - m_circuitModel->SetSimOptions( getCurrentOptions() ); - m_circuitModel->GetNetlist( &formatter, reporter ); - - NETLIST_VIEW_DIALOG dlg( this, errors.IsEmpty() ? wxString( formatter.GetString() ) : errors ); - dlg.ShowModal(); -} - - bool SIM_PLOT_FRAME::canCloseWindow( wxCloseEvent& aEvent ) { if( m_workbook->IsModified() ) @@ -1764,7 +1289,7 @@ bool SIM_PLOT_FRAME::canCloseWindow( wxCloseEvent& aEvent ) return HandleUnsavedChanges( this, msg, [&]() -> bool { - return saveWorkbook( Prj().AbsolutePath( fullFilename ) ); + return SaveWorkbook( Prj().AbsolutePath( fullFilename ) ); } ); } @@ -1839,16 +1364,100 @@ void SIM_PLOT_FRAME::onCursorUpdate( wxCommandEvent& event ) } +void SIM_PLOT_FRAME::setupUIConditions() +{ + EDA_BASE_FRAME::setupUIConditions(); + + ACTION_MANAGER* mgr = m_toolManager->GetActionManager(); + wxASSERT( mgr ); + + auto showGridCondition = + [this]( const SELECTION& aSel ) + { + SIM_PLOT_PANEL* plot = GetCurrentPlot(); + return plot && plot->IsGridShown(); + }; + + auto showLegendCondition = + [this]( const SELECTION& aSel ) + { + SIM_PLOT_PANEL* plot = GetCurrentPlot(); + return plot && plot->IsLegendShown(); + }; + + auto showDottedCondition = + [this]( const SELECTION& aSel ) + { + SIM_PLOT_PANEL* plot = GetCurrentPlot(); + return plot && plot->GetDottedSecondary(); + }; + + auto darkModePlotCondition = + [this]( const SELECTION& aSel ) + { + return m_darkMode; + }; + + auto haveCommand = + [this]( const SELECTION& aSel ) + { + return m_circuitModel->CommandToSimType( GetCurrentSimCommand() ) != ST_UNKNOWN; + }; + + auto simRunning = + [this]( const SELECTION& aSel ) + { + return m_simulator && m_simulator->IsRunning(); + }; + + auto simFinished = + [this]( const SELECTION& aSel ) + { + return m_simFinished; + }; + + auto havePlot = + [this]( const SELECTION& aSel ) + { + return GetCurrentPlot() != nullptr; + }; + +#define ENABLE( x ) ACTION_CONDITIONS().Enable( x ) +#define CHECK( x ) ACTION_CONDITIONS().Check( x ) + + mgr->SetConditions( EE_ACTIONS::openWorkbook, ENABLE( SELECTION_CONDITIONS::ShowAlways ) ); + mgr->SetConditions( EE_ACTIONS::saveWorkbook, ENABLE( SELECTION_CONDITIONS::ShowAlways ) ); + mgr->SetConditions( EE_ACTIONS::saveWorkbookAs, ENABLE( SELECTION_CONDITIONS::ShowAlways ) ); + + mgr->SetConditions( EE_ACTIONS::exportPlotAsPNG, ENABLE( havePlot ) ); + mgr->SetConditions( EE_ACTIONS::exportPlotAsCSV, ENABLE( havePlot ) ); + + mgr->SetConditions( EE_ACTIONS::toggleGrid, CHECK( showGridCondition ) ); + mgr->SetConditions( EE_ACTIONS::toggleLegend, CHECK( showLegendCondition ) ); + mgr->SetConditions( EE_ACTIONS::toggleDottedSecondary, CHECK( showDottedCondition ) ); + mgr->SetConditions( EE_ACTIONS::toggleDarkModePlots, CHECK( darkModePlotCondition ) ); + + mgr->SetConditions( EE_ACTIONS::simCommand, ENABLE( SELECTION_CONDITIONS::ShowAlways ) ); + mgr->SetConditions( EE_ACTIONS::runSimulation, ENABLE( haveCommand && !simRunning ) ); + mgr->SetConditions( EE_ACTIONS::stopSimulation, ENABLE( simRunning ) ); + mgr->SetConditions( EE_ACTIONS::addSignals, ENABLE( simFinished ) ); + mgr->SetConditions( EE_ACTIONS::simProbe, ENABLE( simFinished ) ); + mgr->SetConditions( EE_ACTIONS::simTune, ENABLE( simFinished ) ); + mgr->SetConditions( EE_ACTIONS::showNetlist, ENABLE( SELECTION_CONDITIONS::ShowAlways ) ); + +#undef CHECK +#undef ENABLE +} + + void SIM_PLOT_FRAME::onSimStarted( wxCommandEvent& aEvent ) { - m_toolBar->SetToolNormalBitmap( ID_SIM_RUN, KiBitmap( BITMAPS::sim_stop ) ); SetCursor( wxCURSOR_ARROWWAIT ); } void SIM_PLOT_FRAME::onSimFinished( wxCommandEvent& aEvent ) { - m_toolBar->SetToolNormalBitmap( ID_SIM_RUN, KiBitmap( BITMAPS::sim_run ) ); SetCursor( wxCURSOR_ARROW ); SIM_TYPE simType = m_circuitModel->GetSimType(); @@ -2061,13 +1670,9 @@ void SIM_PLOT_FRAME::CURSOR_CONTEXT_MENU::onMenuEvent( wxMenuEvent& aEvent ) } -void SIM_PLOT_FRAME::menuExit( wxCommandEvent& event ) +void SIM_PLOT_FRAME::onExit( wxCommandEvent& event ) { - if( event.GetId() == wxID_EXIT ) - Kiway().OnKiCadExit(); - - if( event.GetId() == wxID_CLOSE ) - Close( false ); + Kiway().OnKiCadExit(); } diff --git a/eeschema/sim/sim_plot_frame.h b/eeschema/sim/sim_plot_frame.h index 21e0f5ce51..a4683f031b 100644 --- a/eeschema/sim/sim_plot_frame.h +++ b/eeschema/sim/sim_plot_frame.h @@ -1,8 +1,8 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2016-2022 CERN - * Copyright (C) 2017-2022 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2016-2023 CERN + * Copyright (C) 2017-2023 KiCad Developers, see AUTHORS.txt for contributors. * * @author Tomasz Wlostowski * @author Maciej Suminski @@ -29,8 +29,8 @@ #define __SIM_PLOT_FRAME__ -#include "sim_plot_frame_base.h" -#include "sim_types.h" +#include +#include #include #include @@ -48,16 +48,14 @@ class SPICE_SIMULATOR; class SPICE_SIMULATOR_SETTINGS; class NGSPICE_CIRCUIT_MODEL; -#include "sim_plot_panel.h" -#include "sim_panel_base.h" -#include "sim_workbook.h" +#include +#include +#include class SIM_THREAD_REPORTER; class TUNER_SLIDER; -/** - * Implementing SIM_PLOT_FRAME_BASE - */ + class SIM_PLOT_FRAME : public SIM_PLOT_FRAME_BASE { public: @@ -75,6 +73,12 @@ public: */ SIM_PANEL_BASE* NewPlotPanel( wxString aSimCommand, int aSimOptions ); + /** + * Shows a dialog for editing the current tab's simulation command, or creating a new tab + * with a different simulation command type. + */ + void EditSimCommand(); + /** * Add a voltage plot for a given net name. * @@ -126,10 +130,27 @@ public: const NGSPICE_CIRCUIT_MODEL* GetExporter() const; /** - * @return the current background option for plotting. - * false for drak bg, true for clear bg + * Toggle dark-mode of the plot. */ - bool GetPlotBgOpt() const { return m_plotUseWhiteBg; } + void ToggleDarkModePlots(); + + void ReCreateHToolbar(); + + /** + * Load plot settings from a file. + * + * @param aPath is the file name. + * @return True if successful. + */ + bool LoadWorkbook( const wxString& aPath ); + + /** + * Save plot settings to a file. + * + * @param aPath is the file name. + * @return True if successful. + */ + bool SaveWorkbook( const wxString& aPath ); void LoadSettings( APP_SETTINGS_BASE* aCfg ) override; @@ -137,10 +158,37 @@ public: WINDOW_SETTINGS* GetWindowSettings( APP_SETTINGS_BASE* aCfg ) override; + SCH_EDIT_FRAME* GetSchematicFrame() const { return m_schematicFrame; } + + std::shared_ptr GetCircuitModel() const { return m_circuitModel; } + + std::shared_ptr GetSimulator() const { return m_simulator; } + + wxString GetCurrentSimCommand() const + { + if( getCurrentPlotWindow() == nullptr ) + return m_circuitModel->GetSheetSimCommand(); + else + return m_workbook->GetSimCommand( getCurrentPlotWindow() ); + } + + int GetCurrentOptions() const + { + if( getCurrentPlotWindow() == nullptr ) + return m_circuitModel->GetSimOptions(); + else + return m_workbook->GetSimOptions( getCurrentPlotWindow() ); + } + // Simulator doesn't host a tool framework wxWindow* GetToolCanvas() const override { return nullptr; } private: + void setupTools(); + void doReCreateMenuBar() override; + + void setupUIConditions() override; + /** * Load the currently active workbook stored in the project settings. If there is none, * generate a filename for the currently active workbook and store it in the project settings. @@ -152,11 +200,6 @@ private: */ void updateTitle(); - /** - * Give icons to menuitems of the main menubar. - */ - void setIconsForMenuItems(); - /** * Add a new plot to the current panel. * @@ -195,32 +238,6 @@ private: */ void applyTuners(); - /** - * Load plot settings from a file. - * - * @param aPath is the file name. - * @return True if successful. - */ - bool loadWorkbook( const wxString& aPath ); - - /** - * Save plot settings to a file. - * - * @param aPath is the file name. - * @return True if successful. - */ - bool saveWorkbook( const wxString& aPath ); - - /** - * Return the default filename (with extension) to be used in file browser dialog. - */ - wxString getDefaultFilename(); - - /** - * Return the default path to be used in file browser dialog. - */ - wxString getDefaultPath(); - /** * Return the currently opened plot panel (or NULL if there is none). */ @@ -232,55 +249,11 @@ private: /** * */ - wxString getCurrentSimCommand() const - { - if( getCurrentPlotWindow() == nullptr ) - return m_circuitModel->GetSheetSimCommand(); - else - return m_workbook->GetSimCommand( getCurrentPlotWindow() ); - } - - int getCurrentOptions() const - { - if( getCurrentPlotWindow() == nullptr ) - return m_circuitModel->GetSimOptions(); - else - return m_workbook->GetSimOptions( getCurrentPlotWindow() ); - } - /** * Return X axis for a given simulation type. */ SIM_PLOT_TYPE getXAxisType( SIM_TYPE aType ) const; - // Menu handlers - void menuNewPlot( wxCommandEvent& aEvent ) override; - void menuOpenWorkbook( wxCommandEvent& event ) override; - void menuSaveWorkbook( wxCommandEvent& event ) override; - void menuSaveWorkbookAs( wxCommandEvent& event ) override; - void menuExit( wxCommandEvent& event ) override; - void menuSaveImage( wxCommandEvent& event ) override; - void menuSaveCsv( wxCommandEvent& event ) override; - void menuZoomIn( wxCommandEvent& event ) override; - void menuZoomOut( wxCommandEvent& event ) override; - void menuZoomFit( wxCommandEvent& event ) override; - void menuShowGrid( wxCommandEvent& event ) override; - void menuShowGridUpdate( wxUpdateUIEvent& event ) override; - void menuShowLegend( wxCommandEvent& event ) override; - void menuShowLegendUpdate( wxUpdateUIEvent& event ) override; - void menuShowDotted( wxCommandEvent& event ) override; - void menuShowDottedUpdate( wxUpdateUIEvent& event ) override; - void menuWhiteBackground( wxCommandEvent& event ) override; - void menuShowWhiteBackgroundUpdate( wxUpdateUIEvent& event ) override - { - event.Check( m_plotUseWhiteBg ); - } - - void menuSimulateUpdate( wxUpdateUIEvent& event ) override; - void menuAddSignalsUpdate( wxUpdateUIEvent& event ) override; - void menuProbeUpdate( wxUpdateUIEvent& event ) override; - void menuTuneUpdate( wxUpdateUIEvent& event ) override; - // Event handlers void onPlotClose( wxAuiNotebookEvent& event ) override; void onPlotClosed( wxAuiNotebookEvent& event ) override; @@ -295,13 +268,6 @@ private: void onWorkbookModified( wxCommandEvent& event ); void onWorkbookClrModified( wxCommandEvent& event ); - void onSimulate( wxCommandEvent& event ); - void onSettings( wxCommandEvent& event ); - void onAddSignal( wxCommandEvent& event ); - void onProbe( wxCommandEvent& event ); - void onTune( wxCommandEvent& event ); - void onShowNetlist( wxCommandEvent& event ); - bool canCloseWindow( wxCloseEvent& aEvent ) override; void doCloseWindow() override; @@ -311,27 +277,14 @@ private: void onSimStarted( wxCommandEvent& aEvent ); void onSimFinished( wxCommandEvent& aEvent ); + void onExit( wxCommandEvent& event ); + // adjust the sash dimension of splitter windows after reading // the config settings // must be called after the config settings are read, and once the // frame is initialized (end of the Ctor) void setSubWindowsSashSize(); - // Toolbar buttons - wxToolBarToolBase* m_toolSimulate; - wxToolBarToolBase* m_toolAddSignals; - wxToolBarToolBase* m_toolProbe; - wxToolBarToolBase* m_toolTune; - wxToolBarToolBase* m_toolSettings; - - SCH_EDIT_FRAME* m_schematicFrame; - std::shared_ptr m_circuitModel; - std::shared_ptr m_simulator; - SIM_THREAD_REPORTER* m_reporter; - - ///< List of currently displayed tuners - std::list m_tuners; - enum CONTEXT_MENU_EVENTS { REMOVE_SIGNAL = 944, @@ -365,21 +318,29 @@ private: SIM_PLOT_FRAME* m_plotFrame; }; +private: + SCH_EDIT_FRAME* m_schematicFrame; + std::shared_ptr m_circuitModel; + std::shared_ptr m_simulator; + SIM_THREAD_REPORTER* m_reporter; + + std::list m_tuners; + ///< Panel that was used as the most recent one for simulations - SIM_PANEL_BASE* m_lastSimPlot; + SIM_PANEL_BASE* m_lastSimPlot; ///< imagelists used to add a small colored icon to signal names ///< and cursors name, the same color as the corresponding signal traces - wxImageList* m_signalsIconColorList; + wxImageList* m_signalsIconColorList; // Variables for temporary storage: - int m_splitterLeftRightSashPosition; - int m_splitterPlotAndConsoleSashPosition; - int m_splitterSignalsSashPosition; - int m_splitterTuneValuesSashPosition; - bool m_plotUseWhiteBg; - unsigned int m_plotNumber; - bool m_simFinished; + int m_splitterLeftRightSashPosition; + int m_splitterPlotAndConsoleSashPosition; + int m_splitterSignalsSashPosition; + int m_splitterTuneValuesSashPosition; + bool m_darkMode; + unsigned int m_plotNumber; + bool m_simFinished; }; // Commands diff --git a/eeschema/sim/sim_plot_frame_base.cpp b/eeschema/sim/sim_plot_frame_base.cpp index 022850347e..7fd40bbd3d 100644 --- a/eeschema/sim/sim_plot_frame_base.cpp +++ b/eeschema/sim/sim_plot_frame_base.cpp @@ -5,6 +5,8 @@ // PLEASE DO *NOT* EDIT THIS FILE! /////////////////////////////////////////////////////////////////////////// +#include "tool/action_toolbar.h" + #include "sim_plot_frame_base.h" /////////////////////////////////////////////////////////////////////////// @@ -13,115 +15,9 @@ SIM_PLOT_FRAME_BASE::SIM_PLOT_FRAME_BASE( wxWindow* parent, wxWindowID id, const { this->SetSizeHints( wxSize( -1,-1 ), wxDefaultSize ); - m_mainMenu = new wxMenuBar( 0 ); - m_fileMenu = new wxMenu(); - wxMenuItem* m_newPlot; - m_newPlot = new wxMenuItem( m_fileMenu, wxID_NEW, wxString( _("New Plot") ) , wxEmptyString, wxITEM_NORMAL ); - m_fileMenu->Append( m_newPlot ); - - m_fileMenu->AppendSeparator(); - - wxMenuItem* m_openWorkbook; - m_openWorkbook = new wxMenuItem( m_fileMenu, wxID_OPEN, wxString( _("Open Workbook...") ) , wxEmptyString, wxITEM_NORMAL ); - m_fileMenu->Append( m_openWorkbook ); - - wxMenuItem* m_saveWorkbook; - m_saveWorkbook = new wxMenuItem( m_fileMenu, wxID_SAVE, wxString( _("Save Workbook") ) , wxEmptyString, wxITEM_NORMAL ); - m_fileMenu->Append( m_saveWorkbook ); - - wxMenuItem* m_saveWorkbookAs; - m_saveWorkbookAs = new wxMenuItem( m_fileMenu, wxID_SAVEAS, wxString( _("Save Workbook As...") ) + wxT('\t') + wxT("SHIFT+CTRL+S"), wxEmptyString, wxITEM_NORMAL ); - m_fileMenu->Append( m_saveWorkbookAs ); - - m_fileMenu->AppendSeparator(); - - wxMenuItem* m_saveImage; - m_saveImage = new wxMenuItem( m_fileMenu, ID_SAVE_AS_IMAGE, wxString( _("Export Current Plot as PNG...") ) , wxEmptyString, wxITEM_NORMAL ); - m_fileMenu->Append( m_saveImage ); - - wxMenuItem* m_saveCsv; - m_saveCsv = new wxMenuItem( m_fileMenu, ID_SAVE_AS_CSV, wxString( _("Export Current Plot as CSV...") ) , wxEmptyString, wxITEM_NORMAL ); - m_fileMenu->Append( m_saveCsv ); - - m_fileMenu->AppendSeparator(); - - wxMenuItem* m_exitSim; - m_exitSim = new wxMenuItem( m_fileMenu, wxID_CLOSE, wxString( _("Close") ) + wxT('\t') + wxT("CTRL+W"), wxEmptyString, wxITEM_NORMAL ); - m_fileMenu->Append( m_exitSim ); - - m_mainMenu->Append( m_fileMenu, _("File") ); - - m_simulationMenu = new wxMenu(); - m_runSimulation = new wxMenuItem( m_simulationMenu, ID_MENU_RUN_SIM, wxString( _("Run Simulation") ) + wxT('\t') + wxT("Ctrl+R"), wxEmptyString, wxITEM_NORMAL ); - m_simulationMenu->Append( m_runSimulation ); - m_runSimulation->Enable( false ); - - m_simulationMenu->AppendSeparator(); - - m_addSignals = new wxMenuItem( m_simulationMenu, ID_MENU_ADD_SIGNAL, wxString( _("Add Signals...") ) + wxT('\t') + wxT("Ctrl+A"), wxEmptyString, wxITEM_NORMAL ); - m_simulationMenu->Append( m_addSignals ); - m_addSignals->Enable( false ); - - m_probeSignals = new wxMenuItem( m_simulationMenu, ID_MENU_PROBE_SIGNALS, wxString( _("Probe from schematics") ) + wxT('\t') + wxT("Ctrl+P"), wxEmptyString, wxITEM_NORMAL ); - m_simulationMenu->Append( m_probeSignals ); - m_probeSignals->Enable( false ); - - m_tuneValue = new wxMenuItem( m_simulationMenu, ID_MENU_TUNE_SIGNALS, wxString( _("Tune Component Value") ) + wxT('\t') + wxT("Ctrl+T"), wxEmptyString, wxITEM_NORMAL ); - m_simulationMenu->Append( m_tuneValue ); - m_tuneValue->Enable( false ); - - m_simulationMenu->AppendSeparator(); - - m_showNetlist = new wxMenuItem( m_simulationMenu, ID_MENU_SHOW_NETLIST, wxString( _("Show SPICE Netlist...") ) , _("Shows current simulation's netlist. Useful for debugging SPICE errors."), wxITEM_NORMAL ); - m_simulationMenu->Append( m_showNetlist ); - - m_simulationMenu->AppendSeparator(); - - m_boardAdapter = new wxMenuItem( m_simulationMenu, ID_MENU_SET_SIMUL, wxString( _("Settings...") ) , wxEmptyString, wxITEM_NORMAL ); - m_simulationMenu->Append( m_boardAdapter ); - - m_mainMenu->Append( m_simulationMenu, _("Simulation") ); - - m_viewMenu = new wxMenu(); - wxMenuItem* m_zoomIn; - m_zoomIn = new wxMenuItem( m_viewMenu, wxID_ZOOM_IN, wxString( _("Zoom In") ) , wxEmptyString, wxITEM_NORMAL ); - m_viewMenu->Append( m_zoomIn ); - - wxMenuItem* m_zoomOut; - m_zoomOut = new wxMenuItem( m_viewMenu, wxID_ZOOM_OUT, wxString( _("Zoom Out") ) , wxEmptyString, wxITEM_NORMAL ); - m_viewMenu->Append( m_zoomOut ); - - wxMenuItem* m_zoomFit; - m_zoomFit = new wxMenuItem( m_viewMenu, wxID_ZOOM_FIT, wxString( _("Fit on Screen") ) , wxEmptyString, wxITEM_NORMAL ); - m_viewMenu->Append( m_zoomFit ); - - m_viewMenu->AppendSeparator(); - - wxMenuItem* m_showGrid; - m_showGrid = new wxMenuItem( m_viewMenu, ID_MENU_SHOW_GRID, wxString( _("Show &Grid") ) , wxEmptyString, wxITEM_CHECK ); - m_viewMenu->Append( m_showGrid ); - - wxMenuItem* m_showLegend; - m_showLegend = new wxMenuItem( m_viewMenu, ID_MENU_SHOW_LEGEND, wxString( _("Show &Legend") ) , wxEmptyString, wxITEM_CHECK ); - m_viewMenu->Append( m_showLegend ); - - m_viewMenu->AppendSeparator(); - - wxMenuItem* m_showDotted; - m_showDotted = new wxMenuItem( m_viewMenu, ID_MENU_DOTTED, wxString( _("Dotted Current/Phase") ) , wxEmptyString, wxITEM_CHECK ); - m_viewMenu->Append( m_showDotted ); - - wxMenuItem* m_showWhiteBackground; - m_showWhiteBackground = new wxMenuItem( m_viewMenu, ID_MENU_WHITE_BG, wxString( _("White Background") ) , wxEmptyString, wxITEM_CHECK ); - m_viewMenu->Append( m_showWhiteBackground ); - - m_mainMenu->Append( m_viewMenu, _("View") ); - - this->SetMenuBar( m_mainMenu ); - m_sizerMain = new wxBoxSizer( wxVERTICAL ); - m_toolBar = new wxToolBar( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTB_FLAT|wxTB_HORIZONTAL|wxTB_TEXT ); + m_toolBar = new ACTION_TOOLBAR( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxAUI_TB_DEFAULT_STYLE|wxAUI_TB_HORZ_LAYOUT|wxAUI_TB_PLAIN_BACKGROUND ); m_toolBar->Realize(); m_sizerMain->Add( m_toolBar, 0, wxEXPAND, 5 ); @@ -276,28 +172,6 @@ SIM_PLOT_FRAME_BASE::SIM_PLOT_FRAME_BASE( wxWindow* parent, wxWindowID id, const this->Centre( wxBOTH ); // Connect Events - m_fileMenu->Bind(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( SIM_PLOT_FRAME_BASE::menuNewPlot ), this, m_newPlot->GetId()); - m_fileMenu->Bind(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( SIM_PLOT_FRAME_BASE::menuOpenWorkbook ), this, m_openWorkbook->GetId()); - m_fileMenu->Bind(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( SIM_PLOT_FRAME_BASE::menuSaveWorkbook ), this, m_saveWorkbook->GetId()); - m_fileMenu->Bind(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( SIM_PLOT_FRAME_BASE::menuSaveWorkbookAs ), this, m_saveWorkbookAs->GetId()); - m_fileMenu->Bind(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( SIM_PLOT_FRAME_BASE::menuSaveImage ), this, m_saveImage->GetId()); - m_fileMenu->Bind(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( SIM_PLOT_FRAME_BASE::menuSaveCsv ), this, m_saveCsv->GetId()); - m_fileMenu->Bind(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( SIM_PLOT_FRAME_BASE::menuExit ), this, m_exitSim->GetId()); - this->Connect( m_runSimulation->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler( SIM_PLOT_FRAME_BASE::menuSimulateUpdate ) ); - this->Connect( m_addSignals->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler( SIM_PLOT_FRAME_BASE::menuAddSignalsUpdate ) ); - this->Connect( m_probeSignals->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler( SIM_PLOT_FRAME_BASE::menuProbeUpdate ) ); - this->Connect( m_tuneValue->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler( SIM_PLOT_FRAME_BASE::menuTuneUpdate ) ); - m_viewMenu->Bind(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( SIM_PLOT_FRAME_BASE::menuZoomIn ), this, m_zoomIn->GetId()); - m_viewMenu->Bind(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( SIM_PLOT_FRAME_BASE::menuZoomOut ), this, m_zoomOut->GetId()); - m_viewMenu->Bind(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( SIM_PLOT_FRAME_BASE::menuZoomFit ), this, m_zoomFit->GetId()); - m_viewMenu->Bind(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( SIM_PLOT_FRAME_BASE::menuShowGrid ), this, m_showGrid->GetId()); - this->Connect( m_showGrid->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler( SIM_PLOT_FRAME_BASE::menuShowGridUpdate ) ); - m_viewMenu->Bind(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( SIM_PLOT_FRAME_BASE::menuShowLegend ), this, m_showLegend->GetId()); - this->Connect( m_showLegend->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler( SIM_PLOT_FRAME_BASE::menuShowLegendUpdate ) ); - m_viewMenu->Bind(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( SIM_PLOT_FRAME_BASE::menuShowDotted ), this, m_showDotted->GetId()); - this->Connect( m_showDotted->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler( SIM_PLOT_FRAME_BASE::menuShowDottedUpdate ) ); - m_viewMenu->Bind(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( SIM_PLOT_FRAME_BASE::menuWhiteBackground ), this, m_showWhiteBackground->GetId()); - this->Connect( m_showWhiteBackground->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler( SIM_PLOT_FRAME_BASE::menuShowWhiteBackgroundUpdate ) ); m_workbook->Connect( wxEVT_COMMAND_AUINOTEBOOK_END_DRAG, wxAuiNotebookEventHandler( SIM_PLOT_FRAME_BASE::onPlotDragged ), NULL, this ); m_workbook->Connect( wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED, wxAuiNotebookEventHandler( SIM_PLOT_FRAME_BASE::onPlotChanged ), NULL, this ); m_workbook->Connect( wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSE, wxAuiNotebookEventHandler( SIM_PLOT_FRAME_BASE::onPlotClose ), NULL, this ); @@ -310,14 +184,6 @@ SIM_PLOT_FRAME_BASE::SIM_PLOT_FRAME_BASE( wxWindow* parent, wxWindowID id, const SIM_PLOT_FRAME_BASE::~SIM_PLOT_FRAME_BASE() { // Disconnect Events - this->Disconnect( ID_MENU_RUN_SIM, wxEVT_UPDATE_UI, wxUpdateUIEventHandler( SIM_PLOT_FRAME_BASE::menuSimulateUpdate ) ); - this->Disconnect( ID_MENU_ADD_SIGNAL, wxEVT_UPDATE_UI, wxUpdateUIEventHandler( SIM_PLOT_FRAME_BASE::menuAddSignalsUpdate ) ); - this->Disconnect( ID_MENU_PROBE_SIGNALS, wxEVT_UPDATE_UI, wxUpdateUIEventHandler( SIM_PLOT_FRAME_BASE::menuProbeUpdate ) ); - this->Disconnect( ID_MENU_TUNE_SIGNALS, wxEVT_UPDATE_UI, wxUpdateUIEventHandler( SIM_PLOT_FRAME_BASE::menuTuneUpdate ) ); - this->Disconnect( ID_MENU_SHOW_GRID, wxEVT_UPDATE_UI, wxUpdateUIEventHandler( SIM_PLOT_FRAME_BASE::menuShowGridUpdate ) ); - this->Disconnect( ID_MENU_SHOW_LEGEND, wxEVT_UPDATE_UI, wxUpdateUIEventHandler( SIM_PLOT_FRAME_BASE::menuShowLegendUpdate ) ); - this->Disconnect( ID_MENU_DOTTED, wxEVT_UPDATE_UI, wxUpdateUIEventHandler( SIM_PLOT_FRAME_BASE::menuShowDottedUpdate ) ); - this->Disconnect( ID_MENU_WHITE_BG, wxEVT_UPDATE_UI, wxUpdateUIEventHandler( SIM_PLOT_FRAME_BASE::menuShowWhiteBackgroundUpdate ) ); m_workbook->Disconnect( wxEVT_COMMAND_AUINOTEBOOK_END_DRAG, wxAuiNotebookEventHandler( SIM_PLOT_FRAME_BASE::onPlotDragged ), NULL, this ); m_workbook->Disconnect( wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED, wxAuiNotebookEventHandler( SIM_PLOT_FRAME_BASE::onPlotChanged ), NULL, this ); m_workbook->Disconnect( wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSE, wxAuiNotebookEventHandler( SIM_PLOT_FRAME_BASE::onPlotClose ), NULL, this ); diff --git a/eeschema/sim/sim_plot_frame_base.fbp b/eeschema/sim/sim_plot_frame_base.fbp index 80e0467fa9..6a72cbab7a 100644 --- a/eeschema/sim/sim_plot_frame_base.fbp +++ b/eeschema/sim/sim_plot_frame_base.fbp @@ -57,367 +57,16 @@ SIM_PLOT_FRAME wxTAB_TRAVERSAL 1 - - - - 1 - 1 - - - 0 - wxID_ANY - - - m_mainMenu - protected - - - - ; - - - - - - File - m_fileMenu - protected - - - 0 - 1 - - wxID_NEW - wxITEM_NORMAL - New Plot - m_newPlot - none - - - menuNewPlot - - - m_separator3 - none - - - - 0 - 1 - - wxID_OPEN - wxITEM_NORMAL - Open Workbook... - m_openWorkbook - none - - - menuOpenWorkbook - - - - 0 - 1 - - wxID_SAVE - wxITEM_NORMAL - Save Workbook - m_saveWorkbook - none - - - menuSaveWorkbook - - - - 0 - 1 - - wxID_SAVEAS - wxITEM_NORMAL - Save Workbook As... - m_saveWorkbookAs - none - SHIFT+CTRL+S - - menuSaveWorkbookAs - - - m_separator1 - none - - - - 0 - 1 - - ID_SAVE_AS_IMAGE - wxITEM_NORMAL - Export Current Plot as PNG... - m_saveImage - none - - - menuSaveImage - - - - 0 - 1 - - ID_SAVE_AS_CSV - wxITEM_NORMAL - Export Current Plot as CSV... - m_saveCsv - none - - - menuSaveCsv - - - m_separator4 - none - - - - 0 - 1 - - wxID_CLOSE - wxITEM_NORMAL - Close - m_exitSim - none - CTRL+W - - menuExit - - - - Simulation - m_simulationMenu - protected - - - 0 - 0 - - ID_MENU_RUN_SIM - wxITEM_NORMAL - Run Simulation - m_runSimulation - protected - Ctrl+R - - menuSimulateUpdate - - - m_separator31 - none - - - - 0 - 0 - - ID_MENU_ADD_SIGNAL - wxITEM_NORMAL - Add Signals... - m_addSignals - protected - Ctrl+A - - menuAddSignalsUpdate - - - - 0 - 0 - - ID_MENU_PROBE_SIGNALS - wxITEM_NORMAL - Probe from schematics - m_probeSignals - protected - Ctrl+P - - menuProbeUpdate - - - - 0 - 0 - - ID_MENU_TUNE_SIGNALS - wxITEM_NORMAL - Tune Component Value - m_tuneValue - protected - Ctrl+T - - menuTuneUpdate - - - m_separator7 - none - - - - 0 - 1 - Shows current simulation's netlist. Useful for debugging SPICE errors. - ID_MENU_SHOW_NETLIST - wxITEM_NORMAL - Show SPICE Netlist... - m_showNetlist - protected - - - - - m_separator41 - none - - - - 0 - 1 - - ID_MENU_SET_SIMUL - wxITEM_NORMAL - Settings... - m_boardAdapter - protected - - - - - - View - m_viewMenu - protected - - - 0 - 1 - - wxID_ZOOM_IN - wxITEM_NORMAL - Zoom In - m_zoomIn - none - - - menuZoomIn - - - - 0 - 1 - - wxID_ZOOM_OUT - wxITEM_NORMAL - Zoom Out - m_zoomOut - none - - - menuZoomOut - - - - 0 - 1 - - wxID_ZOOM_FIT - wxITEM_NORMAL - Fit on Screen - m_zoomFit - none - - - menuZoomFit - - - m_separator2 - none - - - - 0 - 1 - - ID_MENU_SHOW_GRID - wxITEM_CHECK - Show &Grid - m_showGrid - none - - - menuShowGrid - menuShowGridUpdate - - - - 0 - 1 - - ID_MENU_SHOW_LEGEND - wxITEM_CHECK - Show &Legend - m_showLegend - none - - - menuShowLegend - menuShowLegendUpdate - - - m_separator21 - none - - - - 0 - 1 - - ID_MENU_DOTTED - wxITEM_CHECK - Dotted Current/Phase - m_showDotted - none - - - menuShowDotted - menuShowDottedUpdate - - - - 0 - 1 - - ID_MENU_WHITE_BG - wxITEM_CHECK - White Background - m_showWhiteBackground - none - - - menuWhiteBackground - menuShowWhiteBackgroundUpdate - - - m_sizerMain wxVERTICAL protected - + 5 wxEXPAND 0 - + 1 1 1 @@ -446,6 +95,7 @@ 0 0 wxID_ANY + 0 0 @@ -466,10 +116,12 @@ 5 1 - wxTB_FLAT|wxTB_HORIZONTAL|wxTB_TEXT - + wxAUI_TB_DEFAULT_STYLE|wxAUI_TB_HORZ_LAYOUT|wxAUI_TB_PLAIN_BACKGROUND + ACTION_TOOLBAR; tool/action_toolbar.h; forward_declare + label 0 + 0 diff --git a/eeschema/sim/sim_plot_frame_base.h b/eeschema/sim/sim_plot_frame_base.h index d1cbdbfa42..568cc4e789 100644 --- a/eeschema/sim/sim_plot_frame_base.h +++ b/eeschema/sim/sim_plot_frame_base.h @@ -10,20 +10,18 @@ #include #include #include +class ACTION_TOOLBAR; class wxListView; #include "sim_workbook.h" #include "kiway_player.h" -#include -#include -#include -#include -#include #include +#include +#include #include #include #include -#include +#include #include #include #include @@ -35,18 +33,6 @@ class wxListView; /////////////////////////////////////////////////////////////////////////// -#define ID_SAVE_AS_IMAGE 1000 -#define ID_SAVE_AS_CSV 1001 -#define ID_MENU_RUN_SIM 1002 -#define ID_MENU_ADD_SIGNAL 1003 -#define ID_MENU_PROBE_SIGNALS 1004 -#define ID_MENU_TUNE_SIGNALS 1005 -#define ID_MENU_SHOW_NETLIST 1006 -#define ID_MENU_SET_SIMUL 1007 -#define ID_MENU_SHOW_GRID 1008 -#define ID_MENU_SHOW_LEGEND 1009 -#define ID_MENU_DOTTED 1010 -#define ID_MENU_WHITE_BG 1011 /////////////////////////////////////////////////////////////////////////////// /// Class SIM_PLOT_FRAME_BASE @@ -56,18 +42,8 @@ class SIM_PLOT_FRAME_BASE : public KIWAY_PLAYER private: protected: - wxMenuBar* m_mainMenu; - wxMenu* m_fileMenu; - wxMenu* m_simulationMenu; - wxMenuItem* m_runSimulation; - wxMenuItem* m_addSignals; - wxMenuItem* m_probeSignals; - wxMenuItem* m_tuneValue; - wxMenuItem* m_showNetlist; - wxMenuItem* m_boardAdapter; - wxMenu* m_viewMenu; wxBoxSizer* m_sizerMain; - wxToolBar* m_toolBar; + ACTION_TOOLBAR* m_toolBar; wxSplitterWindow* m_splitterLeftRight; wxPanel* m_panelLeft; wxBoxSizer* m_sizer11; @@ -94,28 +70,6 @@ class SIM_PLOT_FRAME_BASE : public KIWAY_PLAYER wxBoxSizer* m_tuneSizer; // Virtual event handlers, override them in your derived class - virtual void menuNewPlot( wxCommandEvent& event ) { event.Skip(); } - virtual void menuOpenWorkbook( wxCommandEvent& event ) { event.Skip(); } - virtual void menuSaveWorkbook( wxCommandEvent& event ) { event.Skip(); } - virtual void menuSaveWorkbookAs( wxCommandEvent& event ) { event.Skip(); } - virtual void menuSaveImage( wxCommandEvent& event ) { event.Skip(); } - virtual void menuSaveCsv( wxCommandEvent& event ) { event.Skip(); } - virtual void menuExit( wxCommandEvent& event ) { event.Skip(); } - virtual void menuSimulateUpdate( wxUpdateUIEvent& event ) { event.Skip(); } - virtual void menuAddSignalsUpdate( wxUpdateUIEvent& event ) { event.Skip(); } - virtual void menuProbeUpdate( wxUpdateUIEvent& event ) { event.Skip(); } - virtual void menuTuneUpdate( wxUpdateUIEvent& event ) { event.Skip(); } - virtual void menuZoomIn( wxCommandEvent& event ) { event.Skip(); } - virtual void menuZoomOut( wxCommandEvent& event ) { event.Skip(); } - virtual void menuZoomFit( wxCommandEvent& event ) { event.Skip(); } - virtual void menuShowGrid( wxCommandEvent& event ) { event.Skip(); } - virtual void menuShowGridUpdate( wxUpdateUIEvent& event ) { event.Skip(); } - virtual void menuShowLegend( wxCommandEvent& event ) { event.Skip(); } - virtual void menuShowLegendUpdate( wxUpdateUIEvent& event ) { event.Skip(); } - virtual void menuShowDotted( wxCommandEvent& event ) { event.Skip(); } - virtual void menuShowDottedUpdate( wxUpdateUIEvent& event ) { event.Skip(); } - virtual void menuWhiteBackground( wxCommandEvent& event ) { event.Skip(); } - virtual void menuShowWhiteBackgroundUpdate( wxUpdateUIEvent& event ) { event.Skip(); } virtual void onPlotDragged( wxAuiNotebookEvent& event ) { event.Skip(); } virtual void onPlotChanged( wxAuiNotebookEvent& event ) { event.Skip(); } virtual void onPlotClose( wxAuiNotebookEvent& event ) { event.Skip(); } diff --git a/eeschema/sim/sim_plot_panel.cpp b/eeschema/sim/sim_plot_panel.cpp index fe43ad13a6..6777760a45 100644 --- a/eeschema/sim/sim_plot_panel.cpp +++ b/eeschema/sim/sim_plot_panel.cpp @@ -1,8 +1,8 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2016 CERN - * Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2016-2023 CERN + * Copyright (C) 2021-2023 KiCad Developers, see AUTHORS.txt for contributors. * * @author Tomasz Wlostowski * @author Maciej Suminski @@ -302,14 +302,13 @@ void CURSOR::UpdateReference() SIM_PLOT_PANEL::SIM_PLOT_PANEL( const wxString& aCommand, int aOptions, wxWindow* parent, - SIM_PLOT_FRAME* aMainFrame, wxWindowID id, const wxPoint& pos, - const wxSize& size, long style, const wxString& name ) + wxWindowID id, const wxPoint& pos, const wxSize& size, long style, + const wxString& name ) : SIM_PANEL_BASE( aCommand, aOptions, parent, id, pos, size, style, name ), m_axis_x( nullptr ), m_axis_y1( nullptr ), m_axis_y2( nullptr ), - m_dotted_cp( false ), - m_masterFrame( aMainFrame ) + m_dotted_cp( false ) { m_sizer = new wxBoxSizer( wxVERTICAL ); m_plotWin = new mpWindow( this, wxID_ANY, pos, size, style ); diff --git a/eeschema/sim/sim_plot_panel.h b/eeschema/sim/sim_plot_panel.h index 67bc5492e4..15421e9cfd 100644 --- a/eeschema/sim/sim_plot_panel.h +++ b/eeschema/sim/sim_plot_panel.h @@ -1,8 +1,8 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2016 CERN - * Copyright (C) 2016-2021 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2016-2023 CERN + * Copyright (C) 2016-2023 KiCad Developers, see AUTHORS.txt for contributors. * * @author Tomasz Wlostowski * @author Maciej Suminski @@ -168,13 +168,13 @@ public: protected: - CURSOR* m_cursor; + CURSOR* m_cursor; SIM_PLOT_TYPE m_type; - wxColour m_traceColour; + wxColour m_traceColour; private: ///< Name of the signal parameter - wxString m_param; + wxString m_param; }; @@ -183,19 +183,12 @@ class SIM_PLOT_PANEL : public SIM_PANEL_BASE friend class SIM_WORKBOOK; public: - SIM_PLOT_PANEL( const wxString& aCommand, int aOptions, wxWindow* parent, - SIM_PLOT_FRAME* aMainFrame, wxWindowID id, + SIM_PLOT_PANEL( const wxString& aCommand, int aOptions, wxWindow* parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = 0, const wxString& name = wxPanelNameStr ); virtual ~SIM_PLOT_PANEL(); - ///< set the pointer to the sim plot frame - void SetMasterFrame( SIM_PLOT_FRAME* aFrame ) - { - m_masterFrame = aFrame; - } - wxString GetLabelX() const { return m_axis_x ? m_axis_x->GetName() : ""; @@ -256,19 +249,20 @@ public: return m_legend->IsVisible(); } - void SetDottedCurrentPhase( bool aEnable ) + /** + * Draw secondary signal traces (current or phase) with dotted lines + */ + void SetDottedSecondary( bool aEnable ) { m_dotted_cp = aEnable; for( const auto& tr : m_traces ) - { UpdateTraceStyle( tr.second ); - } m_plotWin->UpdateAll(); } - bool GetDottedCurrentPhase() const + bool GetDottedSecondary() const { return m_dotted_cp; } @@ -304,25 +298,24 @@ private: ///> Create/Ensure axes are available for plotting void updateAxes(); - SIM_PLOT_COLORS m_colors; +private: + SIM_PLOT_COLORS m_colors; // Top-level plot window - mpWindow* m_plotWin; - wxBoxSizer* m_sizer; + mpWindow* m_plotWin; + wxBoxSizer* m_sizer; // Traces to be plotted std::map m_traces; - mpScaleXBase* m_axis_x; - mpScaleY* m_axis_y1; - mpScaleY* m_axis_y2; - mpInfoLegend* m_legend; + mpScaleXBase* m_axis_x; + mpScaleY* m_axis_y1; + mpScaleY* m_axis_y2; + mpInfoLegend* m_legend; - bool m_dotted_cp; + bool m_dotted_cp; - std::vector m_topLevel; - - SIM_PLOT_FRAME* m_masterFrame; + std::vector m_topLevel; }; wxDECLARE_EVENT( EVT_SIM_CURSOR_UPDATE, wxCommandEvent ); diff --git a/eeschema/sim/toolbars_sim_plot_frame.cpp b/eeschema/sim/toolbars_sim_plot_frame.cpp new file mode 100644 index 0000000000..1fc151cb99 --- /dev/null +++ b/eeschema/sim/toolbars_sim_plot_frame.cpp @@ -0,0 +1,138 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * +* Copyright (C) 2023 CERN +* Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + + +void SIM_PLOT_FRAME::ReCreateHToolbar() +{ + if( m_toolBar ) + { + m_toolBar->ClearToolbar(); + m_toolBar->SetToolManager( GetToolManager() ); + } + else + { + m_toolBar = new ACTION_TOOLBAR( dynamic_cast( this ), wxID_ANY, + wxDefaultPosition, wxDefaultSize, + KICAD_AUI_TB_STYLE | wxAUI_TB_HORZ_LAYOUT ); + } + + m_toolBar->Add( EE_ACTIONS::openWorkbook ); + m_toolBar->Add( EE_ACTIONS::saveWorkbook ); + + m_toolBar->AddScaledSeparator( this ); + m_toolBar->Add( EE_ACTIONS::simCommand ); + + m_toolBar->AddScaledSeparator( this ); + m_toolBar->Add( EE_ACTIONS::runSimulation ); + m_toolBar->Add( EE_ACTIONS::stopSimulation ); + + m_toolBar->AddScaledSeparator( this ); + m_toolBar->Add( ACTIONS::zoomInCenter ); + m_toolBar->Add( ACTIONS::zoomOutCenter ); + m_toolBar->Add( ACTIONS::zoomFitScreen ); + + m_toolBar->AddScaledSeparator( this ); + m_toolBar->Add( EE_ACTIONS::addSignals ); + m_toolBar->Add( EE_ACTIONS::simProbe ); + m_toolBar->Add( EE_ACTIONS::simTune ); + + m_toolBar->AddScaledSeparator( this ); + m_toolBar->Add( EE_ACTIONS::showNetlist ); + + // after adding the buttons to the toolbar, must call Realize() to reflect the changes + m_toolBar->KiRealize(); + + m_toolBar->Refresh(); +} + + +void SIM_PLOT_FRAME::doReCreateMenuBar() +{ + COMMON_CONTROL* tool = m_toolManager->GetTool(); + // wxWidgets handles the OSX Application menu behind the scenes, but that means + // we always have to start from scratch with a new wxMenuBar. + wxMenuBar* oldMenuBar = dynamic_cast( this )->GetMenuBar(); + WX_MENUBAR* menuBar = new WX_MENUBAR(); + + //-- File menu ----------------------------------------------------------- + // + ACTION_MENU* fileMenu = new ACTION_MENU( false, tool ); + + fileMenu->Add( EE_ACTIONS::newPlot ); + + fileMenu->AppendSeparator(); + fileMenu->Add( EE_ACTIONS::openWorkbook ); + fileMenu->Add( EE_ACTIONS::saveWorkbook ); + fileMenu->Add( EE_ACTIONS::saveWorkbookAs ); + + fileMenu->AppendSeparator(); + fileMenu->Add( EE_ACTIONS::exportPlotAsPNG ); + fileMenu->Add( EE_ACTIONS::exportPlotAsCSV ); + + fileMenu->AppendSeparator(); + fileMenu->AddClose( _( "Simulator" ) ); + + //-- View menu ----------------------------------------------------------- + // + ACTION_MENU* viewMenu = new ACTION_MENU( false, tool ); + + viewMenu->Add( ACTIONS::zoomInCenter ); + viewMenu->Add( ACTIONS::zoomOutCenter ); + viewMenu->Add( ACTIONS::zoomFitScreen ); + + viewMenu->AppendSeparator(); + viewMenu->Add( ACTIONS::toggleGrid, ACTION_MENU::CHECK ); + viewMenu->Add( EE_ACTIONS::toggleLegend, ACTION_MENU::CHECK ); + viewMenu->Add( EE_ACTIONS::toggleDottedSecondary, ACTION_MENU::CHECK ); + viewMenu->Add( EE_ACTIONS::toggleDarkModePlots, ACTION_MENU::CHECK ); + + //-- Simulation menu ----------------------------------------------------------- + // + ACTION_MENU* simulationMenu = new ACTION_MENU( false, tool ); + + simulationMenu->Add( EE_ACTIONS::simCommand ); + simulationMenu->Add( EE_ACTIONS::runSimulation ); + + simulationMenu->AppendSeparator(); + simulationMenu->Add( EE_ACTIONS::addSignals ); + simulationMenu->Add( EE_ACTIONS::simProbe ); + simulationMenu->Add( EE_ACTIONS::simTune ); + + simulationMenu->AppendSeparator(); + simulationMenu->Add( EE_ACTIONS::showNetlist ); + + //-- Menubar ------------------------------------------------------------- + // + menuBar->Append( fileMenu, _( "&File" ) ); + menuBar->Append( viewMenu, _( "&View" ) ); + menuBar->Append( simulationMenu, _( "&Simulation" ) ); + dynamic_cast( this )->AddStandardHelpMenu( menuBar ); + + dynamic_cast( this )->SetMenuBar( menuBar ); + delete oldMenuBar; +} diff --git a/eeschema/toolbars_sch_editor.cpp b/eeschema/toolbars_sch_editor.cpp index d08b7bf497..07eebf43ac 100644 --- a/eeschema/toolbars_sch_editor.cpp +++ b/eeschema/toolbars_sch_editor.cpp @@ -109,7 +109,7 @@ void SCH_EDIT_FRAME::ReCreateHToolbar() m_mainToolBar->AddScaledSeparator( this ); m_mainToolBar->Add( EE_ACTIONS::annotate ); m_mainToolBar->Add( EE_ACTIONS::runERC ); - m_mainToolBar->Add( EE_ACTIONS::runSimulation ); + m_mainToolBar->Add( EE_ACTIONS::showSimulator ); m_mainToolBar->Add( EE_ACTIONS::assignFootprints ); m_mainToolBar->Add( EE_ACTIONS::editSymbolFields ); m_mainToolBar->Add( EE_ACTIONS::generateBOM ); diff --git a/eeschema/tools/ee_actions.cpp b/eeschema/tools/ee_actions.cpp index 9f51bf5662..5aa49ea0d5 100644 --- a/eeschema/tools/ee_actions.cpp +++ b/eeschema/tools/ee_actions.cpp @@ -1,8 +1,8 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2019 CERN - * Copyright (C) 2019-2022 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2019-2023 CERN + * Copyright (C) 2019-2023 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -50,7 +50,7 @@ TOOL_ACTION EE_ACTIONS::checkSymbol( "eeschema.InspectionTool.checkSymbol", _( "Symbol Checker" ), _( "Show the symbol checker window" ), BITMAPS::erc ); -TOOL_ACTION EE_ACTIONS::runSimulation( "eeschema.EditorControl.runSimulation", +TOOL_ACTION EE_ACTIONS::showSimulator( "eeschema.EditorControl.showSimulator", AS_GLOBAL, 0, "", _( "Simulator..." ), _( "Simulate circuit in SPICE" ), BITMAPS::simulator ); @@ -563,14 +563,6 @@ TOOL_ACTION EE_ACTIONS::slice( "eeschema.InteractiveEdit.slice", TOOL_ACTION EE_ACTIONS::restartMove( "eeschema.EditorControl.restartMove", AS_GLOBAL ); -TOOL_ACTION EE_ACTIONS::simProbe( "eeschema.Simulation.probe", - AS_GLOBAL, 0, "", - _( "Add a simulator probe" ), "" ); - -TOOL_ACTION EE_ACTIONS::simTune( "eeschema.Simulation.tune", - AS_GLOBAL, 0, "", - _( "Select a value to be tuned" ), "" ); - TOOL_ACTION EE_ACTIONS::highlightNet( "eeschema.EditorControl.highlightNet", AS_GLOBAL, '`', "", @@ -902,3 +894,94 @@ TOOL_ACTION EE_ACTIONS::saveCurrSheetCopyAs( "eeschema.EditorControl.saveCurrShe // Drag and drop TOOL_ACTION EE_ACTIONS::ddAppendFile( "eeschema.EditorControl.ddAppendFile", AS_GLOBAL ); + +// SIMULATOR +TOOL_ACTION EE_ACTIONS::newPlot( "eeschema.Simulation.newPlot", + AS_GLOBAL, + MD_CTRL + 'N', LEGACY_HK_NAME( "New" ), + _( "New Plot" ), "", + BITMAPS::new_generic ); + +TOOL_ACTION EE_ACTIONS::openWorkbook( "eeschema.Simulation.openWorkbook", + AS_GLOBAL, + MD_CTRL + 'O', LEGACY_HK_NAME( "Open" ), + _( "Open Workbook..." ), "", + BITMAPS::directory_open ); + +TOOL_ACTION EE_ACTIONS::saveWorkbook( "eeschema.Simulation.saveWorkbook", + AS_GLOBAL, + MD_CTRL + 'S', LEGACY_HK_NAME( "Save" ), + _( "Save Workbook" ), "", + BITMAPS::save ); + +TOOL_ACTION EE_ACTIONS::saveWorkbookAs( "eeschema.Simulation.saveWorkbookAs", + AS_GLOBAL, + MD_SHIFT + MD_CTRL + 'S', LEGACY_HK_NAME( "Save As" ), + _( "Save Workbook As..." ), "", + BITMAPS::sim_add_signal ); + +TOOL_ACTION EE_ACTIONS::exportPlotAsPNG( "eeschema.Simulator.exportPNG", + AS_GLOBAL, 0, "", + _( "Export Current Plot as PNG..." ), "", + BITMAPS::export_png ); + +TOOL_ACTION EE_ACTIONS::exportPlotAsCSV( "eeschema.Simulator.exportCSV", + AS_GLOBAL, 0, "", + _( "Export Current Plot as CSV..." ), "", + BITMAPS::export_file ); + +TOOL_ACTION EE_ACTIONS::toggleLegend( "eeschema.Simulator.toggleLegend", + AS_GLOBAL, 0, "", + _( "Show Legend" ), "", + BITMAPS::text ); + +TOOL_ACTION EE_ACTIONS::toggleDottedSecondary( "eeschema.Simulator.toggleDottedSecondary", + AS_GLOBAL, 0, "", + _( "Dotted Current/Phase" ), + _( "Draw secondary signal trace (current or phase) with a dotted line" ) ); + +TOOL_ACTION EE_ACTIONS::toggleDarkModePlots( "eeschema.Simulator.toggleDarkModePlots", + AS_GLOBAL, 0, "", + _( "Dark Mode Plots" ), + _( "Draw plots with a black background" ) ); + +TOOL_ACTION EE_ACTIONS::simCommand( "eeschema.Simulation.simCommand", + AS_GLOBAL, 0, "", + _( "Simulation Command..." ), + _( "Edit the simulation command for the current plot tab" ), + BITMAPS::sim_command ); + +TOOL_ACTION EE_ACTIONS::runSimulation( "eeschema.Simulation.runSimulation", + AS_GLOBAL, + 'R', "", + _( "Run Simulation" ), "", + BITMAPS::sim_run ); + +TOOL_ACTION EE_ACTIONS::stopSimulation( "eeschema.Simulation.stopSimulation", + AS_GLOBAL, 0, "", + _( "Stop Simulation" ), "", + BITMAPS::sim_stop ); + +TOOL_ACTION EE_ACTIONS::addSignals( "eeschema.Simulation.addSignals", + AS_GLOBAL, + 'A', "", + _( "Add Signals..." ), "", + BITMAPS::sim_add_signal ); + +TOOL_ACTION EE_ACTIONS::simProbe( "eeschema.Simulation.probe", + AS_GLOBAL, + 'P', "", + _( "Probe Schematic..." ), _( "Add a simulator probe" ), + BITMAPS::sim_probe ); + +TOOL_ACTION EE_ACTIONS::simTune( "eeschema.Simulation.tune", + AS_GLOBAL, + 'T', "", + _( "Add Tuned Value..." ), _( "Select a value to be tuned" ), + BITMAPS::sim_tune ); + +TOOL_ACTION EE_ACTIONS::showNetlist( "eeschema.Simulation.showNetlist", + AS_GLOBAL, 0, "", + _( "Show SPICE Netlist" ), "", + BITMAPS::netlist ); + diff --git a/eeschema/tools/ee_actions.h b/eeschema/tools/ee_actions.h index b34fb2ae95..37ff5b8d6c 100644 --- a/eeschema/tools/ee_actions.h +++ b/eeschema/tools/ee_actions.h @@ -1,8 +1,8 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2019 CERN - * Copyright (C) 2019-2022 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2019-2023 CERN + * Copyright (C) 2019-2023 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -241,9 +241,23 @@ public: static TOOL_ACTION toggleAnnotateAuto; // SPICE - static TOOL_ACTION runSimulation; + static TOOL_ACTION newPlot; + static TOOL_ACTION openWorkbook; + static TOOL_ACTION saveWorkbook; + static TOOL_ACTION saveWorkbookAs; + static TOOL_ACTION exportPlotAsPNG; + static TOOL_ACTION exportPlotAsCSV; + static TOOL_ACTION showSimulator; static TOOL_ACTION simProbe; static TOOL_ACTION simTune; + static TOOL_ACTION toggleLegend; + static TOOL_ACTION toggleDottedSecondary; + static TOOL_ACTION toggleDarkModePlots; + static TOOL_ACTION simCommand; + static TOOL_ACTION runSimulation; + static TOOL_ACTION stopSimulation; + static TOOL_ACTION addSignals; + static TOOL_ACTION showNetlist; // Net highlighting static TOOL_ACTION highlightNet; diff --git a/eeschema/tools/ee_inspection_tool.cpp b/eeschema/tools/ee_inspection_tool.cpp index 7830c12efc..3a8aa93f87 100644 --- a/eeschema/tools/ee_inspection_tool.cpp +++ b/eeschema/tools/ee_inspection_tool.cpp @@ -1,8 +1,8 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2019 CERN - * Copyright (C) 2019-2022 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2019-2023 CERN + * Copyright (C) 2019-2023 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -350,7 +350,7 @@ void EE_INSPECTION_TOOL::setTransitions() Go( &EE_INSPECTION_TOOL::ExcludeMarker, EE_ACTIONS::excludeMarker.MakeEvent() ); Go( &EE_INSPECTION_TOOL::CheckSymbol, EE_ACTIONS::checkSymbol.MakeEvent() ); - Go( &EE_INSPECTION_TOOL::RunSimulation, EE_ACTIONS::runSimulation.MakeEvent() ); + Go( &EE_INSPECTION_TOOL::RunSimulation, EE_ACTIONS::showSimulator.MakeEvent() ); Go( &EE_INSPECTION_TOOL::ShowDatasheet, EE_ACTIONS::showDatasheet.MakeEvent() ); diff --git a/eeschema/tools/simulator_control.cpp b/eeschema/tools/simulator_control.cpp new file mode 100644 index 0000000000..2a47178539 --- /dev/null +++ b/eeschema/tools/simulator_control.cpp @@ -0,0 +1,443 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +bool SIMULATOR_CONTROL::Init() +{ + Reset( MODEL_RELOAD ); + return true; +} + + +void SIMULATOR_CONTROL::Reset( RESET_REASON aReason ) +{ + m_plotFrame = getEditFrame(); + + if( m_plotFrame ) + { + m_schematicFrame = m_plotFrame->GetSchematicFrame(); + m_circuitModel = m_plotFrame->GetCircuitModel(); + m_simulator = m_plotFrame->GetSimulator(); + } +} + + +int SIMULATOR_CONTROL::NewPlot( const TOOL_EVENT& aEvent ) +{ + SIM_TYPE type = m_circuitModel->GetSimType(); + + if( SIM_PANEL_BASE::IsPlottable( type ) ) + m_plotFrame->NewPlotPanel( m_circuitModel->GetSimCommand(), m_circuitModel->GetSimOptions() ); + + return 0; +} + + +int SIMULATOR_CONTROL::OpenWorkbook( const TOOL_EVENT& aEvent ) +{ + wxFileDialog openDlg( m_plotFrame, _( "Open simulation workbook" ), getDefaultPath(), "", + WorkbookFileWildcard(), wxFD_OPEN | wxFD_FILE_MUST_EXIST ); + + if( openDlg.ShowModal() == wxID_CANCEL ) + return -1; + + m_plotFrame->LoadWorkbook( openDlg.GetPath() ); + return 0; +} + + +wxString SIMULATOR_CONTROL::getDefaultFilename() +{ + wxFileName filename = m_simulator->Settings()->GetWorkbookFilename(); + + if( filename.GetName().IsEmpty() ) + { + if( m_plotFrame->Prj().GetProjectName().IsEmpty() ) + { + filename.SetName( _( "noname" ) ); + filename.SetExt( WorkbookFileExtension ); + } + else + { + filename.SetName( m_plotFrame->Prj().GetProjectName() ); + filename.SetExt( WorkbookFileExtension ); + } + } + + return filename.GetFullName(); +} + + +wxString SIMULATOR_CONTROL::getDefaultPath() +{ + wxFileName path = m_simulator->Settings()->GetWorkbookFilename(); + + path.Normalize( FN_NORMALIZE_FLAGS|wxPATH_NORM_ENV_VARS, m_plotFrame->Prj().GetProjectPath() ); + return path.GetPath(); +} + + +int SIMULATOR_CONTROL::SaveWorkbook( const TOOL_EVENT& aEvent ) +{ + wxString filename; + + if( aEvent.IsAction( &EE_ACTIONS::saveWorkbook ) ) + filename = m_simulator->Settings()->GetWorkbookFilename(); + + if( filename.IsEmpty() ) + { + wxFileDialog saveAsDlg( m_plotFrame, _( "Save Simulation Workbook As" ), getDefaultPath(), + getDefaultFilename(), WorkbookFileWildcard(), + wxFD_SAVE | wxFD_OVERWRITE_PROMPT ); + + if( saveAsDlg.ShowModal() == wxID_CANCEL ) + return -1; + + filename = saveAsDlg.GetPath(); + } + + m_plotFrame->SaveWorkbook( m_plotFrame->Prj().AbsolutePath( filename ) ); + return 0; +} + + +int SIMULATOR_CONTROL::ExportPlotAsPNG( const TOOL_EVENT& aEvent ) +{ + if( !m_plotFrame->GetCurrentPlot() ) + return -1; + + wxFileDialog saveDlg( m_plotFrame, _( "Save Plot as Image" ), "", "", PngFileWildcard(), + wxFD_SAVE | wxFD_OVERWRITE_PROMPT ); + + if( saveDlg.ShowModal() == wxID_CANCEL ) + return -1; + + m_plotFrame->GetCurrentPlot()->GetPlotWin()->SaveScreenshot( saveDlg.GetPath(), + wxBITMAP_TYPE_PNG ); + + return 0; +} + + +int SIMULATOR_CONTROL::ExportPlotAsCSV( const TOOL_EVENT& aEvent ) +{ + if( !m_plotFrame->GetCurrentPlot() ) + return -1; + + const wxChar SEPARATOR = ';'; + + wxFileDialog saveDlg( m_plotFrame, _( "Save Plot Data" ), "", "", CsvFileWildcard(), + wxFD_SAVE | wxFD_OVERWRITE_PROMPT ); + + if( saveDlg.ShowModal() == wxID_CANCEL ) + return -1; + + wxFFile out( saveDlg.GetPath(), "wb" ); + + std::map traces = m_plotFrame->GetCurrentPlot()->GetTraces(); + + if( traces.size() == 0 ) + return -1; + + SIM_TYPE simType = m_circuitModel->GetSimType(); + + std::size_t rowCount = traces.begin()->second->GetDataX().size(); + + // write column header names on the first row + wxString xAxisName( m_simulator->GetXAxis( simType ) ); + out.Write( wxString::Format( wxT( "%s%c" ), xAxisName, SEPARATOR ) ); + + for( const auto& [name, trace] : traces ) + out.Write( wxString::Format( wxT( "%s%c" ), name, SEPARATOR ) ); + + out.Write( wxS( "\r\n" ) ); + + // write each row's numerical value + for ( std::size_t curRow=0; curRow < rowCount; curRow++ ) + { + double xAxisValue = traces.begin()->second->GetDataX().at( curRow ); + out.Write( wxString::Format( wxT( "%g%c" ), xAxisValue, SEPARATOR ) ); + + for( const auto& [name, trace] : traces ) + { + double yAxisValue = trace->GetDataY().at( curRow ); + out.Write( wxString::Format( wxT( "%g%c" ), yAxisValue, SEPARATOR ) ); + } + + out.Write( wxS( "\r\n" ) ); + } + + out.Close(); + return 0; +} + + +int SIMULATOR_CONTROL::Close( const TOOL_EVENT& aEvent ) +{ + m_plotFrame->Close(); + return 0; +} + + +int SIMULATOR_CONTROL::Zoom( const TOOL_EVENT& aEvent ) +{ + if( m_plotFrame->GetCurrentPlot() ) + { + if( aEvent.IsAction( &ACTIONS::zoomInCenter ) ) + m_plotFrame->GetCurrentPlot()->GetPlotWin()->ZoomIn(); + else if( aEvent.IsAction( &ACTIONS::zoomOutCenter ) ) + m_plotFrame->GetCurrentPlot()->GetPlotWin()->ZoomOut(); + else if( aEvent.IsAction( &ACTIONS::zoomFitScreen ) ) + m_plotFrame->GetCurrentPlot()->GetPlotWin()->Fit(); + } + + return 0; +} + + +int SIMULATOR_CONTROL::ToggleGrid( const TOOL_EVENT& aEvent ) +{ + SIM_PLOT_PANEL* plot = m_plotFrame->GetCurrentPlot(); + + if( plot ) + plot->ShowGrid( !plot->IsGridShown() ); + + return 0; +} + + +int SIMULATOR_CONTROL::ToggleLegend( const TOOL_EVENT& aEvent ) +{ + SIM_PLOT_PANEL* plot = m_plotFrame->GetCurrentPlot(); + + if( plot ) + plot->ShowLegend( !plot->IsLegendShown() ); + + return 0; +} + + +int SIMULATOR_CONTROL::ToggleDottedSecondary( const TOOL_EVENT& aEvent ) +{ + SIM_PLOT_PANEL* plot = m_plotFrame->GetCurrentPlot(); + + if( plot ) + plot->SetDottedSecondary( !plot->GetDottedSecondary() ); + + return 0; +} + + +int SIMULATOR_CONTROL::ToggleDarkModePlots( const TOOL_EVENT& aEvent ) +{ + m_plotFrame->ToggleDarkModePlots(); + return 0; +} + + +int SIMULATOR_CONTROL::EditSimCommand( const TOOL_EVENT& aEvent ) +{ + m_plotFrame->EditSimCommand(); + return 0; +} + + +int SIMULATOR_CONTROL::RunSimulation( const TOOL_EVENT& aEvent ) +{ + if( m_simulator->IsRunning() ) + m_simulator->Stop(); + else + m_plotFrame->StartSimulation(); + + return 0; +} + + +int SIMULATOR_CONTROL::AddSignals( const TOOL_EVENT& aEvent ) +{ + SIM_PLOT_PANEL* plotPanel = m_plotFrame->GetCurrentPlot(); + + if( !plotPanel || !m_circuitModel || plotPanel->GetType() != m_circuitModel->GetSimType() ) + { + DisplayInfoMessage( m_plotFrame, _( "You need to run plot-providing simulation first." ) ); + return -1; + } + + DIALOG_SIGNAL_LIST dialog( m_plotFrame, m_circuitModel.get() ); + dialog.ShowModal(); + + return 0; +} + + +int SIMULATOR_CONTROL::Probe( const TOOL_EVENT& aEvent ) +{ + if( m_schematicFrame == nullptr ) + return -1; + + wxWindow* blocking_dialog = m_schematicFrame->Kiway().GetBlockingDialog(); + + if( blocking_dialog ) + blocking_dialog->Close( true ); + + m_schematicFrame->GetToolManager()->RunAction( EE_ACTIONS::simProbe ); + m_schematicFrame->Raise(); + + return 0; +} + + +int SIMULATOR_CONTROL::Tune( const TOOL_EVENT& aEvent ) +{ + if( m_schematicFrame == nullptr ) + return -1; + + wxWindow* blocking_dialog = m_schematicFrame->Kiway().GetBlockingDialog(); + + if( blocking_dialog ) + blocking_dialog->Close( true ); + + m_schematicFrame->GetToolManager()->RunAction( EE_ACTIONS::simTune ); + m_schematicFrame->Raise(); + + return 0; +} + + +class NETLIST_VIEW_DIALOG : public DIALOG_SHIM +{ +public: + enum + { + MARGIN_LINE_NUMBERS + }; + + void onClose( wxCloseEvent& evt ) + { + wxPostEvent( this, wxCommandEvent( wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL ) ); + } + + NETLIST_VIEW_DIALOG( wxWindow* parent, const wxString& source) : + DIALOG_SHIM( parent, wxID_ANY, _( "SPICE Netlist" ), wxDefaultPosition, + wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER ) + { + wxStyledTextCtrl* textCtrl = new wxStyledTextCtrl( this, wxID_ANY ); + textCtrl->SetMinSize( wxSize( 600, 400 ) ); + + textCtrl->SetMarginWidth( MARGIN_LINE_NUMBERS, 50 ); + textCtrl->StyleSetForeground( wxSTC_STYLE_LINENUMBER, wxColour( 75, 75, 75 ) ); + textCtrl->StyleSetBackground( wxSTC_STYLE_LINENUMBER, wxColour( 220, 220, 220 ) ); + textCtrl->SetMarginType( MARGIN_LINE_NUMBERS, wxSTC_MARGIN_NUMBER ); + + wxFont fixedFont = KIUI::GetMonospacedUIFont(); + + for( int i = 0; i < wxSTC_STYLE_MAX; ++i ) + textCtrl->StyleSetFont( i, fixedFont ); + + textCtrl->StyleClearAll(); // Addresses a bug in wx3.0 where styles are not correctly set + + textCtrl->SetWrapMode( wxSTC_WRAP_WORD ); + + textCtrl->SetText( source ); + + textCtrl->SetLexer( wxSTC_LEX_SPICE ); + + wxBoxSizer* sizer = new wxBoxSizer( wxVERTICAL ); + sizer->Add( textCtrl, 1, wxEXPAND | wxALL, 5 ); + SetSizer( sizer ); + + Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( NETLIST_VIEW_DIALOG::onClose ), + nullptr, this ); + + m_scintillaTricks = std::make_unique( textCtrl, wxT( "{}" ), false ); + + finishDialogSettings(); + } + + std::unique_ptr m_scintillaTricks; +}; + + +int SIMULATOR_CONTROL::ShowNetlist( const TOOL_EVENT& aEvent ) +{ + if( m_schematicFrame == nullptr || m_simulator == nullptr ) + return -1; + + wxString errors; + WX_STRING_REPORTER reporter( &errors ); + STRING_FORMATTER formatter; + + m_circuitModel->SetSimOptions( m_plotFrame->GetCurrentOptions() ); + m_circuitModel->GetNetlist( &formatter, reporter ); + + NETLIST_VIEW_DIALOG dlg( m_plotFrame, errors.IsEmpty() ? formatter.GetString() : errors ); + dlg.ShowModal(); + + return 0; +} + + +void SIMULATOR_CONTROL::setTransitions() +{ + Go( &SIMULATOR_CONTROL::NewPlot, EE_ACTIONS::newPlot.MakeEvent() ); + Go( &SIMULATOR_CONTROL::OpenWorkbook, EE_ACTIONS::openWorkbook.MakeEvent() ); + Go( &SIMULATOR_CONTROL::SaveWorkbook, EE_ACTIONS::saveWorkbook.MakeEvent() ); + Go( &SIMULATOR_CONTROL::SaveWorkbook, EE_ACTIONS::saveWorkbookAs.MakeEvent() ); + Go( &SIMULATOR_CONTROL::ExportPlotAsPNG, EE_ACTIONS::exportPlotAsPNG.MakeEvent() ); + Go( &SIMULATOR_CONTROL::ExportPlotAsCSV, EE_ACTIONS::exportPlotAsCSV.MakeEvent() ); + Go( &SIMULATOR_CONTROL::Close, ACTIONS::quit.MakeEvent() ); + + Go( &SIMULATOR_CONTROL::Zoom, ACTIONS::zoomInCenter.MakeEvent() ); + Go( &SIMULATOR_CONTROL::Zoom, ACTIONS::zoomOutCenter.MakeEvent() ); + Go( &SIMULATOR_CONTROL::Zoom, ACTIONS::zoomFitScreen.MakeEvent() ); + Go( &SIMULATOR_CONTROL::ToggleGrid, ACTIONS::toggleGrid.MakeEvent() ); + Go( &SIMULATOR_CONTROL::ToggleLegend, EE_ACTIONS::toggleLegend.MakeEvent() ); + Go( &SIMULATOR_CONTROL::ToggleDottedSecondary, EE_ACTIONS::toggleDottedSecondary.MakeEvent() ); + Go( &SIMULATOR_CONTROL::ToggleDarkModePlots, EE_ACTIONS::toggleDarkModePlots.MakeEvent() ); + + Go( &SIMULATOR_CONTROL::EditSimCommand, EE_ACTIONS::simCommand.MakeEvent() ); + Go( &SIMULATOR_CONTROL::RunSimulation, EE_ACTIONS::runSimulation.MakeEvent() ); + Go( &SIMULATOR_CONTROL::RunSimulation, EE_ACTIONS::stopSimulation.MakeEvent() ); + Go( &SIMULATOR_CONTROL::AddSignals, EE_ACTIONS::addSignals.MakeEvent() ); + Go( &SIMULATOR_CONTROL::Probe, EE_ACTIONS::simProbe.MakeEvent() ); + Go( &SIMULATOR_CONTROL::Tune, EE_ACTIONS::simTune.MakeEvent() ); + + Go( &SIMULATOR_CONTROL::ShowNetlist, EE_ACTIONS::showNetlist.MakeEvent() ); +} diff --git a/eeschema/tools/simulator_control.h b/eeschema/tools/simulator_control.h new file mode 100644 index 0000000000..9919cf1212 --- /dev/null +++ b/eeschema/tools/simulator_control.h @@ -0,0 +1,98 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + + +#ifndef SIMULATOR_CONTROL_H +#define SIMULATOR_CONTROL_H + +#include + +class SIM_PLOT_FRAME; +class NGSPICE_CIRCUIT_MODEL; +class SPICE_SIMULATOR; + + +/** + * Handle actions for the various symbol editor and viewers. + */ +class SIMULATOR_CONTROL : public wxEvtHandler, public TOOL_INTERACTIVE +{ +public: + SIMULATOR_CONTROL() : + TOOL_INTERACTIVE( "eeschema.SimulatorControl" ), + m_plotFrame( nullptr ), + m_schematicFrame( nullptr ) + { } + + virtual ~SIMULATOR_CONTROL() { } + + /// @copydoc TOOL_INTERACTIVE::Init() + bool Init() override; + + /// @copydoc TOOL_INTERACTIVE::Reset() + void Reset( RESET_REASON aReason ) override; + + int NewPlot( const TOOL_EVENT& aEvent ); + int OpenWorkbook( const TOOL_EVENT& aEvent ); + int SaveWorkbook( const TOOL_EVENT& aEvent ); + int ExportPlotAsPNG( const TOOL_EVENT& aEvent ); + int ExportPlotAsCSV( const TOOL_EVENT& aEvent ); + int Close( const TOOL_EVENT& aEvent ); + + int Zoom( const TOOL_EVENT& aEvent ); + int ToggleGrid( const TOOL_EVENT& aEvent ); + int ToggleLegend( const TOOL_EVENT& aEvent ); + int ToggleDottedSecondary( const TOOL_EVENT& aEvent ); + int ToggleDarkModePlots( const TOOL_EVENT& aEvent ); + + int EditSimCommand( const TOOL_EVENT& aEvent ); + int RunSimulation( const TOOL_EVENT& aEvent ); + int AddSignals( const TOOL_EVENT& aEvent ); + int Probe( const TOOL_EVENT& aEvent ); + int Tune( const TOOL_EVENT& aEvent ); + + int ShowNetlist( const TOOL_EVENT& aEvent ); + +private: + /** + * Return the default filename (with extension) to be used in file browser dialog. + */ + wxString getDefaultFilename(); + + /** + * Return the default path to be used in file browser dialog. + */ + wxString getDefaultPath(); + + ///< Set up handlers for various events. + void setTransitions() override; + +private: + SIM_PLOT_FRAME* m_plotFrame; + SCH_EDIT_FRAME* m_schematicFrame; + std::shared_ptr m_circuitModel; + std::shared_ptr m_simulator; +}; + + +#endif // SIMULATOR_CONTROL_H diff --git a/include/bitmaps/bitmaps_list.h b/include/bitmaps/bitmaps_list.h index fe194288b8..6bfb9eca37 100644 --- a/include/bitmaps/bitmaps_list.h +++ b/include/bitmaps/bitmaps_list.h @@ -524,6 +524,7 @@ enum class BITMAPS : unsigned int show_zone_triangulation, showtrack, sim_add_signal, + sim_command, sim_probe, sim_run, sim_stop, diff --git a/include/tool/action_toolbar.h b/include/tool/action_toolbar.h index 1dba363c72..90f4892766 100644 --- a/include/tool/action_toolbar.h +++ b/include/tool/action_toolbar.h @@ -196,6 +196,8 @@ public: */ void SetAuiManager( wxAuiManager* aManager ) { m_auiManager = aManager; } + void SetToolManager( TOOL_MANAGER* aManager ) { m_toolManager = aManager; } + /** * Add a TOOL_ACTION-based button to the toolbar. * diff --git a/resources/bitmaps_png/CMakeLists.txt b/resources/bitmaps_png/CMakeLists.txt index f8ac80003e..b03b07da25 100644 --- a/resources/bitmaps_png/CMakeLists.txt +++ b/resources/bitmaps_png/CMakeLists.txt @@ -458,6 +458,7 @@ set( BMAPS_MID shape_3d_back sheetset simulator + sim_command sim_run sim_stop sim_tune diff --git a/resources/bitmaps_png/png/sim_command_24.png b/resources/bitmaps_png/png/sim_command_24.png new file mode 100644 index 0000000000..dc323d8136 Binary files /dev/null and b/resources/bitmaps_png/png/sim_command_24.png differ diff --git a/resources/bitmaps_png/png/sim_run_24.png b/resources/bitmaps_png/png/sim_run_24.png index 7936627f93..9889bbfecd 100644 Binary files a/resources/bitmaps_png/png/sim_run_24.png and b/resources/bitmaps_png/png/sim_run_24.png differ diff --git a/resources/bitmaps_png/png/sim_stop_24.png b/resources/bitmaps_png/png/sim_stop_24.png index ab6f282d20..28ad449edd 100644 Binary files a/resources/bitmaps_png/png/sim_stop_24.png and b/resources/bitmaps_png/png/sim_stop_24.png differ diff --git a/resources/bitmaps_png/sources/light/sim_command.svg b/resources/bitmaps_png/sources/light/sim_command.svg new file mode 100644 index 0000000000..76502d3549 --- /dev/null +++ b/resources/bitmaps_png/sources/light/sim_command.svg @@ -0,0 +1,120 @@ + + + + + + + + + + image/svg+xml + + simulator + + + + + + + + + + + + + + + simulator + + + + + + + diff --git a/resources/bitmaps_png/sources/light/sim_run.svg b/resources/bitmaps_png/sources/light/sim_run.svg index a10d17831b..19d72fb599 100644 --- a/resources/bitmaps_png/sources/light/sim_run.svg +++ b/resources/bitmaps_png/sources/light/sim_run.svg @@ -1,18 +1,18 @@ + inkscape:version="1.2.1 (9c6d41e, 2022-07-14)" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + inkscape:current-layer="Слой_1" + inkscape:showpageshadow="2" + inkscape:pagecheckerboard="0" + inkscape:deskcolor="#d1d1d1"> sim_run + transform="matrix(0.8194917,0,0,0.83459422,1.3287263,1.1323935)" /> diff --git a/resources/bitmaps_png/sources/light/sim_stop.svg b/resources/bitmaps_png/sources/light/sim_stop.svg index 68bda0035a..041093898c 100644 --- a/resources/bitmaps_png/sources/light/sim_stop.svg +++ b/resources/bitmaps_png/sources/light/sim_stop.svg @@ -1,35 +1,92 @@ - - - - - - - - - image/svg+xml - - add_arc - - - - - - - - - - - - - - - sim_stop - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + image/svg+xml + + add_arc + + + + + + + + + + + + + + + sim_stop +