Added the PseudoDC class from Paul Lanier. It provides a way to

record operations on a DC and then play them back later.


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@40054 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robin Dunn
2006-07-10 15:06:31 +00:00
parent 8e372bbe07
commit 7e664d85e6
7 changed files with 1998 additions and 2 deletions

View File

@@ -51,6 +51,7 @@ _treeList = [
'AUI',
'CheckListCtrlMixin',
'Pickers',
'PseudoDC',
'RichTextCtrl',
'Treebook',
'Toolbook',
@@ -248,6 +249,7 @@ _treeList = [
'MouseGestures',
'OGL',
'PrintFramework',
'PseudoDC',
'ShapedWindow',
'Sound',
'StandardPaths',

306
wxPython/demo/PseudoDC.py Normal file
View File

@@ -0,0 +1,306 @@
import wx
import images
import random
#---------------------------------------------------------------------------
W = 1000
H = 1000
SW = 150
SH = 150
SHAPE_COUNT = 100
MOVING_COUNT = 10
#---------------------------------------------------------------------------
colours = [
"BLACK",
"BLUE",
"BLUE VIOLET",
"BROWN",
"CYAN",
"DARK GREY",
"DARK GREEN",
"GOLD",
"GREY",
"GREEN",
"MAGENTA",
"NAVY",
"PINK",
"RED",
"SKY BLUE",
"VIOLET",
"YELLOW",
]
class MyCanvas(wx.ScrolledWindow):
def __init__(self, parent, id, log, size = wx.DefaultSize):
wx.ScrolledWindow.__init__(self, parent, id, (0, 0), size=size, style=wx.SUNKEN_BORDER)
self.lines = []
self.maxWidth = W
self.maxHeight = H
self.x = self.y = 0
self.curLine = []
self.drawing = False
self.SetBackgroundColour("WHITE")
bmp = images.getTest2Bitmap()
mask = wx.Mask(bmp, wx.BLUE)
bmp.SetMask(mask)
self.bmp = bmp
self.SetVirtualSize((self.maxWidth, self.maxHeight))
self.SetScrollRate(20,20)
# create a PseudoDC to record our drawing
self.pdc = wx.PseudoDC()
self.pen_cache = {}
self.brush_cache = {}
self.DoDrawing(self.pdc)
log.write('Created PseudoDC draw list with %d operations!'%self.pdc.GetLen())
self.Bind(wx.EVT_PAINT, self.OnPaint)
self.Bind(wx.EVT_ERASE_BACKGROUND, lambda x:None)
# use timer to move one of the objects around
self.timer = wx.Timer()
self.timer.SetOwner(self)
self.Bind(wx.EVT_TIMER, self.OnTimer)
self.timer.Start(50)
self.movingids = random.sample(self.objids, MOVING_COUNT)
self.velocitydict = {}
for id in self.movingids:
vx = random.randint(1,5) * random.choice([-1,1])
vy = random.randint(1,5) * random.choice([-1,1])
self.velocitydict[id] = (vx,vy)
def OnTimer(self, event):
# get the current position
xv, yv = self.GetViewStart()
dx, dy = self.GetScrollPixelsPerUnit()
x, y = (xv * dx, yv * dy)
w, h = self.GetClientSizeTuple()
clip = wx.Rect(x,y,w,h)
refreshed = False
for id in self.movingids:
r = self.pdc.GetIdBounds(id)
# get new object position
(vx,vy) = self.velocitydict[id]
x = r.x + vx
y = r.y + vy
# check for bounce
if x < 0:
x = -x
vx = -vx
if x >= W:
x = W - (x - W)
vx = -vx
if y < 0:
y = -y
vy = -vy
if y >= H:
y = H - (y - H)
vy = -vy
self.velocitydict[id] = (vx,vy)
# get change
dx = x - r.x
dy = y - r.y
# translate the object
self.pdc.TranslateId(id, dx, dy)
# redraw
r.x -= 20
if dx < 0:
r.x = x
r.y -= 20
if dy < 0:
r.y = y
r.width += abs(dx) + 40
r.height += abs(dy) + 40
if r.Intersects(clip):
r.x -= clip.x
r.y -= clip.y
refreshed = True
self.RefreshRect(r, False)
def RandomPen(self):
c = random.choice(colours)
t = random.randint(1, 4)
if not self.pen_cache.has_key( (c, t) ):
self.pen_cache[(c, t)] = wx.Pen(c, t)
return self.pen_cache[(c, t)]
def RandomBrush(self):
c = random.choice(colours)
if not self.brush_cache.has_key(c):
self.brush_cache[c] = wx.Brush(c)
return self.brush_cache[c]
def RandomColor(self):
return random.choice(colours)
def OnPaint(self, event):
# Create a buffered paint DC. It will create the real
# wx.PaintDC and then blit the bitmap to it when dc is
# deleted.
dc = wx.BufferedPaintDC(self)
# we need to clear the dc BEFORE calling PrepareDC
bg = wx.Brush(self.GetBackgroundColour())
dc.SetBackground(bg)
dc.Clear()
# use PrepateDC to set position correctly
self.PrepareDC(dc)
# create a clipping rect from our position and size
# and the Update Region
xv, yv = self.GetViewStart()
dx, dy = self.GetScrollPixelsPerUnit()
x, y = (xv * dx, yv * dy)
rgn = self.GetUpdateRegion()
rgn.Offset(x,y)
r = rgn.GetBox()
# draw to the dc using the calculated clipping rect
self.pdc.DrawToDCClipped(dc,r)
def DoDrawing(self, dc):
random.seed()
self.objids = []
self.boundsdict = {}
dc.BeginDrawing()
for i in range(SHAPE_COUNT):
id = wx.NewId()
dc.SetId(id)
choice = random.randint(0,8)
if choice in (0,1):
x = random.randint(0, W)
y = random.randint(0, H)
dc.SetPen(self.RandomPen())
dc.DrawPoint(x,y)
dc.SetIdBounds(id,wx.Rect(x,y,1,1))
elif choice in (2,3):
x1 = random.randint(0, W-SW)
y1 = random.randint(0, H-SH)
x2 = random.randint(x1, x1+SW)
y2 = random.randint(y1, y1+SH)
dc.SetPen(self.RandomPen())
dc.DrawLine(x1,y1,x2,y2)
dc.SetIdBounds(id,wx.Rect(x1,y1,x2-x1,y2-y1))
elif choice in (4,5):
w = random.randint(10, SW)
h = random.randint(10, SH)
x = random.randint(0, W - w)
y = random.randint(0, H - h)
dc.SetPen(self.RandomPen())
dc.SetBrush(self.RandomBrush())
dc.DrawRectangle(x,y,w,h)
dc.SetIdBounds(id,wx.Rect(x,y,w,h))
self.objids.append(id)
elif choice == 6:
Np = 8 # number of characters in text
word = []
for i in range(Np):
c = chr( random.randint(48, 122) )
word.append( c )
word = "".join(word)
w,h = self.GetFullTextExtent(word)[0:2]
x = random.randint(0, W-w)
y = random.randint(0, H-h)
dc.SetTextForeground(self.RandomColor())
dc.SetTextBackground(self.RandomColor())
dc.DrawText(word, x, y)
dc.SetIdBounds(id,wx.Rect(x,y,w,h))
self.objids.append(id)
elif choice == 7:
Np = 8 # number of points per polygon
poly = []
minx = SW
miny = SH
maxx = 0
maxy = 0
for i in range(Np):
x = random.randint(0, SW)
y = random.randint(0, SH)
if x < minx: minx = x
if x > maxx: maxx = x
if y < miny: miny = y
if y > maxy: maxy = y
poly.append(wx.Point(x,y))
x = random.randint(0, W-SW)
y = random.randint(0, H-SH)
dc.SetPen(self.RandomPen())
dc.SetBrush(self.RandomBrush())
dc.DrawPolygon(poly, x,y)
dc.SetIdBounds(id,wx.Rect(minx+x,miny+y,maxx-minx+x,maxy-miny+y))
self.objids.append(id)
elif choice == 8:
w,h = self.bmp.GetSize()
x = random.randint(0, W-w)
y = random.randint(0, H-h)
dc.DrawBitmap(self.bmp,x,y,True)
dc.SetIdBounds(id,wx.Rect(x,y,w,h))
self.objids.append(id)
dc.EndDrawing()
def ShutdownDemo(self):
self.timer.Stop()
del self.timer
#---------------------------------------------------------------------------
def runTest(frame, nb, log):
win = MyCanvas(nb, wx.ID_ANY, log)
return win
#---------------------------------------------------------------------------
overview = """
<html>
<body>
The wx.PseudoDC class provides a way to record operations on a DC and then
play them back later. The PseudoDC can be passed to a drawing routine as
if it were a real DC. All Drawing methods are supported except Blit but
GetXXX methods are not supported and none of the drawing methods return
a value. The PseudoDC records the drawing to an operation
list. The operations can be played back to a real DC using:<pre>
DrawToDC(dc)
</pre>
The operations can be tagged with an id in order to associated them with a
specific object. To do this use:<pre>
SetId(id)
</pre>
Every operation after this will be associated with id until SetId is called
again. The PseudoDC also supports object level clipping. To enable this use:<pre>
SetIdBounds(id,rect)
</pre>
for each object that should be clipped. Then use:<pre>
DrawToDCClipped(dc, clippingRect)
</pre>
To draw the PseudoDC to a real dc. This is useful for large scrolled windows
where many objects are offscreen.
Objects can be moved around without re-drawing using:<pre>
TranslateId(id, dx, dy)
</pre>
To re-draw an object use:<pre>
ClearId(id)
SetId(id)
</pre>
and then re-draw the object.
</body>
</html>
"""
if __name__ == '__main__':
import sys,os
import run
run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])

