]> git.saurik.com Git - wxWidgets.git/blobdiff - contrib/include/wx/canvas/canvas.h
make wxArtProvider pure virtual (I was not so on
[wxWidgets.git] / contrib / include / wx / canvas / canvas.h
index f1255760b3d0c36027a102c77eb0a292dda0e322..37d900ded1a15fdca06e627d27a7d316dcfa4e90 100644 (file)
 #include "wx/image.h"
 #include "wx/txtstrm.h"
 #include "wx/geometry.h"
 #include "wx/image.h"
 #include "wx/txtstrm.h"
 #include "wx/geometry.h"
+#include "wx/matrix.h"
+#include "bbox.h"
 
 
 //----------------------------------------------------------------------------
 // decls
 //----------------------------------------------------------------------------
 
 
 
 //----------------------------------------------------------------------------
 // decls
 //----------------------------------------------------------------------------
 
-#define IMAGE_CANVAS 0
-
 class wxCanvas;
 class wxCanvas;
+class wxCanvasAdmin;
 
 //----------------------------------------------------------------------------
 // wxCanvasObject
 //----------------------------------------------------------------------------
 
 //----------------------------------------------------------------------------
 // wxCanvasObject
 //----------------------------------------------------------------------------
+enum wxDRAG_MODE
+{
+    wxDRAG_RECTANGLE,
+    wxDRAG_ONTOP,
+    wxDRAG_REDRAW
+};
 
 
+//:defenition
+// wxCanvasObject is the base class for  Canvas Objects.
+// All Objects for drawing one the canvas are derived from this class.
+// It supports dragging and moving methods that can be used in derived
+// classes for defining several ways of dragging.
+// Also it is possible to plug in events handlers to do this for all derived classes at once.
+//
+// wxCanvasObjects have themselves as their event handlers by default,
+// but their event handlers could be set to another object entirely. This
+// separation can reduce the amount of derivation required, and allow
+// alteration of a  wxCanvasObject functionality
 class wxCanvasObject: public wxEvtHandler
 {
 class wxCanvasObject: public wxEvtHandler
 {
+    DECLARE_CLASS(wxCanvasObject)
 public:
 public:
-    wxCanvasObject();
-
-    // Area occupied by object. Used for clipping, intersection,
-    // mouse enter etc. Screen coordinates
-    void SetArea( int x, int y, int width, int height );
-    void SetArea( wxRect rect );
-
-    // These are for screen output only therefore use
-    // int as coordinates.
-    virtual bool IsHit( int x, int y, int margin = 0 );
-    virtual void Render(int xabs, int yabs, int clip_x, int clip_y, int clip_width, int clip_height );
-
-    // use doubles later
-    virtual void Move( int x, int y );
 
 
-    // Once we have world coordinates in doubles, this will get
-    // called for every object if the world coordinate system
-    // changes (zooming).
-    virtual void Recreate();
+    wxCanvasObject();
 
 
-    // Later...
+    //If the position (x,y) is within the object this return a pointer to the object
+    //Normally this function needs to be defined for each derived wxCanvasObject.
+    //The default is a simple bounding box test.
+    virtual wxCanvasObject* IsHitWorld( double x, double y, double margin = 0 );
+
+    //render this object to the canvas (either on its buffer or directly on the canvas)
+    //this depends on the wxDC that is set for the active canvas.
+    virtual void Render(wxTransformMatrix* cworld, int clip_x, int clip_y, int clip_width, int clip_height );
+
+    //x position in world coordinates of the object
+    virtual double  GetPosX()=0;
+    //y position in world coordinates of the object
+    virtual double  GetPosY()=0;
+
+    //set position in world coordinates for the object
+    virtual void  SetPosXY( double x, double y)=0;
+
+    //absolute moving the object to position x,y in world coordinates
+    //also does an update of the old and new area
+    virtual void MoveAbsolute( double x, double y );
+
+    //relative moving the object to position x,y in world coordinates
+    //also does an update of the old and new area
+    virtual void MoveRelative( double x, double y );
+
+    //relative translate the object to position x,y in world coordinates
+    //does NOT update the old and new area
+    //this function must be defined for each derived object,
+    //it is used internally for dragging and moving objects.
+    virtual void TransLate( double x, double y )=0;
+
+    //choose one of the three diffrenet drag methods |
+    //DRAG_RECTANGLE = as a rectangle when drag is in progress |
+    //DRAG_ONTOP = only redraw the object when dragging |
+    //DRAG_REDRAW = redraw the damaged areas when dragging
+    void SetDragMode(wxDRAG_MODE mode) { m_dragmode=mode; };
+
+    //return the dragmode
+    wxDRAG_MODE GetDragMode() { return m_dragmode; };
+
+    //called when starting a drag
+    virtual void DragStart();
+    //called when dragging is in progress
+    virtual void DragRelative( double x, double y);
+    //called when dragging is ended
+    virtual void DragEnd();
+
+    //return the object if it is part of the given object or
+    //if the given object is part of a group within this object.
+    //For group objects this means recursively search for it.
+    virtual wxCanvasObject* Contains( wxCanvasObject* obj );
+
+    //calculate the boundingbox in world coordinates
+    virtual void CalcBoundingBox()=0;
+
+    //write the object as SVG (scalable vector grafhics
     virtual void WriteSVG( wxTextOutputStream &stream );
 
     virtual void WriteSVG( wxTextOutputStream &stream );
 
-    wxCanvas *GetOwner()              { return m_owner; }
-    virtual void SetOwner( wxCanvas *owner )  { m_owner = owner; }
+    //get the administrator for the object,
+    //this will give access to the canvas's where it is displayed upon.
+    //It is used to render the object to the active canvas.
+    //Conversion from world to Device coordinates and visa versa is
+    //done using the Active canvas at that moment.
+    wxCanvasAdmin *GetAdmin()              { return m_admin; }
+
+    //set the administrator
+    virtual void SetAdmin( wxCanvasAdmin *admin )  { m_admin = admin; }
 
 
+    //is this a control type of canvas object
     bool        IsControl()     { return m_isControl; }
     bool        IsControl()     { return m_isControl; }
+    //is this a vector type of canvas object
     bool        IsVector()      { return m_isVector; }
     bool        IsVector()      { return m_isVector; }
+    //is this an Image type of canvas object
     bool        IsImage()       { return m_isImage; }
     bool        IsImage()       { return m_isImage; }
-    inline int  GetX()          { return m_area.x; }
-    inline int  GetY()          { return m_area.y; }
-    inline int  GetWidth()      { return m_area.width; }
-    inline int  GetHeight()     { return m_area.height; }
 
 
+    //get minimum X of the boundingbox in world coordinates
+    inline double  GetXMin()     { return m_bbox.GetMinX(); }
+    //get minimum Y of the boundingbox in world coordinates
+    inline double  GetYMin()     { return m_bbox.GetMinY(); }
+    //get maximum X of the boundingbox in world coordinates
+    inline double  GetXMax()     { return m_bbox.GetMaxX(); }
+    //get maximum Y of the boundingbox in world coordinates
+    inline double  GetYMax()     { return m_bbox.GetMaxY(); }
+
+    //get boundingbox
+    inline wxBoundingBox GetBbox() { return m_bbox; }
+
+    //redirect all mouse events for the canvas to this object
     void CaptureMouse();
     void CaptureMouse();
+    //release the mouse capture for this object
     void ReleaseMouse();
     void ReleaseMouse();
+    //is the mouse captured for this object
     bool IsCapturedMouse();
 
     bool IsCapturedMouse();
 
+    //set if this object will visible (be rendered or not)
+    inline void SetVisible(bool visible) { m_visible=visible; }
+    //get visibility
+    inline bool GetVisible() {return m_visible; }
+
+    //can the object be dragged
+    inline void SetDraggable(bool drag) { m_dragable=drag; }
+    //get if the object can be dragged
+    inline bool GetDraggable() {return m_dragable; }
+
+    //get absolute area in the device coordinates where the object
+    //its boundingbox in world coordinates is first translated using the matrix.
+    wxRect GetAbsoluteArea(const wxTransformMatrix& cworld);
+
+    //get currently used eventhandler (always the first in the list)
+    wxEvtHandler *GetEventHandler() const { return m_eventHandler; }
+
+    //process an event for the object, starting with the first eventhandler
+    // in the list.
+    bool ProcessCanvasObjectEvent(wxEvent& event);
+
+    // push/pop event handler: allows to chain a custom event handler to
+    // already existing ones
+    void PushEventHandler( wxEvtHandler *handler );
+
+    //remove first eventhandler in the list (one will be always stay in)
+    wxEvtHandler *PopEventHandler( bool deleteHandler = FALSE );
+    //append an eventhandler to the list, this event handler will be called
+    //if the other skipped the event to process.
+    void AppendEventHandler(wxEvtHandler *handler);
+    //remove last event handler in the list (one will always stay in)
+    wxEvtHandler *RemoveLastEventHandler(bool deleteHandler);
+
 protected:
 protected:
-    wxCanvas   *m_owner;
-    bool        m_isControl;
-    bool        m_isVector;
-    bool        m_isImage;
 
 
-    //relative boundingbox in parent in pixels
-    wxRect      m_area;
+    //administator for rendering and accessing the canvas's
+    wxCanvasAdmin* m_admin;
 
 
-    friend class wxCanvas;
-};
+    //active event handler, default the object itself
+    wxEvtHandler* m_eventHandler;
 
 
-//----------------------------------------------------------------------------
-// wxCanvasObjectGroup
-//----------------------------------------------------------------------------
+    bool m_isControl:1;
+    bool m_isVector:1;
+    bool m_isImage:1;
+    bool m_visible:1;
+    bool m_dragable:1;
+    wxDRAG_MODE m_dragmode:3;
+
+    //boundingbox in world coordinates
+    wxBoundingBox m_bbox;
+
+    //used for dragging
+    wxBitmap m_atnewpos;
+};
 
 
-class wxCanvasObjectGroup
+//:defenition
+// wxCanvasObjectGroup is a container for wxCanvas derived Objects.
+// It renders itself by calling the render methods of the wxCanvasObjects it contains.
+// It can have nested groups also, in the same way as the other wxCanvasObjects it already contains.
+// The group has a matrix to position/rotate/scale the group.
+class wxCanvasObjectGroup: public wxCanvasObject
 {
 {
+    DECLARE_CLASS(wxCanvasObjectGroup)
 public:
 public:
-    wxCanvasObjectGroup();
+    wxCanvasObjectGroup(double x, double y);
     virtual ~wxCanvasObjectGroup();
 
     virtual ~wxCanvasObjectGroup();
 
-    void SetOwner(wxCanvas* canvas);
-    wxCanvas *GetOwner()              { return m_owner; }
+    void SetAdmin(wxCanvasAdmin* admin);
 
 
+    //prepend a wxCanvasObject to this group
     virtual void Prepend( wxCanvasObject* obj );
     virtual void Prepend( wxCanvasObject* obj );
+    //append a wxCanvasObject to this group
     virtual void Append( wxCanvasObject* obj );
     virtual void Append( wxCanvasObject* obj );
+    //insert a wxCanvasObject to this group
     virtual void Insert( size_t before, wxCanvasObject* obj );
     virtual void Insert( size_t before, wxCanvasObject* obj );
+    //remove the given object from the group
     virtual void Remove( wxCanvasObject* obj );
 
     virtual void Remove( wxCanvasObject* obj );
 
-    virtual void Recreate();
-            void DeleteContents( bool );
-    virtual void Render(int xabs, int yabs,int x, int y, int width, int height );
-    virtual void WriteSVG( wxTextOutputStream &stream );
-    virtual bool IsHit( int x, int y, int margin );
-    virtual wxCanvasObject* IsHitObject( int x, int y, int margin );
+    //those this group contain the given object.
+    //in case of nested groups also search in there to the lowwest level.
+    virtual wxCanvasObject* Contains( wxCanvasObject* obj );
+
+    //returns index of the given wxCanvasObject in this group
+    virtual int IndexOf( wxCanvasObject* obj );
 
 
-    void ExtendArea(double x, double y);
+    double  GetPosX() { return lworld.GetValue(2,0); }
+    double  GetPosY() { return lworld.GetValue(2,1); }
+    void    SetPosXY( double x, double y) {lworld.SetValue(2,0,x);lworld.SetValue(2,1,y);CalcBoundingBox();};
 
 
-    inline double  GetXMin()     { return m_minx; }
-    inline double  GetYMin()     { return m_miny; }
-    inline double  GetXMax()     { return m_maxx; }
-    inline double  GetYMax()     { return m_maxy; }
+    void TransLate( double x, double y );
+
+    void CalcBoundingBox();
+    //remove all wxCanvasObjects from the group (flag for deletion of the objectsalso)
+    void DeleteContents( bool );
+    virtual void Render(wxTransformMatrix* cworld,int x, int y, int width, int height );
+    virtual void WriteSVG( wxTextOutputStream &stream );
+
+    //recursive call the IsHitWorld on all contained objects, the first
+    //one that is hit will be returned
+    wxCanvasObject* IsHitWorld( double x, double y, double margin = 0 );
+
+    //recursive calls for contained objects to set eventhandlers,
+    //and also sets its own eventhandler
+    void PushEventHandler( wxEvtHandler *handler );
+    //recursive calls for contained objects to set eventhandlers,
+    //and also sets its own eventhandler
+    wxEvtHandler *PopEventHandler( bool deleteHandler = FALSE );
+    //recursive calls for contained objects to set eventhandlers,
+    //and also sets its own eventhandler
+    void AppendEventHandler(wxEvtHandler *handler);
+    //recursive calls for contained objects to set eventhandlers,
+    //and also sets its own eventhandler
+    wxEvtHandler *RemoveLastEventHandler(bool deleteHandler);
 
 protected:
 
 protected:
-    wxCanvas   *m_owner;
 
 
-    //bounding box
-    double        m_minx;
-    double        m_miny;
-    double        m_maxx;
-    double        m_maxy;
-    bool          m_validbounds;
+    //to position the object
+    wxTransformMatrix lworld;
 
     wxList        m_objects;
 
     friend class wxCanvas;
 };
 
 
     wxList        m_objects;
 
     friend class wxCanvas;
 };
 
-//----------------------------------------------------------------------------
-// wxCanvasObjectGroupRef
-//----------------------------------------------------------------------------
-
-class wxCanvasObjectGroupRef: public wxCanvasObject
+//:defenition
+// wxCanvasObjectRef is a reference to any wxCanvasObject derived class.
+// It does not duplicate the referenced object.
+// It has a matrix to reposition/rotate/scale the object it references.
+// The position/matrix of the referenced Object is accumulated with the one here.
+class wxCanvasObjectRef: public wxCanvasObject
 {
 {
+    DECLARE_CLASS(wxCanvasObjectRef)
 public:
 public:
-    wxCanvasObjectGroupRef(double x, double y,wxCanvasObjectGroup* group);
+    wxCanvasObjectRef(double x, double y,wxCanvasObject* obj);
 
 
-    void SetOwner(wxCanvas* canvas);
+    //set rotation for the reference
+    void SetRotation(double rotation);
 
 
-    virtual void Recreate();
-    virtual void Render(int xabs, int yabs,int x, int y, int width, int height );
-    virtual void WriteSVG( wxTextOutputStream &stream );
-    virtual bool IsHit( int x, int y, int margin );
-    void Move( int x, int y );
+    //set scale in x and y ( > zero)
+    void SetScale( double scalex, double scaley );
 
 
-    inline double  GetPosX()          { return m_x; }
-    inline double  GetPosY()          { return m_y; }
+    void SetAdmin(wxCanvasAdmin* admin);
 
 
-    void ExtendArea(double x, double y);
-    virtual wxCanvasObject* IsHitObject( int x, int y, int margin );
+    double  GetPosX() { return lworld.GetValue(2,0); }
+    double  GetPosY() { return lworld.GetValue(2,1); }
+    void    SetPosXY( double x, double y) {lworld.SetValue(2,0,x);lworld.SetValue(2,1,y);CalcBoundingBox();};
 
 
-protected:
-    //position of the group
-    double        m_x;
-    double        m_y;
+    void TransLate( double x, double y );
+    void CalcBoundingBox();
+    virtual void Render(wxTransformMatrix* cworld,int x, int y, int width, int height );
+    virtual void WriteSVG( wxTextOutputStream &stream );
 
 
-    //reference to the group
-    wxCanvasObjectGroup*        m_group;
+    //return this object if one of the objects it references is hit
+    wxCanvasObject* IsHitWorld( double x, double y, double margin = 0 );
+    virtual wxCanvasObject* Contains( wxCanvasObject* obj );
+
+    //recursive calls for contained objects to set eventhandlers,
+    //and also sets its own eventhandler
+    void PushEventHandler( wxEvtHandler *handler );
+    //recursive calls for contained objects to set eventhandlers,
+    //and also sets its own eventhandler
+    wxEvtHandler *PopEventHandler( bool deleteHandler = FALSE );
+    //recursive calls for contained objects to set eventhandlers,
+    //and also sets its own eventhandler
+    void AppendEventHandler(wxEvtHandler *handler);
+    //recursive calls for contained objects to set eventhandlers,
+    //and also sets its own eventhandler
+    wxEvtHandler *RemoveLastEventHandler(bool deleteHandler);
 
 
-    //bounding box
-    double        m_minx;
-    double        m_miny;
-    double        m_maxx;
-    double        m_maxy;
-    bool          m_validbounds;
+protected:
 
 
-};
+    //to position the object
+    wxTransformMatrix lworld;
 
 
-//----------------------------------------------------------------------------
-// wxCanvasPolygon
-//----------------------------------------------------------------------------
+    //reference to another wxCanvasObject
+    wxCanvasObject* m_obj;
+};
 
 
-class wxCanvasPolygon: public wxCanvasObject
+//:defenition
+// wxCanvasRect
+class wxCanvasRect: public wxCanvasObject
 {
 {
+    DECLARE_CLASS(wxCanvasRect)
 public:
 public:
-    wxCanvasPolygon( int n, wxPoint2DDouble points[] );
-    ~wxCanvasPolygon();
-    void SetBrush(wxBrush& brush)  { m_brush = brush; };
-    void SetPen(wxPen& pen)        { m_pen = pen; };
+    wxCanvasRect( double x, double y, double w, double h , double radius=0 );
+    void SetBrush( const wxBrush& brush)  { m_brush = brush; };
+    void SetPen( const wxPen& pen)        { m_pen = pen; CalcBoundingBox(); };
+
+    double  GetPosX() { return m_x; }
+    double  GetPosY() { return m_y; }
+    void    SetPosXY( double x, double y) {m_x=x; m_y=y; CalcBoundingBox();};
 
 
-    virtual void Recreate();
+    void TransLate( double x, double y );
+    void CalcBoundingBox();
 
 
-    virtual void Render(int xabs, int yabs, int clip_x, int clip_y, int clip_width, int clip_height );
+    virtual void Render(wxTransformMatrix* cworld, int clip_x, int clip_y, int clip_width, int clip_height );
     virtual void WriteSVG( wxTextOutputStream &stream );
 
 private:
     virtual void WriteSVG( wxTextOutputStream &stream );
 
 private:
-    void ExtendArea(double x, double y);
-
-    wxBrush       m_brush;
     wxPen         m_pen;
     wxPen         m_pen;
+    wxBrush       m_brush;
 
 
-    int           m_n;
-    wxPoint2DDouble* m_points;
-
-    //bounding box
-    double        m_minx;
-    double        m_miny;
-    double        m_maxx;
-    double        m_maxy;
-    bool          m_validbounds;
-
+    double        m_x;
+    double        m_y;
+    double        m_width;
+    double        m_height;
+    double        m_radius;
 };
 
 //----------------------------------------------------------------------------
 };
 
 //----------------------------------------------------------------------------
-// wxCanvasPolyline
+// wxCanvasCircle
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
-
-class wxCanvasPolyline: public wxCanvasObject
+class wxCanvasCircle: public wxCanvasObject
 {
 public:
 {
 public:
-    wxCanvasPolyline(int n, wxPoint2DDouble points[]);
-    ~wxCanvasPolyline();
-    void SetPen(wxPen& pen)    { m_pen = pen; };
+    wxCanvasCircle( double x, double y, double radius );
+    void SetBrush( const wxBrush& brush)  { m_brush = brush; };
+    void SetPen( const wxPen& pen)        { m_pen = pen; CalcBoundingBox(); };
+
+    double  GetPosX() { return m_x; }
+    double  GetPosY() { return m_y; }
+    void    SetPosXY( double x, double y) {m_x=x; m_y=y;CalcBoundingBox(); };
 
 
-    virtual void Recreate();
+    void TransLate( double x, double y );
 
 
-    virtual void Render(int xabs, int yabs, int clip_x, int clip_y, int clip_width, int clip_height );
+    void CalcBoundingBox();
+
+    virtual void Render(wxTransformMatrix* cworld, int clip_x, int clip_y, int clip_width, int clip_height );
     virtual void WriteSVG( wxTextOutputStream &stream );
 
     virtual void WriteSVG( wxTextOutputStream &stream );
 
-private:
-    void ExtendArea(double x, double y);
+    wxCanvasObject* IsHitWorld( double x, double y, double margin = 0 );
 
 
+private:
     wxPen         m_pen;
     wxPen         m_pen;
+    wxBrush       m_brush;
 
 
-    int           m_n;
-    wxPoint2DDouble* m_points;
+    double        m_x;
+    double        m_y;
+    double        m_radius;
+};
 
 
-    //bounding box
-    double        m_minx;
-    double        m_miny;
-    double        m_maxx;
-    double        m_maxy;
-    bool          m_validbounds;
+//:defenition
+// wxCanvasEllipse
+class wxCanvasEllipse: public wxCanvasObject
+{
+public:
+    wxCanvasEllipse( double x, double y, double width, double height );
+    void SetBrush( const wxBrush& brush)  { m_brush = brush; };
+    void SetPen( const wxPen& pen)        { m_pen = pen; CalcBoundingBox(); };
 
 
-};
+    double  GetPosX() { return m_x; }
+    double  GetPosY() { return m_y; }
+    void    SetPosXY( double x, double y) {m_x=x; m_y=y; CalcBoundingBox();};
 
 
+    void TransLate( double x, double y );
 
 
+    void CalcBoundingBox();
 
 
-//----------------------------------------------------------------------------
-// wxCanvasRect
-//----------------------------------------------------------------------------
+    virtual void Render(wxTransformMatrix* cworld, int clip_x, int clip_y, int clip_width, int clip_height );
+    virtual void WriteSVG( wxTextOutputStream &stream );
 
 
-class wxCanvasRect: public wxCanvasObject
+    wxCanvasObject* IsHitWorld( double x, double y, double margin = 0 );
+
+private:
+    wxPen         m_pen;
+    wxBrush       m_brush;
+
+    double        m_x;
+    double        m_y;
+    double        m_width;
+    double        m_height;
+};
+
+//:defenition
+// wxCanvasEllipticArc
+class wxCanvasEllipticArc: public wxCanvasObject
 {
 public:
 {
 public:
-    wxCanvasRect( double x, double y, double w, double h );
-    void SetBrush(wxBrush& brush)  { m_brush = brush; };
-    void SetPen(wxPen& pen)        { m_pen = pen; };
+    wxCanvasEllipticArc( double x, double y, double width, double height, double start, double end );
+    void SetBrush( const wxBrush& brush)  { m_brush = brush; };
+    void SetPen( const wxPen& pen)        { m_pen = pen; CalcBoundingBox(); };
+
+    double  GetPosX() { return m_x; }
+    double  GetPosY() { return m_y; }
+    void    SetPosXY( double x, double y) {m_x=x; m_y=y; CalcBoundingBox();};
 
 
-    virtual void Recreate();
+    void TransLate( double x, double y );
+    void CalcBoundingBox();
 
 
-    virtual void Render(int xabs, int yabs, int clip_x, int clip_y, int clip_width, int clip_height );
+    virtual void Render(wxTransformMatrix* cworld, int clip_x, int clip_y, int clip_width, int clip_height );
     virtual void WriteSVG( wxTextOutputStream &stream );
 
     virtual void WriteSVG( wxTextOutputStream &stream );
 
+    wxCanvasObject* IsHitWorld( double x, double y, double margin = 0 );
+
 private:
     wxPen         m_pen;
     wxBrush       m_brush;
 private:
     wxPen         m_pen;
     wxBrush       m_brush;
@@ -268,23 +455,32 @@ private:
     double        m_y;
     double        m_width;
     double        m_height;
     double        m_y;
     double        m_width;
     double        m_height;
+    double        m_start;
+    double        m_end;
 };
 
 };
 
-//----------------------------------------------------------------------------
+//:defenition
 // wxCanvasLine
 // wxCanvasLine
-//----------------------------------------------------------------------------
-
 class wxCanvasLine: public wxCanvasObject
 {
 public:
     wxCanvasLine( double x1, double y1, double x2, double y2 );
 class wxCanvasLine: public wxCanvasObject
 {
 public:
     wxCanvasLine( double x1, double y1, double x2, double y2 );
-    void SetPen(wxPen& pen)    { m_pen = pen; };
+    void SetPen( const wxPen& pen)    { m_pen = pen; CalcBoundingBox(); };
 
 
-    virtual void Recreate();
 
 
-    virtual void Render(int xabs, int yabs, int clip_x, int clip_y, int clip_width, int clip_height );
+    double  GetPosX() { return m_x1; }
+    double  GetPosY() { return m_y1; }
+    void    SetPosXY( double x, double y) {m_x1=x; m_y1=y; CalcBoundingBox();};
+
+    void TransLate( double x, double y );
+
+    void CalcBoundingBox();
+
+    virtual void Render(wxTransformMatrix* cworld, int clip_x, int clip_y, int clip_width, int clip_height );
     virtual void WriteSVG( wxTextOutputStream &stream );
     virtual void WriteSVG( wxTextOutputStream &stream );
-    
+
+    wxCanvasObject* IsHitWorld( double x, double y, double margin = 0 );
+
 private:
     wxPen         m_pen;
 
 private:
     wxPen         m_pen;
 
@@ -294,32 +490,39 @@ private:
     double        m_y2;
 };
 
     double        m_y2;
 };
 
-//----------------------------------------------------------------------------
+//:defenition
 // wxCanvasImage
 // wxCanvasImage
-//----------------------------------------------------------------------------
-
 class wxCanvasImage: public wxCanvasObject
 {
 public:
     wxCanvasImage( const wxImage &image, double x, double y, double w, double h );
 class wxCanvasImage: public wxCanvasObject
 {
 public:
     wxCanvasImage( const wxImage &image, double x, double y, double w, double h );
-    
-    virtual void Recreate();
-    
-    virtual void Render(int xabs, int yabs, int clip_x, int clip_y, int clip_width, int clip_height );
+
+    double  GetPosX() { return m_x; }
+    double  GetPosY() { return m_y; }
+    void    SetPosXY( double x, double y);
+
+    void TransLate( double x, double y );
+
+    void CalcBoundingBox();
+
+    virtual void Render(wxTransformMatrix* cworld, int clip_x, int clip_y, int clip_width, int clip_height );
     virtual void WriteSVG( wxTextOutputStream &stream );
     virtual void WriteSVG( wxTextOutputStream &stream );
-    
+
 private:
     double      m_x;
     double      m_y;
     double      m_width;
     double      m_height;
 private:
     double      m_x;
     double      m_y;
     double      m_width;
     double      m_height;
-    
+
     wxImage     m_image;
     wxImage     m_image;
-#if IMAGE_CANVAS
-    wxImage     m_tmp;
-#else
-    wxBitmap    m_tmp;
-#endif
+    int         m_orgw,m_orgh;
+    
+    // cache
+    wxBitmap    m_cBitmap;
+    wxImage     m_cImage;
+    int         m_cW;
+    int         m_cH;
+    double      m_cR;
 };
 
 //----------------------------------------------------------------------------
 };
 
 //----------------------------------------------------------------------------
@@ -331,30 +534,39 @@ class wxCanvasControl: public wxCanvasObject
 public:
     wxCanvasControl( wxWindow *control );
     ~wxCanvasControl();
 public:
     wxCanvasControl( wxWindow *control );
     ~wxCanvasControl();
-    
-    virtual void Recreate();
-    
-    virtual void Move( int x, int y );
-    
+
+    double  GetPosX();
+    double  GetPosY();
+    void    SetPosXY( double x, double y);
+
+    void TransLate( double x, double y );
+    void MoveRelative( double x, double y );
+
+    void CalcBoundingBox();
+
 private:
     wxWindow     *m_control;
 };
 
 private:
     wxWindow     *m_control;
 };
 
