From f433037dcd14e835bafdd047d9043eca67b5452f Mon Sep 17 00:00:00 2001 From: Jonatan Liljedahl Date: Tue, 19 Nov 2019 17:17:37 +0100 Subject: [PATCH] Eeschema: simulator: allow dotted traces for current and phase. ADD: Allow drawing of current and phase traces with dotted style for easier differentiation from voltage and magnitude. The option is available in the View menu of the simulator. --- common/widgets/mathplot.cpp | 38 ++++++++++------------------ eeschema/sim/sim_plot_frame.cpp | 17 +++++++++++++ eeschema/sim/sim_plot_frame.h | 2 ++ eeschema/sim/sim_plot_frame_base.cpp | 9 +++++++ eeschema/sim/sim_plot_frame_base.fbp | 21 ++++++++++++++- eeschema/sim/sim_plot_frame_base.h | 3 +++ eeschema/sim/sim_plot_panel.cpp | 12 ++++++++- eeschema/sim/sim_plot_panel.h | 22 ++++++++++++++++ include/widgets/mathplot.h | 4 +++ 9 files changed, 101 insertions(+), 27 deletions(-) diff --git a/common/widgets/mathplot.cpp b/common/widgets/mathplot.cpp index 371a5b92a3..d4ef2e4abb 100644 --- a/common/widgets/mathplot.cpp +++ b/common/widgets/mathplot.cpp @@ -696,8 +696,8 @@ void mpFXY::Plot( wxDC& dc, mpWindow& w ) } else { - wxCoord x0, y0; - bool first = true; + wxPoint* points = new wxPoint[GetCount()]; + int count = 0; while( GetNextXY( x, y ) ) { @@ -707,30 +707,13 @@ void mpFXY::Plot( wxDC& dc, mpWindow& w ) wxCoord x1 = w.x2p( px ); wxCoord y1 = w.y2p( py ); - if( first ) - { - first = false; - x0 = x1; - y0 = y1; - continue; - } - -// This gives disastrous results with very high-frequency plots where the -// X coordinate may not increment until several waves later -// -// if( x0 == x1 ) // continue until a new X coordinate is reached -// continue; - - bool outDown = ( y0 > maxYpx ) && ( y1 > maxYpx ); - bool outUp = ( y0 < minYpx ) && ( y1 < minYpx ); - bool outLeft = ( x1 < startPx ) && ( x0 < startPx ); - bool outRight = ( x1 > endPx ) && ( x0 > endPx ); - if( !( outUp || outDown || outLeft || outRight ) ) - dc.DrawLine( x0, y0, x1, y1 ); - - x0 = x1; - y0 = y1; + points[count++] = wxPoint( x1, y1 ); } + + if( count > 0 ) + dc.DrawLines( count, points ); + + delete[] points; } if( !m_name.IsEmpty() && m_showName ) @@ -3377,6 +3360,11 @@ void mpFXYVector::Rewind() m_index = 0; } +size_t mpFXYVector::GetCount() +{ + return m_xs.size(); +} + bool mpFXYVector::GetNextXY( double& x, double& y ) { diff --git a/eeschema/sim/sim_plot_frame.cpp b/eeschema/sim/sim_plot_frame.cpp index 3b9831ce22..54627bec76 100644 --- a/eeschema/sim/sim_plot_frame.cpp +++ b/eeschema/sim/sim_plot_frame.cpp @@ -1084,6 +1084,23 @@ void SIM_PLOT_FRAME::menuShowLegendUpdate( wxUpdateUIEvent& event ) } +void SIM_PLOT_FRAME::menuShowDotted( wxCommandEvent& event ) +{ + SIM_PLOT_PANEL* plot = CurrentPlot(); + + if( plot ) + plot->SetDottedCurrentPhase( !plot->GetDottedCurrentPhase() ); +} + + +void SIM_PLOT_FRAME::menuShowDottedUpdate( wxUpdateUIEvent& event ) +{ + SIM_PLOT_PANEL* plot = CurrentPlot(); + + event.Check( plot ? plot->GetDottedCurrentPhase() : false ); +} + + void SIM_PLOT_FRAME::onPlotClose( wxAuiNotebookEvent& event ) { int idx = event.GetSelection(); diff --git a/eeschema/sim/sim_plot_frame.h b/eeschema/sim/sim_plot_frame.h index 496ca27f22..78a0e71b09 100644 --- a/eeschema/sim/sim_plot_frame.h +++ b/eeschema/sim/sim_plot_frame.h @@ -257,6 +257,8 @@ private: 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; // Event handlers void onPlotChanged( wxAuiNotebookEvent& event ) override; diff --git a/eeschema/sim/sim_plot_frame_base.cpp b/eeschema/sim/sim_plot_frame_base.cpp index 256e6b2c75..ad529d391f 100644 --- a/eeschema/sim/sim_plot_frame_base.cpp +++ b/eeschema/sim/sim_plot_frame_base.cpp @@ -97,6 +97,12 @@ SIM_PLOT_FRAME_BASE::SIM_PLOT_FRAME_BASE( wxWindow* parent, wxWindowID id, const 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 ); + m_mainMenu->Append( m_viewMenu, _("View") ); this->SetMenuBar( m_mainMenu ); @@ -298,6 +304,8 @@ SIM_PLOT_FRAME_BASE::SIM_PLOT_FRAME_BASE( wxWindow* parent, wxWindowID id, const 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_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_signals->Connect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( SIM_PLOT_FRAME_BASE::onSignalDblClick ), NULL, this ); @@ -309,6 +317,7 @@ SIM_PLOT_FRAME_BASE::~SIM_PLOT_FRAME_BASE() // Disconnect Events 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 ) ); 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_signals->Disconnect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( SIM_PLOT_FRAME_BASE::onSignalDblClick ), NULL, this ); diff --git a/eeschema/sim/sim_plot_frame_base.fbp b/eeschema/sim/sim_plot_frame_base.fbp index 8b6d2417cf..aee87dd41e 100644 --- a/eeschema/sim/sim_plot_frame_base.fbp +++ b/eeschema/sim/sim_plot_frame_base.fbp @@ -272,7 +272,7 @@ - + View m_viewMenu protected @@ -352,6 +352,25 @@ menuShowLegend menuShowLegendUpdate + + m_separator21 + none + + + + 0 + 1 + + ID_MENU_DOTTED + wxITEM_CHECK + Dotted current/phase + m_showDotted + none + + + menuShowDotted + menuShowDottedUpdate + diff --git a/eeschema/sim/sim_plot_frame_base.h b/eeschema/sim/sim_plot_frame_base.h index 29a7e790a5..2633d87442 100644 --- a/eeschema/sim/sim_plot_frame_base.h +++ b/eeschema/sim/sim_plot_frame_base.h @@ -42,6 +42,7 @@ #define ID_MENU_SET_SIMUL 1007 #define ID_MENU_SHOW_GRID 1008 #define ID_MENU_SHOW_LEGEND 1009 +#define ID_MENU_DOTTED 1010 /////////////////////////////////////////////////////////////////////////////// /// Class SIM_PLOT_FRAME_BASE @@ -105,6 +106,8 @@ class SIM_PLOT_FRAME_BASE : public KIWAY_PLAYER 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 onPlotChanged( wxAuiNotebookEvent& event ) { event.Skip(); } virtual void onPlotClose( wxAuiNotebookEvent& event ) { event.Skip(); } virtual void onSignalDblClick( wxMouseEvent& event ) { event.Skip(); } diff --git a/eeschema/sim/sim_plot_panel.cpp b/eeschema/sim/sim_plot_panel.cpp index 39a523746d..56de7cc2cd 100644 --- a/eeschema/sim/sim_plot_panel.cpp +++ b/eeschema/sim/sim_plot_panel.cpp @@ -461,6 +461,16 @@ bool SIM_PLOT_PANEL::IsPlottable( SIM_TYPE aSimType ) } +void SIM_PLOT_PANEL::UpdateTraceStyle( TRACE* trace ) +{ + int flags = trace->GetFlags(); + wxPenStyle penStyle = ( ( flags & SPT_AC_PHASE || flags & SPT_CURRENT ) && m_dotted_cp ) ? + wxPENSTYLE_DOT : + wxPENSTYLE_SOLID; + trace->SetPen( wxPen( trace->GetTraceColour(), 2, penStyle ) ); +} + + bool SIM_PLOT_PANEL::AddTrace( const wxString& aName, int aPoints, const double* aX, const double* aY, SIM_PLOT_TYPE aFlags ) { @@ -494,7 +504,7 @@ bool SIM_PLOT_PANEL::AddTrace( const wxString& aName, int aPoints, // New entry trace = new TRACE( aName ); trace->SetTraceColour( generateColor() ); - trace->SetPen( wxPen( trace->GetTraceColour(), 2, wxPENSTYLE_SOLID ) ); + UpdateTraceStyle( trace ); m_traces[aName] = trace; // It is a trick to keep legend & coords always on the top diff --git a/eeschema/sim/sim_plot_panel.h b/eeschema/sim/sim_plot_panel.h index 75b12fb988..919adebf34 100644 --- a/eeschema/sim/sim_plot_panel.h +++ b/eeschema/sim/sim_plot_panel.h @@ -242,6 +242,23 @@ public: return m_legend->IsVisible(); } + void SetDottedCurrentPhase( bool aEnable ) + { + m_dotted_cp = aEnable; + + for( const auto& tr : m_traces ) + { + UpdateTraceStyle( tr.second ); + } + + UpdateAll(); + } + + bool GetDottedCurrentPhase() const + { + return m_dotted_cp; + } + ///> Returns true if the trace has cursor shown. bool HasCursorEnabled( const wxString& aName ) const; @@ -251,6 +268,9 @@ public: ///> Resets scale ranges to fit the current traces void ResetScales(); + ///> Update trace line style + void UpdateTraceStyle( TRACE* trace ); + private: ///> Returns a new color from the palette wxColour generateColor(); @@ -266,6 +286,8 @@ private: mpScaleY* m_axis_y2; mpInfoLegend* m_legend; + bool m_dotted_cp; + std::vector m_topLevel; const SIM_TYPE m_type; diff --git a/include/widgets/mathplot.h b/include/widgets/mathplot.h index c9832e0877..dd6cde9618 100644 --- a/include/widgets/mathplot.h +++ b/include/widgets/mathplot.h @@ -605,6 +605,8 @@ public: */ virtual bool GetNextXY( double& x, double& y ) = 0; + virtual size_t GetCount() = 0; + /** Layer plot handler. * This implementation will plot the locus in the visible area and * put a label according to the alignment specified. @@ -1605,6 +1607,8 @@ protected: */ bool GetNextXY( double& x, double& y ) override; + size_t GetCount() override; + public: /** Returns the actual minimum X data (loaded in SetData). */