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/Perf_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?
Thanks for all the help
Cheers
Astan

from wxPython.wx import *
#----------------------------------------------------------------------

class DragShape:
    def __init__(self, bmp):
        self.bmp = bmp
        self.pos = wxPoint(0,0)
        self.shown = True
        self.text = None
        self.fullscreen = False
        self.size = wxSize(0,0)
        self.line = None
        self.parent = None
        self.ext = None
        self.normal = wxBLACK

    def HitTest(self, pt):
        rect = 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 = wxCOPY):
        if self.bmp.Ok():
            memDC = wxMemoryDC()
            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 = wxCOPY):
        if self.bmp.Ok():
            bg_colour = wxColour(0, 0, 0)
            font = wxFont(15, wxROMAN, wxNORMAL, wxBOLD)
            self.bmp = wxEmptyBitmap(self.size.GetWidth(), 
self.size.GetHeight())
            memDC = wxMemoryDC()
            memDC.SelectObject(self.bmp)
            memDC.Clear()
            memDC.SetTextForeground(wxRED)
            memDC.SetFont(font)
            memDC.DrawText(self.text, 0, 0)
            memDC.SelectObject(wxNullBitmap)
            mask = wxMask(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 = wxCOPY):
        if self.bmp.Ok():
            bg_colour = wxColour(0, 0, 0)
            font = wxFont(15, wxROMAN, wxNORMAL, wxBOLD)
            self.bmp = wxEmptyBitmap(self.size.GetWidth(), 
self.size.GetHeight())
            memDC = wxMemoryDC()
            memDC.SelectObject(self.bmp)
            memDC.Clear()
            memDC.SetTextForeground(self.normal)
            memDC.SetFont(font)
            memDC.DrawText(self.text, 0, 0)
            memDC.SelectObject(wxNullBitmap)
            mask = wxMask(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 = wxCOPY):
        if self.bmp.Ok():
            bg_colour = wxColour(0, 0, 0)
            font = wxFont(15, wxROMAN, wxNORMAL, wxBOLD)
            self.bmp = wxEmptyBitmap(self.size.GetWidth(), 
self.size.GetHeight())
            memDC = wxMemoryDC()
            memDC.SelectObject(self.bmp)
            memDC.Clear()
            memDC.SetTextForeground(wxBLUE)
            memDC.SetFont(font)
            memDC.DrawText(self.text, 0, 0)
            memDC.SelectObject(wxNullBitmap)
            mask = wxMask(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 = wxCOPY):
        if self.bmp.Ok():
            bg_colour = wxColour(0, 0, 0)
            font = wxFont(15, wxROMAN, wxNORMAL, wxBOLD)
            self.bmp = wxEmptyBitmap(self.size.GetWidth(), 
self.size.GetHeight())
            memDC = wxMemoryDC()
            memDC.SelectObject(self.bmp)
            memDC.Clear()
            memDC.SetTextForeground(wxGREEN)
            memDC.SetFont(font)
            memDC.DrawText(self.text, 0, 0)
            memDC.SelectObject(wxNullBitmap)
            mask = wxMask(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(wxScrolledWindow):
    def __init__(self, parent, ID):
        wxScrolledWindow.__init__(self, parent, ID)
        self.shapes = []
        self.dragImage = None
        self.dragShape = None
        self.hiliteShape = None
        self.select_mode = 0
        self.select_start = None
        self.select_end = None
        self.m_savepoint=None
        self._leftclicked=false
        self._selected=false
        self.s_savepoint=None
        self.selected_shapes = []

        self.SetCursor(wxStockCursor(wxCURSOR_ARROW))
        w,h = self.GetClientSize()
        
        self.bg_bmp = wxEmptyBitmap(w,h) 
        
        self.elements = {"CEO":[{"VP 1":["Assistent VP 1","Assistent VP 
2"]},"VP 2"],"father":["son","daughter"]}
        #self.elements = 
{"grandmother":["son","mother"],"President":["VP1","VP2"]}
        # Make a shape from dict
        self.hs = [0,0]
        bg_colour = wxColour(0, 0, 0)
        font = wxFont(15, wxROMAN, wxNORMAL, wxBOLD)
        self.wbrush = wxBrush(wxRED, wxTRANSPARENT)
        self.wpen = wxPen(wxRED, 1, wxSOLID)
        for group,nodez in self.elements.items():            
            textExtent = self.GetFullTextExtent(group, font)
            bmp = wxEmptyBitmap(textExtent[0], textExtent[1])
            dc = wxMemoryDC()
            dc.SelectObject(bmp)
            dc.Clear()
            dc.SetTextForeground(wxBLUE)
            dc.SetFont(font)
            dc.DrawText(group, 0, 0)
            dc.SelectObject(wxNullBitmap)
            mask = wxMask(bmp, bg_colour)
            bmp.SetMask(mask)
            shape = DragShape(bmp)
            shape.pos = wxPoint(0, self.hs[0])
            shape.text = group
            shape.parent = "root"
            shape.normal=wxBLUE
            shape.ext = True
            shape.size = bmp.GetSize()
            self.shapes.append(shape)
            self.hs[0]+=bmp.GetSize().GetHeight()+30
            parent = shape
            for node in nodez:
                try:
                    for subgroup, subnodes in node.items():
                        self.doParentChild(subgroup,subnodes,2,parent)
                except AttributeError:
                    textExtent = self.GetFullTextExtent(node, font)             
       
                    bmp = wxEmptyBitmap(textExtent[0], textExtent[1])
                    dc = wxMemoryDC()
                    dc.SelectObject(bmp)
                    dc.Clear()
                    dc.SetTextForeground(wxBLACK)
                    dc.SetFont(font)
                    dc.DrawText(node, 0, 0)
                    dc.SelectObject(wxNullBitmap)
                    mask = wxMask(bmp, bg_colour)
                    bmp.SetMask(mask)
                    shape = DragShape(bmp)
                    shape.pos = wxPoint(220, self.hs[1])
                    shape.text = node
                    shape.parent = parent
                    shape.size = bmp.GetSize()                
                    self.hs[1]+=bmp.GetSize().GetHeight()+30
                    child = shape                
                    x1,y1 = parent.pos
                    x2,y2 = child.pos
                    x1+=parent.size.GetWidth()
                    y1+=(parent.size.GetHeight()/2)
                    x2+=2
                    y2+=(child.size.GetHeight()/2)
                    angle = 0
                    if x1 > x2 and y1 > y2:
                        angle = 1
                    if x1 > x2:
                        if angle == 0:
                            angle = 2
                        temp = x2
                        x2 = x1
                        x1 = temp
                    if y1 > y2:
                        if angle == 0:
                            angle = 2
                        temp = y2
                        y2 = y1
                        y1 = temp
                    if (x2-x1) < 2:
                        x2+=2
                    if (y2-y1) < 2:
                        y2+=2
                    bmp = wxEmptyBitmap(abs(x2-x1), abs(y2-y1))
                    dc = wxMemoryDC()
                    dc.Clear()
                    dc.SelectObject(bmp)
                    dc.SetBrush(self.wbrush)
                    dc.SetPen(self.wpen)
                    if angle == 0 or angle == 1:
                        dc.DrawLine(0, 0, abs(x2-x1),abs(y2-y1))
                    else:                    
                        dc.DrawLine(abs(x2-x1), 0, 0,abs(y2-y1))
                    dc.SelectObject(wxNullBitmap)                    
                    mask = wxMask(bmp, bg_colour)
                    bmp.SetMask(mask)
                    line = DragShape(bmp)
                    line.pos = wxPoint(x1,y1)
                    shape.line = line                
                    self.shapes.append(shape)
        maxX = 0
        maxY = 0
        for s in self.hs:
            if maxX < s:
                maxX = s
        if maxX < 700:
            maxX = 700
        maxY = len(self.hs)+1
        maxY=maxY*200
        if maxY<460:
            maxY=460
        self.SetScrollbars(20, 20, maxX/20, maxY/20)                
        EVT_ERASE_BACKGROUND(self, self.OnEraseBackground)
        EVT_PAINT(self, self.OnPaint)
        EVT_LEFT_DOWN(self, self.OnLeftDown)
        EVT_LEFT_UP(self, self.OnLeftUp)
        EVT_MOTION(self, self.OnMotion)        
        EVT_LEAVE_WINDOW(self, self.OnLeaveWindow)
        EVT_LEFT_DCLICK(self,self.OnLeftDClick)


    def OnLeaveWindow(self, evt):
        pass

    def doParentChild(self,group,nodez,level,gp):
        bg_colour = wxColour(0, 0, 0)
        font = wxFont(15, wxROMAN, wxNORMAL, wxBOLD)
        while len(self.hs)<=level:
            self.hs.append(0)       
        level1 = level-1
        pos1 = self.hs[level1]
        pos2 = self.hs[level]
        textExtent = self.GetFullTextExtent(group, font)
        bmp = wxEmptyBitmap(textExtent[0], textExtent[1])
        dc = wxMemoryDC()
        dc.SelectObject(bmp)
        dc.Clear()
        dc.SetTextForeground(wxBLUE)
        dc.SetFont(font)
        dc.DrawText(group, 0, 0)
        dc.SelectObject(wxNullBitmap)
        mask = wxMask(bmp, bg_colour)
        bmp.SetMask(mask)
        shape = DragShape(bmp)
        shape.pos = wxPoint((200*(level-1)), pos1)
        shape.text = group
        shape.parent = gp
        shape.ext = True
        shape.normal=wxBLUE
        shape.size = bmp.GetSize()        
        pos1+=bmp.GetSize().GetHeight()+30
        self.hs[level1] = pos1
        parent = shape
        x1,y1 = shape.parent.pos
        x2,y2 = shape.pos
        x1+=shape.parent.size.GetWidth()
        y1+=(shape.parent.size.GetHeight()/2)
        x2+=2
        y2+=(shape.size.GetHeight()/2)
        angle = 0
        if x1 > x2 and y1 > y2:
            angle = 1
        if x1 > x2:
            if angle == 0:
                angle = 2
            temp = x2
            x2 = x1
            x1 = temp
        if y1 > y2:
            if angle == 0:
                angle = 2
            temp = y2
            y2 = y1
            y1 = temp
        if (x2-x1) < 2:
            x2+=2
        if (y2-y1) < 2:
            y2+=2            
        bmp = wxEmptyBitmap(abs(x2-x1), abs(y2-y1))
        dc = wxMemoryDC()
        dc.Clear()
        dc.SelectObject(bmp)
        dc.SetBrush(self.wbrush)
        dc.SetPen(self.wpen)
        if angle == 0 or angle == 1:
            dc.DrawLine(0, 0, abs(x2-x1),abs(y2-y1))
        else:                    
            dc.DrawLine(abs(x2-x1), 0, 0,abs(y2-y1))
        dc.SelectObject(wxNullBitmap)                    
        mask = wxMask(bmp, bg_colour)
        bmp.SetMask(mask)
        line = DragShape(bmp)
        line.pos = wxPoint(x1,y1)
        shape.line = 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 = self.GetFullTextExtent(node, font)
                bmp = wxEmptyBitmap(textExtent[0], textExtent[1])
                dc = wxMemoryDC()
                dc.SelectObject(bmp)
                dc.Clear()
                dc.SetTextForeground(wxBLACK)
                dc.SetFont(font)
                dc.DrawText(node, 0, 0)
                dc.SelectObject(wxNullBitmap)
                mask = wxMask(bmp, bg_colour)
                bmp.SetMask(mask)
                shape = DragShape(bmp)
                shape.pos = wxPoint((200*level), pos2)
                shape.text = node
                shape.parent = parent
                shape.size = bmp.GetSize()                
                pos2+=bmp.GetSize().GetHeight()+30
                self.hs[level]=pos2
                child = shape                
                x1,y1 = parent.pos
                x2,y2 = child.pos
                x1+=parent.size.GetWidth()
                y1+=(parent.size.GetHeight()/2)
                x2+=2
                y2+=(child.size.GetHeight()/2)
                angle = 0
                if x1 > x2 and y1 > y2:
                    angle = 1
                if x1 > x2:
                    if angle == 0:
                        angle = 2
                    temp = x2
                    x2 = x1
                    x1 = temp
                if y1 > y2:
                    if angle == 0:
                        angle = 2
                    temp = y2
                    y2 = y1
                    y1 = temp
                if (x2-x1) < 2:
                    x2+=2
                if (y2-y1) < 2:
                    y2+=2                    
                bmp = wxEmptyBitmap(abs(x2-x1), abs(y2-y1))
                dc = wxMemoryDC()
                dc.Clear()
                dc.SelectObject(bmp)
                dc.SetBrush(self.wbrush)
                dc.SetPen(self.wpen)
                if angle == 0 or angle == 1:
                    dc.DrawLine(0, 0, abs(x2-x1),abs(y2-y1))
                else:                    
                    dc.DrawLine(abs(x2-x1), 0, 0,abs(y2-y1))
                dc.SelectObject(wxNullBitmap)                    
                mask = wxMask(bmp, bg_colour)
                bmp.SetMask(mask)
                line = DragShape(bmp)
                line.pos = wxPoint(x1,y1)
                shape.line = line                
                self.shapes.append(shape)
                self.Refresh()
        

    def TileBackground(self, dc):
        # tile the background bitmap
        sz = self.GetClientSize()
        w = self.bg_bmp.GetWidth()
        h = self.bg_bmp.GetHeight()
        x = 0
        while x < sz.width:
            y = 0
            while y < sz.height:
                dc.DrawBitmap(self.bg_bmp, x, y)
                y = y + h
            x = 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= []
        for shape in self.shapes:
            if shape.parent == parent:
                children.append(shape)
        return children                

    def GetAllKids(self,parent):
        kids = []
        for shape in self.shapes:
            if shape.parent == 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 = 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 = evt.GetDC()
        if not dc:
            dc = wxClientDC(self)
            rect = self.GetUpdateRegion().GetBox()
            dc.SetClippingRegion(rect.x, rect.y, rect.width, rect.height)
        self.TileBackground(dc)


    def OnPaint(self, evt):
        dc = wxPaintDC(self)
        self.PrepareDC(dc)
        self.DrawShapes(dc)

    def OnLeftDClick(self, evt):
        shape = self.FindShape(evt.GetPosition())
        dc = wxClientDC(self)
        if shape.ext == False:        
            shape.ext = True
            children = self.GetAllKids(shape)
            for child in children:
                self.shapes[self.shapes.index(child)].shown = True
                if self.shapes[self.shapes.index(child)].line:
                    self.shapes[self.shapes.index(child)].line.shown = True
            self.DrawShapes(dc)    
            shape.Expand(dc)            
        elif shape.ext == True:            
            shape.ext = False
            children = self.GetAllKids(shape)
            for child in children:
                self.shapes[self.shapes.index(child)].shown = 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 = False
                    
self.EraseShape(self.shapes[self.shapes.index(child)].line,dc)                
            shape.Colapse(dc)
        self.Refresh()
            
        
    def OnLeftDown(self, evt):
        shape = self.FindShape(evt.GetPosition())
        dc= wxClientDC(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 = shape
            self.dragStartPos = evt.GetPosition()            
        else:
            if self.select_mode == 0 and self.select_start == None:   
                wbrush = wxBrush(wxRED, wxTRANSPARENT)
                wpen = wxPen(wxRED, 1, wxSOLID)
                dc.SetBrush(wbrush)
                dc.SetPen(wpen)
                self.select_mode = 1
                self.select_start = evt.GetPosition()
                self.Refresh()
                self.m_savepoint=self.select_start
                self._selected = false
                self._leftclicked = true
                self.selected_shapes = []
                
                    


    def OnLeftUp(self, evt):
        if self.select_mode == 1:
            dc= wxClientDC(self)
            dc.SetLogicalFunction(wxXOR)
            wbrush = wxBrush(wxRED, wxTRANSPARENT)
            wpen = wxPen(wxRED, 1, wxSOLID)
            dc.SetBrush(wbrush)
            dc.SetPen(wpen)

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

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

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

            self.select_mode = 0
            self.select_start = None
            self.select_end = None
            
        else:            
            if not self.dragImage or not self.dragShape:
                self.dragImage = None
                self.dragShape = None
                return

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

            dc = wxClientDC(self)
            if self.hiliteShape:
                self.hiliteShape.Draw(dc)
                self.hiliteShape = None

            # reposition and draw the shape
            self.dragShape.pos = self.dragShape.pos + evt.GetPosition() - 
self.dragStartPos
            self.dragShape.shown = True
            self.dragShape.SetUnSelected(dc)
            self.dragShape.Draw(dc)  
            if self.dragShape.parent == "root":
                for parent,children in self.elements.items():
                    if parent == self.dragShape.text:
                        childrenII = []
                        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 = self.GetMeShape(child_name)
                            bg_colour = wxColour(0, 0, 0)
                            x1,y1 = self.dragShape.pos
                            x2,y2 = child.pos
                            x1+=self.dragShape.size.GetWidth()
                            y1+=(self.dragShape.size.GetHeight()/2)
                            x2+=2
                            y2+=(child.size.GetHeight()/2)
                            angle = 0
                            if x1 > x2 and y1 > y2:
                                angle = 1
                            if x1 > x2:
                                if angle == 0:
                                    angle = 2
                                temp = x2
                                x2 = x1
                                x1 = temp
                            if y1 > y2:
                                if angle == 0:
                                    angle = 2
                                temp = y2
                                y2 = y1
                                y1 = temp                             
                            bmp = wxEmptyBitmap(abs(x2-x1), abs(y2-y1))
                            dc = wxMemoryDC()
                            dc.Clear()            
                            dc.SelectObject(bmp)                        
                            dc.SetBrush(self.wbrush)
                            dc.SetPen(self.wpen)
                            if angle == 0 or angle == 1:
                                dc.DrawLine(0, 0, abs(x2-x1),abs(y2-y1))
                            else:                    
                                dc.DrawLine(abs(x2-x1), 0, 0,abs(y2-y1))
                            dc.SelectObject(wxNullBitmap)                    
                            mask = wxMask(bmp, bg_colour)
                            bmp.SetMask(mask)
                            line = DragShape(bmp)
                            line.pos = wxPoint(x1,y1)
                            child.line = line    
                            child.line.shown = True
                            child.line.Draw(dc)
                            self.Refresh()
            else:
                if self.dragShape.line:                
                    bg_colour = wxColour(0, 0, 0)
                    x1,y1 = self.dragShape.parent.pos
                    x2,y2 = self.dragShape.pos                
                    x1+=self.dragShape.parent.size.GetWidth()
                    y1+=(self.dragShape.parent.size.GetHeight()/2)
                    x2+=2
                    y2+=(self.dragShape.size.GetHeight()/2)
                    angle = 0
                    if x1 > x2 and y1 > y2:
                        angle = 1
                    if x1 > x2:
                        if angle == 0:
                            angle = 2
                        temp = x2
                        x2 = x1
                        x1 = temp
                    if y1 > y2:
                        if angle == 0:
                            angle = 2
                        temp = y2
                        y2 = y1
                        y1 = temp                    
                    bmp = wxEmptyBitmap(abs(x2-x1), abs(y2-y1))
                    dc = wxMemoryDC()
                    dc.Clear()            
                    dc.SelectObject(bmp)
                    dc.SetBrush(self.wbrush)
                    dc.SetPen(self.wpen)
                    if angle == 0 or angle == 1:
                        dc.DrawLine(0, 0, abs(x2-x1),abs(y2-y1))
                    else:                    
                        dc.DrawLine(abs(x2-x1), 0, 0,abs(y2-y1))                
    
                    dc.SelectObject(wxNullBitmap)                    
                    mask = wxMask(bmp, bg_colour)
                    bmp.SetMask(mask)
                    line = DragShape(bmp)
                    self.dragShape.line = line
                    self.dragShape.line.pos = wxPoint(x1,y1)
                    self.dragShape.line.shown = True
                    self.dragShape.line.Draw(dc)
                    self.Refresh()
                    
            children=self.GetChildShapes(self.dragShape)
            for child in children:
                bg_colour = wxColour(0, 0, 0)
                x1,y1 = self.dragShape.pos
                x2,y2 = child.pos
                x1+=self.dragShape.size.GetWidth()
                y1+=(self.dragShape.size.GetHeight()/2)
                x2+=2
                y2+=(child.size.GetHeight()/2)
                angle = 0
                if x1 > x2 and y1 > y2:
                    angle = 1
                if x1 > x2:
                    if angle == 0:
                        angle = 2
                    temp = x2
                    x2 = x1
                    x1 = temp
                if y1 > y2:
                    if angle == 0:
                        angle = 2
                    temp = y2
                    y2 = y1
                    y1 = temp                             
                bmp = wxEmptyBitmap(abs(x2-x1), abs(y2-y1))
                dc = wxMemoryDC()
                dc.Clear()            
                dc.SelectObject(bmp)                        
                dc.SetBrush(self.wbrush)
                dc.SetPen(self.wpen)
                if angle == 0 or angle == 1:
                    dc.DrawLine(0, 0, abs(x2-x1),abs(y2-y1))
                else:                    
                    dc.DrawLine(abs(x2-x1), 0, 0,abs(y2-y1))
                dc.SelectObject(wxNullBitmap)                    
                mask = wxMask(bmp, bg_colour)
                bmp.SetMask(mask)
                line = DragShape(bmp)
                line.pos = wxPoint(x1,y1)
                child.line = line    
                child.line.shown = True
                child.line.Draw(dc)
                self.Refresh()
                
                
            self.dragShape = None

    def GetMeShape(self,s_name):
        for shape in self.shapes:
            if shape.text == s_name:
                return shape
        return None
            
    def OnMotion(self, evt):
        if self._leftclicked and self.select_mode == 1 and self.select_start:
            dc= wxClientDC(self)
            dc.SetLogicalFunction(wxXOR)
            wbrush = wxBrush(wxRED, wxTRANSPARENT)
            wpen = wxPen(wxRED, 1, wxSOLID)
            dc.SetBrush(wbrush)
            dc.SetPen(wpen)
            
            # reset dc bounding box
            dc.ResetBoundingBox()
            dc.BeginDrawing()
            w = (self.m_savepoint.x - self.select_start.x)
            h = (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 = evt.GetPosition()

            w = (self.select_end.x - self.select_start.x)
            h = (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 = 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 = 2
            pt = evt.GetPosition()
            dx = abs(pt.x - self.dragStartPos.x)
            dy = abs(pt.y - self.dragStartPos.y)
            if dx <= tolerance and dy <= tolerance:
                return

            # erase the shape since it will be drawn independently now
            dc = wxClientDC(self)
            
            self.dragShape.shown = False    
            self.EraseShape(self.dragShape, dc)

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

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

            self.dragImage = wxDragImage(self.dragShape.bmp,
                                         wxStockCursor(wxCURSOR_HAND))

            hotspot = self.dragStartPos - self.dragShape.pos
            self.dragImage.BeginDrag(hotspot, self, self.dragShape.fullscreen)

            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 = wxPanel(nb, -1)
    canvas = DragCanvas(win, -1)
    def onSize(evt, panel=win, canvas=canvas): canvas.SetSize(panel.GetSize())
    EVT_SIZE(win, onSize)
    return win

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



overview = """\
"""


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

#!/usr/bin/env python
#----------------------------------------------------------------------------
# Name:         run.py
# Purpose:      Simple framework for running individual demos
#
# Author:       Robin Dunn
#
# Created:      6-March-2000
# RCS-ID:       $Id: run.py,v 1.10.2.8 2003/07/31 17:13:42 RD Exp $
# Copyright:    (c) 2000 by Total Control Software
# Licence:      wxWindows license
#----------------------------------------------------------------------------

"""
This program will load and run one of the individual demos in this
directory within its own frame window.  Just specify the module name
on the command line.
"""

import wx                  # This module uses the new wx namespace
print "wx.VERSION_STRING = ", wx.VERSION_STRING

import sys, os

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

class Log:
    def WriteText(self, text):
        if text[-1:] == '\n':
            text = text[:-1]
        wx.LogMessage(text)
    write = WriteText


class RunDemoApp(wx.App):
    def __init__(self, name, module):
        self.name = name
        self.demoModule = module
        wx.App.__init__(self, 0)


    def OnInit(self):
        wx.InitAllImageHandlers()
        wx.Log_SetActiveTarget(wx.LogStderr())

        #self.SetAssertMode(wx.PYAPP_ASSERT_DIALOG)

        frame = wx.Frame(None, -1, "RunDemo: " + self.name, pos=(50,50), 
size=(0,0),
                        
style=wx.NO_FULL_REPAINT_ON_RESIZE|wx.DEFAULT_FRAME_STYLE)
        frame.CreateStatusBar()
        menuBar = wx.MenuBar()
        menu = wx.Menu()
        menu.Append(101, "E&xit\tAlt-X", "Exit demo")
        wx.EVT_MENU(self, 101, self.OnButton)
        menuBar.Append(menu, "&File")
        frame.SetMenuBar(menuBar)
        frame.Show(True)
        wx.EVT_CLOSE(frame, self.OnCloseFrame)

        win = self.demoModule.runTest(frame, frame, Log())

        # a window will be returned if the demo does not create
        # its own top-level window
        if win:
            # so set the frame to a good size for showing stuff
            frame.SetSize((640, 480))
            win.SetFocus()
            self.window = win

        else:
            # otherwise the demo made its own frame, so just put a
            # button in this one
            if hasattr(frame, 'otherWin'):
                b = wx.Button(frame, -1, " Exit ")
                frame.SetSize((200, 100))
                wx.EVT_BUTTON(frame, b.GetId(), self.OnButton)
            else:
                # It was probably a dialog or something that is already
                # gone, so we're done.
                frame.Destroy()
                return True

        self.SetTopWindow(frame)
        self.frame = frame
        #wx.Log_SetActiveTarget(wx.LogStderr())
        #wx.Log_SetTraceMask(wx.TraceMessages)
        return True


    def OnButton(self, evt):
        self.frame.Close(True)


    def OnCloseFrame(self, evt):
        if hasattr(self, "window") and hasattr(self.window, "ShutdownDemo"):
            self.window.ShutdownDemo()
        evt.Skip()


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


def main(argv):
    if len(argv) < 2:
        print "Please specify a demo module name on the command-line"
        raise SystemExit

    name = argv[1]
    if name[-3:] == '.py':
        name = name[:-3]
    module = __import__(name)


    app = RunDemoApp(name, module)
    app.MainLoop()



if __name__ == "__main__":
    main(sys.argv)


_______________________________________________
FloatCanvas mailing list
[email protected]
http://mail.mithis.com/cgi-bin/mailman/listinfo/floatcanvas

Reply via email to