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/plot/plot.h"
35 #include "wx/bmpbuttn.h"
36 #include "wx/module.h"
40 // ----------------------------------------------------------------------------
42 // ----------------------------------------------------------------------------
44 #if !defined(__WXMSW__) && !defined(__WXPM__)
45 #include "wx/plot/plot_enl.xpm"
46 #include "wx/plot/plot_shr.xpm"
47 #include "wx/plot/plot_zin.xpm"
48 #include "wx/plot/plot_zot.xpm"
49 #include "wx/plot/plot_up.xpm"
50 #include "wx/plot/plot_dwn.xpm"
53 //----------------------------------------------------------------------------
55 //----------------------------------------------------------------------------
57 const int wxEVT_PLOT_SEL_CHANGING
= wxNewEventType();
58 const int wxEVT_PLOT_SEL_CHANGED
= wxNewEventType();
59 const int wxEVT_PLOT_CLICKED
= wxNewEventType();
60 const int wxEVT_PLOT_DOUBLECLICKED
= wxNewEventType();
61 const int wxEVT_PLOT_ZOOM_IN
= wxNewEventType();
62 const int wxEVT_PLOT_ZOOM_OUT
= wxNewEventType();
63 const int wxEVT_PLOT_VALUE_SEL_CREATING
= wxNewEventType();
64 const int wxEVT_PLOT_VALUE_SEL_CREATED
= wxNewEventType();
65 const int wxEVT_PLOT_VALUE_SEL_CHANGING
= wxNewEventType();
66 const int wxEVT_PLOT_VALUE_SEL_CHANGED
= wxNewEventType();
67 const int wxEVT_PLOT_AREA_SEL_CREATING
= wxNewEventType();
68 const int wxEVT_PLOT_AREA_SEL_CREATED
= wxNewEventType();
69 const int wxEVT_PLOT_AREA_SEL_CHANGING
= wxNewEventType();
70 const int wxEVT_PLOT_AREA_SEL_CHANGED
= wxNewEventType();
71 const int wxEVT_PLOT_BEGIN_X_LABEL_EDIT
= wxNewEventType();
72 const int wxEVT_PLOT_END_X_LABEL_EDIT
= wxNewEventType();
73 const int wxEVT_PLOT_BEGIN_Y_LABEL_EDIT
= wxNewEventType();
74 const int wxEVT_PLOT_END_Y_LABEL_EDIT
= wxNewEventType();
75 const int wxEVT_PLOT_BEGIN_TITLE_EDIT
= wxNewEventType();
76 const int wxEVT_PLOT_END_TITLE_EDIT
= wxNewEventType();
77 const int wxEVT_PLOT_AREA_CREATE
= wxNewEventType();
79 //----------------------------------------------------------------------------
80 // accessor functions for the bitmaps (may return NULL, check for it!)
81 //----------------------------------------------------------------------------
83 static wxBitmap
*GetEnlargeBitmap();
84 static wxBitmap
*GetShrinkBitmap();
85 static wxBitmap
*GetZoomInBitmap();
86 static wxBitmap
*GetZoomOutBitmap();
87 static wxBitmap
*GetUpBitmap();
88 static wxBitmap
*GetDownBitmap();
90 //-----------------------------------------------------------------------------
92 //-----------------------------------------------------------------------------
94 #define wxPLOT_SCROLL_STEP 30
96 //-----------------------------------------------------------------------------
98 //-----------------------------------------------------------------------------
100 wxPlotEvent::wxPlotEvent( wxEventType commandType
, int id
)
101 : wxNotifyEvent( commandType
, id
)
103 m_curve
= (wxPlotCurve
*) NULL
;
108 //-----------------------------------------------------------------------------
110 //-----------------------------------------------------------------------------
112 IMPLEMENT_ABSTRACT_CLASS(wxPlotCurve
, wxObject
)
114 wxPlotCurve::wxPlotCurve( int offsetY
, double startY
, double endY
)
121 //-----------------------------------------------------------------------------
123 //-----------------------------------------------------------------------------
125 IMPLEMENT_CLASS(wxPlotOnOffCurve
, wxObject
)
127 #include "wx/arrimpl.cpp"
128 WX_DEFINE_OBJARRAY(wxArrayPlotOnOff
);
130 wxPlotOnOffCurve::wxPlotOnOffCurve( int offsetY
)
137 void wxPlotOnOffCurve::Add( wxInt32 on
, wxInt32 off
, void *clientData
)
139 wxASSERT_MSG( on
> 0, _T("plot index < 0") );
140 wxASSERT( on
<= off
);
147 wxPlotOnOff
*v
= new wxPlotOnOff
;
150 v
->m_clientData
= clientData
;
154 size_t wxPlotOnOffCurve::GetCount()
156 return m_marks
.GetCount();
159 wxInt32
wxPlotOnOffCurve::GetOn( size_t index
)
161 wxPlotOnOff
*v
= &m_marks
.Item( index
);
165 wxInt32
wxPlotOnOffCurve::GetOff( size_t index
)
167 wxPlotOnOff
*v
= &m_marks
.Item( index
);
171 void* wxPlotOnOffCurve::GetClientData( size_t index
)
173 wxPlotOnOff
*v
= &m_marks
.Item( index
);
174 return v
->m_clientData
;
177 wxPlotOnOff
*wxPlotOnOffCurve::GetAt( size_t index
)
179 return &m_marks
.Item( index
);
182 void wxPlotOnOffCurve::DrawOnLine( wxDC
&dc
, wxCoord y
, wxCoord start
, wxCoord end
, void *WXUNUSED(clientData
) )
184 dc
.DrawLine( start
, y
, start
, y
-30 );
185 dc
.DrawLine( start
, y
-30, end
, y
-30 );
186 dc
.DrawLine( end
, y
-30, end
, y
);
189 void wxPlotOnOffCurve::DrawOffLine( wxDC
&dc
, wxCoord y
, wxCoord start
, wxCoord end
)
191 dc
.DrawLine( start
, y
, end
, y
);
194 //-----------------------------------------------------------------------------
196 //-----------------------------------------------------------------------------
198 IMPLEMENT_DYNAMIC_CLASS(wxPlotArea
, wxWindow
)
200 BEGIN_EVENT_TABLE(wxPlotArea
, wxWindow
)
201 EVT_PAINT( wxPlotArea::OnPaint
)
202 EVT_LEFT_DOWN( wxPlotArea::OnMouse
)
203 EVT_LEFT_DCLICK( wxPlotArea::OnMouse
)
206 wxPlotArea::wxPlotArea( wxPlotWindow
*parent
)
207 : wxWindow( parent
, -1, wxDefaultPosition
, wxDefaultSize
, wxSIMPLE_BORDER
, _T("plotarea") )
213 SetBackgroundColour( *wxWHITE
);
216 void wxPlotArea::OnMouse( wxMouseEvent
&event
)
220 GetClientSize( &client_width
, &client_height
);
223 m_owner
->GetViewStart( &view_x
, &view_y
);
224 view_x
*= wxPLOT_SCROLL_STEP
;
225 view_y
*= wxPLOT_SCROLL_STEP
;
227 wxCoord x
= event
.GetX();
228 wxCoord y
= event
.GetY();
232 wxNode
*node
= m_owner
->m_curves
.First();
235 wxPlotCurve
*curve
= (wxPlotCurve
*)node
->Data();
237 double double_client_height
= (double)client_height
;
238 double range
= curve
->GetEndY() - curve
->GetStartY();
239 double end
= curve
->GetEndY();
240 wxCoord offset_y
= curve
->GetOffsetY();
242 double dy
= (end
- curve
->GetY( (wxInt32
)(x
/m_owner
->GetZoom()) )) / range
;
243 wxCoord curve_y
= (wxCoord
)(dy
* double_client_height
) - offset_y
- 1;
245 if ((y
-curve_y
< 4) && (y
-curve_y
> -4))
247 wxPlotEvent
event1( event
.ButtonDClick() ? wxEVT_PLOT_DOUBLECLICKED
: wxEVT_PLOT_CLICKED
, m_owner
->GetId() );
248 event1
.SetEventObject( m_owner
);
249 event1
.SetZoom( m_owner
->GetZoom() );
250 event1
.SetCurve( curve
);
251 event1
.SetPosition( (int)floor(x
/m_owner
->GetZoom()) );
252 m_owner
->GetEventHandler()->ProcessEvent( event1
);
254 if (curve
!= m_owner
->GetCurrent())
256 wxPlotEvent
event2( wxEVT_PLOT_SEL_CHANGING
, m_owner
->GetId() );
257 event2
.SetEventObject( m_owner
);
258 event2
.SetZoom( m_owner
->GetZoom() );
259 event2
.SetCurve( curve
);
260 if (!m_owner
->GetEventHandler()->ProcessEvent( event2
) || event2
.IsAllowed())
262 m_owner
->SetCurrent( curve
);
272 void wxPlotArea::DeleteCurve( wxPlotCurve
*curve
, int from
, int to
)
275 m_owner
->PrepareDC( dc
);
276 dc
.SetPen( *wxWHITE_PEN
);
277 DrawCurve( &dc
, curve
, from
, to
);
280 void wxPlotArea::DrawCurve( wxDC
*dc
, wxPlotCurve
*curve
, int from
, int to
)
284 m_owner
->GetViewStart( &view_x
, &view_y
);
285 view_x
*= wxPLOT_SCROLL_STEP
;
292 GetClientSize( &client_width
, &client_height
);
295 to
= view_x
+ client_width
;
297 double zoom
= m_owner
->GetZoom();
299 int start_x
= wxMax( from
, (int)floor(curve
->GetStartX()*zoom
) );
300 int end_x
= wxMin( to
, (int)floor(curve
->GetEndX()*zoom
) );
302 start_x
= wxMax( view_x
, start_x
);
303 end_x
= wxMin( view_x
+ client_width
, end_x
);
307 double double_client_height
= (double)client_height
;
308 double range
= curve
->GetEndY() - curve
->GetStartY();
309 double end
= curve
->GetEndY();
310 wxCoord offset_y
= curve
->GetOffsetY();
312 wxCoord y
=0,last_y
=0;
313 for (int x
= start_x
; x
< end_x
; x
++)
315 double dy
= (end
- curve
->GetY( (wxInt32
)(x
/zoom
) )) / range
;
316 y
= (wxCoord
)(dy
* double_client_height
) - offset_y
- 1;
319 dc
->DrawLine( x
-1, last_y
, x
, y
);
325 void wxPlotArea::DrawOnOffCurve( wxDC
*dc
, wxPlotOnOffCurve
*curve
, int from
, int to
)
329 m_owner
->GetViewStart( &view_x
, &view_y
);
330 view_x
*= wxPLOT_SCROLL_STEP
;
337 GetClientSize( &client_width
, &client_height
);
340 to
= view_x
+ client_width
;
342 double zoom
= m_owner
->GetZoom();
344 int start_x
= wxMax( from
, (int)floor(curve
->GetStartX()*zoom
) );
345 int end_x
= wxMin( to
, (int)floor(curve
->GetEndX()*zoom
) );
347 start_x
= wxMax( view_x
, start_x
);
348 end_x
= wxMin( view_x
+ client_width
, end_x
);
352 wxCoord offset_y
= curve
->GetOffsetY();
353 wxCoord last_off
= -5;
355 if (curve
->GetCount() == 0)
358 for (size_t index
= 0; index
< curve
->GetCount(); index
++)
360 wxPlotOnOff
*p
= curve
->GetAt( index
);
362 wxCoord on
= (wxCoord
)(p
->m_on
*zoom
);
363 wxCoord off
= (wxCoord
)(p
->m_off
*zoom
);
367 curve
->DrawOffLine( *dc
, client_height
-offset_y
, last_off
, on
);
373 curve
->DrawOffLine( *dc
, client_height
-offset_y
, last_off
, on
);
374 curve
->DrawOnLine( *dc
, client_height
-offset_y
, on
, off
, p
->m_clientData
);
379 wxPlotOnOff
*p
= curve
->GetAt( curve
->GetCount()-1 );
380 wxCoord off
= (wxCoord
)(p
->m_off
*zoom
);
382 curve
->DrawOffLine( *dc
, client_height
-offset_y
, off
, to
);
385 void wxPlotArea::OnPaint( wxPaintEvent
&WXUNUSED(event
) )
389 m_owner
->GetViewStart( &view_x
, &view_y
);
390 view_x
*= wxPLOT_SCROLL_STEP
;
391 view_y
*= wxPLOT_SCROLL_STEP
;
393 wxPaintDC
dc( this );
394 m_owner
->PrepareDC( dc
);
396 wxRegionIterator
upd( GetUpdateRegion() );
400 int update_x
= upd
.GetX();
401 int update_y
= upd
.GetY();
402 int update_width
= upd
.GetWidth();
408 if (m_owner->m_current)
410 dc.SetPen( *wxLIGHT_GREY_PEN );
411 int base_line = client_height - m_owner->m_current->GetOffsetY();
412 dc.DrawLine( update_x-1, base_line-1, update_x+update_width+2, base_line-1 );
416 wxNode
*node
= m_owner
->m_curves
.First();
419 wxPlotCurve
*curve
= (wxPlotCurve
*) node
->Data();
421 if (curve
== m_owner
->GetCurrent())
422 dc
.SetPen( *wxBLACK_PEN
);
424 dc
.SetPen( *wxGREY_PEN
);
426 DrawCurve( &dc
, curve
, update_x
-1, update_x
+update_width
+2 );
431 dc
.SetPen( *wxRED_PEN
);
433 node
= m_owner
->m_onOffCurves
.First();
436 wxPlotOnOffCurve
*curve
= (wxPlotOnOffCurve
*) node
->Data();
438 DrawOnOffCurve( &dc
, curve
, update_x
-1, update_x
+update_width
+2 );
447 void wxPlotArea::ScrollWindow( int dx
, int dy
, const wxRect
*rect
)
449 wxWindow::ScrollWindow( dx
, dy
, rect
);
450 // m_owner->m_xaxis->ScrollWindow( dx, 0 );
453 //-----------------------------------------------------------------------------
455 //-----------------------------------------------------------------------------
457 IMPLEMENT_DYNAMIC_CLASS(wxPlotXAxisArea
, wxWindow
)
459 BEGIN_EVENT_TABLE(wxPlotXAxisArea
, wxWindow
)
460 EVT_PAINT( wxPlotXAxisArea::OnPaint
)
461 EVT_LEFT_DOWN( wxPlotXAxisArea::OnMouse
)
464 wxPlotXAxisArea::wxPlotXAxisArea( wxPlotWindow
*parent
)
465 : wxWindow( parent
, -1, wxDefaultPosition
, wxSize(-1,40), 0, _T("plotxaxisarea") )
469 SetBackgroundColour( *wxWHITE
);
470 SetFont( *wxSMALL_FONT
);
473 void wxPlotXAxisArea::OnMouse( wxMouseEvent
&event
)
477 GetClientSize( &client_width
, &client_height
);
480 m_owner
->GetViewStart( &view_x
, &view_y
);
481 view_x
*= wxPLOT_SCROLL_STEP
;
482 view_y
*= wxPLOT_SCROLL_STEP
;
484 wxCoord x
= event
.GetX();
485 wxCoord y
= event
.GetY();
489 /* do something here */
492 void wxPlotXAxisArea::OnPaint( wxPaintEvent
&WXUNUSED(event
) )
496 m_owner
->GetViewStart( &view_x
, &view_y
);
497 view_x
*= wxPLOT_SCROLL_STEP
;
498 view_y
*= wxPLOT_SCROLL_STEP
;
500 wxPaintDC
dc( this );
504 GetClientSize( &client_width
, &client_height
);
506 double zoom
= m_owner
->GetZoom();
508 double ups
= m_owner
->GetUnitsPerValue() / zoom
;
510 double start
= view_x
* ups
;
511 double end
= (view_x
+ client_width
) * ups
;
512 double range
= end
- start
;
514 int int_log_range
= (int)floor( log10( range
) );
516 if (int_log_range
> 0)
518 for (int i
= 0; i
< int_log_range
; i
++)
521 if (int_log_range
< 0)
523 for (int i
= 0; i
< -int_log_range
; i
++)
526 double lower
= ceil(start
/ step
) * step
;
527 double upper
= floor(end
/ step
) * step
;
529 // if too few values, shrink size
530 if ((range
/step
) < 4)
533 if (lower
-step
> start
) lower
-= step
;
534 if (upper
+step
< end
) upper
+= step
;
537 // if still too few, again
538 if ((range
/step
) < 4)
541 if (lower
-step
> start
) lower
-= step
;
542 if (upper
+step
< end
) upper
+= step
;
545 dc
.SetBrush( *wxWHITE_BRUSH
);
546 dc
.SetPen( *wxTRANSPARENT_PEN
);
547 dc
.DrawRectangle( 4, 5, client_width
-14, 10 );
548 dc
.DrawRectangle( 0, 20, client_width
, 20 );
549 dc
.SetPen( *wxBLACK_PEN
);
551 double current
= lower
;
552 while (current
< upper
+(step
/2))
554 int x
= (int)ceil((current
-start
) / range
* (double)client_width
) - 1;
555 if ((x
> 4) && (x
< client_width
-25))
557 dc
.DrawLine( x
, 5, x
, 15 );
561 label
.Printf( _T("%f"), current
);
562 while (label
.Last() == _T('0'))
564 if ((label
.Last() == _T('.')) || (label
.Last() == _T(',')))
565 label
.Append( _T('0') );
568 label
.Printf( _T("%d"), (int)floor(current
) );
569 dc
.DrawText( label
, x
-4, 20 );
575 dc
.DrawLine( 0, 15, client_width
-8, 15 );
576 dc
.DrawLine( client_width
-4, 15, client_width
-10, 10 );
577 dc
.DrawLine( client_width
-4, 15, client_width
-10, 20 );
580 //-----------------------------------------------------------------------------
582 //-----------------------------------------------------------------------------
584 IMPLEMENT_DYNAMIC_CLASS(wxPlotYAxisArea
, wxWindow
)
586 BEGIN_EVENT_TABLE(wxPlotYAxisArea
, wxWindow
)
587 EVT_PAINT( wxPlotYAxisArea::OnPaint
)
588 EVT_LEFT_DOWN( wxPlotYAxisArea::OnMouse
)
591 wxPlotYAxisArea::wxPlotYAxisArea( wxPlotWindow
*parent
)
592 : wxWindow( parent
, -1, wxDefaultPosition
, wxSize(60,-1), 0, _T("plotyaxisarea") )
596 SetBackgroundColour( *wxWHITE
);
597 SetFont( *wxSMALL_FONT
);
600 void wxPlotYAxisArea::OnMouse( wxMouseEvent
&WXUNUSED(event
) )
602 /* do something here */
605 void wxPlotYAxisArea::OnPaint( wxPaintEvent
&WXUNUSED(event
) )
607 wxPaintDC
dc( this );
609 wxPlotCurve
*curve
= m_owner
->GetCurrent();
615 GetClientSize( &client_width
, &client_height
);
618 double range
= curve
->GetEndY() - curve
->GetStartY();
619 double offset
= ((double) curve
->GetOffsetY() / (double)client_height
) * range
;
620 double start
= curve
->GetStartY() - offset
;
621 double end
= curve
->GetEndY() - offset
;
623 int int_log_range
= (int)floor( log10( range
) );
625 if (int_log_range
> 0)
627 for (int i
= 0; i
< int_log_range
; i
++)
630 if (int_log_range
< 0)
632 for (int i
= 0; i
< -int_log_range
; i
++)
635 double lower
= ceil(start
/ step
) * step
;
636 double upper
= floor(end
/ step
) * step
;
638 // if too few values, shrink size
639 if ((range
/step
) < 4)
642 if (lower
-step
> start
) lower
-= step
;
643 if (upper
+step
< end
) upper
+= step
;
646 // if still too few, again
647 if ((range
/step
) < 4)
650 if (lower
-step
> start
) lower
-= step
;
651 if (upper
+step
< end
) upper
+= step
;
654 dc
.SetPen( *wxBLACK_PEN
);
656 double current
= lower
;
657 while (current
< upper
+(step
/2))
659 int y
= (int)((curve
->GetEndY()-current
) / range
* (double)client_height
) - 1;
660 y
-= curve
->GetOffsetY();
661 if ((y
> 10) && (y
< client_height
-7))
663 dc
.DrawLine( client_width
-15, y
, client_width
-7, y
);
667 label
.Printf( _T("%f"), current
);
668 while (label
.Last() == _T('0'))
670 if ((label
.Last() == _T('.')) || (label
.Last() == _T(',')))
671 label
.Append( _T('0') );
674 label
.Printf( _T("%d"), (int)floor(current
) );
675 dc
.DrawText( label
, 5, y
-7 );
681 dc
.DrawLine( client_width
-15, 6, client_width
-15, client_height
);
682 dc
.DrawLine( client_width
-15, 2, client_width
-20, 8 );
683 dc
.DrawLine( client_width
-15, 2, client_width
-10, 8 );
686 //-----------------------------------------------------------------------------
688 //-----------------------------------------------------------------------------
690 #define ID_ENLARGE 1000
691 #define ID_SHRINK 1002
693 #define ID_MOVE_UP 1006
694 #define ID_MOVE_DOWN 1007
696 #define ID_ZOOM_IN 1010
697 #define ID_ZOOM_OUT 1011
700 IMPLEMENT_DYNAMIC_CLASS(wxPlotWindow
, wxScrolledWindow
)
702 BEGIN_EVENT_TABLE(wxPlotWindow
, wxScrolledWindow
)
703 EVT_BUTTON( ID_MOVE_UP
, wxPlotWindow::OnMoveUp
)
704 EVT_BUTTON( ID_MOVE_DOWN
, wxPlotWindow::OnMoveDown
)
706 EVT_BUTTON( ID_ENLARGE
, wxPlotWindow::OnEnlarge
)
707 EVT_BUTTON( ID_SHRINK
, wxPlotWindow::OnShrink
)
709 EVT_BUTTON( ID_ZOOM_IN
, wxPlotWindow::OnZoomIn
)
710 EVT_BUTTON( ID_ZOOM_OUT
, wxPlotWindow::OnZoomOut
)
712 EVT_SCROLLWIN( wxPlotWindow::OnScroll2
)
715 wxPlotWindow::wxPlotWindow( wxWindow
*parent
, wxWindowID id
, const wxPoint
&pos
, const wxSize
&size
, int flag
)
716 : wxScrolledWindow( parent
, id
, pos
, size
, flag
, _T("plotcanvas") )
718 m_xUnitsPerValue
= 1.0;
721 m_enlargeAroundWindowCentre
= FALSE
;
722 m_scrollOnThumbRelease
= FALSE
;
724 m_area
= new wxPlotArea( this );
725 wxBoxSizer
*mainsizer
= new wxBoxSizer( wxHORIZONTAL
);
727 if ((GetWindowStyleFlag() & wxPLOT_BUTTON_ALL
) != 0)
729 wxBoxSizer
*buttonlist
= new wxBoxSizer( wxVERTICAL
);
730 if ((GetWindowStyleFlag() & wxPLOT_BUTTON_ENLARGE
) != 0)
732 buttonlist
->Add( new wxBitmapButton( this, ID_ENLARGE
, *GetEnlargeBitmap() ), 0, wxEXPAND
|wxALL
, 2 );
733 buttonlist
->Add( new wxBitmapButton( this, ID_SHRINK
, *GetShrinkBitmap() ), 0, wxEXPAND
|wxALL
, 2 );
734 buttonlist
->Add( 20,10, 0 );
736 if ((GetWindowStyleFlag() & wxPLOT_BUTTON_MOVE
) != 0)
738 buttonlist
->Add( new wxBitmapButton( this, ID_MOVE_UP
, *GetUpBitmap() ), 0, wxEXPAND
|wxALL
, 2 );
739 buttonlist
->Add( new wxBitmapButton( this, ID_MOVE_DOWN
, *GetDownBitmap() ), 0, wxEXPAND
|wxALL
, 2 );
740 buttonlist
->Add( 20,10, 0 );
742 if ((GetWindowStyleFlag() & wxPLOT_BUTTON_ZOOM
) != 0)
744 buttonlist
->Add( new wxBitmapButton( this, ID_ZOOM_IN
, *GetZoomInBitmap() ), 0, wxEXPAND
|wxALL
, 2 );
745 buttonlist
->Add( new wxBitmapButton( this, ID_ZOOM_OUT
, *GetZoomOutBitmap() ), 0, wxEXPAND
|wxALL
, 2 );
747 mainsizer
->Add( buttonlist
, 0, wxEXPAND
|wxALL
, 4 );
750 wxBoxSizer
*plotsizer
= new wxBoxSizer( wxHORIZONTAL
);
752 if ((GetWindowStyleFlag() & wxPLOT_Y_AXIS
) != 0)
754 m_yaxis
= new wxPlotYAxisArea( this );
756 wxBoxSizer
*vert1
= new wxBoxSizer( wxVERTICAL
);
757 plotsizer
->Add( vert1
, 0, wxEXPAND
);
758 vert1
->Add( m_yaxis
, 1 );
759 if ((GetWindowStyleFlag() & wxPLOT_X_AXIS
) != 0)
760 vert1
->Add( 60, 40 );
764 m_yaxis
= (wxPlotYAxisArea
*) NULL
;
767 if ((GetWindowStyleFlag() & wxPLOT_X_AXIS
) != 0)
769 m_xaxis
= new wxPlotXAxisArea( this );
771 wxBoxSizer
*vert2
= new wxBoxSizer( wxVERTICAL
);
772 plotsizer
->Add( vert2
, 1, wxEXPAND
);
773 vert2
->Add( m_area
, 1, wxEXPAND
);
774 vert2
->Add( m_xaxis
, 0, wxEXPAND
);
778 plotsizer
->Add( m_area
, 1, wxEXPAND
);
779 m_xaxis
= (wxPlotXAxisArea
*) NULL
;
782 mainsizer
->Add( plotsizer
, 1, wxEXPAND
);
784 SetAutoLayout( TRUE
);
785 SetSizer( mainsizer
);
787 SetTargetWindow( m_area
);
789 SetBackgroundColour( *wxWHITE
);
791 m_current
= (wxPlotCurve
*) NULL
;
794 wxPlotWindow::~wxPlotWindow()
798 void wxPlotWindow::Add( wxPlotCurve
*curve
)
800 m_curves
.Append( curve
);
801 if (!m_current
) m_current
= curve
;
806 size_t wxPlotWindow::GetCount()
808 return m_curves
.GetCount();
811 wxPlotCurve
*wxPlotWindow::GetAt( size_t n
)
813 wxNode
*node
= m_curves
.Nth( n
);
815 return (wxPlotCurve
*) NULL
;
817 return (wxPlotCurve
*) node
->Data();
820 void wxPlotWindow::SetCurrent( wxPlotCurve
* current
)
823 m_area
->Refresh( FALSE
);
827 wxPlotEvent
event( wxEVT_PLOT_SEL_CHANGED
, GetId() );
828 event
.SetEventObject( this );
829 event
.SetZoom( GetZoom() );
830 event
.SetCurve( m_current
);
831 GetEventHandler()->ProcessEvent( event
);
834 void wxPlotWindow::Delete( wxPlotCurve
* curve
)
836 wxNode
*node
= m_curves
.Find( curve
);
839 m_curves
.DeleteObject( curve
);
841 m_area
->DeleteCurve( curve
);
842 m_area
->Refresh( FALSE
);
844 if (curve
== m_current
) m_current
= (wxPlotCurve
*) NULL
;
847 wxPlotCurve
*wxPlotWindow::GetCurrent()
852 void wxPlotWindow::Add( wxPlotOnOffCurve
*curve
)
854 m_onOffCurves
.Append( curve
);
857 void wxPlotWindow::Delete( wxPlotOnOffCurve
* curve
)
859 wxNode
*node
= m_onOffCurves
.Find( curve
);
862 m_onOffCurves
.DeleteObject( curve
);
865 size_t wxPlotWindow::GetOnOffCurveCount()
867 return m_onOffCurves
.GetCount();
870 wxPlotOnOffCurve
*wxPlotWindow::GetOnOffCurveAt( size_t n
)
872 wxNode
*node
= m_onOffCurves
.Nth( n
);
874 return (wxPlotOnOffCurve
*) NULL
;
876 return (wxPlotOnOffCurve
*) node
->Data();
879 void wxPlotWindow::Move( wxPlotCurve
* curve
, int pixels_up
)
881 m_area
->DeleteCurve( curve
);
883 curve
->SetOffsetY( curve
->GetOffsetY() + pixels_up
);
885 m_area
->Refresh( FALSE
);
890 void wxPlotWindow::OnMoveUp( wxCommandEvent
& WXUNUSED(event
) )
892 if (!m_current
) return;
894 Move( m_current
, 25 );
897 void wxPlotWindow::OnMoveDown( wxCommandEvent
& WXUNUSED(event
) )
899 if (!m_current
) return;
901 Move( m_current
, -25 );
904 void wxPlotWindow::Enlarge( wxPlotCurve
*curve
, double factor
)
906 m_area
->DeleteCurve( curve
);
910 m_area
->GetClientSize( &client_width
, &client_height
);
911 double offset
= (double)curve
->GetOffsetY() / (double)client_height
;
913 double range
= curve
->GetEndY() - curve
->GetStartY();
916 double new_range
= range
/ factor
;
917 double new_offset
= offset
/ factor
;
919 if (m_enlargeAroundWindowCentre
)
921 double middle
= curve
->GetStartY() - offset
+ range
/2;
923 curve
->SetStartY( middle
- new_range
/ 2 + new_offset
);
924 curve
->SetEndY( middle
+ new_range
/ 2 + new_offset
);
928 curve
->SetStartY( (curve
->GetStartY() - offset
)/factor
+ new_offset
);
929 curve
->SetEndY( (curve
->GetEndY() - offset
)/factor
+ new_offset
);
932 m_area
->Refresh( FALSE
);
936 void wxPlotWindow::SetUnitsPerValue( double upv
)
938 m_xUnitsPerValue
= upv
;
943 void wxPlotWindow::SetZoom( double zoom
)
945 double old_zoom
= m_xZoom
;
950 GetViewStart( &view_x
, &view_y
);
953 wxNode
*node
= m_curves
.First();
956 wxPlotCurve
*curve
= (wxPlotCurve
*) node
->Data();
957 if (curve
->GetEndX() > max
)
958 max
= curve
->GetEndX();
961 SetScrollbars( wxPLOT_SCROLL_STEP
, wxPLOT_SCROLL_STEP
,
962 (int)((max
*m_xZoom
)/wxPLOT_SCROLL_STEP
)+1, 0,
963 (int)(view_x
*zoom
/old_zoom
), 0,
967 m_area
->Refresh( TRUE
);
970 void wxPlotWindow::ResetScrollbar()
973 wxNode
*node
= m_curves
.First();
976 wxPlotCurve
*curve
= (wxPlotCurve
*) node
->Data();
977 if (curve
->GetEndX() > max
)
978 max
= curve
->GetEndX();
982 SetScrollbars( wxPLOT_SCROLL_STEP
, wxPLOT_SCROLL_STEP
,
983 (int)(((max
*m_xZoom
)/wxPLOT_SCROLL_STEP
)+1), 0 );
986 void wxPlotWindow::RedrawXAxis()
989 m_xaxis
->Refresh( FALSE
);
992 void wxPlotWindow::RedrawYAxis()
995 m_yaxis
->Refresh( TRUE
);
998 void wxPlotWindow::RedrawEverything()
1001 m_xaxis
->Refresh( TRUE
);
1003 m_yaxis
->Refresh( TRUE
);
1004 m_area
->Refresh( TRUE
);
1007 void wxPlotWindow::OnZoomIn( wxCommandEvent
& WXUNUSED(event
) )
1009 SetZoom( m_xZoom
* 1.5 );
1012 void wxPlotWindow::OnZoomOut( wxCommandEvent
& WXUNUSED(event
) )
1014 SetZoom( m_xZoom
* 0.6666 );
1017 void wxPlotWindow::OnEnlarge( wxCommandEvent
& WXUNUSED(event
) )
1019 if (!m_current
) return;
1021 Enlarge( m_current
, 1.5 );
1024 void wxPlotWindow::OnShrink( wxCommandEvent
& WXUNUSED(event
) )
1026 if (!m_current
) return;
1028 Enlarge( m_current
, 0.6666666 );
1031 void wxPlotWindow::OnScroll2( wxScrollWinEvent
& event
)
1033 if ((!m_scrollOnThumbRelease
) || (event
.GetEventType() != wxEVT_SCROLLWIN_THUMBTRACK
))
1035 wxScrolledWindow::OnScroll( event
);
1040 // ----------------------------------------------------------------------------
1042 // ----------------------------------------------------------------------------
1045 static wxBitmap
*GetEnlargeBitmap()
1047 static wxBitmap
* s_bitmap
= (wxBitmap
*) NULL
;
1048 static bool s_loaded
= FALSE
;
1052 s_loaded
= TRUE
; // set it to TRUE anyhow, we won't try again
1054 #if defined(__WXMSW__) || defined(__WXPM__)
1055 s_bitmap
= new wxBitmap(_T("plot_enl_bmp"), wxBITMAP_TYPE_RESOURCE
);
1057 s_bitmap
= new wxBitmap( plot_enl_xpm
);
1064 static wxBitmap
*GetShrinkBitmap()
1066 static wxBitmap
* s_bitmap
= (wxBitmap
*) NULL
;
1067 static bool s_loaded
= FALSE
;
1071 s_loaded
= TRUE
; // set it to TRUE anyhow, we won't try again
1073 #if defined(__WXMSW__) || defined(__WXPM__)
1074 s_bitmap
= new wxBitmap(_T("plot_shr_bmp"), wxBITMAP_TYPE_RESOURCE
);
1076 s_bitmap
= new wxBitmap( plot_shr_xpm
);
1083 static wxBitmap
*GetZoomInBitmap()
1085 static wxBitmap
* s_bitmap
= (wxBitmap
*) NULL
;
1086 static bool s_loaded
= FALSE
;
1090 s_loaded
= TRUE
; // set it to TRUE anyhow, we won't try again
1092 #if defined(__WXMSW__) || defined(__WXPM__)
1093 s_bitmap
= new wxBitmap(_T("plot_zin_bmp"), wxBITMAP_TYPE_RESOURCE
);
1095 s_bitmap
= new wxBitmap( plot_zin_xpm
);
1102 static wxBitmap
*GetZoomOutBitmap()
1104 static wxBitmap
* s_bitmap
= (wxBitmap
*) NULL
;
1105 static bool s_loaded
= FALSE
;
1109 s_loaded
= TRUE
; // set it to TRUE anyhow, we won't try again
1111 #if defined(__WXMSW__) || defined(__WXPM__)
1112 s_bitmap
= new wxBitmap(_T("plot_zot_bmp"), wxBITMAP_TYPE_RESOURCE
);
1114 s_bitmap
= new wxBitmap( plot_zot_xpm
);
1121 static wxBitmap
*GetUpBitmap()
1123 static wxBitmap
* s_bitmap
= (wxBitmap
*) NULL
;
1124 static bool s_loaded
= FALSE
;
1128 s_loaded
= TRUE
; // set it to TRUE anyhow, we won't try again
1130 #if defined(__WXMSW__) || defined(__WXPM__)
1131 s_bitmap
= new wxBitmap(_T("plot_up_bmp"), wxBITMAP_TYPE_RESOURCE
);
1133 s_bitmap
= new wxBitmap( plot_up_xpm
);
1140 static wxBitmap
*GetDownBitmap()
1142 static wxBitmap
* s_bitmap
= (wxBitmap
*) NULL
;
1143 static bool s_loaded
= FALSE
;
1147 s_loaded
= TRUE
; // set it to TRUE anyhow, we won't try again
1149 #if defined(__WXMSW__) || defined(__WXPM__)
1150 s_bitmap
= new wxBitmap(_T("plot_dwn_bmp"), wxBITMAP_TYPE_RESOURCE
);
1152 s_bitmap
= new wxBitmap( plot_dwn_xpm
);