Any examples of the wxCompositeShape OGL class?

Any examples of the wxCompositeShape OGL class?
Does anyone know of sample code using the wxCompositeShape class? C++ code would be fine. I just want to create a shape that contains other shapes.

Below is the code that I have so far, modified from wxOGL.py in the demo directory. It can be run using run.py in the demo directory. There are several problems, but the biggest is that there is a wxWindows assertion violation at wincmn.cpp, line 1995 when the composite object is dropped after dragging. I think I’m just missing some crucial concept somewhere.

wxPython: 2.3.3.1

OS: Win 2K

python: 2.2.1

TIA,

Matthew

from wxPython.wx import *

from wxPython.ogl import *

import images

···

#----------------------------------------------------------------------

This creates some pens and brushes that the OGL library uses.

wxOGLInitialize()

#----------------------------------------------------------------------

class DiamondShape(wxPolygonShape):

    def __init__(self, w=0.0, h=0.0):

            wxPolygonShape.__init__(self)

            if w == 0.0:

                    w = 60.0

            if h == 0.0:

                    h = 60.0

Either wxRealPoints or 2-tuples of floats works.

#points = [ wxRealPoint(0.0, -h/2.0),

            #          wxRealPoint(w/2.0,  0.0),

            #          wxRealPoint(0.0,    h/2.0),

            #          wxRealPoint(-w/2.0, 0.0),

            #          ]

            points = [ (0.0,    -h/2.0),

                               (w/2.0,  0.0),

                               (0.0,    h/2.0),

                               (-w/2.0, 0.0),

                               ]

self.Create(points)

#----------------------------------------------------------------------

class RoundedRectangleShape(wxRectangleShape):

    def __init__(self, w=0.0, h=0.0):

            wxRectangleShape.__init__(self, w, h)

            self.SetCornerRadius(-0.3)

class CompositeShape(wxCompositeShape):

    def __init__(self):

            wxCompositeShape.__init__(self)

#----------------------------------------------------------------------

class MyEvtHandler(wxShapeEvtHandler):

    def __init__(self, log, frame):

            wxShapeEvtHandler.__init__(self)

            self.log = log

            self.statbarFrame = frame

def UpdateStatusBar(self, shape):

            x,y = shape.GetX(), shape.GetY()

            width, height = shape.GetBoundingBoxMax()

            self.statbarFrame.SetStatusText("Pos: (%d,%d)  Size: (%d, %d)" %

                                                                            (x, y, width, height))

def OnLeftClick(self, x, y, keys = 0, attachment = 0):

            shape = self.GetShape()

            print shape.__class__

            canvas = shape.GetCanvas()

            dc = wxClientDC(canvas)

            canvas.PrepareDC(dc)

if shape.Selected():

                    shape.Select(false, dc)

                    canvas.Redraw(dc)

            else:

                    redraw = false

                    shapeList = canvas.GetDiagram().GetShapeList()

                    toUnselect = []

                    for s in shapeList:

                            if s.Selected():

                                    # If we unselect it now then some of the objects in

                                    # shapeList will become invalid (the control points are

                                    # shapes too!) and bad things will happen...

                                    toUnselect.append(s)

shape.Select(true, dc)

if toUnselect:

                            for s in toUnselect:

                                    s.Select(false, dc)

                            canvas.Redraw(dc)

self.UpdateStatusBar(shape)

def OnEndDragLeft(self, x, y, keys = 0, attachment = 0):

            shape = self.GetShape()

            self.base_OnEndDragLeft(x, y, keys, attachment)

            if not shape.Selected():

                    self.OnLeftClick(x, y, keys, attachment)

            self.UpdateStatusBar(shape)

def OnSize(self, x, y):

            self.base_OnSize(x, y)

            self.UpdateStatusBar(self.GetShape())

def OnMovePost(self, dc, x, y, oldX, oldY, display):

self.base_OnMovePost(dc, x, y, oldX, oldY, display)

self.UpdateStatusBar(self.GetShape())

def OnRightClick(self, *dontcare):

            self.log.WriteText("%s\n" % self.GetShape())

