]>
git.saurik.com Git - wxWidgets.git/blob - src/generic/plot.cpp
6cace8f2eb698d2d19e1ed416fe7559b3877e2e6
   1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     wxPlotWindow 
   4 // Author:      Robert Roebling 
   8 // Copyright:   (c) Robert Roebling 
   9 // Licence:     wxWindows license 
  10 ///////////////////////////////////////////////////////////////////////////// 
  13 #pragma implementation "plot.h" 
  16 // For compilers that support precompilation, includes "wx.h". 
  17 #include "wx/wxprec.h" 
  24 #include "wx/object.h" 
  26 #include "wx/colour.h" 
  27 #include "wx/settings.h" 
  31 #include "wx/dcclient.h" 
  34 #include "wx/generic/plot.h" 
  38 //----------------------------------------------------------------------------- 
  40 //----------------------------------------------------------------------------- 
  42 IMPLEMENT_ABSTRACT_CLASS(wxPlotCurve
, wxObject
) 
  44 wxPlotCurve::wxPlotCurve( int offsetY
, double startY
, double endY 
) 
  51 //----------------------------------------------------------------------------- 
  53 //----------------------------------------------------------------------------- 
  55 IMPLEMENT_DYNAMIC_CLASS(wxPlotArea
, wxWindow
) 
  57 BEGIN_EVENT_TABLE(wxPlotArea
, wxWindow
) 
  58   EVT_PAINT(        wxPlotArea::OnPaint
) 
  59   EVT_LEFT_DOWN(    wxPlotArea::OnMouse
) 
  62 wxPlotArea::wxPlotArea( wxPlotWindow 
*parent 
) 
  63         : wxWindow( parent
, -1, wxDefaultPosition
, wxDefaultSize
, wxSIMPLE_BORDER
, "plotarea" ) 
  67     SetBackgroundColour( *wxWHITE 
); 
  70 void wxPlotArea::OnMouse( wxMouseEvent 
&event 
) 
  74     GetClientSize( &client_width
, &client_height
); 
  77     m_owner
->GetViewStart( &view_x
, &view_y 
); 
  86     wxNode 
*node 
= m_owner
->m_curves
.First(); 
  89         wxPlotCurve 
*curve 
= (wxPlotCurve
*)node
->Data(); 
  91         double double_client_height 
= (double)client_height
; 
  92         double range 
= curve
->GetEndY() - curve
->GetStartY(); 
  93         double end 
= curve
->GetEndY(); 
  94         wxCoord offset_y 
= curve
->GetOffsetY(); 
  96         double dy 
= (end 
- curve
->GetY( x 
)) / range
; 
  97         wxCoord curve_y 
= (wxCoord
)(dy 
* double_client_height
) - offset_y 
- 1; 
  99         if ((y
-curve_y 
< 4) && (y
-curve_y 
> -4)) 
 101             m_owner
->SetCurrent( curve 
); 
 109 void wxPlotArea::OnPaint( wxPaintEvent 
&WXUNUSED(event
) ) 
 113     GetClientSize( &client_width
, &client_height
); 
 116     m_owner
->GetViewStart( &view_x
, &view_y 
); 
 120     wxPaintDC 
dc( this ); 
 121     m_owner
->PrepareDC( dc 
); 
 123     wxRegionIterator 
upd( GetUpdateRegion() ); 
 127         int update_x 
= upd
.GetX(); 
 128         int update_y 
= upd
.GetY(); 
 129         int update_width 
= upd
.GetWidth(); 
 135         if (m_owner->m_current) 
 137             dc.SetPen( *wxLIGHT_GREY_PEN ); 
 138             int base_line = client_height - m_owner->m_current->GetOffsetY(); 
 139             dc.DrawLine( update_x-1, base_line-1, update_x+update_width+2, base_line-1 ); 
 143         wxNode 
*node 
= m_owner
->m_curves
.First(); 
 146             wxPlotCurve 
*curve 
= (wxPlotCurve
*)node
->Data(); 
 148             if (curve 
== m_owner
->GetCurrent()) 
 149                 dc
.SetPen( *wxBLACK_PEN 
); 
 151                 dc
.SetPen( *wxLIGHT_GREY_PEN 
); 
 153             int start_x 
= wxMax( update_x
-1, curve
->GetStartX() ); 
 154             int end_x 
= wxMin( update_x
+update_width
+2, curve
->GetEndX() ); 
 156             double double_client_height 
= (double)client_height
; 
 157             double range 
= curve
->GetEndY() - curve
->GetStartY(); 
 158             double end 
= curve
->GetEndY(); 
 159             wxCoord offset_y 
= curve
->GetOffsetY(); 
 161             wxCoord y
=0,last_y
=0; 
 162             for (int x 
= start_x
; x 
< end_x
; x
++) 
 164                 double dy 
= (end 
- curve
->GetY( x 
)) / range
; 
 165                 y 
= (wxCoord
)(dy 
* double_client_height
) - offset_y 
- 1; 
 168                     dc
.DrawLine( x
-1, last_y
, x
, y 
); 
 178 //----------------------------------------------------------------------------- 
 180 //----------------------------------------------------------------------------- 
 182 #define  ID_ENLARGE_100   1000 
 183 #define  ID_ENLARGE_50    1001 
 184 #define  ID_SHRINK_33     1002 
 185 #define  ID_SHRINK_50     1003 
 187 #define  ID_MOVE_UP       1006 
 188 #define  ID_MOVE_DOWN     1007 
 191 IMPLEMENT_DYNAMIC_CLASS(wxPlotWindow
, wxScrolledWindow
) 
 193 BEGIN_EVENT_TABLE(wxPlotWindow
, wxScrolledWindow
) 
 194   EVT_PAINT(        wxPlotWindow::OnPaint
) 
 197 wxPlotWindow::wxPlotWindow( wxWindow 
*parent
, wxWindowID id
, const wxPoint 
&pos
, const wxSize 
&size
, int flag 
) 
 198         : wxScrolledWindow( parent
, id
, pos
, size
, flag
, "plotcanvas" ) 
 200     m_area 
