1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        pseudodc.h
3 // Purpose:     wxPseudoDC classes
4 // Author:      Paul Lanier
5 // Modified by: Robin Dunn
6 //
7 // Created:     25-May-2006
8 // Copyright:   (c) 2006-2018 Total Control Software
9 // Licence:     wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11 
12 #ifndef _WX_PSUEDO_DC_H_BASE_
13 #define _WX_PSUEDO_DC_H_BASE_
14 
15 //----------------------------------------------------------------------------
16 // Base class for all pdcOp classes
17 //----------------------------------------------------------------------------
18 class pdcOp
19 {
20     public:
21         // Constructor and Destructor
pdcOp()22         pdcOp() {}
~pdcOp()23         virtual ~pdcOp() {}
24 
25         // Virtual Drawing Methods
26         virtual void DrawToDC(wxDC *dc, bool grey=false)=0;
Translate(wxCoord WXUNUSED (dx),wxCoord WXUNUSED (dy))27         virtual void Translate(wxCoord WXUNUSED(dx), wxCoord WXUNUSED(dy)) {}
CacheGrey()28         virtual void CacheGrey() {}
29 };
30 
31 //----------------------------------------------------------------------------
32 // declare a list class for list of pdcOps
33 //----------------------------------------------------------------------------
34 WX_DECLARE_LIST(pdcOp, pdcOpList);
35 
36 
37 //----------------------------------------------------------------------------
38 // Helper functions used for drawing greyed out versions of objects
39 //----------------------------------------------------------------------------
40 wxColour &MakeColourGrey(const wxColour &c);
41 wxBrush &GetGreyBrush(wxBrush &brush);
42 wxPen &GetGreyPen(wxPen &pen);
43 wxIcon &GetGreyIcon(wxIcon &icon);
44 wxBitmap &GetGreyBitmap(wxBitmap &bmp);
45 
46 //----------------------------------------------------------------------------
47 // Classes derived from pdcOp
48 // There is one class for each method mirrored from wxDC to wxPseudoDC
49 //----------------------------------------------------------------------------
50 class pdcSetFontOp : public pdcOp
51 {
52     public:
pdcSetFontOp(const wxFont & font)53         pdcSetFontOp(const wxFont& font)
54             {m_font=font;}
55         virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false) {dc->SetFont(m_font);}
56     protected:
57         wxFont m_font;
58 };
59 
60 class pdcSetBrushOp : public pdcOp
61 {
62     public:
pdcSetBrushOp(const wxBrush & brush)63         pdcSetBrushOp(const wxBrush& brush)
64             {m_greybrush=m_brush=brush;}
65         virtual void DrawToDC(wxDC *dc, bool grey=false)
66         {
67             if (!grey) dc->SetBrush(m_brush);
68             else dc->SetBrush(m_greybrush);
69         }
CacheGrey()70         virtual void CacheGrey() {m_greybrush=GetGreyBrush(m_brush);}
71     protected:
72         wxBrush m_brush;
73         wxBrush m_greybrush;
74 };
75 
76 class pdcSetBackgroundOp : public pdcOp
77 {
78     public:
pdcSetBackgroundOp(const wxBrush & brush)79         pdcSetBackgroundOp(const wxBrush& brush)
80             {m_greybrush=m_brush=brush;}
81         virtual void DrawToDC(wxDC *dc, bool grey=false)
82         {
83             if (!grey) dc->SetBackground(m_brush);
84             else dc->SetBackground(m_greybrush);
85         }
CacheGrey()86         virtual void CacheGrey() {m_greybrush=GetGreyBrush(m_brush);}
87     protected:
88         wxBrush m_brush;
89         wxBrush m_greybrush;
90 };
91 
92 class pdcSetPenOp : public pdcOp
93 {
94     public:
pdcSetPenOp(const wxPen & pen)95         pdcSetPenOp(const wxPen& pen)
96             {m_greypen=m_pen=pen;}
97         virtual void DrawToDC(wxDC *dc, bool grey=false)
98         {
99             if (!grey) dc->SetPen(m_pen);
100             else dc->SetPen(m_greypen);
101         }
CacheGrey()102         virtual void CacheGrey() {m_greypen=GetGreyPen(m_pen);}
103     protected:
104         wxPen m_pen;
105         wxPen m_greypen;
106 };
107 
108 class pdcSetTextBackgroundOp : public pdcOp
109 {
110     public:
pdcSetTextBackgroundOp(const wxColour & colour)111         pdcSetTextBackgroundOp(const wxColour& colour)
112             {m_colour=colour;}
113         virtual void DrawToDC(wxDC *dc, bool grey=false)
114         {
115             if (!grey) dc->SetTextBackground(m_colour);
116             else dc->SetTextBackground(MakeColourGrey(m_colour));
117         }
118     protected:
119         wxColour m_colour;
120 };
121 
122 class pdcSetTextForegroundOp : public pdcOp
123 {
124     public:
pdcSetTextForegroundOp(const wxColour & colour)125         pdcSetTextForegroundOp(const wxColour& colour)
126             {m_colour=colour;}
127         virtual void DrawToDC(wxDC *dc, bool grey=false)
128         {
129             if (!grey) dc->SetTextForeground(m_colour);
130             else dc->SetTextForeground(MakeColourGrey(m_colour));
131         }
132     protected:
133         wxColour m_colour;
134 };
135 
136 class pdcDrawRectangleOp : public pdcOp
137 {
138     public:
pdcDrawRectangleOp(wxCoord x,wxCoord y,wxCoord w,wxCoord h)139         pdcDrawRectangleOp(wxCoord x, wxCoord y, wxCoord w, wxCoord h)
140             {m_x=x; m_y=y; m_w=w; m_h=h;}
141         virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false) {dc->DrawRectangle(m_x,m_y,m_w,m_h);}
Translate(wxCoord dx,wxCoord dy)142         virtual void Translate(wxCoord dx, wxCoord dy)
143             {m_x+=dx;m_y+=dy;}
144     protected:
145         wxCoord m_x,m_y,m_w,m_h;
146 };
147 
148 class pdcDrawLineOp : public pdcOp
149 {
150     public:
pdcDrawLineOp(wxCoord x1,wxCoord y1,wxCoord x2,wxCoord y2)151         pdcDrawLineOp(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2)
152             {m_x1=x1; m_y1=y1; m_x2=x2; m_y2=y2;}
153         virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false) {dc->DrawLine(m_x1,m_y1,m_x2,m_y2);}
Translate(wxCoord dx,wxCoord dy)154         virtual void Translate(wxCoord dx, wxCoord dy)
155             {m_x1+=dx; m_y1+=dy; m_x2+=dx; m_y2+=dy;}
156     protected:
157         wxCoord m_x1,m_y1,m_x2,m_y2;
158 };
159 
160 class pdcSetBackgroundModeOp : public pdcOp
161 {
162     public:
pdcSetBackgroundModeOp(int mode)163         pdcSetBackgroundModeOp(int mode) {m_mode=mode;}
164         virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false) {dc->SetBackgroundMode(m_mode);}
165     protected:
166         int m_mode;
167 };
168 
169 class pdcDrawTextOp : public pdcOp
170 {
171     public:
pdcDrawTextOp(const wxString & text,wxCoord x,wxCoord y)172         pdcDrawTextOp(const wxString& text, wxCoord x, wxCoord y)
173             {m_text=text; m_x=x; m_y=y;}
174         virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false) {dc->DrawText(m_text, m_x, m_y);}
Translate(wxCoord dx,wxCoord dy)175         virtual void Translate(wxCoord dx, wxCoord dy)
176             {m_x+=dx; m_y+=dy;}
177     protected:
178         wxString m_text;
179         wxCoord m_x, m_y;
180 };
181 
182 class pdcClearOp : public pdcOp
183 {
184     public:
pdcClearOp()185         pdcClearOp() {}
186         virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false) {dc->Clear();}
187 };
188 
189 class pdcBeginDrawingOp : public pdcOp
190 {
191     public:
pdcBeginDrawingOp()192         pdcBeginDrawingOp() {}
193         virtual void DrawToDC(wxDC *WXUNUSED(dc), bool WXUNUSED(grey)=false) {}
194 };
195 
196 class pdcEndDrawingOp : public pdcOp
197 {
198     public:
pdcEndDrawingOp()199         pdcEndDrawingOp() {}
200         virtual void DrawToDC(wxDC *WXUNUSED(dc), bool WXUNUSED(grey)=false) {}
201 };
202 
203 class pdcFloodFillOp : public pdcOp
204 {
205     public:
pdcFloodFillOp(wxCoord x,wxCoord y,const wxColour & col,wxFloodFillStyle style)206         pdcFloodFillOp(wxCoord x, wxCoord y, const wxColour& col,
207                    wxFloodFillStyle style) {m_x=x; m_y=y; m_col=col; m_style=style;}
208         virtual void DrawToDC(wxDC *dc, bool grey=false)
209         {
210             if (!grey) dc->FloodFill(m_x,m_y,m_col,m_style);
211             else dc->FloodFill(m_x,m_y,MakeColourGrey(m_col),m_style);
212         }
Translate(wxCoord dx,wxCoord dy)213         virtual void Translate(wxCoord dx, wxCoord dy)
214             {m_x+=dx; m_y+=dy;}
215     protected:
216         wxCoord m_x,m_y;
217         wxColour m_col;
218         wxFloodFillStyle m_style;
219 };
220 
221 class pdcCrossHairOp : public pdcOp
222 {
223     public:
pdcCrossHairOp(wxCoord x,wxCoord y)224         pdcCrossHairOp(wxCoord x, wxCoord y) {m_x=x; m_y=y;}
225         virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false) {dc->CrossHair(m_x,m_y);}
Translate(wxCoord dx,wxCoord dy)226         virtual void Translate(wxCoord dx, wxCoord dy)
227             {m_x+=dx; m_y+=dy;}
228     protected:
229         wxCoord m_x,m_y;
230 };
231 
232 class pdcDrawArcOp : public pdcOp
233 {
234     public:
pdcDrawArcOp(wxCoord x1,wxCoord y1,wxCoord x2,wxCoord y2,wxCoord xc,wxCoord yc)235         pdcDrawArcOp(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2,
236                          wxCoord xc, wxCoord yc)
237             {m_x1=x1; m_y1=y1; m_x2=x2; m_y2=y2; m_xc=xc; m_yc=yc;}
238         virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false)
239             {dc->DrawArc(m_x1,m_y1,m_x2,m_y2,m_xc,m_yc);}
Translate(wxCoord dx,wxCoord dy)240         virtual void Translate(wxCoord dx, wxCoord dy)
241             {m_x1+=dx; m_x2+=dx; m_y1+=dy; m_y2+=dy;}
242     protected:
243         wxCoord m_x1,m_x2,m_xc;
244         wxCoord m_y1,m_y2,m_yc;
245 };
246 
247 class pdcDrawCheckMarkOp : public pdcOp
248 {
249     public:
pdcDrawCheckMarkOp(wxCoord x,wxCoord y,wxCoord width,wxCoord height)250         pdcDrawCheckMarkOp(wxCoord x, wxCoord y,
251                        wxCoord width, wxCoord height)
252             {m_x=x; m_y=y; m_w=width; m_h=height;}
253         virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false)
254             {dc->DrawCheckMark(m_x,m_y,m_w,m_h);}
Translate(wxCoord dx,wxCoord dy)255         virtual void Translate(wxCoord dx, wxCoord dy)
256             {m_x+=dx; m_y+=dy;}
257     protected:
258         wxCoord m_x,m_y,m_w,m_h;
259 };
260 
261 class pdcDrawEllipticArcOp : public pdcOp
262 {
263     public:
pdcDrawEllipticArcOp(wxCoord x,wxCoord y,wxCoord w,wxCoord h,double sa,double ea)264         pdcDrawEllipticArcOp(wxCoord x, wxCoord y, wxCoord w, wxCoord h,
265                          double sa, double ea)
266             {m_x=x; m_y=y; m_w=w; m_h=h; m_sa=sa; m_ea=ea;}
267         virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false)
268             {dc->DrawEllipticArc(m_x,m_y,m_w,m_h,m_sa,m_ea);}
Translate(wxCoord dx,wxCoord dy)269         virtual void Translate(wxCoord dx, wxCoord dy)
270             {m_x+=dx; m_y+=dy;}
271     protected:
272         wxCoord m_x,m_y,m_w,m_h;
273         double m_sa,m_ea;
274 };
275 
276 class pdcDrawPointOp : public pdcOp
277 {
278     public:
pdcDrawPointOp(wxCoord x,wxCoord y)279         pdcDrawPointOp(wxCoord x, wxCoord y)
280             {m_x=x; m_y=y;}
281         virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false) {dc->DrawPoint(m_x,m_y);}
Translate(wxCoord dx,wxCoord dy)282         virtual void Translate(wxCoord dx, wxCoord dy)
283             {m_x+=dx; m_y+=dy;}
284     protected:
285         wxCoord m_x,m_y;
286 };
287 
288 class pdcDrawRoundedRectangleOp : public pdcOp
289 {
290     public:
pdcDrawRoundedRectangleOp(wxCoord x,wxCoord y,wxCoord width,wxCoord height,double radius)291         pdcDrawRoundedRectangleOp(wxCoord x, wxCoord y, wxCoord width,
292                                   wxCoord height, double radius)
293             {m_x=x; m_y=y; m_w=width; m_h=height; m_r=radius;}
294         virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false)
295             {dc->DrawRoundedRectangle(m_x,m_y,m_w,m_h,m_r);}
Translate(wxCoord dx,wxCoord dy)296         virtual void Translate(wxCoord dx, wxCoord dy)
297             {m_x+=dx; m_y+=dy;}
298     protected:
299         wxCoord m_x,m_y,m_w,m_h;
300         double m_r;
301 };
302 
303 class pdcDrawEllipseOp : public pdcOp
304 {
305     public:
pdcDrawEllipseOp(wxCoord x,wxCoord y,wxCoord width,wxCoord height)306         pdcDrawEllipseOp(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
307             {m_x=x; m_y=y; m_w=width; m_h=height;}
308         virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false) {dc->DrawEllipse(m_x,m_y,m_w,m_h);}
Translate(wxCoord dx,wxCoord dy)309         virtual void Translate(wxCoord dx, wxCoord dy)
310             {m_x+=dx; m_y+=dy;}
311     protected:
312         wxCoord m_x,m_y,m_w,m_h;
313 };
314 
315 class pdcDrawIconOp : public pdcOp
316 {
317     public:
pdcDrawIconOp(const wxIcon & icon,wxCoord x,wxCoord y)318         pdcDrawIconOp(const wxIcon& icon, wxCoord x, wxCoord y)
319             {m_icon=icon; m_x=x; m_y=y;}
320         virtual void DrawToDC(wxDC *dc, bool grey=false)
321         {
322             if (grey) dc->DrawIcon(m_greyicon,m_x,m_y);
323             else dc->DrawIcon(m_icon,m_x,m_y);
324         }
CacheGrey()325         virtual void CacheGrey() {m_greyicon=GetGreyIcon(m_icon);}
Translate(wxCoord dx,wxCoord dy)326         virtual void Translate(wxCoord dx, wxCoord dy)
327             {m_x+=dx; m_y+=dy;}
328     protected:
329         wxIcon m_icon;
330         wxIcon m_greyicon;
331         wxCoord m_x,m_y;
332 };
333 
334 class pdcDrawLinesOp : public pdcOp
335 {
336     public:
337         pdcDrawLinesOp(const wxPointList* points,
338                        wxCoord xoffset = 0,
339                        wxCoord yoffset = 0);
340         virtual ~pdcDrawLinesOp();
341 
342         virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false)
343             { dc->DrawLines(m_points, m_xoffset, m_yoffset); }
344 
345         virtual void Translate(wxCoord dx, wxCoord dy);
346 
347     protected:
348         wxPointList* m_points;
349         wxCoord m_xoffset;
350         wxCoord m_yoffset;
351 };
352 
353 class pdcDrawPolygonOp : public pdcOp
354 {
355     public:
356         pdcDrawPolygonOp(const wxPointList* points,
357                          wxCoord xoffset = 0,
358                          wxCoord yoffset = 0,
359                          wxPolygonFillMode fillStyle = wxODDEVEN_RULE);
360         virtual ~pdcDrawPolygonOp();
361 
362         virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false)
363             { dc->DrawPolygon(m_points, m_xoffset, m_yoffset, m_fillStyle); }
364 
365         virtual void Translate(wxCoord dx, wxCoord dy);
366 
367     protected:
368         wxPointList* m_points;
369         wxCoord m_xoffset;
370         wxCoord m_yoffset;
371         wxPolygonFillMode m_fillStyle;
372 };
373 
374 class pdcDrawPolyPolygonOp : public pdcOp
375 {
376     public:
377         pdcDrawPolyPolygonOp(int n, int count[], wxPoint points[],
378                          wxCoord xoffset = 0, wxCoord yoffset = 0,
379                          wxPolygonFillMode fillStyle = wxODDEVEN_RULE);
380         virtual ~pdcDrawPolyPolygonOp();
381         virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false)
382             {dc->DrawPolyPolygon(m_n,m_count,m_points,
383                     m_xoffset,m_yoffset,m_fillStyle);}
Translate(wxCoord dx,wxCoord dy)384         virtual void Translate(wxCoord dx, wxCoord dy)
385         {
386             for(int i=0; i<m_totaln; i++)
387             {
388                 m_points[i].x += dx;
389                 m_points[i].y += dy;
390             }
391         }
392     protected:
393         int m_n;
394         int m_totaln;
395         int *m_count;
396         wxPoint *m_points;
397         wxCoord m_xoffset, m_yoffset;
398         wxPolygonFillMode m_fillStyle;
399 };
400 
401 class pdcDrawRotatedTextOp : public pdcOp
402 {
403     public:
pdcDrawRotatedTextOp(const wxString & text,wxCoord x,wxCoord y,double angle)404         pdcDrawRotatedTextOp(const wxString& text, wxCoord x, wxCoord y, double angle)
405             {m_text=text; m_x=x; m_y=y; m_angle=angle;}
406         virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false)
407             {dc->DrawRotatedText(m_text,m_x,m_y,m_angle);}
Translate(wxCoord dx,wxCoord dy)408         virtual void Translate(wxCoord dx, wxCoord dy)
409             {m_x+=dx; m_y+=dy;}
410     protected:
411         wxString m_text;
412         wxCoord m_x,m_y;
413         double m_angle;
414 };
415 
416 class pdcDrawBitmapOp : public pdcOp
417 {
418     public:
419         pdcDrawBitmapOp(const wxBitmap &bmp, wxCoord x, wxCoord y,
420                         bool useMask = false)
421             {m_bmp=bmp; m_x=x; m_y=y; m_useMask=useMask;}
422         virtual void DrawToDC(wxDC *dc, bool grey=false)
423         {
424             if (grey) dc->DrawBitmap(m_greybmp,m_x,m_y,m_useMask);
425             else dc->DrawBitmap(m_bmp,m_x,m_y,m_useMask);
426         }
CacheGrey()427         virtual void CacheGrey() {m_greybmp=GetGreyBitmap(m_bmp);}
Translate(wxCoord dx,wxCoord dy)428         virtual void Translate(wxCoord dx, wxCoord dy)
429             {m_x+=dx; m_y+=dy;}
430     protected:
431         wxBitmap m_bmp;
432         wxBitmap m_greybmp;
433         wxCoord m_x,m_y;
434         bool m_useMask;
435 };
436 
437 class pdcDrawLabelOp : public pdcOp
438 {
439     public:
440         pdcDrawLabelOp(const wxString& text,
441                            const wxBitmap& image,
442                            const wxRect& rect,
443                            int alignment = wxALIGN_LEFT | wxALIGN_TOP,
444                            int indexAccel = -1)
445             {m_text=text; m_image=image; m_rect=rect;
446              m_align=alignment; m_iAccel=indexAccel;}
447         virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false)
448             {dc->DrawLabel(m_text,m_image,m_rect,m_align,m_iAccel);}
Translate(wxCoord dx,wxCoord dy)449         virtual void Translate(wxCoord dx, wxCoord dy)
450             {m_rect.x+=dx; m_rect.y+=dy;}
451     protected:
452         wxString m_text;
453         wxBitmap m_image;
454         wxRect m_rect;
455         int m_align;
456         int m_iAccel;
457 };
458 
459 #if wxUSE_SPLINES
460 class pdcDrawSplineOp : public pdcOp
461 {
462     public:
463         pdcDrawSplineOp(const wxPointList* points);
464         virtual ~pdcDrawSplineOp();
465         virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false)
466             { dc->DrawSpline(m_points); }
467 
468         virtual void Translate(wxCoord dx, wxCoord dy);
469 
470     protected:
471         wxPointList* m_points;
472 };
473 #endif // wxUSE_SPLINES
474 
475 #if wxUSE_PALETTE
476 class pdcSetPaletteOp : public pdcOp
477 {
478     public:
pdcSetPaletteOp(const wxPalette & palette)479         pdcSetPaletteOp(const wxPalette& palette) {m_palette=palette;}
480         virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false) {dc->SetPalette(m_palette);}
481     protected:
482         wxPalette m_palette;
483 };
484 #endif // wxUSE_PALETTE
485 
486 class pdcSetLogicalFunctionOp : public pdcOp
487 {
488     public:
pdcSetLogicalFunctionOp(wxRasterOperationMode function)489         pdcSetLogicalFunctionOp(wxRasterOperationMode function) {m_function=function;}
490         virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false) {dc->SetLogicalFunction(m_function);}
491     protected:
492         wxRasterOperationMode m_function;
493 };
494 
495 //----------------------------------------------------------------------------
496 // pdcObject type to contain list of operations for each real (Python) object
497 //----------------------------------------------------------------------------
498 class pdcObject
499 {
500     public:
pdcObject(int id)501         pdcObject(int id)
502             {m_id=id; m_bounded=false; m_oplist.DeleteContents(true);
503              m_greyedout=false;}
504 
~pdcObject()505         virtual ~pdcObject() {m_oplist.Clear();}
506 
507         // Protected Member Access
SetId(int id)508         void SetId(int id) {m_id=id;}
GetId()509         int  GetId() {return m_id;}
SetBounds(wxRect & rect)510         void   SetBounds(wxRect& rect) {m_bounds=rect; m_bounded=true;}
GetBounds()511         wxRect GetBounds() {return m_bounds;}
SetBounded(bool bounded)512         void SetBounded(bool bounded) {m_bounded=bounded;}
IsBounded()513         bool IsBounded() {return m_bounded;}
514         void SetGreyedOut(bool greyout=true);
GetGreyedOut()515         bool GetGreyedOut() {return m_greyedout;}
516 
517         // Op List Management Methods
Clear()518         void Clear() {m_oplist.Clear();}
AddOp(pdcOp * op)519         void AddOp(pdcOp *op)
520         {
521             m_oplist.Append(op);
522             if (m_greyedout) op->CacheGrey();
523         }
GetLen()524         int  GetLen() {return m_oplist.GetCount();}
525         virtual void Translate(wxCoord dx, wxCoord dy);
526 
527         // Drawing Method
528         virtual void DrawToDC(wxDC *dc);
529     protected:
530         int m_id; // id of object (associates this pdcObject
531                   //               with a Python object with same id)
532         wxRect m_bounds;  // bounding rect of this object
533         bool m_bounded;   // true if bounds is valid, false by default
534         pdcOpList m_oplist; // list of operations for this object
535         bool m_greyedout; // if true then draw this object in greys only
536 };
537 
538 
539 //----------------------------------------------------------------------------
540 // Declare a wxList to hold all the objects.  List order reflects drawing
541 // order (Z order) and is the same order as objects are added to the list
542 //----------------------------------------------------------------------------
543 class pdcObjectList;
544 WX_DECLARE_LIST(pdcObject, pdcObjectList);
545 
546 //Declare a hashmap that maps from ids to nodes in the object list.
547 WX_DECLARE_HASH_MAP(
548     int,
549     pdcObject *,
550     wxIntegerHash,
551     wxIntegerEqual,
552     pdcObjectHash
553 );
554 
555 
556 // ----------------------------------------------------------------------------
557 // wxPseudoDC class
558 // ----------------------------------------------------------------------------
559 // This is the actual PseudoDC class
560 // This class stores a list of recorded dc operations in m_list
561 // and plays them back to a real dc using DrawToDC or DrawToDCClipped.
562 // Drawing methods are mirrored from wxDC but add nodes to m_list
563 // instead of doing any real drawing.
564 // ----------------------------------------------------------------------------
565 class wxPseudoDC : public wxObject
566 {
567 public:
wxPseudoDC()568     wxPseudoDC()
569         {m_currId=-1; m_lastObject=NULL; m_objectlist.DeleteContents(true);m_objectIndex.clear();}
570     ~wxPseudoDC();
571     // ------------------------------------------------------------------------
572     // List management methods
573     //
574     void RemoveAll();
575     int GetLen();
576 
577     // ------------------------------------------------------------------------
578     // methods for managing operations by ID
579     //
580     // Set the Id for all subsequent operations (until SetId is called again)
SetId(int id)581     void SetId(int id) {m_currId = id;}
582     // Remove all the operations associated with an id so it can be redrawn
583     void ClearId(int id);
584     // Remove the object node (and all operations) associated with an id
585     void RemoveId(int id);
586     // Set the bounding rect of a given object
587     // This will create an object node if one doesn't exist
588     void SetIdBounds(int id, wxRect& rect);
589     wxRect GetIdBounds(int id);
590     // Translate all the operations for this id
591     void TranslateId(int id, wxCoord dx, wxCoord dy);
592     // Grey-out an object
593     void SetIdGreyedOut(int id, bool greyout=true);
594     bool GetIdGreyedOut(int id);
595     // Find Objects at a point.  Returns Python list of id's
596     // sorted in reverse drawing order (result[0] is top object)
597     // This version looks at drawn pixels
598     PyObject *FindObjects(wxCoord x, wxCoord y,
599                           wxCoord radius=1, const wxColor& bg=*wxWHITE);
600     // This version only looks at bounding boxes
601     PyObject *FindObjectsByBBox(wxCoord x, wxCoord y);
602 
603     // ------------------------------------------------------------------------
604     // Playback Methods
605     //
606     // draw to dc but skip objects known to be outside of rect
607     // This is a coarse level of clipping to speed things up
608     // when lots of objects are off screen and doesn't affect the dc level
609     // clipping
610     void DrawToDCClipped(wxDC *dc, const wxRect& rect);
611         void DrawToDCClippedRgn(wxDC *dc, const wxRegion& region);
612     // draw to dc with no clipping (well the dc will still clip)
613     void DrawToDC(wxDC *dc);
614     // draw a single object to the dc
615     void DrawIdToDC(int id, wxDC *dc);
616 
617     // ------------------------------------------------------------------------
618     // Hit Detection Methods
619     //
620     // returns list of object with a drawn pixel within radius pixels of (x,y)
621     // the list is in reverse draw order so last drawn is first in list
622     // PyObject *HitTest(wxCoord x, wxCoord y, double radius)
623     // returns list of objects whose bounding boxes include (x,y)
624     // PyObject *HitTestBB(wxCoord x, wxCoord y)
625 
626 
627     // ------------------------------------------------------------------------
628     // Methods mirrored from wxDC
629     //
630     void FloodFill(wxCoord x, wxCoord y, const wxColour& col,
631                    wxFloodFillStyle style = wxFLOOD_SURFACE)
632         {AddToList(new pdcFloodFillOp(x,y,col,style));}
633     void FloodFill(const wxPoint& pt, const wxColour& col,
634                    wxFloodFillStyle style = wxFLOOD_SURFACE)
635         { FloodFill(pt.x, pt.y, col, style); }
636 
DrawLine(wxCoord x1,wxCoord y1,wxCoord x2,wxCoord y2)637     void DrawLine(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2)
638         {AddToList(new pdcDrawLineOp(x1, y1, x2, y2));}
DrawLine(const wxPoint & pt1,const wxPoint & pt2)639     void DrawLine(const wxPoint& pt1, const wxPoint& pt2)
640         { DrawLine(pt1.x, pt1.y, pt2.x, pt2.y); }
641 
CrossHair(wxCoord x,wxCoord y)642     void CrossHair(wxCoord x, wxCoord y)
643         {AddToList(new pdcCrossHairOp(x,y));}
CrossHair(const wxPoint & pt)644     void CrossHair(const wxPoint& pt)
645         { CrossHair(pt.x, pt.y); }
646 
DrawArc(wxCoord x1,wxCoord y1,wxCoord x2,wxCoord y2,wxCoord xc,wxCoord yc)647     void DrawArc(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2,
648                  wxCoord xc, wxCoord yc)
649         {AddToList(new pdcDrawArcOp(x1,y1,x2,y2,xc,yc));}
DrawArc(const wxPoint & pt1,const wxPoint & pt2,const wxPoint & centre)650     void DrawArc(const wxPoint& pt1, const wxPoint& pt2, const wxPoint& centre)
651         { DrawArc(pt1.x, pt1.y, pt2.x, pt2.y, centre.x, centre.y); }
652 
DrawCheckMark(wxCoord x,wxCoord y,wxCoord width,wxCoord height)653     void DrawCheckMark(wxCoord x, wxCoord y,
654                        wxCoord width, wxCoord height)
655         {AddToList(new pdcDrawCheckMarkOp(x,y,width,height));}
DrawCheckMark(const wxRect & rect)656     void DrawCheckMark(const wxRect& rect)
657         { DrawCheckMark(rect.x, rect.y, rect.width, rect.height); }
658 
DrawEllipticArc(wxCoord x,wxCoord y,wxCoord w,wxCoord h,double sa,double ea)659     void DrawEllipticArc(wxCoord x, wxCoord y, wxCoord w, wxCoord h,
660                          double sa, double ea)
661         {AddToList(new pdcDrawEllipticArcOp(x,y,w,h,sa,ea));}
DrawEllipticArc(const wxPoint & pt,const wxSize & sz,double sa,double ea)662     void DrawEllipticArc(const wxPoint& pt, const wxSize& sz,
663                          double sa, double ea)
664         { DrawEllipticArc(pt.x, pt.y, sz.x, sz.y, sa, ea); }
665 
DrawPoint(wxCoord x,wxCoord y)666     void DrawPoint(wxCoord x, wxCoord y)
667         {AddToList(new pdcDrawPointOp(x,y));}
DrawPoint(const wxPoint & pt)668     void DrawPoint(const wxPoint& pt)
669         { DrawPoint(pt.x, pt.y); }
670 
671     void DrawPolygon(const wxPointList* points,
672                      wxCoord xoffset = 0,
673                      wxCoord yoffset = 0,
674                      wxPolygonFillMode fillStyle = wxODDEVEN_RULE)
675         {AddToList(new pdcDrawPolygonOp(points, xoffset, yoffset, fillStyle));}
676 
677     void DrawPolyPolygon(int n, int count[], wxPoint points[],
678                          wxCoord xoffset = 0, wxCoord yoffset = 0,
679                          wxPolygonFillMode fillStyle = wxODDEVEN_RULE)
680         {AddToList(new pdcDrawPolyPolygonOp(n,count,points,xoffset,yoffset,fillStyle));}
681 
DrawRectangle(wxCoord x,wxCoord y,wxCoord width,wxCoord height)682     void DrawRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
683         {AddToList(new pdcDrawRectangleOp(x, y, width, height));}
DrawRectangle(const wxPoint & pt,const wxSize & sz)684     void DrawRectangle(const wxPoint& pt, const wxSize& sz)
685         { DrawRectangle(pt.x, pt.y, sz.x, sz.y); }
DrawRectangle(const wxRect & rect)686     void DrawRectangle(const wxRect& rect)
687         { DrawRectangle(rect.x, rect.y, rect.width, rect.height); }
688 
DrawRoundedRectangle(wxCoord x,wxCoord y,wxCoord width,wxCoord height,double radius)689     void DrawRoundedRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height,
690                               double radius)
691         {AddToList(new pdcDrawRoundedRectangleOp(x,y,width,height,radius));}
DrawRoundedRectangle(const wxPoint & pt,const wxSize & sz,double radius)692     void DrawRoundedRectangle(const wxPoint& pt, const wxSize& sz,
693                              double radius)
694         { DrawRoundedRectangle(pt.x, pt.y, sz.x, sz.y, radius); }
DrawRoundedRectangle(const wxRect & r,double radius)695     void DrawRoundedRectangle(const wxRect& r, double radius)
696         { DrawRoundedRectangle(r.x, r.y, r.width, r.height, radius); }
697 
DrawCircle(wxCoord x,wxCoord y,wxCoord radius)698     void DrawCircle(wxCoord x, wxCoord y, wxCoord radius)
699         { DrawEllipse(x - radius, y - radius, 2*radius, 2*radius); }
DrawCircle(const wxPoint & pt,wxCoord radius)700     void DrawCircle(const wxPoint& pt, wxCoord radius)
701         { DrawCircle(pt.x, pt.y, radius); }
702 
DrawEllipse(wxCoord x,wxCoord y,wxCoord width,wxCoord height)703     void DrawEllipse(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
704         {AddToList(new pdcDrawEllipseOp(x,y,width,height));}
DrawEllipse(const wxPoint & pt,const wxSize & sz)705     void DrawEllipse(const wxPoint& pt, const wxSize& sz)
706         { DrawEllipse(pt.x, pt.y, sz.x, sz.y); }
DrawEllipse(const wxRect & rect)707     void DrawEllipse(const wxRect& rect)
708         { DrawEllipse(rect.x, rect.y, rect.width, rect.height); }
709 
DrawIcon(const wxIcon & icon,wxCoord x,wxCoord y)710     void DrawIcon(const wxIcon& icon, wxCoord x, wxCoord y)
711         {AddToList(new pdcDrawIconOp(icon,x,y));}
DrawIcon(const wxIcon & icon,const wxPoint & pt)712     void DrawIcon(const wxIcon& icon, const wxPoint& pt)
713         { DrawIcon(icon, pt.x, pt.y); }
714 
715     void DrawLines(const wxPointList* points,
716                    wxCoord xoffset = 0, wxCoord yoffset = 0)
717         { AddToList(new pdcDrawLinesOp(points, xoffset, yoffset)); }
718 
719     void DrawBitmap(const wxBitmap &bmp, wxCoord x, wxCoord y,
720                     bool useMask = false)
721         {AddToList(new pdcDrawBitmapOp(bmp,x,y,useMask));}
722     void DrawBitmap(const wxBitmap &bmp, const wxPoint& pt,
723                     bool useMask = false)
724         { DrawBitmap(bmp, pt.x, pt.y, useMask); }
725 
DrawText(const wxString & text,wxCoord x,wxCoord y)726     void DrawText(const wxString& text, wxCoord x, wxCoord y)
727         {AddToList(new pdcDrawTextOp(text, x, y));}
DrawText(const wxString & text,const wxPoint & pt)728     void DrawText(const wxString& text, const wxPoint& pt)
729         { DrawText(text, pt.x, pt.y); }
730 
DrawRotatedText(const wxString & text,wxCoord x,wxCoord y,double angle)731     void DrawRotatedText(const wxString& text, wxCoord x, wxCoord y, double angle)
732         {AddToList(new pdcDrawRotatedTextOp(text,x,y,angle));}
DrawRotatedText(const wxString & text,const wxPoint & pt,double angle)733     void DrawRotatedText(const wxString& text, const wxPoint& pt, double angle)
734         { DrawRotatedText(text, pt.x, pt.y, angle); }
735 
736     // this version puts both optional bitmap and the text into the given
737     // rectangle and aligns is as specified by alignment parameter; it also
738     // will emphasize the character with the given index if it is != -1
739     void DrawLabel(const wxString& text,
740                            const wxBitmap& image,
741                            const wxRect& rect,
742                            int alignment = wxALIGN_LEFT | wxALIGN_TOP,
743                            int indexAccel = -1)
744         {AddToList(new pdcDrawLabelOp(text,image,rect,alignment,indexAccel));}
745 
746     void DrawLabel(const wxString& text, const wxRect& rect,
747                    int alignment = wxALIGN_LEFT | wxALIGN_TOP,
748                    int indexAccel = -1)
749         { DrawLabel(text, wxNullBitmap, rect, alignment, indexAccel); }
750 
751 /*?????? I don't think that the source dc would stick around
752     void Blit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height,
753               wxDC *source, wxCoord xsrc, wxCoord ysrc,
754               int rop = wxCOPY, bool useMask = false, wxCoord xsrcMask = wxDefaultCoord, wxCoord ysrcMask = wxDefaultCoord)
755                 {AddToList(new pdcBlitOp(xdest,ydest,width,height,source,xsrc,
756                                          ysrc,rop,useMask,xsrcMask,ysrcMask));}
757     void Blit(const wxPoint& destPt, const wxSize& sz,
758               wxDC *source, const wxPoint& srcPt,
759               int rop = wxCOPY, bool useMask = false, const wxPoint& srcPtMask = wxDefaultPosition)
760     {
761         Blit(destPt.x, destPt.y, sz.x, sz.y, source, srcPt.x, srcPt.y,
762              rop, useMask, srcPtMask.x, srcPtMask.y);
763     }
764 ??????*/
765 
766 #if wxUSE_SPLINES
DrawSpline(const wxPointList * points)767     void DrawSpline(const wxPointList* points)
768         { AddToList(new pdcDrawSplineOp(points)); }
769 #endif // wxUSE_SPLINES
770 
771 #if wxUSE_PALETTE
SetPalette(const wxPalette & palette)772     void SetPalette(const wxPalette& palette)
773         {AddToList(new pdcSetPaletteOp(palette));}
774 #endif // wxUSE_PALETTE
775 
SetLogicalFunction(wxRasterOperationMode function)776     void SetLogicalFunction(wxRasterOperationMode function)
777         {AddToList(new pdcSetLogicalFunctionOp(function));}
SetFont(const wxFont & font)778     void SetFont(const wxFont& font)
779         {AddToList(new pdcSetFontOp(font));}
SetPen(const wxPen & pen)780     void SetPen(const wxPen& pen)
781         {AddToList(new pdcSetPenOp(pen));}
SetBrush(const wxBrush & brush)782     void SetBrush(const wxBrush& brush)
783         {AddToList(new pdcSetBrushOp(brush));}
SetBackground(const wxBrush & brush)784     void SetBackground(const wxBrush& brush)
785         {AddToList(new pdcSetBackgroundOp(brush));}
SetBackgroundMode(int mode)786     void SetBackgroundMode(int mode)
787         {AddToList(new pdcSetBackgroundModeOp(mode));}
SetTextBackground(const wxColour & colour)788     void SetTextBackground(const wxColour& colour)
789         {AddToList(new pdcSetTextBackgroundOp(colour));}
SetTextForeground(const wxColour & colour)790     void SetTextForeground(const wxColour& colour)
791         {AddToList(new pdcSetTextForegroundOp(colour));}
792 
Clear()793     void Clear()
794         {AddToList(new pdcClearOp());}
BeginDrawing()795     void BeginDrawing()
796         {AddToList(new pdcBeginDrawingOp());}
EndDrawing()797     void EndDrawing()
798         {AddToList(new pdcEndDrawingOp());}
799 
800 protected:
801     // ------------------------------------------------------------------------
802     // protected helper methods
803     void AddToList(pdcOp *newOp);
804     pdcObject *FindObject(int id, bool create=false);
805 
806     // ------------------------------------------------------------------------
807     // Data members
808     //
809     int m_currId; // id to use for operations done on the PseudoDC
810     pdcObject *m_lastObject; // used to find last used object quickly
811     pdcObjectList m_objectlist; // list of objects
812     pdcObjectHash m_objectIndex; //id->object lookup index
813 
814 };
815 
816 #endif
817 
818