Ejemplo n.º 1
0
def dragInMotion(self, event):
  """ 
  Dragged objects follow mouse motion 
  If snap mode, snaps the top-left of the object. 
  Replaced object.x, object.y with the x,y = object.getCenterCoord() , for 
  a center snap. Do the same to the snapNewEntity method in Utilities. 
  NOTE: Center snap causes problems when saving/loading models because it is 
  applied to new nodes created by loading a model. See ASG.py, addNode()
  """
  
  cb = self.cb
  
  x0, y0 = cb.getLastClickCoord() 
  x1, y1 = cb.getCanvasCoords(event)
  dx, dy = [x1-x0, y1-y0]
  selectionSet = cb.getSelectionObjectSet()
  
  # Many entities, try to make dragging more responsive (faster)
  if(len(selectionSet) > 1):
    dragMotion(self, [x0, y0], [x1, y1], selectionSet)
    
  
  elif(self.snapGridInfoTuple):
    
    gridSize, snapArrowNode, snapControlPoints = self.snapGridInfoTuple
    
    # Apply Snap only to entities, exclude arrows
    if(not snapArrowNode):    
      for object in selectionSet:      
        if(isEntityNode(object)):      
          #x,y = object.getCenterCoord() 
          x1 = snapIt(object.x + dx, x1, gridSize)
          y1 = snapIt(object.y + dy, y1, gridSize)        
          cb.setLastClickCoords([x1, y1])
          break
          
    # Snap Entities or Arrows
    else:
      for object in selectionSet:      
        #x,y = object.getCenterCoord() 
        x1 = snapIt(object.x + dx, x1, gridSize)
        y1 = snapIt(object.y + dy, y1, gridSize)               
        cb.setLastClickCoords([x1, y1])
        break
    
    dragMotion(self, [x0, y0], [x1, y1], selectionSet)
    optimizeConnectionPorts(self)
Ejemplo n.º 2
0
def dragInMotion(self, event):
    """ 
  Dragged objects follow mouse motion 
  If snap mode, snaps the top-left of the object. 
  Replaced object.x, object.y with the x,y = object.getCenterCoord() , for 
  a center snap. Do the same to the snapNewEntity method in Utilities. 
  NOTE: Center snap causes problems when saving/loading models because it is 
  applied to new nodes created by loading a model. See ASG.py, addNode()
  """

    cb = self.cb

    x0, y0 = cb.getLastClickCoord()
    x1, y1 = cb.getCanvasCoords(event)
    dx, dy = [x1 - x0, y1 - y0]
    selectionSet = cb.getSelectionObjectSet()

    # Many entities, try to make dragging more responsive (faster)
    if (len(selectionSet) > 1):
        dragMotion(self, [x0, y0], [x1, y1], selectionSet)

    elif (self.snapGridInfoTuple):

        gridSize, snapArrowNode, snapControlPoints = self.snapGridInfoTuple

        # Apply Snap only to entities, exclude arrows
        if (not snapArrowNode):
            for object in selectionSet:
                if (isEntityNode(object)):
                    #x,y = object.getCenterCoord()
                    x1 = snapIt(object.x + dx, x1, gridSize)
                    y1 = snapIt(object.y + dy, y1, gridSize)
                    cb.setLastClickCoords([x1, y1])
                    break

        # Snap Entities or Arrows
        else:
            for object in selectionSet:
                #x,y = object.getCenterCoord()
                x1 = snapIt(object.x + dx, x1, gridSize)
                y1 = snapIt(object.y + dy, y1, gridSize)
                cb.setLastClickCoords([x1, y1])
                break

        dragMotion(self, [x0, y0], [x1, y1], selectionSet)
        optimizeConnectionPorts(self)
Ejemplo n.º 3
0
 def fixConnections(self, params):
     # After re-sizing, arrows may not line up unless we do this
     from Utilities import optimizeConnectionPorts
     optimizeConnectionPorts(self.parent)
