RE: [wxPython-users] wxOGL and Shape.Select()
Jeff, below is some code that defines the shape classes that I use
in my project. The Redraw() and SizeSet() methods may be of use to you.
… mucho Python code …
from wxPython.wx import *
from wxPython.ogl import *
import weakref
BOUNDING_BOX_OFFSET = 2.0
bConnectShapes = 0
···
#----------------------------------------------------------------------
class UniversalShape:
def __init__(self, wxType, object, *_args, **_kwargs):
apply(wxType.__init__, [self] + list(_args), _kwargs)
self._object = None
if object != None:
object.ShapeSet(self)
self.ObjectSet(object)
self.bLimitPosition = 1
self._ref = weakref.ref(self)
eventHandler = ShapeEvtHandler()
eventHandler.SetShape(self)
eventHandler.SetPreviousHandler(self.GetEventHandler())
self.SetEventHandler(eventHandler)
def ForceMove(self, dc = None):
# Force a move to get the shape to redraw correctly
if dc == None:
canvas = self.GetCanvas()
dc = canvas.DcGet()
self.Move(dc, self.GetX(), self.GetY())
def IsLine(self):
return 0
def ObjectGet(self):
if self._object == None:
return None
else:
return self._object()
def ObjectSet(self, object):
if self._object != None:
assert self._object() == object
else:
self._object = weakref.ref(object)
def RectGet(self):
pen = self.GetPen()
penWidth = pen.GetWidth()
maxX, maxY = self.GetBoundingBoxMax()
topLeftX = (self.GetX() - (maxX / 2.0) - \
BOUNDING_BOX_OFFSET) - penWidth
topLeftY = (self.GetY() - (maxY / 2.0) - \
BOUNDING_BOX_OFFSET) - penWidth
width = maxX + ((penWidth + BOUNDING_BOX_OFFSET) * 2.0)
height = maxY + ((penWidth + BOUNDING_BOX_OFFSET) * 2.0)
rect = wxRect(topLeftX, topLeftY, width, height)
return rect
def Redraw(self, dc = None):
if dc == None:
canvas = self.GetCanvas()
dc = canvas.DcGet()
# Another option is to call self.GetCanvas().Redraw(), but this
# forces all objects to be drawn, which seems like overkill
self.Draw(dc)
self.GetCanvas().Refresh(rect = self.RectGet())
return dc
def RegionGet(self):
rect = self.RectGet()
return wxRegion(rect.x, rect.y, rect.width, rect.height)
def RefGet(self):
return self._ref
def Resize(self, sizeNew):
sizeCur = self.GetBoundingBoxMax()
posX = self.GetX()
posY = self.GetY()
penWidth = self.GetPen().GetWidth()
centerX = posX - (sizeCur[0] * .5) + \
(.5 * sizeNew[0]) + penWidth + BOUNDING_BOX_OFFSET
centerY = posY - (sizeCur[1] * .5) + \
(.5 * sizeNew[1]) + penWidth + BOUNDING_BOX_OFFSET
canvas = self.GetCanvas()
dc = wxClientDC(canvas)
canvas.PrepareDC(dc)
self.SetSize(sizeNew[0], sizeNew[1])
self.Move(dc, centerX, centerY)
def SizeSet(self, width, height):
rectPrev = self.RectGet()
self.SetSize(width, height)
self.Redraw()
self.GetCanvas().Refresh(rect = rectPrev)
def TextSet(self, text, bDraw = 1):
self.text = text
self.ClearText()
self.AddText(text)
if bDraw:
self.Redraw()
def VisibleSet(self, bVisible, bRedraw = true):
self.Show(bVisible)
if bRedraw:
self.Redraw()
if not bVisible:
canvas = self.GetCanvas()
if self.RefGet() in canvas.shapeSelection:
canvas.ShapeSelect(self, 0, false)
class CircleShape(wxCircleShape, UniversalShape):
def __init__(self, object, *_args, **_kwargs):
UniversalShape.__init__(self, wxCircleShape, object, *_args, **_kwargs)
class DiamondShape(wxPolygonShape, UniversalShape):
# TODO
def __init__(self, object, *_args, **_kwargs):
UniversalShape.__init__(self, wxPolygonShape, object, *_args, **_kwargs)
class RectangleShape(wxRectangleShape, UniversalShape):
def __init__(self, object, *_args, **_kwargs):
UniversalShape.__init__(self, wxRectangleShape, object, *_args, **_kwargs)
class BitmapShape(wxBitmapShape, UniversalShape):
def __init__(self, object, *_args, **_kwargs):
bitmap = None
argCount = len(_args)
if argCount > 0:
args = list(_args)
bitmap = args.pop(argCount - 1)
_args = tuple(args)
UniversalShape.__init__(self, wxBitmapShape, object, *_args, **_kwargs)
if bitmap != None:
self.SetBitmap(bitmap)
class LineShape(wxLineShape, UniversalShape):
lineControlPoints = 3
def __init__(self, object, *_args, **_kwargs):
UniversalShape.__init__(self, wxLineShape, object, *_args, **_kwargs)
def IsLine(self):
return 1
def TextSet(self, text):
pass
#----------------------------------------------------------------------
BOUNDARY_BORDER = 8
class ShapeEvtHandler(wxShapeEvtHandler):
def __init__(self):
wxShapeEvtHandler.__init__(self)
self.xMin = self.yMin = 0.0
self.bDraggable = false
def LineDraw(self, x, y, attachment):
shape, canvas = self.ShapeCanvasGet()
if canvas != None:
dc = canvas.DcGet()
dottedPen = wxPen(wxColour(0, 0, 0), 1, wxDOT)
dc.SetLogicalFunction(wxINVERT)
dc.SetPen(dottedPen)
pos = shape.GetAttachmentPositionEdge(attachment)
dc.DrawLine(pos[1], pos[2], x, y)
def OnBeginDragLeft(self, x, y, keys, attachment):
shape = self.GetShape()
self.bDraggable = false
object = shape.ObjectGet()
if object != None:
self.bDraggable = not object.ShapeOnBeginDragLeft()
if self.bDraggable:
if shape.bLimitPosition:
xShape = shape.GetX()
yShape = shape.GetY()
width, height = shape.GetBoundingBoxMax()
self.xMin = ((x - xShape) + width / 2.0) + BOUNDARY_BORDER
self.yMin = ((y - yShape) + height / 2.0) + BOUNDARY_BORDER
self.base_OnBeginDragLeft(x, y, keys,attachment)
def OnBeginDragRight(self, x, y, keys, attachment):
shape, canvas = self.ShapeCanvasGet()
if bConnectShapes:
self.LineDraw(x, y, attachment)
canvas.CaptureMouse()
def OnDragLeft(self, arg1, x, y, keys, attachment):
if self.bDraggable:
shape = self.GetShape()
if shape.bLimitPosition:
x = max(x, self.xMin)
y = max(y, self.yMin)
self.base_OnDragLeft(arg1, x, y, keys, attachment)
def OnDragRight(self, arg1, x, y, keys, attachment):
shape, canvas = self.ShapeCanvasGet()
if bConnectShapes:
self.LineDraw(x, y, attachment)
def OnEndDragLeft(self, x, y, keys = 0, attachment = 0):
if self.bDraggable:
shape = self.GetShape()
if shape.bLimitPosition:
x = max(x, self.xMin)
y = max(y, self.yMin)
self.base_OnEndDragLeft(x, y, keys, attachment)
if not shape.Selected():
self.OnLeftClick(x, y, keys, attachment)
object = shape.ObjectGet()
if object != None:
object.ShapeOnEndDragLeft()
def OnEndDragRight(self, x, y, keys = 0, attachment = 0):
shape, canvas = self.ShapeCanvasGet()
if bConnectShapes:
canvas.ReleaseMouse()
# Check if we're on an object
otherShape = canvas.FindFirstSensitiveShape(x, y, OP_DRAG_RIGHT)
if otherShape:
otherShape, attachmentNew = otherShape
if not otherShape.IsLine():
canvas.ShapesConnect(shape, otherShape)
def OnSize(self, x, y):
self.base_OnSize(x, y)
#~ def OnMovePost(self, dc, x, y, oldX, oldY, display):
#~ self.base_OnMovePost(dc, x, y, oldX, oldY, display)
def OnLeftClick(self, x, y, keys = 0, attachment = 0):
shape, canvas = self.ShapeCanvasGet()
object = shape.ObjectGet()
if object != None:
if not object.ShapeOnLeftClick(self.ScreenPositionGet(x, y)):
canvas.ShapeSelect(shape, keys)
def OnLeftDoubleClick(self, x, y, keys, attachment):
shape = self.GetShape()
object = shape.ObjectGet()
if object != None:
object.ShapeOnLeftDoubleClick(self.ScreenPositionGet(x, y))
def OnRightClick(self, *dontcare):
pass
def ScreenPositionGet(self, x, y, dc = None):
shape, canvas = self.ShapeCanvasGet()
if dc == None:
dc = canvas.DcGet()
xl = dc.LogicalToDeviceX(x)
yl = dc.LogicalToDeviceY(y)
xl, yl = canvas.ClientToScreenXY(xl, yl)
return (xl, yl)
def ShapeCanvasGet(self):
canvas = None
shape = self.GetShape()
if shape != None:
canvas = shape.GetCanvas()
return shape, canvas
#----------------------------------------------------------------------
-----Original Message-----
From: Robin Dunn [mailto:robin@alldunn.com]
Sent: Tuesday, January 21, 2003 6:07 PM
To: wxPython-users@lists.wxwindows.org
Subject: Re: [wxPython-users] wxOGL and Shape.Select()
Jeff Kotula wrote:
Turns out the problem I was seeing only manifested when the size of
the Shape was being changed. The workaround was to deselect the
shape, then edit it, then select it when the resizing was all done.
It probably was just a window refresh thing then. The selection handle
shapes were getting moved with the resize, but the old spots were not
getting repainted.
–
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!
To unsubscribe, e-mail: wxPython-users-unsubscribe@lists.wxwindows.org
For additional commands, e-mail: wxPython-users-help@lists.wxwindows.org