1 # Copyright (C) 2006-2008 CEA/DEN, EDF R&D
3 # This library is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU Lesser General Public
5 # License as published by the Free Software Foundation; either
6 # version 2.1 of the License.
8 # This library is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 # Lesser General Public License for more details.
13 # You should have received a copy of the GNU Lesser General Public
14 # License along with this library; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 from qtcanvas import *
24 class DynamicTip( QToolTip ):
25 def __init__( self, parent ):
26 QToolTip.__init__( self, parent )
28 def maybeTip( self, pos ):
29 pos2=self.parentWidget().viewportToContents(pos)
30 point = self.parentWidget().inverseWorldMatrix().map(pos2)
31 ilist = self.parentWidget().canvas().collisions(point) #QCanvasItemList ilist
32 for each_item in ilist:
33 if hasattr(each_item,"tooltip"):
34 each_item.tooltip(self,pos)
36 elif hasattr(each_item,"getObj"):
37 each_item.getObj().tooltip(self,pos)
40 class GraphViewer(QCanvasView):
41 def __init__(self,c,parent,name,f):
42 QCanvasView.__init__(self,c,parent,name,f)
45 self.__moving_start= 0
46 # for highlighting selections
47 self.selectPen=QPen(QColor(255,255,0),2,Qt.DashLine)
48 self.selectBrush=QBrush(Qt.red)
49 self.selectStyle = Qt.Dense5Pattern
51 self.tooltip = DynamicTip( self )
53 def contentsMouseDoubleClickEvent(self,e): # QMouseEvent e
54 point = self.inverseWorldMatrix().map(e.pos())
55 ilist = self.canvas().collisions(point) #QCanvasItemList ilist
56 for each_item in ilist:
57 if each_item.rtti()==984376:
58 if not each_item.hit(point):
60 if e.button()== Qt.LeftButton:
61 if hasattr(each_item,"handleDoubleClick"):
62 each_item.handleDoubleClick(point)
63 self.canvas().update()
67 def contentsMousePressEvent(self,e): # QMouseEvent e
69 point = self.inverseWorldMatrix().map(e.pos())
70 ilist = self.canvas().collisions(point) #QCanvasItemList ilist
71 for each_item in ilist:
72 if each_item.rtti()==984376:
73 if not each_item.hit(point):
75 if e.button()== Qt.RightButton:
79 if hasattr(each_item,"popup"):
80 menu=each_item.popup(self)
82 menu.exec_loop( QCursor.pos() )
83 self.canvas().update()
84 elif hasattr(each_item,"getObj"):
85 menu=each_item.getObj().popup(self)
87 menu.exec_loop( QCursor.pos() )
88 self.canvas().update()
90 elif e.button()== Qt.LeftButton:
93 #We are linking objects
94 if hasattr(each_item,"getObj"):
95 #a connection is ending
96 self.__connecting.link(each_item.getObj().item)
97 #self.__connecting.link(each_item.getObj())
98 self.canvas().update()
101 #We are moving or selecting a composite object
103 self.__moving=each_item
104 self.__moving_start=point
105 self.canvas().update()
107 if e.button()== Qt.RightButton:
110 menu.exec_loop( QCursor.pos() )
111 self.canvas().update()
114 QCanvasView.contentsMousePressEvent(self,e)
116 def selectItem(self,item):
117 #print "selectItem",item
120 self.deselectObj(self.selected)
124 #need to find equivalent canvas item
125 for citem in self.canvas().allItems():
126 if hasattr(citem,"item") and citem.item is item:
128 self.selectObj(self.selected)
130 self.canvas().update()
132 def selectObj(self,obj):
134 obj._origPen = obj.pen()
135 obj._origBrush = obj.brush()
136 obj._origStyle = obj.brush().style()
137 obj.setPen(self.selectPen)
138 #obj.setBrush(self.selectBrush)
140 def deselectObj(self,obj):
142 obj.setPen(obj._origPen)
143 #obj.setBrush(obj._origBrush)
147 caption = QLabel( "<font color=darkblue><u><b>View Menu</b></u></font>", self )
148 caption.setAlignment( Qt.AlignCenter )
149 menu.insertItem( caption )
150 menu.insertItem("add Node", self.addNode)
153 #def layout(self,rankdir):
156 def updateCanvas(self):
157 #Par defaut, Qt n'efface pas le background. Seul repaintContents
158 #semble le faire. Utile apres un popup ou un resize avec scrollbars
159 #Peut-on l'utiliser partout ? Pb de performance ?
160 self.repaintContents(True)
161 #self.canvas().update()
167 m = self.worldMatrix()
169 self.setWorldMatrix( m )
172 m = self.worldMatrix()
174 self.setWorldMatrix( m )
177 ilist = self.canvas().allItems()
178 for each_item in ilist:
180 each_item.setCanvas(None)
182 self.canvas().update()
184 def connecting(self,obj):
185 """Method called by an item to notify canvasView a connection has begun"""
186 print "connecting",obj
187 self.__connecting=obj
189 def contentsMouseMoveEvent(self,e):
191 point = self.inverseWorldMatrix().map(e.pos())
192 self.__moving.moveBy(point.x()-self.__moving_start.x(),point.y()-self.__moving_start.y())
193 self.__moving_start = point
194 self.canvas().update()
196 #self.tooltip.maybeTip(point)
197 QCanvasView.contentsMouseMoveEvent(self,e)
199 class ImageItem(QCanvasRectangle):
200 def __init__(self,img,canvas):
201 QCanvasRectangle.__init__(self,canvas)
203 self.imageRTTI=984376
205 self.pixmap=QPixmap()
206 self.setSize(self.image.width(), self.image.height())
207 self.pixmap.convertFromImage(self.image, Qt.OrderedAlphaDither);
210 return self.imageRTTI
215 if not self.image.valid( ix , iy ):
217 self.pixel = self.image.pixel( ix, iy )
218 return (qAlpha( self.pixel ) != 0)
220 def drawShape(self,p):
221 p.drawPixmap( self.x(), self.y(), self.pixmap )
223 class LinkItem(QCanvasLine):
224 def __init__(self,fromPort, toPort,canvas):
225 QCanvasLine.__init__(self,canvas)
226 self.setPen(QPen(Qt.black))
227 self.setBrush(QBrush(Qt.red))
228 fromPort.addOutLink(self)
229 toPort.addInLink(self)
230 self.setPoints(int(fromPort.x()),int(fromPort.y()), int(toPort.x()), int(toPort.y()))
231 self.setZ(min(fromPort.z(),toPort.z())-1)
232 self.setVisible(True)
233 self.arrow = QCanvasPolygon(self.canvas())
234 self.arrow.setBrush(QBrush(Qt.black))
238 def setFromPoint(self,x,y):
239 self.setPoints(x,y,self.endPoint().x(),self.endPoint().y())
242 def setToPoint(self,x,y):
243 self.setPoints(self.startPoint().x(), self.startPoint().y(),x,y)
246 def moveBy(self,dx,dy):
250 x1,y1=self.startPoint().x(),self.startPoint().y()
251 x2,y2=self.endPoint().x(),self.endPoint().y()
252 d=math.hypot(x2-x1,y2-y1)
258 pa.setPoint(0, QPoint(x+10*cosa,y+10*sina))
259 pa.setPoint(1, QPoint(x-5*sina,y+5*cosa))
260 pa.setPoint(2, QPoint(x+5*sina,y-5*cosa))
261 self.arrow.setPoints(pa)
263 def popup(self,canvasView):
265 caption = QLabel( "<font color=darkblue><u><b>Node Menu</b></u></font>",menu )
266 caption.setAlignment( Qt.AlignCenter )
267 menu.insertItem( caption )
268 menu.insertItem("Delete", self.delete)
274 def tooltip(self,view,pos):
275 r = QRect(pos.x(), pos.y(), pos.x()+10, pos.y()+10)
276 s = QString( "link: %d,%d" % (r.center().x(), r.center().y()) )
279 class PortItem(QCanvasEllipse):
280 def __init__(self,node,canvas):
281 QCanvasEllipse.__init__(self,6,6,canvas)
282 self.setPen(QPen(Qt.black))
283 self.setBrush(QBrush(Qt.red))
284 self.setZ(node.z()+1)
287 def moveBy(self,dx,dy):
288 self.node.moveBy(dx,dy)
290 def myMove(self,dx,dy):
291 QCanvasEllipse.moveBy(self,dx,dy)
296 def popup(self,canvasView):
297 self.context=canvasView
299 caption = QLabel( "<font color=darkblue><u><b>Port Menu</b></u></font>",menu )
300 caption.setAlignment( Qt.AlignCenter )
301 menu.insertItem( caption )
302 menu.insertItem("Connect", self.connect)
306 print "connect",self.context
307 self.context.connecting(self)
312 def tooltip(self,view,pos):
313 r = QRect(self.x(), self.y(), self.width(), self.height())
314 s = QString( "port: %d,%d" % (r.center().x(), r.center().y()) )
317 class InPortItem(PortItem):
318 def __init__(self,node,canvas):
319 PortItem.__init__(self,node,canvas)
322 def myMove(self,dx,dy):
323 PortItem.myMove(self,dx,dy)
324 for link in self.__inList:
325 link.setToPoint( int(self.x()), int(self.y()) )
329 if isinstance(obj,OutPortItem):
331 l=LinkItem(obj,self,self.canvas())
333 def addInLink(self,link):
334 self.__inList.append(link)
336 class OutPortItem(PortItem):
337 def __init__(self,node,canvas):
338 PortItem.__init__(self,node,canvas)
341 def myMove(self,dx,dy):
342 PortItem.myMove(self,dx,dy)
343 for link in self.__outList:
344 link.setFromPoint( int(self.x()), int(self.y()) )
348 if isinstance(obj,InPortItem):
350 l=LinkItem(self,obj,self.canvas())
352 def addOutLink(self,link):
353 self.__outList.append(link)
355 class Cell(QCanvasRectangle):
356 def __init__(self,canvas):
357 QCanvasRectangle.__init__(self,canvas)
363 p=InPortItem(self,canvas)
365 self.inports.append(p)
366 p=OutPortItem(self,canvas)
368 self.outports.append(p)
370 def moveBy(self,dx,dy):
371 QCanvasRectangle.moveBy(self,dx,dy)
372 for p in self.inports:
374 for p in self.outports:
378 QCanvasRectangle.show(self)
379 for p in self.inports:
381 for p in self.outports:
387 def popup(self,canvasView):
389 caption = QLabel( "<font color=darkblue><u><b>Node Menu</b></u></font>",menu )
390 caption.setAlignment( Qt.AlignCenter )
391 menu.insertItem( caption )
392 menu.insertItem("Browse", self.browse)
395 def tooltip(self,view,pos):
396 r = QRect(self.x(), self.y(), self.width(), self.height())
397 s = QString( "node: %d,%d" % (r.center().x(), r.center().y()) )
406 if __name__=='__main__':
407 app=QApplication(sys.argv)
409 QToolBar(box,"toolbar")
410 canvas=QCanvas(800,600)
411 canvas.setAdvancePeriod(30)
412 m=GraphViewer(canvas,box,"example",0)
413 box.setCentralWidget(m)
420 c1.outports[0].link(c2.inports[0])
422 qApp.setMainWidget(box)