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"
39 // ----------------------------------------------------------------------------
41 // ----------------------------------------------------------------------------
43 #if !defined(__WXMSW__) && !defined(__WXPM__)
44 #include "wx/plot/plot_enl.xpm"
45 #include "wx/plot/plot_shr.xpm"
46 #include "wx/plot/plot_zin.xpm"
47 #include "wx/plot/plot_zot.xpm"
48 #include "wx/plot/plot_up.xpm"
49 #include "wx/plot/plot_dwn.xpm"
52 //----------------------------------------------------------------------------
53 // accessor functions for the bitmaps (may return NULL, check for it!)
54 //----------------------------------------------------------------------------
56 static wxBitmap
*GetEnlargeBitmap();
57 static wxBitmap
*GetShrinkBitmap();
58 static wxBitmap
*GetZoomInBitmap();
59 static wxBitmap
*GetZoomOutBitmap();
60 static wxBitmap
*GetUpBitmap();
61 static wxBitmap
*GetDownBitmap();
63 //----------------------------------------------------------------------------
65 //----------------------------------------------------------------------------
67 int wxEVT_PLOT_SEL_CHANGING
;
68 int wxEVT_PLOT_SEL_CHANGED
;
69 int wxEVT_PLOT_CLICKED
;
70 int wxEVT_PLOT_DOUBLECLICKED
;
71 int wxEVT_PLOT_ZOOM_IN
;
72 int wxEVT_PLOT_ZOOM_OUT
;
73 int wxEVT_PLOT_VALUE_SEL_CREATING
;
74 int wxEVT_PLOT_VALUE_SEL_CREATED
;
75 int wxEVT_PLOT_VALUE_SEL_CHANGING
;
76 int wxEVT_PLOT_VALUE_SEL_CHANGED
;
77 int wxEVT_PLOT_AREA_SEL_CREATING
;
78 int wxEVT_PLOT_AREA_SEL_CREATED
;
79 int wxEVT_PLOT_AREA_SEL_CHANGING
;
80 int wxEVT_PLOT_AREA_SEL_CHANGED
;
81 int wxEVT_PLOT_BEGIN_X_LABEL_EDIT
;
82 int wxEVT_PLOT_END_X_LABEL_EDIT
;
83 int wxEVT_PLOT_BEGIN_Y_LABEL_EDIT
;
84 int wxEVT_PLOT_END_Y_LABEL_EDIT
;
85 int wxEVT_PLOT_BEGIN_TITLE_EDIT
;
86 int wxEVT_PLOT_END_TITLE_EDIT
;
87 int wxEVT_PLOT_AREA_CREATE
;
89 //-----------------------------------------------------------------------------
91 //-----------------------------------------------------------------------------
93 #define wxPLOT_SCROLL_STEP 30
95 //-----------------------------------------------------------------------------
97 //-----------------------------------------------------------------------------
99 wxPlotEvent::wxPlotEvent( wxEventType commandType
, int id
)
100 : wxNotifyEvent( commandType
, id
)
102 m_curve
= (wxPlotCurve
*) NULL
;
107 //-----------------------------------------------------------------------------
109 //-----------------------------------------------------------------------------
111 IMPLEMENT_ABSTRACT_CLASS(wxPlotCurve
, wxObject
)
113 wxPlotCurve::wxPlotCurve( int offsetY
, double startY
, double endY
)
120 //-----------------------------------------------------------------------------
122 //-----------------------------------------------------------------------------
124 IMPLEMENT_CLASS(wxPlotOnOffCurve
, wxObject
)
126 #include "wx/arrimpl.cpp"
127 WX_DEFINE_OBJARRAY(wxArrayPlotOnOff
);
129 wxPlotOnOffCurve::wxPlotOnOffCurve( int offsetY
)
136 void wxPlotOnOffCurve::Add( wxInt32 on
, wxInt32 off
, void *clientData
)
138 wxASSERT_MSG( on
> 0, wxT("plot index < 0") );
139 wxASSERT( on
<= off
);
146 wxPlotOnOff
*v
= new wxPlotOnOff
;
149 v
->m_clientData
= clientData
;
153 size_t wxPlotOnOffCurve::GetCount()
155 return m_marks
.GetCount();
158 wxInt32
wxPlotOnOffCurve::GetOn( size_t index
)
160 wxPlotOnOff
*v
= &m_marks
.Item( index
);
164 wxInt32
wxPlotOnOffCurve::GetOff( size_t index
)
166 wxPlotOnOff
*v
= &m_marks
.Item( index
);
170 void* wxPlotOnOffCurve::GetClientData( size_t index
)
172 wxPlotOnOff
*v
= &m_marks
.Item( index
);
173 return v
->m_clientData
;
176 wxPlotOnOff
*wxPlotOnOffCurve::GetAt( size_t index
)
178 return &m_marks
.Item( index
);
181 void wxPlotOnOffCurve::DrawOnLine( wxDC
&dc
, wxCoord y
, wxCoord start
, wxCoord end
, void *WXUNUSED(clientData
) )
183 dc
.DrawLine( start
, y
, start
, y
-30 );
184 dc
.DrawLine( start
, y
-30, end
, y
-30 );
185 dc
.DrawLine( end
, y
-30, end
, y
);
188 void wxPlotOnOffCurve::DrawOffLine( wxDC
&dc
, wxCoord y
, wxCoord start
, wxCoord end
)
190 dc
.DrawLine( start
, y
, end
, y
);
193 //-----------------------------------------------------------------------------
195 //-----------------------------------------------------------------------------
197 IMPLEMENT_DYNAMIC_CLASS(wxPlotArea
, wxWindow
)
199 BEGIN_EVENT_TABLE(wxPlotArea
, wxWindow
)
200 EVT_PAINT( wxPlotArea::OnPaint
)
201 EVT_LEFT_DOWN( wxPlotArea::OnMouse
)
202 EVT_LEFT_DCLICK( wxPlotArea::OnMouse
)
205 wxPlotArea::wxPlotArea( wxPlotWindow
*parent
)
206 : wxWindow( parent
, -1, wxDefaultPosition
, wxDefaultSize
, wxSIMPLE_BORDER
, "plotarea" )
212 SetBackgroundColour( *wxWHITE
);
215 void wxPlotArea::OnMouse( wxMouseEvent
&event
)
219 GetClientSize( &client_width
, &client_height
);
222 m_owner
->GetViewStart( &view_x
, &view_y
);
223 view_x
*= wxPLOT_SCROLL_STEP
;
224 view_y
*= wxPLOT_SCROLL_STEP
;
226 wxCoord x
= event
.GetX();
227 wxCoord y
= event
.GetY();
231 wxNode
*node
= m_owner
->m_curves
.First();
234 wxPlotCurve
*curve
= (wxPlotCurve
*)node
->Data();
236 double double_client_height
= (double)client_height
;
237 double range
= curve
->GetEndY() - curve
->GetStartY();
238 double end
= curve
->GetEndY();
239 wxCoord offset_y
= curve
->GetOffsetY();
241 double dy
= (end
- curve
->GetY( (wxInt32
)(x
/m_owner
->GetZoom()) )) / range
;
242 wxCoord curve_y
= (wxCoord
)(dy
* double_client_height
) - offset_y
- 1;
244 if ((y
-curve_y
< 4) && (y
-curve_y
> -4))
246 wxPlotEvent
event1( event
.ButtonDClick() ? wxEVT_PLOT_DOUBLECLICKED
: wxEVT_PLOT_CLICKED
, m_owner
->GetId() );
247 event1
.SetEventObject( m_owner
);
248 event1
.SetZoom( m_owner
->GetZoom() );
249 event1
.SetCurve( curve
);
250 event1
.SetPosition( (int)floor(x
/m_owner
->GetZoom()) );
251 m_owner
->GetEventHandler()->ProcessEvent( event1
);
253 if (curve
!= m_owner
->GetCurrent())
255 wxPlotEvent
event2( wxEVT_PLOT_SEL_CHANGING
, m_owner
->GetId() );
256 event2
.SetEventObject( m_owner
);
257 event2
.SetZoom( m_owner
->GetZoom() );
258 event2
.SetCurve( curve
);
259 if (!m_owner
->GetEventHandler()->ProcessEvent( event2
) || event2
.IsAllowed())
261 m_owner
->SetCurrent( curve
);
271 void wxPlotArea::DeleteCurve( wxPlotCurve
*curve
, int from
, int to
)
274 m_owner
->PrepareDC( dc
);
275 dc
.SetPen( *wxWHITE_PEN
);
276 DrawCurve( &dc
, curve
, from
, to
);
279 void wxPlotArea::DrawCurve( wxDC
*dc
, wxPlotCurve
*curve
, int from
, int to
)
283 m_owner
->GetViewStart( &view_x
, &view_y
);
284 view_x
*= wxPLOT_SCROLL_STEP
;
291 GetClientSize( &client_width
, &client_height
);
294 to
= view_x
+ client_width
;
296 double zoom
= m_owner
->GetZoom();
298 int start_x
= wxMax( from
, (int)floor(curve
->GetStartX()*zoom
) );
299 int end_x
= wxMin( to
, (int)floor(curve
->GetEndX()*zoom
) );
301 start_x
= wxMax( view_x
, start_x
);
302 end_x
= wxMin( view_x
+ client_width
, end_x
);
306 double double_client_height
= (double)client_height
;
307 double range
= curve
->GetEndY() - curve
->GetStartY();
308 double end
= curve
->GetEndY();
309 wxCoord offset_y
= curve
->GetOffsetY();
311 wxCoord y
=0,last_y
=0;
312 for (int x
= start_x
; x
< end_x
; x
++)
314 double dy
= (end
- curve
->GetY( (wxInt32
)(x
/zoom
) )) / range
;
315 y
= (wxCoord
)(dy
* double_client_height
) - offset_y
- 1;
318 dc
->DrawLine( x
-1, last_y
, x
, y
);
324 void wxPlotArea::DrawOnOffCurve( wxDC
*dc
, wxPlotOnOffCurve
*curve
, int from
, int to
)
328 m_owner
->GetViewStart( &view_x
, &view_y
);
329 view_x
*= wxPLOT_SCROLL_STEP
;
336 GetClientSize( &client_width
, &client_height
);
339 to
= view_x
+ client_width
;
341 double zoom
= m_owner
->GetZoom();
343 int start_x
= wxMax( from
, (int)floor(curve
->GetStartX()*zoom
) );
344 int end_x
= wxMin( to
, (int)floor(curve
->GetEndX()*zoom
) );
346 start_x
= wxMax( view_x
, start_x
);
347 end_x
= wxMin( view_x
+ client_width
, end_x
);
351 wxCoord offset_y
= curve
->GetOffsetY();
352 wxCoord last_off
= -5;
354 if (curve
->GetCount() == 0)
357 for (size_t index
= 0; index
< curve
->GetCount(); index
++)
359 wxPlotOnOff
*p
= curve
->GetAt( index
);
361 wxCoord on
= (wxCoord
)(p
->m_on
*zoom
);
362 wxCoord off
= (wxCoord
)(p
->m_off
*zoom
);
366 curve
->DrawOffLine( *dc
, client_height
-offset_y
, last_off
, on
);
372 curve
->DrawOffLine( *dc
, client_height
-offset_y
, last_off
, on
);
373 curve
->DrawOnLine( *dc
, client_height
-offset_y
, on
, off
, p
->m_clientData
);
378 wxPlotOnOff
*p
= curve
->GetAt( curve
->GetCount()-1 );
379 wxCoord off
= (wxCoord
)(p
->m_off
*zoom
);
381 curve
->DrawOffLine( *dc
, client_height
-offset_y
, off
, to
);
384 void wxPlotArea::OnPaint( wxPaintEvent
&WXUNUSED(event
) )
388 m_owner
->GetViewStart( &view_x
, &view_y
);
389 view_x
*= wxPLOT_SCROLL_STEP
;
390 view_y
*= wxPLOT_SCROLL_STEP
;
392 wxPaintDC
dc( this );
393 m_owner
->PrepareDC( dc
);
395 wxRegionIterator
upd( GetUpdateRegion() );
399 int update_x
= upd
.GetX();
400 int update_y
= upd
.GetY();
401 int update_width
= upd
.GetWidth();
407 if (m_owner->m_current)
409 dc.SetPen( *wxLIGHT_GREY_PEN );
410 int base_line = client_height - m_owner->m_current->GetOffsetY();
411 dc.DrawLine( update_x-1, base_line-1, update_x+update_width+2, base_line-1 );
415 wxNode
*node
= m_owner
->m_curves
.First();
418 wxPlotCurve
*curve
= (wxPlotCurve
*) node
->Data();
420 if (curve
== m_owner
->GetCurrent())
421 dc
.SetPen( *wxBLACK_PEN
);
423 dc
.SetPen( *wxGREY_PEN
);
425 DrawCurve( &dc
, curve
, update_x
-1, update_x
+update_width
+2 );
430 dc
.SetPen( *wxRED_PEN
);
432 node
= m_owner
->m_onOffCurves
.First();
435 wxPlotOnOffCurve
*curve
= (wxPlotOnOffCurve
*) node
->Data();
437 DrawOnOffCurve( &dc
, curve
, update_x
-1, update_x
+update_width
+2 );
446 void wxPlotArea::ScrollWindow( int dx
, int dy
, const wxRect
*rect
)
448 wxWindow::ScrollWindow( dx
, dy
, rect
);
449 // m_owner->m_xaxis->ScrollWindow( dx, 0 );
452 //-----------------------------------------------------------------------------
454 //-----------------------------------------------------------------------------
456 IMPLEMENT_DYNAMIC_CLASS(wxPlotXAxisArea
, wxWindow
)
458 BEGIN_EVENT_TABLE(wxPlotXAxisArea
, wxWindow
)
459 EVT_PAINT( wxPlotXAxisArea::OnPaint
)
460 EVT_LEFT_DOWN( wxPlotXAxisArea::OnMouse
)
463 wxPlotXAxisArea::wxPlotXAxisArea( wxPlotWindow
*parent
)
464 : wxWindow( parent
, -1, wxDefaultPosition
, wxSize(-1,40), 0, "plotxaxisarea" )
468 SetBackgroundColour( *wxWHITE
);
469 SetFont( *wxSMALL_FONT
);
472 void wxPlotXAxisArea::OnMouse( wxMouseEvent
&event
)
476 GetClientSize( &client_width
, &client_height
);
479 m_owner
->GetViewStart( &view_x
, &view_y
);
480 view_x
*= wxPLOT_SCROLL_STEP
;
481 view_y
*= wxPLOT_SCROLL_STEP
;
483 wxCoord x
= event
.GetX();
484 wxCoord y
= event
.GetY();
488 /* do something here */
491 void wxPlotXAxisArea::OnPaint( wxPaintEvent
&WXUNUSED(event
) )
495 m_owner
->GetViewStart( &view_x
, &view_y
);
496 view_x
*= wxPLOT_SCROLL_STEP
;
497 view_y
*= wxPLOT_SCROLL_STEP
;
499 wxPaintDC
dc( this );
503 GetClientSize( &client_width
, &client_height
);
505 double zoom
= m_owner
->GetZoom();
507 double ups
= m_owner
->GetUnitsPerValue() / zoom
;
509 double start
= view_x
* ups
;
510 double end
= (view_x
+ client_width
) * ups
;
511 double range
= end
- start
;
513 int int_log_range
= (int)floor( log10( range
) );
515 if (int_log_range
> 0)
517 for (int i
= 0; i
< int_log_range
; i
++)
520 if (int_log_range
< 0)
522 for (int i
= 0; i
< -int_log_range
; i
++)
525 double lower
= ceil(start
/ step
) * step
;
526 double upper
= floor(end
/ step
) * step
;
528 // if too few values, shrink size
529 if ((range
/step
) < 4)
532 if (lower
-step
> start
) lower
-= step
;
533 if (upper
+step
< end
) upper
+= step
;
536 // if still too few, again
537 if ((range
/step
) < 4)
540 if (lower
-step
> start
) lower
-= step
;
541 if (upper
+step
< end
) upper
+= step
;
544 dc
.SetBrush( *wxWHITE_BRUSH
);
545 dc
.SetPen( *wxTRANSPARENT_PEN
);
546 dc
.DrawRectangle( 4, 5, client_width
-14, 10 );
547 dc
.DrawRectangle( 0, 20, client_width
, 20 );
548 dc
.SetPen( *wxBLACK_PEN
);
550 double current
= lower
;
551 while (current
< upper
+(step
/2))
553 int x
= (int)ceil((current
-start
) / range
* (double)client_width
) - 1;
554 if ((x
> 4) && (x
< client_width
-25))
556 dc
.DrawLine( x
, 5, x
, 15 );
560 label
.Printf( wxT("%f"), current
);
561 while (label
.Last() == wxT('0'))
563 if ((label
.Last() == wxT('.')) || (label
.Last() == wxT(',')))
564 label
.Append( wxT('0') );
567 label
.Printf( wxT("%d"), (int)floor(current
) );
568 dc
.DrawText( label
, x
-4, 20 );
574 dc
.DrawLine( 0, 15, client_width
-8, 15 );
575 dc
.DrawLine( client_width
-4, 15, client_width
-10, 10 );
576 dc
.DrawLine( client_width
-4, 15, client_width
-10, 20 );
579 //-----------------------------------------------------------------------------
581 //-----------------------------------------------------------------------------
583 IMPLEMENT_DYNAMIC_CLASS(wxPlotYAxisArea
, wxWindow
)
585 BEGIN_EVENT_TABLE(wxPlotYAxisArea
, wxWindow
)
586 EVT_PAINT( wxPlotYAxisArea::OnPaint
)
587 EVT_LEFT_DOWN( wxPlotYAxisArea::OnMouse
)
590 wxPlotYAxisArea::wxPlotYAxisArea( wxPlotWindow
*parent
)
591 : wxWindow( parent
, -1, wxDefaultPosition
, wxSize(60,-1), 0, "plotyaxisarea" )
595 SetBackgroundColour( *wxWHITE
);
596 SetFont( *wxSMALL_FONT
);
599 void wxPlotYAxisArea::OnMouse( wxMouseEvent
&WXUNUSED(event
) )
601 /* do something here */
604 void wxPlotYAxisArea::OnPaint( wxPaintEvent
&WXUNUSED(event
) )
606 wxPaintDC
dc( this );
608 wxPlotCurve
*curve
= m_owner
->GetCurrent();
614 GetClientSize( &client_width
, &client_height
);
617 double range
= curve
->GetEndY() - curve
->GetStartY();
618 double offset
= ((double) curve
->GetOffsetY() / (double)client_height
) * range
;
619 double start
= curve
->GetStartY() - offset
;
620 double end
= curve
->GetEndY() - offset
;
622 int int_log_range
= (int)floor( log10( range
) );
624 if (int_log_range
> 0)
626 for (int i
= 0; i
< int_log_range
; i
++)
629 if (int_log_range
< 0)
631 for (int i
= 0; i
< -int_log_range
; i
++)
634 double lower
= ceil(start
/ step
) * step
;
635 double upper
= floor(end
/ step
) * step
;
637 // if too few values, shrink size
638 if ((range
/step
) < 4)
641 if (lower
-step
> start
) lower
-= step
;
642 if (upper
+step
< end
) upper
+= step
;
645 // if still too few, again
646 if ((range
/step
) < 4)
649 if (lower
-step
> start
) lower
-= step
;
650 if (upper
+step
< end
) upper
+= step
;
653 dc
.SetPen( *wxBLACK_PEN
);
655 double current
= lower
;
656 while (current
< upper
+(step
/2))
658 int y
= (int)((curve
->GetEndY()-current
) / range
* (double)client_height
) - 1;
659 y
-= curve
->GetOffsetY();
660 if ((y
> 10) && (y
< client_height
-7))
662 dc
.DrawLine( client_width
-15, y
, client_width
-7, y
);
666 label
.Printf( wxT("%f"), current
);
667 while (label
.Last() == wxT('0'))
669 if ((label
.Last() == wxT('.')) || (label
.Last() == wxT(',')))
670 label
.Append( wxT('0') );
673 label
.Printf( wxT("%d"), (int)floor(current
) );
674 dc
.DrawText( label
, 5, y
-7 );
680 dc
.DrawLine( client_width
-15, 6, client_width
-15, client_height
);
681 dc
.DrawLine( client_width
-15, 2, client_width
-20, 8 );
682 dc
.DrawLine( client_width
-15, 2, client_width
-10, 8 );
685 //-----------------------------------------------------------------------------
687 //-----------------------------------------------------------------------------
689 #define ID_ENLARGE 1000
690 #define ID_SHRINK 1002
692 #define ID_MOVE_UP 1006
693 #define ID_MOVE_DOWN 1007
695 #define ID_ZOOM_IN 1010
696 #define ID_ZOOM_OUT 1011
699 IMPLEMENT_DYNAMIC_CLASS(wxPlotWindow
, wxScrolledWindow
)
701 BEGIN_EVENT_TABLE(wxPlotWindow
, wxScrolledWindow
)
702 EVT_BUTTON( ID_MOVE_UP
, wxPlotWindow::OnMoveUp
)
703 EVT_BUTTON( ID_MOVE_DOWN
, wxPlotWindow::OnMoveDown
)
705 EVT_BUTTON( ID_ENLARGE
, wxPlotWindow::OnEnlarge
)
706 EVT_BUTTON( ID_SHRINK
, wxPlotWindow::OnShrink
)
708 EVT_BUTTON( ID_ZOOM_IN
, wxPlotWindow::OnZoomIn
)
709 EVT_BUTTON( ID_ZOOM_OUT
, wxPlotWindow::OnZoomOut
)
711 EVT_SCROLLWIN( wxPlotWindow::OnScroll2
)
714 wxPlotWindow::wxPlotWindow( wxWindow
*parent
, wxWindowID id
, const wxPoint
&pos
, const wxSize
&size
, int flag
)
715 : wxScrolledWindow( parent
, id
, pos
, size
, flag
, "plotcanvas" )
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 if ((GetWindowStyleFlag() & wxPLOT_Y_AXIS
) != 0)
753 m_yaxis
= new wxPlotYAxisArea( this );
755 wxBoxSizer
*vert1
= new wxBoxSizer( wxVERTICAL
);
756 plotsizer
->Add( vert1
, 0, wxEXPAND
);
757 vert1
->Add( m_yaxis
, 1 );
758 if ((GetWindowStyleFlag() & wxPLOT_X_AXIS
) != 0)
759 vert1
->Add( 60, 40 );
763 m_yaxis
= (wxPlotYAxisArea
*) NULL
;
766 if ((GetWindowStyleFlag() & wxPLOT_X_AXIS
) != 0)
768 m_xaxis
= new wxPlotXAxisArea( this );
770 wxBoxSizer
*vert2
= new wxBoxSizer( wxVERTICAL
);
771 plotsizer
->Add( vert2
, 1, wxEXPAND
);
772 vert2
->Add( m_area
, 1, wxEXPAND
);
773 vert2
->Add( m_xaxis
, 0, wxEXPAND
);
777 plotsizer
->Add( m_area
, 1, wxEXPAND
);
778 m_xaxis
= (wxPlotXAxisArea
*) NULL
;
781 mainsizer
->Add( plotsizer
, 1, wxEXPAND
);
783 SetAutoLayout( TRUE
);
784 SetSizer( mainsizer
);
786 SetTargetWindow( m_area
);
788 SetBackgroundColour( *wxWHITE
);
790 m_current
= (wxPlotCurve
*) NULL
;
793 wxPlotWindow::~wxPlotWindow()
797 void wxPlotWindow::Add( wxPlotCurve
*curve
)
799 m_curves
.Append( curve
);
800 if (!m_current
) m_current
= curve
;
805 size_t wxPlotWindow::GetCount()
807 return m_curves
.GetCount();
810 wxPlotCurve
*wxPlotWindow::GetAt( size_t n
)
812 wxNode
*node
= m_curves
.Nth( n
);
814 return (wxPlotCurve
*) NULL
;
816 return (wxPlotCurve
*) node
->Data();
819 void wxPlotWindow::SetCurrent( wxPlotCurve
* current
)
822 m_area
->Refresh( FALSE
);
826 wxPlotEvent
event( wxEVT_PLOT_SEL_CHANGED
, GetId() );
827 event
.SetEventObject( this );
828 event
.SetZoom( GetZoom() );
829 event
.SetCurve( m_current
);
830 GetEventHandler()->ProcessEvent( event
);
833 void wxPlotWindow::Delete( wxPlotCurve
* curve
)
835 wxNode
*node
= m_curves
.Find( curve
);
838 m_curves
.DeleteObject( curve
);
840 m_area
->DeleteCurve( curve
);
841 m_area
->Refresh( FALSE
);
844 wxPlotCurve
*wxPlotWindow::GetCurrent()
849 void wxPlotWindow::Add( wxPlotOnOffCurve
*curve
)
851 m_onOffCurves
.Append( curve
);
854 void wxPlotWindow::Delete( wxPlotOnOffCurve
* curve
)
856 wxNode
*node
= m_onOffCurves
.Find( curve
);
859 m_onOffCurves
.DeleteObject( curve
);
862 size_t wxPlotWindow::GetOnOffCurveCount()
864 return m_onOffCurves
.GetCount();
867 wxPlotOnOffCurve
*wxPlotWindow::GetOnOffCurveAt( size_t n
)
869 wxNode
*node
= m_onOffCurves
.Nth( n
);
871 return (wxPlotOnOffCurve
*) NULL
;
873 return (wxPlotOnOffCurve
*) node
->Data();
876 void wxPlotWindow::Move( wxPlotCurve
* curve
, int pixels_up
)
878 m_area
->DeleteCurve( curve
);
880 curve
->SetOffsetY( curve
->GetOffsetY() + pixels_up
);
882 m_area
->Refresh( FALSE
);
887 void wxPlotWindow::OnMoveUp( wxCommandEvent
& WXUNUSED(event
) )
889 if (!m_current
) return;
891 Move( m_current
, 25 );
894 void wxPlotWindow::OnMoveDown( wxCommandEvent
& WXUNUSED(event
) )
896 if (!m_current
) return;
898 Move( m_current
, -25 );
901 void wxPlotWindow::Enlarge( wxPlotCurve
*curve
, double factor
)
903 m_area
->DeleteCurve( curve
);
907 m_area
->GetClientSize( &client_width
, &client_height
);
908 double offset
= (double)curve
->GetOffsetY() / (double)client_height
;
910 double range
= curve
->GetEndY() - curve
->GetStartY();
913 double new_range
= range
/ factor
;
914 double new_offset
= offset
/ factor
;
916 if (m_enlargeAroundWindowCentre
)
918 double middle
= curve
->GetStartY() - offset
+ range
/2;
920 curve
->SetStartY( middle
- new_range
/ 2 + new_offset
);
921 curve
->SetEndY( middle
+ new_range
/ 2 + new_offset
);
925 curve
->SetStartY( (curve
->GetStartY() - offset
)/factor
+ new_offset
);
926 curve
->SetEndY( (curve
->GetEndY() - offset
)/factor
+ new_offset
);
929 m_area
->Refresh( FALSE
);
933 void wxPlotWindow::SetUnitsPerValue( double upv
)
935 m_xUnitsPerValue
= upv
;
940 void wxPlotWindow::SetZoom( double zoom
)
942 double old_zoom
= m_xZoom
;
947 GetViewStart( &view_x
, &view_y
);
950 wxNode
*node
= m_curves
.First();
953 wxPlotCurve
*curve
= (wxPlotCurve
*) node
->Data();
954 if (curve
->GetEndX() > max
)
955 max
= curve
->GetEndX();
958 SetScrollbars( wxPLOT_SCROLL_STEP
, wxPLOT_SCROLL_STEP
,
959 (int)((max
*m_xZoom
)/wxPLOT_SCROLL_STEP
)+1, 0,
960 (int)(view_x
*zoom
/old_zoom
), 0,
964 m_area
->Refresh( TRUE
);
967 void wxPlotWindow::ResetScrollbar()
970 wxNode
*node
= m_curves
.First();
973 wxPlotCurve
*curve
= (wxPlotCurve
*) node
->Data();
974 if (curve
->GetEndX() > max
)
975 max
= curve
->GetEndX();
979 SetScrollbars( wxPLOT_SCROLL_STEP
, wxPLOT_SCROLL_STEP
,
980 (int)(((max
*m_xZoom
)/wxPLOT_SCROLL_STEP
)+1), 0 );
983 void wxPlotWindow::RedrawXAxis()
986 m_xaxis
->Refresh( FALSE
);
989 void wxPlotWindow::RedrawYAxis()
992 m_yaxis
->Refresh( TRUE
);
995 void wxPlotWindow::RedrawEverything()
998 m_xaxis
->Refresh( TRUE
);
1000 m_yaxis
->Refresh( TRUE
);
1001 m_area
->Refresh( TRUE
);
1004 void wxPlotWindow::OnZoomIn( wxCommandEvent
& WXUNUSED(event
) )
1006 SetZoom( m_xZoom
* 1.5 );
1009 void wxPlotWindow::OnZoomOut( wxCommandEvent
& WXUNUSED(event
) )
1011 SetZoom( m_xZoom
* 0.6666 );
1014 void wxPlotWindow::OnEnlarge( wxCommandEvent
& WXUNUSED(event
) )
1016 if (!m_current
) return;
1018 Enlarge( m_current
, 1.5 );
1021 void wxPlotWindow::OnShrink( wxCommandEvent
& WXUNUSED(event
) )
1023 if (!m_current
) return;
1025 Enlarge( m_current
, 0.6666666 );
1028 void wxPlotWindow::OnScroll2( wxScrollWinEvent
& event
)
1030 if ((!m_scrollOnThumbRelease
) || (event
.GetEventType() != wxEVT_SCROLLWIN_THUMBTRACK
))
1032 wxScrolledWindow::OnScroll( event
);
1037 // ----------------------------------------------------------------------------
1039 // ----------------------------------------------------------------------------
1042 static wxBitmap
*GetEnlargeBitmap()
1044 static wxBitmap
* s_bitmap
= (wxBitmap
*) NULL
;
1045 static bool s_loaded
= FALSE
;
1049 s_loaded
= TRUE
; // set it to TRUE anyhow, we won't try again
1051 #if defined(__WXMSW__) || defined(__WXPM__)
1052 s_bitmap
= new wxBitmap("plot_enl_bmp", wxBITMAP_TYPE_RESOURCE
);
1054 s_bitmap
= new wxBitmap( plot_enl_xpm
);
1061 static wxBitmap
*GetShrinkBitmap()
1063 static wxBitmap
* s_bitmap
= (wxBitmap
*) NULL
;
1064 static bool s_loaded
= FALSE
;
1068 s_loaded
= TRUE
; // set it to TRUE anyhow, we won't try again
1070 #if defined(__WXMSW__) || defined(__WXPM__)
1071 s_bitmap
= new wxBitmap("plot_shr_bmp", wxBITMAP_TYPE_RESOURCE
);
1073 s_bitmap
= new wxBitmap( plot_shr_xpm
);
1080 static wxBitmap
*GetZoomInBitmap()
1082 static wxBitmap
* s_bitmap
= (wxBitmap
*) NULL
;
1083 static bool s_loaded
= FALSE
;
1087 s_loaded
= TRUE
; // set it to TRUE anyhow, we won't try again
1089 #if defined(__WXMSW__) || defined(__WXPM__)
1090 s_bitmap
= new wxBitmap("plot_zin_bmp", wxBITMAP_TYPE_RESOURCE
);
1092 s_bitmap
= new wxBitmap( plot_zin_xpm
);
1099 static wxBitmap
*GetZoomOutBitmap()
1101 static wxBitmap
* s_bitmap
= (wxBitmap
*) NULL
;
1102 static bool s_loaded
= FALSE
;
1106 s_loaded
= TRUE
; // set it to TRUE anyhow, we won't try again
1108 #if defined(__WXMSW__) || defined(__WXPM__)
1109 s_bitmap
= new wxBitmap("plot_zot_bmp", wxBITMAP_TYPE_RESOURCE
);
1111 s_bitmap
= new wxBitmap( plot_zot_xpm
);
1118 static wxBitmap
*GetUpBitmap()
1120 static wxBitmap
* s_bitmap
= (wxBitmap
*) NULL
;
1121 static bool s_loaded
= FALSE
;
1125 s_loaded
= TRUE
; // set it to TRUE anyhow, we won't try again
1127 #if defined(__WXMSW__) || defined(__WXPM__)
1128 s_bitmap
= new wxBitmap("plot_up_bmp", wxBITMAP_TYPE_RESOURCE
);
1130 s_bitmap
= new wxBitmap( plot_up_xpm
);
1137 static wxBitmap
*GetDownBitmap()
1139 static wxBitmap
* s_bitmap
= (wxBitmap
*) NULL
;
1140 static bool s_loaded
= FALSE
;
1144 s_loaded
= TRUE
; // set it to TRUE anyhow, we won't try again
1146 #if defined(__WXMSW__) || defined(__WXPM__)
1147 s_bitmap
= new wxBitmap("plot_dwn_bmp", wxBITMAP_TYPE_RESOURCE
);
1149 s_bitmap
= new wxBitmap( plot_dwn_xpm
);
1157 //----------------------------------------------------------------------------
1159 //----------------------------------------------------------------------------
1161 class wxPlotModule
: public wxModule
1168 DECLARE_CLASS(wxPlotModule
)
1171 IMPLEMENT_DYNAMIC_CLASS(wxPlotModule
, wxModule
)
1173 bool wxPlotModule::OnInit()
1175 wxEVT_PLOT_SEL_CHANGING
= wxNewId();
1176 wxEVT_PLOT_SEL_CHANGED
= wxNewId();
1177 wxEVT_PLOT_CLICKED
= wxNewId();
1178 wxEVT_PLOT_DOUBLECLICKED
= wxNewId();
1179 wxEVT_PLOT_ZOOM_IN
= wxNewId();
1180 wxEVT_PLOT_ZOOM_OUT
= wxNewId();
1181 wxEVT_PLOT_VALUE_SEL_CREATING
= wxNewId();
1182 wxEVT_PLOT_VALUE_SEL_CREATED
= wxNewId();
1183 wxEVT_PLOT_VALUE_SEL_CHANGING
= wxNewId();
1184 wxEVT_PLOT_VALUE_SEL_CHANGED
= wxNewId();
1185 wxEVT_PLOT_AREA_SEL_CREATING
= wxNewId();
1186 wxEVT_PLOT_AREA_SEL_CREATED
= wxNewId();
1187 wxEVT_PLOT_AREA_SEL_CHANGING
= wxNewId();
1188 wxEVT_PLOT_AREA_SEL_CHANGED
= wxNewId();
1189 wxEVT_PLOT_BEGIN_X_LABEL_EDIT
= wxNewId();
1190 wxEVT_PLOT_END_X_LABEL_EDIT
= wxNewId();
1191 wxEVT_PLOT_BEGIN_Y_LABEL_EDIT
= wxNewId();
1192 wxEVT_PLOT_END_Y_LABEL_EDIT
= wxNewId();
1193 wxEVT_PLOT_BEGIN_TITLE_EDIT
= wxNewId();
1194 wxEVT_PLOT_END_TITLE_EDIT
= wxNewId();
1195 wxEVT_PLOT_AREA_CREATE
= wxNewId();
1200 void wxPlotModule::OnExit()