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.
This commit is contained in:
Jonatan Liljedahl 2019-11-19 17:17:37 +01:00 committed by Wayne Stambaugh
parent 3342055af6
commit f433037dcd
9 changed files with 101 additions and 27 deletions

View File

@ -696,8 +696,8 @@ void mpFXY::Plot( wxDC& dc, mpWindow& w )
} }
else else
{ {
wxCoord x0, y0; wxPoint* points = new wxPoint[GetCount()];
bool first = true; int count = 0;
while( GetNextXY( x, y ) ) while( GetNextXY( x, y ) )
{ {
@ -707,30 +707,13 @@ void mpFXY::Plot( wxDC& dc, mpWindow& w )
wxCoord x1 = w.x2p( px ); wxCoord x1 = w.x2p( px );
wxCoord y1 = w.y2p( py ); wxCoord y1 = w.y2p( py );
if( first ) points[count++] = wxPoint( x1, y1 );
{
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;
} }
if( count > 0 )
dc.DrawLines( count, points );
delete[] points;
} }
if( !m_name.IsEmpty() && m_showName ) if( !m_name.IsEmpty() && m_showName )
@ -3377,6 +3360,11 @@ void mpFXYVector::Rewind()
m_index = 0; m_index = 0;
} }
size_t mpFXYVector::GetCount()
{
return m_xs.size();
}
bool mpFXYVector::GetNextXY( double& x, double& y ) bool mpFXYVector::GetNextXY( double& x, double& y )
{ {

View File

@ -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 ) void SIM_PLOT_FRAME::onPlotClose( wxAuiNotebookEvent& event )
{ {
int idx = event.GetSelection(); int idx = event.GetSelection();

View File

@ -257,6 +257,8 @@ private:
void menuShowGridUpdate( wxUpdateUIEvent& event ) override; void menuShowGridUpdate( wxUpdateUIEvent& event ) override;
void menuShowLegend( wxCommandEvent& event ) override; void menuShowLegend( wxCommandEvent& event ) override;
void menuShowLegendUpdate( wxUpdateUIEvent& event ) override; void menuShowLegendUpdate( wxUpdateUIEvent& event ) override;
void menuShowDotted( wxCommandEvent& event ) override;
void menuShowDottedUpdate( wxUpdateUIEvent& event ) override;
// Event handlers // Event handlers
void onPlotChanged( wxAuiNotebookEvent& event ) override; void onPlotChanged( wxAuiNotebookEvent& event ) override;

View File

@ -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_showLegend = new wxMenuItem( m_viewMenu, ID_MENU_SHOW_LEGEND, wxString( _("Show &Legend") ) , wxEmptyString, wxITEM_CHECK );
m_viewMenu->Append( m_showLegend ); 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") ); m_mainMenu->Append( m_viewMenu, _("View") );
this->SetMenuBar( m_mainMenu ); 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 ) ); 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()); 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 ) ); 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_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_CLOSE, wxAuiNotebookEventHandler( SIM_PLOT_FRAME_BASE::onPlotClose ), NULL, this );
m_signals->Connect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( SIM_PLOT_FRAME_BASE::onSignalDblClick ), 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 // Disconnect Events
this->Disconnect( ID_MENU_SHOW_GRID, wxEVT_UPDATE_UI, wxUpdateUIEventHandler( SIM_PLOT_FRAME_BASE::menuShowGridUpdate ) ); 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_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_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_CLOSE, wxAuiNotebookEventHandler( SIM_PLOT_FRAME_BASE::onPlotClose ), NULL, this );
m_signals->Disconnect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( SIM_PLOT_FRAME_BASE::onSignalDblClick ), NULL, this ); m_signals->Disconnect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( SIM_PLOT_FRAME_BASE::onSignalDblClick ), NULL, this );

View File

