[wxPython-users] Re: Graphical Hierarchy Tree in wxPython

Werner F. Bruhin werner.bruhin at free.fr
Sat Jul 14 01:26:03 PDT 2007


Hi Astan,

Astan Chee wrote:
> Astan Chee wrote:
>> Hi,
>> Im trying to make a tree view in wxPython, except it is graphed and =

>> expressed as nodes. I've tried to modify the demo classes but before =

>> I do that, I was wondering if something like this actually existed in =

>> wxPython. So instead of the normal tree view like =

>> http://www.xmodeler.com/images/part1/figure1.2.PNG , Im trying to =

>> display like =

>> http://wwweic.eri.u-tokyo.ac.jp/computer/manual/lx/SGI_Developer/books/P=
erf_GetStarted/sgi_html/figures/scene.graph.hierarchy.gif =

>> complete with rubber bands, dragable images and =

>> colapseable/expandable views (and combination of these functions).
>> Does anyone know of an existing example in wxPython?
>> People have suggested I use FloatCanvas, and I have no idea how to =

>> use it. People suggested it because it has zoom and pan views (which =

>> might be useful).
>> Anyway, Im half way modifying the wxPython's demo of wxDragImage.
>>
> Hi everyone,
> So I've finished modifying the wxDragImage class to support what I =

> wanted to do as mentioned above. I didnt use FloatCanvas for this =

> because I wanted to display text also I seemed to like the wxDragImage =

> better. As for zooming, I think scrolling is the same thing. The code =

> works by creating a hierarchy from dictionaries that may contain other =

> (deeper) dictionaries.
> One final thing that Im trying to get to work in this is whenever I =

> select multiple texts, I want to move them as well (multiple =

> dragImages). Im not sure how to approach this.
> Any ideas?
Can't help you on the problem, but i noted that you used the old name =

space which gives deprecation warnings on wxPython 2.8, so attached is a =

version which uses the new name space (import wx).

Werner
-------------- next part --------------
import wx
#----------------------------------------------------------------------