Ejemplo n.º 4
0
 def main(self, atom3i ):
   
   # Configure it up
   if(not self.__optionsDatabase.showOptionsDatabase()):
     return # User cancelled the dialog
   self.__processLoadedOptions()
   
   # Rescue mode
   if(self.__zoomRescue == True):
     self.__optionsDatabase.set(self.ZOOM_RESCUE, False)
     for nodetype in atom3i.ASGroot.nodeTypes:  
       for node in atom3i.ASGroot.listNodes[nodetype]:
         obj = node.graphObject_
         if(obj.__dict__.has_key('centerObject')):
           obj = obj.centerObject
           
         # Just kill all layout info
         if(obj.__dict__.has_key('layConstraints')):
           for key in obj.layConstraints.keys():
             value = obj.layConstraints[key]
             if(type(value) == type(1) or type(value == type(0.1))):
               obj.layConstraints[key] = 0
             if(type(value) == type([1,2]) or type(value) == type((1,2))):
               obj.layConstraints[key] = []
               for item in value:
                 obj.layConstraints[key].append(0)                  
     return
         
   # Check if the canvas size has changed: if so apply the change
   x,y = [self.__canvasX,self.__canvasY]
   if( x != atom3i.CANVAS_SIZE_TUPLE[2] or y != atom3i.CANVAS_SIZE_TUPLE[3] ):
     if( x > 600 and y > 600 ):
       atom3i.CANVAS_SIZE_TUPLE = (0,0,x,y)
       atom3i.UMLmodel.configure( scrollregion=atom3i.CANVAS_SIZE_TUPLE )
   
   # No ASG? Halt!  
   if(not atom3i.ASGroot):
     return
     
   # Build a list of nodes
   Object.nodeList = []
   entityList = [] 
   for nodetype in atom3i.ASGroot.nodeTypes:	
     if( atom3i.ASGroot.listNodes.has_key( nodetype ) ):
       for node in atom3i.ASGroot.listNodes[nodetype]:
         if( node.isSubclass(node.graphObject_, "graphLink")):
           edgeObject( node, node.graphObject_.getCenterCoord() )          
         else:
           nodeObject( node, node.graphObject_.getCenterCoord() )
           entityList.append( node.graphObject_ )
         
   # Apply zoom factor (effect depends on previously applied zoom)
   realZoom = float(self.__zoom ) / float(self.__lastZoom)
   self.__lastZoom = self.__zoom 
   for node in Object.nodeList:
     node.zoomify( realZoom )
                       
   # Apply the stretch factor
   lsx, lsy = [ self.__lastStretchX ,self.__lastStretchY ]
   sx,sy = self.__lastStretchX, self.__lastStretchY  = [ self.__stretchX, self.__stretchY ]
   realStretch = [ float(sx ) / float(lsx), float(sy) / float(lsy) ]
   for node in Object.nodeList:
     node.scalePosition( realStretch )
                 
   # Commit zooming & stretching
   for node in Object.nodeList:
     node.commitMove()
                 
   # All that scaling & moving can mess up connections...
   optimizeConnectionPorts(atom3i, entityList)
Ejemplo n.º 5
0
def dragDrop(self, objectSelectionSet ):
  """
  Done dragging... drop all the objects where this last event occurs
  """
  #todo: add auto-suggest QOCA
  #
  if(len(objectSelectionSet) > 1):
    lastCoords, newCoords = Drag.CURR_INSTANCE.destroy()
    dragMotion(self, lastCoords, newCoords, objectSelectionSet,
               applyMultiEntityMotion=True)
  
  for obj in objectSelectionSet:

    # Evaluate global pre-conditions
    res = self.ASGroot.preCondition(ASG.DROP)		
    if res: 
      return self.undodrag(res)
    # Evaluate local pre-conditions
    res = obj.semanticObject.preCondition(ASG.DROP)	
    if res: 
      return self.undodrag(res)	
    
    # Execute global pre-actions
    res = self.ASGroot.preAction(ASG.DROP)		
    # Execute local pre-actions
    res = obj.semanticObject.preAction(ASG.DROP)		
        
    # Evaluate global pre-conditions
    res = self.ASGroot.postCondition(ASG.DROP)		
    if res: 
      return self.constraintViolation(res)	
    # Evaluate local pre-conditions
    res = obj.semanticObject.postCondition(ASG.DROP)	
    if res: 
      return self.constraintViolation(res)		
    
    # Execute global post-actions
    res = self.ASGroot.postAction(ASG.DROP)		
    # Execute local post-actions
    res = obj.semanticObject.postAction(ASG.DROP)	
    
  # Status changed!
  self.statusbar.event(self.statusbar.MODEL, self.statusbar.MODIFY)
  
  #todo: new qoca
  # Initiates an automatic QOCA re-solve, since drop action probably changed
  # something... 
  if(self.qocaAutosolve):    
    varValueList = []
    for obj in objectSelectionSet:
      if(obj.qcX.get() != obj.x):
        varValueList.append((obj.qcX, obj.x))
      if(obj.qcY.get() != obj.y):
        varValueList.append((obj.qcY, obj.y))  