= new wxPlotArea( this ); 
 202     wxBoxSizer 
*mainsizer 
= new wxBoxSizer( wxHORIZONTAL 
); 
 204     wxBoxSizer 
*buttonlist 
= new wxBoxSizer( wxVERTICAL 
); 
 205     buttonlist
->Add( new wxButton( this, ID_ENLARGE_100
, _("+ 100%") ), 0, wxEXPAND
|wxALL
, 5 ); 
 206     buttonlist
->Add( new wxButton( this, ID_ENLARGE_50
, _("+ 50%") ), 0, wxEXPAND
|wxALL
, 5 ); 
 207     buttonlist
->Add( new wxButton( this, ID_SHRINK_33
, _("- 33%") ), 0, wxEXPAND
|wxALL
, 5 ); 
 208     buttonlist
->Add( new wxButton( this, ID_SHRINK_50
, _("- 50%") ), 0, wxEXPAND
|wxALL
, 5 ); 
 209     buttonlist
->Add( 20,20, 0 ); 
 210     buttonlist
->Add( new wxButton( this, ID_MOVE_UP
, _("Up") ), 0, wxEXPAND
|wxALL
, 5 ); 
 211     buttonlist
->Add( new wxButton( this, ID_MOVE_DOWN
, _("Down") ), 0, wxEXPAND
|wxALL
, 5 ); 
 212     buttonlist
->Add( 20,20, 1 ); 
 214     mainsizer
->Add( buttonlist
, 0, wxEXPAND 
); 
 216     mainsizer
->Add( m_area
, 1, wxEXPAND
|wxLEFT
, 50 ); 
 218     SetAutoLayout( TRUE 
); 
 219     SetSizer( mainsizer 
); 
 221     SetTargetWindow( m_area 
); 
 223     SetBackgroundColour( *wxWHITE 
); 
 225     m_current 
= (wxPlotCurve
*) NULL
; 
 228 wxPlotWindow::~wxPlotWindow() 
 232 void wxPlotWindow::Add( wxPlotCurve 
*curve 
) 
 234     m_curves
.Append( curve 
); 
 235     if (!m_current
) m_current 
= curve
; 
 238 size_t wxPlotWindow::GetCount() 
 240     return m_curves
.GetCount(); 
 243 wxPlotCurve 
*wxPlotWindow::GetAt( size_t n 
) 
 245     wxNode 
*node 
= m_curves
.Nth( n 
); 
 247         return (wxPlotCurve
*) NULL
; 
 249     return (wxPlotCurve
*) node
->Data(); 
 252 void wxPlotWindow::SetCurrent( wxPlotCurve
* current 
) 
 255     m_area
->Refresh( FALSE 
); 
 257     wxPoint 
pos( m_area
->GetPosition() ); 
 261     GetClientSize( &client_width
, &client_height
); 
 262     wxRect 
rect(pos
.x
-45,0,45,client_height
); 
 266 wxPlotCurve 
*wxPlotWindow::GetCurrent() 
 271 void wxPlotWindow::OnPaint( wxPaintEvent 
&WXUNUSED(event
) ) 
 273     wxPaintDC 
dc( this ); 
 275     if (!m_current
) return; 
 279     GetClientSize( &client_width
, &client_height
); 
 281     dc
.SetPen( *wxBLACK_PEN 
); 
 283     wxPoint 
pos( m_area
->GetPosition() ); 
 285     double range 
= m_current
->GetEndY() - m_current
->GetStartY(); 
 286     double offset 
= ((double) m_current
->GetOffsetY() / (double)client_height 
) * range
; 
 287     double start 
= m_current
->GetStartY() - offset
; 
 288     double end 
= m_current
->GetEndY() - offset
; 
 289     int int_log_range 
= (int)floor( log10( range 
) ); 
 291     if (int_log_range 
> 0) 
 293         for (int i 
= 0; i 
< int_log_range
; i
++) 
 296     if (int_log_range 
< 0) 
 298         for (int i 
= 0; i 
< -int_log_range
; i
++) 
 301     double lower 
= ceil(start 
/ step
) * step
; 
 302     double upper 
= floor(end 
/ step
) * step
; 
 303     int steps 
= (int)ceil((upper
-lower
)/step
); 
 307         if (lower
-step 
> start
) lower 
-= step
; 
 310     double current 
= lower
; 
 311     while (current 
< upper
+(step
/2)) 
 313         int y 
= (int)((m_current
->GetEndY()-current
) / range 
* (double)client_height
) - 1; 
 314         y 
-= m_current
->GetOffsetY(); 
 315         if ((y 
> 10) && (y 
< client_height
-7)) 
 317             dc
.DrawLine( pos
.x
-15, y
, pos
.x
-7, y 
); 
 319             label
.Printf( "%.1f", current 
); 
 320             dc
.DrawText( label
, pos
.x
-45, y
-7 ); 
 326     dc
.DrawLine( pos
.x
-15, 5, pos
.x
-15, client_height
-5 ); 
 327     dc
.DrawLine( pos
.x
-19, 9, pos
.x
-15, 5 ); 
 328     dc
.DrawLine( pos
.x
-10, 10, pos
.x
-15, 5 );