]>
git.saurik.com Git - wxWidgets.git/blob - src/generic/plot.cpp
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 );