#    print 'suggesting'
#    for (var,value) in varValueList:
#      print var, var.name, value
    self.qocaSolver.suggestVarValue(varValueList)    
    self.qocaSolver.resolve()
    self.qocaSolver.endEdit()
    
    # QOCA can mess up the arrows :(
    optimizeConnectionPorts(self, entityList=objectSelectionSet)
Ejemplo n.º 6
0
def scaleReset(self, textMode = False):
  """ Restores scale to 1.0 """
  
  # Re-Size the text of an Entity or Link
  if(textMode):
    
    allScalableEntityObjects = []
    for object in self.cb.getSelectionObjectSet():
        if(isEntityNode(object)):
            allScalableEntityObjects.append(object)
        elif(object.getCenterObject()):
            allScalableEntityObjects.append(object.getCenterObject())
            
            
    for object in allScalableEntityObjects:
        # Get the last scale factor
        if(not object.layConstraints.has_key('Text Scale')):
          object.layConstraints['Text Scale'] = 1.00                          
        object.ScaleText(1.00)
        object.layConstraints['Text Scale'] = 1.00  
    
  # Re-Size an entity node - NO QOCA 
  elif(isNotUsingQoca()):
    for object in self.cb.getSelectionObjectSet():
      if(isEntityNode(object)):  
        
        # Get the last scale factor
        if(not object.layConstraints.has_key('scale')):
          object.layConstraints['scale'] = [1.00, 1.00]
        sx, sy = object.layConstraints['scale']
        newSize = [1.00, 1.00]
                
        # The final scale factor
        sx, sy = [ newSize[0] / sx, newSize[1] / sy ]  
  
        # Note: moveLinks is fals only because optimizeConnectionPorts is better
        #object.Scale(sx, sy, moveLinks = False)
        x0, y0 = object.getbbox()[:2]
        object.dc.scale(object.tag, x0, y0, sx, sy) 
        object.moveTo(object.x, object.y)
        object.layConstraints['scale'] = newSize
      
    optimizeConnectionPorts(self)
    
  # Re-Size an entity node - WITH QOCA constraints
  else:
    allScalableEntityObjects = []
    for object in self.cb.getSelectionObjectSet():
        if(isEntityNode(object)):
            allScalableEntityObjects.append(object)
          
    # Make the width/height editable
    editVarList = []
    for obj in allScalableEntityObjects:
      editVarList.append(obj.qcW)
      editVarList.append(obj.qcH)
    self.qocaSolver.addEditVars(editVarList)
    
    # Suggest new width/height values
    for obj in allScalableEntityObjects:     
      self.qocaSolver.suggestVarValue([(obj.qcW, obj.sizeX), 
                                       (obj.qcH, obj.sizeY)])   
      
    # Solve to get the new width/height of the entity
    self.qocaSolver.resolve(forceSolve=True)
    self.qocaSolver.endEdit() 
    optimizeConnectionPorts(self)
    
  modelChange(self) # Model changed, update statusbar & undo
