]> git.saurik.com Git - wxWidgets.git/blobdiff - wxPython/demo/OGL.py
Stop the timer when the sample is destroyed
[wxWidgets.git] / wxPython / demo / OGL.py
index 32df0612ec11db976c3f3b190ebe6f661dc0a050..871e6bc9cb416263ee6b8dc7a316a3e746a8646b 100644 (file)
@@ -1,15 +1,55 @@
+# -*- coding: iso-8859-1 -*-
 # 11/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
 #
 # o Updated for wx namespace
 # 
+# 20040508 - Pierre Hjälm
+#
+# o Changed to use the python version of OGL
+# o Added TextShape, CompositeShape and CompositeShape with divisions
+#
+# 20040830 - Pierre Hjälm
+#
+# o Added DrawnShape
+#
 
-import  wx
-import  wx.ogl  as  ogl
+import wx
+import wx.lib.ogl as ogl
 
 import  images
 
-##wx.Trap()
+#----------------------------------------------------------------------
+
+class DrawnShape(ogl.DrawnShape):
+    def __init__(self):
+        ogl.DrawnShape.__init__(self)
+
+        self.SetDrawnBrush(wx.WHITE_BRUSH)
+        self.SetDrawnPen(wx.BLACK_PEN)
+        self.DrawArc((0, -10), (30, 0), (-30, 0))
+
+        self.SetDrawnPen(wx.Pen("#ff8030"))
+        self.DrawLine((-30, 5), (30, 5))
+
+        self.SetDrawnPen(wx.Pen("#00ee10"))
+        self.DrawRoundedRectangle((-20, 10, 40, 10), 5)
+
+        self.SetDrawnPen(wx.Pen("#9090f0"))
+        self.DrawEllipse((-30, 25, 60, 20))
+
+        self.SetDrawnTextColour(wx.BLACK)
+        self.SetDrawnFont(wx.Font(8, wx.SWISS, wx.NORMAL, wx.NORMAL))
+        self.DrawText("DrawText", (-26, 28))
+
+        self.SetDrawnBrush(wx.GREEN_BRUSH)
+        self.DrawPolygon([(-100, 5), (-45, 30), (-35, 20), (-30, 5)])
+
+        self.SetDrawnPen(wx.BLACK_PEN)
+        self.DrawLines([(30, -45), (40, -45), (40 ,45), (30, 45)])
 
+        # Make sure to call CalculateSize when all drawing is done
+        self.CalculateSize()
+        
 #----------------------------------------------------------------------
 
 class DiamondShape(ogl.PolygonShape):
@@ -20,13 +60,6 @@ class DiamondShape(ogl.PolygonShape):
         if h == 0.0:
             h = 60.0
 
