]>
git.saurik.com Git - wxWidgets.git/blob - wxPython/demo/PseudoDC.py
   6 #--------------------------------------------------------------------------- 
  15 #--------------------------------------------------------------------------- 
  39 class MyCanvas(wx
.ScrolledWindow
): 
  40     def __init__(self
, parent
, id, log
, size 
= wx
.DefaultSize
): 
  41         wx
.ScrolledWindow
.__init
__(self
, parent
, id, (0, 0), size
=size
, style
=wx
.SUNKEN_BORDER
) 
  50         self
.SetBackgroundColour("WHITE") 
  51         bmp 
= images
.getTest2Bitmap() 
  52         mask 
= wx
.Mask(bmp
, wx
.BLUE
) 
  56         self
.SetVirtualSize((self
.maxWidth
, self
.maxHeight
)) 
  57         self
.SetScrollRate(20,20) 
  59         # create a PseudoDC to record our drawing 
  60         self
.pdc 
= wx
.PseudoDC() 
  63         self
.DoDrawing(self
.pdc
) 
  64         log
.write('Created PseudoDC draw list with %d operations!'%self
.pdc
.GetLen()) 
  66         self
.Bind(wx
.EVT_PAINT
, self
.OnPaint
) 
  67         self
.Bind(wx
.EVT_ERASE_BACKGROUND
, lambda x
:None) 
  68         self
.Bind(wx
.EVT_MOUSE_EVENTS
, self
.OnMouse
) 
  70         # vars for handling mouse clicks 
  74     def ConvertEventCoords(self
, event
): 
  75         xView
, yView 
= self
.GetViewStart() 
  76         xDelta
, yDelta 
= self
.GetScrollPixelsPerUnit() 
  77         return (event
.GetX() + (xView 
* xDelta
), 
  78             event
.GetY() + (yView 
* yDelta
)) 
  80     def OffsetRect(self
, r
): 
  81         xView
, yView 
= self
.GetViewStart() 
  82         xDelta
, yDelta 
= self
.GetScrollPixelsPerUnit() 
  83         r
.OffsetXY(-(xView
*xDelta
),-(yView
*yDelta
)) 
  85     def OnMouse(self
, event
): 
  88             x
,y 
= self
.ConvertEventCoords(event
) 
  89             #l = self.pdc.FindObjectsByBBox(x, y) 
  90             l 
= self
.pdc
.FindObjects(x
, y
, hitradius
) 
  92                 if not self
.pdc
.GetIdGreyedOut(id): 
  94                     self
.lastpos 
= (event
.GetX(),event
.GetY()) 
  96         elif event
.RightDown(): 
  97             x
,y 
= self
.ConvertEventCoords(event
) 
  98             #l = self.pdc.FindObjectsByBBox(x, y) 
  99             l 
= self
.pdc
.FindObjects(x
, y
, hitradius
) 
 101                 self
.pdc
.SetIdGreyedOut(l
[0], not self
.pdc
.GetIdGreyedOut(l
[0])) 
 102                 r 
= self
.pdc
.GetIdBounds(l
[0]) 
 105                 self
.RefreshRect(r
, False) 
 106         elif event
.Dragging() or event
.LeftUp(): 
 107             if self
.dragid 
!= -1: 
 109                 dx 
= event
.GetX() - x
 
 110                 dy 
= event
.GetY() - y
 
 111                 r 
= self
.pdc
.GetIdBounds(self
.dragid
) 
 112                 self
.pdc
.TranslateId(self
.dragid
, dx
, dy
) 
 113                 r2 
= self
.pdc
.GetIdBounds(self
.dragid
) 
 117                 self
.RefreshRect(r
, False) 
 118                 self
.lastpos 
= (event
.GetX(),event
.GetY()) 
 123         c 
= random
.choice(colours
) 
 124         t 
= random
.randint(1, 4) 
 125         if not self
.pen_cache
.has_key( (c
, t
) ): 
 126             self
.pen_cache
[(c
, t
)] = wx
.Pen(c
, t
) 
 127         return self
.pen_cache
[(c
, t
)] 
 130     def RandomBrush(self
): 
 131         c 
= random
.choice(colours
) 
 132         if not self