Ejemplo n.º 7
0
def scaleWithMotion(self, event, textMode = False):
  """ Scales selected entities with the mouse motion """

  cb = self.cb                     

  x0, y0 = cb.getLastClickCoord() 
  x1, y1 = cb.getCanvasCoords(event)  
  
  allScalableEntityObjects = []
  for object in cb.getSelectionObjectSet():
      if(isEntityNode(object)):
          allScalableEntityObjects.append(object)
      elif(object.getCenterObject()):
          allScalableEntityObjects.append(object.getCenterObject())
  
  # Re-Size the text of an Entity or Link
  if(textMode):
    dx, dy = [ float(x1-x0) / 100.0 , float(y1-y0) / 100.0 ]
                 
    for object in allScalableEntityObjects:
        # Get the last scale factor, and add the movement delta
        if(not object.layConstraints.has_key('Text Scale')):
          object.layConstraints['Text Scale'] = 1.00
            
        newSize = object.layConstraints['Text Scale'] + dy
        
        # Bigger is better, too small is unreadable :D
        if(newSize < 0.2): 
          newSize = 0.2
          
        object.ScaleText(newSize)
        object.layConstraints['Text Scale'] = newSize  
        
        
  # Re-Size an entity node - NO QOCA 
  elif(isNotUsingQoca()):
    dx, dy = [ float(x1-x0) / 100.0 , float(y1-y0) / 100.0 ]
    for object in allScalableEntityObjects:
        
        # Get the last scale factor, and add the movement delta
        if(not object.layConstraints.has_key('scale')):
          object.layConstraints['scale'] = [1.00, 1.00]
        sx, sy = object.layConstraints['scale']
        newSize = [sx + dx, sy + dy]
        
        # Too small is not good :p
        if(newSize[0] < 0.2): 
          newSize[0] = 0.2
        if(newSize[1] < 0.2): 
          newSize[1] = 0.2
        
        # The final scale factor
        sx, sy = [ newSize[0] / sx, newSize[1] / sy ]  
  
        # Note: moveLinks is false only because optimizeConnectionPorts is better
        #object.Scale(sx, sy, moveLinks = False)
        x0, y0 = object.getbbox()[:2]
        object.dc.scale(object.tag, x0, y0, sx, sy) 
        object.moveTo(object.x, object.y)
        object.layConstraints['scale'] = newSize
      
    optimizeConnectionPorts(self)
        
  # Re-Size an entity node - WITH QOCA constraints
  else:  
    dx, dy = [float(x1-x0), float(y1-y0) ]
    
    # Make the width/height editable
    editVarList = []
    for obj in allScalableEntityObjects:
      editVarList.append(obj.qcW)
      editVarList.append(obj.qcH)      
    self.qocaSolver.addEditVars(editVarList)
    
    # Suggest new width/height values
    for obj in allScalableEntityObjects:     
      self.qocaSolver.suggestVarValue([(obj.qcW, obj.qcW.get() + dx), 
                                       (obj.qcH, obj.qcH.get() + dy)])   
      
    # Solve to get the new width/height of the entity
    self.qocaSolver.resolve(forceSolve=True)
    self.qocaSolver.endEdit() 
    object.layConstraints['scale'] = [obj.qcW.get() / obj.sizeX, 
                                      obj.qcH.get() / obj.sizeY]
    optimizeConnectionPorts(self)
    
    
  modelChange(self) # Model changed, update statusbar & undo