View File

@@ -172,6 +172,10 @@ channel.
Added wrappers for the wxAUI classes, in the wx.aui module.
Added the PseudoDC class from Paul Lanier. It provides a way to
record operations on a DC and then play them back later.

View File

@@ -0,0 +1,736 @@
/////////////////////////////////////////////////////////////////////////////
// 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/wx.h"
#include "wx/dc.h"
//----------------------------------------------------------------------------
// Base class for all pdcOp classes
//----------------------------------------------------------------------------
class pdcOp
{
public:
// Constructor and Destructor
pdcOp() {}
virtual ~pdcOp() {}
// Virtual Drawing Methods
virtual void DrawToDC(wxDC *dc)=0;
virtual void Translate(wxCoord WXUNUSED(dx), wxCoord WXUNUSED(dy)) {}
};
//----------------------------------------------------------------------------
// declare a list class for list of pdcOps
//----------------------------------------------------------------------------
WX_DECLARE_LIST(pdcOp, pdcOpList);
//----------------------------------------------------------------------------
// Classes derived from pdcOp
// There is one class for each method mirrored from wxDC to wxPseudoDC
//----------------------------------------------------------------------------
class pdcSetFontOp : public pdcOp
{
public:
pdcSetFontOp(const wxFont& font)
{m_font=font;}
virtual void DrawToDC(wxDC *dc) {dc->SetFont(m_font);}
protected:
wxFont m_font;
};
class pdcSetBrushOp : public pdcOp
{
public:
pdcSetBrushOp(const wxBrush& brush)
{m_brush=brush;}
virtual void DrawToDC(wxDC *dc) {dc->SetBrush(m_brush);}
protected:
wxBrush m_brush;
};
class pdcSetBackgroundOp : public pdcOp
{
public:
pdcSetBackgroundOp(const wxBrush& brush)
{m_brush=brush;}
virtual void DrawToDC(wxDC *dc) {dc->SetBackground(m_brush);}
protected:
wxBrush m_brush;
};
class pdcSetPenOp : public pdcOp
{
public:
pdcSetPenOp(const wxPen& pen)
{m_pen=pen;}
virtual void DrawToDC(wxDC *dc) {dc->SetPen(m_pen);}
protected:
wxPen m_pen;
};
class pdcSetTextBackgroundOp : public pdcOp
{
public:
pdcSetTextBackgroundOp(const wxColour& colour)
{m_colour=colour;}
virtual void DrawToDC(wxDC *dc) {dc->SetTextBackground(m_colour);}
protected:
wxColour m_colour;
};
class pdcSetTextForegroundOp : public pdcOp
{
public:
pdcSetTextForegroundOp(const wxColour& colour)
{m_colour=colour;}
virtual void DrawToDC(wxDC *dc) {dc->SetTextForeground(m_colour);}
protected:
wxColour m_colour;
};
class pdcDrawRectangleOp : public pdcOp
{
public:
pdcDrawRectangleOp(wxCoord x, wxCoord y, wxCoord w, wxCoord h)
{m_x=x; m_y=y; m_w=w; m_h=h;}
virtual void DrawToDC(wxDC *dc) {dc->DrawRectangle(m_x,m_y,m_w,m_h);}
virtual void Translate(wxCoord dx, wxCoord dy)
{m_x+=dx;m_y+=dy;}
protected:
wxCoord m_x,m_y,m_w,m_h;
};
class pdcDrawLineOp : public pdcOp
{
public:
pdcDrawLineOp(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2)
{m_x1=x1; m_y1=y1; m_x2=x2; m_y2=y2;}
virtual void DrawToDC(wxDC *dc) {dc->DrawLine(m_x1,m_y1,m_x2,m_y2);}
virtual void Translate(wxCoord dx, wxCoord dy)
{m_x1+=dx; m_y1+=dy; m_x2+=dx; m_y2+=dy;}
protected:
wxCoord m_x1,m_y1,m_x2,m_y2;
};
class pdcSetBackgroundModeOp : public pdcOp
{
public:
pdcSetBackgroundModeOp(int mode) {m_mode=mode;}
virtual void DrawToDC(wxDC *dc) {dc->SetBackgroundMode(m_mode);}
protected:
int m_mode;
};
class pdcDrawTextOp : public pdcOp
{
public:
pdcDrawTextOp(const wxString& text, wxCoord x, wxCoord y)
{m_text=text; m_x=x; m_y=y;}
virtual void DrawToDC(wxDC *dc) {dc->DrawText(m_text, m_x, m_y);}
virtual void Translate(wxCoord dx, wxCoord dy)
{m_x+=dx; m_y+=dy;}
protected:
wxString m_text;
wxCoord m_x, m_y;
};
class pdcClearOp : public pdcOp
{
public:
pdcClearOp() {}
virtual void DrawToDC(wxDC *dc) {dc->Clear();}
};
class pdcBeginDrawingOp : public pdcOp
{
public:
pdcBeginDrawingOp() {}
virtual void DrawToDC(wxDC *dc) {dc->BeginDrawing();}
};
class pdcEndDrawingOp : public pdcOp
{
public:
pdcEndDrawingOp() {}
virtual void DrawToDC(wxDC *dc) {dc->EndDrawing();}
};
class pdcFloodFillOp : public pdcOp
{
public:
pdcFloodFillOp(wxCoord x, wxCoord y, const wxColour& col,
int style) {m_x=x; m_y=y; m_col=col; m_style=style;}
virtual void DrawToDC(wxDC *dc) {dc->FloodFill(m_x,m_y,m_col,m_style);}
virtual void Translate(wxCoord dx, wxCoord dy)
{m_x+=dx; m_y+=dy;}
protected:
wxCoord m_x,m_y;
wxColour m_col;
int m_style;
};
class pdcCrossHairOp : public pdcOp
{
public:
pdcCrossHairOp(wxCoord x, wxCoord y) {m_x=x; m_y=y;}
virtual void DrawToDC(wxDC *dc) {dc->CrossHair(m_x,m_y);}
virtual void Translate(wxCoord dx, wxCoord dy)
{m_x+=dx; m_y+=dy;}
protected:
wxCoord m_x,m_y;
};
class pdcDrawArcOp : public pdcOp
{
public:
pdcDrawArcOp(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2,
wxCoord xc, wxCoord yc)
{m_x1=x1; m_y1=y1; m_x2=x2; m_y2=y2; m_xc=xc; m_yc=yc;}
virtual void DrawToDC(wxDC *dc)
{dc->DrawArc(m_x1,m_y1,m_x2,m_y2,m_xc,m_yc);}
virtual void Translate(wxCoord dx, wxCoord dy)
{m_x1+=dx; m_x2+=dx; m_y1+=dy; m_y2+=dy;}
protected:
wxCoord m_x1,m_x2,m_xc;
wxCoord m_y1,m_y2,m_yc;
};
class pdcDrawCheckMarkOp : public pdcOp
{
public:
pdcDrawCheckMarkOp(wxCoord x, wxCoord y,
wxCoord width, wxCoord height)
{m_x=x; m_y=y; m_w=width; m_h=height;}
virtual void DrawToDC(wxDC *dc)
{dc->DrawCheckMark(m_x,m_y,m_w,m_h);}
virtual void Translate(wxCoord dx, wxCoord dy)
{m_x+=dx; m_y+=dy;}
protected:
wxCoord m_x,m_y,m_w,m_h;
};
class pdcDrawEllipticArcOp : public pdcOp
{
public:
pdcDrawEllipticArcOp(wxCoord x, wxCoord y, wxCoord w, wxCoord h,
double sa, double ea)
{m_x=x; m_y=y; m_w=w; m_h=h; m_sa=sa; m_ea=ea;}
virtual void DrawToDC(wxDC *dc)
{dc->DrawEllipticArc(m_x,m_y,m_w,m_h,m_sa,m_ea);}
virtual void Translate(wxCoord dx, wxCoord dy)
{m_x+=dx; m_y+=dy;}
protected:
wxCoord m_x,m_y,m_w,m_h;
double m_sa,m_ea;
};
class pdcDrawPointOp : public pdcOp
{
public:
pdcDrawPointOp(wxCoord x, wxCoord y)
{m_x=x; m_y=y;}
virtual void DrawToDC(wxDC *dc) {dc->DrawPoint(m_x,m_y);}
virtual void Translate(wxCoord dx, wxCoord dy)
{m_x+=dx; m_y+=dy;}
protected:
wxCoord m_x,m_y;
};
class pdcDrawRoundedRectangleOp : public pdcOp
{
public:
pdcDrawRoundedRectangleOp(wxCoord x, wxCoord y, wxCoord width,
wxCoord height, double radius)
{m_x=x; m_y=y; m_w=width; m_h=height; m_r=radius;}
virtual void DrawToDC(wxDC *dc)
{dc->DrawRoundedRectangle(m_x,m_y,m_w,m_h,m_r);}
virtual void Translate(wxCoord dx, wxCoord dy)
{m_x+=dx; m_y+=dy;}
protected:
wxCoord m_x,m_y,m_w,m_h;
double m_r;
};
class pdcDrawEllipseOp : public pdcOp
{
public:
pdcDrawEllipseOp(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
{m_x=x; m_y=y; m_w=width; m_h=height;}
virtual void DrawToDC(wxDC *dc) {dc->DrawEllipse(m_x,m_y,m_w,m_h);}
virtual void Translate(wxCoord dx, wxCoord dy)
{m_x+=dx; m_y+=dy;}
protected:
wxCoord m_x,m_y,m_w,m_h;
};
class pdcDrawIconOp : public pdcOp
{
public:
pdcDrawIconOp(const wxIcon& icon, wxCoord x, wxCoord y)
{m_icon=icon; m_x=x; m_y=y;}
virtual void DrawToDC(wxDC *dc) {dc->DrawIcon(m_icon,m_x,m_y);}
virtual void Translate(wxCoord dx, wxCoord dy)
{m_x+=dx; m_y+=dy;}
protected:
wxIcon m_icon;
wxCoord m_x,m_y;
};
class pdcDrawLinesOp : public pdcOp
{
public:
pdcDrawLinesOp(int n, wxPoint points[],
wxCoord xoffset = 0, wxCoord yoffset = 0);
virtual ~pdcDrawLinesOp();
virtual void DrawToDC(wxDC *dc)
{dc->DrawLines(m_n,m_points,m_xoffset,m_yoffset);}
virtual void Translate(wxCoord dx, wxCoord dy)
{
for(int i=0; i<m_n; i++)
{
m_points[i].x+=dx;
m_points[i].y+=dy;
}
}
protected:
int m_n;
wxPoint *m_points;
wxCoord m_xoffset,m_yoffset;
};
class pdcDrawPolygonOp : public pdcOp
{
public:
pdcDrawPolygonOp(int n, wxPoint points[],
wxCoord xoffset = 0, wxCoord yoffset = 0,
int fillStyle = wxODDEVEN_RULE);
virtual ~pdcDrawPolygonOp();
virtual void DrawToDC(wxDC *dc)
{ dc->DrawPolygon(m_n,m_points,m_xoffset,m_yoffset,m_fillStyle); }
virtual void Translate(wxCoord dx, wxCoord dy)
{
for(int i=0; i<m_n; i++)
{
m_points[i].x+=dx;
m_points[i].y+=dy;
}
}
protected:
int m_n;
wxPoint *m_points;
wxCoord m_xoffset,m_yoffset;
int m_fillStyle;
};
class pdcDrawPolyPolygonOp : public pdcOp
{
public:
pdcDrawPolyPolygonOp(int n, int count[], wxPoint points[],
wxCoord xoffset = 0, wxCoord yoffset = 0,
int fillStyle = wxODDEVEN_RULE);
virtual ~pdcDrawPolyPolygonOp();
virtual void DrawToDC(wxDC *dc)
{dc->DrawPolyPolygon(m_n,m_count,m_points,
m_xoffset,m_yoffset,m_fillStyle);}
virtual void Translate(wxCoord dx, wxCoord dy)
{
for(int i=0; i<m_totaln; i++)
{
m_points[i].x += dx;
m_points[i].y += dy;
}
}
protected:
int m_n;
int m_totaln;
int *m_count;
wxPoint *m_points;
wxCoord m_xoffset, m_yoffset;
int m_fillStyle;
};
class pdcDrawRotatedTextOp : public pdcOp
{
public:
pdcDrawRotatedTextOp(const wxString& text, wxCoord x, wxCoord y, double angle)
{m_text=text; m_x=x; m_y=y; m_angle=angle;}
virtual void DrawToDC(wxDC *dc)
{dc->DrawRotatedText(m_text,m_x,m_y,m_angle);}
virtual void Translate(wxCoord dx, wxCoord dy)
{m_x+=dx; m_y+=dy;}
protected:
wxString m_text;
wxCoord m_x,m_y;
double m_angle;
};
class pdcDrawBitmapOp : public pdcOp
{
public:
pdcDrawBitmapOp(const wxBitmap &bmp, wxCoord x, wxCoord y,
bool useMask = false)
{m_bmp=bmp; m_x=x; m_y=y; m_useMask=useMask;}
virtual void DrawToDC(wxDC *dc) {dc->DrawBitmap(m_bmp,m_x,m_y,m_useMask);}
virtual void Translate(wxCoord dx, wxCoord dy)
{m_x+=dx; m_y+=dy;}
protected:
wxBitmap m_bmp;
wxCoord m_x,m_y;
bool m_useMask;
};
class pdcDrawLabelOp : public pdcOp
{
public:
pdcDrawLabelOp(const wxString& text,
const wxBitmap& image,
const wxRect& rect,
int alignment = wxALIGN_LEFT | wxALIGN_TOP,
int indexAccel = -1)
{m_text=text; m_image=image; m_rect=rect;
m_align=alignment; m_iAccel=indexAccel;}
virtual void DrawToDC(wxDC *dc)
{dc->DrawLabel(m_text,m_image,m_rect,m_align,m_iAccel);}
virtual void Translate(wxCoord dx, wxCoord dy)
{m_rect.x+=dx; m_rect.y+=dy;}
protected:
wxString m_text;
wxBitmap m_image;
wxRect m_rect;
int m_align;
int m_iAccel;
};
#if wxUSE_SPLINES
class pdcDrawSplineOp : public pdcOp
{
public:
pdcDrawSplineOp(int n, wxPoint points[]);
virtual ~pdcDrawSplineOp();
virtual void DrawToDC(wxDC *dc) {dc->DrawSpline(m_n,m_points);}
virtual void Translate(wxCoord dx, wxCoord dy)
{
int i;
for(i=0; i<m_n; i++)
m_points[i].x+=dx; m_points[i].y+=dy;
}
protected:
wxPoint *m_points;
int m_n;
};
#endif // wxUSE_SPLINES
#if wxUSE_PALETTE
class pdcSetPaletteOp : public pdcOp
{
public:
pdcSetPaletteOp(const wxPalette& palette) {m_palette=palette;}
virtual void DrawToDC(wxDC *dc) {dc->SetPalette(m_palette);}
protected:
wxPalette m_palette;
};
#endif // wxUSE_PALETTE
class pdcSetLogicalFunctionOp : public pdcOp
{
public:
pdcSetLogicalFunctionOp(int function) {m_function=function;}
virtual void DrawToDC(wxDC *dc) {dc->SetLogicalFunction(m_function);}
protected:
int m_function;
};
//----------------------------------------------------------------------------
// pdcObject type to contain list of operations for each real (Python) object
//----------------------------------------------------------------------------
class pdcObject
{
public:
pdcObject(int id)
{m_id=id; m_bounded=false; m_oplist.DeleteContents(true);}
virtual ~pdcObject() {m_oplist.Clear();}
// Protected Member Access
void SetId(int id) {m_id=id;}
int GetId() {return m_id;}
void SetBounds(wxRect& rect) {m_bounds=rect; m_bounded=true;}
wxRect GetBounds() {return m_bounds;}
void SetBounded(bool bounded) {m_bounded=bounded;}
bool IsBounded() {return m_bounded;}
// Op List Management Methods
void Clear() {m_oplist.Clear();}
void AddOp(pdcOp *op) {m_oplist.Append(op);}
int GetLen() {return m_oplist.GetCount();}
virtual void Translate(wxCoord dx, wxCoord dy);
// Drawing Method
virtual void DrawToDC(wxDC *dc);
protected:
int m_id; // id of object (associates this pdcObject
// with a Python object with same id)
wxRect m_bounds; // bounding rect of this object
bool m_bounded; // true if bounds is valid, false by default
pdcOpList m_oplist; // list of operations for this object
};
//----------------------------------------------------------------------------
// Declare a wxList to hold all the objects. List order reflects drawing
// order (Z order) and is the same order as objects are added to the list
//----------------------------------------------------------------------------
class WXDLLEXPORT pdcObjectList;
WX_DECLARE_LIST(pdcObject, pdcObjectList);
// ----------------------------------------------------------------------------
// 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=-1; m_lastObjNode=NULL; m_objectlist.DeleteContents(true);}
~wxPseudoDC();
// ------------------------------------------------------------------------
// List managment methods
//
void RemoveAll();
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 so it can be redrawn
void ClearId(int id);
// Remove the object node (and all operations) associated with an id
void RemoveId(int id);
// Set the bounding rect of a given object
// This will create an object node if one doesn't exist
void SetIdBounds(int id, wxRect& rect);
void GetIdBounds(int id, wxRect& rect);
// Translate all the operations for this id
void TranslateId(int id, wxCoord dx, wxCoord dy);
// ------------------------------------------------------------------------
// Playback Methods
//
// draw to dc but skip objects 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);
void DrawToDCClippedRgn(wxDC *dc, const wxRegion& region);
// draw to dc with no clipping (well the dc will still clip)
void DrawToDC(wxDC *dc);
// draw a single object to the dc
void DrawIdToDC(int id, wxDC *dc);
// ------------------------------------------------------------------------
// Methods mirrored from wxDC
//
void FloodFill(wxCoord x, wxCoord y, const wxColour& col,
int style = wxFLOOD_SURFACE)
{AddToList(new pdcFloodFillOp(x,y,col,style));}
void FloodFill(const wxPoint& pt, const wxColour& col,
int style = wxFLOOD_SURFACE)
{ FloodFill(pt.x, pt.y, col, style); }
void DrawLine(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2)
{AddToList(new pdcDrawLineOp(x1, y1, x2, y2));}
void DrawLine(const wxPoint& pt1, const wxPoint& pt2)
{ DrawLine(pt1.x, pt1.y, pt2.x, pt2.y); }
void CrossHair(wxCoord x, wxCoord y)
{AddToList(new pdcCrossHairOp(x,y));}
void CrossHair(const wxPoint& pt)
{ CrossHair(pt.x, pt.y); }
void DrawArc(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2,
wxCoord xc, wxCoord yc)
{AddToList(new pdcDrawArcOp(x1,y1,x2,y2,xc,yc));}
void DrawArc(const wxPoint& pt1, const wxPoint& pt2, const wxPoint& centre)
{ DrawArc(pt1.x, pt1.y, pt2.x, pt2.y, centre.x, centre.y); }
void DrawCheckMark(wxCoord x, wxCoord y,
wxCoord width, wxCoord height)
{AddToList(new pdcDrawCheckMarkOp(x,y,width,height));}
void DrawCheckMark(const wxRect& rect)
{ DrawCheckMark(rect.x, rect.y, rect.width, rect.height); }
void DrawEllipticArc(wxCoord x, wxCoord y, wxCoord w, wxCoord h,
double sa, double ea)
{AddToList(new pdcDrawEllipticArcOp(x,y,w,h,sa,ea));}
void DrawEllipticArc(const wxPoint& pt, const wxSize& sz,
double sa, double ea)
{ DrawEllipticArc(pt.x, pt.y, sz.x, sz.y, sa, ea); }
void DrawPoint(wxCoord x, wxCoord y)
{AddToList(new pdcDrawPointOp(x,y));}
void DrawPoint(const wxPoint& pt)
{ DrawPoint(pt.x, pt.y); }
void DrawPolygon(int n, wxPoint points[],
wxCoord xoffset = 0, wxCoord yoffset = 0,
int fillStyle = wxODDEVEN_RULE)
{AddToList(new pdcDrawPolygonOp(n,points,xoffset,yoffset,fillStyle));}
void DrawPolyPolygon(int n, int count[], wxPoint points[],
wxCoord xoffset = 0, wxCoord yoffset = 0,
int fillStyle = wxODDEVEN_RULE)
{AddToList(new pdcDrawPolyPolygonOp(n,count,points,xoffset,yoffset,fillStyle));}
void DrawRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
{AddToList(new pdcDrawRectangleOp(x, y, width, height));}
void DrawRectangle(const wxPoint& pt, const wxSize& sz)
{ DrawRectangle(pt.x, pt.y, sz.x, sz.y); }
void DrawRectangle(const wxRect& rect)
{ DrawRectangle(rect.x, rect.y, rect.width, rect.height); }
void DrawRoundedRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height,
double radius)
{AddToList(new pdcDrawRoundedRectangleOp(x,y,width,height,radius));}
void DrawRoundedRectangle(const wxPoint& pt, const wxSize& sz,
double radius)
{ DrawRoundedRectangle(pt.x, pt.y, sz.x, sz.y, radius); }
void DrawRoundedRectangle(const wxRect& r, double radius)
{ DrawRoundedRectangle(r.x, r.y, r.width, r.height, radius); }
void DrawCircle(wxCoord x, wxCoord y, wxCoord radius)
{ DrawEllipse(x - radius, y - radius, 2*radius, 2*radius); }
void DrawCircle(const wxPoint& pt, wxCoord radius)
{ DrawCircle(pt.x, pt.y, radius); }
void DrawEllipse(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
{AddToList(new pdcDrawEllipseOp(x,y,width,height));}
void DrawEllipse(const wxPoint& pt, const wxSize& sz)
{ DrawEllipse(pt.x, pt.y, sz.x, sz.y); }
void DrawEllipse(const wxRect& rect)
{ DrawEllipse(rect.x, rect.y, rect.width, rect.height); }
void DrawIcon(const wxIcon& icon, wxCoord x, wxCoord y)
{AddToList(new pdcDrawIconOp(icon,x,y));}
void DrawIcon(const wxIcon& icon, const wxPoint& pt)
{ DrawIcon(icon, pt.x, pt.y); }
void DrawLines(int n, wxPoint points[],
wxCoord xoffset = 0, wxCoord yoffset = 0)
{AddToList(new pdcDrawLinesOp(n,points,xoffset,yoffset));}
void DrawBitmap(const wxBitmap &bmp, wxCoord x, wxCoord y,
bool useMask = false)
{AddToList(new pdcDrawBitmapOp(bmp,x,y,useMask));}
void DrawBitmap(const wxBitmap &bmp, const wxPoint& pt,
bool useMask = false)
{ DrawBitmap(bmp, pt.x, pt.y, useMask); }
void DrawText(const wxString& text, wxCoord x, wxCoord y)
{AddToList(new pdcDrawTextOp(text, x, y));}
void DrawText(const wxString& text, const wxPoint& pt)
{ DrawText(text, pt.x, pt.y); }
void DrawRotatedText(const wxString& text, wxCoord x, wxCoord y, double angle)
{AddToList(new pdcDrawRotatedTextOp(text,x,y,angle));}
void DrawRotatedText(const wxString& text, const wxPoint& pt, double angle)
{ DrawRotatedText(text, pt.x, pt.y, angle); }
// this version puts both optional bitmap and the text into the given
// rectangle and aligns is as specified by alignment parameter; it also
// will emphasize the character with the given index if it is != -1
void DrawLabel(const wxString& text,
const wxBitmap& image,
const wxRect& rect,
int alignment = wxALIGN_LEFT | wxALIGN_TOP,
int indexAccel = -1)
{AddToList(new pdcDrawLabelOp(text,image,rect,alignment,indexAccel));}
void DrawLabel(const wxString& text, const wxRect& rect,
int alignment = wxALIGN_LEFT | wxALIGN_TOP,
int indexAccel = -1)
{ DrawLabel(text, wxNullBitmap, rect, alignment, indexAccel); }
/*?????? I don't think that the source dc would stick around
void Blit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height,
wxDC *source, wxCoord xsrc, wxCoord ysrc,
int rop = wxCOPY, bool useMask = false, wxCoord xsrcMask = wxDefaultCoord, wxCoord ysrcMask = wxDefaultCoord)
{AddToList(new pdcBlitOp(xdest,ydest,width,height,source,xsrc,
ysrc,rop,useMask,xsrcMask,ysrcMask));}
void Blit(const wxPoint& destPt, const wxSize& sz,
wxDC *source, const wxPoint& srcPt,
int rop = wxCOPY, bool useMask = false, const wxPoint& srcPtMask = wxDefaultPosition)
{
Blit(destPt.x, destPt.y, sz.x, sz.y, source, srcPt.x, srcPt.y,
rop, useMask, srcPtMask.x, srcPtMask.y);
}
??????*/
#if wxUSE_SPLINES
void DrawSpline(int n, wxPoint points[])
{AddToList(new pdcDrawSplineOp(n,points));}
#endif // wxUSE_SPLINES
#if wxUSE_PALETTE
void SetPalette(const wxPalette& palette)
{AddToList(new pdcSetPaletteOp(palette));}
#endif // wxUSE_PALETTE
void SetLogicalFunction(int function)
{AddToList(new pdcSetLogicalFunctionOp(function));}
void SetFont(const wxFont& font)
{AddToList(new pdcSetFontOp(font));}
void SetPen(const wxPen& pen)
{AddToList(new pdcSetPenOp(pen));}
void SetBrush(const wxBrush& brush)
{AddToList(new pdcSetBrushOp(brush));}
void SetBackground(const wxBrush& brush)
{AddToList(new pdcSetBackgroundOp(brush));}
void SetBackgroundMode(int mode)
{AddToList(new pdcSetBackgroundModeOp(mode));}
void SetTextBackground(const wxColour& colour)
{AddToList(new pdcSetTextBackgroundOp(colour));}
void SetTextForeground(const wxColour& colour)
{AddToList(new pdcSetTextForegroundOp(colour));}
void Clear()
{AddToList(new pdcClearOp());}
void BeginDrawing()
{AddToList(new pdcBeginDrawingOp());}
void EndDrawing()
{AddToList(new pdcEndDrawingOp());}
protected:
// ------------------------------------------------------------------------
// protected helper methods
void AddToList(pdcOp *newOp);
pdcObjectList::Node *FindObjNode(int id, bool create=false);
// ------------------------------------------------------------------------
// Data members
//
int m_currId; // id to use for operations done on the PseudoDC
pdcObjectList::Node *m_lastObjNode; // used to find last used object quickly
pdcObjectList m_objectlist; // list of objects
};
#endif

