From b480710b16ac3b941ba55fd981f441fc6724c386 Mon Sep 17 00:00:00 2001 From: Robert Roebling Date: Sun, 27 Feb 2000 15:56:24 +0000 Subject: [PATCH] More wxPlotWindow goodies. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@6312 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/generic/plot.h | 75 +++++++++++++++- samples/plot/plot.cpp | 6 ++ src/generic/plot.cpp | 175 +++++++++++++++++++++++++++++++++++++- 3 files changed, 254 insertions(+), 2 deletions(-) diff --git a/include/wx/generic/plot.h b/include/wx/generic/plot.h index 7d36701c35..9f7c8d3d3d 100644 --- a/include/wx/generic/plot.h +++ b/include/wx/generic/plot.h @@ -22,6 +22,7 @@ #include "wx/scrolwin.h" #include "wx/event.h" +#include "wx/dynarray.h" //----------------------------------------------------------------------------- // classes @@ -29,6 +30,7 @@ class WXDLLEXPORT wxPlotEvent; class WXDLLEXPORT wxPlotCurve; +class WXDLLEXPORT wxPlotValues; class WXDLLEXPORT wxPlotArea; class WXDLLEXPORT wxPlotXAxisArea; class WXDLLEXPORT wxPlotYAxisArea; @@ -103,15 +105,74 @@ public: { m_offsetY = offsetY; } int GetOffsetY() { return m_offsetY; } + + void SetPenNormal( const wxPen &pen ) + { m_penNormal = pen; } + void SetPenSelected( const wxPen &pen ) + { m_penSelected = pen; } private: int m_offsetY; double m_startY; double m_endY; + wxPen m_penNormal; + wxPen m_penSelected; DECLARE_ABSTRACT_CLASS(wxPlotCurve) }; +//----------------------------------------------------------------------------- +// wxPlotOnOffCurve +//----------------------------------------------------------------------------- + +class WXDLLEXPORT wxPlotOnOff +{ +public: + wxPlotOnOff() { } + + wxInt32 m_on; + wxInt32 m_off; + void *m_clientData; +}; + +WX_DECLARE_EXPORTED_OBJARRAY(wxPlotOnOff, wxArrayPlotOnOff); + +class WXDLLEXPORT wxPlotOnOffCurve: public wxObject +{ +public: + wxPlotOnOffCurve( int offsetY ); + + wxInt32 GetStartX() + { return m_minX; } + wxInt32 GetEndX() + { return m_maxX; } + + void SetOffsetY( int offsetY ) + { m_offsetY = offsetY; } + int GetOffsetY() + { return m_offsetY; } + + void Add( wxInt32 on, wxInt32 off, void *clientData = NULL ); + size_t GetCount(); + + wxInt32 GetOn( size_t index ); + wxInt32 GetOff( size_t index ); + void* GetClientData( size_t index ); + wxPlotOnOff *GetAt( size_t index ); + + virtual void DrawOnLine( wxDC &dc, wxCoord y, wxCoord start, wxCoord end, void *clientData ); + virtual void DrawOffLine( wxDC &dc, wxCoord y, wxCoord start, wxCoord end ); + +private: + int m_offsetY; + wxInt32 m_minX; + wxInt32 m_maxX; + + wxArrayPlotOnOff m_marks; + + DECLARE_CLASS(wxPlotOnOffCurve) +}; + //----------------------------------------------------------------------------- // wxPlotArea //----------------------------------------------------------------------------- @@ -126,6 +187,7 @@ public: void OnMouse( wxMouseEvent &event ); void DrawCurve( wxDC *dc, wxPlotCurve *curve, int from = -1, int to = -1 ); + void DrawOnOffCurve( wxDC *dc, wxPlotOnOffCurve *curve, int from = -1, int to = -1 ); void DeleteCurve( wxPlotCurve *curve, int from = -1, int to = -1 ); virtual void ScrollWindow( int dx, int dy, const wxRect *rect ); @@ -193,13 +255,22 @@ public: // --------------- void Add( wxPlotCurve *curve ); + void Delete( wxPlotCurve* curve ); + size_t GetCount(); wxPlotCurve *GetAt( size_t n ); void SetCurrent( wxPlotCurve* current ); wxPlotCurve *GetCurrent(); - void Delete( wxPlotCurve* curve ); + // mark list accessors + // ------------------- + + void Add( wxPlotOnOffCurve *curve ); + void Delete( wxPlotOnOffCurve* curve ); + + size_t GetOnOffCurveCount(); + wxPlotOnOffCurve *GetOnOffCurveAt( size_t n ); // vertical representation // ----------------------- @@ -262,6 +333,8 @@ private: double m_xZoom; wxList m_curves; + wxList m_onOffCurves; + wxPlotArea *m_area; wxPlotXAxisArea *m_xaxis; wxPlotYAxisArea *m_yaxis; diff --git a/samples/plot/plot.cpp b/samples/plot/plot.cpp index 46e9c363ac..447944fd7b 100644 --- a/samples/plot/plot.cpp +++ b/samples/plot/plot.cpp @@ -124,6 +124,12 @@ MyFrame::MyFrame() m_plot->Add( new MyPlotCurve( 0, -1.5, 1.5 ) ); m_plot->Add( new MyPlotCurve( 50, -1.5, 1.5 ) ); + wxPlotOnOffCurve *oo = new wxPlotOnOffCurve( 10 ); + oo->Add( 10, 20 ); + oo->Add( 25, 30 ); + oo->Add( 100, 400 ); + oo->Add( 1000, 2000 ); + m_plot->Add( oo ); m_log = new wxTextCtrl( this, -1, "This is the log window.\n", wxPoint(0,0), wxSize(100,100), wxTE_MULTILINE ); wxLog *old_log = wxLog::SetActiveTarget( new wxLogTextCtrl( m_log ) ); diff --git a/src/generic/plot.cpp b/src/generic/plot.cpp index 9d363e9880..ba41417925 100644 --- a/src/generic/plot.cpp +++ b/src/generic/plot.cpp @@ -93,6 +93,79 @@ wxPlotCurve::wxPlotCurve( int offsetY, double startY, double endY ) m_endY = endY; } +//----------------------------------------------------------------------------- +// wxPlotOnOffCurve +//----------------------------------------------------------------------------- + +IMPLEMENT_CLASS(wxPlotOnOffCurve, wxObject) + +#include "wx/arrimpl.cpp" +WX_DEFINE_OBJARRAY(wxArrayPlotOnOff); + +wxPlotOnOffCurve::wxPlotOnOffCurve( int offsetY ) +{ + m_offsetY = offsetY; + m_minX = -1; + m_maxX = -1; +} + +void wxPlotOnOffCurve::Add( wxInt32 on, wxInt32 off, void *clientData ) +{ + wxASSERT_MSG( on > 0, wxT("plot index < 0") ); + wxASSERT( on <= off ); + + if (m_minX == -1) + m_minX = on; + if (off > m_maxX) + m_maxX = off; + + wxPlotOnOff *v = new wxPlotOnOff; + v->m_on = on; + v->m_off = off; + v->m_clientData = clientData; + m_marks.Add( v ); +} + +size_t wxPlotOnOffCurve::GetCount() +{ + return m_marks.GetCount(); +} + +wxInt32 wxPlotOnOffCurve::GetOn( size_t index ) +{ + wxPlotOnOff *v = &m_marks.Item( index ); + return v->m_on; +} + +wxInt32 wxPlotOnOffCurve::GetOff( size_t index ) +{ + wxPlotOnOff *v = &m_marks.Item( index ); + return v->m_off; +} + +void* wxPlotOnOffCurve::GetClientData( size_t index ) +{ + wxPlotOnOff *v = &m_marks.Item( index ); + return v->m_clientData; +} + +wxPlotOnOff *wxPlotOnOffCurve::GetAt( size_t index ) +{ + return &m_marks.Item( index ); +} + +void wxPlotOnOffCurve::DrawOnLine( wxDC &dc, wxCoord y, wxCoord start, wxCoord end, void *WXUNUSED(clientData) ) +{ + dc.DrawLine( start, y, start, y-30 ); + dc.DrawLine( start, y-30, end, y-30 ); + dc.DrawLine( end, y-30, end, y ); +} + +void wxPlotOnOffCurve::DrawOffLine( wxDC &dc, wxCoord y, wxCoord start, wxCoord end ) +{ + dc.DrawLine( start, y, end, y ); +} + //----------------------------------------------------------------------------- // wxPlotArea //----------------------------------------------------------------------------- @@ -224,6 +297,66 @@ void wxPlotArea::DrawCurve( wxDC *dc, wxPlotCurve *curve, int from, int to ) } } +void wxPlotArea::DrawOnOffCurve( wxDC *dc, wxPlotOnOffCurve *curve, int from, int to ) +{ + int view_x; + int view_y; + m_owner->GetViewStart( &view_x, &view_y ); + view_x *= wxPLOT_SCROLL_STEP; + + if (from == -1) + from = view_x; + + int client_width; + int client_height; + GetClientSize( &client_width, &client_height); + + if (to == -1) + to = view_x + client_width; + + double zoom = m_owner->GetZoom(); + + int start_x = wxMax( from, (int)floor(curve->GetStartX()*zoom) ); + int end_x = wxMin( to, (int)floor(curve->GetEndX()*zoom) ); + + start_x = wxMax( view_x, start_x ); + end_x = wxMin( view_x + client_width, end_x ); + + end_x++; + + wxCoord offset_y = curve->GetOffsetY(); + wxCoord last_off = -5; + + if (curve->GetCount() == 0) + return; + + for (size_t index = 0; index < curve->GetCount(); index++) + { + wxPlotOnOff *p = curve->GetAt( index ); + + wxCoord on = (wxCoord)(p->m_on*zoom); + wxCoord off = (wxCoord)(p->m_off*zoom); + + if (end_x < on) + { + curve->DrawOffLine( *dc, client_height-offset_y, last_off, on ); + break; + } + + if (off >= start_x) + { + curve->DrawOffLine( *dc, client_height-offset_y, last_off, on ); + curve->DrawOnLine( *dc, client_height-offset_y, on, off, p->m_clientData ); + } + last_off = off; + } + + wxPlotOnOff *p = curve->GetAt( curve->GetCount()-1 ); + wxCoord off = (wxCoord)(p->m_off*zoom); + if (off < end_x) + curve->DrawOffLine( *dc, client_height-offset_y, off, to ); +} + void wxPlotArea::OnPaint( wxPaintEvent &WXUNUSED(event) ) { int view_x; @@ -258,7 +391,7 @@ void wxPlotArea::OnPaint( wxPaintEvent &WXUNUSED(event) ) wxNode *node = m_owner->m_curves.First(); while (node) { - wxPlotCurve *curve = (wxPlotCurve*)node->Data(); + wxPlotCurve *curve = (wxPlotCurve*) node->Data(); if (curve == m_owner->GetCurrent()) dc.SetPen( *wxBLACK_PEN ); @@ -269,6 +402,19 @@ void wxPlotArea::OnPaint( wxPaintEvent &WXUNUSED(event) ) node = node->Next(); } + + dc.SetPen( *wxRED_PEN ); + + node = m_owner->m_onOffCurves.First(); + while (node) + { + wxPlotOnOffCurve *curve = (wxPlotOnOffCurve*) node->Data(); + + DrawOnOffCurve( &dc, curve, update_x-1, update_x+update_width+2 ); + + node = node->Next(); + } + upd ++; } } @@ -676,6 +822,33 @@ wxPlotCurve *wxPlotWindow::GetCurrent() return m_current; } +void wxPlotWindow::Add( wxPlotOnOffCurve *curve ) +{ + m_onOffCurves.Append( curve ); +} + +void wxPlotWindow::Delete( wxPlotOnOffCurve* curve ) +{ + wxNode *node = m_onOffCurves.Find( curve ); + if (!node) return; + + m_onOffCurves.DeleteObject( curve ); +} + +size_t wxPlotWindow::GetOnOffCurveCount() +{ + return m_onOffCurves.GetCount(); +} + +wxPlotOnOffCurve *wxPlotWindow::GetOnOffCurveAt( size_t n ) +{ + wxNode *node = m_onOffCurves.Nth( n ); + if (!node) + return (wxPlotOnOffCurve*) NULL; + + return (wxPlotOnOffCurve*) node->Data(); +} + void wxPlotWindow::Move( wxPlotCurve* curve, int pixels_up ) { m_area->DeleteCurve( curve ); -- 2.45.2