Ejemplo n.º 8
0
def scaleReset(self, textMode=False):
    """ Restores scale to 1.0 """

    # Re-Size the text of an Entity or Link
    if (textMode):

        allScalableEntityObjects = []
        for object in self.cb.getSelectionObjectSet():
            if (isEntityNode(object)):
                allScalableEntityObjects.append(object)
            elif (object.getCenterObject()):
                allScalableEntityObjects.append(object.getCenterObject())

        for object in allScalableEntityObjects:
            # Get the last scale factor
            if (not object.layConstraints.has_key('Text Scale')):
                object.layConstraints['Text Scale'] = 1.00
            object.ScaleText(1.00)
            object.layConstraints['Text Scale'] = 1.00

    # Re-Size an entity node - NO QOCA
    elif (isNotUsingQoca()):
        for object in self.cb.getSelectionObjectSet():
            if (isEntityNode(object)):

                # Get the last scale factor
                if (not object.layConstraints.has_key('scale')):
                    object.layConstraints['scale'] = [1.00, 1.00]
                sx, sy = object.layConstraints['scale']
                newSize = [1.00, 1.00]

                # The final scale factor
                sx, sy = [newSize[0] / sx, newSize[1] / sy]

                # Note: moveLinks is fals only because optimizeConnectionPorts is better
                #object.Scale(sx, sy, moveLinks = False)
                x0, y0 = object.getbbox()[:2]
                object.dc.scale(object.tag, x0, y0, sx, sy)
                object.moveTo(object.x, object.y)
                object.layConstraints['scale'] = newSize

        optimizeConnectionPorts(self)

    # Re-Size an entity node - WITH QOCA constraints
    else:
        allScalableEntityObjects = []
        for object in self.cb.getSelectionObjectSet():
            if (isEntityNode(object)):
                allScalableEntityObjects.append(object)

        # Make the width/height editable
        editVarList = []
        for obj in allScalableEntityObjects:
            editVarList.append(obj.qcW)
            editVarList.append(obj.qcH)
        self.qocaSolver.addEditVars(editVarList)

        # Suggest new width/height values
        for obj in allScalableEntityObjects:
            self.qocaSolver.suggestVarValue([(obj.qcW, obj.sizeX),
                                             (obj.qcH, obj.sizeY)])

        # Solve to get the new width/height of the entity
        self.qocaSolver.resolve(forceSolve=True)
        self.qocaSolver.endEdit()
        optimizeConnectionPorts(self)

    modelChange(self)  # Model changed, update statusbar & undo
Ejemplo n.º 9
0
def scaleWithMotion(self, event, textMode=False):
    """ Scales selected entities with the mouse motion """

    cb = self.cb

    x0, y0 = cb.getLastClickCoord()
    x1, y1 = cb.getCanvasCoords(event)

    allScalableEntityObjects = []
    for object in cb.getSelectionObjectSet():
        if (isEntityNode(object)):
            allScalableEntityObjects.append(object)
        elif (object.getCenterObject()):
            allScalableEntityObjects.append(object.getCenterObject())

    # Re-Size the text of an Entity or Link
    if (textMode):
        dx, dy = [float(x1 - x0) / 100.0, float(y1 - y0) / 100.0]

        for object in allScalableEntityObjects:
            # Get the last scale factor, and add the movement delta
            if (not object.layConstraints.has_key('Text Scale')):
                object.layConstraints['Text Scale'] = 1.00

            newSize = object.layConstraints['Text Scale'] + dy

            # Bigger is better, too small is unreadable :D
            if (newSize < 0.2):
                newSize = 0.2

            object.ScaleText(newSize)
            object.layConstraints['Text Scale'] = newSize

    # Re-Size an entity node - NO QOCA
    elif (isNotUsingQoca()):
        dx, dy = [float(x1 - x0) / 100.0, float(y1 - y0) / 100.0]
        for object in allScalableEntityObjects:

            # Get the last scale factor, and add the movement delta
            if (not object.layConstraints.has_key('scale')):
                object.layConstraints['scale'] = [1.00, 1.00]
            sx, sy = object.layConstraints['scale']
            newSize = [sx + dx, sy + dy]

            # Too small is not good :p
            if (newSize[0] < 0.2):
                newSize[0] = 0.2
            if (newSize[1] < 0.2):
                newSize[1] = 0.2

            # The final scale factor
            sx, sy = [newSize[0] / sx, newSize[1] / sy]

            # Note: moveLinks is false only because optimizeConnectionPorts is better
            #object.Scale(sx, sy, moveLinks = False)
            x0, y0 = object.getbbox()[:2]
            object.dc.scale(object.tag, x0, y0, sx, sy)
            object.moveTo(object.x, object.y)
            object.layConstraints['scale'] = newSize

        optimizeConnectionPorts(self)

    # Re-Size an entity node - WITH QOCA constraints
    else:
        dx, dy = [float(x1 - x0), float(y1 - y0)]

        # Make the width/height editable
        editVarList = []
        for obj in allScalableEntityObjects:
            editVarList.append(obj.qcW)
            editVarList.append(obj.qcH)
        self.qocaSolver.addEditVars(editVarList)

        # Suggest new width/height values
        for obj in allScalableEntityObjects:
            self.qocaSolver.suggestVarValue([(obj.qcW, obj.qcW.get() + dx),
                                             (obj.qcH, obj.qcH.get() + dy)])

        # Solve to get the new width/height of the entity
        self.qocaSolver.resolve(forceSolve=True)
        self.qocaSolver.endEdit()
        object.layConstraints['scale'] = [
            obj.qcW.get() / obj.sizeX,
            obj.qcH.get() / obj.sizeY
        ]
        optimizeConnectionPorts(self)

    modelChange(self)  # Model changed, update statusbar & undo
