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.
“”"