-//----------------------------------------------------------------------------
+//:defenition
 // wxCanvasText
 // wxCanvasText
-//----------------------------------------------------------------------------
-
 class wxCanvasText: public wxCanvasObject
 {
 public:
     wxCanvasText( const wxString &text, double x, double y, const wxString &foneFile, int size );
     ~wxCanvasText();
 
 class wxCanvasText: public wxCanvasObject
 {
 public:
     wxCanvasText( const wxString &text, double x, double y, const wxString &foneFile, int size );
     ~wxCanvasText();
 
-    void Recreate();
+    double  GetPosX() { return m_x; }
+    double  GetPosY() { return m_y; }
+    void    SetPosXY( double x, double y) {m_x=x; m_y=y;CalcBoundingBox(); };
 
 
-    virtual void Render(int xabs, int yabs, int clip_x, int clip_y, int clip_width, int clip_height );
+    void TransLate( double x, double y );
+
+    void CalcBoundingBox();
+
+    virtual void Render(wxTransformMatrix* cworld, int clip_x, int clip_y, int clip_width, int clip_height );
     virtual void WriteSVG( wxTextOutputStream &stream );
     virtual void WriteSVG( wxTextOutputStream &stream );
-    
+
     void SetRGB( unsigned char red, unsigned char green, unsigned char blue );
     void SetFlag( int flag );
     int GetFlag()              { return m_flag; }
     void SetRGB( unsigned char red, unsigned char green, unsigned char blue );
     void SetFlag( int flag );
     int GetFlag()              { return m_flag; }
@@ -373,89 +585,120 @@ private:
     int             m_size;
 };
 
     int             m_size;
 };
 