.brush_cache
.has_key(c
): 
 133             self
.brush_cache
[c
] = wx
.Brush(c
) 
 135         return self
.brush_cache
[c
] 
 137     def RandomColor(self
): 
 138         return random
.choice(colours
) 
 141     def OnPaint(self
, event
): 
 142         # Create a buffered paint DC.  It will create the real 
 143         # wx.PaintDC and then blit the bitmap to it when dc is 
 145         dc 
= wx
.BufferedPaintDC(self
) 
 146         # use PrepateDC to set position correctly 
 148         # we need to clear the dc BEFORE calling PrepareDC 
 149         bg 
= wx
.Brush(self
.GetBackgroundColour()) 
 152         # create a clipping rect from our position and size 
 153         # and the Update Region 
 154         xv
, yv 
= self
.GetViewStart() 
 155         dx
, dy 
= self
.GetScrollPixelsPerUnit() 
 156         x
, y   
= (xv 
* dx
, yv 
* dy
) 
 157         rgn 
= self
.GetUpdateRegion() 
 160         # draw to the dc using the calculated clipping rect 
 161         self
.pdc
.DrawToDCClipped(dc
,r
) 
 163     def DoDrawing(self
, dc
): 
 168         for i 
in range(SHAPE_COUNT
): 
 171             choice 
= random
.randint(0,8) 
 173                 x 
= random
.randint(0, W
) 
 174                 y 
= random
.randint(0, H
) 
 175                 pen 
= self
.RandomPen() 
 179                 r
.Inflate(pen
.GetWidth(),pen
.GetWidth()) 
 181             elif choice 
in (2,3): 
 182                 x1 
= random
.randint(0, W
-SW
) 
 183                 y1 
= random
.randint(0, H
-SH
) 
 184                 x2 
= random
.randint(x1
, x1
+SW
) 
 185                 y2 
= random
.randint(y1
, y1
+SH
) 
 186                 pen 
= self
.RandomPen() 
 188                 dc
.DrawLine(x1
,y1
,x2
,y2
) 
 189                 r 
= wx
.Rect(x1
,y1
,x2
-x1
,y2
-y1
) 
 190                 r
.Inflate(pen
.GetWidth(),pen
.GetWidth()) 
 192             elif choice 
in (4,5): 
 193                 w 
= random
.randint(10, SW
) 
 194                 h 
= random
.randint(10, SH
) 
 195                 x 
= random
.randint(0, W 
- w
) 
 196                 y 
= random
.randint(0, H 
- h
) 
 197                 pen 
= self
.RandomPen() 
 199                 dc
.SetBrush(self
.RandomBrush()) 
 200                 dc
.DrawRectangle(x
,y
,w
,h
) 
 202                 r
.Inflate(pen
.GetWidth(),pen
.GetWidth()) 
 204                 self
.objids
.append(id) 
 206                 Np 
= 8 # number of characters in text 
 209                     c 
= chr( random
.randint(48, 122) ) 
 212                 w
,h 
= self
.GetFullTextExtent(word
)[0:2] 
 213                 x 
= random
.randint(0, W
-w
) 
 214                 y 
= random
.randint(0, H
-h
) 
 215                 dc
.SetFont(self
.GetFont()) 
 216                 dc
.SetTextForeground(self
.RandomColor()) 
 217                 dc
.SetTextBackground(self
.RandomColor()) 
 218                 dc
.DrawText(word
, x
, y
) 
 221                 dc
.SetIdBounds(id, r
) 
 222                 self
.objids
.append(id) 
 224                 Np 
= 8 # number of points per polygon 
 231                     x 
= random
.randint(0, SW
) 
 232                     y 
= random
.randint(0, SH
) 
 233                     if x 
< minx
: minx 
= x
 
 234                     if x 
> maxx
: maxx 
= x
 
 235                     if y 
< miny
: miny 
= y
 
 236                     if y 
> maxy
: maxy 
= y
 
 237                     poly
.append(wx
.Point(x
,y
)) 
 238                 x 
= random
.randint(0, W
-SW
) 
 239                 y 
= random
.randint(0, H
-SH
) 
 240                 pen 
= self
.RandomPen() 
 242                 dc
.SetBrush(self
.RandomBrush()) 
 243                 dc
