CURSOR class for simulation plot

This commit is contained in:
Maciej Suminski 2016-08-11 14:41:22 +02:00
parent 24bccb00d6
commit ba99dfdabf
2 changed files with 133 additions and 19 deletions

View File

@ -28,6 +28,67 @@
#include <algorithm> #include <algorithm>
#include <limits> #include <limits>
void CURSOR::Plot( wxDC& aDC, mpWindow& aWindow )
{
if( !m_visible )
return;
const auto& dataX = m_trace->GetDataX();
const auto& dataY = m_trace->GetDataY();
if( dataX.size() <= 1 )
return;
if( m_moved )
{
m_coords.x = aWindow.p2x( m_dim.x );
// Find the closest point coordinates
auto maxXIt = std::upper_bound( dataX.begin(), dataX.end(), m_coords.x );
int maxIdx = maxXIt - dataX.begin();
int minIdx = maxIdx - 1;
// Out of bounds checks
if( minIdx < 0 )
{
minIdx = 0;
maxIdx = 1;
m_coords.x = dataX[0];
}
else if( maxIdx >= (int) dataX.size() )
{
maxIdx = dataX.size() - 1;
minIdx = maxIdx - 1;
m_coords.x = dataX[maxIdx];
}
const double leftX = dataX[minIdx];
const double rightX = dataX[maxIdx];
const double leftY = dataY[minIdx];
const double rightY = dataY[maxIdx];
m_coords.y = leftY + ( rightY - leftY ) / ( rightX - leftX ) * ( m_coords.x - leftX );
m_moved = false;
}
else
{
UpdateReference();
}
// Line length in horizontal and vertical dimensions
const int horLen = aWindow.GetScrX();
const int verLen = aWindow.GetScrY();
const wxPoint cursorPos( m_window->x2p( m_coords.x ), m_window->y2p( m_coords.y ) );
aDC.SetPen( wxPen( *wxBLACK, 1, m_continuous ? wxSOLID : wxLONG_DASH ) );
aDC.DrawLine( -horLen, cursorPos.y, horLen, cursorPos.y );
aDC.DrawLine( cursorPos.x, -verLen, cursorPos.x, verLen );
}
SIM_PLOT_PANEL::SIM_PLOT_PANEL( wxWindow* parent, wxWindowID id, const wxPoint& pos, SIM_PLOT_PANEL::SIM_PLOT_PANEL( wxWindow* parent, wxWindowID id, const wxPoint& pos,
const wxSize& size, long style, const wxString& name ) const wxSize& size, long style, const wxString& name )
: mpWindow( parent, id, pos, size, style ), m_colorIdx( 0 ) : mpWindow( parent, id, pos, size, style ), m_colorIdx( 0 )

View File

@ -28,22 +28,9 @@
#include <widgets/mathplot.h> #include <widgets/mathplot.h>
class SIM_PLOT_PANEL : public mpWindow class TRACE : public mpFXYVector
{ {
public: public:
SIM_PLOT_PANEL( wxWindow* parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize, long style = 0, const wxString& name = wxPanelNameStr );
~SIM_PLOT_PANEL();
void AddTrace( const wxString& aSpiceName, const wxString& aTitle, int aPoints,
const double* aT, const double* aY, int aFlags );
void DeleteTraces();
class TRACE : public mpFXYVector
{
public:
TRACE( const wxString& aTitle, const wxString& aSpiceName ) TRACE( const wxString& aTitle, const wxString& aSpiceName )
: mpFXYVector( aTitle ), m_spiceName( aSpiceName ) : mpFXYVector( aTitle ), m_spiceName( aSpiceName )
{ {
@ -56,9 +43,75 @@ public:
return m_spiceName; return m_spiceName;
} }
private: const std::vector<double>& GetDataX() const
{
return m_xs;
}
const std::vector<double>& GetDataY() const
{
return m_ys;
}
private:
wxString m_spiceName; wxString m_spiceName;
}; };
class CURSOR : public mpInfoLayer
{
public:
CURSOR( const TRACE* aTrace, mpWindow* aWindow )
: mpInfoLayer( wxRect( 0, 0, DRAG_MARGIN, DRAG_MARGIN ), wxTRANSPARENT_BRUSH ),
m_trace( aTrace ), m_moved( false ), m_coords( 0.0, 0.0 ), m_window( aWindow )
{
}
void Plot( wxDC& aDC, mpWindow& aWindow ) override;
bool Inside( wxPoint& aPoint )
{
return ( std::abs( aPoint.x - m_window->x2p( m_coords.x ) ) <= DRAG_MARGIN )
&& ( std::abs( aPoint.y - m_window->y2p( m_coords.y ) ) <= DRAG_MARGIN );
}
void Move( wxPoint aDelta ) override
{
m_moved = true;
mpInfoLayer::Move( aDelta );
}
void UpdateReference()
{
m_reference.x = m_window->x2p( m_coords.x );
m_reference.y = m_window->y2p( m_coords.y );
}
const wxRealPoint& GetCoords() const
{
return m_coords;
}
private:
const TRACE* m_trace;
bool m_moved;
wxRealPoint m_coords;
mpWindow* m_window;
const int DRAG_MARGIN = 10;
};
class SIM_PLOT_PANEL : public mpWindow
{
public:
SIM_PLOT_PANEL( wxWindow* parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize, long style = 0, const wxString& name = wxPanelNameStr );
~SIM_PLOT_PANEL();
void AddTrace( const wxString& aSpiceName, const wxString& aTitle, int aPoints,
const double* aT, const double* aY, int aFlags );
void DeleteTraces();
const std::vector<TRACE*>& GetTraces() const const std::vector<TRACE*>& GetTraces() const
{ {