Source

boa-constructor / SelectionTags.py

#----------------------------------------------------------------------
# Name:        SelectionTags.py
# Purpose:     
#
# Author:      Riaan Booysen
#
# Created:     1999
# RCS-ID:      $Id$
# Copyright:   (c) 1999, 2000 Riaan Booysen
# Licence:     GPL
#----------------------------------------------------------------------

from wxPython.wx import *
import string
import sender

defPos = (0, 0)
defSze = (0, 0)
tagSize = 7
frmWid = 2
screenGran = 4

def granularise(val):
    return ((val + screenGran / 2) /screenGran)*screenGran


# XXX Add 4 more sizers n, s, e, w
# XXX This module needs a bit of rework and some doc strings, interfaces are
# XXX too vauge.
class SelectionGroup:
    def newBlock(self):
        block = wxPanel(self.parent, -1)
	block.SetSize(wxSize(1, 1))
        block.SetBackgroundColour(wxBLACK)
        self.senders.addObject(block)
	EVT_MOTION(block, self.OnMouseOver)
	return block
        
    def __init__(self, parent, senders, inspector, designer):
#        print 'init selection!'
        self.designer = designer
        self.inspSel = None
        self.inspector = inspector
        self.parent = parent
        self.senders = senders
        self.selection = None
        self.dragTag = None
        self.dragCtrl = None
        self.dragOffset = wxPoint()
        self.dragSize = wxSize()
        self.lastDragPos = wxPoint()
        
        self.position = wxPoint(defPos[0], defPos[1])
        self.size = wxSize(defSze[0], defSze[1])

	self.sfT = self.newBlock()
	self.sfR = self.newBlock()
	self.sfB = self.newBlock()
	self.sfL = self.newBlock()
        
        # Create selection tags
        self.stTL = TLSelTag(parent, wxPoint(defPos[0], defPos[1]), wxCURSOR_SIZENWSE, 
          (-1, -1), tagSize, self.OnSizeBegin, self.OnSizeEnd, self.OnMouseOver, self)
        self.senders.addObject(self.stTL)

        self.stTR = TRSelTag(parent, wxPoint(defPos[0] + defSze[0], defPos[1]), wxCURSOR_SIZENESW, 
          (1, -1), tagSize, self.OnSizeBegin, self.OnSizeEnd, self.OnMouseOver, self)
        self.senders.addObject(self.stTR)

        self.stBR = BRSelTag(parent, wxPoint(defPos[0] + defSze[0], defPos[1] + defSze[1]), wxCURSOR_SIZENWSE, 
          (1, 1), tagSize, self.OnSizeBegin, self.OnSizeEnd, self.OnMouseOver, self)
        self.senders.addObject(self.stBR)

        self.stBL = BLSelTag(parent, wxPoint(defPos[0], defPos[1] + defSze[1]), wxCURSOR_SIZENESW, 
          (-1, 1), tagSize, self.OnSizeBegin, self.OnSizeEnd, self.OnMouseOver, self)
        self.senders.addObject(self.stBL)
        
        self.tags = [self.sfT, self.sfR, self.sfB, self.sfL, 
        	     self.stTL, self.stTR, self.stBR, self.stBL]
    def __del__(self):
#        print '!!!!!!!!!!!!!!!!!!!!!!!!!deleting selection group!!!!!!!!!!!!!!!!!!!!!'
        map(lambda tag: tag.Destroy(), self.tags)

    def showTags(self):
	self.stTL.Show(true)
	self.stTR.Show(true)
	self.stBR.Show(true)
	self.stBL.Show(true)
	self.sfL.Show(false)
	self.sfR.Show(false)
	self.sfB.Show(false)
	self.sfT.Show(false)

    def hideTags(self):
        map(lambda tag: tag.Show(false), self.tags)

    def showFramedTags(self, notHide):
        map(lambda tag: tag.Show(true), self.tags)
    
    def reparentTags(self, parent):
        map(lambda tag, newparent = parent: tag.Reparent(newparent), self.tags)

    def moveRelease(self):
