CURSOR class for simulation plot
This commit is contained in:
parent
24bccb00d6
commit
ba99dfdabf
|
@ -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 )
|
||||||
|
|
|
@ -28,6 +28,78 @@
|
||||||
|
|
||||||
#include <widgets/mathplot.h>
|
#include <widgets/mathplot.h>
|
||||||
|
|
||||||
|
class TRACE : public mpFXYVector
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TRACE( const wxString& aTitle, const wxString& aSpiceName )
|
||||||
|
: mpFXYVector( aTitle ), m_spiceName( aSpiceName )
|
||||||
|
{
|
||||||
|
SetContinuity( true );
|
||||||
|
ShowName( false );
|
||||||
|
}
|
||||||
|
|
||||||
|
const wxString& GetSpiceName() const
|
||||||
|
{
|
||||||
|
return m_spiceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<double>& GetDataX() const
|
||||||
|
{
|
||||||
|
return m_xs;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<double>& GetDataY() const
|
||||||
|
{
|
||||||
|
return m_ys;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
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
|
class SIM_PLOT_PANEL : public mpWindow
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -41,25 +113,6 @@ public:
|
||||||
|
|
||||||
void DeleteTraces();
|
void DeleteTraces();
|
||||||
|
|
||||||
class TRACE : public mpFXYVector
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
TRACE( const wxString& aTitle, const wxString& aSpiceName )
|
|
||||||
: mpFXYVector( aTitle ), m_spiceName( aSpiceName )
|
|
||||||
{
|
|
||||||
SetContinuity( true );
|
|
||||||
ShowName( false );
|
|
||||||
}
|
|
||||||
|
|
||||||
const wxString& GetSpiceName() const
|
|
||||||
{
|
|
||||||
return m_spiceName;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
wxString m_spiceName;
|
|
||||||
};
|
|
||||||
|
|
||||||
const std::vector<TRACE*>& GetTraces() const
|
const std::vector<TRACE*>& GetTraces() const
|
||||||
{
|
{
|
||||||
return m_traces;
|
return m_traces;
|
||||||
|
|
Loading…
Reference in New Issue