From 8556b795c369382a1f5f2ed9405138a450ecc4a6 Mon Sep 17 00:00:00 2001
From: Robert Roebling <robert@roebling.de>
Date: Tue, 16 Jan 2001 11:33:29 +0000
Subject: [PATCH]   Readded wxPlotWindow as external lib.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@9107 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
---
 contrib/configure                    |    4 +
 contrib/configure.in                 |    2 +
 contrib/include/wx/plot/plot.h       |  403 +++++++++
 contrib/include/wx/plot/plot_dwn.bmp |  Bin 0 -> 334 bytes
 contrib/include/wx/plot/plot_dwn.xpm |   32 +
 contrib/include/wx/plot/plot_enl.bmp |  Bin 0 -> 358 bytes
 contrib/include/wx/plot/plot_enl.xpm |   34 +
 contrib/include/wx/plot/plot_shr.bmp |  Bin 0 -> 358 bytes
 contrib/include/wx/plot/plot_shr.xpm |   34 +
 contrib/include/wx/plot/plot_up.bmp  |  Bin 0 -> 334 bytes
 contrib/include/wx/plot/plot_up.xpm  |   32 +
 contrib/include/wx/plot/plot_zin.bmp |  Bin 0 -> 334 bytes
 contrib/include/wx/plot/plot_zin.xpm |   32 +
 contrib/include/wx/plot/plot_zot.bmp |  Bin 0 -> 334 bytes
 contrib/include/wx/plot/plot_zot.xpm |   32 +
 contrib/include/wx/plot/wxplot.rc    |    8 +
 contrib/samples/Makefile.in          |    2 +-
 contrib/samples/plot/Makefile.in     |   16 +
 contrib/samples/plot/plot.cpp        |  185 ++++
 contrib/samples/plot/plot.def        |    7 +
 contrib/samples/plot/plot.rc         |    2 +
 contrib/src/plot/Makefile.in         |   23 +
 contrib/src/plot/plot.cpp            | 1204 ++++++++++++++++++++++++++
 23 files changed, 2051 insertions(+), 1 deletion(-)
 create mode 100644 contrib/include/wx/plot/plot.h
 create mode 100644 contrib/include/wx/plot/plot_dwn.bmp
 create mode 100644 contrib/include/wx/plot/plot_dwn.xpm
 create mode 100644 contrib/include/wx/plot/plot_enl.bmp
 create mode 100644 contrib/include/wx/plot/plot_enl.xpm
 create mode 100644 contrib/include/wx/plot/plot_shr.bmp
 create mode 100644 contrib/include/wx/plot/plot_shr.xpm
 create mode 100644 contrib/include/wx/plot/plot_up.bmp
 create mode 100644 contrib/include/wx/plot/plot_up.xpm
 create mode 100644 contrib/include/wx/plot/plot_zin.bmp
 create mode 100644 contrib/include/wx/plot/plot_zin.xpm
 create mode 100644 contrib/include/wx/plot/plot_zot.bmp
 create mode 100644 contrib/include/wx/plot/plot_zot.xpm
 create mode 100644 contrib/include/wx/plot/wxplot.rc
 create mode 100644 contrib/samples/plot/Makefile.in
 create mode 100644 contrib/samples/plot/plot.cpp
 create mode 100644 contrib/samples/plot/plot.def
 create mode 100644 contrib/samples/plot/plot.rc
 create mode 100644 contrib/src/plot/Makefile.in
 create mode 100644 contrib/src/plot/plot.cpp

diff --git a/contrib/configure b/contrib/configure
index d3786f6abc..e20808c0c3 100755
--- a/contrib/configure
+++ b/contrib/configure
@@ -820,6 +820,7 @@ trap 'rm -fr `echo "
             src/xml/Makefile
             src/canvas/Makefile
             src/gizmos/Makefile
+            src/plot/Makefile
             samples/Makefile
             samples/mmedia/Makefile
             samples/ogl/Makefile
@@ -833,6 +834,7 @@ trap 'rm -fr `echo "
             samples/gizmos/multicell/Makefile
             samples/gizmos/splittree/Makefile
             samples/xml/Makefile
+            samples/plot/Makefile
             utils/Makefile
             utils/wxrc/Makefile
             utils/wxrcedit/Makefile
