]>
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:])