View File

@@ -207,11 +207,11 @@ swig_sources = run_swig(['gdi.i'], 'src', GENDIR, PKGDIR,
'src/_pen.i',
'src/_palette.i',
'src/_renderer.i',
## 'src/_pseudodc.i',
'src/_pseudodc.i',
],
True)
ext = Extension('_gdi_', ['src/drawlist.cpp',
## 'src/pseudodc.cpp'
'src/pseudodc.cpp'
] + swig_sources,
include_dirs = includes,
define_macros = defines,

580
wxPython/src/_pseudodc.i Normal file
View File

@@ -0,0 +1,580 @@
/////////////////////////////////////////////////////////////////////////////
// Name:
// Purpose: Wraper definitions for the wxPseudoDC Class
// Author: Paul Lanier
// Modified by:
// Created: 05/25/06
// RCS-ID: $Id$
// Copyright: (c) wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
%{
#include "wx/wxPython/pseudodc.h"
%}
%newgroup;
DocStr(wxPseudoDC,
"A PseudoDC is an object that can be used as if it were a `wx.DC`. All
commands issued to the PseudoDC are stored in a list. You can then
play these commands back to a real DC object using the DrawToDC
method. Commands in the command list are indexed by ID. You can use
this to clear the operations associated with a single ID and then
re-draw the object associated with that ID.", "");
class wxPseudoDC : public wxObject
{
public:
DocCtorStr(
wxPseudoDC(),
"Constructs a new Pseudo device context for recording dc operations","");
DocDeclStr(
void , BeginDrawing(),
"Allows for optimization of drawing code on platforms that need it. On
other platforms this is just an empty function and is harmless. To
take advantage of this postential optimization simply enclose each
group of calls to the drawing primitives within calls to
`BeginDrawing` and `EndDrawing`.", "");
DocDeclStr(
void , EndDrawing(),
"Ends the group of drawing primitives started with `BeginDrawing`, and
invokes whatever optimization is available for this DC type on the
current platform.", "");
DocCtorStr(
~wxPseudoDC(),
"Frees memory used by the operation list of the pseudo dc","");
DocDeclStr(
void, RemoveAll(),
"Removes all objects and operations from the recorded list.", "");
DocDeclStr(
int, GetLen(),
"Returns the number of operations in the recorded list.", "");
DocDeclStr(
void, SetId(int id),
"Sets the id to be associated with subsequent operations.", "");
DocDeclStr(
void, ClearId(int id),
"Removes all operations associated with id so the object can be redrawn.", "");
DocDeclStr(
void, RemoveId(int id),
"Remove the object node (and all operations) associated with an id.", "");
DocDeclStr(
void, TranslateId(int id, wxCoord dx, wxCoord dy),
"Translate the operations of id by dx,dy.", "");
DocDeclStr(
void, DrawIdToDC(int id, wxDC *dc),
"Draw recorded operations of id to dc.", "");
DocDeclStr(
void, SetIdBounds(int id, wxRect& rect),
"Set the bounding rect of a given object. This will create
an object node if one doesn't exist.", "");
%extend {
DocStr(
GetIdBounds,
"Returns the bounding rectangle previouly set with SetIdBounds. If
no bounds have been set, it returns wx.Rect(0,0,0,0).", "");
wxRect GetIdBounds(int id) {
wxRect rect;
self->GetIdBounds(id, rect);
return rect;
}
}
DocDeclStr(
void, DrawToDCClipped(wxDC *dc, const wxRect& rect),
"Draws the recorded operations to dc unless the operation is known to
be outside rect.", "");
DocDeclStr(
void, DrawToDCClippedRgn(wxDC *dc, const wxRegion& region),
"Draws the recorded operations to dc unless the operation is known to
be outside rect.", "");
DocDeclStr(
void, DrawToDC(wxDC *dc),
"Draws the recorded operations to dc.", "");
//-------------------------------------------------------------------------
// Methods Mirrored from wxDC
//-------------------------------------------------------------------------
//
// DocDeclStr(
// void , SetFont(const wxFont& font),
// "Sets the current font for the DC. It must be a valid font, in
//particular you should not pass ``wx.NullFont`` to this method.","
//
//:see: `wx.Font`");
//
// DocDeclStr(
// void , SetPen(const wxPen& pen),
// "Sets the current pen for the DC.
//
//If the argument is ``wx.NullPen``, the current pen is selected out of the
//device context, and the original pen restored.", "
//
//:see: `wx.Pen`");
//
// DocDeclStr(
// void , SetBrush(const wxBrush& brush),
// "Sets the current brush for the DC.
//
//If the argument is ``wx.NullBrush``, the current brush is selected out
//of the device context, and the original brush restored, allowing the
//current brush to be destroyed safely.","
//
//:see: `wx.Brush`");
//
// DocDeclStr(
// void , SetBackground(const wxBrush& brush),
// "Sets the current background brush for the DC.", "");
//
// DocDeclStr(
// void , SetBackgroundMode(int mode),
// "*mode* may be one of ``wx.SOLID`` and ``wx.TRANSPARENT``. This setting
//determines whether text will be drawn with a background colour or
//not.", "");
//
// DocDeclStr(
// void , SetTextForeground(const wxColour& colour),
// "Sets the current text foreground colour for the DC.", "");
//
// DocDeclStr(
// void , SetTextBackground(const wxColour& colour),
// "Sets the current text background colour for the DC.", "");
// DocDeclStr(
// void , DrawLabel(const wxString& text, const wxRect& rect,
// int alignment = wxALIGN_LEFT | wxALIGN_TOP,
// int indexAccel = -1),
// "Draw *text* within the specified rectangle, abiding by the alignment
//flags. Will additionally emphasize the character at *indexAccel* if
//it is not -1.", "
//
//:see: `DrawImageLabel`");
// DocStr(
// DrawText,
// "Draws a text string at the specified point, using the current text
//font, and the current text foreground and background colours.
//
//The coordinates refer to the top-left corner of the rectangle bounding
//the string. See `GetTextExtent` for how to get the dimensions of a
//text string, which can be used to position the text more precisely.
//
//**NOTE**: under wxGTK the current logical function is used by this
//function but it is ignored by wxMSW. Thus, you should avoid using
//logical functions with this function in portable programs.", "
//
//:see: `DrawRotatedText`");
// void DrawText(const wxString& text, wxCoord x, wxCoord y);
// DocStr(
// DrawLine,
// "Draws a line from the first point to the second. The current pen is
//used for drawing the line. Note that the second point is *not* part of
//the line and is not drawn by this function (this is consistent with
//the behaviour of many other toolkits).", "");
// void DrawLine(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2);
// DocDeclStr(
// void, DrawRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height),
// "Draws a rectangle with the given top left corner, and with the given
//size. The current pen is used for the outline and the current brush
//for filling the shape.", "");
// DocDeclStr(
// void , Clear(),
// "Clears the device context using the current background brush.", "");
DocStr(
FloodFill,
"Flood fills the device context starting from the given point, using
the current brush colour, and using a style:
- **wxFLOOD_SURFACE**: the flooding occurs until a colour other than
the given colour is encountered.
- **wxFLOOD_BORDER**: the area to be flooded is bounded by the given
colour.
Returns False if the operation failed.
Note: The present implementation for non-Windows platforms may fail to
find colour borders if the pixels do not match the colour
exactly. However the function will still return true.", "");
void FloodFill(wxCoord x, wxCoord y, const wxColour& col, int style = wxFLOOD_SURFACE);
%Rename(FloodFillPoint, void, FloodFill(const wxPoint& pt, const wxColour& col, int style = wxFLOOD_SURFACE));
DocStr(
DrawLine,
"Draws a line from the first point to the second. The current pen is
used for drawing the line. Note that the second point is *not* part of
the line and is not drawn by this function (this is consistent with
the behaviour of many other toolkits).", "");
void DrawLine(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2);
%Rename(DrawLinePoint, void, DrawLine(const wxPoint& pt1, const wxPoint& pt2));
DocStr(
CrossHair,
"Displays a cross hair using the current pen. This is a vertical and
horizontal line the height and width of the window, centred on the
given point.", "");
void CrossHair(wxCoord x, wxCoord y);
%Rename(CrossHairPoint, void, CrossHair(const wxPoint& pt));
DocStr(
DrawArc,
"Draws an arc of a circle, centred on the *center* point (xc, yc), from
the first point to the second. The current pen is used for the outline
and the current brush for filling the shape.
The arc is drawn in an anticlockwise direction from the start point to
the end point.", "");
void DrawArc(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2, wxCoord xc, wxCoord yc);
%Rename(DrawArcPoint, void, DrawArc(const wxPoint& pt1, const wxPoint& pt2, const wxPoint& center));
DocStr(
DrawCheckMark,
"Draws a check mark inside the given rectangle.", "");
void DrawCheckMark(wxCoord x, wxCoord y, wxCoord width, wxCoord height);
%Rename(DrawCheckMarkRect, void, DrawCheckMark(const wxRect& rect));
DocStr(
DrawEllipticArc,
"Draws an arc of an ellipse, with the given rectangle defining the
bounds of the ellipse. The current pen is used for drawing the arc and
the current brush is used for drawing the pie.
The *start* and *end* parameters specify the start and end of the arc
relative to the three-o'clock position from the center of the
rectangle. Angles are specified in degrees (360 is a complete
circle). Positive values mean counter-clockwise motion. If start is
equal to end, a complete ellipse will be drawn.", "");
void DrawEllipticArc(wxCoord x, wxCoord y, wxCoord w, wxCoord h, double start, double end);
%Rename(DrawEllipticArcPointSize, void, DrawEllipticArc(const wxPoint& pt, const wxSize& sz, double start, double end));
DocStr(
DrawPoint,
"Draws a point using the current pen.", "");
void DrawPoint(wxCoord x, wxCoord y);
%Rename(DrawPointPoint, void, DrawPoint(const wxPoint& pt));
DocStr(
DrawRectangle,
"Draws a rectangle with the given top left corner, and with the given
size. The current pen is used for the outline and the current brush
for filling the shape.", "");
void DrawRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height);
%Rename(DrawRectangleRect,void, DrawRectangle(const wxRect& rect));
%Rename(DrawRectanglePointSize, void, DrawRectangle(const wxPoint& pt, const wxSize& sz));
DocStr(
DrawRoundedRectangle,
"Draws a rectangle with the given top left corner, and with the given
size. The corners are quarter-circles using the given radius. The
current pen is used for the outline and the current brush for filling
the shape.
If radius is positive, the value is assumed to be the radius of the
rounded corner. If radius is negative, the absolute value is assumed
to be the proportion of the smallest dimension of the rectangle. This
means that the corner can be a sensible size relative to the size of
the rectangle, and also avoids the strange effects X produces when the
corners are too big for the rectangle.", "");
void DrawRoundedRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height, double radius);
%Rename(DrawRoundedRectangleRect, void, DrawRoundedRectangle(const wxRect& r, double radius));
%Rename(DrawRoundedRectanglePointSize, void, DrawRoundedRectangle(const wxPoint& pt, const wxSize& sz, double radius));
DocStr(
DrawCircle,
"Draws a circle with the given center point and radius. The current
pen is used for the outline and the current brush for filling the
shape.", "
:see: `DrawEllipse`");
void DrawCircle(wxCoord x, wxCoord y, wxCoord radius);
%Rename(DrawCirclePoint, void, DrawCircle(const wxPoint& pt, wxCoord radius));
DocStr(
DrawEllipse,
"Draws an ellipse contained in the specified rectangle. The current pen
is used for the outline and the current brush for filling the shape.", "
:see: `DrawCircle`");
void DrawEllipse(wxCoord x, wxCoord y, wxCoord width, wxCoord height);
%Rename(DrawEllipseRect, void, DrawEllipse(const wxRect& rect));
%Rename(DrawEllipsePointSize, void, DrawEllipse(const wxPoint& pt, const wxSize& sz));
DocStr(
DrawIcon,
"Draw an icon on the display (does nothing if the device context is
PostScript). This can be the simplest way of drawing bitmaps on a
window.", "");
void DrawIcon(const wxIcon& icon, wxCoord x, wxCoord y);
%Rename(DrawIconPoint, void, DrawIcon(const wxIcon& icon, const wxPoint& pt));
DocStr(
DrawBitmap,
"Draw a bitmap on the device context at the specified point. If
*transparent* is true and the bitmap has a transparency mask, (or
alpha channel on the platforms that support it) then the bitmap will
be drawn transparently.", "
When drawing a mono-bitmap, the current text foreground colour will be
used to draw the foreground of the bitmap (all bits set to 1), and the
current text background colour to draw the background (all bits set to
0).
:see: `SetTextForeground`, `SetTextBackground` and `wx.MemoryDC`");
void DrawBitmap(const wxBitmap &bmp, wxCoord x, wxCoord y, bool useMask = false);
%Rename(DrawBitmapPoint, void, DrawBitmap(const wxBitmap &bmp, const wxPoint& pt, bool useMask = false));
DocStr(
DrawText,
"Draws a text string at the specified point, using the current text
font, and the current text foreground and background colours.
The coordinates refer to the top-left corner of the rectangle bounding
the string. See `GetTextExtent` for how to get the dimensions of a
text string, which can be used to position the text more precisely.
**NOTE**: under wxGTK the current logical function is used by this
function but it is ignored by wxMSW. Thus, you should avoid using
logical functions with this function in portable programs.", "
:see: `DrawRotatedText`");
void DrawText(const wxString& text, wxCoord x, wxCoord y);
%Rename(DrawTextPoint, void, DrawText(const wxString& text, const wxPoint& pt));
DocStr(
DrawRotatedText,
"Draws the text rotated by *angle* degrees, if supported by the platform.
**NOTE**: Under Win9x only TrueType fonts can be drawn by this
function. In particular, a font different from ``wx.NORMAL_FONT``
should be used as the it is not normally a TrueType
font. ``wx.SWISS_FONT`` is an example of a font which is.","
:see: `DrawText`");
void DrawRotatedText(const wxString& text, wxCoord x, wxCoord y, double angle);
%Rename(DrawRotatedTextPoint, void, DrawRotatedText(const wxString& text, const wxPoint& pt, double angle));
// DocDeclStr(
// bool , Blit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height,
// wxDC *source, wxCoord xsrc, wxCoord ysrc,
// int rop = wxCOPY, bool useMask = false,
// wxCoord xsrcMask = -1, wxCoord ysrcMask = -1),
// "Copy from a source DC to this DC. Parameters specify the destination
//coordinates, size of area to copy, source DC, source coordinates,
//logical function, whether to use a bitmap mask, and mask source
//position.", "
//
// :param xdest: Destination device context x position.
// :param ydest: Destination device context y position.
// :param width: Width of source area to be copied.
// :param height: Height of source area to be copied.
// :param source: Source device context.
// :param xsrc: Source device context x position.
// :param ysrc: Source device context y position.
// :param rop: Logical function to use: see `SetLogicalFunction`.
// :param useMask: If true, Blit does a transparent blit using the mask
// that is associated with the bitmap selected into the
// source device context.
// :param xsrcMask: Source x position on the mask. If both xsrcMask and
// ysrcMask are -1, xsrc and ysrc will be assumed for
// the mask source position.
// :param ysrcMask: Source y position on the mask.
//");
// DocDeclStrName(
// bool , Blit(const wxPoint& destPt, const wxSize& sz,
// wxDC *source, const wxPoint& srcPt,
// int rop = wxCOPY, bool useMask = false,
// const wxPoint& srcPtMask = wxDefaultPosition),
// "Copy from a source DC to this DC. Parameters specify the destination
//coordinates, size of area to copy, source DC, source coordinates,
//logical function, whether to use a bitmap mask, and mask source
//position.", "
//
// :param destPt: Destination device context position.
// :param sz: Size of source area to be copied.
// :param source: Source device context.
// :param srcPt: Source device context position.
// :param rop: Logical function to use: see `SetLogicalFunction`.
// :param useMask: If true, Blit does a transparent blit using the mask
// that is associated with the bitmap selected into the
// source device context.
// :param srcPtMask: Source position on the mask.
//",
// BlitPointSize);
DocDeclAStr(
void , DrawLines(int points, wxPoint* points_array,
wxCoord xoffset = 0, wxCoord yoffset = 0),
"DrawLines(self, List points, int xoffset=0, int yoffset=0)",
"Draws lines using a sequence of `wx.Point` objects, adding the
optional offset coordinate. The current pen is used for drawing the
lines.", "");
DocDeclAStr(
void , DrawPolygon(int points, wxPoint* points_array,
wxCoord xoffset = 0, wxCoord yoffset = 0,
int fillStyle = wxODDEVEN_RULE),
"DrawPolygon(self, List points, int xoffset=0, int yoffset=0,
int fillStyle=ODDEVEN_RULE)",
"Draws a filled polygon using a sequence of `wx.Point` objects, adding
the optional offset coordinate. The last argument specifies the fill
rule: ``wx.ODDEVEN_RULE`` (the default) or ``wx.WINDING_RULE``.
The current pen is used for drawing the outline, and the current brush
for filling the shape. Using a transparent brush suppresses
filling. Note that wxWidgets automatically closes the first and last
points.", "");
// TODO: Figure out a good typemap for this...
// Convert the first 3 args from a sequence of sequences?
// void DrawPolyPolygon(int n, int count[], wxPoint points[],
// wxCoord xoffset = 0, wxCoord yoffset = 0,
// int fillStyle = wxODDEVEN_RULE);
DocDeclStr(
void , DrawLabel(const wxString& text, const wxRect& rect,
int alignment = wxALIGN_LEFT | wxALIGN_TOP,
int indexAccel = -1),
"Draw *text* within the specified rectangle, abiding by the alignment
flags. Will additionally emphasize the character at *indexAccel* if
it is not -1.", "
:see: `DrawImageLabel`");
DocDeclStrName(
void, DrawLabel(const wxString& text,
const wxBitmap& image,
const wxRect& rect,
int alignment = wxALIGN_LEFT | wxALIGN_TOP,
int indexAccel = -1),
"Draw *text* and an image (which may be ``wx.NullBitmap`` to skip
drawing it) within the specified rectangle, abiding by the alignment
flags. Will additionally emphasize the character at *indexAccel* if
it is not -1.", "", DrawImageLabel);
DocDeclAStr(
void , DrawSpline(int points, wxPoint* points_array),
"DrawSpline(self, List points)",
"Draws a spline between all given control points, (a list of `wx.Point`
objects) using the current pen. The spline is drawn using a series of
lines, using an algorithm taken from the X drawing program 'XFIG'.", "");
DocDeclStr(
virtual void , Clear(),
"Clears the device context using the current background brush.", "");
// set objects to use for drawing
// ------------------------------
DocDeclStr(
virtual void , SetFont(const wxFont& font),
"Sets the current font for the DC. It must be a valid font, in
particular you should not pass ``wx.NullFont`` to this method.","
:see: `wx.Font`");
DocDeclStr(
virtual void , SetPen(const wxPen& pen),
"Sets the current pen for the DC.
If the argument is ``wx.NullPen``, the current pen is selected out of the
device context, and the original pen restored.", "
:see: `wx.Pen`");
DocDeclStr(
virtual void , SetBrush(const wxBrush& brush),
"Sets the current brush for the DC.
If the argument is ``wx.NullBrush``, the current brush is selected out
of the device context, and the original brush restored, allowing the
current brush to be destroyed safely.","
:see: `wx.Brush`");
DocDeclStr(
virtual void , SetBackground(const wxBrush& brush),
"Sets the current background brush for the DC.", "");
DocDeclStr(
virtual void , SetBackgroundMode(int mode),
"*mode* may be one of ``wx.SOLID`` and ``wx.TRANSPARENT``. This setting
determines whether text will be drawn with a background colour or
not.", "");
DocDeclStr(
virtual void , SetPalette(const wxPalette& palette),
"If this is a window DC or memory DC, assigns the given palette to the
window or bitmap associated with the DC. If the argument is
``wx.NullPalette``, the current palette is selected out of the device
context, and the original palette restored.", "
:see: `wx.Palette`");
DocDeclStr(
virtual void , SetTextForeground(const wxColour& colour),
"Sets the current text foreground colour for the DC.", "");
DocDeclStr(
virtual void , SetTextBackground(const wxColour& colour),
"Sets the current text background colour for the DC.", "");
DocDeclStr(
virtual void , SetLogicalFunction(int function),
"Sets the current logical function for the device context. This
determines how a source pixel (from a pen or brush colour, or source
device context if using `Blit`) combines with a destination pixel in
the current device context.
The possible values and their meaning in terms of source and
destination pixel values are as follows:
================ ==========================
wx.AND src AND dst
wx.AND_INVERT (NOT src) AND dst
wx.AND_REVERSE src AND (NOT dst)
wx.CLEAR 0
wx.COPY src
wx.EQUIV (NOT src) XOR dst
wx.INVERT NOT dst
wx.NAND (NOT src) OR (NOT dst)
wx.NOR (NOT src) AND (NOT dst)
wx.NO_OP dst
wx.OR src OR dst
wx.OR_INVERT (NOT src) OR dst
wx.OR_REVERSE src OR (NOT dst)
wx.SET 1
wx.SRC_INVERT NOT src
wx.XOR src XOR dst
================ ==========================
The default is wx.COPY, which simply draws with the current
colour. The others combine the current colour and the background using
a logical operation. wx.INVERT is commonly used for drawing rubber
bands or moving outlines, since drawing twice reverts to the original
colour.
", "");
};

368
wxPython/src/pseudodc.cpp Normal file
View File

@@ -0,0 +1,368 @@
/////////////////////////////////////////////////////////////////////////////
// Name: common/pseudodc.cpp
// Purpose: Implementation of the wxPseudoDC Class
// Author: Paul Lanier
// Modified by:
// Created: 05/25/06
// RCS-ID: $Id$
// Copyright: (c) wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#include "wx/wxPython/pseudodc.h"
#include <stdio.h>
// wxList based class definitions
#include <wx/listimpl.cpp>
WX_DEFINE_LIST(pdcOpList);
WX_DEFINE_LIST(pdcObjectList);
// ============================================================================
// various pdcOp class implementation methods
// ============================================================================
// ----------------------------------------------------------------------------
// pdcDrawPolyPolygonOp constructor
// ----------------------------------------------------------------------------
pdcDrawPolyPolygonOp::pdcDrawPolyPolygonOp(int n, int count[], wxPoint points[],
wxCoord xoffset, wxCoord yoffset, int fillStyle)
{
m_n=n; m_xoffset=xoffset; m_yoffset=yoffset; m_fillStyle=fillStyle;
int total_n=0;
if (n)
{
m_count = new int[n];
for(int i=0; i<n; i++)
{
total_n+=count[i];
m_count[i]=count[i];
}
if (total_n)
{
m_points = new wxPoint[total_n];
for(int j=0; j<total_n; j++)
m_points[j] = points[j];
}
else m_points=NULL;
}
else
{
m_points=NULL;
m_count=NULL;
}
m_totaln = total_n;
}
// ----------------------------------------------------------------------------
// pdcDrawPolyPolygonOp destructor
// ----------------------------------------------------------------------------
pdcDrawPolyPolygonOp::~pdcDrawPolyPolygonOp()
{
if (m_points) delete m_points;
if (m_count) delete m_count;
m_points=NULL;
m_count=NULL;
}
// ----------------------------------------------------------------------------
// pdcDrawLinesOp constructor
// ----------------------------------------------------------------------------
pdcDrawLinesOp::pdcDrawLinesOp(int n, wxPoint points[],
wxCoord xoffset, wxCoord yoffset)
{
m_n=n; m_xoffset=xoffset; m_yoffset=yoffset;
if (n)
{
m_points = new wxPoint[n];
for (int i=0; i<n; i++)
m_points[i] = points[i];
}
else m_points=NULL;
}
// ----------------------------------------------------------------------------
// pdcDrawLinesOp destructor
// ----------------------------------------------------------------------------
pdcDrawLinesOp::~pdcDrawLinesOp()
{
if (m_points) delete m_points;
m_points=NULL;
}
// ----------------------------------------------------------------------------
// pdcDrawPolygonOp constructor
// ----------------------------------------------------------------------------
pdcDrawPolygonOp::pdcDrawPolygonOp(int n, wxPoint points[],
wxCoord xoffset, wxCoord yoffset, int fillStyle)
{
m_n=n; m_xoffset=xoffset; m_yoffset=yoffset; m_fillStyle=fillStyle;
if (n)
{
m_points = new wxPoint[n];
for (int i=0; i<n; i++)
m_points[i] = points[i];
}
else m_points=NULL;
}
// ----------------------------------------------------------------------------
// pdcDrawPolygonOp destructor
// ----------------------------------------------------------------------------
pdcDrawPolygonOp::~pdcDrawPolygonOp()
{
if (m_points) delete m_points;
m_points=NULL;
}
#if wxUSE_SPLINES
// ----------------------------------------------------------------------------
// pdcDrawSplineOp constructor
// ----------------------------------------------------------------------------
pdcDrawSplineOp::pdcDrawSplineOp(int n, wxPoint points[])
{
m_n=n;
if (n)
{
m_points = new wxPoint[n];
for(int i=0; i<n; i++)
m_points[i] = points[i];
}
else m_points=NULL;
}
// ----------------------------------------------------------------------------
// pdcDrawSplineOp destructor
// ----------------------------------------------------------------------------
pdcDrawSplineOp::~pdcDrawSplineOp()
{
if (m_points) delete m_points;
m_points=NULL;
}
#endif // wxUSE_SPLINES
// ============================================================================
// pdcObject implementation
// ============================================================================
// ----------------------------------------------------------------------------
// DrawToDC - play back the op list to the DC
// ----------------------------------------------------------------------------
void pdcObject::DrawToDC(wxDC *dc)
{
pdcOpList::Node *node = m_oplist.GetFirst();
while(node)
{
node->GetData()->DrawToDC(dc);
node = node->GetNext();
}
}
// ----------------------------------------------------------------------------
// Translate - translate all the operations by some dx,dy
// ----------------------------------------------------------------------------
void pdcObject::Translate(wxCoord dx, wxCoord dy)
{
pdcOpList::Node *node = m_oplist.GetFirst();
while(node)
{
node->GetData()->Translate(dx,dy);
node = node->GetNext();
}
if (m_bounded)
{
m_bounds.x += dx;
m_bounds.y += dy;
}
}
// ============================================================================
// wxPseudoDC implementation
// ============================================================================
// ----------------------------------------------------------------------------
// Destructor
// ----------------------------------------------------------------------------
wxPseudoDC::~wxPseudoDC()
{
// delete all the nodes in the list
RemoveAll();
}
// ----------------------------------------------------------------------------
// ClearAll - remove all nodes from list
// ----------------------------------------------------------------------------
void wxPseudoDC::RemoveAll(void)
{
m_objectlist.Clear();
m_currId = -1;
m_lastObjNode = NULL;
}
// ----------------------------------------------------------------------------
// GetLen - return the number of operations in the current op list
// ----------------------------------------------------------------------------
int wxPseudoDC::GetLen(void)
{
pdcObjectList::Node *pt = m_objectlist.GetFirst();
int len=0;
while (pt)
{
len += pt->GetData()->GetLen();
pt = pt->GetNext();
}
return len;
}
// ----------------------------------------------------------------------------
// FindObjNode - find and return an object node by id. If node doesn't exist
// and create is true then create one and return it. Otherwise
// return NULL.
// ----------------------------------------------------------------------------
pdcObjectList::Node *wxPseudoDC::FindObjNode(int id, bool create)
{
// see if last operation was for same id
if (m_lastObjNode && m_lastObjNode->GetData()->GetId() == id)
return m_lastObjNode;
// if not then search for it
pdcObjectList::Node *pt = m_objectlist.GetFirst();
while (pt)
{
if (pt->GetData()->GetId() == id)
{
// cache this node for future operations
m_lastObjNode = pt;
return pt;
}
pt = pt->GetNext();
}
// if create then create and return a new node
if (create)
{
// cache this node for future operations
m_lastObjNode = m_objectlist.Append(new pdcObject(id));
return m_lastObjNode;
}
// otherwise just return NULL
return NULL;
}
// ----------------------------------------------------------------------------
// AddToList - Add a node to the list at the end (preserve draw order)
// ----------------------------------------------------------------------------
void wxPseudoDC::AddToList(pdcOp *newOp)
{
pdcObjectList::Node *pt = FindObjNode(m_currId, true);
pt->GetData()->AddOp(newOp);
}
// ----------------------------------------------------------------------------
// ClearID - remove all the operations associated with a single ID
// ----------------------------------------------------------------------------
void wxPseudoDC::ClearId(int id)
{
pdcObjectList::Node *pt = FindObjNode(id);
if (pt) pt->GetData()->Clear();
}
// ----------------------------------------------------------------------------
// RemoveID - Remove the object node (and all operations) associated with an id
// ----------------------------------------------------------------------------
void wxPseudoDC::RemoveId(int id)
{
pdcObjectList::Node *pt = FindObjNode(id);
if (pt)
{
if (m_lastObjNode == pt)
m_lastObjNode = NULL;
m_objectlist.DeleteNode(pt);
}
}
// ----------------------------------------------------------------------------
// SetIdBounds - Set the bounding rect for a given id
// ----------------------------------------------------------------------------
void wxPseudoDC::SetIdBounds(int id, wxRect& rect)
{
pdcObjectList::Node *pt = FindObjNode(id, true);
pt->GetData()->SetBounds(rect);
}
// ----------------------------------------------------------------------------
// GetIdBounds - Get the bounding rect for a given id
// ----------------------------------------------------------------------------
void wxPseudoDC::GetIdBounds(int id, wxRect& rect)
{
pdcObjectList::Node *pt = FindObjNode(id);
if (pt && pt->GetData()->IsBounded())
rect = pt->GetData()->GetBounds();
else
rect.x = rect.y = rect.width = rect.height = 0;
}
// ----------------------------------------------------------------------------
// TranslateId - Translate all the operations of a single id
// ----------------------------------------------------------------------------
void wxPseudoDC::TranslateId(int id, wxCoord dx, wxCoord dy)
{
pdcObjectList::Node *pt = FindObjNode(id);
if (pt) pt->GetData()->Translate(dx,dy);
}
// ----------------------------------------------------------------------------
// DrawIdToDC - Draw a specific id to the dc passed in
// ----------------------------------------------------------------------------
void wxPseudoDC::DrawIdToDC(int id, wxDC *dc)
{
pdcObjectList::Node *pt = FindObjNode(id);
if (pt) pt->GetData()->DrawToDC(dc);
}
// ----------------------------------------------------------------------------
// DrawToDCClipped - play back the op list to the DC but clip any objects
// known to be not in 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 wxPseudoDC::DrawToDCClipped(wxDC *dc, const wxRect& rect)
{
pdcObjectList::Node *pt = m_objectlist.GetFirst();
pdcObject *obj;
while (pt)
{
obj = pt->GetData();
if (!obj->IsBounded() || rect.Intersects(obj->GetBounds()))
obj->DrawToDC(dc);
pt = pt->GetNext();
}
}
void wxPseudoDC::DrawToDCClippedRgn(wxDC *dc, const wxRegion& region)
{
pdcObjectList::Node *pt = m_objectlist.GetFirst();
pdcObject *obj;
while (pt)
{
obj = pt->GetData();
if (!obj->IsBounded() ||
(region.Contains(obj->GetBounds()) != wxOutRegion))
obj->DrawToDC(dc);
pt = pt->GetNext();
}
}
// ----------------------------------------------------------------------------
// DrawToDC - play back the op list to the DC
// ----------------------------------------------------------------------------
void wxPseudoDC::DrawToDC(wxDC *dc)
{
pdcObjectList::Node *pt = m_objectlist.GetFirst();
while (pt)
{
pt->GetData()->DrawToDC(dc);
pt = pt->GetNext();
}
}