@ -272,7 +272,7 @@
<property name="unchecked_bitmap"></property> <property name="unchecked_bitmap"></property>
</object> </object>
</object> </object>
<object class="wxMenu" expanded="0"> <object class="wxMenu" expanded="1">
<property name="label">View</property> <property name="label">View</property>
<property name="name">m_viewMenu</property> <property name="name">m_viewMenu</property>
<property name="permission">protected</property> <property name="permission">protected</property>
@ -352,6 +352,25 @@
<event name="OnMenuSelection">menuShowLegend</event> <event name="OnMenuSelection">menuShowLegend</event>
<event name="OnUpdateUI">menuShowLegendUpdate</event> <event name="OnUpdateUI">menuShowLegendUpdate</event>
</object> </object>
<object class="separator" expanded="1">
<property name="name">m_separator21</property>
<property name="permission">none</property>
</object>
<object class="wxMenuItem" expanded="1">
<property name="bitmap"></property>
<property name="checked">0</property>
<property name="enabled">1</property>
<property name="help"></property>
<property name="id">ID_MENU_DOTTED</property>
<property name="kind">wxITEM_CHECK</property>
<property name="label">Dotted current/phase</property>
<property name="name">m_showDotted</property>
<property name="permission">none</property>
<property name="shortcut"></property>
<property name="unchecked_bitmap"></property>
<event name="OnMenuSelection">menuShowDotted</event>
<event name="OnUpdateUI">menuShowDottedUpdate</event>
</object>
</object> </object>
</object> </object>
<object class="wxBoxSizer" expanded="1"> <object class="wxBoxSizer" expanded="1">

View File

@ -42,6 +42,7 @@
#define ID_MENU_SET_SIMUL 1007 #define ID_MENU_SET_SIMUL 1007
#define ID_MENU_SHOW_GRID 1008 #define ID_MENU_SHOW_GRID 1008
#define ID_MENU_SHOW_LEGEND 1009 #define ID_MENU_SHOW_LEGEND 1009
#define ID_MENU_DOTTED 1010
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
/// Class SIM_PLOT_FRAME_BASE /// 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 menuShowGridUpdate( wxUpdateUIEvent& event ) { event.Skip(); }
virtual void menuShowLegend( wxCommandEvent& event ) { event.Skip(); } virtual void menuShowLegend( wxCommandEvent& event ) { event.Skip(); }
virtual void menuShowLegendUpdate( wxUpdateUIEvent& 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 onPlotChanged( wxAuiNotebookEvent& event ) { event.Skip(); }
virtual void onPlotClose( wxAuiNotebookEvent& event ) { event.Skip(); } virtual void onPlotClose( wxAuiNotebookEvent& event ) { event.Skip(); }
virtual void onSignalDblClick( wxMouseEvent& event ) { event.Skip(); } virtual void onSignalDblClick( wxMouseEvent& event ) { event.Skip(); }

View File

@ -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, bool SIM_PLOT_PANEL::AddTrace( const wxString& aName, int aPoints,
const double* aX, const double* aY, SIM_PLOT_TYPE aFlags ) 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 // New entry
trace = new TRACE( aName ); trace = new TRACE( aName );
trace->SetTraceColour( generateColor() ); trace->SetTraceColour( generateColor() );
trace->SetPen( wxPen( trace->GetTraceColour(), 2, wxPENSTYLE_SOLID ) ); UpdateTraceStyle( trace );
m_traces[aName] = trace; m_traces[aName] = trace;
// It is a trick to keep legend & coords always on the top // It is a trick to keep legend & coords always on the top

View File

@ -242,6 +242,23 @@ public:
return m_legend->IsVisible(); 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. ///> Returns true if the trace has cursor shown.
bool HasCursorEnabled( const wxString& aName ) const; bool HasCursorEnabled( const wxString& aName ) const;
@ -251,6 +268,9 @@ public:
///> Resets scale ranges to fit the current traces ///> Resets scale ranges to fit the current traces
void ResetScales(); void ResetScales();
///> Update trace line style
void UpdateTraceStyle( TRACE* trace );
private: private:
///> Returns a new color from the palette ///> Returns a new color from the palette
wxColour generateColor(); wxColour generateColor();
@ -266,6 +286,8 @@ private:
mpScaleY* m_axis_y2; mpScaleY* m_axis_y2;
mpInfoLegend* m_legend; mpInfoLegend* m_legend;
bool m_dotted_cp;
std::vector<mpLayer*> m_topLevel; std::vector<mpLayer*> m_topLevel;
const SIM_TYPE m_type; const SIM_TYPE m_type;

View File

@ -605,6 +605,8 @@ public:
*/ */
virtual bool GetNextXY( double& x, double& y ) = 0; virtual bool GetNextXY( double& x, double& y ) = 0;
virtual size_t GetCount() = 0;
/** Layer plot handler. /** Layer plot handler.
* This implementation will plot the locus in the visible area and * This implementation will plot the locus in the visible area and
* put a label according to the alignment specified. * put a label according to the alignment specified.
@ -1605,6 +1607,8 @@ protected:
*/ */
bool GetNextXY( double& x, double& y ) override; bool GetNextXY( double& x, double& y ) override;
size_t GetCount() override;
public: public:
/** Returns the actual minimum X data (loaded in SetData). /** Returns the actual minimum X data (loaded in SetData).
*/ */