#        print 'move release'
        if self.dragTag:
            # XXX nasty passing a None event
            self.OnSizeEnd(None)
	    self.showTags()
        if self.dragCtrl:
            # XXX Have to hide and show to clean up artifacts, refreshing
            # XXX is not sufficient. Show/hiding seems to screw up Z order
	    self.dragCtrl.Show(false)
#	    print 'move release, calling resize'
	    self.resizeCtrl()
#	    self.dragCtrl.SetDimensions(self.position.x, self.position.y, self.size.x, self.size.y)
	    self.dragCtrl.Show(true)
#            self.dragCtrl.Refresh()
	    self.dragCtrl = None
	    self.showTags()
            self.inspector.constructorUpdate('Position')

    def moveCapture(self, ctrl, compn, pos):
#        print 'move capture'
        # Put selection around control

        self.lastDragPos.x = pos.x
        self.lastDragPos.y = pos.y

        # Begin a drag
        # XXX hardcoded to frame
        if ctrl != self.designer:
            self.dragCtrl = ctrl
	    self.dragOffset = pos
	    self.showFramedTags(None)
	    self.dragSize = ctrl.GetSize()
	
    def moving(self, ctrl, pos):
#        print 'moving,', ctrl.GetName()
        # Sizing
        if self.dragTag:
            # XXX PARENTS
    	
     	    screenPos = ctrl.ClientToScreen(pos)
     	    parentPos = self.parent.ScreenToClient(screenPos)
    	    self.dragTag.setPos(parentPos)
    	# Moving
    	elif self.dragCtrl:
            self.lastDragPos.x = pos.x
            self.lastDragPos.y = pos.y
     	    screenPos = ctrl.ClientToScreen(pos)
     	    parentPos = self.parent.ScreenToClient(screenPos)

     	    print 'dragOffset:', self.dragOffset.x, self.dragOffset.y

            # Calculate an offset that is the difference between the 
            # client size and the control size. Comes into play because
            # dragging is relative to the dragging start point (dragOffset)
            # This should work with symmetric differences
            cs = self.dragCtrl.GetSize()
            ccs = self.dragCtrl.GetClientSize()
            cp = self.dragCtrl.GetPosition()
            
            offsetX = (cs.x - ccs.x) /2
            offsetY = (cs.y - ccs.y) /2
	    
            self.position = wxPoint(parentPos.x - self.dragOffset.x - offsetX, 
    	                            parentPos.y - self.dragOffset.y - offsetY)

	    self.setSelection()
  
    def selectCtrl(self, ctrl, compn):
        print 'select ctrl'
        
        self.hideTags()
        if not ctrl:
            self.selection = None
            self.inspSel = None
        else: 
            # XXX fix!
            if ctrl == self.designer:
                self.parent = ctrl
                cp = wxPoint(0, 0)
            else:
                self.parent = ctrl.GetParent()
                cp = ctrl.GetPosition()

                self.showTags()

            self.reparentTags(self.parent)

            self.position = wxPoint(cp.x, cp.y)
            self.size = ctrl.GetSize()
          
            self.selection = ctrl
            self.lastDragPos = wxPoint(self.position.x, self.position.y)

            self.setSelection()

#            if self.inspSel <> ctrl: #        or compn.designer != self.designer:

            self.inspSel = ctrl	
            print '$$$selection tags select control'
            print 'SelectionTags: selectObj'
            self.inspector.selectObject(ctrl, compn)

    def selectNone(self):
        self.hideTags()
        self.inspSel = None
        self.selection = None


    def resizeCtrl(self):
        """ Set the selected control's dimensions by granulising
            the current selection group's size & pos """
#        print 'resize ctrl'
#        self.selection.Show(false)
        self.selection.SetDimensions( \
          granularise(self.position.x), granularise(self.position.y), 
          granularise(self.size.x), granularise(self.size.y))
