# __ File: graphEntity.py __________________________________________________________________________________________________ # Implements : class graphEntity, child of VisualObj # Author : Juan de Lara # Description : This is the base class for all graphical graphEntity Objects # Modified : 30 Oct 2001 # ____________________________________________________________________________________________________________________ from VisualObj import * class graphEntity(VisualObj): """ Attributes (these should be private): - self.center : tuple with the center of the object. - self.connectors : list of connectors elements. - self.delta_x, self.delta_y : last increment applied in Scaling. - self.graphForms : list of graphical forms. __________________________________________________________________________________________________________________________________________________ Private methods: - __moveConnection(self, conHandle, coordList, dx, dy, which): method to displace a connection. coordList is a list with the coordinates of conHandle. (dx, dy) is the displacement to apply. __________________________________________________________________________________________________________________________________________________ Public methods: - Move(self, delta_x, delta_y): Modifies object position by delta_x, delta_y - isFree (self, x0, y0, x1, y1 ): decides if this object has a connector whose average coordinates are either (x0, y0) or (x1, y1) - getCoordsVertex(self): returns the coordinate of the upper-left connector - getCoords(self, handle): returns the coordinates of a given handler - Scale(self, x_inc, y_inc): Scales the object in a factor of x_inc in x and y_inc in y - hasGraphicalConnection(self, node): checks if there are a connection between this object and node. Check this method. It WILL NOT WORK WITH THE NEW VERSION OF ATOM3 - deleteGraphicalConnection(self, handler): Deletes connection with handler 'handler' from actual node and from the other node end. Should check this, it will not work in the new version of ATOM3 - HighLight(self, flag): Highlights (flag = 1) or LowLights (flag = 0) all the VISIBLE elements with the 'selected' tag - connect(self, obj, intermediatePoints = []): Connects this object with another object of type 'graphLink'. The connection may have intermediate points, stored in the list intermediatePoints. - connectActions (self, htuple): Actions performed if this object is the destination of a connection. Adds the handler (1st component of htuple) to the list of connections - hasConnectHandler(self, ch): checks if the object has a connection with handler 'ch'. Returns a tuple ( handler, ) where order is 0 o 1 depending if it is the origing or destination - removeConnection(self, atom3i, handler): Removes the (input or output) connection whose handler is 'handler'. - Returns: -1 if handler is not a connection. 0 if handler corresponds to an output segment 1 if handler corresponds to an input segment - def erase (self, atom3i): Deletes the graphical Object. """ def __init__(self, x, y): """ Initializes object """ VisualObj.__init__(self) self.x, self.y = x, y self.center = (-1, -1) self.connectors = [] # set of connector handlers self.delta_x = 0 self.delta_y = 0 self.graphForms = [] # ________________________________________________________________________________________________________________ # PRIVATE METHODS # ________________________________________________________________________________________________________________ def __moveConnection(self, conHandle, dx, dy, sobj, lobj, graphLinkObj): """ method to displace (dx, dy) units a connection, whose handler is conHandle. The link may also have a drawing (lobj) and the segment may also have a link (sobj) """ coordList = self.dc.coords(conHandle) cx, cy = coordList[0], coordList[1] # obtain coordinates to move. We always select the two firsts, as connection are drawn from entities to links coordList[0], coordList[1] = cx+dx, cy+dy # move coordinates # self.dc.coords(conHandle, tuple(coordList)) # HV replaced by following for backward compatibility apply(self.dc.coords, tuple([conHandle] + coordList)) if lobj != None: # if we have a link object, then move it also... lobj.Move(dx, dy, 0) if sobj != None: graphLinkObj.drawSegmentIcon( conHandle, sobj ) # ________________________________________________________________________________________________________________ # PUBLIC METHODS # ________________________________________________________________________________________________________________ def Move(self, delta_x, delta_y, moveConn = 1): """ Modifies object position by delta_x, delta_y """ for gf in self.graphForms: # move each graphical form... self.dc.move(gf.handler, delta_x, delta_y) for con in self.connectors: # move each connector self.dc.move(con, delta_x, delta_y) self.moveGGLabel( delta_x, delta_y) self.x = self.x + delta_x self.y = self.y + delta_y if -1 not in self.center: self.center = (self.center[0] + delta_x, self.center[1] + delta_y) # now move connections if moveConn: for con_order in self.connections: con, order, sobj, lobj, obj = con_order self.__moveConnection(con, delta_x, delta_y, sobj, lobj, obj) def isFree (self, x0, y0, x1, y1 ): """ decides if this object has a connector whose average coordinates are either (x0, y0) or (x1, y1) """ for conn in self.connections: cl = self.dc.coords(conn[0]) limit = len(cl)/2 for i in range(limit): x, y = cl[i*2:i*2+2] if ((x, y) == (x0, y0)) or ((x, y) == (x1, y1)): return 0 return 1 def getCoordsVertex(self): """ returns the coordinate of the upper-left connector """ xmin, ymin = 10000, 10000 for h in self.connectors: x0, y0, x1, y1 = self.dc.coords(h) x, y = (x0+x1)/2, (y0+y1)/2 if x 0 and len(tags) > 0: # Modified 4-Jul-2002 atom3i.deleteConnection(c[0], tags[0]) # delete connection! (calling pre and post conditions) if c in self.connections: # Modified 18-Jan-2002 self.connections.remove(c) cts = self.dc.find_withtag(self.tag) for c in cts: self.dc.delete(c) self.Destroy() def redrawObject(self, canvas, showGG = 0): """ The canvas in which this object was drawn has been closed, and now it is requested to this object to draw itself again... """ while len(self.connections)>0: self.connections.pop() # remove connectors 'in place' while len(self.connectors)>0: self.connectors.pop() # remove connectors 'in place' while len(self.graphForms)>0: self.graphForms.pop() # remove graphForms 'in place' self.attr_display = {} self.DrawObject(canvas, showGG) def getbbox(self): """ gets the bounding box of this object """ minx, miny, maxx, maxy = 10000, 10000, -10000, -10000 # 1st collect all the handlers... for grform in self.graphForms: bbx = self.dc.bbox(grform.handler) if bbx: # the thing can be invisble and not have bounding box!!! if bbx[0] < minx: minx = bbx[0] if bbx[1] < miny: miny = bbx[1] if bbx[2] > maxx: maxx = bbx[2] if bbx[3] > maxy: maxy = bbx[3] return (minx, miny, maxx, maxy) def write2File(self, file, indent): """ Writes its properties into a file . """ for gf in self.graphForms: gf.write2File(file, indent)