wxOGL and Shape.Select()

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