]> git.saurik.com Git - wxWidgets.git/blob - src/generic/plot.cpp
Add draft wxPlotWindow
[wxWidgets.git] / src / generic / plot.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: plot.cpp
3 // Purpose: wxPlotWindow
4 // Author: Robert Roebling
5 // Modified by:
6 // Created: 12/01/2000
7 // RCS-ID: $Id$
8 // Copyright: (c) Robert Roebling
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "plot.h"
14 #endif
15
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #ifndef WX_PRECOMP
24 #include "wx/object.h"
25 #include "wx/font.h"
26 #include "wx/colour.h"
27 #include "wx/settings.h"
28 #include "wx/sizer.h"
29 #include "wx/log.h"
30 #include "wx/intl.h"
31 #include "wx/dcclient.h"
32 #endif
33
34 #include "wx/generic/plot.h"
35
36 //-----------------------------------------------------------------------------
37 // wxPlotCurve
38 //-----------------------------------------------------------------------------
39
40 IMPLEMENT_ABSTRACT_CLASS(wxPlotCurve, wxObject)
41
42 wxPlotCurve::wxPlotCurve( int offsetY )
43 {
44 m_offsetY = offsetY;
45 }
46
47 //-----------------------------------------------------------------------------
48 // wxPlotArea
49 //-----------------------------------------------------------------------------
50
51 IMPLEMENT_DYNAMIC_CLASS(wxPlotArea, wxWindow)
52
53 BEGIN_EVENT_TABLE(wxPlotArea, wxWindow)
54 EVT_PAINT( wxPlotArea::OnPaint)
55 EVT_LEFT_DOWN( wxPlotArea::OnMouse)
56 END_EVENT_TABLE()
57
58 wxPlotArea::wxPlotArea( wxPlotWindow *parent )
59 : wxWindow( parent, -1, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER, "plotarea" )
60 {
61 m_owner = parent;
62
63 SetBackgroundColour( *wxWHITE );
64 }
65
66 void wxPlotArea::OnMouse( wxMouseEvent &event )
67 {
68 int client_width;
69 int client_height;
70 GetClientSize( &client_width, &client_height);
71 int view_x;
72 int view_y;
73 m_owner->GetViewStart( &view_x, &view_y );
74 view_x *= 10;
75 view_y *= 10;
76
77 int x = event.GetX();
78 int y = event.GetY();
79 x += view_x;
80 y += view_y;
81
82 wxNode *node = m_owner->m_curves.First();
83 while (node)
84 {
85 wxPlotCurve *curve = (wxPlotCurve*)node->Data();
86
87 wxCoord offset_y = client_height - curve->GetOffsetY();
88
89 double dy = curve->GetY( x );
90 int curve_y = (wxCoord)(-dy * 100) + offset_y - 1;
91 if ((y-curve_y < 4) && (y-curve_y > -4))
92 {
93 m_owner->SetCurrent( curve );
94 return;
95 }
96
97 node = node->Next();
98 }
99 }
100
101 void wxPlotArea::OnPaint( wxPaintEvent &WXUNUSED(event) )
102 {
103 int client_width;
104 int client_height;
105 GetClientSize( &client_width, &client_height);
106 int view_x;
107 int view_y;
108 m_owner->GetViewStart( &view_x, &view_y );
109 view_x *= 10;
110 view_y *= 10;
111
112 wxPaintDC dc( this );
113 m_owner->PrepareDC( dc );
114
115 wxRegionIterator upd( GetUpdateRegion() );
116
117 while (upd)
118 {
119 int update_x = upd.GetX();
120 int update_y = upd.GetY();
121 int update_width = upd.GetWidth();
122
123 update_x += view_x;
124 update_y += view_y;
125
126 if (m_owner->m_current)
127 {
128 dc.SetPen( *wxLIGHT_GREY_PEN );
129 int base_line = client_height - m_owner->m_current->GetOffsetY();
130 dc.DrawLine( update_x-1, base_line-1, update_x+update_width+2, base_line-1 );
131 }
132
133 wxNode *node = m_owner->m_curves.First();
134 while (node)
135 {
136 wxPlotCurve *curve = (wxPlotCurve*)node->Data();
137
138 if (curve == m_owner->GetCurrent())
139 dc.SetPen( *wxBLACK_PEN );
140 else
141 dc.SetPen( *wxLIGHT_GREY_PEN );
142 wxCoord offset_y = client_height - curve->GetOffsetY();
143
144 int start_x = wxMax( update_x-1, curve->GetStartX() );
145 int end_x = wxMin( update_x+update_width+2, curve->GetEndX() );
146
147 wxCoord y=0,last_y=0;
148 for (int x = start_x; x < end_x; x++)
149 {
150 double dy = curve->GetY( x );
151 y = (wxCoord)(-dy * 100) + offset_y - 1;
152
153 if (x != start_x)
154 dc.DrawLine( x-1, last_y, x, y );
155
156 last_y = y;
157 }
158 node = node->Next();
159 }
160 upd ++;
161 }
162 }
163
164 //-----------------------------------------------------------------------------
165 // wxPlotWindow
166 //-----------------------------------------------------------------------------
167
168 #define ID_ENLARGE_100 1000
169 #define ID_ENLARGE_50 1001
170 #define ID_SHRINK_33 1002
171 #define ID_SHRINK_50 1003
172
173 #define ID_MOVE_UP 1006
174 #define ID_MOVE_DOWN 1007
175
176
177 IMPLEMENT_DYNAMIC_CLASS(wxPlotWindow, wxScrolledWindow)
178
179 BEGIN_EVENT_TABLE(wxPlotWindow, wxScrolledWindow)
180 EVT_PAINT( wxPlotWindow::OnPaint)
181 END_EVENT_TABLE()
182
183 wxPlotWindow::wxPlotWindow( wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, int flag )
184 : wxScrolledWindow( parent, id, pos, size, flag, "plotcanvas" )
185 {
186 m_area = new wxPlotArea( this );
187
188 wxBoxSizer *mainsizer = new wxBoxSizer( wxHORIZONTAL );
189
190 wxBoxSizer *buttonlist = new wxBoxSizer( wxVERTICAL );
191 buttonlist->Add( new wxButton( this, ID_ENLARGE_100, _("+ 100%") ), 0, wxEXPAND|wxALL, 5 );
192 buttonlist->Add( new wxButton( this, ID_ENLARGE_50, _("+ 50%") ), 0, wxEXPAND|wxALL, 5 );
193 buttonlist->Add( new wxButton( this, ID_SHRINK_33, _("- 33%") ), 0, wxEXPAND|wxALL, 5 );
194 buttonlist->Add( new wxButton( this, ID_SHRINK_50, _("- 50%") ), 0, wxEXPAND|wxALL, 5 );
195 buttonlist->Add( 20,20, 0 );
196 buttonlist->Add( new wxButton( this, ID_MOVE_UP, _("Up") ), 0, wxEXPAND|wxALL, 5 );
197 buttonlist->Add( new wxButton( this, ID_MOVE_DOWN, _("Down") ), 0, wxEXPAND|wxALL, 5 );
198 buttonlist->Add( 20,20, 1 );
199
200 mainsizer->Add( buttonlist, 0, wxEXPAND );
201
202 mainsizer->Add( m_area, 1, wxEXPAND|wxLEFT, 50 );
203
204 SetAutoLayout( TRUE );
205 SetSizer( mainsizer );
206
207 SetTargetWindow( m_area );
208
209 SetBackgroundColour( *wxWHITE );
210
211 m_current = (wxPlotCurve*) NULL;
212 }
213
214 wxPlotWindow::~wxPlotWindow()
215 {
216 }
217
218 void wxPlotWindow::Add( wxPlotCurve *curve )
219 {
220 m_curves.Append( curve );
221 if (!m_current) m_current = curve;
222 }
223
224 size_t wxPlotWindow::GetCount()
225 {
226 return m_curves.GetCount();
227 }
228
229 wxPlotCurve *wxPlotWindow::GetAt( size_t n )
230 {
231 wxNode *node = m_curves.Nth( n );
232 if (!node)
233 return (wxPlotCurve*) NULL;
234
235 return (wxPlotCurve*) node->Data();
236 }
237
238 void wxPlotWindow::SetCurrent( wxPlotCurve* current )
239 {
240 m_current = current;
241 m_area->Refresh( TRUE );
242
243 wxPoint pos( m_area->GetPosition() );
244
245 int client_width;
246 int client_height;
247 GetClientSize( &client_width, &client_height);
248 wxRect rect(pos.x-40,0,40,client_height);
249 Refresh(TRUE,&rect);
250 }
251
252 wxPlotCurve *wxPlotWindow::GetCurrent()
253 {
254 return m_current;
255 }
256
257 void wxPlotWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
258 {
259 wxPaintDC dc( this );
260
261 if (!m_current) return;
262
263 int client_width;
264 int client_height;
265 GetClientSize( &client_width, &client_height);
266
267 dc.SetPen( *wxBLACK_PEN );
268
269 wxPoint pos( m_area->GetPosition() );
270
271 dc.DrawLine( pos.x-15, 5, pos.x-15, client_height-5 );
272 dc.DrawLine( pos.x-19, 9, pos.x-15, 5 );
273 dc.DrawLine( pos.x-10, 10, pos.x-15, 5 );
274
275 int y = client_height - m_current->GetOffsetY() - 1;
276 dc.DrawLine( pos.x-15, y, pos.x-7, y );
277 }
278