-//----------------------------------------------------------------------------
-// wxCanvas
-//----------------------------------------------------------------------------
-
+//:defenition
+// wxCanvas is used to display a wxCanvasGroupObject, which contains wxCanvasObject derived
+// drawable objects. The group to draw is called the root.
+// All objects are defined in world coordinates, relative to its parent (e.g. nested groups)
+// There are methods to convert from world to device coordinates and visa versa.
+// Rendering a draw is normally started on the root, it to a buffer, afterwords
+// an update of the damaged parts will blitted from the buffer to the screen.
+// This is done in Idle time, but can also be forced.
+// World coordinates can be with the Y axis going up are down.
+// The area of the drawing in world coordinates that is visible on the canvas
+// can be set. Parts of this area can be zoomed into resulting in scroll bars
+// to be displayed.
 class wxCanvas: public wxScrolledWindow
 {
 public:
     // constructors and destructors
 class wxCanvas: public wxScrolledWindow
 {
 public:
     // constructors and destructors
-    wxCanvas( wxWindow *parent, wxWindowID id = -1,
+    wxCanvas( wxCanvasAdmin* admin ,wxWindow *parent, wxWindowID id = -1,
         const wxPoint& pos = wxDefaultPosition,
         const wxSize& size = wxDefaultSize,
         long style = wxScrolledWindowStyle );
     virtual ~wxCanvas();
 
         const wxPoint& pos = wxDefaultPosition,
         const wxSize& size = wxDefaultSize,
         long style = wxScrolledWindowStyle );
     virtual ~wxCanvas();
 
-    virtual void SetArea( int width, int height );
-    virtual void SetColour( unsigned char red, unsigned char green, unsigned char blue );
+    //background colour for the canvas
+    virtual  void SetColour( const wxColour& background );
+
+    //update the area given in device coordinates
     virtual void Update( int x, int y, int width, int height, bool blit = TRUE );
     virtual void Update( int x, int y, int width, int height, bool blit = TRUE );
+
+    //blit all updated areas now to the screen, else it will happen in idle time.
+    //Use this to support dragging for instance, becuase in such cases idle time
+    //will take to long.
     virtual void UpdateNow();
 
     virtual void UpdateNow();
 
+    //prevent canvas activety
     virtual void Freeze();
     virtual void Freeze();
+    //allow canvas activety
     virtual void Thaw();
 
     virtual void Thaw();
 
-    virtual void Prepend( wxCanvasObject* obj );
-    virtual void Append( wxCanvasObject* obj );
-    virtual void Insert( size_t before, wxCanvasObject* obj );
-    virtual void Remove( wxCanvasObject* obj );
-
-    // override these to change your coordiate system ...
-    virtual int GetDeviceX( double x );
-    virtual int GetDeviceY( double y );
-    virtual int GetDeviceWidth( double width );
-    virtual int GetDeviceHeight( double height );
-
-    // ... and call this to tell all objets to recreate then
-    virtual void Recreate();
-
-#if IMAGE_CANVAS
-    inline wxImage *GetBuffer()  { return &m_buffer; }
-#else
+    //get the buffer that is used for rendering in general
     inline wxBitmap *GetBuffer() { return &m_buffer; }
     inline wxBitmap *GetBuffer() { return &m_buffer; }
-    inline wxMemoryDC *GetDC()   { return m_renderDC; }
-#endif
-    inline int GetBufferX()      { return m_bufferX; }
-    inline int GetBufferY()      { return m_bufferY; }
+    //get the DC that is used for rendering
+    inline wxDC *GetDC()   { return m_renderDC; }
+    //set the DC that is used for rendering
+    inline void  SetDC(wxDC* dc)   { m_renderDC=dc; }
+
     inline int GetBufferWidth()  { return m_buffer.GetWidth(); }
     inline int GetBufferHeight() { return m_buffer.GetHeight(); }
     inline int GetBufferWidth()  { return m_buffer.GetWidth(); }
     inline int GetBufferHeight() { return m_buffer.GetHeight(); }
-    
+
+    //updating is needed for the canvas if the buffer did change
     bool NeedUpdate()            { return m_needUpdate; }
     bool IsFrozen()              { return m_frozen; }
 
     bool NeedUpdate()            { return m_needUpdate; }
     bool IsFrozen()              { return m_frozen; }
 
+    //blit damaged areas in the buffer to the screen
     void BlitBuffer( wxDC &dc );
 
     void BlitBuffer( wxDC &dc );
 
+    //redirect events to this canvas object
     void SetCaptureMouse( wxCanvasObject *obj );
     void SetCaptureMouse( wxCanvasObject *obj );
+    //are events redirected, if so return the object else NULL
+    inline wxCanvasObject* GetCaptured() { return m_captureMouse;}
+
+    //set the root group where the objects for this canvas are stored
+    void SetRoot(wxCanvasObjectGroup* aroot){m_root=aroot;}
+
+    //get root group that is displayed on the canvas
+    wxCanvasObjectGroup* GetRoot(){return m_root;}
 
 
+    //scroll the window in device coordinates
     virtual void ScrollWindow( int dx, int dy,
                                const wxRect* rect = (wxRect *) NULL );
 
     virtual void ScrollWindow( int dx, int dy,
                                const wxRect* rect = (wxRect *) NULL );
 
-private:
-#if IMAGE_CANVAS
-    wxImage          m_buffer;
-#else
+    //get y axis orientation
+    virtual bool GetYaxis() { return FALSE; }
+    
+    //get the visible part in world coordinates
+    virtual double GetMinX() const;
+    virtual double GetMinY() const;
+    virtual double GetMaxX() const;
+    virtual double GetMaxY() const;
+
+    //convert from window to virtual coordinates
+    virtual double DeviceToLogicalX(int x) const;
+    virtual double DeviceToLogicalY(int y) const;
+    virtual double DeviceToLogicalXRel(int x) const;
+    virtual double DeviceToLogicalYRel(int y) const;
+    virtual int LogicalToDeviceX(double x) const;
+    virtual int LogicalToDeviceY(double y) const;
+    virtual int LogicalToDeviceXRel(double x) const;
+    virtual int LogicalToDeviceYRel(double y) const;
+
+protected:
     wxBitmap         m_buffer;
     wxBitmap         m_buffer;
-    wxMemoryDC      *m_renderDC;
-#endif
-    int              m_bufferX;
-    int              m_bufferY;
+
+    //always available and m_buffer selected
+    wxDC*            m_renderDC;
+    
     bool             m_needUpdate;
     wxList           m_updateRects;
     wxCanvasObjectGroup* m_root;
 
     bool             m_needUpdate;
     wxList           m_updateRects;
     wxCanvasObjectGroup* m_root;
 
-    unsigned char    m_green,m_red,m_blue;
+    wxColour         m_background;
     bool             m_frozen;
     wxCanvasObject  *m_lastMouse;
     wxCanvasObject  *m_captureMouse;
     bool             m_frozen;
     wxCanvasObject  *m_lastMouse;
     wxCanvasObject  *m_captureMouse;
-    
-    int              m_oldDeviceX,m_oldDeviceY;
 
 
-    friend class wxCanvasObject;
+    int              m_oldDeviceX,m_oldDeviceY;
 
 
+    wxCanvasAdmin*   m_admin;
+    
 private:
 private:
-    void OnChar( wxKeyEvent &event );
-    void OnPaint( wxPaintEvent &event );
+    int              m_bufferX,m_bufferY;
+
+protected:
     void OnMouse( wxMouseEvent &event );
     void OnMouse( wxMouseEvent &event );
+    void OnPaint( wxPaintEvent &event );
     void OnSize( wxSizeEvent &event );
     void OnIdle( wxIdleEvent &event );
     void OnSetFocus( wxFocusEvent &event );
     void OnSize( wxSizeEvent &event );
     void OnIdle( wxIdleEvent &event );
     void OnSetFocus( wxFocusEvent &event );
@@ -468,6 +711,153 @@ private:
 };
 
 
 };
 
 