class DragShape:
    def __init__(self, bmp):
        self.bmp =3D bmp
        self.pos =3D wx.Point(0,0)
        self.shown =3D True
        self.text =3D None
        self.fullscreen =3D False
        self.size =3D wx.Size(0,0)
        self.line =3D None
        self.parent =3D None
        self.ext =3D None
        self.normal =3D wx.BLACK

    def HitTest(self, pt):
        rect =3D self.GetRect()
        return rect.InsideXY(pt.x, pt.y)


    def GetRect(self):
        return wxRect(self.pos.x, self.pos.y,
                      self.bmp.GetWidth(), self.bmp.GetHeight())


    def Draw(self, dc, op =3D wx.COPY):
        if self.bmp.Ok():
            memDC =3D wx.MemoryDC()
            memDC.SelectObject(self.bmp)

            dc.Blit(self.pos.x, self.pos.y,
                    self.bmp.GetWidth(), self.bmp.GetHeight(),
                    memDC, 0, 0, op, True)

            return True
        else:
            return False

    def SetSelected(self,dc, op =3D wx.COPY):
        if self.bmp.Ok():
            bg_colour =3D wx.Colour(0, 0, 0)
            font =3D wx.Font(15, wx.ROMAN, wx.NORMAL, wx.BOLD)
            self.bmp =3D wx.EmptyBitmap(self.size.GetWidth(), self.size.Get=
Height())
            memDC =3D wx.MemoryDC()
            memDC.SelectObject(self.bmp)
            memDC.Clear()
            memDC.SetTextForeground(wx.RED)
            memDC.SetFont(font)
            memDC.DrawText(self.text, 0, 0)
            memDC.SelectObject(wx.NullBitmap)
            mask =3D wx.Mask(self.bmp, bg_colour)
            self.bmp.SetMask(mask)

            dc.Blit(self.pos.x, self.pos.y,
                    self.bmp.GetWidth(), self.bmp.GetHeight(),
                    memDC, 0, 0, op, True)

            return True
        else:
            return False
    def SetUnSelected(self,dc, op =3D wx.COPY):
        if self.bmp.Ok():
            bg_colour =3D wx.Colour(0, 0, 0)
            font =3D wx.Font(15, wx.ROMAN, wx.NORMAL, wx.BOLD)
            self.bmp =3D wx.EmptyBitmap(self.size.GetWidth(), self.size.Get=
Height())
            memDC =3D wx.MemoryDC()
            memDC.SelectObject(self.bmp)
            memDC.Clear()
            memDC.SetTextForeground(self.normal)
            memDC.SetFont(font)
            memDC.DrawText(self.text, 0, 0)
            memDC.SelectObject(wx.NullBitmap)
            mask =3D wx.Mask(self.bmp, bg_colour)
            self.bmp.SetMask(mask)

            dc.Blit(self.pos.x, self.pos.y,
                    self.bmp.GetWidth(), self.bmp.GetHeight(),
                    memDC, 0, 0, op, True)

            return True
        else:
            return False

    def Expand(self,dc, op =3D wx.COPY):
        if self.bmp.Ok():
            bg_colour =3D wx.Colour(0, 0, 0)
            font =3D wx.Font(15, wx.ROMAN, wx.NORMAL, wx.BOLD)
            self.bmp =3D wx.EmptyBitmap(self.size.GetWidth(), self.size.Get=
Height())
            memDC =3D wx.MemoryDC()
            memDC.SelectObject(self.bmp)
            memDC.Clear()
            memDC.SetTextForeground(wx.BLUE)
            memDC.SetFont(font)
            memDC.DrawText(self.text, 0, 0)
            memDC.SelectObject(wx.NullBitmap)
            mask =3D wx.Mask(self.bmp, bg_colour)
            self.bmp.SetMask(mask)

            dc.Blit(self.pos.x, self.pos.y,
                    self.bmp.GetWidth(), self.bmp.GetHeight(),
                    memDC, 0, 0, op, True)

            return True
        else:
            return False

    def Colapse(self,dc, op =3D wx.COPY):
        if self.bmp.Ok():
            bg_colour =3D wx.Colour(0, 0, 0)
            font =3D wx.Font(15, wx.ROMAN, wx.NORMAL, wx.BOLD)
            self.bmp =3D wx.EmptyBitmap(self.size.GetWidth(), self.size.Get=
Height())
            memDC =3D wx.MemoryDC()
            memDC.SelectObject(self.bmp)
            memDC.Clear()
            memDC.SetTextForeground(wx.GREEN)
            memDC.SetFont(font)
            memDC.DrawText(self.text, 0, 0)
            memDC.SelectObject(wx.NullBitmap)
            mask =3D wx.Mask(self.bmp, bg_colour)
            self.bmp.SetMask(mask)

            dc.Blit(self.pos.x, self.pos.y,
                    self.bmp.GetWidth(), self.bmp.GetHeight(),
                    memDC, 0, 0, op, True)

            return True
        else:
            return False

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