@@ -923,6 +925,7 @@ CONFIG_FILES=\${CONFIG_FILES-"Makefile
             src/xml/Makefile
             src/canvas/Makefile
             src/gizmos/Makefile
+            src/plot/Makefile
             samples/Makefile
             samples/mmedia/Makefile
             samples/ogl/Makefile
@@ -936,6 +939,7 @@ CONFIG_FILES=\${CONFIG_FILES-"Makefile
             samples/gizmos/multicell/Makefile
             samples/gizmos/splittree/Makefile
             samples/xml/Makefile
+            samples/plot/Makefile
             utils/Makefile
             utils/wxrc/Makefile
             utils/wxrcedit/Makefile
diff --git a/contrib/configure.in b/contrib/configure.in
index d8bee0cfe2..eaf92dbd50 100644
--- a/contrib/configure.in
+++ b/contrib/configure.in
@@ -45,6 +45,7 @@ AC_OUTPUT([
             src/xml/Makefile
             src/canvas/Makefile
             src/gizmos/Makefile
+            src/plot/Makefile
             samples/Makefile
             samples/mmedia/Makefile
             samples/ogl/Makefile
@@ -58,6 +59,7 @@ AC_OUTPUT([
             samples/gizmos/multicell/Makefile
             samples/gizmos/splittree/Makefile
             samples/xml/Makefile
+            samples/plot/Makefile
             utils/Makefile
             utils/wxrc/Makefile
             utils/wxrcedit/Makefile
diff --git a/contrib/include/wx/plot/plot.h b/contrib/include/wx/plot/plot.h
new file mode 100644
index 0000000000..68b948d17b
--- /dev/null
+++ b/contrib/include/wx/plot/plot.h
@@ -0,0 +1,403 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        plot.h
+// Purpose:     wxPlotWindow
+// Author:      Robert Roebling
+// Modified by:
+// Created:     12/1/2000
+// Copyright:   (c) Robert Roebling
+// RCS-ID:      $Id$
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef _WX_PLOT_H_
+#define _WX_PLOT_H_
+
+#ifdef __GNUG__
+#pragma interface "plot.h"
+#endif
+
+#include "wx/defs.h"
+
+#include "wx/scrolwin.h"
+#include "wx/event.h"
+#include "wx/dynarray.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxPlotEvent;
+class WXDLLEXPORT wxPlotCurve;
+class WXDLLEXPORT wxPlotValues;
+class WXDLLEXPORT wxPlotArea;
+class WXDLLEXPORT wxPlotXAxisArea;
+class WXDLLEXPORT wxPlotYAxisArea;
+class WXDLLEXPORT wxPlotWindow;
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+extern int wxEVT_PLOT_SEL_CHANGING;
+extern int wxEVT_PLOT_SEL_CHANGED;
+extern int wxEVT_PLOT_CLICKED;
+extern int wxEVT_PLOT_DOUBLECLICKED;
+extern int wxEVT_PLOT_ZOOM_IN;
+extern int wxEVT_PLOT_ZOOM_OUT;
+extern int wxEVT_PLOT_VALUE_SEL_CREATING;
+extern int wxEVT_PLOT_VALUE_SEL_CREATED;
+extern int wxEVT_PLOT_VALUE_SEL_CHANGING;
+extern int wxEVT_PLOT_VALUE_SEL_CHANGED;
+extern int wxEVT_PLOT_AREA_SEL_CREATING;
+extern int wxEVT_PLOT_AREA_SEL_CREATED;
+extern int wxEVT_PLOT_AREA_SEL_CHANGING;
+extern int wxEVT_PLOT_AREA_SEL_CHANGED;
+extern int wxEVT_PLOT_BEGIN_X_LABEL_EDIT;
+extern int wxEVT_PLOT_END_X_LABEL_EDIT;
+extern int wxEVT_PLOT_BEGIN_Y_LABEL_EDIT;
+extern int wxEVT_PLOT_END_Y_LABEL_EDIT;
+extern int wxEVT_PLOT_BEGIN_TITLE_EDIT;
+extern int wxEVT_PLOT_END_TITLE_EDIT;
+extern int wxEVT_PLOT_AREA_CREATE;
+
+//-----------------------------------------------------------------------------
+// consts
+//-----------------------------------------------------------------------------
+
+#define wxPLOT_X_AXIS          0x0004
+#define wxPLOT_Y_AXIS          0x0008
+#define wxPLOT_BUTTON_MOVE     0x0010
+#define wxPLOT_BUTTON_ZOOM     0x0020
+#define wxPLOT_BUTTON_ENLARGE  0x0040
+
+#define wxPLOT_BUTTON_ALL  (wxPLOT_BUTTON_MOVE|wxPLOT_BUTTON_ZOOM|wxPLOT_BUTTON_ENLARGE)
+#define wxPLOT_DEFAULT     (wxPLOT_X_AXIS|wxPLOT_Y_AXIS | wxPLOT_BUTTON_ALL)
+
+//-----------------------------------------------------------------------------
+// wxPlotEvent
+//-----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxPlotEvent: public wxNotifyEvent
+{
+public:
+    wxPlotEvent( wxEventType commandType = wxEVT_NULL, int id = 0 );
+
+    wxPlotCurve *GetCurve()
+        { return m_curve; }
+    void SetCurve( wxPlotCurve *curve )
+        { m_curve = curve; }
+
+    double GetZoom()
+        { return m_zoom; }
+    void SetZoom( double zoom )
+        { m_zoom = zoom; }
+
+    wxInt32 GetPosition()
+        { return m_position; }
+    void SetPosition( wxInt32 pos )
+        { m_position = pos; }
+
+private:
+    wxPlotCurve   *m_curve;
+    double         m_zoom;
+    wxInt32        m_position;
+};
+
+//-----------------------------------------------------------------------------
+// wxPlotCurve
+//-----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxPlotCurve: public wxObject
+{
+public:
+    wxPlotCurve( int offsetY, double startY, double endY );
+
+    virtual wxInt32 GetStartX() = 0;
+    virtual wxInt32 GetEndX() = 0;
+
+    virtual double GetY( wxInt32 x ) = 0;
+
+    void SetStartY( double startY )
+        { m_startY = startY; }
+    double GetStartY()
+        { return m_startY; }
+    void SetEndY( double endY )
+        { m_endY = endY; }
+    double GetEndY()
+        { return m_endY; }
+    void SetOffsetY( int offsetY )
+       { m_offsetY = offsetY; }
+    int GetOffsetY()
+       { return m_offsetY; }
+       
+    void SetPenNormal( const wxPen &pen )
+       { m_penNormal = pen; }
+    void SetPenSelected( const wxPen &pen )
+       { m_penSelected = pen; }
+
+private:
+    int     m_offsetY;
+    double  m_startY;
+    double  m_endY;
+    wxPen   m_penNormal;
+    wxPen   m_penSelected;
+
+    DECLARE_ABSTRACT_CLASS(wxPlotCurve)
+};
+
+//-----------------------------------------------------------------------------
+// wxPlotOnOffCurve
+//-----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxPlotOnOff
+{
+public:
+    wxPlotOnOff() { }
+
+    wxInt32   m_on;
+    wxInt32   m_off;
+    void     *m_clientData;
+};
+
+WX_DECLARE_EXPORTED_OBJARRAY(wxPlotOnOff, wxArrayPlotOnOff);
+
+class WXDLLEXPORT wxPlotOnOffCurve: public wxObject
+{
+public:
+    wxPlotOnOffCurve( int offsetY );
+
+    wxInt32 GetStartX()
+        { return m_minX; }
+    wxInt32 GetEndX()
+        { return m_maxX; }
+
+    void SetOffsetY( int offsetY )
+       { m_offsetY = offsetY; }
+    int GetOffsetY()
+       { return m_offsetY; }
+       
+    void Add( wxInt32 on, wxInt32 off, void *clientData = NULL );
+    size_t GetCount();
+    
+    wxInt32 GetOn( size_t index );
+    wxInt32 GetOff( size_t index );
+    void* GetClientData( size_t index );
+    wxPlotOnOff *GetAt( size_t index );
+
+    virtual void DrawOnLine( wxDC &dc, wxCoord y, wxCoord start, wxCoord end, void *clientData );
+    virtual void DrawOffLine( wxDC &dc, wxCoord y, wxCoord start, wxCoord end );
+
+private:
+    int               m_offsetY;
+    wxInt32           m_minX;
+    wxInt32           m_maxX;
+    
+    wxArrayPlotOnOff   m_marks;
+
+    DECLARE_CLASS(wxPlotOnOffCurve)
+};
+
+//-----------------------------------------------------------------------------
+// wxPlotArea
+//-----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxPlotArea: public wxWindow
+{
+public:
+    wxPlotArea() {}
+    wxPlotArea( wxPlotWindow *parent );
+
+    void OnPaint( wxPaintEvent &event );
+    void OnMouse( wxMouseEvent &event );
+
+    void DrawCurve( wxDC *dc, wxPlotCurve *curve, int from = -1, int to = -1 );
+    void DrawOnOffCurve( wxDC *dc, wxPlotOnOffCurve *curve, int from = -1, int to = -1 );
+    void DeleteCurve( wxPlotCurve *curve, int from = -1, int to = -1 );
+
+    virtual void ScrollWindow( int dx, int dy, const wxRect *rect );
+
+private:
+    wxPlotWindow     *m_owner;
+    bool              m_zooming;
+
+    DECLARE_CLASS(wxPlotArea)
+    DECLARE_EVENT_TABLE()
+};
+
+//-----------------------------------------------------------------------------
+// wxPlotXAxisArea
+//-----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxPlotXAxisArea: public wxWindow
+{
+public:
+    wxPlotXAxisArea() {}
+    wxPlotXAxisArea( wxPlotWindow *parent );
+
+    void OnPaint( wxPaintEvent &event );
+    void OnMouse( wxMouseEvent &event );
+
+private:
+    wxPlotWindow   *m_owner;
+
+    DECLARE_CLASS(wxPlotXAxisArea)
+    DECLARE_EVENT_TABLE()
+};
+
+//-----------------------------------------------------------------------------
+// wxPlotYAxisArea
+//-----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxPlotYAxisArea: public wxWindow
+{
+public:
+    wxPlotYAxisArea() {}
+    wxPlotYAxisArea( wxPlotWindow *parent );
+
+    void OnPaint( wxPaintEvent &event );
+    void OnMouse( wxMouseEvent &event );
+
+private:
+    wxPlotWindow   *m_owner;
+
+    DECLARE_CLASS(wxPlotYAxisArea)
+    DECLARE_EVENT_TABLE()
+};
+
+//-----------------------------------------------------------------------------
+// wxPlotWindow
+//-----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxPlotWindow: public wxScrolledWindow
+{
+public:
+    wxPlotWindow() {}
+    wxPlotWindow( wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, int flags = wxPLOT_DEFAULT );
+    ~wxPlotWindow();
+
+    // curve accessors
+    // ---------------
+
+    void Add( wxPlotCurve *curve );
+    void Delete( wxPlotCurve* curve );
+
+    size_t GetCount();
+    wxPlotCurve *GetAt( size_t n );
+
+    void SetCurrent( wxPlotCurve* current );
+    wxPlotCurve *GetCurrent();
+
+    // mark list accessors
+    // -------------------
+
+    void Add( wxPlotOnOffCurve *curve );
+    void Delete( wxPlotOnOffCurve* curve );
+    
+    size_t GetOnOffCurveCount();
+    wxPlotOnOffCurve *GetOnOffCurveAt( size_t n );
+
+    // vertical representation
+    // -----------------------
+
+    void Move( wxPlotCurve* curve, int pixels_up );
+    void Enlarge( wxPlotCurve *curve, double factor );
+
+    // horizontal representation
+    // -------------------------
+
+    void SetUnitsPerValue( double upv );
+    double GetUnitsPerValue()
+        { return m_xUnitsPerValue; }
+
+    void SetZoom( double zoom );
+    double GetZoom()
+        { return m_xZoom; }
+
+    // options
+    // -------
+
+    void SetScrollOnThumbRelease( bool scrollOnThumbRelease = TRUE )
+        { m_scrollOnThumbRelease = scrollOnThumbRelease; }
+    bool GetScrollOnThumbRelease()
+        { return m_scrollOnThumbRelease; }
+
+    void SetEnlargeAroundWindowCentre( bool enlargeAroundWindowCentre = TRUE )
+        { m_enlargeAroundWindowCentre = enlargeAroundWindowCentre; }
+    bool GetEnlargeAroundWindowCentre()
+        { return m_enlargeAroundWindowCentre; }
+
+    // events (may be overridden)
+    // --------------------------
+
+    void OnMoveUp( wxCommandEvent& event );
+    void OnMoveDown( wxCommandEvent& event );
+
+    void OnEnlarge( wxCommandEvent& event );
+    void OnShrink( wxCommandEvent& event );
+    void OnZoomIn( wxCommandEvent& event );
+    void OnZoomOut( wxCommandEvent& event );
+
+    void OnScroll2( wxScrollWinEvent& event );
+
+    // utilities
+    // ---------
+
+    void RedrawEverything();
+    void RedrawXAxis();
+    void RedrawYAxis();
+
+    void ResetScrollbar();
+
+private:
+    friend class wxPlotArea;
+    friend class wxPlotXAxisArea;
+    friend class wxPlotYAxisArea;
+
+    double             m_xUnitsPerValue;
+    double             m_xZoom;
+
+    wxList             m_curves;
+    wxList             m_onOffCurves;
+    
+    wxPlotArea        *m_area;
+    wxPlotXAxisArea   *m_xaxis;
+    wxPlotYAxisArea   *m_yaxis;
+    wxPlotCurve       *m_current;
+
+    bool               m_scrollOnThumbRelease;
+    bool               m_enlargeAroundWindowCentre;
+
+    DECLARE_CLASS(wxPlotWindow)
+    DECLARE_EVENT_TABLE()
+};
+
+// ----------------------------------------------------------------------------
+// plot event macros
+// ----------------------------------------------------------------------------
+
+typedef void (wxEvtHandler::*wxPlotEventFunction)(wxPlotEvent&);
+
+#define EVT_PLOT(id, fn) { wxEVT_PLOT_DOUBLECLICKED, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) (wxNotifyEventFunction) (wxPlotEventFunction) & fn, (wxObject *) NULL },
+#define EVT_PLOT_SEL_CHANGING(id, fn) { wxEVT_PLOT_SEL_CHANGING, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) (wxNotifyEventFunction) (wxPlotEventFunction) & fn, (wxObject *) NULL },
+#define EVT_PLOT_SEL_CHANGED(id, fn) { wxEVT_PLOT_SEL_CHANGED, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) (wxNotifyEventFunction) (wxPlotEventFunction) & fn, (wxObject *) NULL },
+#define EVT_PLOT_CLICKED(id, fn) { wxEVT_PLOT_CLICKED, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) (wxNotifyEventFunction) (wxPlotEventFunction) & fn, (wxObject *) NULL },
+#define EVT_PLOT_DOUBLECLICKED(id, fn) { wxEVT_PLOT_DOUBLECLICKED, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) (wxNotifyEventFunction) (wxPlotEventFunction) & fn, (wxObject *) NULL },
+#define EVT_PLOT_ZOOM_IN(id, fn) { wxEVT_PLOT_ZOOM_IN, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) (wxNotifyEventFunction) (wxPlotEventFunction) & fn, (wxObject *) NULL },
+#define EVT_PLOT_ZOOM_OUT(id, fn) { wxEVT_PLOT_ZOOM_OUT, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) (wxNotifyEventFunction) (wxPlotEventFunction) & fn, (wxObject *) NULL },
+#define EVT_PLOT_VALUE_SEL_CREATING(id, fn) { wxEVT_PLOT_VALUE_SEL_CREATING, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) (wxNotifyEventFunction) (wxPlotEventFunction) & fn, (wxObject *) NULL },
+#define EVT_PLOT_VALUE_SEL_CREATED(id, fn) { wxEVT_PLOT_VALUE_SEL_CREATED, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) (wxNotifyEventFunction) (wxPlotEventFunction) & fn, (wxObject *) NULL },
+#define EVT_PLOT_VALUE_SEL_CHANGING(id, fn) { wxEVT_PLOT_VALUE_SEL_CHANGING, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) (wxNotifyEventFunction) (wxPlotEventFunction) & fn, (wxObject *) NULL },
+#define EVT_PLOT_VALUE_SEL_CHANGED(id, fn) { wxEVT_PLOT_VALUE_SEL_CHANGED, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) (wxNotifyEventFunction) (wxPlotEventFunction) & fn, (wxObject *) NULL },
+#define EVT_PLOT_AREA_SEL_CREATING(id, fn) { wxEVT_PLOT_AREA_SEL_CREATING, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) (wxNotifyEventFunction) (wxPlotEventFunction) & fn, (wxObject *) NULL },
+#define EVT_PLOT_AREA_SEL_CREATED(id, fn) { wxEVT_PLOT_AREA_SEL_CREATED, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) (wxNotifyEventFunction) (wxPlotEventFunction) & fn, (wxObject *) NULL },
+#define EVT_PLOT_AREA_SEL_CHANGING(id, fn) { wxEVT_PLOT_AREA_SEL_CHANGING, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) (wxNotifyEventFunction) (wxPlotEventFunction) & fn, (wxObject *) NULL },
+#define EVT_PLOT_AREA_SEL_CHANGED(id, fn) { wxEVT_PLOT_AREA_SEL_CHANGED, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) (wxNotifyEventFunction) (wxPlotEventFunction) & fn, (wxObject *) NULL },
+#define EVT_PLOT_BEGIN_X_LABEL_EDIT(id, fn) { wxEVT_PLOT_BEGIN_X_LABEL_EDIT, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) (wxNotifyEventFunction) (wxPlotEventFunction) & fn, (wxObject *) NULL },
+#define EVT_PLOT_END_X_LABEL_EDIT(id, fn) { wxEVT_PLOT_END_X_LABEL_EDIT, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) (wxNotifyEventFunction) (wxPlotEventFunction) & fn, (wxObject *) NULL },
+#define EVT_PLOT_BEGIN_Y_LABEL_EDIT(id, fn) { wxEVT_PLOT_BEGIN_Y_LABEL_EDIT, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) (wxNotifyEventFunction) (wxPlotEventFunction) & fn, (wxObject *) NULL },
+#define EVT_PLOT_END_Y_LABEL_EDIT(id, fn) { wxEVT_PLOT_END_Y_LABEL_EDIT, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) (wxNotifyEventFunction) (wxPlotEventFunction) & fn, (wxObject *) NULL },
+#define EVT_PLOT_BEGIN_TITLE_EDIT(id, fn) { wxEVT_PLOT_BEGIN_TITLE_EDIT, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) (wxNotifyEventFunction) (wxPlotEventFunction) & fn, (wxObject *) NULL },
+#define EVT_PLOT_END_TITLE_EDIT(id, fn) { wxEVT_PLOT_END_TITLE_EDIT, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) (wxNotifyEventFunction) (wxPlotEventFunction) & fn, (wxObject *) NULL },
+
+#endif
+   // _WX_PLOT_H_
diff --git a/contrib/include/wx/plot/plot_dwn.bmp b/contrib/include/wx/plot/plot_dwn.bmp
new file mode 100644
index 0000000000000000000000000000000000000000..3d2c04fe5d779087628037f1f734b13b0aaf8ca2
GIT binary patch
literal 334
zcmY+8K?=e!5Ji7M5V{ia5S~K{lZ~Dwi(tf67ecS$+DkOY@HX-PB(3^8^Yc2HNpd=0
zIuu>$N9KXKXLi`ofp_t0J1)wq8DL<Z>p~|YrG#-DxsgjCXAzU1O0>8Nh_?JJ{1~R#
z_-4_G2lfQUM0Om|jH$=5rg?D~>QQ3Vq{jY-`|Voyujk6>!Hw2`|Mo;*+01kZ1q8jP
H=>M({B*A1~

literal 0
HcmV?d00001

diff --git a/contrib/include/wx/plot/plot_dwn.xpm b/contrib/include/wx/plot/plot_dwn.xpm
new file mode 100644
index 0000000000..51a59d3f16
--- /dev/null
+++ b/contrib/include/wx/plot/plot_dwn.xpm
@@ -0,0 +1,32 @@
+/* XPM */
+static char *plot_dwn_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"20 18 8 1",
+"  c Gray0",
+". c #000084",
+"X c Blue",
+"o c Green",
+"O c #848484",
+"+ c #c6c6c6",
+"@ c None",
+"# c Gray100",
+/* pixels */
+"@@.@@@@@@@@@@@@@@@@@",
+"@...@@@@@@@@@@@@@@@@",
+".@.@.@@@@@@@@@@@@@@@",
+"@@.@@@@@@@@  @@@@@@@",
+"@@.@@@@++++o +++@@@@",
+"@@.@@@@@   o   @@@@@",
+"@@.@@@@@+ ooo +@@@@@",
+"@@.@@@@@@+ o +@@@@@@",
+"@@.@@@@@@@+ +@@@@@@@",
+"@@.@@@@@@@@+@@@@@@@@",
+"@@.@@....@@@@@@@@@@@",
+"@@.@.O@@@.O@@@@@@@@@",
+"@@.O.@@@@@.@@@@@@@.@",
+"@@..@@@@@@@.@@@@@.O@",
+"@@.@@@@@@@@O.@@@.O@@",
+"@@.@@@@@@@@@O...O@@@",
+"@@.@@@@@@@@@@@@@@@@@",
+"@@@@@@@@@@@@@@@@@@@@",
+};
diff --git a/contrib/include/wx/plot/plot_enl.bmp b/contrib/include/wx/plot/plot_enl.bmp
new file mode 100644
index 0000000000000000000000000000000000000000..840f2958e1a4dbd253acb6902275343f335ad275
GIT binary patch
literal 358
zcmYjLu?+$-4D?G#NMBJf1aqL5oQ5^1Q$!e1r9k>Ms97Qzi4DTpZ$cdVe6g*w&zI{&
zW;fsoarBsIXZ4Ta1_vaK%?c5mO4$++lxnS%b4H_?Q)|i)cv=ETHzHwtq86Ob`_AM0
z)j7?ChR;0yGZF_b&t?71+*yM11riCqf(I7c$Ep)hL(k^Z!lTZhKkgmx5x<ientp%M
JU1ol#^DmzrYCiw~

literal 0
HcmV?d00001

diff --git a/contrib/include/wx/plot/plot_enl.xpm b/contrib/include/wx/plot/plot_enl.xpm
new file mode 100644
index 0000000000..7e48e2c138
--- /dev/null
+++ b/contrib/include/wx/plot/plot_enl.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static char *plot_enl_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"20 20 8 1",
+"  c Gray0",
+". c #000084",
+"X c Blue",
+"o c Green",
+"O c #848484",
+"+ c #c6c6c6",
+"@ c None",
+"# c Gray100",
+/* pixels */
+"@@.@@@@@@@@@@@@@@@@@",
+"@...@@@@@@@+@@@@@@@@",
+".@.@.@@@@@+ +@@@@@@@",
+"@@.@@@@@@+ o +@@@@@@",
+"@@.@@@@@+ ooo +@@@@@",
+"@@.@@@@@   o   @@@@@",
+"@@.@@@@++++o +++@@@@",
+"@@.@@....@@  @@@@@@@",
+"@@.@.O@@@.O@@@@@@@@@",
+"@@.O.@@@@@.@@@@@@@.@",
+"@@..@@@@@@@.@@@@@.O@",
+"@@.@@@@@@@@O.@@@.O@@",
+"@@.@@@@@@@@@O...O@@@",
+"@@.@@@@@@@@  @@@@@@@",
+"@@.@@@@++++o +++@@@@",
+"@@.@@@@@   o   @@@@@",
+"@@.@@@@@+ ooo +@@@@@",
+"@@.@@@@@@+ o +@@@@@@",
+"@@.@@@@@@@+ +@@@@@@@",
+"@@@@@@@@@@@+@@@@@@@@",
+};
diff --git a/contrib/include/wx/plot/plot_shr.bmp b/contrib/include/wx/plot/plot_shr.bmp
new file mode 100644
index 0000000000000000000000000000000000000000..7b4f3cfccbcd752c24095a9967b0d12737467ede
GIT binary patch
literal 358
zcmYjMyA1*{4E0G!NLNuX1aqKBPQx11DWWr?N`Z81P_slb5*vi)d`KMo<;DM8Z})|Y
zY`_cb+-#vk@qY_eIN?&O5{aM`W4(Z&lv1J)0s^@x<*W>bqb`8_g-93=cLX&49Gq6d
zqx#+FJ#yBOBTk#OT6vkh^9PGnZV>j+9o({%d93*szFzAMB9PW+?m5kxcj&t@qq6Pn
Kb=Lfs*7FC(1!_M4

literal 0
HcmV?d00001

diff --git a/contrib/include/wx/plot/plot_shr.xpm b/contrib/include/wx/plot/plot_shr.xpm
new file mode 100644
index 0000000000..0918938095
--- /dev/null
+++ b/contrib/include/wx/plot/plot_shr.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static char *plot_shr_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"20 20 8 1",
+"  c Gray0",
+". c #000084",
+"X c Blue",
+"o c Green",
+"O c #848484",
+"+ c #c6c6c6",
+"@ c None",
+"# c Gray100",
+/* pixels */
+"@@.@@@@@@@@@@@@@@@@@",
+"@...@@@@@@@  @@@@@@@",
+".@.@.@@++++o +++@@@@",
+"@@.@@@@@   o   @@@@@",
+"@@.@@@@@+ ooo +@@@@@",
+"@@.@@@@@@+ o +@@@@@@",
+"@@.@@@@@@@+ +@@@@@@@",
+"@@.@@....@@+@@@@@@@@",
+"@@.@.O@@@.O@@@@@@@@@",
+"@@.O.@@@@@.@@@@@@@.@",
+"@@..@@@@@@@.@@@@@.O@",
+"@@.@@@@@@@@O.@@@.O@@",
+"@@.@@@@@@@@+O...O@@@",
+"@@.@@@@@@@+ +@@@@@@@",
+"@@.@@@@@@+ o +@@@@@@",
+"@@.@@@@@+ ooo +@@@@@",
+"@@.@@@@@   o   @@@@@",
+"@@.@@@@++++o +++@@@@",
+"@@.@@@@@@@@  @@@@@@@",
+"@@@@@@@@@@@@@@@@@@@@",
+};
diff --git a/contrib/include/wx/plot/plot_up.bmp b/contrib/include/wx/plot/plot_up.bmp
new file mode 100644
index 0000000000000000000000000000000000000000..96b0be6ef7930845f36f353aaa20c929d1dae3eb
GIT binary patch
literal 334
zcmYL@O$q`r429o-Ak0d{LwF7;q#Hd;7sZOJE`+&;YcJ6r!`sxC{@6_3%hyaY)64a?
zpvIkkrcTt6TCk%7-|Ec{EUFd>U?Qbf=tSh45o6?wQWK>pQGB#T3;zIujKkoU*+S=s
z1gmT~<Cz=TazS@QXDoZVuk20xlrmdx-}@}j$ymWdn{l7_oLT2gaBPn|D3V2_lCszP
J)ad`}`~%s_WM2RP

literal 0
HcmV?d00001

diff --git a/contrib/include/wx/plot/plot_up.xpm b/contrib/include/wx/plot/plot_up.xpm
new file mode 100644
index 0000000000..cafdb0b07b
--- /dev/null
+++ b/contrib/include/wx/plot/plot_up.xpm
@@ -0,0 +1,32 @@
+/* XPM */
+static char *plot_up_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"20 18 8 1",
+"  c Gray0",
+". c #000084",
+"X c Blue",
+"o c Green",
+"O c #848484",
+"+ c #c6c6c6",
+"@ c None",
+"# c Gray100",
+/* pixels */
+"@@.@@@@@@@@@@@@@@@@@",
+"@...@@@@@@@@@@@@@@@@",
+".@.@.@@@@@@@@@@@@@@@",
+"@@.@@@@@@@@+@@@@@@@@",
+"@@.@@@@@@@+ +@@@@@@@",
+"@@.@@@@@@+ o +@@@@@@",
+"@@.@@@@@+ ooo +@@@@@",
+"@@.@@@@@   o   @@@@@",
+"@@.@@@@++++o +++@@@@",
+"@@.@@@@@@@@  @@@@@@@",
+"@@.@@....@@@@@@@@@@@",
+"@@.@.O@@@.O@@@@@@@@@",
+"@@.O.@@@@@.@@@@@@@.@",
+"@@..@@@@@@@.@@@@@.O@",
+"@@.@@@@@@@@O.@@@.O@@",
+"@@.@@@@@@@@@O...O@@@",
+"@@.@@@@@@@@@@@@@@@@@",
+"@@@@@@@@@@@@@@@@@@@@",
+};
diff --git a/contrib/include/wx/plot/plot_zin.bmp b/contrib/include/wx/plot/plot_zin.bmp
new file mode 100644
index 0000000000000000000000000000000000000000..6df6ffeff24e58e95f72ac64d0b0f29de129f43b
GIT binary patch
literal 334
zcmY+8K?=e!5Ji7M2y`XlAv}i!(v6-ai{QBILg+PI_Y&<fyiNT-(-xi1|9P3t47uL!
z4Qf2-7wSx%s0If*@Tu;0<RN)X029;X2c3v{p3(O`e=IezEFy}ZN;KO8u(Vw^e#OC7
zekSY0kv)YukUI`&CaI@mP4nUseU;cOm}Re976;$iB4oTP=Wz^D?QhlN^}qgoPfA=`
M11NgW%D?ab0!~6=O#lD@

literal 0
HcmV?d00001

diff --git a/contrib/include/wx/plot/plot_zin.xpm b/contrib/include/wx/plot/plot_zin.xpm
new file mode 100644
index 0000000000..27aabe85df
--- /dev/null
+++ b/contrib/include/wx/plot/plot_zin.xpm
@@ -0,0 +1,32 @@
+/* XPM */
+static char *plot_zin_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"20 18 8 1",
+"  c Gray0",
+". c #000084",
+"X c Blue",
+"o c Green",
+"O c #848484",
+"+ c #c6c6c6",
+"@ c None",
+"# c Gray100",
+/* pixels */
+"@@.@@@@@@@@@@@@@@@@@",
+"@...@@@@@@@@@@@@@@@@",
+".@.@.@@@@+@@@@+@@@@@",
+"@@.@@@@+ +@@@@+ +@@@",
+"@@.@@@+  +@@@@+  +@@",
+"@@.@@+ o +@@@@+ o +@",
+"@@.@+ oooo @@ oooo +",
+"@@.@@+ o   @@   o +@",
+"@@.@@@+  +@@@@+  +@@",
+"@@.@@@@+ +@@@@+ +@@@",
+"@@.@@....+@@@@+@@@@@",
+"@@.@.O@@@.O@@@@@@@@@",
+"@@.O.@@@@@.@@@@@@@.@",
+"@@..@@@@@@@.@@@@@.O@",
+"@@.@@@@@@@@O.@@@.O@@",
+"@@.@@@@@@@@@O...O@@@",
+"@@.@@@@@@@@@@@@@@@@@",
+"@@@@@@@@@@@@@@@@@@@@",
+};
diff --git a/contrib/include/wx/plot/plot_zot.bmp b/contrib/include/wx/plot/plot_zot.bmp
new file mode 100644
index 0000000000000000000000000000000000000000..dbe24799d0b5df57c77a34d4e12a440c1322b7e1
GIT binary patch
literal 334
zcmZXOF%H5o3`Kt>q)1E%aR|<VDkTe?B}0T6J0SHM%)LZ<3~p2Yk7*fj{eNCu+wJ9g
z>(Js(KT{{_NOjoJfp>Ga0}sig0!-BE2c3v{o-qsqUo0)LEFy}JN;KO7u()1Ue)gk%
z`4KINd-fFONKPEkOjJ)|P4nW?`zo<zRfF%z!HiNp<7Ku-Xgp0JQ{J!ofB$b!jJ{pp
LD*B%mZFb`iS%P9s

literal 0
HcmV?d00001

diff --git a/contrib/include/wx/plot/plot_zot.xpm b/contrib/include/wx/plot/plot_zot.xpm
new file mode 100644
index 0000000000..d3a34d141f
--- /dev/null
+++ b/contrib/include/wx/plot/plot_zot.xpm
@@ -0,0 +1,32 @@
+/* XPM */
+static char *plot_zot_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"20 18 8 1",
+"  c Gray0",
+". c #000084",
+"X c Blue",
+"o c Green",
+"O c #848484",
+"+ c #c6c6c6",
+"@ c None",
+"# c Gray100",
+/* pixels */
+"@@.@@@@@@@@@@@@@@@@@",
+"@...@@@@@@@@@@@@@@@@",
+".@.@.@+@@@@@@@@@@+@@",
+"@@.@@@+ +@@@@@@+ +@@",
+"@@.@@@+  +@@@@+  +@@",
+"@@.@@@+ o +@@+ o +@@",
+"@@.@@ oooo ++ oooo @",
+"@@.@@   o +@@+ o   @",
+"@@.@@@+  +@@@@+  +@@",
+"@@.@@@+ +@@@@@@+ +@@",
+"@@.@@....@@@@@@@@+@@",
+"@@.@.O@@@.O@@@@@@@@@",
+"@@.O.@@@@@.@@@@@@@.@",
+"@@..@@@@@@@.@@@@@.O@",
+"@@.@@@@@@@@O.@@@.O@@",
+"@@.@@@@@@@@@O...O@@@",
+"@@.@@@@@@@@@@@@@@@@@",
+"@@@@@@@@@@@@@@@@@@@@",
+};
diff --git a/contrib/include/wx/plot/wxplot.rc b/contrib/include/wx/plot/wxplot.rc
new file mode 100644
index 0000000000..e53398c433
--- /dev/null
+++ b/contrib/include/wx/plot/wxplot.rc
@@ -0,0 +1,8 @@
+
+// For /plot.cpp
+plot_up_bmp             BITMAP  "wx/plot/plot_up.bmp"
+plot_dwn_bmp            BITMAP  "wx/plot/plot_dwn.bmp"
+plot_enl_bmp            BITMAP  "wx/plot/plot_enl.bmp"
+plot_shr_bmp            BITMAP  "wx/plot/plot_shr.bmp"
+plot_zin_bmp            BITMAP  "wx/plot/plot_zin.bmp"
+plot_zot_bmp            BITMAP  "wx/plot/plot_zot.bmp"
diff --git a/contrib/samples/Makefile.in b/contrib/samples/Makefile.in
index fd6917aabd..93436487e4 100644
--- a/contrib/samples/Makefile.in
+++ b/contrib/samples/Makefile.in
@@ -1,6 +1,6 @@
 # $Id$
 
-CONTRIB_SAMPLES=mmedia ogl stc gizmos canvas xml
+CONTRIB_SAMPLES=mmedia ogl stc gizmos canvas xml plot
 
 all:
 	@for d in $(CONTRIB_SAMPLES); do (cd $$d && $(MAKE)); done
diff --git a/contrib/samples/plot/Makefile.in b/contrib/samples/plot/Makefile.in
new file mode 100644
index 0000000000..c305d4fcd6
--- /dev/null
+++ b/contrib/samples/plot/Makefile.in
@@ -0,0 +1,16 @@
+# Makefile for mmedia sample.
+# $Id$
+
+top_srcdir = @top_srcdir@/..
+top_builddir = ../../..
+program_dir = contrib/samples/plot
+
+PROGRAM=plot
+
+OBJECTS=plot.o
+
+APPEXTRALIBS=$(top_builddir)/lib/libplot.@WX_TARGET_LIBRARY_TYPE@
+APPEXTRADEFS=-I$(top_srcdir)/contrib/include
+
+include $(top_builddir)/src/makeprog.env
+
diff --git a/contrib/samples/plot/plot.cpp b/contrib/samples/plot/plot.cpp
new file mode 100644
index 0000000000..3898313e16
--- /dev/null
+++ b/contrib/samples/plot/plot.cpp
@@ -0,0 +1,185 @@
+/*
+ * Program: wxPlotWindow
+ *
+ * Author: Robert Roebling
+ *
+ * Copyright: (C) 1999, Robert Roebling
+ *
+ */
+
+// For compilers that support precompilation, includes "wx/wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/wx.h"
+#endif
+
+#include "wx/plot.h"
+
+#include "wx/image.h"
+#include "wx/listctrl.h"
+#include "wx/sizer.h"
+#include "wx/log.h"
+#include "wx/intl.h"
+
+#include <math.h>
+
+// derived classes
+
+class MyPlotCurve;
+class MyFrame;
+class MyApp;
+
+// MyPlotCurve
+
+class MyPlotCurve: public wxPlotCurve
+{
+public:
+    MyPlotCurve( int offsetY, double startY, double endY ) : 
+        wxPlotCurve( offsetY, startY, endY ) {}
+    
+    virtual wxInt32 GetStartX()
+        { return 0; }
+    virtual wxInt32 GetEndX()
+        { return 7000; }
+    
+    virtual double GetY( wxInt32 x )
+        { 
+            double dx = x;
+            dx /= 100;
+            return sin( dx );
+        }
+};
+
+// MyFrame
+
+class MyFrame: public wxFrame
+{
+public:
+    MyFrame();
+
+    void OnAbout( wxCommandEvent &event );
+    void OnQuit( wxCommandEvent &event );
+    
+    void OnPlotClick( wxPlotEvent &event );
+    void OnPlotDClick( wxPlotEvent &event );
+
+    wxPlotWindow   *m_plot;
+    wxTextCtrl     *m_log;
+
+private:
+    DECLARE_DYNAMIC_CLASS(MyFrame)
+    DECLARE_EVENT_TABLE()
+};
+
+// MyApp
+
+class MyApp: public wxApp
+{
+public:
+    virtual bool OnInit();
+};
+
+// main program
+
+IMPLEMENT_APP(MyApp)
+
+// MyFrame
+
+const int ID_QUIT  = 108;
+const int ID_ABOUT = 109;
+
+IMPLEMENT_DYNAMIC_CLASS( MyFrame, wxFrame )
+
+BEGIN_EVENT_TABLE(MyFrame,wxFrame)
+  EVT_MENU             (ID_ABOUT, MyFrame::OnAbout)
+  EVT_MENU             (ID_QUIT,  MyFrame::OnQuit)
+  EVT_PLOT_CLICKED         ( -1,  MyFrame::OnPlotClick)
+  EVT_PLOT_DOUBLECLICKED   ( -1,  MyFrame::OnPlotDClick)
+END_EVENT_TABLE()
+
+MyFrame::MyFrame()
+       : wxFrame( (wxFrame *)NULL, -1, "wxPlotWindow sample",
+                  wxPoint(20,20), wxSize(470,500) )
+{
+    wxMenu *file_menu = new wxMenu();
+    file_menu->Append( ID_ABOUT, "&About..");
+    file_menu->Append( ID_QUIT, "E&xit\tAlt-X");
+
+    wxMenuBar *menu_bar = new wxMenuBar();
+    menu_bar->Append(file_menu, "&File");
+
+    SetMenuBar( menu_bar );
+
+    CreateStatusBar(2);
+    int widths[] = { -1, 100 };
+    SetStatusWidths( 2, widths );
+
+    m_plot = new wxPlotWindow( this, -1, wxPoint(0,0), wxSize(100,100), wxSUNKEN_BORDER | wxPLOT_DEFAULT );
+    m_plot->SetUnitsPerValue( 0.01 );
+    m_plot->SetScrollOnThumbRelease( TRUE );
+
+    m_plot->Add( new MyPlotCurve( 0,  -1.5, 1.5 ) );
+    m_plot->Add( new MyPlotCurve( 50, -1.5, 1.5 ) );
+    wxPlotOnOffCurve *oo = new wxPlotOnOffCurve( 10 );
+    oo->Add( 10, 20 );
+    oo->Add( 25, 30 );
+    oo->Add( 100, 400 );
+    oo->Add( 1000, 2000 );
+    m_plot->Add( oo );
+  
+    m_log = new wxTextCtrl( this, -1, "This is the log window.\n", wxPoint(0,0), wxSize(100,100), wxTE_MULTILINE );
+    wxLog *old_log = wxLog::SetActiveTarget( new wxLogTextCtrl( m_log ) );
+    delete old_log;
+    
+    wxBoxSizer *topsizer = new wxBoxSizer( wxVERTICAL );
+    
+    topsizer->Add( m_plot, 1, wxEXPAND );
+    topsizer->Add( m_log, 0, wxEXPAND );
+
+    SetAutoLayout( TRUE );
+    SetSizer( topsizer );
+}
+
+void MyFrame::OnQuit( wxCommandEvent &WXUNUSED(event) )
+{
+  Close( TRUE );
+}
+
+void MyFrame::OnAbout( wxCommandEvent &WXUNUSED(event) )
+{
+  (void)wxMessageBox( "wxPlotWindow Demo\n"
+                      "Robert Roebling (c) 1999,2000",
+                      "About wxPlotWindow Demo", wxICON_INFORMATION | wxOK );
+}
+
+void MyFrame::OnPlotClick( wxPlotEvent &event )
+{
+    double x = event.GetPosition() * m_plot->GetUnitsPerValue();
+    double y = event.GetCurve()->GetY( event.GetPosition() );
+    wxLogMessage( "Clicked on curve at x coordinate: %f, value: %f", x, y );
+}
+
+void MyFrame::OnPlotDClick( wxPlotEvent &event )
+{
+    double x = event.GetPosition() * m_plot->GetUnitsPerValue();
+    double y = event.GetCurve()->GetY( event.GetPosition() );
+    wxLogMessage( "Double clicked on curve at x coordinate: %f, value: %f", x, y );
+}
+
+//-----------------------------------------------------------------------------
+// MyApp
+//-----------------------------------------------------------------------------
+
+bool MyApp::OnInit()
+{
+    wxFrame *frame = new MyFrame();
+    frame->Show( TRUE );
+
+    return TRUE;
+}
+
diff --git a/contrib/samples/plot/plot.def b/contrib/samples/plot/plot.def
new file mode 100644
index 0000000000..a0e0c65399
--- /dev/null
+++ b/contrib/samples/plot/plot.def
@@ -0,0 +1,7 @@
+NAME         Plot
+DESCRIPTION  'wxWindows Plot sample'
+EXETYPE      WINDOWS
+CODE         PRELOAD MOVEABLE DISCARDABLE
+DATA         PRELOAD MOVEABLE MULTIPLE
+HEAPSIZE     4048
+STACKSIZE    16000
diff --git a/contrib/samples/plot/plot.rc b/contrib/samples/plot/plot.rc
new file mode 100644
index 0000000000..2b2f92f2da
--- /dev/null
+++ b/contrib/samples/plot/plot.rc
@@ -0,0 +1,2 @@
+#include "wx/msw/wx.rc"
+#include "wx/plot/wxplot.rc"
diff --git a/contrib/src/plot/Makefile.in b/contrib/src/plot/Makefile.in
new file mode 100644
index 0000000000..3d3d55a65f
--- /dev/null
+++ b/contrib/src/plot/Makefile.in
@@ -0,0 +1,23 @@
+# $Id$
+
+top_srcdir = @top_srcdir@/..
+top_builddir = ../../..
+libsrc_dir = contrib/src/plot
+
+TARGET_LIBNAME=libplot
+
+LIBVERSION_CURRENT=1
+LIBVERSION_REVISION=0
+LIBVERSION_AGE=0
+
+HEADER_PATH=$(top_srcdir)/contrib/include/wx
+HEADER_SUBDIR=plot
+
+HEADERS=plot.h
+
+OBJECTS=plot.o
+
+APPEXTRADEFS=-I$(top_srcdir)/contrib/include
+
+include $(top_builddir)/src/makelib.env
+
diff --git a/contrib/src/plot/plot.cpp b/contrib/src/plot/plot.cpp
new file mode 100644
index 0000000000..af509c3440
--- /dev/null
+++ b/contrib/src/plot/plot.cpp
@@ -0,0 +1,1204 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        plot.cpp
+// Purpose:     wxPlotWindow
+// Author:      Robert Roebling
+// Modified by:
+// Created:     12/01/2000
+// RCS-ID:      $Id$
+// Copyright:   (c) Robert Roebling
+// Licence:     wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "plot.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/object.h"
+#include "wx/font.h"
+#include "wx/colour.h"
+#include "wx/settings.h"
+#include "wx/sizer.h"
+#include "wx/log.h"
+#include "wx/intl.h"
+#include "wx/dcclient.h"
+#endif
+
+#include "wx/plot/plot.h"
+#include "wx/bmpbuttn.h"
+
+#include <math.h>
+
+// ----------------------------------------------------------------------------
+// XPMs
+// ----------------------------------------------------------------------------
+
+#if !defined(__WXMSW__) && !defined(__WXPM__)
+    #include "wx/plot/plot_enl.xpm"
+    #include "wx/plot/plot_shr.xpm"
+    #include "wx/plot/plot_zin.xpm"
+    #include "wx/plot/plot_zot.xpm"
+    #include "wx/plot/plot_up.xpm"
+    #include "wx/plot/plot_dwn.xpm"
+#endif
+
+//----------------------------------------------------------------------------
+// accessor functions for the bitmaps (may return NULL, check for it!)
+//----------------------------------------------------------------------------
+
+static wxBitmap *GetEnlargeBitmap();
+static wxBitmap *GetShrinkBitmap();
+static wxBitmap *GetZoomInBitmap();
+static wxBitmap *GetZoomOutBitmap();
+static wxBitmap *GetUpBitmap();
+static wxBitmap *GetDownBitmap();
+
+//----------------------------------------------------------------------------
+// event types
+//----------------------------------------------------------------------------
+
+int wxEVT_PLOT_SEL_CHANGING;
+int wxEVT_PLOT_SEL_CHANGED;
+int wxEVT_PLOT_CLICKED;
+int wxEVT_PLOT_DOUBLECLICKED;
+int wxEVT_PLOT_ZOOM_IN;
+int wxEVT_PLOT_ZOOM_OUT;
+int wxEVT_PLOT_VALUE_SEL_CREATING;
+int wxEVT_PLOT_VALUE_SEL_CREATED;
+int wxEVT_PLOT_VALUE_SEL_CHANGING;
+int wxEVT_PLOT_VALUE_SEL_CHANGED;
+int wxEVT_PLOT_AREA_SEL_CREATING;
+int wxEVT_PLOT_AREA_SEL_CREATED;
+int wxEVT_PLOT_AREA_SEL_CHANGING;
+int wxEVT_PLOT_AREA_SEL_CHANGED;
+int wxEVT_PLOT_BEGIN_X_LABEL_EDIT;
+int wxEVT_PLOT_END_X_LABEL_EDIT;
+int wxEVT_PLOT_BEGIN_Y_LABEL_EDIT;
+int wxEVT_PLOT_END_Y_LABEL_EDIT;
+int wxEVT_PLOT_BEGIN_TITLE_EDIT;
+int wxEVT_PLOT_END_TITLE_EDIT;
+int wxEVT_PLOT_AREA_CREATE;
+
+//-----------------------------------------------------------------------------
+// consts
+//-----------------------------------------------------------------------------
+
+#define wxPLOT_SCROLL_STEP  30
+
+//-----------------------------------------------------------------------------
+// wxPlotEvent
+//-----------------------------------------------------------------------------
+
+wxPlotEvent::wxPlotEvent( wxEventType commandType, int id )
+    : wxNotifyEvent( commandType, id )
+{ 
+    m_curve = (wxPlotCurve*) NULL;
+    m_zoom = 1.0;
+    m_position = 0;
+}
+      
+//-----------------------------------------------------------------------------
+// wxPlotCurve
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_ABSTRACT_CLASS(wxPlotCurve, wxObject)
+
+wxPlotCurve::wxPlotCurve( int offsetY, double startY, double endY )
+{
+    m_offsetY = offsetY;
+    m_startY = startY;
+    m_endY = endY;
+}
+
+//-----------------------------------------------------------------------------
+// wxPlotOnOffCurve
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_CLASS(wxPlotOnOffCurve, wxObject)
+
+#include "wx/arrimpl.cpp"
+WX_DEFINE_OBJARRAY(wxArrayPlotOnOff);
+
+wxPlotOnOffCurve::wxPlotOnOffCurve( int offsetY )
+{
+    m_offsetY = offsetY;
+    m_minX = -1;
+    m_maxX = -1;
+}
+
+void wxPlotOnOffCurve::Add( wxInt32 on, wxInt32 off, void *clientData )
+{
+    wxASSERT_MSG( on > 0, wxT("plot index < 0") );
+    wxASSERT( on <= off );
+
+    if (m_minX == -1)
+        m_minX = on;
+    if (off > m_maxX)
+        m_maxX = off;
+    
+    wxPlotOnOff *v = new wxPlotOnOff;
+    v->m_on = on;
+    v->m_off = off;
+    v->m_clientData = clientData;
+    m_marks.Add( v );
+}
+
+size_t wxPlotOnOffCurve::GetCount()
+{
+    return m_marks.GetCount();
+}
+
+wxInt32 wxPlotOnOffCurve::GetOn( size_t index )
+{
+    wxPlotOnOff *v = &m_marks.Item( index );
+    return v->m_on;
+}
+
+wxInt32 wxPlotOnOffCurve::GetOff( size_t index )
+{
+    wxPlotOnOff *v = &m_marks.Item( index );
+    return v->m_off;
+}
+
+void* wxPlotOnOffCurve::GetClientData( size_t index )
+{
+    wxPlotOnOff *v = &m_marks.Item( index );
+    return v->m_clientData;
+}
+
+wxPlotOnOff *wxPlotOnOffCurve::GetAt( size_t index )
+{
+    return &m_marks.Item( index );
+}
+
+void wxPlotOnOffCurve::DrawOnLine( wxDC &dc, wxCoord y, wxCoord start, wxCoord end, void *WXUNUSED(clientData) )
+{
+    dc.DrawLine( start, y, start, y-30 );
+    dc.DrawLine( start, y-30, end, y-30 );
+    dc.DrawLine( end, y-30, end, y );
+}
+
+void wxPlotOnOffCurve::DrawOffLine( wxDC &dc, wxCoord y, wxCoord start, wxCoord end )
+{
+    dc.DrawLine( start, y, end, y );
+}
+
+//-----------------------------------------------------------------------------
+// wxPlotArea
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxPlotArea, wxWindow)
+
+BEGIN_EVENT_TABLE(wxPlotArea, wxWindow)
+  EVT_PAINT(        wxPlotArea::OnPaint)
+  EVT_LEFT_DOWN(    wxPlotArea::OnMouse)
+  EVT_LEFT_DCLICK(  wxPlotArea::OnMouse)
+END_EVENT_TABLE()
+
+wxPlotArea::wxPlotArea( wxPlotWindow *parent )
+        : wxWindow( parent, -1, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER, "plotarea" )
+{
+    m_owner = parent;
+    
+    m_zooming = FALSE;
+
+    SetBackgroundColour( *wxWHITE );
+}
+
+void wxPlotArea::OnMouse( wxMouseEvent &event )
+{
+    int client_width;
+    int client_height;
+    GetClientSize( &client_width, &client_height);
+    int view_x;
+    int view_y;
+    m_owner->GetViewStart( &view_x, &view_y );
+    view_x *= wxPLOT_SCROLL_STEP;
+    view_y *= wxPLOT_SCROLL_STEP;
+    
+    wxCoord x = event.GetX();
+    wxCoord y = event.GetY();
+    x += view_x;
+    y += view_y;
+    
+    wxNode *node = m_owner->m_curves.First();
+    while (node)
+    {
+        wxPlotCurve *curve = (wxPlotCurve*)node->Data();
+            
+        double double_client_height = (double)client_height;
+        double range = curve->GetEndY() - curve->GetStartY();
+        double end = curve->GetEndY();
+        wxCoord offset_y = curve->GetOffsetY();
+            
+        double dy = (end - curve->GetY( (wxInt32)(x/m_owner->GetZoom()) )) / range;
+        wxCoord curve_y = (wxCoord)(dy * double_client_height) - offset_y - 1;
+                
+        if ((y-curve_y < 4) && (y-curve_y > -4))
+        {
+            wxPlotEvent event1( event.ButtonDClick() ? wxEVT_PLOT_DOUBLECLICKED : wxEVT_PLOT_CLICKED, m_owner->GetId() );
+            event1.SetEventObject( m_owner );
+            event1.SetZoom( m_owner->GetZoom() );
+            event1.SetCurve( curve );
+            event1.SetPosition( (int)floor(x/m_owner->GetZoom()) );
+            m_owner->GetEventHandler()->ProcessEvent( event1 );
+            
+            if (curve != m_owner->GetCurrent())
+            {
+                wxPlotEvent event2( wxEVT_PLOT_SEL_CHANGING, m_owner->GetId() );
+                event2.SetEventObject( m_owner );
+                event2.SetZoom( m_owner->GetZoom() );
+                event2.SetCurve( curve );
+                if (!m_owner->GetEventHandler()->ProcessEvent( event2 ) || event2.IsAllowed())
+                {
+                    m_owner->SetCurrent( curve );
+                }
+            }
+            return;
+        }
+            
+        node = node->Next();
+    }
+}
+
+void wxPlotArea::DeleteCurve( wxPlotCurve *curve, int from, int to )
+{
+    wxClientDC dc(this);
+    m_owner->PrepareDC( dc );
+    dc.SetPen( *wxWHITE_PEN );
+    DrawCurve( &dc, curve, from, to );
+}
+
+void wxPlotArea::DrawCurve( wxDC *dc, wxPlotCurve *curve, int from, int to )
+{
+    int view_x;
+    int view_y;
+    m_owner->GetViewStart( &view_x, &view_y );
+    view_x *= wxPLOT_SCROLL_STEP;
+    
+    if (from == -1)
+        from = view_x;
+
+    int client_width;
+    int client_height;
+    GetClientSize( &client_width, &client_height);
+    
+    if (to == -1)
+        to = view_x + client_width;
+        
+    double zoom = m_owner->GetZoom();
+
+    int start_x = wxMax( from, (int)floor(curve->GetStartX()*zoom) );
+    int end_x = wxMin( to, (int)floor(curve->GetEndX()*zoom) );
+
+    start_x = wxMax( view_x, start_x );
+    end_x = wxMin( view_x + client_width, end_x );
+    
+    end_x++;
+
+    double double_client_height = (double)client_height;
+    double range = curve->GetEndY() - curve->GetStartY();
+    double end = curve->GetEndY();
+    wxCoord offset_y = curve->GetOffsetY();
+            
+    wxCoord y=0,last_y=0;
+    for (int x = start_x; x < end_x; x++)
+    {
+        double dy = (end - curve->GetY( (wxInt32)(x/zoom) )) / range;
+        y = (wxCoord)(dy * double_client_height) - offset_y - 1;
+            
+        if (x != start_x)
+           dc->DrawLine( x-1, last_y, x, y );
+            
+        last_y = y;
+    }
+}
+
+void wxPlotArea::DrawOnOffCurve( wxDC *dc, wxPlotOnOffCurve *curve, int from, int to )
+{
+    int view_x;
+    int view_y;
+    m_owner->GetViewStart( &view_x, &view_y );
+    view_x *= wxPLOT_SCROLL_STEP;
+    
+    if (from == -1)
+        from = view_x;
+
+    int client_width;
+    int client_height;
+    GetClientSize( &client_width, &client_height);
+    
+    if (to == -1)
+        to = view_x + client_width;
+        
+    double zoom = m_owner->GetZoom();
+
+    int start_x = wxMax( from, (int)floor(curve->GetStartX()*zoom) );
+    int end_x = wxMin( to, (int)floor(curve->GetEndX()*zoom) );
+
+    start_x = wxMax( view_x, start_x );
+    end_x = wxMin( view_x + client_width, end_x );
+    
+    end_x++;
+
+    wxCoord offset_y = curve->GetOffsetY();
+    wxCoord last_off = -5;
+    
+    if (curve->GetCount() == 0)
+        return;
+    
+    for (size_t index = 0; index < curve->GetCount(); index++)
+    {
+        wxPlotOnOff *p = curve->GetAt( index );
+        
+        wxCoord on = (wxCoord)(p->m_on*zoom);
+        wxCoord off = (wxCoord)(p->m_off*zoom);
+
+        if (end_x < on)
+        {
+            curve->DrawOffLine( *dc, client_height-offset_y, last_off, on );
+            break;
+        }
+        
+        if (off >= start_x)
+        {
+            curve->DrawOffLine( *dc, client_height-offset_y, last_off, on );
+            curve->DrawOnLine( *dc, client_height-offset_y, on, off, p->m_clientData );
+        }
+        last_off = off;
+    }
+    
+    wxPlotOnOff *p = curve->GetAt( curve->GetCount()-1 );
+    wxCoord off = (wxCoord)(p->m_off*zoom);
+    if (off < end_x)
+        curve->DrawOffLine( *dc, client_height-offset_y, off, to );
+}
+
+void wxPlotArea::OnPaint( wxPaintEvent &WXUNUSED(event) )
+{
+    int view_x;
+    int view_y;
+    m_owner->GetViewStart( &view_x, &view_y );
+    view_x *= wxPLOT_SCROLL_STEP;
+    view_y *= wxPLOT_SCROLL_STEP;
+
+    wxPaintDC dc( this );
+    m_owner->PrepareDC( dc );
+
+    wxRegionIterator upd( GetUpdateRegion() );
+    
+    while (upd)
+    {
+        int update_x = upd.GetX();
+        int update_y = upd.GetY();
+        int update_width = upd.GetWidth();
+        
+        update_x += view_x;
+        update_y += view_y;
+        
+/*
+        if (m_owner->m_current)
+        {
+            dc.SetPen( *wxLIGHT_GREY_PEN );
+            int base_line = client_height - m_owner->m_current->GetOffsetY();
+            dc.DrawLine( update_x-1, base_line-1, update_x+update_width+2, base_line-1 );
+        }
+*/
+        
+        wxNode *node = m_owner->m_curves.First();
+        while (node)
+        {
+            wxPlotCurve *curve = (wxPlotCurve*) node->Data();
+            
+            if (curve == m_owner->GetCurrent())
+                dc.SetPen( *wxBLACK_PEN );
+            else
+                dc.SetPen( *wxGREY_PEN );
+                
+            DrawCurve( &dc, curve, update_x-1, update_x+update_width+2 );
+
+            node = node->Next();
+        }
+        
+        dc.SetPen( *wxRED_PEN );
+        
+        node = m_owner->m_onOffCurves.First();
+        while (node)
+        {
+            wxPlotOnOffCurve *curve = (wxPlotOnOffCurve*) node->Data();
+            
+            DrawOnOffCurve( &dc, curve, update_x-1, update_x+update_width+2 );
+            
+            node = node->Next();
+        }
+        
+        upd ++;
+    }
+}
+
+void wxPlotArea::ScrollWindow( int dx, int dy, const wxRect *rect )
+{
+    wxWindow::ScrollWindow( dx, dy, rect );
+//    m_owner->m_xaxis->ScrollWindow( dx, 0 );
+}
+
+//-----------------------------------------------------------------------------
+// wxPlotXAxisArea
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxPlotXAxisArea, wxWindow)
+
+BEGIN_EVENT_TABLE(wxPlotXAxisArea, wxWindow)
+  EVT_PAINT(        wxPlotXAxisArea::OnPaint)
+  EVT_LEFT_DOWN(    wxPlotXAxisArea::OnMouse)
+END_EVENT_TABLE()
+
+wxPlotXAxisArea::wxPlotXAxisArea( wxPlotWindow *parent )
+        : wxWindow( parent, -1, wxDefaultPosition, wxSize(-1,40), 0, "plotxaxisarea" )
+{
+    m_owner = parent;
+    
+    SetBackgroundColour( *wxWHITE );
+    SetFont( *wxSMALL_FONT );
+}
+
+void wxPlotXAxisArea::OnMouse( wxMouseEvent &event )
+{
+    int client_width;
+    int client_height;
+    GetClientSize( &client_width, &client_height);
+    int view_x;
+    int view_y;
+    m_owner->GetViewStart( &view_x, &view_y );
+    view_x *= wxPLOT_SCROLL_STEP;
+    view_y *= wxPLOT_SCROLL_STEP;
+    
+    wxCoord x = event.GetX();
+    wxCoord y = event.GetY();
+    x += view_x;
+    y += view_y;
+    
+    /* do something here */
+}
+
+void wxPlotXAxisArea::OnPaint( wxPaintEvent &WXUNUSED(event) )
+{
+    int view_x;
+    int view_y;
+    m_owner->GetViewStart( &view_x, &view_y );
+    view_x *= wxPLOT_SCROLL_STEP;
+    view_y *= wxPLOT_SCROLL_STEP;
+
+    wxPaintDC dc( this );
+    
+    int client_width;
+    int client_height;
+    GetClientSize( &client_width, &client_height);
+    
+    double zoom = m_owner->GetZoom();
+    
+    double ups = m_owner->GetUnitsPerValue() / zoom;
+    
+    double start = view_x * ups;
+    double end = (view_x + client_width) * ups;
+    double range = end - start;
+    
+    int int_log_range = (int)floor( log10( range ) );
+    double step = 1.0;
+    if (int_log_range > 0)
+    {
+        for (int i = 0; i < int_log_range; i++)
+           step *= 10; 
+    }
+    if (int_log_range < 0)
+    {
+        for (int i = 0; i < -int_log_range; i++)
+           step /= 10; 
+    }
+    double lower = ceil(start / step) * step;
+    double upper = floor(end / step) * step;
+    
+    // if too few values, shrink size
+    if ((range/step) < 4)
+    {
+        step /= 2;
+        if (lower-step > start) lower -= step;
+        if (upper+step < end) upper += step;
+    }
+    
+    // if still too few, again
+    if ((range/step) < 4)
+    {
+        step /= 2;
+        if (lower-step > start) lower -= step;
+        if (upper+step < end) upper += step;
+    }
+    
+    dc.SetBrush( *wxWHITE_BRUSH );
+    dc.SetPen( *wxTRANSPARENT_PEN );
+    dc.DrawRectangle( 4, 5, client_width-14, 10 );
+    dc.DrawRectangle( 0, 20, client_width, 20 );
+    dc.SetPen( *wxBLACK_PEN );
+    
+    double current = lower;
+    while (current < upper+(step/2))
+    {
+        int x = (int)ceil((current-start) / range * (double)client_width) - 1;
+        if ((x > 4) && (x < client_width-25))
+        {
+            dc.DrawLine( x, 5, x, 15 );
+            wxString label;
+            if (range < 50)
+            {
+                label.Printf( wxT("%f"), current );
+                while (label.Last() == wxT('0')) 
+                    label.RemoveLast();
+                if ((label.Last() == wxT('.')) || (label.Last() == wxT(',')))
+                    label.Append( wxT('0') );
+            }
+            else
+                label.Printf( wxT("%d"), (int)floor(current) );
+            dc.DrawText( label, x-4, 20 );
+        }
+
+        current += step;
+    }
+    
+    dc.DrawLine( 0, 15, client_width-8, 15 );
+    dc.DrawLine( client_width-4, 15, client_width-10, 10 );
+    dc.DrawLine( client_width-4, 15, client_width-10, 20 );
+}
+
+//-----------------------------------------------------------------------------
+// wxPlotYAxisArea
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxPlotYAxisArea, wxWindow)
+
+BEGIN_EVENT_TABLE(wxPlotYAxisArea, wxWindow)
+  EVT_PAINT(        wxPlotYAxisArea::OnPaint)
+  EVT_LEFT_DOWN(    wxPlotYAxisArea::OnMouse)
+END_EVENT_TABLE()
+
+wxPlotYAxisArea::wxPlotYAxisArea( wxPlotWindow *parent )
+        : wxWindow( parent, -1, wxDefaultPosition, wxSize(60,-1), 0, "plotyaxisarea" )
+{
+    m_owner = parent;
+    
+    SetBackgroundColour( *wxWHITE );
+    SetFont( *wxSMALL_FONT );
+}
+
+void wxPlotYAxisArea::OnMouse( wxMouseEvent &WXUNUSED(event) )
+{
+    /* do something here */
+}
+
+void wxPlotYAxisArea::OnPaint( wxPaintEvent &WXUNUSED(event) )
+{
+    wxPaintDC dc( this );
+    
+    wxPlotCurve *curve = m_owner->GetCurrent();
+    
+    if (!curve) return;
+    
+    int client_width;
+    int client_height;
+    GetClientSize( &client_width, &client_height);
+
+    
+    double range = curve->GetEndY() - curve->GetStartY();
+    double offset = ((double) curve->GetOffsetY() / (double)client_height ) * range;
+    double start = curve->GetStartY() - offset;
+    double end = curve->GetEndY() - offset;
+    
+    int int_log_range = (int)floor( log10( range ) );
+    double step = 1.0;
+    if (int_log_range > 0)
+    {
+        for (int i = 0; i < int_log_range; i++)
+           step *= 10; 
+    }
+    if (int_log_range < 0)
+    {
+        for (int i = 0; i < -int_log_range; i++)
+           step /= 10; 
+    }
+    double lower = ceil(start / step) * step;
+    double upper = floor(end / step) * step;
+    
+    // if too few values, shrink size
+    if ((range/step) < 4)
+    {
+        step /= 2;
+        if (lower-step > start) lower -= step;
+        if (upper+step < end) upper += step;
+    }
+    
+    // if still too few, again
+    if ((range/step) < 4)
+    {
+        step /= 2;
+        if (lower-step > start) lower -= step;
+        if (upper+step < end) upper += step;
+    }
+
+    dc.SetPen( *wxBLACK_PEN );
+    
+    double current = lower;
+    while (current < upper+(step/2))
+    {
+        int y = (int)((curve->GetEndY()-current) / range * (double)client_height) - 1;
+        y -= curve->GetOffsetY();
+        if ((y > 10) && (y < client_height-7))
+        {
+            dc.DrawLine( client_width-15, y, client_width-7, y );
+            wxString label;
+            if (range < 50)
+            {
+                label.Printf( wxT("%f"), current );
+                while (label.Last() == wxT('0')) 
+                    label.RemoveLast();
+                if ((label.Last() == wxT('.')) || (label.Last() == wxT(',')))
+                    label.Append( wxT('0') );
+            }
+            else
+                label.Printf( wxT("%d"), (int)floor(current) );
+            dc.DrawText( label, 5, y-7 );
+        }
+
+        current += step;
+    }
+    
+    dc.DrawLine( client_width-15, 6, client_width-15, client_height );
+    dc.DrawLine( client_width-15, 2, client_width-20, 8 );
+    dc.DrawLine( client_width-15, 2, client_width-10, 8 );
+}
+
+//-----------------------------------------------------------------------------
+// wxPlotWindow
+//-----------------------------------------------------------------------------
+
+#define  ID_ENLARGE       1000
+#define  ID_SHRINK        1002
+
+#define  ID_MOVE_UP       1006
+#define  ID_MOVE_DOWN     1007
+
+#define  ID_ZOOM_IN       1010
+#define  ID_ZOOM_OUT      1011
+
+
+IMPLEMENT_DYNAMIC_CLASS(wxPlotWindow, wxScrolledWindow)
+
+BEGIN_EVENT_TABLE(wxPlotWindow, wxScrolledWindow)
+  EVT_BUTTON(  ID_MOVE_UP,     wxPlotWindow::OnMoveUp)
+  EVT_BUTTON(  ID_MOVE_DOWN,   wxPlotWindow::OnMoveDown)
+  
+  EVT_BUTTON(  ID_ENLARGE,  wxPlotWindow::OnEnlarge)
+  EVT_BUTTON(  ID_SHRINK,   wxPlotWindow::OnShrink)
+  
+  EVT_BUTTON(  ID_ZOOM_IN,     wxPlotWindow::OnZoomIn)
+  EVT_BUTTON(  ID_ZOOM_OUT,    wxPlotWindow::OnZoomOut)
+  
+  EVT_SCROLLWIN( wxPlotWindow::OnScroll2)
+END_EVENT_TABLE()
+
+wxPlotWindow::wxPlotWindow( wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, int flag )
+        : wxScrolledWindow( parent, id, pos, size, flag, "plotcanvas" )
+{
+    m_xUnitsPerValue = 1.0;
+    m_xZoom = 1.0;
+    
+    m_enlargeAroundWindowCentre = FALSE;
+    m_scrollOnThumbRelease = FALSE;
+
+    m_area = new wxPlotArea( this );
+    wxBoxSizer *mainsizer = new wxBoxSizer( wxHORIZONTAL );
+    
+    if ((GetWindowStyleFlag() & wxPLOT_BUTTON_ALL) != 0)
+    {
+        wxBoxSizer *buttonlist = new wxBoxSizer( wxVERTICAL );
+        if ((GetWindowStyleFlag() & wxPLOT_BUTTON_ENLARGE) != 0)
+        {
+            buttonlist->Add( new wxBitmapButton( this, ID_ENLARGE, *GetEnlargeBitmap() ), 0, wxEXPAND|wxALL, 2 );
+            buttonlist->Add( new wxBitmapButton( this, ID_SHRINK, *GetShrinkBitmap() ), 0, wxEXPAND|wxALL, 2 );
+            buttonlist->Add( 20,10, 0 );
+        }
+        if ((GetWindowStyleFlag() & wxPLOT_BUTTON_MOVE) != 0)
+        {
+            buttonlist->Add( new wxBitmapButton( this, ID_MOVE_UP, *GetUpBitmap() ), 0, wxEXPAND|wxALL, 2 );
+            buttonlist->Add( new wxBitmapButton( this, ID_MOVE_DOWN, *GetDownBitmap() ), 0, wxEXPAND|wxALL, 2 );
+            buttonlist->Add( 20,10, 0 );
+        }
+        if ((GetWindowStyleFlag() & wxPLOT_BUTTON_ZOOM) != 0)
+        {
+            buttonlist->Add( new wxBitmapButton( this, ID_ZOOM_IN, *GetZoomInBitmap() ), 0, wxEXPAND|wxALL, 2 );
+            buttonlist->Add( new wxBitmapButton( this, ID_ZOOM_OUT, *GetZoomOutBitmap() ), 0, wxEXPAND|wxALL, 2 );
+        }
+        mainsizer->Add( buttonlist, 0, wxEXPAND|wxALL, 4 );
+    }
+    
+    wxBoxSizer *plotsizer = new wxBoxSizer( wxHORIZONTAL );
+    
+    if ((GetWindowStyleFlag() & wxPLOT_Y_AXIS) != 0)
+    {
+        m_yaxis = new wxPlotYAxisArea( this );
+    
+        wxBoxSizer *vert1 = new wxBoxSizer( wxVERTICAL );
+        plotsizer->Add( vert1, 0, wxEXPAND );
+        vert1->Add( m_yaxis, 1 );
+        if ((GetWindowStyleFlag() & wxPLOT_X_AXIS) != 0)
+            vert1->Add( 60, 40 );
+    }
+    else
+    {
+        m_yaxis = (wxPlotYAxisArea*) NULL;
+    }
+    
+    if ((GetWindowStyleFlag() & wxPLOT_X_AXIS) != 0)
+    {
+        m_xaxis = new wxPlotXAxisArea( this );
+    
+        wxBoxSizer *vert2 = new wxBoxSizer( wxVERTICAL );
+        plotsizer->Add( vert2, 1, wxEXPAND );
+        vert2->Add( m_area, 1, wxEXPAND );
+        vert2->Add( m_xaxis, 0, wxEXPAND );
+    }
+    else
+    {
+        plotsizer->Add( m_area, 1, wxEXPAND );
+        m_xaxis = (wxPlotXAxisArea*) NULL;
+    }
+
+    mainsizer->Add( plotsizer, 1, wxEXPAND );    
+    
+    SetAutoLayout( TRUE );
+    SetSizer( mainsizer );
+
+    SetTargetWindow( m_area );
+
+    SetBackgroundColour( *wxWHITE );
+    
+    m_current = (wxPlotCurve*) NULL;
+}
+
+wxPlotWindow::~wxPlotWindow()
+{
+}
+
+void wxPlotWindow::Add( wxPlotCurve *curve )
+{
+    m_curves.Append( curve );
+    if (!m_current) m_current = curve;
+    
+    ResetScrollbar();
+}
+
+size_t wxPlotWindow::GetCount()
+{
+    return m_curves.GetCount();
+}
+
+wxPlotCurve *wxPlotWindow::GetAt( size_t n )
+{
+    wxNode *node = m_curves.Nth( n );
+    if (!node)
+        return (wxPlotCurve*) NULL;
+        
+    return (wxPlotCurve*) node->Data();
+}
+
+void wxPlotWindow::SetCurrent( wxPlotCurve* current )
+{
+    m_current = current;
+    m_area->Refresh( FALSE );
+    
+    RedrawYAxis();
+    
+    wxPlotEvent event( wxEVT_PLOT_SEL_CHANGED, GetId() );
+    event.SetEventObject( this );
+    event.SetZoom( GetZoom() );
+    event.SetCurve( m_current );
+    GetEventHandler()->ProcessEvent( event );
+}
+
+void wxPlotWindow::Delete( wxPlotCurve* curve )
+{
+    wxNode *node = m_curves.Find( curve );
+    if (!node) return;
+    
+    m_curves.DeleteObject( curve );
+    
+    m_area->DeleteCurve( curve );
+    m_area->Refresh( FALSE );
+}
+
+wxPlotCurve *wxPlotWindow::GetCurrent()
+{
+    return m_current;
+}
+
+void wxPlotWindow::Add( wxPlotOnOffCurve *curve )
+{
+    m_onOffCurves.Append( curve );
+}
+
+void wxPlotWindow::Delete( wxPlotOnOffCurve* curve )
+{
+    wxNode *node = m_onOffCurves.Find( curve );
+    if (!node) return;
+    
+    m_onOffCurves.DeleteObject( curve );
+}
+
+size_t wxPlotWindow::GetOnOffCurveCount()
+{
+    return m_onOffCurves.GetCount();
+}
+
+wxPlotOnOffCurve *wxPlotWindow::GetOnOffCurveAt( size_t n )
+{
+    wxNode *node = m_onOffCurves.Nth( n );
+    if (!node)
+        return (wxPlotOnOffCurve*) NULL;
+        
+    return (wxPlotOnOffCurve*) node->Data();
+}
+
+void wxPlotWindow::Move( wxPlotCurve* curve, int pixels_up )
+{
+    m_area->DeleteCurve( curve );
+    
+    curve->SetOffsetY( curve->GetOffsetY() + pixels_up );
+    
+    m_area->Refresh( FALSE );
+    
+    RedrawYAxis();
+}
+
+void wxPlotWindow::OnMoveUp( wxCommandEvent& WXUNUSED(event) )
+{
+    if (!m_current) return;
+    
+    Move( m_current, 25 );
+}
+
+void wxPlotWindow::OnMoveDown( wxCommandEvent& WXUNUSED(event) )
+{
+    if (!m_current) return;
+    
+    Move( m_current, -25 );
+}
+
+void wxPlotWindow::Enlarge( wxPlotCurve *curve, double factor )
+{
+    m_area->DeleteCurve( curve );
+    
+    int client_width;
+    int client_height;
+    m_area->GetClientSize( &client_width, &client_height);
+    double offset = (double)curve->GetOffsetY() / (double)client_height;
+    
+    double range = curve->GetEndY() - curve->GetStartY();
+    offset *= range;
+    
+    double new_range = range / factor;
+    double new_offset = offset / factor;
+    
+    if (m_enlargeAroundWindowCentre)
+    {
+        double middle = curve->GetStartY() - offset + range/2;
+    
+        curve->SetStartY( middle - new_range / 2 + new_offset );
+        curve->SetEndY( middle + new_range / 2 + new_offset  );
+    }
+    else
+    {
+        curve->SetStartY( (curve->GetStartY() - offset)/factor + new_offset );
+        curve->SetEndY( (curve->GetEndY() - offset)/factor + new_offset );
+    }
+    
+    m_area->Refresh( FALSE );
+    RedrawYAxis();
+}
+
+void wxPlotWindow::SetUnitsPerValue( double upv )
+{
+    m_xUnitsPerValue = upv;
+    
+    RedrawXAxis();
+}
+
+void wxPlotWindow::SetZoom( double zoom )
+{
+    double old_zoom = m_xZoom;
+    m_xZoom = zoom;
+    
+    int view_x = 0;
+    int view_y = 0;
+    GetViewStart( &view_x, &view_y );
+    
+    wxInt32 max = 0;
+    wxNode *node = m_curves.First();
+    while (node)
+    {
+        wxPlotCurve *curve = (wxPlotCurve*) node->Data();
+        if (curve->GetEndX() > max)
+            max = curve->GetEndX();
+        node = node->Next();
+    }
+    SetScrollbars( wxPLOT_SCROLL_STEP, wxPLOT_SCROLL_STEP, 
+                   (int)((max*m_xZoom)/wxPLOT_SCROLL_STEP)+1, 0, 
+                   (int)(view_x*zoom/old_zoom), 0, 
+                   TRUE );
+
+    RedrawXAxis();
+    m_area->Refresh( TRUE );
+}
+
+void wxPlotWindow::ResetScrollbar()
+{
+    wxInt32 max = 0;
+    wxNode *node = m_curves.First();
+    while (node)
+    {
+        wxPlotCurve *curve = (wxPlotCurve*) node->Data();
+        if (curve->GetEndX() > max)
+            max = curve->GetEndX();
+        node = node->Next();
+    }
+    
+    SetScrollbars( wxPLOT_SCROLL_STEP, wxPLOT_SCROLL_STEP, 
+                   (int)(((max*m_xZoom)/wxPLOT_SCROLL_STEP)+1), 0 );
+}
+
+void wxPlotWindow::RedrawXAxis()
+{
+    if (m_xaxis)
+        m_xaxis->Refresh( FALSE );
+}
+
+void wxPlotWindow::RedrawYAxis()
+{
+    if (m_yaxis)
+       m_yaxis->Refresh( TRUE );
+}
+
+void wxPlotWindow::RedrawEverything()
+{
+    if (m_xaxis)
+        m_xaxis->Refresh( TRUE );
+    if (m_yaxis)
+        m_yaxis->Refresh( TRUE );
+    m_area->Refresh( TRUE );
+}
+
+void wxPlotWindow::OnZoomIn( wxCommandEvent& WXUNUSED(event) )
+{
+    SetZoom( m_xZoom * 1.5 );
+}
+
+void wxPlotWindow::OnZoomOut( wxCommandEvent& WXUNUSED(event) )
+{
+    SetZoom( m_xZoom * 0.6666 );
+}
+
+void wxPlotWindow::OnEnlarge( wxCommandEvent& WXUNUSED(event) )
+{
+    if (!m_current) return;
+    
+    Enlarge( m_current, 1.5 );
+}
+
+void wxPlotWindow::OnShrink( wxCommandEvent& WXUNUSED(event) )
+{
+    if (!m_current) return;
+    
+    Enlarge( m_current, 0.6666666 );
+}
+
+void wxPlotWindow::OnScroll2( wxScrollWinEvent& event )
+{
+    if ((!m_scrollOnThumbRelease) || (event.GetEventType() != wxEVT_SCROLLWIN_THUMBTRACK))
+    {
+        wxScrolledWindow::OnScroll( event );
+        RedrawXAxis();
+    }
+}
+
+// ----------------------------------------------------------------------------
+// global functions
+// ----------------------------------------------------------------------------
+
+// FIXME MT-UNSAFE
+static wxBitmap *GetEnlargeBitmap()
+{
+    static wxBitmap* s_bitmap = (wxBitmap *) NULL;
+    static bool s_loaded = FALSE;
+
+    if ( !s_loaded )
+    {
+        s_loaded = TRUE; // set it to TRUE anyhow, we won't try again
+
+        #if defined(__WXMSW__) || defined(__WXPM__)
+            s_bitmap = new wxBitmap("plot_enl_bmp", wxBITMAP_TYPE_RESOURCE);
+        #else
+            s_bitmap = new wxBitmap( plot_enl_xpm );
+        #endif
+    }
+
+    return s_bitmap;
+}
+
+static wxBitmap *GetShrinkBitmap()
+{
+    static wxBitmap* s_bitmap = (wxBitmap *) NULL;
+    static bool s_loaded = FALSE;
+
+    if ( !s_loaded )
+    {
+        s_loaded = TRUE; // set it to TRUE anyhow, we won't try again
+
+        #if defined(__WXMSW__) || defined(__WXPM__)
+            s_bitmap = new wxBitmap("plot_shr_bmp", wxBITMAP_TYPE_RESOURCE);
+        #else
+            s_bitmap = new wxBitmap( plot_shr_xpm );
+        #endif
+    }
+
+    return s_bitmap;
+}
+
+static wxBitmap *GetZoomInBitmap()
+{
+    static wxBitmap* s_bitmap = (wxBitmap *) NULL;
+    static bool s_loaded = FALSE;
+
+    if ( !s_loaded )
+    {
+        s_loaded = TRUE; // set it to TRUE anyhow, we won't try again
+
+        #if defined(__WXMSW__) || defined(__WXPM__)
+            s_bitmap = new wxBitmap("plot_zin_bmp", wxBITMAP_TYPE_RESOURCE);
+        #else
+            s_bitmap = new wxBitmap( plot_zin_xpm );
+        #endif
+    }
+
+    return s_bitmap;
+}
+
+static wxBitmap *GetZoomOutBitmap()
+{
+    static wxBitmap* s_bitmap = (wxBitmap *) NULL;
+    static bool s_loaded = FALSE;
+
+    if ( !s_loaded )
+    {
+        s_loaded = TRUE; // set it to TRUE anyhow, we won't try again
+
+        #if defined(__WXMSW__) || defined(__WXPM__)
+            s_bitmap = new wxBitmap("plot_zot_bmp", wxBITMAP_TYPE_RESOURCE);
+        #else
+            s_bitmap = new wxBitmap( plot_zot_xpm );
+        #endif
+    }
+
+    return s_bitmap;
+}
+
+static wxBitmap *GetUpBitmap()
+{
+    static wxBitmap* s_bitmap = (wxBitmap *) NULL;
+    static bool s_loaded = FALSE;
+
+    if ( !s_loaded )
+    {
+        s_loaded = TRUE; // set it to TRUE anyhow, we won't try again
+
+        #if defined(__WXMSW__) || defined(__WXPM__)
+            s_bitmap = new wxBitmap("plot_up_bmp", wxBITMAP_TYPE_RESOURCE);
+        #else
+            s_bitmap = new wxBitmap( plot_up_xpm );
+        #endif
+    }
+
+    return s_bitmap;
+}
+
+static wxBitmap *GetDownBitmap()
+{
+    static wxBitmap* s_bitmap = (wxBitmap *) NULL;
+    static bool s_loaded = FALSE;
+
+    if ( !s_loaded )
+    {
+        s_loaded = TRUE; // set it to TRUE anyhow, we won't try again
+
+        #if defined(__WXMSW__) || defined(__WXPM__)
+            s_bitmap = new wxBitmap("plot_dwn_bmp", wxBITMAP_TYPE_RESOURCE);
+        #else
+            s_bitmap = new wxBitmap( plot_dwn_xpm );
+        #endif
+    }
+
+    return s_bitmap;
+}
+
+
+//----------------------------------------------------------------------------
+// wxPlotModule
+//----------------------------------------------------------------------------
+
+class wxPlotModule : public wxModule
+{
+public:
+    bool OnInit();
+    void OnExit();
+
+private:
+    DECLARE_CLASS(wxPlotModule)
+};
+
+IMPLEMENT_DYNAMIC_CLASS(wxPlotModule, wxModule)
+
+bool wxPlotModule::OnInit()
+{
+    wxEVT_PLOT_SEL_CHANGING = wxNewId();
+    wxEVT_PLOT_SEL_CHANGED = wxNewId();
+    wxEVT_PLOT_CLICKED = wxNewId();
+    wxEVT_PLOT_DOUBLECLICKED = wxNewId();
+    wxEVT_PLOT_ZOOM_IN = wxNewId();
+    wxEVT_PLOT_ZOOM_OUT = wxNewId();
+    wxEVT_PLOT_VALUE_SEL_CREATING = wxNewId();
+    wxEVT_PLOT_VALUE_SEL_CREATED = wxNewId();
+    wxEVT_PLOT_VALUE_SEL_CHANGING = wxNewId();
+    wxEVT_PLOT_VALUE_SEL_CHANGED = wxNewId();
+    wxEVT_PLOT_AREA_SEL_CREATING = wxNewId();
+    wxEVT_PLOT_AREA_SEL_CREATED = wxNewId();
+    wxEVT_PLOT_AREA_SEL_CHANGING = wxNewId();
+    wxEVT_PLOT_AREA_SEL_CHANGED = wxNewId();
+    wxEVT_PLOT_BEGIN_X_LABEL_EDIT = wxNewId();
+    wxEVT_PLOT_END_X_LABEL_EDIT = wxNewId();
+    wxEVT_PLOT_BEGIN_Y_LABEL_EDIT = wxNewId();
+    wxEVT_PLOT_END_Y_LABEL_EDIT = wxNewId();
+    wxEVT_PLOT_BEGIN_TITLE_EDIT = wxNewId();
+    wxEVT_PLOT_END_TITLE_EDIT = wxNewId();
+    wxEVT_PLOT_AREA_CREATE = wxNewId();
+    
+    return TRUE;
+}
+
+void wxPlotModule::OnExit()
+{
+}
+
+
-- 
2.50.0