+
+class wxVectorCanvas: public wxCanvas
+{
+public:
+    // constructors and destructors
+    wxVectorCanvas( wxCanvasAdmin* admin ,wxWindow *parent, wxWindowID id = -1,
+        const wxPoint& pos = wxDefaultPosition,
+        const wxSize& size = wxDefaultSize,
+        long style = wxScrolledWindowStyle );
+
+    //scroll the window in device coordinates
+    virtual void ScrollWindow( int dx, int dy,
+                               const wxRect* rect = (wxRect *) NULL );
+
+    //set if the Yaxis goes up or down
+    void SetYaxis(bool up) { m_yaxis=up; }
+
+    //get currently used Yaxis setting
+    virtual bool GetYaxis() { return m_yaxis; }
+
+    //to set the total area in world coordinates that can be scrolled.
+    // when totaly zoomed out (SetMappingScroll same size as given here),
+    // this will be the area displayed.
+    // To display all of a drawing, set this here to the boundingbox of the root group
+    // of the canvas.
+    void SetScroll(double vx1,double vy1,double vx2,double vy2);
+
+    //given the virtual size to be displayed, the mappingmatrix will be calculated
+    //in such a manner that it fits (same ratio in width and height) to the window size.
+    //The window size is used to intitialize the mapping.
+    //The virtual size is just an indication, it will be ajusted to fit in the client window ratio.
+    //When border is set an extra margin is added so that the drawing will fit nicely.
+    // To display all of a drawing, set this here to the boundingbox of the root group
+    // of the canvas.
+    void SetMappingScroll(double vx1,double vy1,double vx2,double vy2,bool border);
+
+    //matrix for calculating the virtual coordinate given a screen coordinate
+    wxTransformMatrix   GetInverseMappingMatrix();
+
+    //matrix for calculating the screen coordinate given a virtual coordinate
+    wxTransformMatrix   GetMappingMatrix();
+
+    //get minimum X of the visible part in world coordinates
+    virtual double GetMinX() const;
+    virtual double GetMinY() const;
+    virtual double GetMaxX() const;
+    virtual double GetMaxY() const;
+    
+    //convert from window to virtual coordinates and back
+    virtual double DeviceToLogicalX(int x) const;
+    virtual double DeviceToLogicalY(int y) const;
+    virtual double DeviceToLogicalXRel(int x) const;
+    virtual double DeviceToLogicalYRel(int y) const;
+    virtual int LogicalToDeviceX(double x) const;
+    virtual int LogicalToDeviceY(double y) const;
+    virtual int LogicalToDeviceXRel(double x) const;
+    virtual int LogicalToDeviceYRel(double y) const;
+
+protected:
+    // up or down
+    bool m_yaxis;
+
+    // holds the matrix for mapping from virtual to screen coordinates
+    wxTransformMatrix m_mapping_matrix;
+
+    // holds the inverse of the mapping matrix
+    wxTransformMatrix m_inverse_mapping;
+
+    //virtual coordinates of total drawing
+    double m_virtm_minX, m_virtm_minY, m_virtm_maxX, m_virtm_maxY;
+
+    // virtual coordinates box
+    double m_virt_minX, m_virt_minY, m_virt_maxX, m_virt_maxY;
+
+    // bounding box
+    double m_minX, m_minY, m_maxX, m_maxY;
+
+    //are scroll bars active?
+    bool m_scrolled;
+
+private:
+    void OnScroll(wxScrollWinEvent& event);
+    void OnChar( wxKeyEvent &event );
+    void OnSize( wxSizeEvent &event );
+
+private:
+    DECLARE_CLASS(wxVectorCanvas)
+    DECLARE_EVENT_TABLE()
+};
+
+
+
+//:defenition
+//Contains a list of wxCanvas Objects that will be maintained through this class.
+//Each wxCanvasObject can be displayed on several wxCanvas Objects at the same time.
+//The active wxCanvas is used to render and convert coordinates from world to device.
+//So it is important to set the active wxCanvas based on the wxCanvas that has the focus
+//or is scrolled etc. This is normally done within wxCanvas when appropriate.
+class wxCanvasAdmin
+{
+public:
+    // constructors and destructors
+    wxCanvasAdmin();
+    virtual ~wxCanvasAdmin();
+
+    //convert from window to virtual coordinates
+    double DeviceToLogicalX(int x) const;
+    //convert from window to virtual coordinates
+    double DeviceToLogicalY(int y) const;
+    //convert from window to virtual coordinates relatif
+    double DeviceToLogicalXRel(int x) const;
+    //convert from window to virtual coordinates relatif
+    double DeviceToLogicalYRel(int y) const;
+    //convert from virtual to window coordinates
+    int LogicalToDeviceX(double x) const;
+    //convert from virtual to window coordinates
+    int LogicalToDeviceY(double y) const;
+    //convert from virtual to window coordinates relatif
+    int LogicalToDeviceXRel(double x) const;
+    //convert from virtual to window coordinates relatif
+    int LogicalToDeviceYRel(double y) const;
+
+    //update in the buffer off all canvases, the area given in world coordinates
+    virtual void Update(wxCanvasObject* obj, double x, double y, double width, double height);
+
+    //blit all updated areas now to the screen, else it will happen in idle time.
+    //Use this to support dragging for instance, becuase in such cases idle time
+    //will take to long.
+    virtual void UpdateNow();
+
+    //append another canvas
+    virtual void Append( wxCanvas* canvas );
+
+    //remove a canvas
+    virtual void Remove( wxCanvas* canvas );
+
+    //set the given canvas as active (for rendering, coordinate conversion etc.)
+    void SetActive(wxCanvas* activate);
+
+    //get active canvas
+    inline wxCanvas* GetActive() {return m_active;};
+
+private:
+    wxList m_canvaslist;
+    wxCanvas* m_active;
+};
+
 #endif
     // WXCANVAS
 
 #endif
     // WXCANVAS