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"
32 #include "wx/stattext.h"
35 #include "wx/plot/plot.h"
36 #include "wx/bmpbuttn.h"
37 #include "wx/module.h"
41 // ----------------------------------------------------------------------------
43 // ----------------------------------------------------------------------------
45 #if !defined(__WXMSW__) && !defined(__WXPM__)
46 #include "wx/plot/plot_enl.xpm"
47 #include "wx/plot/plot_shr.xpm"
48 #include "wx/plot/plot_zin.xpm"
49 #include "wx/plot/plot_zot.xpm"
50 #include "wx/plot/plot_up.xpm"
51 #include "wx/plot/plot_dwn.xpm"
54 //----------------------------------------------------------------------------
56 //----------------------------------------------------------------------------
58 DEFINE_EVENT_TYPE(wxEVT_PLOT_SEL_CHANGING
);
59 DEFINE_EVENT_TYPE(wxEVT_PLOT_SEL_CHANGED
);
60 DEFINE_EVENT_TYPE(wxEVT_PLOT_CLICKED
);
61 DEFINE_EVENT_TYPE(wxEVT_PLOT_DOUBLECLICKED
);
62 DEFINE_EVENT_TYPE(wxEVT_PLOT_ZOOM_IN
);
63 DEFINE_EVENT_TYPE(wxEVT_PLOT_ZOOM_OUT
);
64 DEFINE_EVENT_TYPE(wxEVT_PLOT_VALUE_SEL_CREATING
);
65 DEFINE_EVENT_TYPE(wxEVT_PLOT_VALUE_SEL_CREATED
);
66 DEFINE_EVENT_TYPE(wxEVT_PLOT_VALUE_SEL_CHANGING
);
67 DEFINE_EVENT_TYPE(wxEVT_PLOT_VALUE_SEL_CHANGED
);
68 DEFINE_EVENT_TYPE(wxEVT_PLOT_AREA_SEL_CREATING
);
69 DEFINE_EVENT_TYPE(wxEVT_PLOT_AREA_SEL_CREATED
);
70 DEFINE_EVENT_TYPE(wxEVT_PLOT_AREA_SEL_CHANGING
);
71 DEFINE_EVENT_TYPE(wxEVT_PLOT_AREA_SEL_CHANGED
);
72 DEFINE_EVENT_TYPE(wxEVT_PLOT_BEGIN_X_LABEL_EDIT
);
73 DEFINE_EVENT_TYPE(wxEVT_PLOT_END_X_LABEL_EDIT
);
74 DEFINE_EVENT_TYPE(wxEVT_PLOT_BEGIN_Y_LABEL_EDIT
);
75 DEFINE_EVENT_TYPE(wxEVT_PLOT_END_Y_LABEL_EDIT
);
76 DEFINE_EVENT_TYPE(wxEVT_PLOT_BEGIN_TITLE_EDIT
);
77 DEFINE_EVENT_TYPE(wxEVT_PLOT_END_TITLE_EDIT
);
78 DEFINE_EVENT_TYPE(wxEVT_PLOT_AREA_CREATE
);
80 //----------------------------------------------------------------------------
81 // accessor functions for the bitmaps (may return NULL, check for it!)
82 //----------------------------------------------------------------------------
84 static wxBitmap
*GetEnlargeBitmap();
85 static wxBitmap
*GetShrinkBitmap();
86 static wxBitmap
*GetZoomInBitmap();
87 static wxBitmap
*GetZoomOutBitmap();
88 static wxBitmap
*GetUpBitmap();
89 static wxBitmap
*GetDownBitmap();
91 //-----------------------------------------------------------------------------
93 //-----------------------------------------------------------------------------
95 #define wxPLOT_SCROLL_STEP 30
97 //-----------------------------------------------------------------------------
99 //-----------------------------------------------------------------------------
101 wxPlotEvent::wxPlotEvent( wxEventType commandType
, int id
)
102 : wxNotifyEvent( commandType
, id
)
104 m_curve
= (wxPlotCurve
*) NULL
;
109 //-----------------------------------------------------------------------------
111 //-----------------------------------------------------------------------------
113 IMPLEMENT_ABSTRACT_CLASS(wxPlotCurve
, wxObject
)
115 wxPlotCurve::wxPlotCurve( int offsetY
, double startY
, double endY
)
116 : m_penNormal(*wxGREY_PEN
), m_penSelected(*wxBLACK_PEN
)
123 //-----------------------------------------------------------------------------
125 //-----------------------------------------------------------------------------
127 IMPLEMENT_CLASS(wxPlotOnOffCurve
, wxObject
)
129 #include "wx/arrimpl.cpp"
130 WX_DEFINE_OBJARRAY(wxArrayPlotOnOff
);
132 wxPlotOnOffCurve::wxPlotOnOffCurve( int offsetY
)
139 void wxPlotOnOffCurve::Add( wxInt32 on
, wxInt32 off
, void *clientData
)
141 wxASSERT_MSG( on
> 0, _T("plot index < 0") );
142 wxASSERT( on
<= off
);
149 wxPlotOnOff
*v
= new wxPlotOnOff
;
152 v
->m_clientData
= clientData
;
156 size_t wxPlotOnOffCurve::GetCount()
158 return m_marks
.GetCount();
161 wxInt32
wxPlotOnOffCurve::GetOn( size_t index
)
163 wxPlotOnOff
*v
= &m_marks
.Item( index
);
167 wxInt32
wxPlotOnOffCurve::GetOff( size_t index
)
169 wxPlotOnOff
*v
= &m_marks
.Item( index
);
173 void* wxPlotOnOffCurve::GetClientData( size_t index
)
175 wxPlotOnOff
*v
= &m_marks
.Item( index
);
176 return v
->m_clientData
;
179 wxPlotOnOff
*wxPlotOnOffCurve::GetAt( size_t index
)
181 return &m_marks
.Item( index
);
184 void wxPlotOnOffCurve::DrawOnLine( wxDC
&dc
, wxCoord y
, wxCoord start
, wxCoord end
, void *WXUNUSED(clientData
) )
186 dc
.DrawLine( start
, y
, start
, y
-30 );
187 dc
.DrawLine( start
, y
-30, end
, y
-30 );
188 dc
.DrawLine( end
, y
-30, end
, y
);
191 void wxPlotOnOffCurve::DrawOffLine( wxDC
&dc
, wxCoord y
, wxCoord start
, wxCoord end
)
193 dc
.DrawLine( start
, y
, end
, y
);
196 //-----------------------------------------------------------------------------
198 //-----------------------------------------------------------------------------
200 IMPLEMENT_DYNAMIC_CLASS(wxPlotArea
, wxWindow
)
202 BEGIN_EVENT_TABLE(wxPlotArea
, wxWindow
)
203 EVT_PAINT( wxPlotArea::OnPaint
)
204 EVT_LEFT_DOWN( wxPlotArea::OnMouse
)
205 EVT_LEFT_DCLICK( wxPlotArea::OnMouse
)
208 wxPlotArea::wxPlotArea( wxPlotWindow
*parent
)
209 : wxWindow( parent
, wxID_ANY
, wxDefaultPosition
, wxDefaultSize
, wxSIMPLE_BORDER
, _T("plotarea") )
215 SetBackgroundColour( *wxWHITE
);
218 void wxPlotArea::OnMouse( wxMouseEvent
&event
)
222 GetClientSize( &client_width
, &client_height
);
225 m_owner
->GetViewStart( &view_x
, &view_y
);
226 view_x
*= wxPLOT_SCROLL_STEP
;
227 view_y
*= wxPLOT_SCROLL_STEP
;
229 wxCoord x
= event
.GetX();
230 wxCoord y
= event
.GetY();
234 wxList::compatibility_iterator node
= m_owner
->m_curves
.GetFirst();
237 wxPlotCurve
*curve
= (wxPlotCurve
*)node
->GetData();
239 double double_client_height
= (double)client_height
;
240 double range
= curve
->GetEndY() - curve
->GetStartY();
241 double end
= curve
->GetEndY();
242 wxCoord offset_y
= curve
->GetOffsetY();
244 double dy
= (end
- curve
->GetY( (wxInt32
)(x
/m_owner
->GetZoom()) )) / range
;
245 wxCoord curve_y
= (wxCoord
)(dy
* double_client_height
) - offset_y
- 1;
247 if ((y
-curve_y
< 4) && (y
-curve_y
> -4))
249 wxPlotEvent
event1( event
.ButtonDClick() ? wxEVT_PLOT_DOUBLECLICKED
: wxEVT_PLOT_CLICKED
, m_owner
->GetId() );
250 event1
.SetEventObject( m_owner
);
251 event1
.SetZoom( m_owner
->GetZoom() );
252 event1
.SetCurve( curve
);
253 event1
.SetPosition( (int)floor(x
/m_owner
->GetZoom()) );
254 m_owner
->GetEventHandler()->ProcessEvent( event1
);
256 if (curve
!= m_owner
->GetCurrentCurve())
258 wxPlotEvent
event2( wxEVT_PLOT_SEL_CHANGING
, m_owner
->GetId() );
259 event2
.SetEventObject( m_owner
);
260 event2
.SetZoom( m_owner
->GetZoom() );
261 event2
.SetCurve( curve
);
262 if (!m_owner
->GetEventHandler()->ProcessEvent( event2
) || event2
.IsAllowed())
264 m_owner
->SetCurrentCurve( curve
);
270 node
= node
->GetNext();
274 void wxPlotArea::DeleteCurve( wxPlotCurve
*curve
, int from
, int to
)
277 m_owner
->PrepareDC( dc
);
278 dc
.SetPen( *wxWHITE_PEN
);
279 DrawCurve( &dc
, curve
, from
, to
);
282 void wxPlotArea::DrawCurve( wxDC
*dc
, wxPlotCurve
*curve
, int from
, int to
)
286 m_owner
->GetViewStart( &view_x
, &view_y
);
287 view_x
*= wxPLOT_SCROLL_STEP
;
294 GetClientSize( &client_width
, &client_height
);
297 to
= view_x
+ client_width
;
299 double zoom
= m_owner
->GetZoom();
301 int start_x
= wxMax( from
, (int)floor(curve
->GetStartX()*zoom
) );
302 int end_x
= wxMin( to
, (int)floor(curve
->GetEndX()*zoom
) );
304 start_x
= wxMax( view_x
, start_x
);
305 end_x
= wxMin( view_x
+ client_width
, end_x
);
309 double double_client_height
= (double)client_height
;
310 double range
= curve
->GetEndY() - curve
->GetStartY();
311 double end
= curve
->GetEndY();
312 wxCoord offset_y
= curve
->GetOffsetY();
315 for (int x
= start_x
; x
< end_x
; x
++)
317 double dy
= (end
- curve
->GetY( (wxInt32
)(x
/zoom
) )) / range
;
318 wxCoord y
= (wxCoord
)(dy
* double_client_height
) - offset_y
- 1;
321 dc
->DrawLine( x
-1, last_y
, x
, y
);
327 void wxPlotArea::DrawOnOffCurve( wxDC
*dc
, wxPlotOnOffCurve
*curve
, int from
, int to
)
331 m_owner
->GetViewStart( &view_x
, &view_y
);
332 view_x
*= wxPLOT_SCROLL_STEP
;
339 GetClientSize( &client_width
, &client_height
);
342 to
= view_x
+ client_width
;
344 double zoom
= m_owner
->GetZoom();
346 int start_x
= wxMax( from
, (int)floor(curve
->GetStartX()*zoom
) );
347 int end_x
= wxMin( to
, (int)floor(curve
->GetEndX()*zoom
) );
349 start_x
= wxMax( view_x
, start_x
);
350 end_x
= wxMin( view_x
+ client_width
, end_x
);
354 wxCoord offset_y
= curve
->GetOffsetY();
355 wxCoord last_off
= -5;
357 if (curve
->GetCount() == 0)
360 for (size_t index
= 0; index
< curve
->GetCount(); index
++)
362 wxPlotOnOff
*p
= curve
->GetAt( index
);
364 wxCoord on
= (wxCoord
)(p
->m_on
*zoom
);
365 wxCoord off
= (wxCoord
)(p
->m_off
*zoom
);
369 curve
->DrawOffLine( *dc
, client_height
-offset_y
, last_off
, on
);
375 curve
->DrawOffLine( *dc
, client_height
-offset_y
, last_off
, on
);
376 curve
->DrawOnLine( *dc
, client_height
-offset_y
, on
, off
, p
->m_clientData
);
381 wxPlotOnOff
*p
= curve
->GetAt( curve
->GetCount()-1 );
382 wxCoord off
= (wxCoord
)(p
->m_off
*zoom
);
384 curve
->DrawOffLine( *dc
, client_height
-offset_y
, off
, to
);
387 void wxPlotArea::OnPaint( wxPaintEvent
&WXUNUSED(event
) )
391 m_owner
->GetViewStart( &view_x
, &view_y
);
392 view_x
*= wxPLOT_SCROLL_STEP
;
393 view_y
*= wxPLOT_SCROLL_STEP
;
395 wxPaintDC
dc( this );
396 m_owner
->PrepareDC( dc
);
398 wxRegionIterator
upd( GetUpdateRegion() );
402 int update_x
= upd
.GetX() + view_x
;
403 int update_width
= upd
.GetWidth();
406 if (m_owner->m_current)
408 dc.SetPen( *wxLIGHT_GREY_PEN );
409 int base_line = client_height - m_owner->m_current->GetOffsetY();
410 dc.DrawLine( update_x-1, base_line-1, update_x+update_width+2, base_line-1 );
414 wxList::compatibility_iterator node
= m_owner
->m_curves
.GetFirst();
417 wxPlotCurve
*curve
= (wxPlotCurve
*) node
->GetData();
419 if (curve
== m_owner
->GetCurrentCurve())
420 dc
.SetPen( curve
->GetPenSelected() );
422 dc
.SetPen( curve
->GetPenNormal() );
424 DrawCurve( &dc
, curve
, update_x
-1, update_x
+update_width
+2 );
426 node
= node
->GetNext();
429 dc
.SetPen( *wxRED_PEN
);
431 node
= m_owner
->m_onOffCurves
.GetFirst();
434 wxPlotOnOffCurve
*curve
= (wxPlotOnOffCurve
*) node
->GetData();
436 DrawOnOffCurve( &dc
, curve
, update_x
-1, update_x
+update_width
+2 );
438 node
= node
->GetNext();
445 void wxPlotArea::ScrollWindow( int dx
, int dy
, const wxRect
*rect
)
447 wxWindow::ScrollWindow( dx
, dy
, rect
);
448 // m_owner->m_xaxis->ScrollWindow( dx, 0 );
451 //-----------------------------------------------------------------------------
453 //-----------------------------------------------------------------------------
455 IMPLEMENT_DYNAMIC_CLASS(wxPlotXAxisArea
, wxWindow
)
457 BEGIN_EVENT_TABLE(wxPlotXAxisArea
, wxWindow
)
458 EVT_PAINT( wxPlotXAxisArea::OnPaint
)
459 EVT_LEFT_DOWN( wxPlotXAxisArea::OnMouse
)
462 wxPlotXAxisArea::wxPlotXAxisArea( wxPlotWindow
*parent
)
463 : wxWindow( parent
, wxID_ANY
, wxDefaultPosition
, wxSize(wxDefaultCoord
,40), 0, _T("plotxaxisarea") )
467 SetBackgroundColour( *wxWHITE
);
468 SetFont( *wxSMALL_FONT
);
471 void wxPlotXAxisArea::OnMouse( wxMouseEvent
&event
)
475 GetClientSize( &client_width
, &client_height
);
478 m_owner
->GetViewStart( &view_x
, &view_y
);
479 view_x
*= wxPLOT_SCROLL_STEP
;
480 view_y
*= wxPLOT_SCROLL_STEP
;
482 wxCoord x
= event
.GetX() + view_x
;
483 wxCoord y
= event
.GetY() + view_y
;
485 /* TO DO: do something here */
490 void wxPlotXAxisArea::OnPaint( wxPaintEvent
&WXUNUSED(event
) )
494 m_owner
->GetViewStart( &view_x
, &view_y
);
495 view_x
*= wxPLOT_SCROLL_STEP
;
496 view_y
*= wxPLOT_SCROLL_STEP
;
498 wxPaintDC
dc( this );
502 GetClientSize( &client_width
, &client_height
);
504 double zoom
= m_owner
->GetZoom();
506 double ups
= m_owner
->GetUnitsPerValue() / zoom
;
508 double start
= view_x
* ups
;
509 double end
= (view_x
+ client_width
) * ups
;
510 double range
= end
- start
;
512 int int_log_range
= (int)floor( log10( range
) );
514 if (int_log_range
> 0)
516 for (int i
= 0; i
< int_log_range
; i
++)
519 if (int_log_range
< 0)
521 for (int i
= 0; i
< -int_log_range
; i
++)
524 double lower
= ceil(start
/ step
) * step
;
525 double upper
= floor(end
/ step
) * step
;
527 // if too few values, shrink size
528 if ((range
/step
) < 4)
531 if (lower
-step
> start
) lower
-= step
;
532 if (upper
+step
< end
) upper
+= step
;
535 // if still too few, again
536 if ((range
/step
) < 4)
539 if (lower
-step
> start
) lower
-= step
;
540 if (upper
+step
< end
) upper
+= step
;
543 dc
.SetBrush( *wxWHITE_BRUSH
);
544 dc
.SetPen( *wxTRANSPARENT_PEN
);
545 dc
.DrawRectangle( 4, 5, client_width
-14, 10 );
546 dc
.DrawRectangle( 0, 20, client_width
, 20 );
547 dc
.SetPen( *wxBLACK_PEN
);
549 double current
= lower
;
550 while (current
< upper
+(step
/2))
552 int x
= (int)ceil((current
-start
) / range
* (double)client_width
) - 1;
553 if ((x
> 4) && (x
< client_width
-25))
555 dc
.DrawLine( x
, 5, x
, 15 );
559 label
.Printf( _T("%f"), current
);
560 while (label
.Last() == _T('0'))
562 if ((label
.Last() == _T('.')) || (label
.Last() == _T(',')))
563 label
.Append( _T('0') );
566 label
.Printf( _T("%d"), (int)floor(current
) );
567 dc
.DrawText( label
, x
-4, 20 );
573 dc
.DrawLine( 0, 15, client_width
-8, 15 );
574 dc
.DrawLine( client_width
-4, 15, client_width
-10, 10 );
575 dc
.DrawLine( client_width
-4, 15, client_width
-10, 20 );
578 //-----------------------------------------------------------------------------
580 //-----------------------------------------------------------------------------
582 IMPLEMENT_DYNAMIC_CLASS(wxPlotYAxisArea
, wxWindow
)
584 BEGIN_EVENT_TABLE(wxPlotYAxisArea
, wxWindow
)
585 EVT_PAINT( wxPlotYAxisArea::OnPaint
)
586 EVT_LEFT_DOWN( wxPlotYAxisArea::OnMouse
)
589 wxPlotYAxisArea::wxPlotYAxisArea( wxPlotWindow
*parent
)
590 : wxWindow( parent
, wxID_ANY
, wxDefaultPosition
, wxSize(60,wxDefaultCoord
), 0, _T("plotyaxisarea") )
594 SetBackgroundColour( *wxWHITE
);
595 SetFont( *wxSMALL_FONT
);
598 void wxPlotYAxisArea::OnMouse( wxMouseEvent
&WXUNUSED(event
) )
600 /* do something here */
603 void wxPlotYAxisArea::OnPaint( wxPaintEvent
&WXUNUSED(event
) )
605 wxPaintDC
dc( this );
607 wxPlotCurve
*curve
= m_owner
->GetCurrentCurve();
613 GetClientSize( &client_width
, &client_height
);
616 double range
= curve
->GetEndY() - curve
->GetStartY();
617 double offset
= ((double) curve
->GetOffsetY() / (double)client_height
) * range
;
618 double start
= curve
->GetStartY() - offset
;
619 double end
= curve
->GetEndY() - offset
;
621 int int_log_range
= (int)floor( log10( range
) );
623 if (int_log_range
> 0)
625 for (int i
= 0; i
< int_log_range
; i
++)
628 if (int_log_range
< 0)
630 for (int i
= 0; i
< -int_log_range
; i
++)
633 double lower
= ceil(start
/ step
) * step
;
634 double upper
= floor(end
/ step
) * step
;
636 // if too few values, shrink size
637 if ((range
/step
) < 4)
640 if (lower
-step
> start
) lower
-= step
;
641 if (upper
+step
< end
) upper
+= step
;
644 // if still too few, again
645 if ((range
/step
) < 4)
648 if (lower
-step
> start
) lower
-= step
;
649 if (upper
+step
< end
) upper
+= step
;
652 dc
.SetPen( *wxBLACK_PEN
);
654 double current
= lower
;
655 while (current
< upper
+(step
/2))
657 int y
= (int)((curve
->GetEndY()-current
) / range
* (double)client_height
) - 1;
658 y
-= curve
->GetOffsetY();
659 if ((y
> 10) && (y
< client_height
-7))
661 dc
.DrawLine( client_width
-15, y
, client_width
-7, y
);
665 label
.Printf( _T("%f"), current
);
666 while (label
.Last() == _T('0'))
668 if ((label
.Last() == _T('.')) || (label
.Last() == _T(',')))
669 label
.Append( _T('0') );
672 label
.Printf( _T("%d"), (int)floor(current
) );
673 dc
.DrawText( label
, 5, y
-7 );
679 dc
.DrawLine( client_width
-15, 6, client_width
-15, client_height
);
680 dc
.DrawLine( client_width
-15, 2, client_width
-20, 8 );
681 dc
.DrawLine( client_width
-15, 2, client_width
-10, 8 );
684 //-----------------------------------------------------------------------------
686 //-----------------------------------------------------------------------------
688 #define ID_ENLARGE 1000
689 #define ID_SHRINK 1002
691 #define ID_MOVE_UP 1006
692 #define ID_MOVE_DOWN 1007
694 #define ID_ZOOM_IN 1010
695 #define ID_ZOOM_OUT 1011
698 IMPLEMENT_DYNAMIC_CLASS(wxPlotWindow
, wxScrolledWindow
)
700 BEGIN_EVENT_TABLE(wxPlotWindow
, wxScrolledWindow
)
701 EVT_BUTTON( ID_MOVE_UP
, wxPlotWindow::OnMoveUp
)
702 EVT_BUTTON( ID_MOVE_DOWN
, wxPlotWindow::OnMoveDown
)
704 EVT_BUTTON( ID_ENLARGE
, wxPlotWindow::OnEnlarge
)
705 EVT_BUTTON( ID_SHRINK
, wxPlotWindow::OnShrink
)
707 EVT_BUTTON( ID_ZOOM_IN
, wxPlotWindow::OnZoomIn
)
708 EVT_BUTTON( ID_ZOOM_OUT
, wxPlotWindow::OnZoomOut
)
710 EVT_SCROLLWIN( wxPlotWindow::OnScroll2
)
713 wxPlotWindow::wxPlotWindow( wxWindow
*parent
, wxWindowID id
, const wxPoint
&pos
, const wxSize
&size
, int flag
)
714 : wxScrolledWindow( parent
, id
, pos
, size
, flag
, _T("plotcanvas") ),
715 m_titleStaticText( NULL
)
717 m_xUnitsPerValue
= 1.0;
720 m_enlargeAroundWindowCentre
= false;
721 m_scrollOnThumbRelease
= false;
723 m_area
= new wxPlotArea( this );
724 wxBoxSizer
*mainsizer
= new wxBoxSizer( wxHORIZONTAL
);
726 if ((GetWindowStyleFlag() & wxPLOT_BUTTON_ALL
) != 0)
728 wxBoxSizer
*buttonlist
= new wxBoxSizer( wxVERTICAL
);
729 if ((GetWindowStyleFlag() & wxPLOT_BUTTON_ENLARGE
) != 0)
731 buttonlist
->Add( new wxBitmapButton( this, ID_ENLARGE
, *GetEnlargeBitmap() ), 0, wxEXPAND
|wxALL
, 2 );
732 buttonlist
->Add( new wxBitmapButton( this, ID_SHRINK
, *GetShrinkBitmap() ), 0, wxEXPAND
|wxALL
, 2 );
733 buttonlist
->Add( 20,10, 0 );
735 if ((GetWindowStyleFlag() & wxPLOT_BUTTON_MOVE
) != 0)
737 buttonlist
->Add( new wxBitmapButton( this, ID_MOVE_UP
, *GetUpBitmap() ), 0, wxEXPAND
|wxALL
, 2 );
738 buttonlist
->Add( new wxBitmapButton( this, ID_MOVE_DOWN
, *GetDownBitmap() ), 0, wxEXPAND
|wxALL
, 2 );
739 buttonlist
->Add( 20,10, 0 );
741 if ((GetWindowStyleFlag() & wxPLOT_BUTTON_ZOOM
) != 0)
743 buttonlist
->Add( new wxBitmapButton( this, ID_ZOOM_IN
, *GetZoomInBitmap() ), 0, wxEXPAND
|wxALL
, 2 );
744 buttonlist
->Add( new wxBitmapButton( this, ID_ZOOM_OUT
, *GetZoomOutBitmap() ), 0, wxEXPAND
|wxALL
, 2 );
746 mainsizer
->Add( buttonlist
, 0, wxEXPAND
|wxALL
, 4 );
749 wxBoxSizer
*plotsizer
= new wxBoxSizer( wxHORIZONTAL
);
751 //Add sizer to hold the title and plot.
752 //Title to be added later.
753 m_plotAndTitleSizer
= new wxBoxSizer( wxVERTICAL
);
754 m_plotAndTitleSizer
->Add( plotsizer
, 1, wxEXPAND
| wxTOP
, 10 );
756 if ((GetWindowStyleFlag() & wxPLOT_Y_AXIS
) != 0)
758 m_yaxis
= new wxPlotYAxisArea( this );
760 wxBoxSizer
*vert1
= new wxBoxSizer( wxVERTICAL
);
761 plotsizer
->Add( vert1
, 1, wxEXPAND
|wxTOP
,10 );
762 vert1
->Add( m_yaxis
, 1 );
763 if ((GetWindowStyleFlag() & wxPLOT_X_AXIS
) != 0)
764 vert1
->Add( 60, 40 );
768 m_yaxis
= (wxPlotYAxisArea
*) NULL
;
771 if ((GetWindowStyleFlag() & wxPLOT_X_AXIS
) != 0)
773 m_xaxis
= new wxPlotXAxisArea( this );
775 wxBoxSizer
*vert2
= new wxBoxSizer( wxVERTICAL
);
776 plotsizer
->Add( vert2
, 5, wxEXPAND
);
777 vert2
->Add( m_area
, 1, wxEXPAND
|wxTOP
,10 );
778 vert2
->Add( m_xaxis
, 0, wxEXPAND
);
782 plotsizer
->Add( m_area
, 1, wxEXPAND
);
783 m_xaxis
= (wxPlotXAxisArea
*) NULL
;
786 mainsizer
->Add( m_plotAndTitleSizer
, 1, wxEXPAND
);
788 SetAutoLayout( true );
789 SetSizer( mainsizer
);
790 mainsizer
->Fit(this);
791 mainsizer
->SetSizeHints(this);
793 SetTargetWindow( m_area
);
795 SetBackgroundColour( *wxWHITE
);
797 m_current
= (wxPlotCurve
*) NULL
;
800 wxPlotWindow::~wxPlotWindow()
804 void wxPlotWindow::Add( wxPlotCurve
*curve
)
806 m_curves
.Append( curve
);
807 if (!m_current
) m_current
= curve
;
812 size_t wxPlotWindow::GetCount()
814 return m_curves
.GetCount();
817 wxPlotCurve
*wxPlotWindow::GetAt( size_t n
)
819 wxList::compatibility_iterator node
= m_curves
.Item( n
);
821 return (wxPlotCurve
*) NULL
;
823 return (wxPlotCurve
*) node
->GetData();
826 void wxPlotWindow::SetCurrentCurve( wxPlotCurve
* current
)
829 m_area
->Refresh( false );
833 wxPlotEvent
event( wxEVT_PLOT_SEL_CHANGED
, GetId() );
834 event
.SetEventObject( this );
835 event
.SetZoom( GetZoom() );
836 event
.SetCurve( m_current
);
837 GetEventHandler()->ProcessEvent( event
);
840 void wxPlotWindow::Delete( wxPlotCurve
* curve
)
842 wxList::compatibility_iterator node
= m_curves
.Find( curve
);
845 m_curves
.DeleteObject( curve
);
847 m_area
->DeleteCurve( curve
);
848 m_area
->Refresh( false );
850 if (curve
== m_current
) m_current
= (wxPlotCurve
*) NULL
;
853 wxPlotCurve
*wxPlotWindow::GetCurrentCurve()
858 void wxPlotWindow::Add( wxPlotOnOffCurve
*curve
)
860 m_onOffCurves
.Append( curve
);
863 void wxPlotWindow::Delete( wxPlotOnOffCurve
* curve
)
865 wxList::compatibility_iterator node
= m_onOffCurves
.Find( curve
);
868 m_onOffCurves
.DeleteObject( curve
);
871 size_t wxPlotWindow::GetOnOffCurveCount()
873 return m_onOffCurves
.GetCount();
876 wxPlotOnOffCurve
*wxPlotWindow::GetOnOffCurveAt( size_t n
)
878 wxList::compatibility_iterator node
= m_onOffCurves
.Item( n
);
880 return (wxPlotOnOffCurve
*) NULL
;
882 return (wxPlotOnOffCurve
*) node
->GetData();
885 void wxPlotWindow::Move( wxPlotCurve
* curve
, int pixels_up
)
887 m_area
->DeleteCurve( curve
);
889 curve
->SetOffsetY( curve
->GetOffsetY() + pixels_up
);
891 m_area
->Refresh( false );
896 void wxPlotWindow::OnMoveUp( wxCommandEvent
& WXUNUSED(event
) )
898 if (!m_current
) return;
900 Move( m_current
, 25 );
903 void wxPlotWindow::OnMoveDown( wxCommandEvent
& WXUNUSED(event
) )
905 if (!m_current
) return;
907 Move( m_current
, -25 );
910 void wxPlotWindow::Enlarge( wxPlotCurve
*curve
, double factor
)
912 m_area
->DeleteCurve( curve
);
916 m_area
->GetClientSize( &client_width
, &client_height
);
917 double offset
= (double)curve
->GetOffsetY() / (double)client_height
;
919 double range
= curve
->GetEndY() - curve
->GetStartY();
922 double new_range
= range
/ factor
;
923 double new_offset
= offset
/ factor
;
925 if (m_enlargeAroundWindowCentre
)
927 double middle
= curve
->GetStartY() - offset
+ range
/2;
929 curve
->SetStartY( middle
- new_range
/ 2 + new_offset
);
930 curve
->SetEndY( middle
+ new_range
/ 2 + new_offset
);
934 curve
->SetStartY( (curve
->GetStartY() - offset
)/factor
+ new_offset
);
935 curve
->SetEndY( (curve
->GetEndY() - offset
)/factor
+ new_offset
);
938 m_area
->Refresh( false );
942 void wxPlotWindow::SetUnitsPerValue( double upv
)
944 m_xUnitsPerValue
= upv
;
949 void wxPlotWindow::SetZoom( double zoom
)
951 double old_zoom
= m_xZoom
;
956 GetViewStart( &view_x
, &view_y
);
959 wxList::compatibility_iterator node
= m_curves
.GetFirst();
962 wxPlotCurve
*curve
= (wxPlotCurve
*) node
->GetData();
963 if (curve
->GetEndX() > max
)
964 max
= curve
->GetEndX();
965 node
= node
->GetNext();
967 SetScrollbars( wxPLOT_SCROLL_STEP
, wxPLOT_SCROLL_STEP
,
968 (int)((max
*m_xZoom
)/wxPLOT_SCROLL_STEP
)+1, 0,
969 (int)(view_x
*zoom
/old_zoom
), 0,
973 m_area
->Refresh( true );
976 void wxPlotWindow::ResetScrollbar()
979 wxList::compatibility_iterator node
= m_curves
.GetFirst();
982 wxPlotCurve
*curve
= (wxPlotCurve
*) node
->GetData();
983 if (curve
->GetEndX() > max
)
984 max
= curve
->GetEndX();
985 node
= node
->GetNext();
988 SetScrollbars( wxPLOT_SCROLL_STEP
, wxPLOT_SCROLL_STEP
,
989 (int)(((max
*m_xZoom
)/wxPLOT_SCROLL_STEP
)+1), 0 );
992 void wxPlotWindow::AddChartTitle(const wxString
& title
, wxFont font
,
997 m_titleColour
= colour
;
1001 void wxPlotWindow::DrawChartTitle()
1003 if(m_title
.size() != 0)
1005 //If it is already added, remove child and delete
1006 if(m_titleStaticText
)
1008 RemoveChild( m_titleStaticText
);
1009 m_titleStaticText
->Destroy();
1012 //Create the text control and set the font, colour
1013 m_titleStaticText
= new wxStaticText( this, -1, m_title
);
1014 m_titleStaticText
->SetFont( m_titleFont
);
1015 m_titleStaticText
->SetForegroundColour( m_titleColour
);
1017 //Create a sizer for the title. Prepend it to the Plot + Title sizer.
1018 wxBoxSizer
* titleSizer
= new wxBoxSizer( wxHORIZONTAL
);
1019 titleSizer
->Add( m_titleStaticText
, 0, wxALIGN_CENTER
| wxALL
, 10 );
1020 m_plotAndTitleSizer
->Prepend( titleSizer
, 0, wxALIGN_CENTER_HORIZONTAL
);
1022 //Finally, force layout
1023 m_plotAndTitleSizer
->Layout();
1027 void wxPlotWindow::RedrawXAxis()
1030 m_xaxis
->Refresh( true );
1033 void wxPlotWindow::RedrawYAxis()
1036 m_yaxis
->Refresh( true );
1039 void wxPlotWindow::RedrawEverything()
1042 m_xaxis
->Refresh( true );
1044 m_yaxis
->Refresh( true );
1045 m_area
->Refresh( true );
1050 void wxPlotWindow::OnZoomIn( wxCommandEvent
& WXUNUSED(event
) )
1052 SetZoom( m_xZoom
* 1.5 );
1055 void wxPlotWindow::OnZoomOut( wxCommandEvent
& WXUNUSED(event
) )
1057 SetZoom( m_xZoom
* 0.6666 );
1060 void wxPlotWindow::OnEnlarge( wxCommandEvent
& WXUNUSED(event
) )
1062 if (!m_current
) return;
1064 Enlarge( m_current
, 1.5 );
1067 void wxPlotWindow::OnShrink( wxCommandEvent
& WXUNUSED(event
) )
1069 if (!m_current
) return;
1071 Enlarge( m_current
, 0.6666666 );
1074 void wxPlotWindow::OnScroll2( wxScrollWinEvent
& event
)
1076 if ((!m_scrollOnThumbRelease
) || (event
.GetEventType() != wxEVT_SCROLLWIN_THUMBTRACK
))
1078 wxScrolledWindow::OnScroll( event
);
1083 // ----------------------------------------------------------------------------
1085 // ----------------------------------------------------------------------------
1088 static wxBitmap
*GetEnlargeBitmap()
1090 static wxBitmap
* s_bitmap
= (wxBitmap
*) NULL
;
1091 static bool s_loaded
= false;
1095 s_loaded
= true; // set it to true anyhow, we won't try again
1097 #if defined(__WXMSW__) || defined(__WXPM__)
1098 s_bitmap
= new wxBitmap(_T("plot_enl_bmp"), wxBITMAP_TYPE_RESOURCE
);
1100 s_bitmap
= new wxBitmap( plot_enl_xpm
);
1107 static wxBitmap
*GetShrinkBitmap()
1109 static wxBitmap
* s_bitmap
= (wxBitmap
*) NULL
;
1110 static bool s_loaded
= false;
1114 s_loaded
= true; // set it to true anyhow, we won't try again
1116 #if defined(__WXMSW__) || defined(__WXPM__)
1117 s_bitmap
= new wxBitmap(_T("plot_shr_bmp"), wxBITMAP_TYPE_RESOURCE
);
1119 s_bitmap
= new wxBitmap( plot_shr_xpm
);
1126 static wxBitmap
*GetZoomInBitmap()
1128 static wxBitmap
* s_bitmap
= (wxBitmap
*) NULL
;
1129 static bool s_loaded
= false;
1133 s_loaded
= true; // set it to true anyhow, we won't try again
1135 #if defined(__WXMSW__) || defined(__WXPM__)
1136 s_bitmap
= new wxBitmap(_T("plot_zin_bmp"), wxBITMAP_TYPE_RESOURCE
);
1138 s_bitmap
= new wxBitmap( plot_zin_xpm
);
1145 static wxBitmap
*GetZoomOutBitmap()
1147 static wxBitmap
* s_bitmap
= (wxBitmap
*) NULL
;
1148 static bool s_loaded
= false;
1152 s_loaded
= true; // set it to true anyhow, we won't try again
1154 #if defined(__WXMSW__) || defined(__WXPM__)
1155 s_bitmap
= new wxBitmap(_T("plot_zot_bmp"), wxBITMAP_TYPE_RESOURCE
);
1157 s_bitmap
= new wxBitmap( plot_zot_xpm
);
1164 static wxBitmap
*GetUpBitmap()
1166 static wxBitmap
* s_bitmap
= (wxBitmap
*) NULL
;
1167 static bool s_loaded
= false;
1171 s_loaded
= true; // set it to true anyhow, we won't try again
1173 #if defined(__WXMSW__) || defined(__WXPM__)
1174 s_bitmap
= new wxBitmap(_T("plot_up_bmp"), wxBITMAP_TYPE_RESOURCE
);
1176 s_bitmap
= new wxBitmap( plot_up_xpm
);
1183 static wxBitmap
*GetDownBitmap()
1185 static wxBitmap
* s_bitmap
= (wxBitmap
*) NULL
;
1186 static bool s_loaded
= false;
1190 s_loaded
= true; // set it to true anyhow, we won't try again
1192 #if defined(__WXMSW__) || defined(__WXPM__)
1193 s_bitmap
= new wxBitmap(_T("plot_dwn_bmp"), wxBITMAP_TYPE_RESOURCE
);
1195 s_bitmap
= new wxBitmap( plot_dwn_xpm
);