diff --git a/eeschema/sim/sim_plot_frame.cpp b/eeschema/sim/sim_plot_frame.cpp index a75a70c27b..c787aef01d 100644 --- a/eeschema/sim/sim_plot_frame.cpp +++ b/eeschema/sim/sim_plot_frame.cpp @@ -340,7 +340,16 @@ void SIM_PLOT_FRAME::updateTitle() } -void SIM_PLOT_FRAME::onModify() +void SIM_PLOT_FRAME::updateWorkbook() +{ + // We need to keep track of the plot panel positions + for( unsigned int i = 0; i < m_plotNotebook->GetPageCount(); i++ ) + m_workbook->SetPlotPanelPosition( + dynamic_cast( m_plotNotebook->GetPage( i ) ), i ); +} + + +void SIM_PLOT_FRAME::updateFrame() { updateTitle(); } @@ -518,7 +527,7 @@ SIM_PANEL_BASE* SIM_PLOT_FRAME::NewPlotPanel( wxString aSimCommand ) m_plotNotebook->AddPage( dynamic_cast( plotPanel ), pageTitle, true ); - onModify(); + updateFrame(); return plotPanel; } @@ -685,7 +694,7 @@ void SIM_PLOT_FRAME::removePlot( const wxString& aPlotName, bool aErase ) updateSignalList(); wxCommandEvent dummy; onCursorUpdate( dummy ); - onModify(); + updateFrame(); } @@ -794,7 +803,7 @@ bool SIM_PLOT_FRAME::updatePlot( const TRACE_DESC& aDescriptor, SIM_PLOT_PANEL* offset += inner; } - onModify(); + updateFrame(); return true; } } @@ -803,7 +812,7 @@ bool SIM_PLOT_FRAME::updatePlot( const TRACE_DESC& aDescriptor, SIM_PLOT_PANEL* data_x.data(), data_y.data(), aDescriptor.GetType() ) ) m_workbook->AddTrace( aPanel, aDescriptor.GetTitle(), aDescriptor ); - onModify(); + updateFrame(); return true; } @@ -922,7 +931,7 @@ bool SIM_PLOT_FRAME::loadWorkbook( const wxString& aPath ) if( !file.Open() ) { - onModify(); + updateFrame(); return false; } @@ -931,7 +940,7 @@ bool SIM_PLOT_FRAME::loadWorkbook( const wxString& aPath ) if( !file.GetFirstLine().ToLong( &plotsCount ) ) // GetFirstLine instead of GetNextLine { file.Close(); - onModify(); + updateFrame(); return false; } @@ -941,7 +950,7 @@ bool SIM_PLOT_FRAME::loadWorkbook( const wxString& aPath ) if( !file.GetNextLine().ToLong( &plotType ) ) { - onModify(); + updateFrame(); return false; } @@ -959,7 +968,7 @@ bool SIM_PLOT_FRAME::loadWorkbook( const wxString& aPath ) if( !file.GetNextLine().ToLong( &tracesCount ) ) { - onModify(); + updateFrame(); return false; } @@ -971,7 +980,7 @@ bool SIM_PLOT_FRAME::loadWorkbook( const wxString& aPath ) if( !file.GetNextLine().ToLong( &traceType ) ) { file.Close(); - onModify(); + updateFrame(); return false; } @@ -981,7 +990,7 @@ bool SIM_PLOT_FRAME::loadWorkbook( const wxString& aPath ) if( name.IsEmpty() || param.IsEmpty() ) { file.Close(); - onModify(); + updateFrame(); return false; } @@ -994,7 +1003,7 @@ bool SIM_PLOT_FRAME::loadWorkbook( const wxString& aPath ) // Successfully loading a workbook does not count as modyfying it. m_workbook->ClrModified(); - onModify(); + updateFrame(); return true; } @@ -1020,32 +1029,23 @@ bool SIM_PLOT_FRAME::saveWorkbook( const wxString& aPath ) file.Create(); } - unsigned long plotCount = 0; + std::vector plotPanels = m_workbook->GetSortedPlotPanels(); - // XXX: Count all valid plots. Replace this once we move the workbook format to JSON or - // S-expressions. - for( const auto& plot : m_workbook->GetPlots() ) + file.AddLine( wxString::Format( "%llu", plotPanels.size() ) ); + + for( const SIM_PANEL_BASE*& plotPanel : plotPanels ) { - if( plot.first ) - plotCount++; - } + SIM_WORKBOOK::PLOT_INFO plot = m_workbook->GetPlot( plotPanel ); - file.AddLine( wxString::Format( "%llu", plotCount ) ); + file.AddLine( wxString::Format( "%d", plotPanel->GetType() ) ); + file.AddLine( plot.m_simCommand ); + file.AddLine( wxString::Format( "%llu", plot.m_traces.size() ) ); - for( const auto& plot : m_workbook->GetPlots() ) - { - if( plot.first ) + for( const auto& trace : plot.m_traces ) { - file.AddLine( wxString::Format( "%d", plot.first->GetType() ) ); - file.AddLine( plot.second.m_simCommand ); - file.AddLine( wxString::Format( "%llu", plot.second.m_traces.size() ) ); - - for( const auto& trace : plot.second.m_traces ) - { - file.AddLine( wxString::Format( "%d", trace.second.GetType() ) ); - file.AddLine( trace.second.GetName() ); - file.AddLine( trace.second.GetParam() ); - } + file.AddLine( wxString::Format( "%d", trace.second.GetType() ) ); + file.AddLine( trace.second.GetName() ); + file.AddLine( trace.second.GetParam() ); } } @@ -1056,7 +1056,7 @@ bool SIM_PLOT_FRAME::saveWorkbook( const wxString& aPath ) // the frame is closed and then opened again. m_simulator->Settings()->SetWorkbookFilename( wxFileName( savePath ).GetFullName() ); m_workbook->ClrModified(); - onModify(); + updateFrame(); return res; } @@ -1097,7 +1097,7 @@ void SIM_PLOT_FRAME::menuNewPlot( wxCommandEvent& aEvent ) if( prevPlot ) { m_workbook->SetSimCommand( newPlot, m_workbook->GetSimCommand( prevPlot ) ); - onModify(); + updateFrame(); } } } @@ -1322,7 +1322,13 @@ void SIM_PLOT_FRAME::onPlotClose( wxAuiNotebookEvent& event ) m_workbook->RemovePlotPanel( plotPanel ); wxCommandEvent dummy; onCursorUpdate( dummy ); - onModify(); +} + + +void SIM_PLOT_FRAME::onPlotClosed( wxAuiNotebookEvent& event ) +{ + updateWorkbook(); + updateFrame(); } @@ -1331,6 +1337,16 @@ void SIM_PLOT_FRAME::onPlotChanged( wxAuiNotebookEvent& event ) updateSignalList(); wxCommandEvent dummy; onCursorUpdate( dummy ); + + updateWorkbook(); + updateFrame(); +} + + +void SIM_PLOT_FRAME::onPlotDragged( wxAuiNotebookEvent& event ) +{ + updateWorkbook(); + updateFrame(); } @@ -1415,7 +1431,7 @@ void SIM_PLOT_FRAME::onSettings( wxCommandEvent& event ) m_workbook->SetSimCommand( plotPanelWindow, newCommand ); m_simulator->Init(); - onModify(); + updateFrame(); } } @@ -1654,7 +1670,7 @@ void SIM_PLOT_FRAME::onSimFinished( wxCommandEvent& aEvent ) updateSignalList(); plotPanel->GetPlotWin()->UpdateAll(); plotPanel->ResetScales(); - onModify(); + updateFrame(); } else if( simType == ST_OP ) { diff --git a/eeschema/sim/sim_plot_frame.h b/eeschema/sim/sim_plot_frame.h index 2cd3667670..e8011075e5 100644 --- a/eeschema/sim/sim_plot_frame.h +++ b/eeschema/sim/sim_plot_frame.h @@ -149,11 +149,16 @@ private: */ void updateTitle(); + /** + * Update the workbook to match the changes in the frame. + */ + void updateWorkbook(); + /** * Update the frame to match the changes to the workbook. Should be always called after the * workbook was modified. */ - void onModify(); + void updateFrame(); /** * Give icons to menuitems of the main menubar. @@ -267,8 +272,10 @@ private: } // Event handlers - void onPlotChanged( wxAuiNotebookEvent& event ) override; void onPlotClose( wxAuiNotebookEvent& event ) override; + void onPlotClosed( wxAuiNotebookEvent& event ) override; + void onPlotChanged( wxAuiNotebookEvent& event ) override; + void onPlotDragged( wxAuiNotebookEvent& event ) override; void onSignalDblClick( wxMouseEvent& event ) override; void onSignalRClick( wxListEvent& event ) override; diff --git a/eeschema/sim/sim_plot_frame_base.cpp b/eeschema/sim/sim_plot_frame_base.cpp index a0f402c615..fed0d234e5 100644 --- a/eeschema/sim/sim_plot_frame_base.cpp +++ b/eeschema/sim/sim_plot_frame_base.cpp @@ -46,7 +46,7 @@ SIM_PLOT_FRAME_BASE::SIM_PLOT_FRAME_BASE( wxWindow* parent, wxWindowID id, const m_fileMenu->AppendSeparator(); wxMenuItem* m_exitSim; - m_exitSim = new wxMenuItem( m_fileMenu, wxID_CLOSE, wxString( _("Close Simulation") ) + wxT('\t') + wxT("CTRL+W"), wxEmptyString, wxITEM_NORMAL ); + 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") ); @@ -290,8 +290,10 @@ SIM_PLOT_FRAME_BASE::SIM_PLOT_FRAME_BASE( wxWindow* parent, wxWindowID id, const 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_plotNotebook->Connect( wxEVT_COMMAND_AUINOTEBOOK_END_DRAG, wxAuiNotebookEventHandler( SIM_PLOT_FRAME_BASE::onPlotDragged ), NULL, this ); m_plotNotebook->Connect( wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED, wxAuiNotebookEventHandler( SIM_PLOT_FRAME_BASE::onPlotChanged ), NULL, this ); m_plotNotebook->Connect( wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSE, wxAuiNotebookEventHandler( SIM_PLOT_FRAME_BASE::onPlotClose ), NULL, this ); + m_plotNotebook->Connect( wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSED, wxAuiNotebookEventHandler( SIM_PLOT_FRAME_BASE::onPlotClosed ), NULL, this ); m_signals->Connect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( SIM_PLOT_FRAME_BASE::onSignalDblClick ), NULL, this ); m_signals->Connect( wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK, wxListEventHandler( SIM_PLOT_FRAME_BASE::onSignalRClick ), NULL, this ); } @@ -303,8 +305,10 @@ SIM_PLOT_FRAME_BASE::~SIM_PLOT_FRAME_BASE() 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_plotNotebook->Disconnect( wxEVT_COMMAND_AUINOTEBOOK_END_DRAG, wxAuiNotebookEventHandler( SIM_PLOT_FRAME_BASE::onPlotDragged ), NULL, this ); m_plotNotebook->Disconnect( wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED, wxAuiNotebookEventHandler( SIM_PLOT_FRAME_BASE::onPlotChanged ), NULL, this ); m_plotNotebook->Disconnect( wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSE, wxAuiNotebookEventHandler( SIM_PLOT_FRAME_BASE::onPlotClose ), NULL, this ); + m_plotNotebook->Disconnect( wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSED, wxAuiNotebookEventHandler( SIM_PLOT_FRAME_BASE::onPlotClosed ), NULL, this ); m_signals->Disconnect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( SIM_PLOT_FRAME_BASE::onSignalDblClick ), NULL, this ); m_signals->Disconnect( wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK, wxListEventHandler( SIM_PLOT_FRAME_BASE::onSignalRClick ), NULL, this ); diff --git a/eeschema/sim/sim_plot_frame_base.fbp b/eeschema/sim/sim_plot_frame_base.fbp index 18523c4aaa..d7f24e613a 100644 --- a/eeschema/sim/sim_plot_frame_base.fbp +++ b/eeschema/sim/sim_plot_frame_base.fbp @@ -27,7 +27,7 @@ UI 0 0 - + 0 wxAUI_MGR_DEFAULT @@ -54,7 +54,7 @@ SIM_PLOT_FRAME wxTAB_TRAVERSAL 1 - + 1 @@ -76,7 +76,7 @@ - + File m_fileMenu protected @@ -183,7 +183,7 @@ wxID_CLOSE wxITEM_NORMAL - Close Simulation + Close m_exitSim none CTRL+W @@ -191,7 +191,7 @@ menuExit - + Simulation m_simulationMenu protected @@ -286,7 +286,7 @@ - + View m_viewMenu protected @@ -402,7 +402,7 @@ - + m_sizerMain wxVERTICAL @@ -469,11 +469,11 @@ - + 5 wxEXPAND 1 - + 1 1 1 @@ -530,8 +530,8 @@ wxBORDER_NONE - - + + 1 1 1 @@ -582,16 +582,16 @@ wxTAB_TRAVERSAL - + -1,-1 m_sizer11 wxVERTICAL protected - + 5 wxEXPAND 1 - + 1 1 1 @@ -648,8 +648,8 @@ - - + + 1 1 1 @@ -763,15 +763,17 @@ + onPlotDragged onPlotChanged onPlotClose + onPlotClosed - - + + 1 1 1 @@ -899,8 +901,8 @@ - - + + 1 1 1 @@ -951,16 +953,16 @@ wxTAB_TRAVERSAL - + m_sideSizer wxVERTICAL protected - + 5 wxEXPAND 1 - + 1 1 1 @@ -1017,8 +1019,8 @@ - - + + 1 1 1 @@ -1202,8 +1204,8 @@ - - + + 1 1 1 diff --git a/eeschema/sim/sim_plot_frame_base.h b/eeschema/sim/sim_plot_frame_base.h index 74141a8ef7..3667952124 100644 --- a/eeschema/sim/sim_plot_frame_base.h +++ b/eeschema/sim/sim_plot_frame_base.h @@ -110,8 +110,10 @@ class SIM_PLOT_FRAME_BASE : public KIWAY_PLAYER 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(); } + virtual void onPlotClosed( wxAuiNotebookEvent& event ) { event.Skip(); } virtual void onSignalDblClick( wxMouseEvent& event ) { event.Skip(); } virtual void onSignalRClick( wxListEvent& event ) { event.Skip(); } diff --git a/eeschema/sim/sim_workbook.cpp b/eeschema/sim/sim_workbook.cpp index 671e426262..9b706ea97a 100644 --- a/eeschema/sim/sim_workbook.cpp +++ b/eeschema/sim/sim_workbook.cpp @@ -70,6 +70,23 @@ void SIM_WORKBOOK::RemovePlotPanel( SIM_PANEL_BASE* aPlotPanel ) } +std::vector SIM_WORKBOOK::GetSortedPlotPanels() const +{ + std::vector plotPanels; + + for( const auto& plot : m_plots ) + plotPanels.push_back( plot.first ); + + std::sort( plotPanels.begin(), plotPanels.end(), + [&]( const SIM_PANEL_BASE*& a, const SIM_PANEL_BASE*& b ) + { + return m_plots.at( a ).pos < m_plots.at( b ).pos; + }); + + return plotPanels; +} + + void SIM_WORKBOOK::AddTrace( const SIM_PANEL_BASE* aPlotPanel, const wxString& aName, const TRACE_DESC& aTrace ) { diff --git a/eeschema/sim/sim_workbook.h b/eeschema/sim/sim_workbook.h index 423278a441..9c40abfc26 100644 --- a/eeschema/sim/sim_workbook.h +++ b/eeschema/sim/sim_workbook.h @@ -90,6 +90,9 @@ public: ///< Spice directive used to execute the simulation wxString m_simCommand; + + ///< The current position of the plot in the notebook + unsigned int pos; }; typedef std::map PLOT_MAP; @@ -101,6 +104,7 @@ public: void AddPlotPanel( SIM_PANEL_BASE* aPlotPanel ); void RemovePlotPanel( SIM_PANEL_BASE* aPlotPanel ); + std::vector GetSortedPlotPanels() const; bool HasPlotPanel( SIM_PANEL_BASE* aPlotPanel ) const { @@ -122,6 +126,14 @@ public: return m_plots.at( aPlotPanel ).m_traces.cend(); } + void SetPlotPanelPosition( const SIM_PANEL_BASE* aPlotPanel, unsigned int pos ) + { + if( pos != m_plots.at( aPlotPanel ).pos ) + m_flagModified = true; + + m_plots.at( aPlotPanel ).pos = pos; + } + void SetSimCommand( const SIM_PANEL_BASE* aPlotPanel, const wxString& aSimCommand ) { if( m_plots.at( aPlotPanel ).m_simCommand != aSimCommand ) @@ -135,14 +147,16 @@ public: return m_plots.at( aPlotPanel ).m_simCommand; } - const PLOT_MAP GetPlots() const { return m_plots; } + PLOT_INFO GetPlot( const SIM_PANEL_BASE* aPlotPanel ) const + { + return m_plots.at( aPlotPanel ); + } const TRACE_MAP GetTraces( const SIM_PANEL_BASE* aPlotPanel ) const { return m_plots.at( aPlotPanel ).m_traces; } - void ClrModified() { m_flagModified = false; } bool IsModified() const { return m_flagModified; }