def applyLayout(self): for nodetype in self.ASGroot.nodeTypes: for node in self.ASGroot.listNodes[nodetype]: if (isEntityNode(node.graphObject_)): # Move the nodes around currPos = node.graphObject_.getCenterCoord() newPos = [randint(0, 640), randint(0, 480)] node.graphObject_.Move(-currPos[0], -currPos[1], False) # Go back to the origin node.graphObject_.Move(newPos[0], newPos[1], False) # Move to random location else: # Move the links around currPos = node.graphObject_.getCenterCoord() newPos = [randint(0, 640), randint(0, 480)] node.graphObject_.Move(-currPos[0], -currPos[1]) # Go back to the origin node.graphObject_.Move(newPos[0], newPos[1]) # Move to random location selectAllVisibleObjects(self) optimizeLinks(self.cb) """
def initReSizer(self): self.buildSelectionObjectSet() # Re-Size is only valid if done on entities, so need at least 1 entity for obj in self.selectionObjectSet: if(isEntityNode(obj) or obj.getCenterObject()): self.reSizeAbort = False return self.reSizeAbort = True
def dragLabelsInMotion(self, event): """ Drags all selected labels around """ cb = self.cb x0, y0 = cb.getLastClickCoord() x1, y1 = cb.getCanvasCoords(event) dx, dy = [x1 - x0, y1 - y0] selectionSet = cb.getSelectionObjectSet() # All selected objects for obj in selectionSet: # Graph Entities (not links) if (isEntityNode(obj)): objectLabelMoved = False # Associated graphical forms for gf in obj.graphForms: # Text label if (gf.elementType == 'text'): self.cb.getCanvas().move(gf.handler, dx, dy) objectLabelMoved = True # Save the offest as a graphical layout constraint for model save/load if (objectLabelMoved): if (not obj.layConstraints.has_key('Label Offset')): obj.layConstraints['Label Offset'] = [dx, dy] else: deltaX, deltaY = obj.layConstraints['Label Offset'] obj.layConstraints['Label Offset'] = [ dx + deltaX, dy + deltaY ] # This is a link else: # Label is the centerObject if (obj.centerObject): obj.centerObject.Move(dx, dy, 0) # Save the offest as a graphical layout constraint for model save/load if (not obj.layConstraints.has_key('Label Offset')): obj.layConstraints['Label Offset'] = [dx, dy] else: deltaX, deltaY = obj.layConstraints['Label Offset'] obj.layConstraints['Label Offset'] = [ dx + deltaX, dy + deltaY ]
def textScaleConstraint( graphObject, scale ): """ Scales a graphical entity's text """ # Normal objects that we must scale if( isObject_Scaling_Neutral( graphObject ) ): # Entity node if( isEntityNode( graphObject ) ): graphObject.ScaleText( scale ) # Link with a center object elif( graphObject.centerObject ): graphObject.centerObject.layConstraints[ 'Text Scale' ] = scale graphObject.centerObject.ScaleText( scale )
def dragLabelsInMotion(self, event): """ Drags all selected labels around """ cb = self.cb x0, y0 = cb.getLastClickCoord() x1, y1 = cb.getCanvasCoords(event) dx, dy = [x1-x0, y1-y0] selectionSet = cb.getSelectionObjectSet() # All selected objects for obj in selectionSet: # Graph Entities (not links) if(isEntityNode(obj)): objectLabelMoved = False # Associated graphical forms for gf in obj.graphForms: # Text label if(gf.elementType == 'text'): self.cb.getCanvas().move(gf.handler, dx, dy) objectLabelMoved = True # Save the offest as a graphical layout constraint for model save/load if(objectLabelMoved): if(not obj.layConstraints.has_key('Label Offset')): obj.layConstraints['Label Offset'] = [dx, dy ] else: deltaX, deltaY = obj.layConstraints['Label Offset'] obj.layConstraints['Label Offset'] = [dx+deltaX, dy+deltaY] # This is a link else: # Label is the centerObject if(obj.centerObject): obj.centerObject.Move(dx, dy, 0) # Save the offest as a graphical layout constraint for model save/load if(not obj.layConstraints.has_key('Label Offset')): obj.layConstraints['Label Offset'] = [dx, dy] else: deltaX, deltaY = obj.layConstraints['Label Offset'] obj.layConstraints['Label Offset'] = [dx+deltaX, dy+deltaY]
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)
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)
def labelOffsetConstraint( graphObject, labelOffset ): """ Offset to the label of link or entity """ if( isObject_Self_Label_Offseting (graphObject ) ): return # Entity Label if( isEntityNode( graphObject ) ): # Associated graphical forms for gf in graphObject.graphForms: # Text label if( gf.elementType == 'text' ): graphObject.dc.move( gf.handler, labelOffset[0], labelOffset[1] ) # Link Label elif( graphObject.centerObject ): graphObject.centerObject.Move( labelOffset[0], labelOffset[1], 0 )
def createDynamicMenu(self, event): """ Create a dynamic context sensitive popup menu system """ cb = self.cb selectionIsEmpty = cb.isLastSelectionEmpty() # Item under cursor? itemTuple = cb.getItemUnderCursor(self, event) if(itemTuple and cb.isItemVisible(itemTuple[0])): obj = itemTuple[2] # Graph Entity Object Selected if(isEntityNode(obj)): if(selectionIsEmpty): self.popupMenuCreator.EntityAtCursorNoSelectPopup(event) else: self.popupMenuCreator.EntityAtCursorMultiSelectPopup(event) # Graph Link Object Selected elif(isConnectionLink(obj)): if(selectionIsEmpty): self.popupMenuCreator.LinkAtCursorNoSelectPopup(event) else: self.popupMenuCreator.LinkAtCursorMultiSelectPopup(event) # Uknown Object Selected else: raise Exception, \ "Not an entity, not a link, what is it? Superman? " + str(obj) # No item under cursor, no items selected elif(selectionIsEmpty): self.popupMenuCreator.NoCursorNoSelectPopup(event) # No item under cursor, but multiple items selected else: self.popupMenuCreator.NoCursorMultiSelectPopup(event)
def createDynamicMenu(self, event): """ Create a dynamic context sensitive popup menu system """ cb = self.cb selectionIsEmpty = cb.isLastSelectionEmpty() # Item under cursor? itemTuple = cb.getItemUnderCursor(self, event) if (itemTuple and cb.isItemVisible(itemTuple[0])): obj = itemTuple[2] # Graph Entity Object Selected if (isEntityNode(obj)): if (selectionIsEmpty): self.popupMenuCreator.EntityAtCursorNoSelectPopup(event) else: self.popupMenuCreator.EntityAtCursorMultiSelectPopup(event) # Graph Link Object Selected elif (isConnectionLink(obj)): if (selectionIsEmpty): self.popupMenuCreator.LinkAtCursorNoSelectPopup(event) else: self.popupMenuCreator.LinkAtCursorMultiSelectPopup(event) # Uknown Object Selected else: raise Exception, \ "Not an entity, not a link, what is it? Superman? " + str(obj) # No item under cursor, no items selected elif (selectionIsEmpty): self.popupMenuCreator.NoCursorNoSelectPopup(event) # No item under cursor, but multiple items selected else: self.popupMenuCreator.NoCursorMultiSelectPopup(event)
def scaleConstraint( graphObject, scaleSize ): """ Scales a graphical entity """ # Normal objects that we must scale if( isObject_Scaling_Neutral( graphObject ) ): # Entity node if( isEntityNode( graphObject ) ): graphObject.Scale( scaleSize[0], scaleSize[1], moveLinks = False ) # Make sure scale didn't screw up the the top-left (not supposed to...) graphObject.moveTo(graphObject.x, graphObject.y) # Link with a center object elif( graphObject.centerObject ): #x, y = graphObject.centerObject.getbbox()[:2] graphObject.centerObject.layConstraints[ 'scale' ] = scaleSize graphObject.centerObject.Scale( scaleSize[0], scaleSize[1], moveLinks = False ) # Make sure scale didn't screw up the the top-left (not supposed to...) #graphObject.centerObject.moveTo(x, y) # Some formalisms can *almost* scale themselves without any help... elif( isObject_Partially_Self_Scaling( graphObject ) ): graphObject.scaleHack( scaleSize[0], scaleSize[1] )
def optimizeConnectionPorts(self, entityList = None, linkObjectList=None, doAllLinks = False, cb=None ): """ Ensures that the endpoints of the arrows use the optimal connectors Applied only to selected arrows and to the arrows attached to selected nodes Does not move arrows attached to named ports :D 4 Modes of operation: i) Given entityList, a list of nodes, the links between them will be optimized ii) Given linkObjectList, a list of edge graph objects, the links are optimized iii) Given doAllLinks, a boolean and self=atom3i, optimizes all links on the canvas iv) Given self=atom3i or cb=cb, will optimize everything currently selected on the canvas NOTES: a) self argument should be atom3 instance, required if doAllLinks=True, otherwise, cb=cb is acceptable b) cb is an instance of CallbackState """ if( not cb ): cb = self.cb dc = cb.getCanvas() # Step 1A: Given entities, not a selection dict, so get all affected links if( entityList ): augmentedSelection = dict() # List of node/entity objects for obj in entityList: # Any one of its links may need optimization augmentTheSelection( dc, obj, augmentedSelection ) # Step 1B: Given list of link objects elif( linkObjectList ): augmentedSelection = dict() for linkObject in linkObjectList: linkTag = linkObject.tag + "1stSeg0" itemHandler = dc.find_withtag( linkTag ) if( not itemHandler ): print "WARNING: Utilities.optimizeConnectionPorts() cannot find item with tag", linkTag continue # raise Exception, "optimizeConnectionPorts() having trouble playing " \ # + "tag, Step 1B (Try save & load)" # Add to the selection, {tag : [itemHandler, Object] } augmentedSelection[ linkTag ] = [ itemHandler[0], linkObject ] # Step 1C: Find all the links! elif( doAllLinks ): augmentedSelection = dict() nodeTypes = self.ASGroot.nodeTypes listNodes = self.ASGroot.listNodes for nodetype in nodeTypes: if( listNodes[nodetype] ): if( isConnectionLink( listNodes[nodetype][0].graphObject_ ) ): # Iterate over all the links only for node in listNodes[nodetype]: linkTag = node.graphObject_.tag + "1stSeg0" itemHandler = dc.find_withtag( linkTag ) if( not itemHandler ): print "WARNING: itemhandler not found! Utilities.py --> " \ + "optimizeConnectionPorts() fails (Try save & load)" continue # Add to the selection, {tag : [itemHandler, Object] } augmentedSelection[ linkTag ] = [ itemHandler[0], node.graphObject_ ] # Step 1D: Augment the selection with links affected by the node movement # & remove nodes else: selection = cb.getSelectionDict() augmentedSelection = selection.copy() # <--- This copy() is soooo important for tag in selection: itemHandler, obj = selection[tag] # This is a NODE if( isEntityNode( obj ) ): # Any one of its links may need optimization augmentTheSelection( dc, obj, augmentedSelection ) # We don't need to optimize nodes, just links... so... bye bye node del augmentedSelection[tag] # Step 2: Optimize all the selected links for tag in augmentedSelection: obj = augmentedSelection[tag][1] baseTag = obj.tag # Ex: Obj3 , the tag of the intermediate link object # Some links have center objects (labels/drawings) that look way better # if they are above the arrow centerObj = obj.getCenterObject() if( centerObj ): dc.tag_raise(centerObj.tag ) # Find all the entities that the edge is linking to # (general enough to handle hyperedges) objectsFrom = [] objectsTo = [] semObject = obj.getSemanticObject() arrowArrowCase = False for semObj in semObject.in_connections_: if(isConnectionLink(semObj.graphObject_)): arrowArrowCase = True objectsFrom.append( semObj.graphObject_ ) for semObj in semObject.out_connections_: if(isConnectionLink(semObj.graphObject_)): arrowArrowCase = True objectsTo.append( semObj.graphObject_ ) # Arrow connected to another arrow, this isn't handled!!! if(arrowArrowCase): continue # Initial point/s in the connection ---> Object/s From for i in range(0, len(objectsFrom) ): # Get the tag & itemhandler for each from segement segTag = baseTag + "1stSeg" + str(i) itemHandler = dc.find_withtag( segTag ) if( not itemHandler ): print "WARNING: Having problems looking up canvas tags!", segTag continue #raise Exception, "Having problems looking up canvas tags!" coords = dc.coords( itemHandler ) objFrom = objectsFrom[i] # If the object has connectors and they are not NAMED connectors if( objFrom.hasConnectors() and not objFrom.isConnectedByNamedPort( obj.semanticObject ) ): # Snap to the nearest connection port if not already there # NOTE: the [obj.x,obj.y] part makes sure we connect directly # to the intermediate object x, y = objFrom.getClosestConnector2Point(objFrom, coords[2], coords[3]) if( x != coords[0] or y != coords[1] ): dc.coords(* [itemHandler] + [x, y] + coords[2:-2] + [obj.x, obj.y]) # Check if a link drawing needs moving... obj.updateDrawingsTo( x, y, itemHandler[0] ) # Final point/s in the connection ---> Object/s To for i in range(0, len(objectsTo) ): # Get the tag & itemhandler for each to segement segTag = baseTag + "2ndSeg" + str(i) itemHandler = dc.find_withtag( segTag ) if( not itemHandler ): print "WARNING: Having problems looking up canvas tags!", segTag continue #raise Exception, "Having problems looking up canvas tags!" itemHandler = itemHandler[0] coords = dc.coords( itemHandler ) objTo = objectsTo[i] if( objTo.hasConnectors() and not objTo.isConnectedByNamedPort( obj.semanticObject ) ): # Snap to the nearest connection port if not already there # NOTE: the [obj.x,obj.y] part makes sure we connect directly to the # intermediate object x, y = objTo.getClosestConnector2Point(objTo, coords[2], coords[3]) if( x != coords[0] or y != coords[1] ): dc.coords(* [itemHandler] + [x, y] + coords[2:-2] + [obj.x, obj.y]) # Check if a link drawing needs moving... obj.updateDrawingsTo( x, y, itemHandler, segmentNumber=2 )
def optimizeConnectionPorts(self, entityList=None, linkObjectList=None, doAllLinks=False, cb=None): """ Ensures that the endpoints of the arrows use the optimal connectors Applied only to selected arrows and to the arrows attached to selected nodes Does not move arrows attached to named ports :D 4 Modes of operation: i) Given entityList, a list of nodes, the links between them will be optimized ii) Given linkObjectList, a list of edge graph objects, the links are optimized iii) Given doAllLinks, a boolean and self=atom3i, optimizes all links on the canvas iv) Given self=atom3i or cb=cb, will optimize everything currently selected on the canvas NOTES: a) self argument should be atom3 instance, required if doAllLinks=True, otherwise, cb=cb is acceptable b) cb is an instance of CallbackState """ if (not cb): cb = self.cb dc = cb.getCanvas() # Step 1A: Given entities, not a selection dict, so get all affected links if (entityList): augmentedSelection = dict() # List of node/entity objects for obj in entityList: # Any one of its links may need optimization augmentTheSelection(dc, obj, augmentedSelection) # Step 1B: Given list of link objects elif (linkObjectList): augmentedSelection = dict() for linkObject in linkObjectList: linkTag = linkObject.tag + "1stSeg0" itemHandler = dc.find_withtag(linkTag) if (not itemHandler): print "WARNING: Utilities.optimizeConnectionPorts() cannot find item with tag", linkTag continue # raise Exception, "optimizeConnectionPorts() having trouble playing " \ # + "tag, Step 1B (Try save & load)" # Add to the selection, {tag : [itemHandler, Object] } augmentedSelection[linkTag] = [itemHandler[0], linkObject] # Step 1C: Find all the links! elif (doAllLinks): augmentedSelection = dict() nodeTypes = self.ASGroot.nodeTypes listNodes = self.ASGroot.listNodes for nodetype in nodeTypes: if (listNodes[nodetype]): if (isConnectionLink(listNodes[nodetype][0].graphObject_)): # Iterate over all the links only for node in listNodes[nodetype]: linkTag = node.graphObject_.tag + "1stSeg0" itemHandler = dc.find_withtag(linkTag) if (not itemHandler): print "WARNING: itemhandler not found! Utilities.py --> " \ + "optimizeConnectionPorts() fails (Try save & load)" continue # Add to the selection, {tag : [itemHandler, Object] } augmentedSelection[linkTag] = [ itemHandler[0], node.graphObject_ ] # Step 1D: Augment the selection with links affected by the node movement # & remove nodes else: selection = cb.getSelectionDict() augmentedSelection = selection.copy( ) # <--- This copy() is soooo important for tag in selection: itemHandler, obj = selection[tag] # This is a NODE if (isEntityNode(obj)): # Any one of its links may need optimization augmentTheSelection(dc, obj, augmentedSelection) # We don't need to optimize nodes, just links... so... bye bye node del augmentedSelection[tag] # Step 2: Optimize all the selected links for tag in augmentedSelection: obj = augmentedSelection[tag][1] baseTag = obj.tag # Ex: Obj3 , the tag of the intermediate link object # Some links have center objects (labels/drawings) that look way better # if they are above the arrow centerObj = obj.getCenterObject() if (centerObj): dc.tag_raise(centerObj.tag) # Find all the entities that the edge is linking to # (general enough to handle hyperedges) objectsFrom = [] objectsTo = [] semObject = obj.getSemanticObject() arrowArrowCase = False for semObj in semObject.in_connections_: if (isConnectionLink(semObj.graphObject_)): arrowArrowCase = True objectsFrom.append(semObj.graphObject_) for semObj in semObject.out_connections_: if (isConnectionLink(semObj.graphObject_)): arrowArrowCase = True objectsTo.append(semObj.graphObject_) # Arrow connected to another arrow, this isn't handled!!! if (arrowArrowCase): continue # Initial point/s in the connection ---> Object/s From for i in range(0, len(objectsFrom)): # Get the tag & itemhandler for each from segement segTag = baseTag + "1stSeg" + str(i) itemHandler = dc.find_withtag(segTag) if (not itemHandler): print "WARNING: Having problems looking up canvas tags!", segTag continue #raise Exception, "Having problems looking up canvas tags!" coords = dc.coords(itemHandler) objFrom = objectsFrom[i] # If the object has connectors and they are not NAMED connectors if (objFrom.hasConnectors() and not objFrom.isConnectedByNamedPort(obj.semanticObject)): # Snap to the nearest connection port if not already there # NOTE: the [obj.x,obj.y] part makes sure we connect directly # to the intermediate object x, y = objFrom.getClosestConnector2Point( objFrom, coords[2], coords[3]) if (x != coords[0] or y != coords[1]): dc.coords(*[itemHandler] + [x, y] + coords[2:-2] + [obj.x, obj.y]) # Check if a link drawing needs moving... obj.updateDrawingsTo(x, y, itemHandler[0]) # Final point/s in the connection ---> Object/s To for i in range(0, len(objectsTo)): # Get the tag & itemhandler for each to segement segTag = baseTag + "2ndSeg" + str(i) itemHandler = dc.find_withtag(segTag) if (not itemHandler): print "WARNING: Having problems looking up canvas tags!", segTag continue #raise Exception, "Having problems looking up canvas tags!" itemHandler = itemHandler[0] coords = dc.coords(itemHandler) objTo = objectsTo[i] if (objTo.hasConnectors() and not objTo.isConnectedByNamedPort(obj.semanticObject)): # Snap to the nearest connection port if not already there # NOTE: the [obj.x,obj.y] part makes sure we connect directly to the # intermediate object x, y = objTo.getClosestConnector2Point(objTo, coords[2], coords[3]) if (x != coords[0] or y != coords[1]): dc.coords(*[itemHandler] + [x, y] + coords[2:-2] + [obj.x, obj.y]) # Check if a link drawing needs moving... obj.updateDrawingsTo(x, y, itemHandler, segmentNumber=2)
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
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
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
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