]> git.saurik.com Git - wxWidgets.git/blob - wxPython/demo/OGL.py
mention wxLogInterposer(Temp)
[wxWidgets.git] / wxPython / demo / OGL.py
1 # -*- coding: iso-8859-1 -*-
2 # 11/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
3 #
4 # o Updated for wx namespace
5 #
6 # 20040508 - Pierre Hjälm
7 #
8 # o Changed to use the python version of OGL
9 # o Added TextShape, CompositeShape and CompositeShape with divisions
10 #
11 # 20040830 - Pierre Hjälm
12 #
13 # o Added DrawnShape
14 #
15
16 import wx
17 import wx.lib.ogl as ogl
18
19 import images
20
21 #----------------------------------------------------------------------
22
23 class DrawnShape(ogl.DrawnShape):
24 def __init__(self):
25 ogl.DrawnShape.__init__(self)
26
27 self.SetDrawnBrush(wx.WHITE_BRUSH)
28 self.SetDrawnPen(wx.BLACK_PEN)
29 self.DrawArc((0, -10), (30, 0), (-30, 0))
30
31 self.SetDrawnPen(wx.Pen("#ff8030"))
32 self.DrawLine((-30, 5), (30, 5))
33
34 self.SetDrawnPen(wx.Pen("#00ee10"))
35 self.DrawRoundedRectangle((-20, 10, 40, 10), 5)
36
37 self.SetDrawnPen(wx.Pen("#9090f0"))
38 self.DrawEllipse((-30, 25, 60, 20))
39
40 self.SetDrawnTextColour(wx.BLACK)
41 self.SetDrawnFont(wx.Font(8, wx.SWISS, wx.NORMAL, wx.NORMAL))
42 self.DrawText("DrawText", (-26, 28))
43
44 self.SetDrawnBrush(wx.GREEN_BRUSH)
45 self.DrawPolygon([(-100, 5), (-45, 30), (-35, 20), (-30, 5)])
46
47 self.SetDrawnPen(wx.BLACK_PEN)
48 self.DrawLines([(30, -45), (40, -45), (40 ,45), (30, 45)])
49
50 # Make sure to call CalculateSize when all drawing is done
51 self.CalculateSize()
52
53 #----------------------------------------------------------------------
54
55 class DiamondShape(ogl.PolygonShape):
56 def __init__(self, w=0.0, h=0.0):
57 ogl.PolygonShape.__init__(self)
58 if w == 0.0:
59 w = 60.0
60 if h == 0.0:
61 h = 60.0
62
63 points = [ (0.0, -h/2.0),
64 (w/2.0, 0.0),
65 (0.0, h/2.0),
66 (-w/2.0, 0.0),
67 ]
68
69 self.Create(points)
70
71
72 #----------------------------------------------------------------------
73
74 class RoundedRectangleShape(ogl.RectangleShape):
75 def __init__(self, w=0.0, h=0.0):
76 ogl.RectangleShape.__init__(self, w, h)
77 self.SetCornerRadius(-0.3)
78
79
80 #----------------------------------------------------------------------
81
82 class CompositeDivisionShape(ogl.CompositeShape):
83 def __init__(self, canvas):
84 ogl.CompositeShape.__init__(self)
85
86 self.SetCanvas(canvas)
87
88 # create a division in the composite
89 self.MakeContainer()
90
91 # add a shape to the original division
92 shape2 = ogl.RectangleShape(40, 60)
93 self.GetDivisions()[0].AddChild(shape2)
94
95 # now divide the division so we get 2
96 self.GetDivisions()[0].Divide(wx.HORIZONTAL)
97
98 # and add a shape to the second division (and move it to the
99 # centre of the division)
100 shape3 = ogl.CircleShape(40)
101 shape3.SetBrush(wx.CYAN_BRUSH)
102 self.GetDivisions()[1].AddChild(shape3)
103 shape3.SetX(self.GetDivisions()[1].GetX())
104
105 for division in self.GetDivisions():
106 division.SetSensitivityFilter(0)
107
108 #----------------------------------------------------------------------
109
110 class CompositeShape(ogl.CompositeShape):
111 def __init__(self, canvas):
112 ogl.CompositeShape.__init__(self)
113
114 self.SetCanvas(canvas)
115
116 constraining_shape = ogl.RectangleShape(120, 100)
117 constrained_shape1 = ogl.CircleShape(50)
118 constrained_shape2 = ogl.RectangleShape(80, 20)
119
120 constraining_shape.SetBrush(wx.BLUE_BRUSH)
121 constrained_shape2.SetBrush(wx.RED_BRUSH)
122
123 self.AddChild(constraining_shape)
124 self.AddChild(constrained_shape1)
125 self.AddChild(constrained_shape2)
126
127 constraint = ogl.Constraint(ogl.CONSTRAINT_MIDALIGNED_BOTTOM, constraining_shape, [constrained_shape1, constrained_shape2])
128 self.AddConstraint(constraint)
129 self.Recompute()
130
131 # If we don't do this, the shapes will be able to move on their
132 # own, instead of moving the composite
133 constraining_shape.SetDraggable(False)
134 constrained_shape1.SetDraggable(False)
135 constrained_shape2.SetDraggable(False)
136
137 # If we don't do this the shape will take all left-clicks for itself
138 constraining_shape.SetSensitivityFilter(0)
139
140
141 #----------------------------------------------------------------------
142
143 class DividedShape(ogl.DividedShape):
144 def __init__(self, width, height, canvas):
145 ogl.DividedShape.__init__(self, width, height)
146
147 region1 = ogl.ShapeRegion()
148 region1.SetText('DividedShape')
149 region1.SetProportions(0.0, 0.2)
150 region1.SetFormatMode(ogl.FORMAT_CENTRE_HORIZ)
151 self.AddRegion(region1)
152
153 region2 = ogl.ShapeRegion()
154 region2.SetText('This is Region number two.')
155 region2.SetProportions(0.0, 0.3)
156 region2.SetFormatMode(ogl.FORMAT_CENTRE_HORIZ|ogl.FORMAT_CENTRE_VERT)
157 self.AddRegion(region2)
158
159 region3 = ogl.ShapeRegion()
160 region3.SetText('Region 3\nwith embedded\nline breaks')
161 region3.SetProportions(0.0, 0.5)
162 region3.SetFormatMode(ogl.FORMAT_NONE)
163 self.AddRegion(region3)
164
165 self.SetRegionSizes()
166 self.ReformatRegions(canvas)
167
168
169 def ReformatRegions(self, canvas=None):
170 rnum = 0
171
172 if canvas is None:
173 canvas = self.GetCanvas()
174
175 dc = wx.ClientDC(canvas) # used for measuring
176
177 for region in self.GetRegions():
178 text = region.GetText()
179 self.FormatText(dc, text, rnum)
180 rnum += 1
181
182
183 def OnSizingEndDragLeft(self, pt, x, y, keys, attch):
184 print "***", self
185 ogl.DividedShape.OnSizingEndDragLeft(self, pt, x, y, keys, attch)
186 self.SetRegionSizes()
187 self.ReformatRegions()
188 self.GetCanvas().Refresh()
189
190
191 #----------------------------------------------------------------------
192
193 class MyEvtHandler(ogl.ShapeEvtHandler):
194 def __init__(self, log, frame):
195 ogl.ShapeEvtHandler.__init__(self)
196 self.log = log
197 self.statbarFrame = frame
198
199 def UpdateStatusBar(self, shape):
200 x, y = shape.GetX(), shape.GetY()
201 width, height = shape.GetBoundingBoxMax()
202 self.statbarFrame.SetStatusText("Pos: (%d, %d) Size: (%d, %d)" %
203 (x, y, width, height))
204
205
206 def OnLeftClick(self, x, y, keys=0, attachment=0):
207 shape = self.GetShape()
208 canvas = shape.GetCanvas()
209 dc = wx.ClientDC(canvas)
210 canvas.PrepareDC(dc)
211
212 if shape.Selected():
213 shape.Select(False, dc)
214 #canvas.Redraw(dc)
215 canvas.Refresh(False)
216 else:
217 redraw = False
218 shapeList = canvas.GetDiagram().GetShapeList()
219 toUnselect = []
220
221 for s in shapeList:
222 if s.Selected():
223 # If we unselect it now then some of the objects in
224 # shapeList will become invalid (the control points are
225 # shapes too!) and bad things will happen...
226 toUnselect.append(s)
227
228 shape.Select(True, dc)
229
230 if toUnselect:
231 for s in toUnselect:
232 s.Select(False, dc)
233
234 ##canvas.Redraw(dc)
235 canvas.Refresh(False)
236
237 self.UpdateStatusBar(shape)
238
239
240 def OnEndDragLeft(self, x, y, keys=0, attachment=0):
241 shape = self.GetShape()
242 ogl.ShapeEvtHandler.OnEndDragLeft(self, x, y, keys, attachment)
243
244 if not shape.Selected():
245 self.OnLeftClick(x, y, keys, attachment)
246
247 self.UpdateStatusBar(shape)
248
249
250 def OnSizingEndDragLeft(self, pt, x, y, keys, attch):
251 ogl.ShapeEvtHandler.OnSizingEndDragLeft(self, pt, x, y, keys, attch)
252 self.UpdateStatusBar(self.GetShape())
253
254
255 def OnMovePost(self, dc, x, y, oldX, oldY, display):
256 shape = self.GetShape()
257 ogl.ShapeEvtHandler.OnMovePost(self, dc, x, y, oldX, oldY, display)
258 self.UpdateStatusBar(shape)
259 if "wxMac" in wx.PlatformInfo:
260 shape.GetCanvas().Refresh(False)
261
262 def OnRightClick(self, *dontcare):
263 self.log.WriteText("%s\n" % self.GetShape())
264
265
266 #----------------------------------------------------------------------
267
268 class TestWindow(ogl.ShapeCanvas):
269 def __init__(self, parent, log, frame):
270 ogl.ShapeCanvas.__init__(self, parent)
271
272 maxWidth = 1000
273 maxHeight = 1000
274 self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20)
275
276 self.log = log
277 self.frame = frame
278 self.SetBackgroundColour("LIGHT BLUE") #wx.WHITE)
279 self.diagram = ogl.Diagram()
280 self.SetDiagram(self.diagram)
281 self.diagram.SetCanvas(self)
282 self.shapes = []
283 self.save_gdi = []
284
285 rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID)
286 dsBrush = wx.Brush("WHEAT", wx.SOLID)
287
288 self.MyAddShape(
289 CompositeDivisionShape(self),
290 270, 310, wx.BLACK_PEN, wx.BLUE_BRUSH, "Division"
291 )
292
293 self.MyAddShape(
294 CompositeShape(self),
295 100, 260, wx.BLACK_PEN, wx.RED_BRUSH, "Composite"
296 )
297
298 self.MyAddShape(
299 ogl.CircleShape(80),
300 75, 110, wx.Pen(wx.BLUE, 3), wx.GREEN_BRUSH, "Circle"
301 )
302
303 self.MyAddShape(
304 ogl.TextShape(120, 45),
305 160, 35, wx.GREEN_PEN, wx.LIGHT_GREY_BRUSH, "OGL is now a\npure Python lib!"
306 )
307
308 self.MyAddShape(
309 ogl.RectangleShape(85, 50),
310 305, 60, wx.BLACK_PEN, wx.LIGHT_GREY_BRUSH, "Rectangle"
311 )
312
313 self.MyAddShape(
314 DrawnShape(),
315 500, 80, wx.BLACK_PEN, wx.BLACK_BRUSH, "DrawnShape"
316 )
317
318 ds = self.MyAddShape(
319 DividedShape(140, 150, self),
320 520, 265, wx.BLACK_PEN, dsBrush, ''
321 )
322
323 self.MyAddShape(
324 DiamondShape(90, 90),
325 355, 260, wx.Pen(wx.BLUE, 3, wx.DOT), wx.RED_BRUSH, "Polygon"
326 )
327
328 self.MyAddShape(
329 RoundedRectangleShape(95, 70),
330 345, 145, wx.Pen(wx.RED, 2), rRectBrush, "Rounded Rect"
331 )
332
333 bmp = images.getTest2Bitmap()
334 mask = wx.Mask(bmp, wx.BLUE)
335 bmp.SetMask(mask)
336
337 s = ogl.BitmapShape()
338 s.SetBitmap(bmp)
339 self.MyAddShape(s, 225, 130, None, None, "Bitmap")
340
341 #dc = wx.ClientDC(self)
342 #self.PrepareDC(dc)
343
344 for x in range(len(self.shapes)):
345 fromShape = self.shapes[x]
346 if x+1 == len(self.shapes):
347 toShape = self.shapes[0]
348 else:
349 toShape = self.shapes[x+1]
350
351 line = ogl.LineShape()
352 line.SetCanvas(self)
353 line.SetPen(wx.BLACK_PEN)
354 line.SetBrush(wx.BLACK_BRUSH)
355 line.AddArrow(ogl.ARROW_ARROW)
356 line.MakeLineControlPoints(2)
357 fromShape.AddLine(line, toShape)
358 self.diagram.AddShape(line)
359 line.Show(True)
360
361
362 def MyAddShape(self, shape, x, y, pen, brush, text):
363 # Composites have to be moved for all children to get in place
364 if isinstance(shape, ogl.CompositeShape):
365 dc = wx.ClientDC(self)
366 self.PrepareDC(dc)
367 shape.Move(dc, x, y)
368 else:
369 shape.SetDraggable(True, True)
370 shape.SetCanvas(self)
371 shape.SetX(x)
372 shape.SetY(y)
373 if pen: shape.SetPen(pen)
374 if brush: shape.SetBrush(brush)
375 if text:
376 for line in text.split('\n'):
377 shape.AddText(line)
378 #shape.SetShadowMode(ogl.SHADOW_RIGHT)
379 self.diagram.AddShape(shape)
380 shape.Show(True)
381
382 evthandler = MyEvtHandler(self.log, self.frame)
383 evthandler.SetShape(shape)
384 evthandler.SetPreviousHandler(shape.GetEventHandler())
385 shape.SetEventHandler(evthandler)
386
387 self.shapes.append(shape)
388 return shape
389
390
391 def OnBeginDragLeft(self, x, y, keys):
392 self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys))
393
394 def OnEndDragLeft(self, x, y, keys):
395 self.log.write("OnEndDragLeft: %s, %s, %s\n" % (x, y, keys))
396
397
398 #----------------------------------------------------------------------
399
400 def runTest(frame, nb, log):
401 # This creates some pens and brushes that the OGL library uses.
402 # It should be called after the app object has been created, but
403 # before OGL is used.
404 ogl.OGLInitialize()
405
406 win = TestWindow(nb, log, frame)
407 return win
408
409 #----------------------------------------------------------------------
410
411
412 overview = """<html><body>
413 <h2>Object Graphics Library</h2>
414
415 The Object Graphics Library is a library supporting the creation and
416 manipulation of simple and complex graphic images on a canvas.
417
418 <p>The OGL library was originally written in C++ and provided to
419 wxPython via an extension module wrapper as is most of the rest of
420 wxPython. The code has now been ported to Python (with many thanks to
421 Pierre Hjälm!) in order to make it be more easily maintainable and
422 less likely to get rusty because nobody cares about the C++ lib any
423 more.
424
425 """
426
427 if __name__ == '__main__':
428 import sys, os
429 import run
430 run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
431