#        self.selection.Show(true)

    def sizeFromCtrl(self):
        """ Called from outside the module. Set the group's size & pos from
            a control and notifies the Inspector. """
        print 'size from ctrl'
        # XXX What about granularity?
        if self.selection:
            self.position = self.selection.GetPosition()
            self.size = self.selection.GetSize()
            self.inspector.constructorUpdate('Size')
            self.inspector.propertyUpdate('ClientSize')
#        print self.position, self.size
        
    def setSelection(self):
#        print 'set selection'
        position = self.position
        size = self.size

        trPos = wxPoint(granularise(position.x), granularise(position.y))
        trSze = wxSize(granularise(size.x), granularise(size.y))

        self.stTL.SetDimensions(trPos.x -4, trPos.y -4, tagSize, tagSize)
        self.stTR.SetDimensions(trPos.x -3 +trSze.x, trPos.y -4, tagSize, tagSize)
        self.stBR.SetDimensions(trPos.x -3 +trSze.x, trPos.y -3 + trSze.y, tagSize, tagSize)
        self.stBL.SetDimensions(trPos.x -4, trPos.y -3 + trSze.y, tagSize, tagSize)
        
        self.sfT.SetDimensions(trPos.x + 3, trPos.y -2, trSze.x - 2*3, frmWid)
	self.sfR.SetDimensions(trPos.x + trSze.x, trPos.y + 3, frmWid, trSze.y - 2*3)
	self.sfB.SetDimensions(trPos.x +3, trPos.y + trSze.y, trSze.x - 2*3, frmWid)
	self.sfL.SetDimensions(trPos.x -2, trPos.y + 3, frmWid, trSze.y - 2*3)
        
    # Events
    def OnSizeBegin(self, event):
#        print 'On size begin'
        self.dragTag = self.senders.getObject(event)
        self.showFramedTags(self.dragTag)

    def OnSizeEnd(self, event):
#        print 'On size end'
        self.resizeCtrl()
#        self.selectCtrl(self.selection)
        self.showTags()
        self.dragTag = None

    def OnMouseOver(self, event):
#        print 'On move over'
    	if event.Dragging():
     	    pos = event.GetPosition()
     	    ctrl = self.senders.getObject(event)
	    self.moving(ctrl, pos)
	event.Skip()
    	    
class SelectionTag(wxPanel):
    def __init__(self, parent, position, cursor, offset, size, funcDown, funcUp, funcDrag, group):
        wxPanel.__init__(self, parent, -1)
        self.group = group
        self.SetSize(wxSize(size, size))
        self.SetBackgroundColour(wxBLACK)
        self.SetForegroundColour(wxBLACK)
        self.SetCursor(wxStockCursor(cursor))
        self.selection = None
        self.offset = offset
	self.position = position

	EVT_LEFT_DOWN(self, funcDown)
	EVT_LEFT_UP(self, funcUp)
	EVT_MOTION(self, funcDrag)

    def setPos(self, position):
        pass

class TLSelTag(SelectionTag):
    def setPos(self, position):
	oldPos = self.group.position
        self.group.position = position
        self.group.size = wxSize((oldPos.x - position.x) + self.group.size.x, (oldPos.y - position.y) + self.group.size.y)
        self.group.setSelection()
        
class TRSelTag(SelectionTag):
    def setPos(self, position):
	oldPos = self.group.position
        self.group.position = wxPoint(oldPos.x, position.y)
        self.group.size = wxSize((position.x - oldPos.x), (oldPos.y - position.y) + self.group.size.y)
        self.group.setSelection()
        
class BRSelTag(SelectionTag):
    def setPos(self, position):
	oldPos = self.group.position
        self.group.size = wxSize((position.x - oldPos.x), (position.y - oldPos.y))
        self.group.setSelection()

class BLSelTag(SelectionTag):
    def setPos(self, position):
	oldPos = self.group.position
        self.group.position = wxPoint(position.x, oldPos.y)
        self.group.size = wxSize((oldPos.x - position.x) + self.group.size.x, (position.y - oldPos.y))
        self.group.setSelection()
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.