.DrawPolygon(poly
, x
,y
) 
 244                 r 
= wx
.Rect(minx
+x
,miny
+y
,maxx
-minx
,maxy
-miny
) 
 245                 r
.Inflate(pen
.GetWidth(),pen
.GetWidth()) 
 247                 self
.objids
.append(id) 
 249                 w
,h 
= self
.bmp
.GetSize() 
 250                 x 
= random
.randint(0, W
-w
) 
 251                 y 
= random
.randint(0, H
-h
) 
 252                 dc
.DrawBitmap(self
.bmp
,x
,y
,True) 
 253                 dc
.SetIdBounds(id,wx
.Rect(x
,y
,w
,h
)) 
 254                 self
.objids
.append(id) 
 257 class ControlPanel(wx
.Panel
): 
 258     def __init__(self
, parent
, id, pos
=wx
.DefaultPosition
, 
 259             size
=wx
.DefaultSize
, style 
= wx
.TAB_TRAVERSAL
): 
 260         wx
.Panel
.__init
__(self
,parent
,id,pos
,size
,style
) 
 261         lbl 
= wx
.StaticText(self
, wx
.ID_ANY
, "Hit Test Radius: ") 
 262         lbl2 
= wx
.StaticText(self
, wx
.ID_ANY
, "Left Click to drag, Right Click to enable/disable") 
 263         sc 
= wx
.SpinCtrl(self
, wx
.ID_ANY
, "5") 
 266         sc
.SetValue(hitradius
) 
 268         sz 
= wx
.BoxSizer(wx
.HORIZONTAL
) 
 269         sz
.Add(lbl
,0,wx
.EXPAND
) 
 271         sz
.Add(lbl2
,0,wx
.LEFT
,5) 
 272         sz
.Add((10,10),1,wx
.EXPAND
) 
 273         self
.SetSizerAndFit(sz
) 
 274         sc
.Bind(wx
.EVT_SPINCTRL
,self
.OnChange
) 
 275         sc
.Bind(wx
.EVT_TEXT
,self
.OnChange
) 
 277     def OnChange(self
, event
): 
 279         hitradius 
= self
.sc
.GetValue() 
 282 #--------------------------------------------------------------------------- 
 284 def runTest(frame
, nb
, log
): 
 285     pnl 
= wx
.Panel(nb
, wx
.ID_ANY
,size
=(200,30)) 
 286     pnl2 
= ControlPanel(pnl
,wx
.ID_ANY
) 
 287     win 
= MyCanvas(pnl
, wx
.ID_ANY
, log
) 
 288     sz 
= wx
.BoxSizer(wx
.VERTICAL
) 
 289     sz
.Add(pnl2
,0,wx
.EXPAND|wx
.ALL
,5) 
 290     sz
.Add(win
,1,wx
.EXPAND
) 
 291     pnl
.SetSizerAndFit(sz
) 
 294 #--------------------------------------------------------------------------- 
 303 The wx.PseudoDC class provides a way to record operations on a DC and then 
 304 play them back later.  The PseudoDC can be passed to a drawing routine as 
 305 if it were a real DC.  All Drawing methods are supported except Blit but 
 306 GetXXX methods are not supported and none of the drawing methods return 
 307 a value. The PseudoDC records the drawing to an operation 
 308 list.  The operations can be played back to a real DC using:<pre> 
 311 The operations can be tagged with an id in order to associated them with a 
 312 specific object.  To do this use:<pre> 
 315 Every operation after this will be associated with id until SetId is called 
 316 again.  The PseudoDC also supports object level clipping.  To enable this use:<pre> 
 319 for each object that should be clipped.  Then use:<pre> 
 320     DrawToDCClipped(dc, clippingRect) 
 322 To draw the PseudoDC to a real dc. This is useful for large scrolled windows  
 323 where many objects are offscreen. 
 325 Objects can be moved around without re-drawing using:<pre> 
 326     TranslateId(id, dx, dy) 
 329 To re-draw an object use:<pre> 
 333 and then re-draw the object. 
 339 if __name__ 
== '__main__': 
 342     run
.main(['', os
.path
.basename(sys
.argv
[0])] + sys
.argv
[1:])