Ejemplo n.º 10
0
def dragDrop(self, objectSelectionSet):
    """
  Done dragging... drop all the objects where this last event occurs
  """
    #todo: add auto-suggest QOCA
    #
    if (len(objectSelectionSet) > 1):
        lastCoords, newCoords = Drag.CURR_INSTANCE.destroy()
        dragMotion(self,
                   lastCoords,
                   newCoords,
                   objectSelectionSet,
                   applyMultiEntityMotion=True)

    for obj in objectSelectionSet:

        # Evaluate global pre-conditions
        res = self.ASGroot.preCondition(ASG.DROP)
        if res:
            return self.undodrag(res)
        # Evaluate local pre-conditions
        res = obj.semanticObject.preCondition(ASG.DROP)
        if res:
            return self.undodrag(res)

        # Execute global pre-actions
        res = self.ASGroot.preAction(ASG.DROP)
        # Execute local pre-actions
        res = obj.semanticObject.preAction(ASG.DROP)

        # Evaluate global pre-conditions
        res = self.ASGroot.postCondition(ASG.DROP)
        if res:
            return self.constraintViolation(res)
        # Evaluate local pre-conditions
        res = obj.semanticObject.postCondition(ASG.DROP)
        if res:
            return self.constraintViolation(res)

        # Execute global post-actions
        res = self.ASGroot.postAction(ASG.DROP)
        # Execute local post-actions
        res = obj.semanticObject.postAction(ASG.DROP)

    # Status changed!
    self.statusbar.event(self.statusbar.MODEL, self.statusbar.MODIFY)

    #todo: new qoca
    # Initiates an automatic QOCA re-solve, since drop action probably changed
    # something...
    if (self.qocaAutosolve):
        varValueList = []
        for obj in objectSelectionSet:
            if (obj.qcX.get() != obj.x):
                varValueList.append((obj.qcX, obj.x))
            if (obj.qcY.get() != obj.y):
                varValueList.append((obj.qcY, obj.y))


#    print 'suggesting'
#    for (var,value) in varValueList:
#      print var, var.name, value
        self.qocaSolver.suggestVarValue(varValueList)
        self.qocaSolver.resolve()
        self.qocaSolver.endEdit()

        # QOCA can mess up the arrows :(
        optimizeConnectionPorts(self, entityList=objectSelectionSet)
Ejemplo n.º 11
0
 def fixConnections(self, params):
    # After re-sizing, arrows may not line up unless we do this
    from Utilities import optimizeConnectionPorts
    optimizeConnectionPorts( self.parent )