class DragCanvas(wx.ScrolledWindow):
    def __init__(self, parent, ID):
        wx.ScrolledWindow.__init__(self, parent, ID)
        self.shapes =3D []
        self.dragImage =3D None
        self.dragShape =3D None
        self.hiliteShape =3D None
        self.select_mode =3D 0
        self.select_start =3D None
        self.select_end =3D None
        self.m_savepoint=3DNone
        self._leftclicked=3DFalse
        self._selected=3DFalse
        self.s_savepoint=3DNone
        self.selected_shapes =3D []

        self.SetCursor(wx.StockCursor(wx.CURSOR_ARROW))
        w,h =3D self.GetClientSize()

        self.bg_bmp =3D wx.EmptyBitmap(w,h)

        self.elements =3D {"CEO":[{"VP 1":["Assistent VP 1","Assistent VP 2=
"]},"VP 2"],"father":["son","daughter"]}
        #self.elements =3D {"grandmother":["son","mother"],"President":["VP=
1","VP2"]}
        # Make a shape from dict
        self.hs =3D [0,0]
        bg_colour =3D wx.Colour(0, 0, 0)
        font =3D wx.Font(15, wx.ROMAN, wx.NORMAL, wx.BOLD)
        self.wbrush =3D wx.Brush(wx.RED, wx.TRANSPARENT)
        self.wpen =3D wx.Pen(wx.RED, 1, wx.SOLID)
        for group,nodez in self.elements.items():
            textExtent =3D self.GetFullTextExtent(group, font)
            bmp =3D wx.EmptyBitmap(textExtent[0], textExtent[1])
            dc =3D wx.MemoryDC()
            dc.SelectObject(bmp)
            dc.Clear()
            dc.SetTextForeground(wx.BLUE)
            dc.SetFont(font)
            dc.DrawText(group, 0, 0)
            dc.SelectObject(wx.NullBitmap)
            mask =3D wx.Mask(bmp, bg_colour)
            bmp.SetMask(mask)
            shape =3D DragShape(bmp)
            shape.pos =3D wx.Point(0, self.hs[0])
            shape.text =3D group
            shape.parent =3D "root"
            shape.normal=3Dwx.BLUE
            shape.ext =3D True
            shape.size =3D bmp.GetSize()
            self.shapes.append(shape)
            self.hs[0]+=3Dbmp.GetSize().GetHeight()+30
            parent =3D shape
            for node in nodez:
                try:
                    for subgroup, subnodes in node.items():
                        self.doParentChild(subgroup,subnodes,2,parent)
                except AttributeError:
                    textExtent =3D self.GetFullTextExtent(node, font)
                    bmp =3D wx.EmptyBitmap(textExtent[0], textExtent[1])
                    dc =3D wx.MemoryDC()
                    dc.SelectObject(bmp)
                    dc.Clear()
                    dc.SetTextForeground(wx.BLACK)
                    dc.SetFont(font)
                    dc.DrawText(node, 0, 0)
                    dc.SelectObject(wx.NullBitmap)
                    mask =3D wx.Mask(bmp, bg_colour)
                    bmp.SetMask(mask)
                    shape =3D DragShape(bmp)
                    shape.pos =3D wx.Point(220, self.hs[1])
                    shape.text =3D node
                    shape.parent =3D parent
                    shape.size =3D bmp.GetSize()
                    self.hs[1]+=3Dbmp.GetSize().GetHeight()+30
                    child =3D shape
                    x1,y1 =3D parent.pos
                    x2,y2 =3D child.pos
                    x1+=3Dparent.size.GetWidth()
                    y1+=3D(parent.size.GetHeight()/2)
                    x2+=3D2
                    y2+=3D(child.size.GetHeight()/2)
                    angle =3D 0
                    if x1 > x2 and y1 > y2:
                        angle =3D 1
                    if x1 > x2:
                        if angle =3D=3D 0:
                            angle =3D 2
                        temp =3D x2
                        x2 =3D x1
                        x1 =3D temp
                    if y1 > y2:
                        if angle =3D=3D 0:
                            angle =3D 2
                        temp =3D y2
                        y2 =3D y1
                        y1 =3D temp
                    if (x2-x1) < 2:
                        x2+=3D2
                    if (y2-y1) < 2:
                        y2+=3D2
                    bmp =3D wx.EmptyBitmap(abs(x2-x1), abs(y2-y1))
                    dc =3D wx.MemoryDC()
                    dc.Clear()
                    dc.SelectObject(bmp)
                    dc.SetBrush(self.wbrush)
                    dc.SetPen(self.wpen)
                    if angle =3D=3D 0 or angle =3D=3D 1:
                        dc.DrawLine(0, 0, abs(x2-x1),abs(y2-y1))
                    else:
                        dc.DrawLine(abs(x2-x1), 0, 0,abs(y2-y1))
                    dc.SelectObject(wx.NullBitmap)
                    mask =3D wx.Mask(bmp, bg_colour)
                    bmp.SetMask(mask)
                    line =3D DragShape(bmp)
                    line.pos =3D wx.Point(x1,y1)
                    shape.line =3D line
                    self.shapes.append(shape)
        maxX =3D 0
        maxY =3D 0
        for s in self.hs:
            if maxX < s:
                maxX =3D s
        if maxX < 700:
            maxX =3D 700
        maxY =3D len(self.hs)+1
        maxY=3DmaxY*200
        if maxY<460:
            maxY=3D460
        self.SetScrollbars(20, 20, maxX/20, maxY/20)
        self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
        self.Bind(wx.EVT_PAINT, self.OnPaint)
        self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
        self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
        self.Bind(wx.EVT_MOTION, self.OnMotion)
        self.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeaveWindow)
        self.Bind(wx.EVT_LEFT_DCLICK, self.OnLeftDClick)


    def OnLeaveWindow(self, evt):
        pass

    def doParentChild(self,group,nodez,level,gp):
        bg_colour =3D wx.Colour(0, 0, 0)
        font =3D wx.Font(15, wx.ROMAN, wx.NORMAL, wx.BOLD)
        while len(self.hs)<=3Dlevel:
            self.hs.append(0)
        level1 =3D level-1
        pos1 =3D self.hs[level1]
        pos2 =3D self.hs[level]
        textExtent =3D self.GetFullTextExtent(group, font)
        bmp =3D wx.EmptyBitmap(textExtent[0], textExtent[1])
        dc =3D wx.MemoryDC()
        dc.SelectObject(bmp)
        dc.Clear()
        dc.SetTextForeground(wx.BLUE)
        dc.SetFont(font)
        dc.DrawText(group, 0, 0)
        dc.SelectObject(wx.NullBitmap)
        mask =3D wx.Mask(bmp, bg_colour)
        bmp.SetMask(mask)
        shape =3D DragShape(bmp)
        shape.pos =3D wx.Point((200*(level-1)), pos1)
        shape.text =3D group
        shape.parent =3D gp
        shape.ext =3D True
        shape.normal=3Dwx.BLUE
        shape.size =3D bmp.GetSize()
        pos1+=3Dbmp.GetSize().GetHeight()+30
        self.hs[level1] =3D pos1
        parent =3D shape
        x1,y1 =3D shape.parent.pos
        x2,y2 =3D shape.pos
        x1+=3Dshape.parent.size.GetWidth()
        y1+=3D(shape.parent.size.GetHeight()/2)
        x2+=3D2
        y2+=3D(shape.size.GetHeight()/2)
        angle =3D 0
        if x1 > x2 and y1 > y2:
            angle =3D 1
        if x1 > x2:
            if angle =3D=3D 0:
                angle =3D 2
            temp =3D x2
            x2 =3D x1
            x1 =3D temp
        if y1 > y2:
            if angle =3D=3D 0:
                angle =3D 2
            temp =3D y2
            y2 =3D y1
            y1 =3D temp
        if (x2-x1) < 2:
            x2+=3D2
        if (y2-y1) < 2:
            y2+=3D2
        bmp =3D wx.EmptyBitmap(abs(x2-x1), abs(y2-y1))
        dc =3D wx.MemoryDC()
        dc.Clear()
        dc.SelectObject(bmp)
        dc.SetBrush(self.wbrush)
        dc.SetPen(self.wpen)
        if angle =3D=3D 0 or angle =3D=3D 1:
            dc.DrawLine(0, 0, abs(x2-x1),abs(y2-y1))
        else:
            dc.DrawLine(abs(x2-x1), 0, 0,abs(y2-y1))
        dc.SelectObject(wx.NullBitmap)
        mask =3D wx.Mask(bmp, bg_colour)
        bmp.SetMask(mask)
        line =3D DragShape(bmp)
        line.pos =3D wx.Point(x1,y1)
        shape.line =3D line
        self.shapes.append(shape)
        self.Refresh()

        for node in nodez:
            try:
                for subgroup, subnodes in node.items():
                    self.doParentChild(subgroup,subnodes,level+1,gp)
            except AttributeError:
                textExtent =3D self.GetFullTextExtent(node, font)
                bmp =3D wx.EmptyBitmap(textExtent[0], textExtent[1])
                dc =3D wx.MemoryDC()
                dc.SelectObject(bmp)
                dc.Clear()
                dc.SetTextForeground(wx.BLACK)
                dc.SetFont(font)
                dc.DrawText(node, 0, 0)
                dc.SelectObject(wx.NullBitmap)
                mask =3D wx.Mask(bmp, bg_colour)
                bmp.SetMask(mask)
                shape =3D DragShape(bmp)
                shape.pos =3D wx.Point((200*level), pos2)
                shape.text =3D node
                shape.parent =3D parent
                shape.size =3D bmp.GetSize()
                pos2+=3Dbmp.GetSize().GetHeight()+30
                self.hs[level]=3Dpos2
                child =3D shape
                x1,y1 =3D parent.pos
                x2,y2 =3D child.pos
                x1+=3Dparent.size.GetWidth()
                y1+=3D(parent.size.GetHeight()/2)
                x2+=3D2
                y2+=3D(child.size.GetHeight()/2)
                angle =3D 0
                if x1 > x2 and y1 > y2:
                    angle =3D 1
                if x1 > x2:
                    if angle =3D=3D 0:
                        angle =3D 2
                    temp =3D x2
                    x2 =3D x1
                    x1 =3D temp
                if y1 > y2:
                    if angle =3D=3D 0:
                        angle =3D 2
                    temp =3D y2
                    y2 =3D y1
                    y1 =3D temp
                if (x2-x1) < 2:
                    x2+=3D2
                if (y2-y1) < 2:
                    y2+=3D2
                bmp =3D wx.EmptyBitmap(abs(x2-x1), abs(y2-y1))
                dc =3D wx.MemoryDC()
                dc.Clear()
                dc.SelectObject(bmp)
                dc.SetBrush(self.wbrush)
                dc.SetPen(self.wpen)
                if angle =3D=3D 0 or angle =3D=3D 1:
                    dc.DrawLine(0, 0, abs(x2-x1),abs(y2-y1))
                else:
                    dc.DrawLine(abs(x2-x1), 0, 0,abs(y2-y1))
                dc.SelectObject(wx.NullBitmap)
                mask =3D wx.Mask(bmp, bg_colour)
                bmp.SetMask(mask)
                line =3D DragShape(bmp)
                line.pos =3D wx.Point(x1,y1)
                shape.line =3D line
                self.shapes.append(shape)
                self.Refresh()


    def TileBackground(self, dc):
        # tile the background bitmap
        sz =3D self.GetClientSize()
        w =3D self.bg_bmp.GetWidth()
        h =3D self.bg_bmp.GetHeight()
        x =3D 0
        while x < sz.width:
            y =3D 0
            while y < sz.height:
                dc.DrawBitmap(self.bg_bmp, x, y)
                y =3D y + h
            x =3D x + w

    def DrawShapes(self, dc):
        for shape in self.shapes:
            if shape.shown:
                shape.Draw(dc)
            if shape.line:
                if shape.line.shown:
                    shape.line.Draw(dc)

    def GetChildShapes(self,parent):
        children=3D []
        for shape in self.shapes:
            if shape.parent =3D=3D parent:
                children.append(shape)
        return children

    def GetAllKids(self,parent):
        kids =3D []
        for shape in self.shapes:
            if shape.parent =3D=3D parent:
                kids.append(shape)
        for me_now in kids:
            for me_p in self.GetAllKids(me_now):
                kids.append(me_p)
        return kids

    def FindShape(self, pt):
        for shape in self.shapes:
            if shape.HitTest(pt):
                return shape
        return None


    def EraseShape(self, shape, dc):
        r =3D shape.GetRect()
        dc.SetClippingRegion(r.x, r.y, r.width, r.height)
        self.TileBackground(dc)
        self.DrawShapes(dc)
        dc.DestroyClippingRegion()

    def OnEraseBackground(self, evt):
        dc =3D evt.GetDC()
        if not dc:
            dc =3D wx.ClientDC(self)
            rect =3D self.GetUpdateRegion().GetBox()
            dc.SetClippingRegion(rect.x, rect.y, rect.width, rect.height)
        self.TileBackground(dc)


    def OnPaint(self, evt):
        dc =3D wx.PaintDC(self)
        self.PrepareDC(dc)
        self.DrawShapes(dc)

    def OnLeftDClick(self, evt):
        shape =3D self.FindShape(evt.GetPosition())
        dc =3D wx.ClientDC(self)
        if shape.ext =3D=3D False:
            shape.ext =3D True
            children =3D self.GetAllKids(shape)
            for child in children:
                self.shapes[self.shapes.index(child)].shown =3D True
                if self.shapes[self.shapes.index(child)].line:
                    self.shapes[self.shapes.index(child)].line.shown =3D Tr=
ue
            self.DrawShapes(dc)
            shape.Expand(dc)
        elif shape.ext =3D=3D True:
            shape.ext =3D False
            children =3D self.GetAllKids(shape)
            for child in children:
                self.shapes[self.shapes.index(child)].shown =3D False
                self.EraseShape(self.shapes[self.shapes.index(child)], dc)
                if self.shapes[self.shapes.index(child)].line:
                    self.shapes[self.shapes.index(child)].line.shown =3D Fa=
lse
                    self.EraseShape(self.shapes[self.shapes.index(child)].l=
ine,dc)
            shape.Colapse(dc)
        self.Refresh()


    def OnLeftDown(self, evt):
        shape =3D self.FindShape(evt.GetPosition())
        dc=3D wx.ClientDC(self)
        for shapep in self.shapes:
            shapep.SetUnSelected(dc)
        if shape:
            # get ready to start dragging, but wait for the user to
            # move it a bit first
            self.selected_shapes.append(shape)
            shape.SetSelected(dc)
            self.Refresh()
            self.dragShape =3D shape
            self.dragStartPos =3D evt.GetPosition()
        else:
            if self.select_mode =3D=3D 0 and self.select_start =3D=3D None:
                wbrush =3D wx.Brush(wx.RED, wx.TRANSPARENT)
                wpen =3D wx.Pen(wx.RED, 1, wx.SOLID)
                dc.SetBrush(wbrush)
                dc.SetPen(wpen)
                self.select_mode =3D 1
                self.select_start =3D evt.GetPosition()
                self.Refresh()
                self.m_savepoint=3Dself.select_start
                self._selected =3D False
                self._leftclicked =3D True
                self.selected_shapes =3D []




    def OnLeftUp(self, evt):
        if self.select_mode =3D=3D 1:
            dc=3D wx.ClientDC(self)
            dc.SetLogicalFunction(wx.XOR)
            wbrush =3D wx.Brush(wx.RED, wx.TRANSPARENT)
            wpen =3D wx.Pen(wx.RED, 1, wx.SOLID)
            dc.SetBrush(wbrush)
            dc.SetPen(wpen)

            dc.ResetBoundingBox()
            dc.BeginDrawing()
            w =3D (self.m_savepoint.x - self.select_start.x)
            h =3D (self.m_savepoint.y - self.select_start.y)

            dc.DrawRectangle(self.select_start.x, self.select_start.y, w, h)

            dc.EndDrawing()

            self._selected =3D True
            self._leftclicked =3D False
            for shape in self.shapes:
                x,y =3D shape.pos
                x1,y1 =3D self.select_start
                x2,y2 =3D self.m_savepoint
                if x >=3D x1 and x <=3D x2 and y >=3D y1 and y <=3D y2 and =
shape.shown:
                    self.selected_shapes.append(shape)
                    shape.SetSelected(dc)
                    self.Refresh()

            self.select_mode =3D 0
            self.select_start =3D None
            self.select_end =3D None

        else:
            if not self.dragImage or not self.dragShape:
                self.dragImage =3D None
                self.dragShape =3D None
                return

            # end the dragging
            self.dragImage.Hide()
            self.dragImage.EndDrag()
            self.dragImage =3D None

            dc =3D wx.ClientDC(self)
            if self.hiliteShape:
                self.hiliteShape.Draw(dc)
                self.hiliteShape =3D None

            # reposition and draw the shape
            self.dragShape.pos =3D self.dragShape.pos + evt.GetPosition() -=
 self.dragStartPos
            self.dragShape.shown =3D True
            self.dragShape.SetUnSelected(dc)
            self.dragShape.Draw(dc)
            if self.dragShape.parent =3D=3D "root":
                for parent,children in self.elements.items():
                    if parent =3D=3D self.dragShape.text:
                        childrenII =3D []
                        for child_name in children:
                            try:
                                for names in child_name.keys():
                                    childrenII.append(names)
                            except AttributeError:
                                childrenII.append(child_name)
                        for child_name in childrenII:
                            child =3D self.GetMeShape(child_name)
                            bg_colour =3D wx.Colour(0, 0, 0)
                            x1,y1 =3D self.dragShape.pos
                            x2,y2 =3D child.pos
                            x1+=3Dself.dragShape.size.GetWidth()
                            y1+=3D(self.dragShape.size.GetHeight()/2)
                            x2+=3D2
                            y2+=3D(child.size.GetHeight()/2)
                            angle =3D 0
                            if x1 > x2 and y1 > y2:
                                angle =3D 1
                            if x1 > x2:
                                if angle =3D=3D 0:
                                    angle =3D 2
                                temp =3D x2
                                x2 =3D x1
                                x1 =3D temp
                            if y1 > y2:
                                if angle =3D=3D 0:
                                    angle =3D 2
                                temp =3D y2
                                y2 =3D y1
                                y1 =3D temp
                            bmp =3D wx.EmptyBitmap(abs(x2-x1), abs(y2-y1))
                            dc =3D wx.MemoryDC()
                            dc.Clear()
                            dc.SelectObject(bmp)
                            dc.SetBrush(self.wbrush)
                            dc.SetPen(self.wpen)
                            if angle =3D=3D 0 or angle =3D=3D 1:
                                dc.DrawLine(0, 0, abs(x2-x1),abs(y2-y1))
                            else:
                                dc.DrawLine(abs(x2-x1), 0, 0,abs(y2-y1))
                            dc.SelectObject(wx.NullBitmap)
                            mask =3D wx.Mask(bmp, bg_colour)
                            bmp.SetMask(mask)
                            line =3D DragShape(bmp)
                            line.pos =3D wx.Point(x1,y1)
                            child.line =3D line
                            child.line.shown =3D True
                            child.line.Draw(dc)
                            self.Refresh()
            else:
                if self.dragShape.line:
                    bg_colour =3D wx.Colour(0, 0, 0)
                    x1,y1 =3D self.dragShape.parent.pos
                    x2,y2 =3D self.dragShape.pos
                    x1+=3Dself.dragShape.parent.size.GetWidth()
                    y1+=3D(self.dragShape.parent.size.GetHeight()/2)
                    x2+=3D2
                    y2+=3D(self.dragShape.size.GetHeight()/2)
                    angle =3D 0
                    if x1 > x2 and y1 > y2:
                        angle =3D 1
                    if x1 > x2:
                        if angle =3D=3D 0:
                            angle =3D 2
                        temp =3D x2
                        x2 =3D x1
                        x1 =3D temp
                    if y1 > y2:
                        if angle =3D=3D 0:
                            angle =3D 2
                        temp =3D y2
                        y2 =3D y1
                        y1 =3D temp
                    bmp =3D wx.EmptyBitmap(abs(x2-x1), abs(y2-y1))
                    dc =3D wx.MemoryDC()
                    dc.Clear()
                    dc.SelectObject(bmp)
                    dc.SetBrush(self.wbrush)
                    dc.SetPen(self.wpen)
                    if angle =3D=3D 0 or angle =3D=3D 1:
                        dc.DrawLine(0, 0, abs(x2-x1),abs(y2-y1))
                    else:
                        dc.DrawLine(abs(x2-x1), 0, 0,abs(y2-y1))
                    dc.SelectObject(wx.NullBitmap)
                    mask =3D wx.Mask(bmp, bg_colour)
                    bmp.SetMask(mask)
                    line =3D DragShape(bmp)
                    self.dragShape.line =3D line
                    self.dragShape.line.pos =3D wx.Point(x1,y1)
                    self.dragShape.line.shown =3D True
                    self.dragShape.line.Draw(dc)
                    self.Refresh()

            children=3Dself.GetChildShapes(self.dragShape)
            for child in children:
                bg_colour =3D wx.Colour(0, 0, 0)
                x1,y1 =3D self.dragShape.pos
                x2,y2 =3D child.pos
                x1+=3Dself.dragShape.size.GetWidth()
                y1+=3D(self.dragShape.size.GetHeight()/2)
                x2+=3D2
                y2+=3D(child.size.GetHeight()/2)
                angle =3D 0
                if x1 > x2 and y1 > y2:
                    angle =3D 1
                if x1 > x2:
                    if angle =3D=3D 0:
                        angle =3D 2
                    temp =3D x2
                    x2 =3D x1
                    x1 =3D temp
                if y1 > y2:
                    if angle =3D=3D 0:
                        angle =3D 2
                    temp =3D y2
                    y2 =3D y1
                    y1 =3D temp
                bmp =3D wx.EmptyBitmap(abs(x2-x1), abs(y2-y1))
                dc =3D wx.MemoryDC()
                dc.Clear()
                dc.SelectObject(bmp)
                dc.SetBrush(self.wbrush)
                dc.SetPen(self.wpen)
                if angle =3D=3D 0 or angle =3D=3D 1:
                    dc.DrawLine(0, 0, abs(x2-x1),abs(y2-y1))
                else:
                    dc.DrawLine(abs(x2-x1), 0, 0,abs(y2-y1))
                dc.SelectObject(wx.NullBitmap)
                mask =3D wx.Mask(bmp, bg_colour)
                bmp.SetMask(mask)
                line =3D DragShape(bmp)
                line.pos =3D wx.Point(x1,y1)
                child.line =3D line
                child.line.shown =3D True
                child.line.Draw(dc)
                self.Refresh()


            self.dragShape =3D None

    def GetMeShape(self,s_name):
        for shape in self.shapes:
            if shape.text =3D=3D s_name:
                return shape
        return None

    def OnMotion(self, evt):
        if self._leftclicked and self.select_mode =3D=3D 1 and self.select_=
start:
            dc=3D wx.ClientDC(self)
            dc.SetLogicalFunction(wx.XOR)
            wbrush =3D wx.Brush(wx.RED, wx.TRANSPARENT)
            wpen =3D wx.Pen(wx.RED, 1, wx.SOLID)
            dc.SetBrush(wbrush)
            dc.SetPen(wpen)

            # reset dc bounding box
            dc.ResetBoundingBox()
            dc.BeginDrawing()
            w =3D (self.m_savepoint.x - self.select_start.x)
            h =3D (self.m_savepoint.y - self.select_start.y)

            # To erase previous rectangle
            dc.DrawRectangle(self.select_start.x, self.select_start.y, w, h)

            # Draw new rectangle
            self.select_end =3D evt.GetPosition()

            w =3D (self.select_end.x - self.select_start.x)
            h =3D (self.select_end.y - self.select_start.y)

            # Set clipping region to rectangle corners
            dc.SetClippingRegion(self.select_start.x, self.select_start.y, =
w,h)
            dc.DrawRectangle(self.select_start.x, self.select_start.y, w, h)
            dc.EndDrawing()

            self.m_savepoint =3D self.select_end

        if not self.dragShape or not evt.Dragging() or not evt.LeftIsDown():
            return

        # if we have a shape, but haven't started dragging yet
        if self.dragShape and not self.dragImage:

            # only start the drag after having moved a couple pixels
            tolerance =3D 2
            pt =3D evt.GetPosition()
            dx =3D abs(pt.x - self.dragStartPos.x)
            dy =3D abs(pt.y - self.dragStartPos.y)
            if dx <=3D tolerance and dy <=3D tolerance:
                return

            # erase the shape since it will be drawn independently now
            dc =3D wx.ClientDC(self)

            self.dragShape.shown =3D False
            self.EraseShape(self.dragShape, dc)

            if self.dragShape.line:
                self.dragShape.line.shown =3D False
                self.EraseShape(self.dragShape.line,dc)

            children=3Dself.GetChildShapes(self.dragShape)
            for child in children:
                child.line.shown =3D False
                self.EraseShape(child.line,dc)

            self.dragImage =3D wx.DragImage(self.dragShape.bmp,
                                         wxStockCursor(wx.CURSOR_HAND))

            hotspot =3D self.dragStartPos - self.dragShape.pos
            self.dragImage.BeginDrag(hotspot, self, self.dragShape.fullscre=
en)

            self.dragImage.Move(pt)
            self.dragImage.Show()

        # if we have shape and image then move it
        elif self.dragShape and self.dragImage:
            # now move it and show it again if needed
            self.dragImage.Move(evt.GetPosition())


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

def runTest(frame, nb, log):
    win =3D wx.Panel(nb, -1)
    canvas =3D DragCanvas(win, -1)
    def onSize(evt, panel=3Dwin, canvas=3Dcanvas): canvas.SetSize(panel.Get=
Size())
    win.Bind(wx.EVT_SIZE, onSize)
    return win

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



overview =3D """\
"""


if __name__ =3D=3D '__main__':
    import sys,os
    import run
    run.main(['', os.path.basename(sys.argv[0])])


More information about the wxpython-users mailing list