diff --git a/eeschema/sim/sim_plot_panel.cpp b/eeschema/sim/sim_plot_panel.cpp index 0369e5800a..e353730353 100644 --- a/eeschema/sim/sim_plot_panel.cpp +++ b/eeschema/sim/sim_plot_panel.cpp @@ -28,6 +28,67 @@ #include #include + +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, const wxSize& size, long style, const wxString& name ) : mpWindow( parent, id, pos, size, style ), m_colorIdx( 0 ) diff --git a/eeschema/sim/sim_plot_panel.h b/eeschema/sim/sim_plot_panel.h index b484d8ef0e..0b73f44168 100644 --- a/eeschema/sim/sim_plot_panel.h +++ b/eeschema/sim/sim_plot_panel.h @@ -28,6 +28,78 @@ #include +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& GetDataX() const + { + return m_xs; + } + + const std::vector& 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 { public: @@ -41,25 +113,6 @@ public: 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& GetTraces() const { return m_traces;