Ejemplo n.º 12
0
  def main(self, selection):

    Object.objList = []
    atom3i = self.atom3i
    dc = self.dc

    # Specific objects have been chosen on the canvas
    if( selection ):
        for obj in selection:
            self.__grabInfoFromGraphicalObject( obj )          
        
    # Nothing on canvas selected, do all!
    else:
   
      # Grab all the nodes in the diagram, except those with 0 size (arrows)
      # Store them in the "nodeObject" and reference them by objList
      for nodetype in atom3i.ASGroot.nodeTypes:	
        for node in atom3i.ASGroot.listNodes[nodetype]:        
          obj =   node.graphObject_
          #print obj
          self.__grabInfoFromGraphicalObject( obj )  

                
    self.__totalNodes = len( Object.objList )  
    
    #self.__sortNodes()     
    
    # Trivial non-overlap case
    if( self.__totalNodes <= 1 ):
      return
    
    self.__isLayoutStable = False
        
    # Keep at it till the layout is stable
    i = 0
    while( not self.__isLayoutStable ):
      self.__isLayoutStable = True # Optimism is good...
      self.__calculationLoop()
      
      # Disgusting: I have to actually sleep, otherwise I'll be done so fast
      # you won't have even seen it move :p
      if( self.__animationTime and i < self.__maxAnimIterations):
        self.dc.update_idletasks()
        time.sleep(self.__animationTime)  
        
      if( i > self.__maxIterations ):   break
      i += 1
      
      
    # Hijack the status bar to show what the FTA is doing...
    if( self.__useStatusBar ):
      if( i >= self.__maxIterations ):
        atom3i.statusbar.set(1,"FTA halted at max iterations, layout unstable",None)
      else:
        atom3i.statusbar.set(1,"FTA needed "+str(i)+" iterations to find stable layout",None)

    # Keep the whole thing in the viewable area of the canvas
    minY = minX = 10000
    for node in Object.objList:
      if( isinstance( node, NodeObject ) ):
        x,y = node.getTopLeftPos()
      else:
        x,y = node.getCoords()
      if( x < minX ): minX = x
      if( y < minY ): minY = y
      
    if( minX < self.__borderDistance ):
      minX = abs(minX) + self.__borderDistance
    else:
      minX = 0
    if( minY < self.__borderDistance ):
      minY = abs(minY) + self.__borderDistance
    else:
      minY = 0
   
    # Push on it!
    for node in Object.objList:
      node.recenteringPush(minX, minY )
      
    # All that moving stuff around can mess up the connections...
    if( selection ):
        optimizeConnectionPorts(atom3i, entityList=selection )
    else:
        optimizeConnectionPorts(atom3i, doAllLinks=True )
Ejemplo n.º 13
0
    def main(self, selection):

        Object.objList = []
        atom3i = self.atom3i
        dc = self.dc

        # Specific objects have been chosen on the canvas
        if (selection):
            for obj in selection:
                self.__grabInfoFromGraphicalObject(obj)

        # Nothing on canvas selected, do all!
        else:

            # Grab all the nodes in the diagram, except those with 0 size (arrows)
            # Store them in the "nodeObject" and reference them by objList
            for nodetype in atom3i.ASGroot.nodeTypes:
                for node in atom3i.ASGroot.listNodes[nodetype]:
                    obj = node.graphObject_
                    #print obj
                    self.__grabInfoFromGraphicalObject(obj)

        self.__totalNodes = len(Object.objList)

        #self.__sortNodes()

        # Trivial non-overlap case
        if (self.__totalNodes <= 1):
            return

        self.__isLayoutStable = False

        # Keep at it till the layout is stable
        i = 0
        while (not self.__isLayoutStable):
            self.__isLayoutStable = True  # Optimism is good...
            self.__calculationLoop()

            # Disgusting: I have to actually sleep, otherwise I'll be done so fast
            # you won't have even seen it move :p
            if (self.__animationTime and i < self.__maxAnimIterations):
                self.dc.update_idletasks()
                time.sleep(self.__animationTime)

            if (i > self.__maxIterations): break
            i += 1

        # Hijack the status bar to show what the FTA is doing...
        if (self.__useStatusBar):
            if (i >= self.__maxIterations):
                atom3i.statusbar.set(
                    1, "FTA halted at max iterations, layout unstable", None)
            else:
                atom3i.statusbar.set(
                    1, "FTA needed " + str(i) +
                    " iterations to find stable layout", None)

        # Keep the whole thing in the viewable area of the canvas
        minY = minX = 10000
        for node in Object.objList:
            if (isinstance(node, NodeObject)):
                x, y = node.getTopLeftPos()
            else:
                x, y = node.getCoords()
            if (x < minX): minX = x
            if (y < minY): minY = y

        if (minX < self.__borderDistance):
            minX = abs(minX) + self.__borderDistance
        else:
            minX = 0
        if (minY < self.__borderDistance):
            minY = abs(minY) + self.__borderDistance
        else:
            minY = 0

        # Push on it!
        for node in Object.objList:
            node.recenteringPush(minX, minY)

        # All that moving stuff around can mess up the connections...
        if (selection):
            optimizeConnectionPorts(atom3i, entityList=selection)
        else:
            optimizeConnectionPorts(atom3i, doAllLinks=True)