///////////////////////////////////////////////////////////////////////////// // Name: pseudodc.h // Purpose: wxPseudoDC class // Author: Paul Lanier // Modified by: // Created: 05/25/06 // RCS-ID: $Id:$ // Copyright: (c) wxWidgets team // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// #ifndef _WX_PSUEDO_DC_H_BASE_ #define _WX_PSUEDO_DC_H_BASE_ #include "wx/dc.h" // enum for dc operations enum pdcOpType { pdcOP_SET_FONT, pdcOP_SET_PEN, pdcOP_SET_BRUSH, pdcOP_SET_BACKGROUND, pdcOP_SET_BACKGROUND_MODE, pdcOP_SET_TEXT_BACKGROUND, pdcOP_SET_TEXT_FOREGROUND, pdcOP_DRAW_LABEL, pdcOP_DRAW_TEXT, pdcOP_DRAW_RECTANGLE, pdcOP_CLEAR, pdcOP_BEGIN_DRAWING, pdcOP_END_DRAWING, pdcOP_DRAW_LINE, pdcOP_NOP }; // Base Class for Nodes in the linked list of operations // This class contains Bi-Dir circular linked list functionality // as well as the operation code and associated id for this node // The id is used to associate a set of drawing operations with // a particular object so that when that object is re-drawn // its operations can be removed before the redraw is done class WXDLLEXPORT pdcNode; class WXDLLEXPORT pdcNode { public: // Constructors and Destructor pdcNode() {m_next=this; m_prev=this; m_op=pdcOP_NOP; m_id=wxID_ANY;} pdcNode(pdcOpType op, int id) {m_next=this; m_prev=this; m_op=op; m_id=id;} ~pdcNode() {Unlink();} // Linked List Methods void Insert(pdcNode *node) {node->m_next=this; node->m_prev=m_prev; m_prev->m_next=node; m_prev=node;} void Append(pdcNode *node) {node->m_next=m_next; node->m_prev=this; m_next->m_prev=node; m_next=node;} void Unlink() {m_prev->m_next=m_next; m_next->m_prev=m_prev; m_next=m_prev=this;} pdcNode *Next() {return m_next;} pdcNode *Prev() {return m_prev;} // Protected Member Access void SetId(int id) {m_id=id;} int GetId() {return m_id;} void SetOp(pdcOpType op) {m_op=op;} pdcOpType GetOp() {return m_op;} protected: pdcOpType m_op; // operation this node represents int m_id; // id that owns this operation pdcNode *m_next; // pointer to next node in linked list pdcNode *m_prev; // pointer to prev node in linked list }; // Classes derived from pdcNode // There is one class for each argument configuration used // by various dc methods e.g. pdcFontNode is used for SetFont class pdcFontNode : public pdcNode { public: pdcFontNode(pdcOpType op, int id, const wxFont& font) : pdcNode(op,id) {m_font=font;} wxFont m_font; }; class pdcBrushNode : public pdcNode { public: pdcBrushNode(pdcOpType op, int id, const wxBrush& brush) : pdcNode(op,id) {m_brush=brush;} wxBrush m_brush; }; class pdcPenNode : public pdcNode { public: pdcPenNode(pdcOpType op, int id, const wxPen& pen) : pdcNode(op,id) {m_pen=pen;} wxPen m_pen; }; class pdcColourNode : public pdcNode { public: pdcColourNode(pdcOpType op, int id, const wxColour& colour) : pdcNode(op,id) {m_id=id; m_colour=colour;} wxColour m_colour; }; class pdc4CoordNode : public pdcNode { public: pdc4CoordNode(pdcOpType op, int id, wxCoord c0, wxCoord c1, wxCoord c2, wxCoord c3) : pdcNode(op,id) {m_c0=c0; m_c1=c1; m_c2=c2; m_c3=c3;} wxCoord m_c0,m_c1,m_c2,m_c3; }; class pdcIntNode : public pdcNode { public: pdcIntNode(pdcOpType op, int id, int i) : pdcNode(op,id) {m_i=i;} int m_i; }; class pdcDrawLabelNode : public pdcNode { public: pdcDrawLabelNode(pdcOpType op, int id, const wxString& text, const wxRect& rect, int alignment, int indexAccel) : pdcNode(op,id) {m_text=text; m_rect=rect; m_align=alignment; m_iAccel=indexAccel;} wxString m_text; wxRect m_rect; int m_align,m_iAccel; }; class pdcDrawTextNode : public pdcNode { public: pdcDrawTextNode(pdcOpType op, int id, const wxString& text, wxCoord x, wxCoord y) {m_next=NULL; m_op=op; m_id=id; m_text=text; m_x=x; m_y=y;} wxString m_text; wxCoord m_x, m_y; }; // wxPseudoDC class // This is the actual PseudoDC class // This class stores a list of recorded dc operations in m_list // and plays them back to a real dc using DrawToDC or DrawToDCClipped. // Drawing methods are mirrored from wxDC but add nodes to m_list // instead of doing any real drawing. class WXDLLEXPORT wxPseudoDC : public wxObject { public: wxPseudoDC() {m_currId=0;} ~wxPseudoDC(); void ClearAll(); int GetLen(); // methods for managing operations by ID // Set the Id for all subsequent operations (until SetId is called again) void SetId(int id) {m_currId = id;} // Remove all the operations associated with an id void ClearId(int id); // Playback Methods // draw to dc but skip operations known to be outside of rect // This is a coarse level of clipping to speed things up // when lots of objects are off screen and doesn't affect the dc level // clipping void DrawToDCClipped(wxDC *dc, const wxRect& rect); // draw to dc with no clipping (well the dc will still clip) void DrawToDC(wxDC *dc); // Methods mirrored from wxDC void SetFont(const wxFont& font) {AddToList(new pdcFontNode(pdcOP_SET_FONT, m_currId, font));} void SetPen(const wxPen& pen) {AddToList(new pdcPenNode(pdcOP_SET_PEN, m_currId, pen));} void SetBrush(const wxBrush& brush) {AddToList(new pdcBrushNode(pdcOP_SET_BRUSH, m_currId, brush));} void SetBackground(const wxBrush& brush) {AddToList(new pdcBrushNode(pdcOP_SET_BACKGROUND, m_currId, brush));} void SetBackgroundMode(int mode) {AddToList(new pdcIntNode(pdcOP_SET_BACKGROUND_MODE, m_currId, mode));} void SetTextBackground(const wxColour& colour) {AddToList(new pdcColourNode(pdcOP_SET_TEXT_BACKGROUND, m_currId, colour));} void SetTextForeground(const wxColour& colour) {AddToList(new pdcColourNode(pdcOP_SET_TEXT_FOREGROUND, m_currId, colour));} void DrawLabel(const wxString& text, const wxRect& rect, int alignment = wxALIGN_LEFT | wxALIGN_TOP, int indexAccel = -1) {AddToList(new pdcDrawLabelNode(pdcOP_DRAW_LABEL, m_currId, text, rect, alignment, indexAccel));} void DrawText(const wxString& text, wxCoord x, wxCoord y) {AddToList(new pdcDrawTextNode(pdcOP_DRAW_TEXT, m_currId, text, x, y));} void DrawRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height) {AddToList(new pdc4CoordNode(pdcOP_DRAW_RECTANGLE, m_currId, x, y, width, height));} void DrawLine(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2) {AddToList(new pdc4CoordNode(pdcOP_DRAW_LINE, m_currId, x1, y1, x2, y2));} void Clear() {AddToList(new pdcNode(pdcOP_CLEAR, m_currId));} protected: void AddToList(pdcNode *newNode); int m_currId; pdcNode m_list; // use dummy node for list pointer }; #endif