1 ///////////////////////////////////////////////////////////////////////////// 2 // Name: plotctrl.h 3 // Purpose: wxPlotCtrl 4 // Author: John Labenski, Robert Roebling 5 // Modified by: 6 // Created: 6/5/2002 7 // Copyright: (c) John Labenski, Robert Roebling 8 // Licence: wxWindows licence 9 ///////////////////////////////////////////////////////////////////////////// 10 11 #ifndef _WX_PLOTCTRL_H_ 12 #define _WX_PLOTCTRL_H_ 13 14 #include "wx/defs.h" 15 #include "wx/geometry.h" 16 #include "wx/bitmap.h" 17 #include "wx/window.h" 18 #include "wx/plotctrl/plotdefs.h" 19 #include "wx/plotctrl/plotcurv.h" 20 #include "wx/plotctrl/plotdata.h" 21 #include "wx/plotctrl/plotmark.h" 22 #include "wx/plotctrl/plotfunc.h" 23 #include "wx/wxthings/range.h" 24 25 class WXDLLEXPORT wxDC; 26 class WXDLLEXPORT wxNotifyEvent; 27 class WXDLLEXPORT wxPaintEvent; 28 class WXDLLEXPORT wxMouseEvent; 29 class WXDLLEXPORT wxKeyEvent; 30 class WXDLLEXPORT wxTimer; 31 class WXDLLEXPORT wxTimerEvent; 32 class WXDLLEXPORT wxEraseEvent; 33 class WXDLLEXPORT wxScrollBar; 34 class WXDLLEXPORT wxBitmap; 35 class WXDLLEXPORT wxTextCtrl; 36 37 class WXDLLIMPEXP_THINGS wxRangeIntSelection; 38 class WXDLLIMPEXP_THINGS wxRangeDoubleSelection; 39 class WXDLLIMPEXP_THINGS wxArrayRangeIntSelection; 40 class WXDLLIMPEXP_THINGS wxArrayRangeDoubleSelection; 41 42 class WXDLLIMPEXP_PLOTCTRL wxPlotArea; 43 class WXDLLIMPEXP_PLOTCTRL wxPlotAxis; 44 class WXDLLIMPEXP_PLOTCTRL wxPlotCtrl; 45 class WXDLLIMPEXP_PLOTCTRL wxPlotEvent; 46 47 class WXDLLIMPEXP_PLOTCTRL wxPlotCurve; 48 class WXDLLIMPEXP_PLOTCTRL wxPlotData; 49 class WXDLLIMPEXP_PLOTCTRL wxPlotFunction; 50 51 class WXDLLIMPEXP_PLOTCTRL wxPlotDrawerArea; 52 class WXDLLIMPEXP_PLOTCTRL wxPlotDrawerXAxis; 53 class WXDLLIMPEXP_PLOTCTRL wxPlotDrawerYAxis; 54 class WXDLLIMPEXP_PLOTCTRL wxPlotDrawerKey; 55 class WXDLLIMPEXP_PLOTCTRL wxPlotDrawerCurve; 56 class WXDLLIMPEXP_PLOTCTRL wxPlotDrawerDataCurve; 57 class WXDLLIMPEXP_PLOTCTRL wxPlotDrawerMarker; 58 59 //----------------------------------------------------------------------------- 60 // wxPlot Constants 61 //----------------------------------------------------------------------------- 62 #ifdef __VISUALC__ 63 #include <yvals.h> 64 // disable warning for stl::numeric_limits, 65 // C++ language change: to explicitly specialize 66 #pragma warning(disable:4663) 67 #endif // __VISUALC__ 68 69 #include <limits> 70 extern std::numeric_limits<wxDouble> wxDouble_limits; 71 72 extern const wxDouble wxPlot_MIN_DBL; // = wxDouble_limits.min()*10 73 extern const wxDouble wxPlot_MAX_DBL; // = wxDouble_limits.max()/10 74 extern const wxDouble wxPlot_MAX_RANGE; // = wxPlot_MAX_DBL*2 75 76 #define CURSOR_GRAB (wxCURSOR_MAX+100) // A hand cursor with fingers closed 77 78 #include "wx/dynarray.h" 79 #ifndef WX_DECLARE_OBJARRAY_WITH_DECL // for wx2.4 backwards compatibility 80 #define WX_DECLARE_OBJARRAY_WITH_DECL(T, name, expmode) WX_DECLARE_USER_EXPORTED_OBJARRAY(T, name, WXDLLIMPEXP_PLOTCTRL) 81 #endif 82 WX_DECLARE_OBJARRAY_WITH_DECL(wxPoint2DDouble, wxArrayPoint2DDouble, class WXDLLIMPEXP_PLOTCTRL); 83 WX_DECLARE_OBJARRAY_WITH_DECL(wxRect2DDouble, wxArrayRect2DDouble, class WXDLLIMPEXP_PLOTCTRL); 84 WX_DECLARE_OBJARRAY_WITH_DECL(wxPlotCurve, wxArrayPlotCurve, class WXDLLIMPEXP_PLOTCTRL); 85 86 // What type of axis for wxPlotAxis window 87 enum wxPlotAxis_Type 88 { 89 wxPLOT_X_AXIS = 0x0020, 90 wxPLOT_Y_AXIS = 0x0200, 91 wxPLOT_DEFAULT = wxPLOT_X_AXIS|wxPLOT_Y_AXIS 92 }; 93 94 // What is the function of the mouse during left down and dragging 95 enum wxPlotMouse_Type 96 { 97 wxPLOT_MOUSE_NOTHING, // do nothing 98 wxPLOT_MOUSE_ZOOM, // zoom into the plot 99 wxPLOT_MOUSE_SELECT, // select points in the active curve 100 wxPLOT_MOUSE_DESELECT, // deselect points in the active curve 101 wxPLOT_MOUSE_PAN // offset the origin 102 }; 103 104 // What sort of marker should be drawn for mouse left down and dragging 105 enum wxPlotMarker_Type 106 { 107 wxPLOT_MARKER_NONE, // draw nothing 108 wxPLOT_MARKER_RECT, // draw a rectangle 109 wxPLOT_MARKER_VERT, // draw two vertical lines 110 wxPLOT_MARKER_HORIZ // draw two horizonal lines 111 }; 112 113 // How does the selection mechanism act to selections 114 enum wxPlotSelection_Type 115 { 116 wxPLOT_SELECT_NONE, // no selections 117 wxPLOT_SELECT_SINGLE, // only one selection in one curve at a time 118 wxPLOT_SELECT_SINGLE_CURVE, // only one curve may have selections at once 119 wxPLOT_SELECT_SINGLE_PER_CURVE, // multiple curves may one have one selection each 120 wxPLOT_SELECT_MULTIPLE // multiple curves may have multiple selections 121 }; 122 123 // Redraw parts or all of the windows 124 enum wxPlotRedraw_Type 125 { 126 wxPLOT_REDRAW_NONE = 0x000, // do nothing 127 wxPLOT_REDRAW_PLOT = 0x001, // redraw only the plot area 128 wxPLOT_REDRAW_XAXIS = 0x002, // redraw x-axis, combine w/ redraw_plot 129 wxPLOT_REDRAW_YAXIS = 0x004, // redraw y-axis, combine w/ redraw_plot 130 wxPLOT_REDRAW_WINDOW = 0x008, // wxPlotCtrl container window 131 wxPLOT_REDRAW_WHOLEPLOT = wxPLOT_REDRAW_PLOT|wxPLOT_REDRAW_XAXIS|wxPLOT_REDRAW_YAXIS, 132 wxPLOT_REDRAW_EVERYTHING = wxPLOT_REDRAW_WHOLEPLOT|wxPLOT_REDRAW_WINDOW, 133 wxPLOT_REDRAW_BLOCKER = 0x010 // don't let OnPaint redraw, used internally 134 }; 135 136 // Styles for the different plot window components 137 enum wxPlotStyle_Type 138 { 139 wxPLOT_STYLE_WINDOW, 140 wxPLOT_STYLE_LABELS, 141 wxPLOT_STYLE_TITLE, 142 wxPLOT_STYLE_XAXIS_LABEL, 143 wxPLOT_STYLE_YAXIS_LABEL, 144 wxPLOT_STYLE_XAXIS_TICS, 145 wxPLOT_STYLE_YAXIS_TICS, 146 wxPLOT_STYLE_KEY, 147 148 wxPLOT_STYLE_LAST 149 }; 150 151 enum wxPlotStyleUse_Type 152 { 153 wxPLOT_STYLEUSE_FORECOLOUR = 0x0001, 154 wxPLOT_STYLEUSE_BACKCOLOUR = 0x0002, 155 wxPLOT_STYLEUSE_FONT = 0x0004, 156 wxPLOT_STYLEUSE_LINEWIDTH = 0x0008 157 }; 158 159 //----------------------------------------------------------------------------- 160 // wxPlotArea - window where the plot is drawn (privately used in wxPlotCtrl) 161 //----------------------------------------------------------------------------- 162 163 class WXDLLIMPEXP_PLOTCTRL wxPlotArea : public wxWindow 164 { 165 public: wxPlotArea(wxWindow * parent,wxWindowID win_id)166 wxPlotArea( wxWindow *parent, wxWindowID win_id ) 167 { 168 Init(); 169 (void)Create(parent, win_id); 170 } 171 172 bool Create( wxWindow *parent, wxWindowID win_id ); ~wxPlotArea()173 virtual ~wxPlotArea() {} 174 175 // Get the owner (parent) wxPlotCtrl GetOwner()176 wxPlotCtrl *GetOwner() const { return m_owner; } 177 178 // Draw the area of the plot window in client coords bounded by rect 179 // resizes backing bitmap if necessary 180 void CreateBitmap( const wxRect &rect ); 181 182 // implementation OnEraseBackground(wxEraseEvent &)183 void OnEraseBackground( wxEraseEvent & ) { } 184 void OnPaint( wxPaintEvent &event ); 185 void OnMouse( wxMouseEvent &event ); 186 void OnChar( wxKeyEvent &event ); 187 void OnKeyDown( wxKeyEvent &event ); 188 void OnKeyUp( wxKeyEvent &event ); 189 190 wxRect m_mouseRect; // mouse drag rectangle, or 0,0,0,0 when not dragging 191 wxPoint m_mousePt; // last mouse position 192 wxBitmap m_bitmap; 193 wxPlotCtrl *m_owner; 194 195 private: 196 void Init(); 197 DECLARE_CLASS(wxPlotArea) 198 DECLARE_EVENT_TABLE() 199 }; 200 201 //----------------------------------------------------------------------------- 202 // wxPlotAxis - X or Y axis window (privately used in wxPlotCtrl) 203 //----------------------------------------------------------------------------- 204 205 class WXDLLIMPEXP_PLOTCTRL wxPlotAxis : public wxWindow 206 { 207 public: wxPlotAxis(wxWindow * parent,wxWindowID win_id,wxPlotAxis_Type style)208 wxPlotAxis( wxWindow *parent, wxWindowID win_id, wxPlotAxis_Type style ) 209 { 210 Init(); 211 (void)Create( parent, win_id, style ); 212 } 213 214 bool Create( wxWindow *parent, wxWindowID win_id, wxPlotAxis_Type style ); ~wxPlotAxis()215 virtual ~wxPlotAxis() {} 216 217 // Create the backing bitmap of the window contents 218 void CreateBitmap(); 219 // Get the owner (parent) wxPlotCtrl GetOwner()220 wxPlotCtrl *GetOwner() const { return m_owner; } 221 IsXAxis()222 bool IsXAxis() const { return (m_style & wxPLOT_X_AXIS) != 0; } 223 224 // implementation OnEraseBackground(wxEraseEvent &)225 void OnEraseBackground( wxEraseEvent & ) { } 226 void OnPaint( wxPaintEvent &event ); 227 void OnMouse( wxMouseEvent &event ); 228 void OnChar( wxKeyEvent &event ); 229 230 wxPoint m_mousePt; // last mouse position 231 wxPlotAxis_Type m_style; 232 wxBitmap m_bitmap; 233 wxPlotCtrl *m_owner; 234 235 private: 236 void Init(); 237 DECLARE_CLASS(wxPlotAxis) 238 DECLARE_EVENT_TABLE() 239 }; 240 241 //----------------------------------------------------------------------------- 242 // wxPlotCtrl - window to display wxPlotCurves, public interface 243 // 244 // notes: 245 // call CalcBoundingRect() whenever you modify a curve's values so that 246 // the default size of the plot is correct, see wxPlotCurve::GetBoundingRect 247 // 248 //----------------------------------------------------------------------------- 249 250 class WXDLLIMPEXP_PLOTCTRL wxPlotCtrl : public wxWindow 251 { 252 public: wxPlotCtrl()253 wxPlotCtrl() : wxWindow() { Init(); } 254 255 wxPlotCtrl( wxWindow *parent, wxWindowID win_id = wxID_ANY, 256 const wxPoint &pos = wxDefaultPosition, 257 const wxSize &size = wxDefaultSize, 258 wxPlotAxis_Type flags = wxPLOT_DEFAULT, 259 const wxString& name = wxT("wxPlotCtrl") ) 260 { 261 Init(); 262 (void)Create(parent, win_id, pos, size, flags, name); 263 } 264 265 bool Create( wxWindow *parent, wxWindowID id = wxID_ANY, 266 const wxPoint &pos = wxDefaultPosition, 267 const wxSize &size = wxDefaultSize, 268 wxPlotAxis_Type flags = wxPLOT_DEFAULT, 269 const wxString& name = wxT("wxPlotCtrl") ); 270 271 virtual ~wxPlotCtrl(); 272 273 // ------------------------------------------------------------------------ 274 // Curve Accessors 275 // 276 // note: the curves are stored in an array casted to class wxPlotCurve 277 // in order to know the type and use it as a wxPlotFunction, wxPlotData 278 // or a class derived from one of these use 279 // wxPlotData *pd = wxDynamicCast( GetCurve(i), wxPlotData ); 280 // pd will be NULL if GetCurve isn't a wxPlotData (or derived from it) 281 // ------------------------------------------------------------------------ 282 283 // Add a curve to the plot, takes ownership of the curve and deletes it 284 bool AddCurve( wxPlotCurve *curve, bool select=true, bool send_event=false ); 285 // Add a curve to the plot, increases ref count 286 bool AddCurve( const wxPlotCurve &curve, bool select=true, bool send_event=false ); 287 // Delete this curve 288 bool DeleteCurve( wxPlotCurve* curve, bool send_event=false ); 289 // Delete this curve, if curve_index = -1, delete all curves 290 bool DeleteCurve( int curve_index, bool send_event=false ); 291 292 // Total number of curves associated with the plotctrl GetCurveCount()293 int GetCurveCount() const { return m_curves.GetCount(); } CurveIndexOk(int curve_index)294 bool CurveIndexOk(int curve_index) const 295 { return (curve_index>=0) && (curve_index < int(m_curves.GetCount())); } 296 297 // Get the curve at this index 298 wxPlotCurve *GetCurve( int curve_index ) const; 299 // returns NULL if curve_index is not wxPlotData or derived from it GetDataCurve(int curve_index)300 wxPlotData *GetDataCurve( int curve_index ) const { return wxDynamicCast(GetCurve(curve_index), wxPlotData); } 301 // returns NULL if curve_index is not wxPlotFunction or derived from it GetFunctionCurve(int curve_index)302 wxPlotFunction *GetFunctionCurve( int curve_index ) const { return wxDynamicCast(GetCurve(curve_index), wxPlotFunction); } 303 // returns true if the curve is a wxPlotData curve IsDataCurve(int curve_index)304 bool IsDataCurve( int curve_index ) const { return GetDataCurve(curve_index) != NULL; } 305 // returns true if the curve is a wxPlotFunction curve IsFunctionCurve(int curve_index)306 bool IsFunctionCurve( int curve_index ) const { return GetFunctionCurve(curve_index) != NULL; } 307 // Else the function must be some sort of subclassed wxPlotCurve 308 309 // Sets the currently active curve, NULL for none active 310 void SetActiveCurve( wxPlotCurve* curve, bool send_event=false ); 311 // Gets the currently active curve, NULL if none GetActiveCurve()312 wxPlotCurve *GetActiveCurve() const { return m_activeCurve; } 313 // Gets the currently active curve as a wxPlotFunction 314 // returns NULL if its not a wxPlotFunction, even if a curve is active GetActiveFuncCurve()315 wxPlotFunction *GetActiveFuncCurve() const { return wxDynamicCast(m_activeCurve, wxPlotFunction); } 316 // Gets the currently active curve as a wxPlotData 317 // returns NULL if its not a wxPlotData, even if a curve is active GetActiveDataCurve()318 wxPlotData *GetActiveDataCurve() const { return wxDynamicCast(m_activeCurve, wxPlotData); } 319 320 // Set the curve_index curve active, use -1 to have none selected 321 void SetActiveIndex( int curve_index, bool send_event=false ); 322 // Get the index of the active curve, returns -1 if none active GetActiveIndex()323 int GetActiveIndex() const { return m_active_index; } 324 325 // Get an array of curve indexes that are of class wxPlotData, 326 // wxPlotFunction or derived from either 327 wxArrayInt GetPlotDataIndexes() const; 328 wxArrayInt GetPlotFunctionIndexes() const; 329 330 //------------------------------------------------------------------------- 331 // Markers 332 //------------------------------------------------------------------------- 333 334 // Add a marker to be displayed 335 int AddMarker( const wxPlotMarker& marker ); 336 337 void RemoveMarker(int marker); 338 void ClearMarkers(); 339 340 wxPlotMarker GetMarker(int marker) const; GetMarkerArray()341 wxArrayPlotMarker& GetMarkerArray() { return m_plotMarkers; } 342 343 //------------------------------------------------------------------------- 344 // Cursor position - a single selected point in a curve 345 //------------------------------------------------------------------------- 346 347 // Hide the cursor 348 void InvalidateCursor(bool send_event=false); 349 // Does the cursor point to a valid curve and if a data curve a valid data index 350 bool IsCursorValid(); 351 // Get the index of the curve that the cursor is associated with, -1 if none GetCursorCurveIndex()352 int GetCursorCurveIndex() const { return m_cursor_curve; } 353 // Get the index into the wxPlotData curve of the cursor, -1 if not on a data curve GetCursorDataIndex()354 int GetCursorDataIndex() const { return m_cursor_index; } 355 // Get the location of the cursor, valid for all curve types if cursor valid 356 wxPoint2DDouble GetCursorPoint(); 357 // Set the curve and the index into the wxPlotData of the cursor 358 // curve_index must point to a data curve and cursor_index valid in data 359 bool SetCursorDataIndex(int curve_index, int cursor_index, bool send_event=false); 360 // Set the curve and the x-value of the cursor, valid for all curve types 361 // if curve_index is a wxPlotData curve it finds nearest index 362 bool SetCursorXPoint(int curve_index, double x, bool send_event=false); 363 // The cursor must be valid, if center then it centers the plot on the cursor 364 // if !center then make the cursor just barely visible by shifting the view 365 void MakeCursorVisible(bool center, bool send_event=false); 366 367 //------------------------------------------------------------------------- 368 // Selected points 369 //------------------------------------------------------------------------- 370 371 // Is anything selected in a particular curve or any curve if index = -1 372 bool HasSelection(int curve_index = -1) const; 373 374 // double valued selections can be made for wxPlotCurves and wxPlotFunctions 375 // for curves that are wxPlotData, the selection is empty, see GetDataCurveSelections GetCurveSelections()376 const wxArrayRangeDoubleSelection& GetCurveSelections() const { return m_curveSelections; } 377 // Get the particluar selection for the curve at index curve_index 378 wxRangeDoubleSelection *GetCurveSelection(int curve_index) const; 379 380 // the selections of wxPlotData curves are of the indexes of the data 381 // for curves that are wxPlotCurves or wxPlotFunctions the selection is empty GetDataCurveSelections()382 const wxArrayRangeIntSelection& GetDataCurveSelections() const { return m_dataSelections; } 383 // Get the particluar selection for the curve at index curve_index 384 wxRangeIntSelection *GetDataCurveSelection(int curve_index) const; 385 386 // Get the number of individual selections of this curve 387 int GetSelectedRangeCount(int curve_index) const; 388 389 // Selects points in a curve using a rectangular selection (see select range) 390 // this works for all plotcurve classes, for wxPlotData they're converted to the indexes however 391 // if there's nothing to select or already selected it returns false 392 // if curve_index == -1 then try to select points in all curves 393 bool SelectRectangle( int curve_index, const wxRect2DDouble &rect, bool send_event = false) 394 { return DoSelectRectangle(curve_index, rect, true, send_event); } 395 bool DeselectRectangle( int curve_index, const wxRect2DDouble &rect, bool send_event = false) 396 { return DoSelectRectangle(curve_index, rect, false, send_event); } 397 398 // Select a single point wxRangeDouble(pt,pt) or a data range wxRangeDouble(pt1, pt2) 399 // this works for all plotcurve classes, for wxPlotData they're converted to the indexes however 400 // if there's nothing to select or already selected it returns false 401 // if curve_index == -1 then try to select points in all curves 402 bool SelectXRange(int curve_index, const wxRangeDouble &range, bool send_event = false) 403 { return DoSelectRectangle(curve_index, wxRect2DDouble(range.m_min, -wxPlot_MAX_DBL, range.GetRange(), wxPlot_MAX_RANGE), true, send_event); } 404 bool DeselectXRange(int curve_index, const wxRangeDouble &range, bool send_event = false) 405 { return DoSelectRectangle(curve_index, wxRect2DDouble(range.m_min, -wxPlot_MAX_DBL, range.GetRange(), wxPlot_MAX_RANGE), false, send_event); } 406 bool SelectYRange(int curve_index, const wxRangeDouble &range, bool send_event = false) 407 { return DoSelectRectangle(curve_index, wxRect2DDouble(-wxPlot_MAX_DBL, range.m_min, wxPlot_MAX_RANGE, range.GetRange()), true, send_event); } 408 bool DeselectYRange(int curve_index, const wxRangeDouble &range, bool send_event = false) 409 { return DoSelectRectangle(curve_index, wxRect2DDouble(-wxPlot_MAX_DBL, range.m_min, wxPlot_MAX_RANGE, range.GetRange()), false, send_event); } 410 411 // Select a single point wxRangeInt(pt, pt) or a range of points wxRangeInt(pt1, pt2) 412 // if there's nothing to select or already selected it returns false, 413 // this ONLY works for wxPlotData curves 414 bool SelectDataRange(int curve_index, const wxRangeInt &range, bool send_event = false) 415 { return DoSelectDataRange(curve_index, range, true, send_event); } 416 bool DeselectDataRange(int curve_index, const wxRangeInt &range, bool send_event = false) 417 { return DoSelectDataRange(curve_index, range, false, send_event); } 418 419 // Clear the ranges, if curve_index = -1 then clear them all 420 bool ClearSelectedRanges(int curve_index, bool send_event = false); 421 422 // internal use, or not... 423 virtual bool DoSelectRectangle(int curve_index, const wxRect2DDouble &rect, bool select, bool send_event = false); 424 virtual bool DoSelectDataRange(int curve_index, const wxRangeInt &range, bool select, bool send_event = false); 425 // called from DoSelect... when selecting to ensure that the current selection 426 // matches the SetSelectionType by unselecting as appropriate 427 // The input curve_index implies that a selection will be made for that curve 428 // This is not called for a deselection event. 429 virtual bool UpdateSelectionState(int curve_index, bool send_event); 430 431 // Set how the selections mechanism operates, see enum wxPlotSelection_Type 432 // You are responsible to clean up the selections if you change this, 433 // however it won't fail, but may be out of sync. SetSelectionType(wxPlotSelection_Type type)434 void SetSelectionType(wxPlotSelection_Type type) { m_selection_type = type; } GetSelectionType()435 int GetSelectionType() const { return m_selection_type; } 436 437 // ------------------------------------------------------------------------ 438 // Get/Set origin, size, and Zoom in/out of view, set scaling, size... 439 // ------------------------------------------------------------------------ 440 441 // make this curve fully visible or -1 to make all curves visible 442 // uses wxPlotCurve::GetBoundingRect() 443 // data curves have known sizes, function curves use default rect, unless set 444 bool MakeCurveVisible(int curve_index, bool send_event=false); 445 446 // Set the origin of the plot window 447 bool SetOrigin( double origin_x, double origin_y, bool send_event=false ) 448 { return SetZoom( m_zoom.m_x, m_zoom.m_y, origin_x, origin_y, send_event ); } 449 450 // Get the bounds of the plot window view in plot coords GetViewRect()451 const wxRect2DDouble& GetViewRect() const { return m_viewRect; } 452 // Set the bounds of the plot window 453 bool SetViewRect(const wxRect2DDouble &view, bool send_event=false); 454 455 // Get the zoom factor = (pixel size of window)/(GetViewRect().m_width or height) GetZoom()456 const wxPoint2DDouble& GetZoom() const { return m_zoom; } 457 458 // Zoom, if zoom_x or zoom_y <= 0 then fit that axis to window and center it 459 bool SetZoom( const wxPoint2DDouble &zoom, bool around_center=true, bool send_event=false ); 460 virtual bool SetZoom( double zoom_x, double zoom_y, 461 double origin_x, double origin_y, bool send_event=false ); 462 463 // Zoom in client coordinates, window.[xy] is top left (unlike plot axis) 464 bool SetZoom( const wxRect &window, bool send_event=false ); 465 466 // Set/Get the default size the plot should take when either no curves are 467 // loaded or only plot(curves/functions) that have no bounds are loaded 468 // The width and the height must both be > 0 469 void SetDefaultBoundingRect( const wxRect2DDouble &rect, bool send_event = false ); GetDefaultBoundingRect()470 const wxRect2DDouble& GetDefaultBoundingRect() const { return m_defaultPlotRect; } 471 472 // Get the bounding rect of all the curves, 473 // equals the default if no curves or no bounds on the curves GetCurveBoundingRect()474 const wxRect2DDouble& GetCurveBoundingRect() const { return m_curveBoundingRect; } 475 476 // Get client rect of the wxPlotArea window, 0, 0, client_width, client_height GetPlotAreaRect()477 const wxRect& GetPlotAreaRect() const { return m_areaClientRect; } 478 479 // The history of mouse drag rects are saved (mouseFunc_zoom) 480 void NextHistoryView(bool foward, bool send_event=false); GetHistoryViewCount()481 int GetHistoryViewCount() const { return m_historyViews.GetCount(); } GetHistoryViewIndex()482 int GetHistoryViewIndex() const { return m_history_views_index; } 483 484 // Fix the aspect ratio of the x and y axes, if set then when the zoom is 485 // set the smaller of the two (x or y) zooms is multiplied by the ratio 486 // to calculate the other. 487 void SetFixAspectRatio(bool fix, double ratio = 1.0); 488 void FixAspectRatio( double *zoom_x, double *zoom_y, double *origin_x, double *origin_y ); 489 490 // ------------------------------------------------------------------------ 491 // Mouse Functions for the area window 492 // ------------------------------------------------------------------------ 493 494 // The current (last) pixel position of the mouse in the plotArea GetAreaMouseCoord()495 const wxPoint& GetAreaMouseCoord() const { return m_area->m_mousePt; } 496 497 // The current plotArea position of the mouse cursor GetAreaMousePoint()498 wxPoint2DDouble GetAreaMousePoint() const 499 { return wxPoint2DDouble(GetPlotCoordFromClientX(m_area->m_mousePt.x), 500 GetPlotCoordFromClientY(m_area->m_mousePt.y)); } 501 502 // Get the rect during dragging mouse, else 0 GetAreaMouseMarkedRect()503 const wxRect& GetAreaMouseMarkedRect() const { return m_area->m_mouseRect; } 504 505 // Set what the mouse will do for different actions 506 void SetAreaMouseFunction(wxPlotMouse_Type func, bool send_event=false); GetAreaMouseFunction()507 wxPlotMouse_Type GetAreaMouseFunction() const { return m_area_mouse_func; } 508 509 // Set what sort of marker should be drawn when dragging mouse 510 void SetAreaMouseMarker(wxPlotMarker_Type type); GetAreaMouseMarker()511 wxPlotMarker_Type GetAreaMouseMarker() const { return m_area_mouse_marker; } 512 513 // Set the mouse cursor wxCURSOR_XXX + CURSOR_GRAB for the plot area 514 void SetAreaMouseCursor(int cursorid); 515 516 // ------------------------------------------------------------------------ 517 // Options 518 // ------------------------------------------------------------------------ 519 520 // Scroll the window only when the mouse button is released (for slow machines) GetScrollOnThumbRelease()521 bool GetScrollOnThumbRelease() const { return m_scroll_on_thumb_release; } 522 void SetScrollOnThumbRelease( bool scrollOnThumbRelease = true ) 523 { m_scroll_on_thumb_release = scrollOnThumbRelease; } 524 525 // Use a full width/height crosshair as a cursor GetCrossHairCursor()526 bool GetCrossHairCursor() const { return m_crosshair_cursor; } 527 void SetCrossHairCursor( bool useCrosshairCursor = false ) 528 { m_crosshair_cursor = useCrosshairCursor; 529 m_area->m_mousePt = wxPoint(-1,-1); Redraw(wxPLOT_REDRAW_PLOT); } 530 531 // Draw the data curve symbols on the plotctrl GetDrawSymbols()532 bool GetDrawSymbols() const { return m_draw_symbols; } 533 void SetDrawSymbols( bool drawsymbols = true ) 534 { m_draw_symbols = drawsymbols; Redraw(wxPLOT_REDRAW_PLOT); } 535 536 // Draw the interconnecting straight lines between data points GetDrawLines()537 bool GetDrawLines() const { return m_draw_lines; } 538 void SetDrawLines( bool drawlines = true ) 539 { m_draw_lines = drawlines; Redraw(wxPLOT_REDRAW_PLOT); } 540 541 // Draw the interconnecting splines between data points GetDrawSpline()542 bool GetDrawSpline() const { return m_draw_spline; } 543 void SetDrawSpline( bool drawspline = false ) 544 { m_draw_spline = drawspline; Redraw(wxPLOT_REDRAW_PLOT); } 545 546 // Draw the plot grid over the whole window, else just tick marks at edge GetDrawGrid()547 bool GetDrawGrid() const { return m_draw_grid; } 548 void SetDrawGrid( bool drawgrid = true ) 549 { m_draw_grid = drawgrid; Redraw(wxPLOT_REDRAW_PLOT); } 550 551 // Try to fit the window to show all curves when a new curve is added GetFitPlotOnNewCurve()552 bool GetFitPlotOnNewCurve() const { return m_fit_on_new_curve; } 553 void SetFitPlotOnNewCurve( bool fit = true ) { m_fit_on_new_curve = fit; } 554 555 // Set the focus to this window if the mouse enters it, otherwise you have to click 556 // sometimes convenient, but often this is annoying GetGreedyFocus()557 bool GetGreedyFocus() const { return m_greedy_focus; } 558 void SetGreedyFocus(bool grab_focus = false) { m_greedy_focus = grab_focus; } 559 560 // turn on or off the Correct Ticks functions. Turning this off allows a graph 561 // that scrolls to scroll smoothly in the direction expected. Turning this 562 // on (default) gives better accuracy for 'mouse hover' information display GetCorrectTicks()563 bool GetCorrectTicks() const { return m_correct_ticks; } 564 void SetCorrectTicks( bool correct = true ) { m_correct_ticks = correct; } 565 566 // get/set the width of a 1 pixel pen in mm for printing GetPrintingPenWidth(void)567 double GetPrintingPenWidth(void) { return m_pen_print_width; } SetPrintingPenWidth(double width)568 void SetPrintingPenWidth(double width) { m_pen_print_width = width; } 569 570 // ------------------------------------------------------------------------ 571 // Colours & Fonts for windows, labels, title... 572 // ------------------------------------------------------------------------ 573 574 // Get/Set the background colour of all the plot windows, default white GetBackgroundColour()575 wxColour GetBackgroundColour() const { return m_area->GetBackgroundColour(); } 576 virtual bool SetBackgroundColour( const wxColour &colour ); 577 578 // Get/Set the colour of the grid lines in the plot area, default grey GetGridColour()579 wxColour GetGridColour() const { return m_area->GetForegroundColour(); } 580 void SetGridColour( const wxColour &colour ); 581 582 // Get/Set the colour of the border around the plot area, default black GetBorderColour()583 wxColour GetBorderColour() const { return m_borderColour; } 584 void SetBorderColour( const wxColour &colour ); 585 586 // Get/Set the colour of the cursor marker, default green 587 wxColour GetCursorColour() const; 588 void SetCursorColour( const wxColour &colour ); 589 // Get/Set the cursor size, the size of the circle drawn for the cursor. 590 // set size to 0 to not have the cursor shown (default = 2) 591 int GetCursorSize() const; 592 void SetCursorSize(int size); 593 594 // Get/Set the axis numbers font and colour, default normal & black 595 wxFont GetAxisFont() const; 596 wxColour GetAxisColour() const; 597 void SetAxisFont( const wxFont &font ); 598 void SetAxisColour( const wxColour &colour ); 599 600 // Get/Set axis label fonts and colour, default swiss and black 601 wxFont GetAxisLabelFont() const; 602 wxColour GetAxisLabelColour() const; 603 void SetAxisLabelFont( const wxFont &font ); 604 void SetAxisLabelColour( const wxColour &colour ); 605 606 // Get/Set the title font and colour, default swiss and black GetPlotTitleFont()607 wxFont GetPlotTitleFont() const { return m_titleFont; } GetPlotTitleColour()608 wxColour GetPlotTitleColour() const { return m_titleColour; } 609 void SetPlotTitleFont( const wxFont &font ); 610 void SetPlotTitleColour( const wxColour &colour ); 611 612 // Get/Set the key font and colour 613 wxFont GetKeyFont() const; 614 wxColour GetKeyColour() const; 615 void SetKeyFont( const wxFont &font ); 616 void SetKeyColour( const wxColour & colour ); 617 618 // ------------------------------------------------------------------------ 619 // Title, axis labels, and key values and visibility 620 // ------------------------------------------------------------------------ 621 622 // Get/Set showing x and/or y axes SetShowXAxis(bool show)623 void SetShowXAxis(bool show) { m_show_xAxis = show; } SetShowYAxis(bool show)624 void SetShowYAxis(bool show) { m_show_yAxis = show; } GetShowXAxis()625 bool GetShowXAxis() { return m_show_xAxis; } GetShowYAxis()626 bool GetShowYAxis() { return m_show_yAxis; } 627 628 // Get/Set and show/hide the axis labels GetXAxisLabel()629 const wxString& GetXAxisLabel() const { return m_xLabel; } GetYAxisLabel()630 const wxString& GetYAxisLabel() const { return m_yLabel; } 631 void SetXAxisLabel(const wxString &label); 632 void SetYAxisLabel(const wxString &label); GetShowXAxisLabel()633 bool GetShowXAxisLabel() const { return m_show_xlabel; } GetShowYAxisLabel()634 bool GetShowYAxisLabel() const { return m_show_ylabel; } SetShowXAxisLabel(bool show)635 void SetShowXAxisLabel( bool show ) { m_show_xlabel = show; DoSize(); } SetShowYAxisLabel(bool show)636 void SetShowYAxisLabel( bool show ) { m_show_ylabel = show; DoSize(); } 637 638 // Get/Set and show/hide the title GetPlotTitle()639 const wxString& GetPlotTitle() const { return m_title; } 640 void SetPlotTitle(const wxString &title); GetShowPlotTitle()641 bool GetShowPlotTitle() const { return m_show_title; } SetShowPlotTitle(bool show)642 void SetShowPlotTitle( bool show ) { m_show_title = show; DoSize(); } 643 644 // Show a key with the function/data names, pos is %width and %height (0-100) GetKeyString()645 const wxString& GetKeyString() const { return m_keyString; } GetShowKey()646 bool GetShowKey() const { return m_show_key; } SetShowKey(bool show)647 void SetShowKey(bool show) { m_show_key = show; Redraw(wxPLOT_REDRAW_PLOT); } 648 wxPoint GetKeyPosition() const; 649 bool GetKeyInside() const; 650 void SetKeyPosition(const wxPoint &pos, bool stay_inside = true); 651 652 // used internally to update the key string from the curve names 653 virtual void CreateKeyString(); 654 655 // set the minimum value to be displayed as an exponential on the axes GetMinExpValue()656 long GetMinExpValue() const { return m_min_exponential; } SetMinExpValue(long min)657 void SetMinExpValue( long min ) { m_min_exponential = min; } 658 659 // ------------------------------------------------------------------------ 660 // Title, axis label editor control 661 // ------------------------------------------------------------------------ 662 663 enum wxPlotCtrlTextCtrl_Type 664 { 665 wxPLOT_EDIT_TITLE = 1, 666 wxPLOT_EDIT_XAXIS, 667 wxPLOT_EDIT_YAXIS, 668 }; 669 670 // Sends the wxEVT_PLOT_BEGIN_TITLE_(X/Y_LABEL)_EDIT event if send_event 671 // which can be vetoed 672 void ShowTextCtrl(wxPlotCtrlTextCtrl_Type type, bool send_event = false); 673 // Sends the wxEVT_PLOT_END_TITLE_(X/Y_LABEL)_EDIT event if send_event 674 // which can be vetoed 675 void HideTextCtrl(bool save_value = true, bool send_event = false); 676 bool IsTextCtrlShown() const; 677 678 // ------------------------------------------------------------------------ 679 // Event processing 680 // ------------------------------------------------------------------------ 681 682 // EVT_MOUSE_EVENTS from the area and axis windows are passed to these functions 683 virtual void ProcessAreaEVT_MOUSE_EVENTS( wxMouseEvent &event ); 684 virtual void ProcessAxisEVT_MOUSE_EVENTS( wxMouseEvent &event ); 685 686 // EVT_CHAR from the area and axis windows are passed to these functions ProcessAreaEVT_CHAR(wxKeyEvent & event)687 virtual void ProcessAreaEVT_CHAR( wxKeyEvent &event ) { OnChar(event); return; } 688 virtual void ProcessAreaEVT_KEY_DOWN( wxKeyEvent &event ); 689 virtual void ProcessAreaEVT_KEY_UP( wxKeyEvent &event ); ProcessAxisEVT_CHAR(wxKeyEvent & event)690 virtual void ProcessAxisEVT_CHAR( wxKeyEvent &event ) { OnChar(event); return; } 691 692 void OnChar( wxKeyEvent &event ); 693 void OnScroll( wxScrollEvent& event ); 694 void OnPaint( wxPaintEvent &event ); OnEraseBackground(wxEraseEvent & event)695 void OnEraseBackground( wxEraseEvent &event ) { event.Skip(false); } 696 void OnIdle( wxIdleEvent &event ); 697 void OnMouse( wxMouseEvent &event ); 698 void OnTextEnter( wxCommandEvent &event ); 699 700 // ------------------------------------------------------------------------ 701 // Drawing functions 702 // ------------------------------------------------------------------------ 703 704 // call BeginBatch to disable redrawing EndBatch to reenable and refresh 705 // when batchcount == 0, if !force_refresh then don't refresh when batch == 0 BeginBatch()706 void BeginBatch() { m_batch_count++; } 707 void EndBatch(bool force_refresh = true); GetBatchCount()708 int GetBatchCount() const { return m_batch_count; } 709 710 // Redraw parts of the plotctrl using combinations of wxPlot_Redraw_Type 711 void Redraw(int type); 712 // Get/Set the redraw type variable (this is for internal use, see Redraw()) GetRedrawType()713 int GetRedrawType() const { return m_redraw_type; } SetRedrawType(int type)714 void SetRedrawType(int type) { m_redraw_type = type; } 715 716 // Draw a marker in lower right signifying that this has the focus 717 virtual void DrawActiveBitmap( wxDC *dc ); 718 // Draw the wxPlotCtrl (this window) 719 virtual void DrawPlotCtrl( wxDC *dc ); 720 // Draw the area window 721 virtual void DrawAreaWindow( wxDC *dc, const wxRect& rect ); 722 // Draw a wxPlotData derived curve 723 virtual void DrawDataCurve( wxDC *dc, wxPlotData *curve, int curve_index, const wxRect &rect ); 724 // Draw a generic wxPlotCurve curve 725 virtual void DrawCurve( wxDC *dc, wxPlotCurve *curve, int curve_index, const wxRect &rect ); 726 // Draw the key 727 virtual void DrawKey( wxDC *dc ); 728 // Draw the left click drag marker, type is wxPlot_Marker_Type 729 virtual void DrawMouseMarker( wxDC *dc, int type, const wxRect &rect ); 730 // Draw a crosshair cursor at the point (mouse cursor) 731 virtual void DrawCrosshairCursor( wxDC *dc, const wxPoint &pos ); 732 // Draw the cursor marking a single point in a curve wxPlotCtrl::GetCursorPoint 733 virtual void DrawCurveCursor( wxDC *dc ); 734 // Draw the tick marks or grid lines 735 virtual void DrawTickMarks( wxDC *dc, const wxRect& rect ); 736 // Draw markers 737 virtual void DrawMarkers( wxDC *dc, const wxRect& rect ); 738 739 // redraw this wxPlotData between these two indexes (for (de)select redraw) 740 virtual void RedrawDataCurve(int index, int min_index, int max_index); 741 // redraw this wxPlotCurve between these two values (for (de)select redraw) 742 virtual void RedrawCurve(int index, double min_x, double max_x); 743 744 // Draw the X or Y axis onto the dc 745 virtual void DrawXAxis( wxDC *dc, bool refresh ); 746 virtual void DrawYAxis( wxDC *dc, bool refresh ); 747 748 // Draw the plot axes and plotctrl on this wxDC for printing, sort of WYSIWYG 749 // the plot is drawn to fit inside the boundingRect (i.e. the margins) 750 void DrawWholePlot( wxDC *dc, const wxRect &boundingRect, int dpi = 72 ); 751 752 // ------------------------------------------------------------------------ 753 // Axis tick calculations 754 // ------------------------------------------------------------------------ 755 756 // find the optimal number of ticks, step size, and format string AutoCalcTicks()757 void AutoCalcTicks() { AutoCalcXAxisTicks(); AutoCalcYAxisTicks(); } AutoCalcXAxisTicks()758 void AutoCalcXAxisTicks() { DoAutoCalcTicks(true); } AutoCalcYAxisTicks()759 void AutoCalcYAxisTicks() { DoAutoCalcTicks(false); } 760 virtual void DoAutoCalcTicks(bool x_axis); 761 // slightly correct the Zoom and origin to exactly match tick marks 762 // otherwise when the mouse is over '1' you may get 0.99999 or 1.000001 CorrectTicks()763 void CorrectTicks() { CorrectXAxisTicks(); CorrectYAxisTicks(); } 764 void CorrectXAxisTicks(); 765 void CorrectYAxisTicks(); 766 // Find the correct dc coords for the tick marks and label strings, internal use CalcTickPositions()767 void CalcTickPositions() { CalcXAxisTickPositions(); CalcYAxisTickPositions(); } 768 virtual void CalcXAxisTickPositions(); 769 virtual void CalcYAxisTickPositions(); 770 771 // ------------------------------------------------------------------------ 772 // Utilities 773 // ------------------------------------------------------------------------ 774 775 // Find a curve at pt, in rect of size +- dxdyPt, starting with active curve 776 // return sucess, setting curve_index, data_index if data curve, and if 777 // curvePt fills the exact point in the curve. 778 bool FindCurve(const wxPoint2DDouble &pt, const wxPoint2DDouble &dxdyPt, 779 int &curve_index, int &data_index, wxPoint2DDouble *curvePt = NULL) const; 780 781 // if n is !finite send wxEVT_PLOT_ERROR if msg is not empty 782 bool IsFinite(double n, const wxString &msg = wxEmptyString) const; 783 784 // call this whenever you adjust the size of a data curve 785 // this necessary to know the default zoom to show them 786 void CalcBoundingPlotRect(); 787 788 // Client (pixels) to/from plot (double) coords GetPlotCoordFromClientX(int clientx)789 inline double GetPlotCoordFromClientX( int clientx ) const 790 { return (clientx/m_zoom.m_x + m_viewRect.GetLeft()); } GetPlotCoordFromClientY(int clienty)791 inline double GetPlotCoordFromClientY( int clienty ) const 792 { return ((m_areaClientRect.height - clienty)/m_zoom.m_y + m_viewRect.GetTop());} GetPlotRectFromClientRect(const wxRect & clientRect)793 inline wxRect2DDouble GetPlotRectFromClientRect( const wxRect &clientRect ) const 794 { 795 return wxRect2DDouble( GetPlotCoordFromClientX(clientRect.x), 796 GetPlotCoordFromClientY(clientRect.GetBottom()), 797 clientRect.width/m_zoom.m_x, 798 clientRect.height/m_zoom.m_y ); 799 } 800 GetClientCoordFromPlotX(double plotx)801 inline int GetClientCoordFromPlotX( double plotx ) const 802 { double x = m_zoom.m_x*(plotx - m_viewRect.GetLeft()) + 0.5; return x < INT_MAX ? int(x) : INT_MAX; } GetClientCoordFromPlotY(double ploty)803 inline int GetClientCoordFromPlotY( double ploty ) const 804 { double y = m_areaClientRect.height - m_zoom.m_y*(ploty - m_viewRect.GetTop()) + 0.5; return y < INT_MAX ? int(y) : INT_MAX; } GetClientRectFromPlotRect(const wxRect2DDouble & plotRect)805 inline wxRect GetClientRectFromPlotRect( const wxRect2DDouble &plotRect ) const 806 { 807 double w = plotRect.m_width*m_zoom.m_x + 0.5; 808 double h = plotRect.m_height*m_zoom.m_y + 0.5; 809 return wxRect( GetClientCoordFromPlotX(plotRect.m_x), 810 GetClientCoordFromPlotY(plotRect.GetBottom()), 811 w < INT_MAX ? int(w) : INT_MAX, 812 h < INT_MAX ? int(h) : INT_MAX ); 813 } 814 815 // IDs for the children windows 816 enum 817 { 818 ID_PLOTCTRL_X_AXIS = 100, 819 ID_PLOTCTRL_Y_AXIS, 820 ID_PLOTCTRL_AREA, 821 ID_PLOTCTRL_X_SCROLLBAR, 822 ID_PLOTCTRL_Y_SCROLLBAR 823 }; 824 825 // Get the windows GetPlotArea()826 wxPlotArea* GetPlotArea() const { return m_area; } GetPlotXAxis()827 wxPlotAxis* GetPlotXAxis() const { return m_xAxis; } GetPlotYAxis()828 wxPlotAxis* GetPlotYAxis() const { return m_yAxis; } 829 830 // internal use size adjustment 831 void AdjustScrollBars(); 832 void UpdateWindowSize(); 833 void DoSize(const wxRect &boundingRect = wxRect(0, 0, 0, 0)); 834 835 // who's got the focus, if this then draw the bitmap to show it, internal 836 bool CheckFocus(); 837 838 // send event returning true if it's allowed 839 bool DoSendEvent(wxPlotEvent &event) const; 840 841 // Start the mouse timer with the win_id, stops old if for different id 842 enum mouseTimerIDs 843 { 844 ID_AREA_TIMER = 10, 845 ID_XAXIS_TIMER, 846 ID_YAXIS_TIMER 847 }; 848 void StartMouseTimer(wxWindowID win_id); 849 void StopMouseTimer(); 850 bool IsTimerRunning(); 851 void OnTimer( wxTimerEvent &event ); 852 853 // A locker for the captured window, set to NULL to release 854 void SetCaptureWindow( wxWindow *win ); GetCaptureWindow()855 wxWindow *GetCaptureWindow() const { return m_winCapture; } 856 857 protected: 858 void OnSize( wxSizeEvent& event ); 859 860 wxArrayPlotCurve m_curves; // all the curves 861 wxPlotCurve* m_activeCurve; // currently active curve 862 int m_active_index; // index in array of currently active curve 863 864 wxPlotMarker m_cursorMarker; // marker to draw for cursor 865 int m_cursor_curve; // index into plot curve array 866 int m_cursor_index; // if data curve, index in curve 867 868 wxArrayRangeIntSelection m_dataSelections; // for wxPlotData 869 wxArrayRangeDoubleSelection m_curveSelections; // for wxPlotCurve, wxPlotFunction 870 int m_selection_type; 871 872 wxArrayPlotMarker m_plotMarkers; // extra markers to draw 873 874 bool m_show_key; // show the key 875 wxString m_keyString; // the key string 876 877 // title and label 878 bool m_show_title; 879 wxString m_title; 880 bool m_show_xlabel, m_show_ylabel; 881 wxString m_xLabel, m_yLabel; 882 wxRect m_titleRect, m_xLabelRect, m_yLabelRect; 883 884 // fonts and colours 885 wxFont m_titleFont; 886 wxColour m_titleColour; 887 wxColour m_borderColour; 888 889 // option variables 890 bool m_scroll_on_thumb_release; 891 bool m_crosshair_cursor; 892 bool m_draw_symbols; 893 bool m_draw_lines; 894 bool m_draw_spline; 895 bool m_draw_grid; 896 bool m_fit_on_new_curve; 897 bool m_show_xAxis; 898 bool m_show_yAxis; 899 900 // rects of the positions of each window - remember for DrawPlotCtrl 901 wxRect m_xAxisRect, m_yAxisRect, m_areaRect, m_clientRect; 902 903 // zooms 904 wxPoint2DDouble m_zoom; 905 wxArrayRect2DDouble m_historyViews; 906 int m_history_views_index; 907 void AddHistoryView(); // maintains small list of views 908 909 bool m_fix_aspectratio; 910 double m_aspectratio; 911 912 // bounding rect, (GetLeft,GetTop) is lower left in screen coords 913 wxRect2DDouble m_viewRect; // part of the plot currently displayed 914 wxRect2DDouble m_curveBoundingRect; // total extent of the plot - CalcBoundingPlotRect 915 wxRect2DDouble m_defaultPlotRect; // default extent of the plot, fallback 916 wxRect m_areaClientRect; // rect of (wxPoint(0,0), PlotArea.GetClientSize()) 917 918 wxArrayInt m_xAxisTicks, m_yAxisTicks; // pixel coordinates of the tic marks 919 wxArrayString m_xAxisTickLabels, m_yAxisTickLabels; // the tick labels 920 wxString m_xAxisTickFormat, m_yAxisTickFormat; // format %lg for example 921 double m_xAxisTick_step, m_yAxisTick_step; // step size between ticks 922 int m_xAxisTick_count, m_yAxisTick_count; // how many ticks fit? 923 bool m_correct_ticks; // tick correction 924 925 // drawers 926 wxPlotDrawerArea *m_areaDrawer; 927 wxPlotDrawerXAxis *m_xAxisDrawer; 928 wxPlotDrawerYAxis *m_yAxisDrawer; 929 wxPlotDrawerKey *m_keyDrawer; 930 wxPlotDrawerCurve *m_curveDrawer; 931 wxPlotDrawerDataCurve *m_dataCurveDrawer; 932 wxPlotDrawerMarker *m_markerDrawer; 933 934 // windows 935 wxPlotArea *m_area; 936 wxPlotAxis *m_xAxis, *m_yAxis; 937 wxScrollBar *m_xAxisScrollbar, *m_yAxisScrollbar; 938 939 // textctrl for label/title editor, created and deleted as necessary 940 wxTextCtrl *m_textCtrl; 941 942 // focusing and bitmap to display focus 943 wxBitmap *m_activeBitmap, *m_inactiveBitmap; 944 bool m_focused; 945 bool m_greedy_focus; 946 947 // remember what needs to be repainted so unnecessary EVT_PAINTS are skipped 948 int m_redraw_type; 949 int m_batch_count; 950 951 wxSize m_axisFontSize; // pixel size of the number '5' for axis font 952 int m_y_axis_text_width; // size of "-5e+005" for max y axis width 953 int m_area_border_width; // width of area border pen (default 1) 954 int m_border; // width of border between labels and axes 955 long m_min_exponential; // minimum number displayed as an exponential 956 double m_pen_print_width; // width of a 1 pixel pen in mm when printed 957 958 wxTimer *m_timer; // don't use, see accessor functions 959 wxWindow *m_winCapture; // don't use, see accessor functions 960 961 wxPlotMouse_Type m_area_mouse_func; 962 wxPlotMarker_Type m_area_mouse_marker; 963 int m_area_mouse_cursorid; 964 965 void SetPlotWinMouseCursor(int cursorid); 966 int m_mouse_cursorid; 967 968 private: 969 void Init(); 970 DECLARE_ABSTRACT_CLASS(wxPlotCtrl) 971 DECLARE_EVENT_TABLE() 972 }; 973 974 //----------------------------------------------------------------------------- 975 // wxPlotEvent 976 //----------------------------------------------------------------------------- 977 978 class WXDLLIMPEXP_PLOTCTRL wxPlotEvent : public wxNotifyEvent 979 { 980 public: 981 wxPlotEvent(wxEventType commandType = wxEVT_NULL, int id = wxID_ANY, 982 wxPlotCtrl *window = NULL); 983 wxPlotEvent(const wxPlotEvent & event)984 wxPlotEvent(const wxPlotEvent &event) : wxNotifyEvent(event), 985 m_curve(event.m_curve), m_curveIndex(event.m_curveIndex), 986 m_curveData_index(event.m_curveData_index), m_x(event.m_x), m_y(event.m_y) {} 987 988 // position of the mouse cursor, double click, single point selection or 1st selected point GetX()989 double GetX() const { return m_x; } GetY()990 double GetY() const { return m_y; } SetPosition(double x,double y)991 void SetPosition( double x, double y ) { m_x = x; m_y = y; } 992 GetCurveDataIndex()993 int GetCurveDataIndex() const { return m_curveData_index; } SetCurveDataIndex(int data_index)994 void SetCurveDataIndex(int data_index) { m_curveData_index = data_index; } 995 996 // pointer to the curve, NULL if not appropriate for the event type GetCurve()997 wxPlotCurve *GetCurve() const { return m_curve; } SetCurve(wxPlotCurve * curve,int curve_index)998 void SetCurve(wxPlotCurve *curve, int curve_index) 999 { m_curve = curve; m_curveIndex = curve_index; } 1000 1001 // index of the curve in wxPlotCtrl::GetCurve(index) GetCurveIndex()1002 int GetCurveIndex() const { return m_curveIndex; } SetCurveIndex(int curve_index)1003 void SetCurveIndex( int curve_index ) { m_curveIndex = curve_index; } 1004 IsDataCurve()1005 bool IsDataCurve() const { return wxDynamicCast(m_curve, wxPlotData) != NULL; } 1006 GetPlotCtrl()1007 wxPlotCtrl *GetPlotCtrl() const 1008 { return wxDynamicCast(GetEventObject(),wxPlotCtrl); } 1009 GetMouseFunction()1010 int GetMouseFunction() const { return m_commandInt; } SetMouseFunction(int func)1011 void SetMouseFunction(int func) { m_commandInt = func; } 1012 1013 // implementation Clone()1014 virtual wxEvent *Clone() const { return new wxPlotEvent(*this); } 1015 1016 wxPlotCurve *m_curve; 1017 int m_curveIndex; 1018 int m_curveData_index; 1019 double m_x, m_y; 1020 1021 private: 1022 DECLARE_ABSTRACT_CLASS(wxPlotEvent); 1023 }; 1024 1025 //----------------------------------------------------------------------------- 1026 // wxPlotEvent 1027 //----------------------------------------------------------------------------- 1028 1029 class WXDLLIMPEXP_PLOTCTRL wxPlotSelectionEvent : public wxPlotEvent 1030 { 1031 public: 1032 wxPlotSelectionEvent(wxEventType commandType = wxEVT_NULL, int id = wxID_ANY, 1033 wxPlotCtrl *window = NULL); 1034 wxPlotSelectionEvent(const wxPlotSelectionEvent & event)1035 wxPlotSelectionEvent(const wxPlotSelectionEvent &event) : wxPlotEvent(event), 1036 m_dataRange(event.m_dataRange), 1037 m_curveRange(event.m_curveRange), 1038 m_dataSelection(event.m_dataSelection), 1039 m_selecting(event.m_selecting) {} 1040 1041 // for SELection events the range specifies the new (de)selection range 1042 // note : for unordered data sets an event is only sent after all selections are made 1043 1044 // the data selection range is used for wxPlotData curves these are the indexes 1045 // for wxPlotCurves and wxPlotFunctions these are the pixel locations GetDataSelectionRange()1046 wxRangeInt GetDataSelectionRange() const { return m_dataRange; } SetDataSelectionRange(const wxRangeInt & range,bool selecting)1047 void SetDataSelectionRange( const wxRangeInt &range, bool selecting ) 1048 { m_dataRange = range; m_selecting = selecting; } 1049 1050 // the curve selection range is the double valued start and stop position of the selection GetCurveSelectionRange()1051 wxRangeDouble GetCurveSelectionRange() const { return m_curveRange; } SetCurveSelectionRange(const wxRangeDouble & range,bool selecting)1052 void SetCurveSelectionRange( const wxRangeDouble &range, bool selecting ) 1053 { m_curveRange = range; m_selecting = selecting; } 1054 1055 // for a wxPlotData this is filled with the (de)selected ranges. 1056 // there will only be more than one for unordered wxPlotDatas GetDataSelections()1057 wxRangeIntSelection GetDataSelections() const { return m_dataSelection; } SetDataSelections(const wxRangeIntSelection & ranges)1058 void SetDataSelections(const wxRangeIntSelection &ranges) { m_dataSelection = ranges; } 1059 1060 // range is selected as opposed to being deselected IsSelecting()1061 bool IsSelecting() const { return m_selecting; } 1062 1063 // implementation Clone()1064 virtual wxEvent *Clone() const { return new wxPlotSelectionEvent(*this); } 1065 1066 wxRangeInt m_dataRange; 1067 wxRangeDouble m_curveRange; 1068 wxRangeIntSelection m_dataSelection; 1069 bool m_selecting; 1070 1071 private: 1072 DECLARE_ABSTRACT_CLASS(wxPlotSelectionEvent); 1073 }; 1074 1075 // ---------------------------------------------------------------------------- 1076 // wxPlotEvent event types 1077 // ---------------------------------------------------------------------------- 1078 1079 BEGIN_DECLARE_EVENT_TYPES() 1080 1081 // wxPlotEvent 1082 DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_PLOTCTRL, wxEVT_PLOT_ADD_CURVE, 0) // a curve has been added 1083 DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_PLOTCTRL, wxEVT_PLOT_DELETING_CURVE, 0) // a curve is about to be deleted, event.Skip(false) to prevent 1084 DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_PLOTCTRL, wxEVT_PLOT_DELETED_CURVE, 0) // a curve has been deleted 1085 1086 DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_PLOTCTRL, wxEVT_PLOT_CURVE_SEL_CHANGING, 0) // curve selection changing, event.Skip(false) to prevent 1087 DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_PLOTCTRL, wxEVT_PLOT_CURVE_SEL_CHANGED, 0) // curve selection has changed 1088 1089 DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_PLOTCTRL, wxEVT_PLOT_MOUSE_MOTION, 0) // mouse moved 1090 DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_PLOTCTRL, wxEVT_PLOT_CLICKED, 0) // mouse left or right clicked 1091 DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_PLOTCTRL, wxEVT_PLOT_DOUBLECLICKED, 0) // mouse left or right doubleclicked 1092 DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_PLOTCTRL, wxEVT_PLOT_POINT_CLICKED, 0) // clicked on a plot point (+-2pixels) 1093 DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_PLOTCTRL, wxEVT_PLOT_POINT_DOUBLECLICKED,0) // dclicked on a plot point (+-2pixels) 1094 1095 DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_PLOTCTRL, wxEVT_PLOT_AREA_SEL_CREATING, 0) // mouse left down and drag begin 1096 DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_PLOTCTRL, wxEVT_PLOT_AREA_SEL_CHANGING, 0) // mouse left down and dragging 1097 DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_PLOTCTRL, wxEVT_PLOT_AREA_SEL_CREATED, 0) // mouse left down and drag end 1098 1099 DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_PLOTCTRL, wxEVT_PLOT_VIEW_CHANGING, 0) // zoom or origin of plotctrl is about to change 1100 DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_PLOTCTRL, wxEVT_PLOT_VIEW_CHANGED, 0) // zoom or origin of plotctrl has changed 1101 1102 DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_PLOTCTRL, wxEVT_PLOT_CURSOR_CHANGING, 0) // cursor point/curve is about to change, event.Skip(false) to prevent 1103 // if the cursor is invalidated since 1104 // the curve is gone you cannot prevent it 1105 DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_PLOTCTRL, wxEVT_PLOT_CURSOR_CHANGED, 0) // cursor point/curve changed 1106 1107 DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_PLOTCTRL, wxEVT_PLOT_ERROR, 0) // an error has occured, see event.GetString() 1108 // usually nonfatal NaN overflow errors 1109 1110 DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_PLOTCTRL, wxEVT_PLOT_BEGIN_TITLE_EDIT, 0) // title is about to be edited, event.Skip(false) to prevent 1111 DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_PLOTCTRL, wxEVT_PLOT_END_TITLE_EDIT, 0) // title has been edited and changed, event.Skip(false) to prevent 1112 DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_PLOTCTRL, wxEVT_PLOT_BEGIN_X_LABEL_EDIT, 0) // x label is about to be edited, event.Skip(false) to prevent 1113 DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_PLOTCTRL, wxEVT_PLOT_END_X_LABEL_EDIT, 0) // x label has been edited and changed, event.Skip(false) to prevent 1114 DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_PLOTCTRL, wxEVT_PLOT_BEGIN_Y_LABEL_EDIT, 0) // y label is about to be edited, event.Skip(false) to prevent 1115 DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_PLOTCTRL, wxEVT_PLOT_END_Y_LABEL_EDIT, 0) // y label has been edited and changed, event.Skip(false) to prevent 1116 1117 DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_PLOTCTRL, wxEVT_PLOT_MOUSE_FUNC_CHANGING,0) 1118 DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_PLOTCTRL, wxEVT_PLOT_MOUSE_FUNC_CHANGED, 0) 1119 1120 // wxPlotSelectionEvent 1121 //DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_PLOTCTRL, wxEVT_PLOT_RANGE_SEL_CREATING,0) 1122 //DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_PLOTCTRL, wxEVT_PLOT_RANGE_SEL_CREATED, 0) 1123 //DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_PLOTCTRL, wxEVT_PLOT_RANGE_SEL_CHANGING,0) 1124 DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_PLOTCTRL, wxEVT_PLOT_RANGE_SEL_CHANGED, 0) 1125 1126 // unused 1127 /* 1128 DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_PLOTCTRL, wxEVT_PLOT_VALUE_SEL_CREATING, 0) 1129 DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_PLOTCTRL, wxEVT_PLOT_VALUE_SEL_CREATED, 0) 1130 DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_PLOTCTRL, wxEVT_PLOT_VALUE_SEL_CHANGING, 0) 1131 DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_PLOTCTRL, wxEVT_PLOT_VALUE_SEL_CHANGED, 0) 1132 DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_PLOTCTRL, wxEVT_PLOT_AREA_SEL_CHANGED, 0) 1133 */ 1134 END_DECLARE_EVENT_TYPES() 1135 // ---------------------------------------------------------------------------- 1136 // wxPlotEvent macros 1137 // ---------------------------------------------------------------------------- 1138 1139 typedef void (wxEvtHandler::*wxPlotEventFunction)(wxPlotEvent&); 1140 #define wxPlotEventHandler(func) \ 1141 (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(wxPlotEventFunction, &func) 1142 #define wx__DECLARE_PLOTEVT(evt, id, fn) wx__DECLARE_EVT1( evt, id, wxPlotEventHandler(fn)) 1143 1144 #define EVT_PLOT_ADD_CURVE(id, fn) wx__DECLARE_PLOTEVT(wxEVT_PLOT_ADD_CURVE, id, fn) 1145 #define EVT_PLOT_DELETING_CURVE(id, fn) wx__DECLARE_PLOTEVT(wxEVT_PLOT_DELETING_CURVE, id, fn) 1146 #define EVT_PLOT_DELETED_CURVE(id, fn) wx__DECLARE_PLOTEVT(wxEVT_PLOT_DELETED_CURVE, id, fn) 1147 1148 #define EVT_PLOT_CURVE_SEL_CHANGING(id, fn) wx__DECLARE_PLOTEVT(wxEVT_PLOT_CURVE_SEL_CHANGING, id, fn) 1149 #define EVT_PLOT_CURVE_SEL_CHANGED(id, fn) wx__DECLARE_PLOTEVT(wxEVT_PLOT_CURVE_SEL_CHANGED, id, fn) 1150 1151 #define EVT_PLOT_MOUSE_MOTION(id, fn) wx__DECLARE_PLOTEVT(wxEVT_PLOT_MOUSE_MOTION, id, fn) 1152 #define EVT_PLOT_CLICKED(id, fn) wx__DECLARE_PLOTEVT(wxEVT_PLOT_CLICKED, id, fn) 1153 #define EVT_PLOT_DOUBLECLICKED(id, fn) wx__DECLARE_PLOTEVT(wxEVT_PLOT_DOUBLECLICKED, id, fn) 1154 #define EVT_PLOT_POINT_CLICKED(id, fn) wx__DECLARE_PLOTEVT(wxEVT_PLOT_POINT_CLICKED, id, fn) 1155 #define EVT_PLOT_POINT_DOUBLECLICKED(id, fn) wx__DECLARE_PLOTEVT(wxEVT_PLOT_POINT_DOUBLECLICKED, id, fn) 1156 1157 #define EVT_PLOT_AREA_SEL_CREATING(id, fn) wx__DECLARE_PLOTEVT(wxEVT_PLOT_AREA_SEL_CREATING, id, fn) 1158 #define EVT_PLOT_AREA_SEL_CHANGING(id, fn) wx__DECLARE_PLOTEVT(wxEVT_PLOT_AREA_SEL_CHANGING, id, fn) 1159 #define EVT_PLOT_AREA_SEL_CREATED(id, fn) wx__DECLARE_PLOTEVT(wxEVT_PLOT_VIEW_CREATED, id, fn) 1160 1161 #define EVT_PLOT_VIEW_CHANGING(id, fn) wx__DECLARE_PLOTEVT(wxEVT_PLOT_VIEW_CHANGING, id, fn) 1162 #define EVT_PLOT_VIEW_CHANGED(id, fn) wx__DECLARE_PLOTEVT(wxEVT_PLOT_VIEW_CHANGED, id, fn) 1163 1164 #define EVT_PLOT_CURSOR_CHANGING(id, fn) wx__DECLARE_PLOTEVT(wxEVT_PLOT_CURSOR_CHANGING, id, fn) 1165 #define EVT_PLOT_CURSOR_CHANGED(id, fn) wx__DECLARE_PLOTEVT(wxEVT_PLOT_CURSOR_CHANGED, id, fn) 1166 1167 #define EVT_PLOT_ERROR(id, fn) wx__DECLARE_PLOTEVT(wxEVT_PLOT_ERROR, id, fn) 1168 1169 #define EVT_PLOT_BEGIN_TITLE_EDIT(id, fn) wx__DECLARE_PLOTEVT(wxEVT_PLOT_BEGIN_TITLE_EDIT, id, fn) 1170 #define EVT_PLOT_END_TITLE_EDIT(id, fn) wx__DECLARE_PLOTEVT(wxEVT_PLOT_END_TITLE_EDIT, id, fn) 1171 #define EVT_PLOT_BEGIN_X_LABEL_EDIT(id, fn) wx__DECLARE_PLOTEVT(wxEVT_PLOT_BEGIN_X_LABEL_EDIT, id, fn) 1172 #define EVT_PLOT_END_X_LABEL_EDIT(id, fn) wx__DECLARE_PLOTEVT(wxEVT_PLOT_END_X_LABEL_EDIT, id, fn) 1173 #define EVT_PLOT_BEGIN_Y_LABEL_EDIT(id, fn) wx__DECLARE_PLOTEVT(wxEVT_PLOT_BEGIN_Y_LABEL_EDIT, id, fn) 1174 #define EVT_PLOT_END_Y_LABEL_EDIT(id, fn) wx__DECLARE_PLOTEVT(wxEVT_PLOT_END_Y_LABEL_EDIT, id, fn) 1175 1176 #define EVT_PLOT_MOUSE_FUNC_CHANGING(id, fn) wx__DECLARE_PLOTEVT(wxEVT_PLOT_MOUSE_FUNC_CHANGING, id, fn) 1177 #define EVT_PLOT_MOUSE_FUNC_CHANGED(id, fn) wx__DECLARE_PLOTEVT(wxEVT_PLOT_MOUSE_FUNC_CHANGED, id, fn) 1178 1179 typedef void (wxEvtHandler::*wxPlotSelectionEventFunction)(wxPlotSelectionEvent&); 1180 #define wxPlotSelectionEventHandler(func) \ 1181 (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(wxPlotSelectionEventFunction, &func) 1182 #define wx__DECLARE_PLOTSELECTIONEVT(evt, id, fn) wx__DECLARE_EVT1( evt, id, wxPlotSelectionEventHandler(fn)) 1183 1184 //#define EVT_PLOT_RANGE_SEL_CREATING(id, fn) DECLARE_EVENT_TABLE_ENTRY(wxEVT_PLOT_RANGE_SEL_CREATING, id, wxID_ANY, (wxObjectEventFunction) (wxEventFunction) wxStaticCastEvent( wxPlotSelectionEventFunction, & fn ), (wxObject *) NULL ), 1185 //#define EVT_PLOT_RANGE_SEL_CREATED(id, fn) DECLARE_EVENT_TABLE_ENTRY(wxEVT_PLOT_RANGE_SEL_CREATED, id, wxID_ANY, (wxObjectEventFunction) (wxEventFunction) wxStaticCastEvent( wxPlotSelectionEventFunction, & fn ), (wxObject *) NULL ), 1186 //#define EVT_PLOT_RANGE_SEL_CHANGING(id, fn) DECLARE_EVENT_TABLE_ENTRY(wxEVT_PLOT_RANGE_SEL_CHANGING, id, wxID_ANY, (wxObjectEventFunction) (wxEventFunction) wxStaticCastEvent( wxPlotSelectionEventFunction, & fn ), (wxObject *) NULL ), 1187 #define EVT_PLOT_RANGE_SEL_CHANGED(id, fn) wx__DECLARE_PLOTSELECTIONEVT(wxEVT_PLOT_RANGE_SEL_CHANGED, id, fn) 1188 1189 /* 1190 #define EVT_PLOT_VALUE_SEL_CREATING(id, fn) DECLARE_EVENT_TABLE_ENTRY(wxEVT_PLOT_VALUE_SEL_CREATING, id, wxID_ANY, (wxObjectEventFunction) (wxEventFunction) wxStaticCastEvent( wxPlotEventFunction, & fn ), (wxObject *) NULL ), 1191 #define EVT_PLOT_VALUE_SEL_CREATED(id, fn) DECLARE_EVENT_TABLE_ENTRY(wxEVT_PLOT_VALUE_SEL_CREATED, id, wxID_ANY, (wxObjectEventFunction) (wxEventFunction) wxStaticCastEvent( wxPlotEventFunction, & fn ), (wxObject *) NULL ), 1192 #define EVT_PLOT_VALUE_SEL_CHANGING(id, fn) DECLARE_EVENT_TABLE_ENTRY(wxEVT_PLOT_VALUE_SEL_CHANGING, id, wxID_ANY, (wxObjectEventFunction) (wxEventFunction) wxStaticCastEvent( wxPlotEventFunction, & fn ), (wxObject *) NULL ), 1193 #define EVT_PLOT_VALUE_SEL_CHANGED(id, fn) DECLARE_EVENT_TABLE_ENTRY(wxEVT_PLOT_VALUE_SEL_CHANGED, id, wxID_ANY, (wxObjectEventFunction) (wxEventFunction) wxStaticCastEvent( wxPlotEventFunction, & fn ), (wxObject *) NULL ), 1194 #define EVT_PLOT_AREA_SEL_CHANGED(id, fn) DECLARE_EVENT_TABLE_ENTRY(wxEVT_PLOT_AREA_SEL_CHANGED, id, wxID_ANY, (wxObjectEventFunction) (wxEventFunction) wxStaticCastEvent( wxPlotEventFunction, & fn ), (wxObject *) NULL ), 1195 */ 1196 1197 #endif // _WX_PLOTCTRL_H_ 1198