-        # Either ogl.RealPoints or 2-tuples of floats  works.
-
-        #points = [ ogl.RealPoint(0.0,    -h/2.0),
-        #          ogl.RealPoint(w/2.0,  0.0),
-        #          ogl.RealPoint(0.0,    h/2.0),
-        #          ogl.RealPoint(-w/2.0, 0.0),
-        #          ]
         points = [ (0.0,    -h/2.0),
                    (w/2.0,  0.0),
                    (0.0,    h/2.0),
@@ -44,6 +77,67 @@ class RoundedRectangleShape(ogl.RectangleShape):
         self.SetCornerRadius(-0.3)
 
 
+#----------------------------------------------------------------------
+
+class CompositeDivisionShape(ogl.CompositeShape):
+    def __init__(self, canvas):
+        ogl.CompositeShape.__init__(self)
+
+        self.SetCanvas(canvas)
+
+        # create a division in the composite
+        self.MakeContainer()
+
+        # add a shape to the original division
+        shape2 = ogl.RectangleShape(40, 60)
+        self.GetDivisions()[0].AddChild(shape2)
+
+        # now divide the division so we get 2
+        self.GetDivisions()[0].Divide(wx.HORIZONTAL)
+
+        # and add a shape to the second division (and move it to the
+        # centre of the division)
+        shape3 = ogl.CircleShape(40)
+        shape3.SetBrush(wx.CYAN_BRUSH)
+        self.GetDivisions()[1].AddChild(shape3)
+        shape3.SetX(self.GetDivisions()[1].GetX())
+
+        for division in self.GetDivisions():
+            division.SetSensitivityFilter(0)
+        
+#----------------------------------------------------------------------
+
+class CompositeShape(ogl.CompositeShape):
+    def __init__(self, canvas):
+        ogl.CompositeShape.__init__(self)
+
+        self.SetCanvas(canvas)
+
+        constraining_shape = ogl.RectangleShape(120, 100)
+        constrained_shape1 = ogl.CircleShape(50)
+        constrained_shape2 = ogl.RectangleShape(80, 20)
+
+        constraining_shape.SetBrush(wx.BLUE_BRUSH)
+        constrained_shape2.SetBrush(wx.RED_BRUSH)
+        
+        self.AddChild(constraining_shape)
+        self.AddChild(constrained_shape1)
+        self.AddChild(constrained_shape2)
+
+        constraint = ogl.Constraint(ogl.CONSTRAINT_MIDALIGNED_BOTTOM, constraining_shape, [constrained_shape1, constrained_shape2])
+        self.AddConstraint(constraint)
+        self.Recompute()
+
+        # If we don't do this, the shapes will be able to move on their
+        # own, instead of moving the composite
+        constraining_shape.SetDraggable(False)
+        constrained_shape1.SetDraggable(False)
+        constrained_shape2.SetDraggable(False)
+
+        # If we don't do this the shape will take all left-clicks for itself
+        constraining_shape.SetSensitivityFilter(0)
+
+        
 #----------------------------------------------------------------------
 
 class DividedShape(ogl.DividedShape):
@@ -88,7 +182,7 @@ class DividedShape(ogl.DividedShape):
 
     def OnSizingEndDragLeft(self, pt, x, y, keys, attch):
         print "***", self
-        self.base_OnSizingEndDragLeft(pt, x, y, keys, attch)
+        ogl.DividedShape.OnSizingEndDragLeft(self, pt, x, y, keys, attch)
         self.SetRegionSizes()
         self.ReformatRegions()
         self.GetCanvas().Refresh()
@@ -103,15 +197,14 @@ class MyEvtHandler(ogl.ShapeEvtHandler):
         self.statbarFrame = frame
 
     def UpdateStatusBar(self, shape):
-        x,y = shape.GetX(), shape.GetY()
+        x, y = shape.GetX(), shape.GetY()
         width, height = shape.GetBoundingBoxMax()
-        self.statbarFrame.SetStatusText("Pos: (%d,%d)  Size: (%d, %d)" %
+        self.statbarFrame.SetStatusText("Pos: (%d, %d)  Size: (%d, %d)" %
                                         (x, y, width, height))
 
 
-    def OnLeftClick(self, x, y, keys = 0, attachment = 0):
+    def OnLeftClick(self, x, y, keys=0, attachment=0):
         shape = self.GetShape()
-        print shape.__class__, shape.GetClassName()
         canvas = shape.GetCanvas()
         dc = wx.ClientDC(canvas)
         canvas.PrepareDC(dc)
@@ -142,9 +235,9 @@ class MyEvtHandler(ogl.ShapeEvtHandler):
         self.UpdateStatusBar(shape)
 
 
-    def OnEndDragLeft(self, x, y, keys = 0, attachment = 0):
+    def OnEndDragLeft(self, x, y, keys=0, attachment=0):
         shape = self.GetShape()
-        self.base_OnEndDragLeft(x, y, keys, attachment)
+        ogl.ShapeEvtHandler.OnEndDragLeft(self, x, y, keys, attachment)
 
         if not shape.Selected():
             self.OnLeftClick(x, y, keys, attachment)
@@ -153,12 +246,12 @@ class MyEvtHandler(ogl.ShapeEvtHandler):
 
 
     def OnSizingEndDragLeft(self, pt, x, y, keys, attch):
-        self.base_OnSizingEndDragLeft(pt, x, y, keys, attch)
+        ogl.ShapeEvtHandler.OnSizingEndDragLeft(self, pt, x, y, keys, attch)
         self.UpdateStatusBar(self.GetShape())
 
 
     def OnMovePost(self, dc, x, y, oldX, oldY, display):
-        self.base_OnMovePost(dc, x, y, oldX, oldY, display)
+        ogl.ShapeEvtHandler.OnMovePost(self, dc, x, y, oldX, oldY, display)
         self.UpdateStatusBar(self.GetShape())
 
 
@@ -188,38 +281,58 @@ class TestWindow(ogl.ShapeCanvas):
         rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID)
         dsBrush = wx.Brush("WHEAT", wx.SOLID)
 
+        self.MyAddShape(
+            CompositeDivisionShape(self), 
+            270, 310, wx.BLACK_PEN, wx.BLUE_BRUSH, "Division"
+            )
+        
+        self.MyAddShape(
+            CompositeShape(self), 
+            100, 260, wx.BLACK_PEN, wx.RED_BRUSH, "Composite"
+            )
+        
         self.MyAddShape(
             ogl.CircleShape(80), 
-            100, 100, wx.Pen(wx.BLUE, 3), wx.GREEN_BRUSH, "Circle"
+            75, 110, wx.Pen(wx.BLUE, 3), wx.GREEN_BRUSH, "Circle"
             )
             
+        self.MyAddShape(
+            ogl.TextShape(120, 45), 
+            160, 35, wx.GREEN_PEN, wx.LIGHT_GREY_BRUSH, "OGL is now a\npure Python lib!"
+            )
+
         self.MyAddShape(
             ogl.RectangleShape(85, 50), 
             305, 60, wx.BLACK_PEN, wx.LIGHT_GREY_BRUSH, "Rectangle"
             )
 
+        self.MyAddShape(
+            DrawnShape(),
+            500, 80, wx.BLACK_PEN, wx.BLACK_BRUSH, "DrawnShape"
+            )
+
         ds = self.MyAddShape(
-                    DividedShape(140, 150, self), 
-                    495, 145, wx.BLACK_PEN, dsBrush, ''
-                    )
+            DividedShape(140, 150, self), 
+            520, 265, wx.BLACK_PEN, dsBrush, ''
+            )
 
         self.MyAddShape(
             DiamondShape(90, 90), 
-            345, 235, wx.Pen(wx.BLUE, 3, wx.DOT), wx.RED_BRUSH, "Polygon"
+            355, 260, wx.Pen(wx.BLUE, 3, wx.DOT), wx.RED_BRUSH, "Polygon"
             )
             
         self.MyAddShape(
-            RoundedRectangleShape(95,70), 
-            140, 255, wx.Pen(wx.RED, 2), rRectBrush, "Rounded Rect"
+            RoundedRectangleShape(95, 70), 
+            345, 145, wx.Pen(wx.RED, 2), rRectBrush, "Rounded Rect"
             )
 
         bmp = images.getTest2Bitmap()