#----------------------------------------------------------------------

class TestWindow(wxShapeCanvas):

    def __init__(self, parent, log, frame):

            wxShapeCanvas.__init__(self, parent)

maxWidth = 1000

            maxHeight = 1000

            self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20)

self.log = log

            self.frame = frame

            self.SetBackgroundColour("LIGHT BLUE") #wxWHITE)

            self.diagram = wxDiagram()

            self.SetDiagram(self.diagram)

            self.diagram.SetCanvas(self)

            shapes = []

            self.save_gdi = []

self.MyAddShape(wxCircleShape(80), 100, 100,

                    wxPen(wxBLUE, 3), wxGREEN_BRUSH, "Circle", shapes)

            self.MyAddShape(wxRectangleShape(85, 50), 305, 60,

                    wxBLACK_PEN, wxLIGHT_GREY_BRUSH, "Rectangle", shapes)

           
            body = self.MyAddShape(wxRectangleShape(150, 100), 300, 260,

                    wxBLACK_PEN, wxCYAN_BRUSH, "Name",

                    bEventHandler = false, bDraggable = false)

            header = self.MyAddShape(wxRectangleShape(150, 30), 300, 260,

                    wxBLACK_PEN, wxBLUE_BRUSH, "Type",

                    bEventHandler = false, bDraggable = false)

compositeShape = CompositeShape()

            compositeShape.AddChild(body)

            compositeShape.AddChild(header)

           
            constraint = wxOGLConstraint(gyCONSTRAINT_BELOW, header, [body])

            compositeShape.AddConstraint(constraint)

           
            compositeShape.Recompute()

            self.MyAddShape(compositeShape, 500, 260,

                    wxBLACK_PEN, wxBLUE_BRUSH, "Composite", shapes)

            compositeShape.MakeContainer()

           
            dc = wxClientDC(self)

            self.PrepareDC(dc)

            for x in range(len(shapes)):

                    fromShape = shapes[x]

                    if x+1 == len(shapes):

                            toShape = shapes[0]

                    else:

                            toShape = shapes[x+1]

                    line = wxLineShape()

                    line.SetCanvas(self)

                    line.SetPen(wxBLACK_PEN)

                    line.SetBrush(wxBLACK_BRUSH)

                    line.AddArrow(ARROW_ARROW)

                    line.MakeLineControlPoints(2)

                    fromShape.AddLine(line, toShape)

                    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())

EVT_WINDOW_DESTROY(self, self.OnDestroy)

def MyAddShape(self, shape,

                    x = None, y = None,

                    pen = None, brush = None,

                    text = None, shapeList = None,

                    bEventHandler = true, bDraggable = true,

                    bAddToDiagram = true):

            shape.SetDraggable(bDraggable, bDraggable)

            shape.SetCanvas(self)

            if x != None: shape.SetX(x)

            if y != None: shape.SetY(y)

            if pen:    shape.SetPen(pen)

            if brush:  shape.SetBrush(brush)

            if text:   shape.AddText(text)

            if bAddToDiagram:

                    self.diagram.AddShape(shape)

           
            shape.Show(true)

if bEventHandler:

                    evthandler = MyEvtHandler(self.log, self.frame)

                    evthandler.SetShape(shape)

                    evthandler.SetPreviousHandler(shape.GetEventHandler())

                    shape.SetEventHandler(evthandler)

if shapeList != None:

                    shapeList.append(shape)

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

def OnEndDragLeft(self, x, y, keys):

            self.log.write("OnEndDragLeft: %s, %s, %s\n" % (x, y, keys))

#----------------------------------------------------------------------

def runTest(frame, nb, log):

    win = TestWindow(nb, log, frame)

    return win

#----------------------------------------------------------------------

class __Cleanup:

    cleanup = wxOGLCleanUp

    def __del__(self):

            self.cleanup()

when this module gets cleaned up then wxOGLCleanUp() will get called

__cu = __Cleanup()

overview = “”"\

The Object Graphics Library is a library supporting the creation and

manipulation of simple and complex graphic images on a canvas.

“”"