-        mask = wx.MaskColour(bmp, wx.BLUE)
+        mask = wx.Mask(bmp, wx.BLUE)
         bmp.SetMask(mask)
 
         s = ogl.BitmapShape()
         s.SetBitmap(bmp)
-        self.MyAddShape(s, 225, 150, None, None, "Bitmap")
+        self.MyAddShape(s, 225, 130, None, None, "Bitmap")
 
         dc = wx.ClientDC(self)
         self.PrepareDC(dc)
@@ -241,20 +354,23 @@ class TestWindow(ogl.ShapeCanvas):
             self.diagram.AddShape(line)
             line.Show(True)
 
-            # for some reason, the shapes have to be moved for the line to show up...
-            fromShape.Move(dc, fromShape.GetX(), fromShape.GetY())
-
-        self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy)
-
 
     def MyAddShape(self, shape, x, y, pen, brush, text):
-        shape.SetDraggable(True, True)
+        # Composites have to be moved for all children to get in place
+        if isinstance(shape, ogl.CompositeShape):
+            dc = wx.ClientDC(self)
+            self.PrepareDC(dc)
+            shape.Move(dc, x, y)
+        else:
+            shape.SetDraggable(True, True)
         shape.SetCanvas(self)
         shape.SetX(x)
         shape.SetY(y)
         if pen:    shape.SetPen(pen)
         if brush:  shape.SetBrush(brush)
-        if text:   shape.AddText(text)
+        if text:
+            for line in text.split('\n'):
+                shape.AddText(line)
         #shape.SetShadowMode(ogl.SHADOW_RIGHT)
         self.diagram.AddShape(shape)
         shape.Show(True)
@@ -268,16 +384,6 @@ class TestWindow(ogl.ShapeCanvas):
         return shape
 
 
-    def OnDestroy(self, evt):
-        # Do some cleanup
-        for shape in self.diagram.GetShapeList():
-            if shape.GetParent() == None:
-                shape.SetCanvas(None)
-                shape.Destroy()
-
-        self.diagram.Destroy()
-
-
     def OnBeginDragLeft(self, x, y, keys):
         self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys))
 
@@ -298,25 +404,24 @@ def runTest(frame, nb, log):
     
 #----------------------------------------------------------------------
 
-# The OGL library holds some resources that need to be freed before
-# the app shuts down.
-class __Cleanup:
-    def __del__(self, cleanup=ogl.OGLCleanUp):
-        cleanup()
-
-# When this module gets cleaned up by Python then __cu will be cleaned
-# up and it's __dell__ is called, which will then call ogl.OGLCleanUp.
-__cu = __Cleanup()
 
+overview = """<html><body>
+<h2>Object Graphics Library</h2>
 
-overview = """\
 The Object Graphics Library is a library supporting the creation and
 manipulation of simple and complex graphic images on a canvas.
 
+<p>The OGL library was originally written in C++ and provided to
+wxPython via an extension module wrapper as is most of the rest of
+wxPython.  The code has now been ported to Python (with many thanks to
+Pierre Hjälm!) in order to make it be more easily maintainable and
+less likely to get rusty because nobody cares about the C++ lib any
+more.
+
 """
 
 if __name__ == '__main__':
-    import sys,os
+    import sys, os
     import run
     run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])