示例#1
0
class NodeList(QtModule.QWidget):
    #
    # __init__
    #
    def __init__(self, parent):
        #
        QtModule.QWidget.__init__(self, parent)
        #
        # Define signals for PyQt5
        #
        if usePySide or usePyQt5:
            #
            self.setActiveNodeList = Signal()
            self.addNode = Signal()
            #
        self.nodesLib = ''
        self.nodesDir = ''
        # This is always the same
        self.ui = Ui_nodeList()
        self.ui.setupUi(self)
        self.ui.treeView.setDragEnabled(True)
        #self.ui.treeView.setRootIsDecorated( True )
        self.connectSignals()
        self.updateGui()

    #
    # connectSignals
    #
    def connectSignals(self):
        #
        if usePyQt4:
            QtCore.QObject.connect(self.ui.treeView,
                                   QtCore.SIGNAL("pressed(QModelIndex)"),
                                   self.clicked)
            QtCore.QObject.connect(self.ui.treeView,
                                   QtCore.SIGNAL("doubleClicked(QModelIndex)"),
                                   self.doubleClicked)
        else:
            self.ui.treeView.pressed.connect(self.clicked)
            self.ui.treeView.doubleClicked.connect(self.doubleClicked)

    #
    # updateGui
    #
    def updateGui(self):
        #
        if self.nodesLib != '':
            # self.ui.treeView.setupModel( self.nodesLib.model )

            self.ui.treeView.reset()
            self.ui.treeView.setModel(self.nodesLib.model)

            self.ui.infoText.clear()
            #self.ui.infoText.setText( "<i>Node:</i><br /><i>Author:</i><br />" )

    #
    # setLibrary
    #
    def setLibrary(self, dirName):
        #
        self.nodesDir = dirName
        self.nodesLib = NodeLibrary(dirName)
        self.updateGui()

    #
    # reloadLibrary
    #
    def reloadLibrary(self):
        #
        print '>> NodeList: reloadLibrary'
        self.nodesLib = NodeLibrary(self.nodesDir)
        self.updateGui()

    #
    # clicked
    #
    def clicked(self, index):
        #
        print ">> NodeList::clicked "
        item = self.nodesLib.model.itemFromIndex(index)
        self.showDescription(item)
        #
        # send signal to MainWindow to help distinguish which nodeList
        # is active for addNode getNode events
        #
        print ">> NodeList::emit setActiveNodeList"
        if usePyQt4:
            self.emit(QtCore.SIGNAL("setActiveNodeList"), self)
        else:
            self.setActiveNodeList.emit(self)

    #
    # doubleClicked
    #
    def doubleClicked(self, index):
        #
        print ">> NodeList::doubleClicked "
        item = self.nodesLib.model.itemFromIndex(index)
        nodeKind = item.whatsThis()

        if nodeKind != 'folder':
            if usePyQt4:
                nodeFilename = item.data(QtCore.Qt.UserRole + 4).toString()
            else:
                nodeFilename = item.data(QtCore.Qt.UserRole + 4)

            print ">> NodeList::emit addNode"
            if usePyQt4:
                self.emit(QtCore.SIGNAL('addNode'), nodeFilename)
            else:
                self.addNode.emit(nodeFilename)

    #
    # showDescription
    #
    def showDescription(self, item):
        #
        print ">> NodeList::showDescription "
        import os

        nodeName = item.text()
        nodeKind = item.whatsThis()
        if usePyQt4:
            nodeAuthor = item.data(QtCore.Qt.UserRole + 1).toString()
            nodeType = item.data(QtCore.Qt.UserRole + 2).toString()
            nodeHelp = item.data(QtCore.Qt.UserRole + 3).toString()
            nodeFilename = item.data(QtCore.Qt.UserRole + 4).toString()
            nodeIcon = item.data(QtCore.Qt.UserRole + 5).toString()
        else:
            nodeAuthor = item.data(QtCore.Qt.UserRole + 1)
            nodeType = item.data(QtCore.Qt.UserRole + 2)
            nodeHelp = item.data(QtCore.Qt.UserRole + 3)
            nodeFilename = item.data(QtCore.Qt.UserRole + 4)
            nodeIcon = item.data(QtCore.Qt.UserRole + 5)

        self.ui.infoText.clear()

        description = ''

        if nodeKind != 'folder':
            if nodeIcon != '':
                iconFileName = os.path.join(os.path.dirname(str(nodeFilename)),
                                            str(nodeIcon))
                print str(iconFileName)
                description += '<img src="' + iconFileName + '" />'  # width="128" height="128"

            description += "<table>"
            #description += "<tr>"
            #description += "<td align=right>name:</td>"
            #description += "<td><b>" + nodeName + "</b></td>"
            #description += "</tr>"
            #description += "<tr>"
            #description += "<td align=right>type:</td>"
            #description += "<td><b>" + nodeType +"</b></td>"
            #description += "</tr>"
            #description += "<tr>"
            #description += "<td align=right>filename:</td>"
            #description += "<td>" + nodeFilename +"</td>"
            #description += "</tr>"
            description += "<tr>"
            description += "<td align=left>author:</td>"
            description += "<td><i>" + nodeAuthor + "</i></td>"
            description += "</tr>"
            description += "</table><br />"

            description += "<br />" + nodeHelp + "</b><br />"

            self.ui.infoText.setText(description)
示例#2
0
class ImageView(QtModule.QGraphicsView):
    #
    # __init__
    #
    def __init__(self, parent):
        #
        QtModule.QGraphicsView.__init__(self, parent)
        #
        # Define signals for PyQt5
        #
        if usePySide or usePyQt5:
            #
            self.mouseDoubleClickSignal = Signal()
            #
        self.state = 'idle'
        self.panStartPos = None

        self.pixmap = None

        # set scene
        scene = QtModule.QGraphicsScene(self)

        scene.setSceneRect(0, 0, 256, 256)
        #scene.setItemIndexMethod ( QtGui.QGraphicsScene.NoIndex )
        self.setScene(scene)

        # qt graphics stuff
        #self.setCacheMode ( QtGui.QGraphicsView.CacheBackground )
        self.setRenderHint(QtGui.QPainter.Antialiasing)

        self.setTransformationAnchor(QtModule.QGraphicsView.AnchorUnderMouse)
        self.setResizeAnchor(QtModule.QGraphicsView.AnchorViewCenter)
        self.setDragMode(QtModule.QGraphicsView.RubberBandDrag)

        self.setMouseTracking(False)

        self.BgBrush = QtGui.QBrush(QtGui.QColor(128, 128, 128))

    #
    # keyPressEvent
    #
    def keyPressEvent(self, event):
        #
        print ">> ImageView.keyPressEvent"
        QtModule.QGraphicsView.keyPressEvent(self, event)

    #
    # wheelEvent
    #
    def wheelEvent(self, event):
        #
        #print ">> ImageView.wheelEvent"
        # QtGui.QGraphicsView.wheelEvent( self, event)
        import sys
        scale = -1.0
        if 'linux' in sys.platform: scale = 1.0
        import math
        if not usePyQt5:
            scaleFactor = math.pow(2.0, scale * event.delta() / 600.0)
        else:
            delta = event.angleDelta()
            #print ( '>> delta rx = %d ry = %d' % ( delta.x (), delta.y () ) )
            scaleFactor = math.pow(2.0, scale * delta.y() / 600.0)
        # self.matrix () is depicated
        factor = self.transform().scale(scaleFactor, scaleFactor).mapRect(
            QtCore.QRectF(-1, -1, 2, 2)).width()
        if factor < 0.07 or factor > 100: return
        self.scale(scaleFactor, scaleFactor)

    #
    # mousePressEvent
    #
    def mousePressEvent(self, event):
        #
        #print ">> ImageView.mousePressEvent"
        if (event.button() == QtCore.Qt.MidButton
                or (event.button() == QtCore.Qt.LeftButton
                    and event.modifiers() == QtCore.Qt.ShiftModifier)):
            if self.state == 'idle':
                self.panStartPos = self.mapToScene(event.pos())
                self.state = 'pan'
                return
        QtModule.QGraphicsView.mousePressEvent(self, event)

    #
    # mouseDoubleClickEvent
    #
    def mouseDoubleClickEvent(self, event):
        #
        #print ">> ImageView.mouseDoubleClickEvent"
        if usePyQt4:
            self.emit(QtCore.SIGNAL('mouseDoubleClickSignal'))
        else:
            self.mouseDoubleClickSignal.emit()
        QtModule.QGraphicsView.mouseDoubleClickEvent(self, event)

    #
    # mouseMoveEvent
    #
    def mouseMoveEvent(self, event):
        #
        #print ">> ImageView.mouseMoveEvent"
        if self.state == 'pan':
            panCurrentPos = self.mapToScene(event.pos())
            panDeltaPos = panCurrentPos - self.panStartPos
            # update view matrix
            self.setInteractive(False)
            self.translate(panDeltaPos.x(), panDeltaPos.y())
            self.setInteractive(True)
        else:
            QtModule.QGraphicsView.mouseMoveEvent(self, event)

    #
    # mouseReleaseEvent
    #
    def mouseReleaseEvent(self, event):
        #
        #print ">> ImageView.mouseReleaseEvent"
        if self.state == 'pan':
            self.state = 'idle'
            self.panStartPos = None
        QtModule.QGraphicsView.mouseReleaseEvent(self, event)

    #
    # viewportEvent
    #
    def viewportEvent(self, event):
        #case QEvent::TouchBegin:
        # case QEvent::TouchUpdate:
        # case QEvent::TouchEnd:
        if event.type() == QtCore.QEvent.TouchBegin:
            print(">> ImageView: QEvent.TouchBegin")
        return QtModule.QGraphicsView.viewportEvent(self, event)

    #
    # setImage
    #
    def setImage(self, imageName):
        #
        self.pixmap = QtGui.QPixmap()
        wi = 256
        hi = 256

        if imageName != '':
            print(">> ImageView.setImage name = %s" % imageName)

            imageReader = QtGui.QImageReader(imageName)

            if imageReader.canRead():
                image = imageReader.read()
                if not self.pixmap.convertFromImage(image):
                    print("!! QPixmap can't convert %s" % imageName)
            else:
                print("!! QImageReader can't read %s..." % imageName)
                # print imageReader.supportedImageFormats ()
                print("!! Lets try PIL module ...")
                import Image
                image = Image.open(imageName)
                # image.verify()

                import os
                from global_vars import app_global_vars

                tmpname = app_global_vars['TempPath'] + '/' + os.path.basename(
                    imageName + '.png')
                print("** Save %s ..." % tmpname)
                image.save(tmpname)

                self.pixmap = QtGui.QPixmap(tmpname)

        if not self.pixmap.isNull():
            wi = self.pixmap.width()
            hi = self.pixmap.height()
        else:
            print("!! ImageView: isNull()")

        self.scene().setSceneRect(0, 0, wi, hi)
        self.scene().update()

    #
    # drawBackground
    #
    def drawBackground(self, painter, rect):
        #
        painter.setRenderHint(QtGui.QPainter.Antialiasing)
        painter.setRenderHint(QtGui.QPainter.SmoothPixmapTransform)
        painter.fillRect(rect, self.BgBrush)
        if self.pixmap is not None:
            painter.drawPixmap(0, 0, self.pixmap)

    #
    # resetZoom
    #
    def resetZoom(self):
        #
        self.setInteractive(False)
        self.resetTransform()
        self.setInteractive(True)
class NodePropertiesEditor(QtModule.QWidget):
    #
    # __init__
    #
    def __init__(self, parent, editNode=None):
        #
        QtModule.QWidget.__init__(self, parent)
        #
        # Define signals for PyQt5
        #
        if usePySide or usePyQt5:
            #
            self.changeNodeLabel = Signal()
            #
        self.editNode = editNode

        # self.debugPrint()
        self.buildGui()
        self.setNode(editNode)
        #
        # buildGui
        #

    def buildGui(self):
        # build the gui created with QtDesigner
        self.ui = Ui_NodePropertiesEditor()
        self.ui.setupUi(self)
        #
        # setNode
        #

    def setNode(self, editNode):
        #
        self.disconnectSignals()
        self.editNode = editNode

        if self.editNode is not None:
            #
            name = self.editNode.name
            if self.editNode.name is None:
                name = ""
            self.ui.name_lineEdit.setText(name)

            label = self.editNode.label
            if self.editNode.label is None:
                label = ""
            self.ui.label_lineEdit.setText(label)

            author = self.editNode.author
            if self.editNode.author is None:
                author = ""
            self.ui.author_lineEdit.setText(author)

            master = self.editNode.master
            if self.editNode.master is None:
                master = ""
            self.ui.master_lineEdit.setText(master)

            icon = self.editNode.icon
            if self.editNode.icon is None:
                icon = ""
            self.ui.icon_lineEdit.setText(icon)
            # print '* self.editNode.help = %s' %  self.editNode.help

            doc = QtGui.QTextDocument()
            help_text = ""
            if self.editNode.help != None:
                help_text = self.editNode.help

            doc.setPlainText(help_text)
            layout = QtModule.QPlainTextDocumentLayout(doc)
            doc.setDocumentLayout(layout)

            self.ui.help_plainTextEdit.setDocument(doc)

            self.ui.id_lineEdit.setText(str(self.editNode.id))

            self.ui.type_comboBox.setEditable(False)
            self.ui.type_comboBox.setMinimumSize(QtCore.QSize(UI.COMBO_WIDTH, UI.COMBO_HEIGHT))
            self.ui.type_comboBox.setMaximumSize(QtCore.QSize(UI.MAX, UI.COMBO_HEIGHT))

            currentIdx = -1
            i = 0
            for label in VALID_NODE_TYPES:
                self.ui.type_comboBox.addItem(label)
                if label == self.editNode.type:
                    currentIdx = i
                i += 1

            self.ui.type_comboBox.setCurrentIndex(currentIdx)

            # temporary disabled, until "how to do it gracefully" will be clear ...
            self.ui.type_comboBox.setEnabled(False)

            self.connectSignals()
            #
            # connectSignals
            #

    def connectSignals(self):
        # QtCore.QObject.
        if usePyQt4:
            self.connect(self.ui.name_lineEdit, QtCore.SIGNAL("editingFinished()"), self.onEditNodeStrAttrName)
            self.connect(self.ui.label_lineEdit, QtCore.SIGNAL("editingFinished()"), self.onEditNodeStrAttrLabel)
            self.connect(self.ui.master_lineEdit, QtCore.SIGNAL("editingFinished()"), self.onEditNodeStrAttrMaster)
            self.connect(self.ui.author_lineEdit, QtCore.SIGNAL("editingFinished()"), self.onEditNodeStrAttrAuthor)
            self.connect(self.ui.icon_lineEdit, QtCore.SIGNAL("editingFinished()"), self.onEditNodeStrAttrIcon)
            self.connect(self.ui.type_comboBox, QtCore.SIGNAL("activated(int)"), self.onEditNodeType)
            self.connect(self.ui.help_plainTextEdit, QtCore.SIGNAL("textChanged()"), self.onEditNodeTxtAttr)
        else:
            self.ui.name_lineEdit.editingFinished.connect(self.onEditNodeStrAttrName)
            self.ui.label_lineEdit.editingFinished.connect(self.onEditNodeStrAttrLabel)
            self.ui.master_lineEdit.editingFinished.connect(self.onEditNodeStrAttrMaster)
            self.ui.author_lineEdit.editingFinished.connect(self.onEditNodeStrAttrAuthor)
            self.ui.icon_lineEdit.editingFinished.connect(self.onEditNodeStrAttrIcon)
            self.ui.type_comboBox.activated.connect(self.onEditNodeType)
            self.ui.help_plainTextEdit.textChanged.connect(self.onEditNodeTxtAttr)
            #
            # disconnectSignals
            #

    def disconnectSignals(self):
        #
        if usePyQt4:
            if self.editNode is not None:
                self.disconnect(self.ui.name_lineEdit, QtCore.SIGNAL("editingFinished()"), self.onEditNodeStrAttrName)
                self.disconnect(self.ui.label_lineEdit, QtCore.SIGNAL("editingFinished()"), self.onEditNodeStrAttrLabel)
                self.disconnect(
                    self.ui.master_lineEdit, QtCore.SIGNAL("editingFinished()"), self.onEditNodeStrAttrMaster
                )
                self.disconnect(
                    self.ui.author_lineEdit, QtCore.SIGNAL("editingFinished()"), self.onEditNodeStrAttrAuthor
                )
                self.disconnect(self.ui.icon_lineEdit, QtCore.SIGNAL("editingFinished()"), self.onEditNodeStrAttrIcon)
                self.disconnect(self.ui.type_comboBox, QtCore.SIGNAL("activated(int)"), self.onEditNodeType)
                self.disconnect(self.ui.help_plainTextEdit, QtCore.SIGNAL("textChanged()"), self.onEditNodeTxtAttr)
        else:
            if self.editNode is not None:
                self.ui.name_lineEdit.editingFinished.disconnect(self.onEditNodeStrAttrName)
                self.ui.label_lineEdit.editingFinished.disconnect(self.onEditNodeStrAttrLabel)
                self.ui.master_lineEdit.editingFinished.disconnect(self.onEditNodeStrAttrMaster)
                self.ui.author_lineEdit.editingFinished.disconnect(self.onEditNodeStrAttrAuthor)
                self.ui.icon_lineEdit.editingFinished.disconnect(self.onEditNodeStrAttrIcon)
                self.ui.type_comboBox.activated.disconnect(self.onEditNodeType)
                self.ui.help_plainTextEdit.textChanged.disconnect(self.onEditNodeTxtAttr)
                #
                #
                # doesn't work ...
                #

    def onEditNodeStrAttr(self, attr=None):
        #
        if attr is not None and self.editNode is not None:
            if attr == "name":
                self.editNode.name = str(self.ui.name_lineEdit.text())
            elif attr == "label":
                self.editNode.label = str(self.ui.label_lineEdit.text())
            elif attr == "master":
                self.editNode.master = str(self.ui.master_lineEdit.text())
            elif attr == "author":
                self.editNode.author = str(self.ui.author_lineEdit.text())
            elif attr == "icon":
                self.editNode.icon = str(self.ui.icon_lineEdit.text())
                #
                #
                #

    def onEditNodeStrAttrName(self):
        self.editNode.name = str(self.ui.name_lineEdit.text())

    def onEditNodeStrAttrLabel(self):
        #
        oldLabel = self.editNode.label
        newLabel = str(self.ui.label_lineEdit.text()).strip()
        if newLabel == "":
            if usePyQt4:
                self.disconnect(self.ui.label_lineEdit, QtCore.SIGNAL("editingFinished()"), self.onEditNodeStrAttrLabel)
            else:
                self.ui.label_lineEdit.editingFinished.disconnect(self.onEditNodeStrAttrLabel)
            newLabel = oldLabel
            self.ui.label_lineEdit.setText(newLabel)
            if usePyQt4:
                self.connect(self.ui.label_lineEdit, QtCore.SIGNAL("editingFinished()"), self.onEditNodeStrAttrLabel)
            else:
                self.ui.label_lineEdit.editingFinished.connect(self.onEditNodeStrAttrLabel)
        if newLabel != oldLabel:
            self.editNode.label = newLabel
            if usePyQt4:
                self.emit(QtCore.SIGNAL("changeNodeLabel"), oldLabel, newLabel)
            else:
                self.changeNodeLabel.emit(oldLabel, newLabel)
                #
                # onEditNodeStrAttrMaster
                #

    def onEditNodeStrAttrMaster(self):
        #
        self.editNode.master = str(self.ui.master_lineEdit.text())
        #
        # onEditNodeStrAttrAuthor
        #

    def onEditNodeStrAttrAuthor(self):
        #
        self.editNode.author = str(self.ui.author_lineEdit.text())
        #
        # onEditNodeStrAttrIcon
        #

    def onEditNodeStrAttrIcon(self):
        #
        self.editNode.icon = str(self.ui.icon_lineEdit.text())
        #
        # onEditNodeTxtAttr
        #

    def onEditNodeTxtAttr(self):
        #
        self.editNode.help = str(self.ui.help_plainTextEdit.toPlainText())
        #
        # onEditNodeType
        #

    def onEditNodeType(self, idx):
        #
        self.editNode.type = str(self.ui.type_comboBox.itemText(idx))
示例#4
0
class ImageView ( QtModule.QGraphicsView ) :
	#
	# __init__
	#
	def __init__ ( self, parent ) :
		#
		QtModule.QGraphicsView.__init__ ( self, parent )
		#
		# Define signals for PyQt5
		#
		if usePySide or usePyQt5 :
			#
			self.mouseDoubleClickSignal = Signal ()
			#
		self.state = 'idle' 
		self.panStartPos = None
		self.pixmap = None
		# set scene
		scene = QtModule.QGraphicsScene ( self )
		scene.setSceneRect ( 0, 0, 256, 256 )
		#scene.setItemIndexMethod ( QtGui.QGraphicsScene.NoIndex )
		self.setScene ( scene )
		# qt graphics stuff
		#self.setCacheMode ( QtGui.QGraphicsView.CacheBackground )
		self.setRenderHint ( QtGui.QPainter.Antialiasing )
		self.setTransformationAnchor ( QtModule.QGraphicsView.AnchorUnderMouse )
		self.setResizeAnchor ( QtModule.QGraphicsView.AnchorViewCenter )
		self.setDragMode ( QtModule.QGraphicsView.RubberBandDrag )
		self.setMouseTracking ( False )
		self.BgBrush = QtGui.QBrush ( QtGui.QColor ( 128, 128, 128 ) )  
	#
	# keyPressEvent
	#
	def keyPressEvent ( self, event ) : 
		#
		print ">> ImageView.keyPressEvent"
		QtModule.QGraphicsView.keyPressEvent ( self, event)
	#
	# wheelEvent
	#  
	def wheelEvent ( self, event ) :
		#
		#print ">> ImageView.wheelEvent"
		# QtGui.QGraphicsView.wheelEvent( self, event)
		import sys
		scale = -1.0
		if 'linux' in sys.platform: scale = 1.0     
		import math
		if  not usePyQt5 :
			scaleFactor = math.pow( 2.0, scale * event.delta() / 600.0 )
		else :
			delta = event.angleDelta ()
			#print ( '>> delta rx = %d ry = %d' % ( delta.x (), delta.y () ) )
			scaleFactor = math.pow( 2.0, scale * delta.y () / 600.0 )
		# self.matrix () is depicated
		factor = self.transform ().scale ( scaleFactor, scaleFactor ).mapRect ( QtCore.QRectF ( -1, -1, 2, 2 ) ).width ()
		if factor < 0.07 or factor > 100: return
		self.scale ( scaleFactor, scaleFactor )      
	#
	# mousePressEvent
	#
	def mousePressEvent ( self, event ) :
		#
		#print ">> ImageView.mousePressEvent"
		if ( event.button () == QtCore.Qt.MidButton or 
			 ( event.button () == QtCore.Qt.LeftButton and event.modifiers () == QtCore.Qt.ShiftModifier ) ) :  
			if self.state == 'idle':
				self.panStartPos = self.mapToScene ( event.pos () )
				self.state = 'pan'
				return
		QtModule.QGraphicsView.mousePressEvent ( self, event )        
	#
	# mouseDoubleClickEvent
	#
	def mouseDoubleClickEvent ( self, event ) :
		#
		#print ">> ImageView.mouseDoubleClickEvent"
		if usePyQt4 :
			self.emit ( QtCore.SIGNAL ( 'mouseDoubleClickSignal' ) )
		else :
			self.mouseDoubleClickSignal.emit ()
		QtModule.QGraphicsView.mouseDoubleClickEvent ( self, event )
	#
	# mouseMoveEvent
	#
	def mouseMoveEvent ( self, event ) :
		#
		#print ">> ImageView.mouseMoveEvent"
		if self.state == 'pan' :
			panCurrentPos = self.mapToScene ( event.pos () )
			panDeltaPos = panCurrentPos - self.panStartPos
			# update view matrix
			self.setInteractive ( False )
			self.translate ( panDeltaPos.x (), panDeltaPos.y () )        
			self.setInteractive ( True )  
		else :
			QtModule.QGraphicsView.mouseMoveEvent ( self, event )        
	#
	# mouseReleaseEvent
	#
	def mouseReleaseEvent ( self, event ):        
		#
		#print ">> ImageView.mouseReleaseEvent"
		if self.state == 'pan' :
			self.state = 'idle'  
			self.panStartPos = None
		QtModule.QGraphicsView.mouseReleaseEvent ( self, event )   
	#
	# viewportEvent
	#
	def viewportEvent ( self, event ) :
		#case QEvent::TouchBegin:
		# case QEvent::TouchUpdate:
		# case QEvent::TouchEnd:
		if event.type () == QtCore.QEvent.TouchBegin :
			print ">> ImageView: QEvent.TouchBegin"
		return QtModule.QGraphicsView.viewportEvent ( self, event )
	#
	# setImage
	#
	def setImage ( self, imageName ) :
		#
		self.pixmap = QtGui.QPixmap () 
		wi = 256
		hi = 256   

		if imageName != '' :
			print ">> ImageView.setImage name = %s" % imageName

			imageReader = QtGui.QImageReader ( imageName )

			if imageReader.canRead () :
				image = imageReader.read ()
				if not self.pixmap.convertFromImage ( image ) :
					print "!! QPixmap can't convert %s" % imageName  
			else:
				print "!! QImageReader can't read %s..." % imageName   
				# print imageReader.supportedImageFormats ()
				print "!! Lets try PIL module ..."
				import Image
				image = Image.open ( imageName )
				# image.verify()

				import os
				from global_vars import app_global_vars

				tmpname = app_global_vars [ 'TempPath' ] + '/' + os.path.basename ( imageName + '.png' )
				print "** Save %s ..." % tmpname 
				image.save ( tmpname )  

				self.pixmap = QtGui.QPixmap ( tmpname )

		if not self.pixmap.isNull ():
			wi = self.pixmap.width ()
			hi = self.pixmap.height () 
		else:
			print "!! ImageView: isNull()"  

		self.scene ().setSceneRect ( 0, 0, wi, hi )
		self.scene ().update ()
	#
	# drawBackground
	#
	def drawBackground ( self, painter, rect ) :
		#
		painter.setRenderHint ( QtGui.QPainter.Antialiasing )
		painter.setRenderHint ( QtGui.QPainter.SmoothPixmapTransform )
		painter.fillRect ( rect, self.BgBrush )
		if self.pixmap is not None:
			painter.drawPixmap ( 0, 0, self.pixmap )  
	#
	# resetZoom
	#
	def resetZoom ( self ) :
		#
		self.setInteractive ( False )
		self.resetTransform () 
		self.setInteractive ( True )          
示例#5
0
class ParamWidget ( QtModule.QWidget ) :
	#
	# __init__
	#
	def __init__ ( self, param, gfxNode, ignoreSubtype = False ) :
		#
		QtModule.QWidget.__init__ ( self )
		#
		# Define signals for PyQt5
		#
		if usePySide or usePyQt5 :
			#
			self.nodeParamRemoved = Signal ()
			#
		self.param = param
		self.gfxNode = gfxNode
		self.ignoreSubtype = ignoreSubtype # if widget is used in NodeEditor, then ignoreSubtype = True

		self.buildGeneralGui ()
		self.buildGui ()
		self.ui.updateGui ( self.param.value )
		#self.connectSignals ()
		#self.connect( self.param, QtCore.SIGNAL( 'paramChanged(QObject)' ), self.onParamChanged )
		#if DEBUG_MODE : print ">> ParamWidget (%s.%s)  __init__" % ( self.gfxNode.node.label, self.param.label )
	#
	#  __del__
	#
	def __del__ ( self ) :
		#
		if DEBUG_MODE : print ( '>> ParamWidget( %s ).__del__ ' % self.param.name )
	#
	# connectSignals
	#
	def connectSignals ( self ) :
		#
		pass
	#
	# setEnabled
	#
	def setEnabled ( self, enabled = True ) :
		#
		for hl in self.param_vl.children () :
			for i in range ( hl.count () ) :
				obj = hl.itemAt ( i ).widget ()
				if obj is not None :
					obj.setEnabled ( enabled )
	#
	# onParamChanged
	#
	def onParamChanged ( self, param ) :
		#
		if DEBUG_MODE : print ( ">> ParamWidget( %s ).onParamChanged" % param.name )
		self.ui.disconnectSignals ( self )
		self.ui.updateGui ( self.param.value )
		self.ui.connectSignals ( self )
		#self.emit ( QtCore.SIGNAL( 'onParamChanged(QObject)' ), param )
	#
	# buildGeneralGui
	#
	def buildGeneralGui ( self ) :
		#if DEBUG_MODE : print ">> ParamWidget buildGeneralGui"
		
		self.label_vl = QtModule.QVBoxLayout ()
		self.label_vl.setSpacing ( UI.SPACING )
		self.label_vl.setContentsMargins ( 0, 0, 0, 0 )
		self.label_vl.setAlignment ( QtCore.Qt.AlignTop | QtCore.Qt.AlignLeft )
		
		
		self.hl = QtModule.QHBoxLayout ()
		self.hl.setSpacing ( UI.SPACING )
		self.hl.setContentsMargins ( 0, 0, 0, 0 )
		self.hl.setAlignment ( QtCore.Qt.AlignTop | QtCore.Qt.AlignLeft )
		
		# vertical layout for parametrs values (e.g. output links or matrix rows)
		self.param_vl = QtModule.QVBoxLayout ()
		self.param_vl.setSpacing ( UI.SPACING )
		self.param_vl.setContentsMargins ( 0, 0, 0, 0 )
		self.param_vl.setAlignment ( QtCore.Qt.AlignTop | QtCore.Qt.AlignLeft )
		#
		# add 'isShaderParam' check box only for RSL nodes
		#
		if self.gfxNode is not None :
			#
			# add "Use as Shader parameter" checkbox
			#
			#if ( self.gfxNode.node.type in VALID_RSL_NODE_TYPES ) and ( self.param.type in VALID_RSL_PARAM_TYPES ) and ( self.param.provider != 'attribute' ) :
			if ( self.gfxNode.node.format == 'rsl' ) and \
				( self.param.type in VALID_RSL_PARAM_TYPES ) and \
				( self.param.provider != 'attribute' ) :
				self.check = QtModule.QCheckBox ( self )
				self.check.setMinimumSize ( QtCore.QSize ( UI.CHECK_WIDTH, UI.HEIGHT ) )
				self.check.setMaximumSize ( QtCore.QSize ( UI.CHECK_WIDTH, UI.HEIGHT ) )
				self.check.setToolTip ( 'Use as Shader parameter' )
				self.check.setChecked ( self.param.shaderParam )
				if  usePyQt4 :
					self.connect ( self.check, QtCore.SIGNAL ( 'stateChanged(int)' ), self.onShaderParamChanged )
				else :
					self.check.stateChanged.connect ( self.onShaderParamChanged )
				self.hl.addWidget ( self.check )
			else :
				spacer = QtModule.QSpacerItem ( UI.LT_SPACE, UI.HEIGHT, QtModule.QSizePolicy.Minimum, QtModule.QSizePolicy.Minimum )
				self.hl.addItem ( spacer )
			#
			# add 'remove' button for removable parameters
			#
			if self.param.removable :
				self.removeButton = QtModule.QToolButton ( self )
				sizePolicy = QtModule.QSizePolicy ( QtModule.QSizePolicy.Fixed, QtModule.QSizePolicy.Fixed )
				sizePolicy.setHorizontalStretch ( 20 )
				sizePolicy.setVerticalStretch ( 20 )
				sizePolicy.setHeightForWidth ( self.removeButton.sizePolicy().hasHeightForWidth() )
				self.removeButton.setSizePolicy ( sizePolicy )
				self.removeButton.setMaximumSize ( QtCore.QSize ( 20, 20 ) )
				icon = QtGui.QIcon ()
				icon.addPixmap ( QtGui.QPixmap ( ':/edit_icons/resources/del_list.png' ), QtGui.QIcon.Normal, QtGui.QIcon.On )
				self.removeButton.setIcon ( icon )
				self.removeButton.setAutoRaise ( True )
				self.removeButton.setToolTip ( 'Remove parameter' )
				self.removeButton.setIconSize ( QtCore.QSize ( 16, 16 ) )
				self.removeButton.setObjectName ( 'removeButton' )
				self.hl.addWidget ( self.removeButton )
				if usePyQt4 :
					QtCore.QObject.connect ( self.removeButton, QtCore.SIGNAL ( 'clicked()' ), self.onRemoveItem )
				else :
					self.removeButton.clicked.connect ( self.onRemoveItem )

		self.label = ParamLabel ( self, self.param )
		
		self.helpMark = QtModule.QLabel ( self )
		palette = QtGui.QPalette ()
		palette.setColor ( QtGui.QPalette.WindowText, QtGui.QColor ( 0, 140, 0 ) )
		font1 = QtGui.QFont ()
		font1.setBold ( True )
		self.helpMark.setPalette ( palette )
		self.helpMark.setFont ( font1 )
		self.helpMark.setText ( '' )
		
		self.helpMark.setMinimumSize ( QtCore.QSize ( 6, UI.HEIGHT ) )
		self.helpMark.setMaximumSize ( QtCore.QSize ( 6, UI.HEIGHT ) )
		
		self.helpMark.setEnabled ( False )
		
		if self.param.help is not None and self.param.help != '' :
			self.label.setWhatsThis ( self.param.help )
			self.helpMark.setWhatsThis ( self.param.help )
			self.helpMark.setText ( '?' )
			self.helpMark.setEnabled ( True )
		
		self.label.setAlignment ( QtCore.Qt.AlignLeading | QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter )
		#self.label.setMinimumSize ( QtCore.QSize ( UI.LABEL_WIDTH, UI.HEIGHT ) )
		#self.label.setMaximumSize ( QtCore.QSize ( UI.LABEL_WIDTH, UI.HEIGHT ) )
		
		#self.vl.addWidget ( self.gui )
		self.hl.addWidget ( self.label )
		self.hl.addWidget ( self.helpMark )
		#self.hl.addLayout ( self.param_vl )
		#sp = QtModule.QSpacerItem ( 20, 20, QtModule.QSizePolicy.Expanding, QtModule.QSizePolicy.Minimum )
		
		self.label_vl.addLayout ( self.hl )
		sp_v = QtModule.QSpacerItem ( 0, 0, QtModule.QSizePolicy.Minimum, QtModule.QSizePolicy.Expanding )
		self.label_vl.addItem ( sp_v )
		
	#
	# onShaderParamChanged
	#
	def onShaderParamChanged ( self, value ) :
		#
		self.param.shaderParam = self.check.isChecked ()
		self.gfxNode.updateGfxNodeParams ( True )
	#
	# buildGui -- virtual method
	# should be overriden in inherited classes
	#
	def buildGui ( self ) :
		#
		pass
		#spacer = QtModule.QSpacerItem ( 20, 20, QtModule.QSizePolicy.Expanding, QtModule.QSizePolicy.Minimum )
		#self.hl.addItem ( spacer )
	#
	# onRemoveItem
	#
	def onRemoveItem ( self ) : 
		#
		if DEBUG_MODE : print '>> ParamWidget( %s ).onRemoveItem ' % self.param.name
		if usePyQt4 :   
			self.emit ( QtCore.SIGNAL ( 'nodeParamRemoved' ), self.param ) 
		else :
			self.nodeParamRemoved.emit ( self.param ) 
示例#6
0
class meRendererSetup ( QtModule.QDialog ) :
	#
	# __init__
	#
	def __init__ ( self, rendererPreset ) :
		#
		QtModule.QDialog.__init__ ( self )
		#
		# Define signals for PyQt5
		#
		if usePySide or usePyQt5 :
			#
			self.presetChanged = Signal ()
			self.savePreset = Signal ()
			#
		self.rendererPreset = rendererPreset
		self.labelsReady = False
		self.buildGui ()
	#
	# buildGui
	#
	def buildGui ( self ) :
		# build the gui created with QtDesigner
		import sys
		self.ui = Ui_meRendererSetup ()
		self.ui.setupUi ( self )
		
		font = QtGui.QFont ()
		if ( sys.platform == 'win32' ) :
			# Runing on windows, override font sizes from Designer to default 
			font.setPointSize ( 8 )
		else :
			font.setPointSize ( 10 )
		self.ui.labelPreset.setFont ( font )
		self.ui.listPreset.setFont ( font )
		self.ui.newButton.setFont ( font )
		self.ui.deleteButton.setFont ( font )
		self.ui.cancelButton.setFont ( font )
		self.ui.okButton.setFont ( font )
		self.ui.saveButton.setFont ( font )
		self.ui.tabs.setFont ( font )
		self.ui.labelName.setFont ( font )
		self.ui.labelCmd.setFont ( font )
		self.ui.labelFlags.setFont ( font )
		self.ui.labelCompiler.setFont ( font )
		self.ui.labelShaderInfo.setFont ( font )
		self.ui.labelDefines.setFont ( font )
		self.ui.labelShaderExt.setFont ( font )
		self.ui.labelShaderExt.setFont ( font )
		self.ui.labelTexMake.setFont ( font )
		self.ui.labelTexInfo.setFont ( font )
		self.ui.labelTexViewer.setFont ( font )
		self.ui.labelTexExt.setFont ( font )

		self.labelsReady = False

		for label in self.rendererPreset.getPresetNames () :
			self.ui.listPreset.addItem ( label )
		
		self.labelsReady = True
		
		presetName = self.rendererPreset.getCurrentPresetName ()
		idx = self.ui.listPreset.findText ( presetName ) 
		print ">> buildGui:: set current renderer to: %s (%d)" % ( presetName, idx )
		#self.ui.listPreset.setCurrentIndex ( -1 )
		self.ui.listPreset.setCurrentIndex ( idx ) 
	#
	# getDataFromGui
	# 
	def getDataFromGui ( self ) :
		# ckeck if current_renderer still exists after deleting preset
		#print ">> getDataFromGui:: current renderer to: %s" % self.rendererPreset.getCurrentPresetName() 
			
		self.rendererPreset.currentPreset.RendererName = str ( self.ui.lineCmd.text () )
		self.rendererPreset.currentPreset.RendererFlags = str ( self.ui.lineFlags.text () )
		self.rendererPreset.currentPreset.ShaderCompiler = str ( self.ui.lineCompiler.text () )
		self.rendererPreset.currentPreset.ShaderInfo = str ( self.ui.lineShaderInfo.text () )
		self.rendererPreset.currentPreset.ShaderDefines = str ( self.ui.lineDefines.text () )
		self.rendererPreset.currentPreset.ShaderExt = str ( self.ui.lineShaderExt.text () )
		self.rendererPreset.currentPreset.TextureMake = str ( self.ui.lineTexMake.text () )
		self.rendererPreset.currentPreset.TextureInfo = str ( self.ui.lineTexInfo.text () )
		self.rendererPreset.currentPreset.TextureViewer = str ( self.ui.lineTexViewer.text () )
		self.rendererPreset.currentPreset.TextureExt = str ( self.ui.lineTexExt.text () )
	#
	# onIndexChanged
	#    
	def onIndexChanged ( self, name ) : 
		if DEBUG_MODE : print ">> onIndexChanged:: nam = %s self.labelsReady == %d" % ( name, self.labelsReady )
		#if DEBUG_MODE : print self.ui.listPreset.currentText ()
		name = self.ui.listPreset.currentText ()
		if ( self.labelsReady and name != '' ) :
			# change current renderer
			self.rendererPreset.setCurrentPresetByName ( str ( name ) )
		self.updateGui ()
	#
	# updateGui
	#  
	def updateGui ( self ) :
		# redraw gui elements
		#print ">> updateGui:: current renderer: %s" % self.rendererPreset.getCurrentPresetName() 
		if len ( self.rendererPreset.presetsList ) > 0 :
			if self.rendererPreset.currentPreset is not None :
				self.ui.lineName.setText ( self.rendererPreset.getCurrentPresetName () )
				self.ui.lineCmd.setText ( self.rendererPreset.currentPreset.RendererName )
				self.ui.lineFlags.setText ( self.rendererPreset.currentPreset.RendererFlags )
				self.ui.lineCompiler.setText ( self.rendererPreset.currentPreset.ShaderCompiler )
				self.ui.lineShaderInfo.setText ( self.rendererPreset.currentPreset.ShaderInfo )
				self.ui.lineDefines.setText ( self.rendererPreset.currentPreset.ShaderDefines )
				self.ui.lineShaderExt.setText ( self.rendererPreset.currentPreset.ShaderExt )
				self.ui.lineTexMake.setText ( self.rendererPreset.currentPreset.TextureMake )
				self.ui.lineTexInfo.setText ( self.rendererPreset.currentPreset.TextureInfo )
				self.ui.lineTexViewer.setText ( self.rendererPreset.currentPreset.TextureViewer )
				self.ui.lineTexExt.setText ( self.rendererPreset.currentPreset.TextureExt )
				self.ui.deleteButton.setEnabled ( True )
				self.ui.tab1.setEnabled ( True )
				self.ui.tab2.setEnabled ( True)
				self.ui.tab3.setEnabled ( True )
		else :
			self.ui.deleteButton.setEnabled ( False )
			self.ui.tab1.setEnabled ( False )
			self.ui.tab2.setEnabled ( False )
			self.ui.tab3.setEnabled ( False )
			self.ui.lineName.clear ()
			self.ui.lineCmd.clear ()
			self.ui.lineFlags.clear ()
			self.ui.lineCompiler.clear ()
			self.ui.lineShaderInfo.clear ()
			self.ui.lineDefines.clear ()
			self.ui.lineShaderExt.clear ()
			self.ui.lineTexMake.clear ()
			self.ui.lineTexInfo.clear ()
			self.ui.lineTexViewer.clear ()
			self.ui.lineTexExt.clear ()
	#
	# onNewPreset
	#
	def onNewPreset ( self ) :
		# create new empty preset
		title = 'Untitled' 
		newLabel = title
		#self.labelsReady = False
		i = 0
		while True :
			if newLabel in self.rendererPreset.getPresetNames () :
				newLabel = title + str ( i )
				i += 1
				continue
			else :
				break;
		self.rendererPreset.addPreset ( newLabel )
		#self.labelsReady = True
		self.ui.listPreset.addItem ( newLabel ) 
		idx = self.ui.listPreset.findText ( newLabel )
		self.ui.listPreset.setCurrentIndex ( -1 )
		self.ui.listPreset.setCurrentIndex ( idx ) 
		#self.updateGui ()
	#  
	# onDeletePreset
	#  
	def onDeletePreset ( self ) :
		# delete existing preset
		if len ( self.rendererPreset.presetsList ) > 0 :
			msgBox = QtModule.QMessageBox ()
			ret = msgBox.warning ( self, 'Warning', "Do you really want to delete this preset?", 
			QtGui.QMessageBox.Yes | QtGui.QMessageBox.No,  QtGui.QMessageBox.No )
			
			if ret ==  QtModule.QMessageBox.Yes :
				self.rendererPreset.deleteCurrentPreset ()
				i = self.ui.listPreset.currentIndex ()
				self.ui.listPreset.removeItem ( i )
				self.rendererPreset.setCurrentPresetByName ( str ( self.ui.listPreset.currentText () ) )
	#
	# onEditLabel
	#    
	def onEditLabel ( self ) :
		# edit label
		newLabel = str ( self.ui.lineName.text () )
		if ( self.rendererPreset.getCurrentPresetName () != newLabel ) :
			if newLabel not in self.rendererPreset.getPresetNames () :
				self.rendererPreset.renameCurrentPreset ( newLabel )
				# rename current preset ComboBox item to new label
				i = self.ui.listPreset.currentIndex ()
				self.ui.listPreset.setItemText ( i, newLabel )
			else :
				# this label already exists, so restore to previose
				self.ui.lineName.setText ( self.rendererPreset.getCurrentPresetName () )
	#
	# onSave
	#  
	def onSave ( self ) :
		# get data from Gui for current renderer before saving
		self.getDataFromGui ()
		if  usePyQt4 :
			self.emit ( QtCore.SIGNAL ( 'presetChanged' ) )
			self.emit ( QtCore.SIGNAL ( 'savePreset' ) )
		else :
			self.presetChanged.emit ()
			self.savePreset.emit ()
		#self.done ( 0 ) 
	#
	# onSelect
	#  
	def onSelect ( self ) :
		# get data from Gui for current renderer before saving
		self.getDataFromGui ()
		if  usePyQt4 :
			self.emit( QtCore.SIGNAL ( 'presetChanged' ) )
		else :
			self.presetChanged.emit ()
		self.done ( 0 ) 
示例#7
0
class NodeParamEditor ( QtModule.QWidget ) :
	#
	# __init__
	#
	def __init__ ( self, parent ) :
		#
		QtModule.QWidget.__init__ ( self, parent )
		#
		# Define signals for PyQt5
		#
		if usePySide or usePyQt5 :
			#
			self.changeParamName = Signal ()
			self.changeParamLabel = Signal ()
			self.changeParamIsShader = Signal ()
			self.changeParamType = Signal ()
			self.changeParamDetail = Signal ()
			self.changeParamProvider = Signal ()
			self.changeParamSubtype = Signal ()
			self.changeParamRange = Signal ()
			
			self.changeParamValue = Signal ()
			self.changeParamDefValue = Signal ()
		#
		self.param = None
		self.param_default = None
		self.paramWidgets = {	 'string'       : StringWidget
													,'image'        : StringWidget
													,'rib'          : StringWidget
													,'surface'      : StringWidget
													,'displacement' : StringWidget
													,'light'        : StringWidget
													,'volume'       : StringWidget
													,'float'        : FloatWidget
													,'int'          : IntWidget
													,'color'        : ColorWidget
													,'normal'       : NormalWidget
													,'transform'    : PointWidget
													,'point'        : PointWidget
													,'vector'       : VectorWidget
													,'matrix'       : MatrixWidget
													,'text'         : TextWidget
													,'control'      : ControlWidget
													,'shader'       : StringWidget
													,'geom'         : StringWidget
												}

		self.buildGui()
	#
	#
	def __delete__ ( self, obj ) :
		#
		print '* NodeParamEditor closed... %s' % str( obj )
	#
	# buildGui
	#
	def buildGui ( self ) :
		# build the gui created with QtDesigner
		self.ui = Ui_NodeParamEditor ( )
		self.ui.setupUi ( self )

		# correct UI sizes for some controls
		self.ui.check_enabled.setMinimumSize ( QtCore.QSize ( UI.CHECK_WIDTH, UI.HEIGHT ) )
		self.ui.check_enabled.setMaximumSize ( QtCore.QSize ( UI.CHECK_WIDTH, UI.HEIGHT ) )
		
		self.ui.check_display.setMinimumSize ( QtCore.QSize ( UI.CHECK_WIDTH, UI.HEIGHT ) )
		self.ui.check_display.setMaximumSize ( QtCore.QSize ( UI.CHECK_WIDTH, UI.HEIGHT ) )

		self.ui.check_shader.setMinimumSize ( QtCore.QSize ( UI.CHECK_WIDTH, UI.HEIGHT ) )
		self.ui.check_shader.setMaximumSize ( QtCore.QSize ( UI.CHECK_WIDTH, UI.HEIGHT ) )

		for label in VALID_PARAM_TYPES : self.ui.type_comboBox.addItem ( label )
		
		self.ui.type_comboBox.setCurrentIndex ( -1 )
		self.ui.type_comboBox.setMinimumSize ( QtCore.QSize ( UI.COMBO_WIDTH, UI.COMBO_HEIGHT ) )
		self.ui.type_comboBox.setMaximumSize ( QtCore.QSize( UI.MAX, UI.COMBO_HEIGHT ) )

		# temporary disabled, until "how to do it gracefully" will be clear ...
		self.ui.type_comboBox.setEnabled ( False )

		for label in [ 'None', 'uniform', 'varying', ]  :
			self.ui.detail_comboBox.addItem ( label )
		self.ui.detail_comboBox.setCurrentIndex ( -1 )
		self.ui.detail_comboBox.setMinimumSize ( QtCore.QSize ( UI.COMBO_WIDTH, UI.COMBO_HEIGHT ) )
		self.ui.detail_comboBox.setMaximumSize ( QtCore.QSize( UI.MAX, UI.COMBO_HEIGHT ) )

		for label in [ 'None', 'internal', 'external', 'primitive', 'attribute' ]  :
			self.ui.provider_comboBox.addItem ( label )
		self.ui.provider_comboBox.setCurrentIndex ( -1 )
		self.ui.provider_comboBox.setMinimumSize ( QtCore.QSize ( UI.COMBO_WIDTH, UI.COMBO_HEIGHT ) )
		self.ui.provider_comboBox.setMaximumSize ( QtCore.QSize( UI.MAX, UI.COMBO_HEIGHT ) )

		for label in [ 'None', 'slider', 'switch', 'selector', 'file', 'button' ]  :
			self.ui.subtype_comboBox.addItem ( label )
		self.ui.subtype_comboBox.setCurrentIndex ( -1 )
		self.ui.subtype_comboBox.setMinimumSize ( QtCore.QSize ( UI.COMBO_WIDTH, UI.COMBO_HEIGHT ) )
		self.ui.subtype_comboBox.setMaximumSize ( QtCore.QSize( UI.MAX, UI.COMBO_HEIGHT ) )
	#
	# As paramWidet is monitoring a change of param.value only,
	# we need to cynchronize changing of param_default.value with param.default
	#
	def onParamDefValueChanged ( self, param ) :
		#
		if DEBUG_MODE : print '* onParamDefValueChanged'
		self.param.default = self.param_default.value
		if  usePyQt4 :
			self.emit ( QtCore.SIGNAL ( 'changeParamDefValue' ), self.param )
		else :
			self.changeParamDefValue.emit ( self.param )
	#
	# onParamValueChanged
	#
	def onParamValueChanged ( self, param ) :
		#
		if DEBUG_MODE : print '* onParamValueChanged'
		self.param.value = param.value
		if  usePyQt4 :
			self.emit ( QtCore.SIGNAL ( 'changeParamValue' ), self.param )
		else :
			self.changeParamValue.emit ( self.param )
	#
	# connectSignals
	#
	def connectSignals ( self ) :
		#
		if  usePyQt4 :
			self.connect ( self.param_default, QtCore.SIGNAL ( 'paramChangedSignal(QObject)' ), self.onParamDefValueChanged )
			self.connect ( self.param, QtCore.SIGNAL ( 'paramChangedSignal(QObject)' ), self.onParamValueChanged )
			
			self.connect ( self.ui.name_lineEdit, QtCore.SIGNAL ( 'editingFinished()' ), self.onEditParamName )
			self.connect ( self.ui.label_lineEdit, QtCore.SIGNAL ( 'editingFinished()' ), self.onEditParamLabel )
			self.connect ( self.ui.check_enabled, QtCore.SIGNAL ( 'stateChanged(int)' ), self.onEditParamEnabled )
			self.connect ( self.ui.check_display, QtCore.SIGNAL ( 'stateChanged(int)' ), self.onEditParamDisplay )
			self.connect ( self.ui.check_shader, QtCore.SIGNAL ( 'stateChanged(int)' ), self.onEditParamShader )
			self.connect ( self.ui.type_comboBox, QtCore.SIGNAL ( 'activated(int)' ), self.onEditParamType )
			self.connect ( self.ui.detail_comboBox, QtCore.SIGNAL ( 'activated(int)' ), self.onEditParamDetail )
			self.connect ( self.ui.provider_comboBox, QtCore.SIGNAL ( 'activated(int)' ), self.onEditParamProvider )
			self.connect ( self.ui.subtype_comboBox, QtCore.SIGNAL ( 'activated(int)' ), self.onEditParamSubtype )
			self.connect ( self.ui.range_lineEdit, QtCore.SIGNAL ( 'editingFinished()' ), self.onEditParamRange )
			self.connect ( self.ui.descr_plainTextEdit, QtCore.SIGNAL ( 'textChanged()' ), self.onEditParamHelp )
		else :
			self.param_default.paramChangedSignal.connect ( self.onParamDefValueChanged )
			self.param.paramChangedSignal.connect ( self.onParamValueChanged )
			
			self.ui.name_lineEdit.editingFinished.connect ( self.onEditParamName )
			self.ui.label_lineEdit.editingFinished.connect ( self.onEditParamLabel )
			self.ui.check_enabled.stateChanged.connect ( self.onEditParamEnabled )
			self.ui.check_display.stateChanged.connect ( self.onEditParamDisplay )
			self.ui.check_shader.stateChanged.connect ( self.onEditParamShader )
			self.ui.type_comboBox.activated.connect ( self.onEditParamType )
			self.ui.detail_comboBox.activated.connect ( self.onEditParamDetail )
			self.ui.provider_comboBox.activated.connect ( self.onEditParamProvider )
			self.ui.subtype_comboBox.activated.connect ( self.onEditParamSubtype )
			self.ui.range_lineEdit.editingFinished.connect ( self.onEditParamRange )
			self.ui.descr_plainTextEdit.textChanged.connect ( self.onEditParamHelp )
	#
	# disconnectSignals
	#
	def disconnectSignals ( self ) :
		#
		if  usePyQt4 :
			if self.param_default is not None :
				self.disconnect ( self.param_default, QtCore.SIGNAL ( 'paramChangedSignal(QObject)' ), self.onParamDefValueChanged )
			if self.param is not None :
				self.disconnect ( self.param, QtCore.SIGNAL ( 'paramChangedSignal(QObject)' ), self.onParamValueChanged )
				
				self.disconnect ( self.ui.name_lineEdit, QtCore.SIGNAL ( 'editingFinished()' ), self.onEditParamName )
				self.disconnect ( self.ui.label_lineEdit, QtCore.SIGNAL ( 'editingFinished()' ), self.onEditParamLabel )
				self.disconnect ( self.ui.check_enabled, QtCore.SIGNAL ( 'stateChanged(int)' ), self.onEditParamEnabled )
				self.disconnect ( self.ui.check_display, QtCore.SIGNAL ( 'stateChanged(int)' ), self.onEditParamDisplay )
				self.disconnect ( self.ui.check_shader, QtCore.SIGNAL ( 'stateChanged(int)' ), self.onEditParamShader )
				self.disconnect ( self.ui.type_comboBox, QtCore.SIGNAL ( 'activated(int)' ), self.onEditParamType )
				self.disconnect ( self.ui.detail_comboBox, QtCore.SIGNAL ( 'activated(int)' ), self.onEditParamDetail )
				self.disconnect ( self.ui.provider_comboBox, QtCore.SIGNAL ( 'activated(int)' ), self.onEditParamProvider )
				self.disconnect ( self.ui.subtype_comboBox, QtCore.SIGNAL ( 'activated(int)' ), self.onEditParamSubtype )
				self.disconnect ( self.ui.descr_plainTextEdit, QtCore.SIGNAL ( 'textChanged()' ), self.onEditParamHelp )
		else :
			if self.param_default is not None :
				self.param_default.paramChangedSignal.disconnect ( self.onParamDefValueChanged )
			if self.param is not None :
				self.param.paramChangedSignal.disconnect ( self.onParamValueChanged )
				
				self.ui.name_lineEdit.editingFinished.disconnect ( self.onEditParamName )
				self.ui.label_lineEdit.editingFinished.disconnect ( self.onEditParamLabel )
				self.ui.check_enabled.stateChanged.disconnect ( self.onEditParamEnabled )
				self.ui.check_display.stateChanged.disconnect ( self.onEditParamDisplay )
				self.ui.check_shader.stateChanged.disconnect ( self.onEditParamShader )
				self.ui.type_comboBox.activated.disconnect ( self.onEditParamType )
				self.ui.detail_comboBox.activated.disconnect ( self.onEditParamDetail )
				self.ui.provider_comboBox.activated.disconnect ( self.onEditParamProvider )
				self.ui.subtype_comboBox.activated.disconnect ( self.onEditParamSubtype )
				self.ui.range_lineEdit.editingFinished.disconnect ( self.onEditParamRange )
				self.ui.descr_plainTextEdit.textChanged.disconnect ( self.onEditParamHelp )
	#
	# reset
	#
	def reset ( self ) :
		#
		self.ui.name_lineEdit.setText ( '' )
		self.ui.label_lineEdit.setText ( '' )
		
		self.ui.check_enabled.setChecked ( True )
		self.ui.check_display.setChecked ( True )
		self.ui.check_shader.setChecked ( False )

		self.ui.type_comboBox.setCurrentIndex( -1 )
		self.ui.detail_comboBox.setCurrentIndex ( -1 )
		self.ui.provider_comboBox.setCurrentIndex ( -1 )
		self.ui.subtype_comboBox.setCurrentIndex ( -1 )
		self.ui.range_lineEdit.setText ( '' )

		doc = QtGui.QTextDocument ()
		doc.setPlainText ( '' )
		layout = QtModule.QPlainTextDocumentLayout ( doc )
		doc.setDocumentLayout ( layout )
		self.ui.descr_plainTextEdit.setDocument ( doc )
	#
	# Remove stackedWidget's layout every time,
	# when current parameter (or it's type) is changing
	#
	def removeValueWidget ( self ) :
		#
		while True :
			currentWidget = self.ui.value_stackedWidget.currentWidget ()
			if currentWidget is not None :
				#print '> removeWidget: %s' % str( currentWidget )
				self.ui.value_stackedWidget.removeWidget ( currentWidget )
			else :
				break
	#
	# setParam
	#
	def setParam ( self, param ) :
		#
		self.removeValueWidget()
		self.disconnectSignals()
		self.param = param
		
		if self.param is not None :
			#import copy
			self.param_default = self.param.copy() # duplicate param for default value editing
			self.param_default.value = param.default

			self.ui.name_lineEdit.setText ( self.param.name )
			self.ui.label_lineEdit.setText ( self.param.label )
			
			self.ui.check_enabled.setChecked ( self.param.enabled )
			self.ui.check_display.setChecked ( self.param.display )
			self.ui.check_shader.setChecked ( self.param.shaderParam )

			self.ui.type_comboBox.setCurrentIndex ( self.ui.type_comboBox.findText ( self.param.type ) )
			self.ui.detail_comboBox.setCurrentIndex ( self.ui.detail_comboBox.findText ( self.param.detail ) )
			self.ui.provider_comboBox.setCurrentIndex ( self.ui.provider_comboBox.findText ( self.param.provider ) )
			self.ui.subtype_comboBox.setCurrentIndex ( self.ui.subtype_comboBox.findText ( self.param.subtype ) )
			self.ui.range_lineEdit.setText ( self.param.range )

			doc = QtGui.QTextDocument ()
			help_text = ''
			if self.param.help != None : help_text = self.param.help

			doc.setPlainText ( help_text )
			layout = QtModule.QPlainTextDocumentLayout ( doc )
			doc.setDocumentLayout( layout )

			self.ui.descr_plainTextEdit.setDocument ( doc )
			#
			# setup param values view
			#
			paramsLayout = QtModule.QGridLayout ()
			paramsLayout.setContentsMargins ( 2, 2, 2, 2 )
			paramsLayout.setSizeConstraint ( QtModule.QLayout.SetNoConstraint )
			paramsLayout.setVerticalSpacing ( 4 )
			paramsLayout.setColumnStretch ( 1, 1 )
			paramsLayout.setRowStretch ( 2, 1 )
			
			frame = QtModule.QFrame ()
			frame.setLayout ( paramsLayout )

			if self.param.type in self.paramWidgets.keys () :
				print '>> Create %s param widget' % self.param.type

				# create paramWidget without GfxNode and ignoreSubtype = True
				self.ui.value_widget = apply ( self.paramWidgets [ self.param.type ], [ self.param, None, True ] )
				self.ui.value_widget.label.setText ( 'Current Value' )
				
				paramsLayout.addLayout ( self.ui.value_widget.label_vl, 0, 0, 1, 1 )
				paramsLayout.addLayout ( self.ui.value_widget.param_vl, 0, 1, 1, 1 )
				
				self.ui.def_value_widget = apply ( self.paramWidgets [ self.param_default.type ], [ self.param_default, None, True ] )
				self.ui.def_value_widget.label.setText ( 'Default Value' )

				paramsLayout.addLayout ( self.ui.def_value_widget.label_vl, 1, 0, 1, 1 )
				paramsLayout.addLayout ( self.ui.def_value_widget.param_vl, 1, 1, 1, 1 )
				
				spacer = QtModule.QSpacerItem ( 20, 20, QtModule.QSizePolicy.Minimum, QtModule.QSizePolicy.Expanding )
				paramsLayout.addItem ( spacer, 2, 0, 1, 1 ) 

			self.ui.value_stackedWidget.addWidget ( frame )
			self.connectSignals ()
		else :
			self.reset ()
	#
	# onEditParamName
	#
	def onEditParamName ( self ) :
		#
		# !!! ListWidget item for param also should be changed
		#
		oldName = self.param.name
		newName = str ( self.ui.name_lineEdit.text () ).strip ()
		if newName == '' :
			newName = oldName
			self.ui.name_lineEdit.setText ( newName )
		if newName != oldName :
			self.param.name = newName
			if  usePyQt4 :
				self.emit( QtCore.SIGNAL ( 'changeParamName' ), oldName, newName )
			else :
				self.changeParamName.emit ( oldName, newName )
	#
	# onEditParamLabel
	#
	def onEditParamLabel ( self ) :
		#
		oldName = self.param.label
		newName  = str ( self.ui.label_lineEdit.text () ).strip ()
		if newName == '' :
			newName = oldName
			self.ui.label_lineEdit.setText ( newName )
		if newName != oldName :
			self.param.label = newName
			if  usePyQt4 :
				self.emit ( QtCore.SIGNAL ( 'changeParamLabel' ), oldName, newName )
			else :
				self.changeParamLabel.emit ( oldName, newName )
	#
	# onEditParamEnabled
	#
	def onEditParamEnabled ( self, value ) : 
		#
		self.param.enabled = self.ui.check_enabled.isChecked ()
	#
	# onEditParamEnabled
	#
	def onEditParamDisplay ( self, value ) : 
		#
		self.param.display = self.ui.check_display.isChecked ()
	#
	# onEditParamShader
	#
	def onEditParamShader ( self, value )  : 
		#
		self.param.shaderParam = self.ui.check_shader.isChecked ()
		if  usePyQt4 :
			self.emit ( QtCore.SIGNAL ( 'changeParamIsShader' ), self.param )
		else :
			self.changeParamIsShader.emit ( self.param )
	#
	# onEditParamType
	#	
	def onEditParamType ( self, idx ) :
		#
		# !!! UI for param.value and param.default also should be changed
		#
		self.param.type = str ( self.ui.type_comboBox.itemText ( idx ) )
		if  usePyQt4 :
			self.emit ( QtCore.SIGNAL ( 'changeParamType' ), self.param )
		else :
			self.changeParamType.emit ( self.param )
	#
	# onEditParamDetail
	#	
	def onEditParamDetail ( self, idx ) :
		#
		self.param.detail = str ( self.ui.detail_comboBox.itemText ( idx ) )
		if  usePyQt4 :
			self.emit ( QtCore.SIGNAL ( 'changeParamDetail' ), self.param )
		else :
			self.changeParamDetail.emit ( self.param )
	#
	# onEditParamProvider
	#		
	def onEditParamProvider ( self, idx ) : 
		#
		self.param.provider = str ( self.ui.provider_comboBox.itemText ( idx ) )
		if  usePyQt4 :
			self.emit ( QtCore.SIGNAL ( 'changeParamProvider' ), self.param )
		else :
			self.changeParamProvider.emit ( self.param )
	#
	# onEditParamSubtype
	#		
	def onEditParamSubtype ( self, idx ) : 
		#
		self.param.subtype = str ( self.ui.subtype_comboBox.itemText ( idx ) )
		if  usePyQt4 :
			self.emit ( QtCore.SIGNAL ( 'changeParamSubtype' ), self.param )
		else :
			self.changeParamSubtype.emit ( self.param )
	#
	# onEditParamRange
	#		
	def onEditParamRange ( self ) : 
		#
		self.param.range = str ( self.ui.range_lineEdit.text () )
		if  usePyQt4 :
			self.emit ( QtCore.SIGNAL ( 'changeParamRange' ), self.param )
		else :
			self.changeParamRange.emit ( self.param )
	#
	# onEditParamHelp
	#			
	def onEditParamHelp ( self ) : 
		#
		self.param.help = str ( self.ui.descr_plainTextEdit.toPlainText () )
示例#8
0
class NodeParamView(QtModule.QWidget):
    #
    # __init__
    #
    def __init__(self):
        #
        QtModule.QWidget.__init__(self)
        #
        # Define signals for PyQt5
        #
        if usePySide or usePyQt5:
            #
            self.nodeParamChangedSignal = Signal()
            self.nodeLabelChangedSignal = Signal()
            #
        self.gfxNode = None

        self.inputParamListTab = None
        self.outputParamListTab = None

        self.showConnected = False
        self.buildGui()
        self.updateGui()
        self.connectSignals()

    #
    # setNode
    #
    def setNode(self, gfxNode):
        #
        #if DEBUG_MODE : print ">> NodeParamView.setNode"
        self.disconnectParamSignals()
        self.gfxNode = gfxNode
        self.inputParamListTab.setNode(gfxNode)
        self.outputParamListTab.setNode(gfxNode)
        self.nameEdit.setEnabled(self.gfxNode is not None)
        self.updateGui()
        self.connectParamSignals()

    #
    # connectSignals
    #
    def connectSignals(self):
        #
        if usePyQt4:
            self.connect(self.nameEdit, QtCore.SIGNAL('editingFinished()'),
                         self.nodeLabelChanged)
            self.connect(self.showConnectButton,
                         QtCore.SIGNAL('toggled(bool)'), self.showConnections)
        else:
            self.nameEdit.editingFinished.connect(self.nodeLabelChanged)
            self.showConnectButton.toggled.connect(self.showConnections)

    #
    # disconnectSignals
    #
    def disconnectSignals(self):
        #
        if usePyQt4:
            self.disconnect(self.nameEdit, QtCore.SIGNAL('editingFinished()'),
                            self.nodeLabelChanged)
            self.disconnect(self.showConnectButton,
                            QtCore.SIGNAL('toggled(bool)'),
                            self.showConnections)
        else:
            self.nameEdit.editingFinished.disconnect(self.nodeLabelChanged)
            self.showConnectButton.toggled.disconnect(self.showConnections)

    #
    # connectParamSignals
    #
    def connectParamSignals(self):
        #print ">> NodeParamView.connectParamSignals"
        if self.gfxNode is not None:
            for inputParam in self.gfxNode.node.inputParams:
                if usePyQt4:
                    self.connect(inputParam,
                                 QtCore.SIGNAL('paramChangedSignal(QObject)'),
                                 self.onParamChanged)
                else:
                    inputParam.paramChangedSignal.connect(self.onParamChanged)
            for outputParam in self.gfxNode.node.outputParams:
                if usePyQt4:
                    self.connect(outputParam,
                                 QtCore.SIGNAL('paramChangedSignal(QObject)'),
                                 self.onParamChanged)
                else:
                    outputParam.paramChangedSignal.connect(self.onParamChanged)

    #
    # disconnectParamSignals
    #
    def disconnectParamSignals(self):
        #print ">> NodeParamView.disconnectParamSignals"
        if self.gfxNode is not None:
            for inputParam in self.gfxNode.node.inputParams:
                if usePyQt4:
                    self.disconnect(
                        inputParam,
                        QtCore.SIGNAL('paramChangedSignal(QObject)'),
                        self.onParamChanged)
                else:
                    inputParam.paramChangedSignal.disconnect(
                        self.onParamChanged)
            for outputParam in self.gfxNode.node.outputParams:
                if usePyQt4:
                    self.disconnect(
                        outputParam,
                        QtCore.SIGNAL('paramChangedSignal(QObject)'),
                        self.onParamChanged)
                else:
                    outputParam.paramChangedSignal.disconnect(
                        self.onParamChanged)

    #
    # showConnections
    #
    def showConnections(self, show):
        #
        print ">> NodeParamView.showConnections %s" % show
        self.showConnected = show
        self.inputParamListTab.showConnected = show
        self.outputParamListTab.showConnected = show
        self.inputParamListTab.updateGui()
        self.outputParamListTab.updateGui()

    #
    # onParamChanged
    #
    def onParamChanged(self, param):
        #
        if DEBUG_MODE:
            print(">> NodeParamView.onParamChanged node = %s param = %s" %
                  (self.gfxNode.node.label, param.name))
        if usePyQt4:
            self.emit(QtCore.SIGNAL('nodeParamChangedSignal'), self.gfxNode,
                      param)  # .node
        else:
            self.nodeParamChangedSignal.emit(self.gfxNode, param)  # .node

    #
    # nodeLabelChanged
    #
    def nodeLabelChanged(self):
        #
        #if DEBUG_MODE : print ">> NodeParamView.nodeLabelChanged"
        if self.gfxNode is not None:
            from core.meCommon import getParsedLabel
            newLabel = getParsedLabel(self.nameEdit.text())
            #if DEBUG_MODE : print "** newLabel = %s" % newLabel
            if newLabel != '':
                # update label only if realy changed
                if newLabel != self.gfxNode.node.label:
                    # rename node label if same name exists in NodeNet
                    if usePyQt4:
                        self.emit(QtCore.SIGNAL('nodeLabelChangedSignal'),
                                  self.gfxNode, newLabel)
                    else:
                        self.nodeLabelChangedSignal.emit(
                            self.gfxNode, newLabel)
                    self.nameEdit.clear()
            self.nameEdit.setText(self.gfxNode.node.label)

    #
    # buildGui
    #
    def buildGui(self):
        #
        label = QtModule.QLabel()
        label.setMinimumSize(QtCore.QSize(UI.NODE_LABEL_WIDTH, UI.HEIGHT))
        label.setMaximumSize(QtCore.QSize(UI.NODE_LABEL_WIDTH, UI.HEIGHT))

        font = QtGui.QFont()
        label.setFont(font)
        #label.setAlignment(QtCore.Qt.AlignCenter)
        label.setText('Label')

        self.nameEdit = QtModule.QLineEdit()
        self.nameEdit.setMaximumSize(QtCore.QSize(UI.MAX, UI.HEIGHT))
        self.nameEdit.setEnabled(False)

        self.showConnectButton = QtModule.QToolButton(self)
        sizePolicy = QtModule.QSizePolicy(QtModule.QSizePolicy.Fixed,
                                          QtModule.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(20)
        sizePolicy.setVerticalStretch(20)
        sizePolicy.setHeightForWidth(
            self.showConnectButton.sizePolicy().hasHeightForWidth())
        self.showConnectButton.setSizePolicy(sizePolicy)
        self.showConnectButton.setMaximumSize(QtCore.QSize(20, 20))
        icon = QtGui.QIcon()
        icon.addPixmap(
            QtGui.QPixmap(':/show_icons/resources/show_connect.png'),
            QtGui.QIcon.Normal, QtGui.QIcon.On)
        self.showConnectButton.setIcon(icon)
        self.showConnectButton.setAutoRaise(False)
        self.showConnectButton.setCheckable(True)
        self.showConnectButton.setChecked(self.showConnected)
        self.showConnectButton.setToolTip('Show connected parameters')
        #self.showConnectButton.setIconSize ( QtCore.QSize ( 16, 16 ) )
        self.showConnectButton.setObjectName('showConnectButton')

        headerLayout = QtModule.QHBoxLayout()
        headerLayout.setSpacing(UI.SPACING)
        headerLayout.setContentsMargins(UI.SPACING, UI.SPACING, UI.SPACING,
                                        UI.SPACING)
        headerLayout.setStretch(1, 1)

        headerLayout.addWidget(label)
        headerLayout.addWidget(self.nameEdit)
        headerLayout.addWidget(self.showConnectButton)

        mainLayout = QtModule.QVBoxLayout()
        mainLayout.addLayout(headerLayout)

        self.params_tabs = QtModule.QTabWidget(self)

        self.inputParamListTab = NodeParamListTab(
            self, self.gfxNode, isInput=True, showConnected=self.showConnected)
        self.params_tabs.addTab(self.inputParamListTab, 'Input')

        self.outputParamListTab = NodeParamListTab(
            self,
            self.gfxNode,
            isInput=False,
            showConnected=self.showConnected)
        self.params_tabs.addTab(self.outputParamListTab, 'Output')

        self.params_tabs.setCurrentIndex(0)

        mainLayout.addWidget(self.params_tabs)

        self.setLayout(mainLayout)

    #
    # updateGui
    #
    def updateGui(self):
        #
        #if DEBUG_MODE : print '>> NodeParamView.updateGui'

        self.nameEdit.clear()
        if self.gfxNode is not None:
            self.nameEdit.setText(self.gfxNode.node.label)

        self.inputParamListTab.updateGui()
        self.outputParamListTab.updateGui()
示例#9
0
class WorkArea ( QtModule.QGraphicsView ) :
	#
	# __init__
	#
	def __init__ ( self ) :
		#
		QtModule.QGraphicsView.__init__ ( self )
		#
		# Define signals for PyQt5
		#
		if usePySide or usePyQt5 :
			#
			self.selectNodes = Signal () #( list, list )
			self.nodeConnectionChanged = Signal () #QtCore.pyqtSignal ( QtModule.QGraphicsObject, QtCore.QObject )

			self.gfxNodeAdded = Signal () #( QtModule.QGraphicsObject )
			self.gfxNodeRemoved = Signal () #( QtModule.QGraphicsObject )
			#
		self.drawGrid = True
		self.gridSnap = False
		self.straightLinks = False
		self.reverseFlow = False

		self.gridSize = 10
		self.minGap = 120
		self.current_Z = 1

		self.state = 'idle'
		self.pressed = False
		self.startPos = None

		self.lastConnectCandidate = None
		self.currentGfxLink = None

		self.inspectedNode = None
		self.nodeNet = None

		self.selectedNodes = []
		self.selectedLinks = []

		# set scene
		scene = WorkAreaScene ( self )

		scene.setSceneRect ( -10000, -10000, 20000, 20000 )
		#scene.setItemIndexMethod ( QtGui.QGraphicsScene.NoIndex )
		self.setScene ( scene )

		# qt graphics stuff
		self.setCacheMode ( QtModule.QGraphicsView.CacheBackground )
		self.setRenderHint ( QtGui.QPainter.Antialiasing )

		self.setTransformationAnchor ( QtModule.QGraphicsView.AnchorUnderMouse ) # QtGui.QGraphicsView.AnchorUnderMouse
		self.setResizeAnchor ( QtModule.QGraphicsView.AnchorUnderMouse )  # AnchorViewCenter
		self.setDragMode ( QtModule.QGraphicsView.RubberBandDrag )

		self.setMouseTracking ( False )
		self.setAcceptDrops ( True )
		"""
		viewport = self.viewport()
		if viewport is not None :
			print ">> WorkArea viewport.setAcceptTouchEvents"
			#proxy = QtGui.QGraphicsProxyWidget ()
			proxy = viewport.graphicsProxyWidget ()
			if proxy is not None :
				proxy.setAcceptTouchEvents ( True )

			#self.setAttribute ( QtGui.AcceptTouchEvents, True )
			#viewport()->setAttribute(Qt::WA_AcceptTouchEvents);
			#setDragMode(ScrollHandDrag);
			#Qt::WA_AcceptTouchEvents
		"""
		self.viewBrush = QtGui.QBrush ( QtGui.QColor ( 148, 148, 148 ) )
		self.setBackgroundBrush ( self.viewBrush )

		# self.connectSignals ()




		if DEBUG_MODE : print ">> WorkArea. __init__"
	#
	# connectSignals
	#
	def connectSignals ( self ) :
		#
		pass
	#
	# drawBackground
	#
	def drawBackground ( self, painter, rect ) :
		#
		sc_rect = self.sceneRect ()
		bbrush = QtGui.QBrush( QtGui.QColor ( 148, 148, 148 ) ) ## painter.background()
		painter.fillRect ( rect, bbrush )

		if self.drawGrid :
		#  print( "grid size = %d" % self.gridSize )
			gr_pen = QtGui.QPen ( QtGui.QColor ( 180, 180, 180 ) )
			gr_pen.setWidth ( 0 )
			painter.setPen ( gr_pen )
			for x in range ( int ( sc_rect.x () ), int ( sc_rect.right () ), self.gridSize ):
				painter.drawLine ( x, sc_rect.y (), x, sc_rect.bottom () )
			for y in range ( int ( sc_rect.y () ), int ( sc_rect.bottom () ), self.gridSize ):
				painter.drawLine ( sc_rect.x (), y, sc_rect.right (), y )
	#
	# Returns a list of GfxNodes in the scene for given type
	# or all nodes if type == None
	#
	def getGfxNodesByType ( self, type = None ) :
		#
		resultList = []
		for item in self.scene ().items () :
			if ( isinstance ( item, GfxNode ) or
					 isinstance ( item, GfxSwatchNode ) or 
					 ( isinstance ( item, GfxNodeConnector ) and item.isNode () ) ) :
				if type is None or item.node.type == type :
					resultList.append ( item )
		return resultList
	#
	# Returns a list of GfxNodes in the scene for given format
	# or all nodes if type == None
	#
	def getGfxNodesByFormat ( self, format = None ) :
		#
		resultList = []
		for item in self.scene ().items () :
			if ( isinstance ( item, GfxNode ) or
					 isinstance ( item, GfxSwatchNode ) or 
					 ( isinstance ( item, GfxNodeConnector ) and item.isNode () ) ) :
				if format is None or item.node.format == format :
					resultList.append ( item )
		return resultList
	#
	# Returns GfxNodes for given Node
	#
	def getGfxNodesByNode ( self, node = None ) :
		#
		gfxNode = None
		for item in self.scene ().items () :
			if ( isinstance ( item, GfxNode ) or
					 isinstance ( item, GfxSwatchNode ) or 
					( isinstance ( item, GfxNodeConnector ) and item.isNode () ) ) :
				if item.node == node :
					gfxNode = item
					break
		return gfxNode
	#
	# selectAllNodes
	#
	def getAllGfxNodes ( self ) : return self.getGfxNodesByType ( None )
	#
	# selectAllNodes
	#
	def selectAllNodes ( self ) :
		#
		for item in self.getAllGfxNodes () : item.setSelected ( True )
	#
	# selectAbove
	#
	def selectAbove ( self, upperGfxNode ) :
		#
		if DEBUG_MODE : print '>> WorkArea::selectAbove node (%s) links:' % upperGfxNode.node.label
		for link_list in upperGfxNode.node.outputLinks.values () :
			for link in link_list :
				# link.printInfo ()
				if self.nodeNet.hasThisLink ( link ) :
					gfxNode = self.getGfxNodesByNode ( link.dstNode )
					gfxNode.setSelected ( True )
					self.selectAbove ( gfxNode )
				else :
					if DEBUG_MODE : print '!! invalid link ...'
	#
	# updateBelow
	#
	def updateBelow ( self, upperGfxNode, removeLinks = False ) :
		#
		if DEBUG_MODE : print '>> WorkArea::updateBelow upperGfxNode.node (%s) children:' % upperGfxNode.node.label
		for node in upperGfxNode.node.childs :
			if DEBUG_MODE : print '* %s' % node.label
			gfxNode = self.getGfxNodesByNode ( node )
			gfxNode.updateGfxNode ( removeLinks )
			self.updateBelow ( gfxNode, removeLinks )
	#
	# selectBelow
	#
	def selectBelow ( self, upperGfxNode ) :
		#
		if DEBUG_MODE : print '>> WorkArea::selectBelow upperGfxNode.node (%s) children:' % upperGfxNode.node.label
		for node in upperGfxNode.node.childs :
			if DEBUG_MODE : print '* %s' % node.label
			gfxNode = self.getGfxNodesByNode ( node )
			gfxNode.setSelected ( True )
			self.selectBelow ( gfxNode )
	#
	# setNodeNetwork
	#
	def setNodeNetwork ( self, nodeNet ) : self.nodeNet = nodeNet
	#
	# clear
	#
	def clear ( self ):
		#
		if DEBUG_MODE : print '>> WorkArea:: clearing nodes ...'
		for item in self.scene ().items () : self.scene ().removeItem ( item )
		self.nodeNet.clear ()
		self.state = 'idle'
		self.panStartPos = None
		self.lastConnectCandidate = None
		self.currentGfxLink = None
		self.inspectedNode = None
	#
	# addGfxLink
	#
	def addGfxLink ( self, link ) :
		#
		if DEBUG_MODE : print '>> WorkArea::addGfxLink (id=%d)' % link.id
		gfxLink = GfxLink ( link )
		( srcNode, srcParam ) = link.getSrc ()
		( dstNode, dstParam ) = link.getDst ()
		srcConnector = None
		dstConnector = None
		for item in self.scene ().items ():
			if isinstance ( item, GfxNode ) or isinstance ( item, GfxSwatchNode ) :
				if item.node == srcNode :
					srcConnector = item.getOutputConnectorByParam ( srcParam )
				elif item.node == dstNode :
					dstConnector = item.getInputConnectorByParam ( dstParam )
			elif isinstance ( item, GfxNodeConnector ) and item.isNode () :
				if item.node == srcNode :
					srcConnector = item
				elif item.node == dstNode :
					dstConnector = item
			if ( srcConnector != None and dstConnector != None ) :
				break
		gfxLink.setSrcConnector ( srcConnector )
		gfxLink.setDstConnector ( dstConnector )
		gfxLink.adjust ()
		self.scene ().addItem ( gfxLink )
	#
	# Node already in NodeNet, so add new GfxNode to scene
	#
	def addGfxNode ( self, node, pos = None ) :
		#
		#print ( ">> WorkArea: addGfxNode %s" % node.label )
		if node.type == 'connector' :
			gfxNode = GfxNodeConnector ( node.inputParams [ 0 ], node = node )
		elif node.type == 'note' :
			gfxNode = GfxNote ( node )
		elif node.type == 'swatch' :
			gfxNode = GfxSwatchNode ( node )
		else :
			gfxNode = GfxNode ( node )
		scene = self.scene ()
		if pos != None : gfxNode.moveBy ( pos.x(), pos.y() )
		#for item in scene.selectedItems (): item.setSelected ( False )
		scene.addItem ( gfxNode )
		gfxNode.setSelected ( True )
		if usePyQt4 :
			self.emit ( QtCore.SIGNAL ( 'gfxNodeAdded' ), gfxNode )
		else :
			self.gfxNodeAdded.emit ( gfxNode )
	#
	# adjustLinks
	#
	def adjustLinks ( self ) :
		#
		for item in self.scene ().items () :
			if isinstance ( item, GfxLink ): item.adjust ()
	#
	# fitGfxNodesInView
	#
	def fitGfxNodesInView ( self, gfxNodeList ) :
		#
		nodeNetRect = QtCore.QRectF ()
		for gfxNode in gfxNodeList :
			nodeRect = gfxNode.sceneBoundingRect ()
			if nodeNetRect.isNull () :
				nodeNetRect = nodeRect
			nodeNetRect = nodeNetRect.united ( nodeRect )
		if nodeNetRect.isValid () :
			self.fitInView ( nodeNetRect, QtCore.Qt.KeepAspectRatio ) 
	#
	# onSelectionChanged
	#
	def onSelectionChanged ( self ) :
		#
		#print ">> WorkArea: onSelectionChanged "
		self.selectedNodes = []
		self.selectedLinks = []
		selected = self.scene ().selectedItems ()

		for item in selected:
			if   isinstance ( item, GfxNode ) : self.selectedNodes.append ( item )
			elif isinstance ( item, GfxNote ) : self.selectedNodes.append ( item )
			elif isinstance ( item, GfxNodeConnector ) : self.selectedNodes.append ( item )
			elif isinstance ( item, GfxSwatchNode ) : self.selectedNodes.append ( item )
			elif isinstance ( item, GfxLink ) : self.selectedLinks.append ( item )

		if usePyQt4 :
			self.emit ( QtCore.SIGNAL ( 'selectNodes' ), self.selectedNodes, self.selectedLinks )
		else :
			self.selectNodes.emit ( self.selectedNodes, self.selectedLinks )
	#
	# lastConnectCandidateReset
	#
	def lastConnectCandidateReset ( self ) :
		#
		if self.lastConnectCandidate is not None :
			self.lastConnectCandidate.hilite( False )
		self.lastConnectCandidate = None
	#
	# isLinkAcceptable
	#
	def isLinkAcceptable ( self, connector, connectCandidate ) :
		#
		isAcceptable = False
		if isinstance ( connectCandidate, GfxNodeConnector ):
			# do not connect to itself
			if connectCandidate != connector :
				# do not connect to the same node
				if connectCandidate.parentItem () != connector.parentItem () :
					# do not connect the same link to connector twice
					if not connectCandidate.hasThisLink ( self.currentGfxLink ) :
						# connect only to similar type
						if connector.param.encodedTypeStr() == connectCandidate.param.encodedTypeStr () :
							if not connectCandidate.isNode () :
								# connect only input with output and vice versa
								if connector.param.isInput != connectCandidate.param.isInput :
										isAcceptable = True
							else :
								# we have nodeConnector
								isAcceptable = True

		return isAcceptable
	#
	# onStartNodeLink
	#
	#@QtCore.pyqtSlot( GfxNodeConnector )
	def onStartNodeLink ( self, connector ):
		#
		#if DEBUG_MODE : print '>> WorkArea::onStartNodeLink'
		#if DEBUG_MODE : print connector	
		srcNode = connector.getNode ()
		srcParam = connector.param
		if DEBUG_MODE : print '>> WorkArea::onStartNodeLink from %s (%s)' % ( srcNode.label, srcParam.label )

		srcConnector = connector
		self.state = 'traceNodeLink'
		self.lastConnectCandidate = None

		if connector.isInput () and connector.isLinked () :
			oldLink = connector.getFirstGfxLink ()
			srcConnector = oldLink.srcConnector
			oldLink.remove ()

		gfxLink = GfxLink ( None, srcConnector )
		self.scene ().addItem ( gfxLink )
		self.currentGfxLink = gfxLink
		self.currentGfxLink.isLinkSelected = True
	#
	# onTraceNodeLink
	#
	def onTraceNodeLink ( self, connector, scenePos ) :
		# node = connector.parentItem().node
		# print ">> WorkArea: onDrawNodeLink from %s (%d %d)" % ( node.label, scenePos.x(), scenePos.y() )
		if usePyQt4 :
			connectCandidate = self.scene ().itemAt ( scenePos )
		else :
			connectCandidate = self.scene ().itemAt ( scenePos, self.transform () )
		srcConnector = self.currentGfxLink.srcConnector
		swappedLink = False
		if srcConnector is None : # link has swapped connectors
			srcConnector = self.currentGfxLink.dstConnector
			swappedLink = True

		if self.isLinkAcceptable ( srcConnector, connectCandidate ) :
			if connectCandidate != self.lastConnectCandidate :
				self.lastConnectCandidateReset ()
				connectCandidate.hilite ( True )
				self.lastConnectCandidate = connectCandidate
				# link_node = connectCandidate.parentItem ().node
				# print ">> WorkArea: onDrawNodeLink to %s" % link_node.label
			else :
				scenePos = self.lastConnectCandidate.getCenterPoint () # snap to last position
				pass
				# self.lastConnectCandidateReset ()
		else :
			self.lastConnectCandidateReset ()

		#if self.currentGfxLink is not None :
		if swappedLink :
			self.currentGfxLink.setSrcPoint ( scenePos )
		else :
			self.currentGfxLink.setDstPoint ( scenePos )
	#
	# onEndNodeLink
	#
	def onEndNodeLink ( self, connector, scenePos ) :
		#
		srcConnector = self.currentGfxLink.srcConnector
		dstConnector = self.currentGfxLink.dstConnector
		swappedLink = False
		if srcConnector is None : # link has swapped connectors
			swappedLink = True

		if self.lastConnectCandidate is None :
			self.currentGfxLink.remove ()
			#self.emit( QtCore.SIGNAL( 'nodeParamChanged' ), srcConnector.parentItem(), srcConnector.param )
			#self.emit( QtCore.SIGNAL( 'nodeParamChanged' ), dstConnector.parentItem(), dstConnector.param )
		else :
			if self.lastConnectCandidate.isNode () :
				# if connection was made to ConnectorNode
				if dstConnector is None :
					self.lastConnectCandidate.removeInputGfxLinks ()
			else :
				# remove old link first if it exists
				if self.lastConnectCandidate.isInput () and self.lastConnectCandidate.isLinked () :
					#oldLink = self.lastConnectCandidate.getFirstLink ()
					#oldLink.remove ()
					self.lastConnectCandidate.removeInputGfxLinks ()

			self.currentGfxLink.isLinkSelected = False
			self.currentGfxLink.update ()

			srcNode = dstNode = None
			srcParam = dstParam = None

			if swappedLink :
				srcNode = self.lastConnectCandidate.getNode ()
				srcParam = self.lastConnectCandidate.param
				if self.lastConnectCandidate.isNode () :
					srcParam = self.lastConnectCandidate.getFirstOutputParam ()
				dstNode = dstConnector.getNode ()
				dstParam = dstConnector.param
				self.currentGfxLink.setSrcConnector ( self.lastConnectCandidate )
			else :
				srcNode = srcConnector.getNode ()
				srcParam = srcConnector.param
				dstNode = self.lastConnectCandidate.getNode ()
				dstParam = self.lastConnectCandidate.param
				if self.lastConnectCandidate.isNode () :
					dstParam = self.lastConnectCandidate.getFirstInputParam ()
				self.currentGfxLink.setDstConnector ( self.lastConnectCandidate )

			link = NodeLink.build ( srcNode, dstNode, srcParam, dstParam )

			#if not dstParam.isInput :
				# swap source and destination
			#  self.currentGfxLink.swapConnectors ()
			#  link.swapNodes ()

			self.currentGfxLink.link = link
			self.nodeNet.addLink ( link )
			if usePyQt4 :
				self.emit ( QtCore.SIGNAL ( 'nodeConnectionChanged' ), self.currentGfxLink.dstConnector.getGfxNode (), self.currentGfxLink.dstConnector.param )
			else :
				self.nodeConnectionChanged.emit ( self.currentGfxLink.dstConnector.getGfxNode (), self.currentGfxLink.dstConnector.param )

		self.lastConnectCandidateReset ()
		self.currentGfxLink = None
		self.state = 'idle'
	#
	# onStartNodeConnector
	#
	def onStartNodeConnector ( self, connector, scenePos  ) :
		#
		if DEBUG_MODE : print '>> WorkArea::onStartNodeConnector'
		self.state = 'traceNodeConnector'

		newNode = ConnectorNode ()
		self.nodeNet.addNode ( newNode )

		newParam = connector.param.copy ()
		newParam.isInput = False
		newInParam = newParam.copy ()
		newOutParam = newParam.copy ()

		newNode.addInputParam ( newInParam )
		newNode.addOutputParam ( newOutParam )

		newConnector = GfxNodeConnector ( newParam, connector.radius, node = newNode )
		newConnector.brush = connector.brush
		newConnector.setPos ( scenePos )
		newConnector.moveBy ( -connector.radius, -connector.radius )

		self.lastConnectCandidate = newConnector
		self.scene ().addItem ( newConnector )
		newConnector.hilite ( True )

		srcNode = connector.getNode ()
		srcParam = connector.getOutputParam ()
		dstNode = newConnector.getNode ()
		dstParam = newConnector.getInputParam ()

		#
		# swap link direction only for connectors
		# in open chain connected to input node parameter
		#
		swappedLink = False
		if connector.isConnectedToInput () and not connector.isConnectedToOutput () :
			if DEBUG_MODE : print '*** swap link direction ***'
			swappedLink = True
			srcNode = newConnector.getNode ()
			srcParam = newConnector.getOutputParam ()
			dstNode = connector.getNode ()
			dstParam = connector.getInputParam ()

		link = NodeLink.build ( srcNode, dstNode, srcParam, dstParam )
		# if swappedLink : link.swapNodes ()
		self.nodeNet.addLink ( link )

		#if DEBUG_MODE : self.nodeNet.printInfo ()

		# preserve existing links for parameter connectors
		if connector.isLinked () and not connector.isNode () :
			if connector.isInput () :
				#print '*** preserve input ***'
				# TODO!!!
				# This is very rough code -- needs to be wrapped in functions
				gfxLinks = connector.getInputGfxLinks ()
				
				for gfxLink in gfxLinks :
					gfxLink.setDstConnector ( newConnector )

					# remove gfxLink from previouse connector
					connector.removeGfxLink ( gfxLink )

					# adjust destination for node link
					newConnector.getNode ().attachInputParamToLink ( newConnector.getInputParam (), gfxLink.link )
					newConnector.getNode ().addChild ( gfxLink.link.srcNode )
					connector.getNode ().removeChild ( gfxLink.link.srcNode )

					gfxLink.link.dstNode = newConnector.getNode ()
					gfxLink.link.dstParam = newConnector.getInputParam ()
			else :
				#print '*** preserve output ***'
				gfxLinks = connector.getOutputGfxLinks ()
				
				for gfxLink in gfxLinks :
					gfxLink.setSrcConnector ( newConnector )

					# remove gfxLink from previouse connector
					connector.removeGfxLink ( gfxLink )

					# adjust source for node link
					connector.getNode ().detachOutputParamFromLink ( gfxLink.link.srcParam, gfxLink.link )
					newConnector.getNode ().attachOutputParamToLink ( newConnector.getOutputParam (), gfxLink.link )
					#newConnector.getNode ().childs.add ( connector.getNode () )
					gfxLink.link.dstNode.addChild ( newConnector.getNode () )
					gfxLink.link.dstNode.removeChild ( connector.getNode () )

					gfxLink.link.srcNode = newConnector.getNode ()
					gfxLink.link.srcParam = newConnector.getOutputParam ()

			#if DEBUG_MODE : self.nodeNet.printInfo ()

		gfxLink = GfxLink ( link, connector, newConnector  )
		self.scene ().addItem ( gfxLink )
	#
	# onTraceNodeConnector
	#
	def onTraceNodeConnector ( self, connector, scenePos ) :
		#
		#if DEBUG_MODE : print '>> WorkArea::onTraceNodeConnector'
		if self.lastConnectCandidate is not None :
			self.lastConnectCandidate.setPos ( scenePos )
			self.lastConnectCandidate.moveBy ( -connector.radius, -connector.radius )
	 #
	# onEndNodeConnector
	#
	def onEndNodeConnector ( self, connector, scenePos ) :
		#
		if DEBUG_MODE : print '>> WorkArea::onEndNodeConnector'
		print '>> lastConnectCandidate.node.type = %s' % self.lastConnectCandidate.node.type
		self.lastConnectCandidateReset ()
		self.state = 'idle'
	#
	# onRemoveNode
	#
	def onRemoveNode ( self, gfxNode ) :
		#
		print ">> WorkArea.onRemoveNode %s (id = %d)" % ( gfxNode.node.label, gfxNode.node.id )
		if usePyQt4 :
			self.emit ( QtCore.SIGNAL ( 'gfxNodeRemoved' ), gfxNode )
		else :
			self.gfxNodeRemoved.emit ( gfxNode )
		self.scene ().removeItem ( gfxNode )
		self.nodeNet.removeNode ( gfxNode.node )

		#if DEBUG_MODE : self.nodeNet.printInfo ()
	#
	# onRemoveLink
	#
	def onRemoveLink ( self, gfxLink ) :
		#
		print ">> WorkArea.onRemoveLink ..."
		self.scene ().removeItem ( gfxLink )
		
		if gfxLink.link is not None :
			print "*** (id = %d)" % ( gfxLink.link.id )
			srcConnector = gfxLink.srcConnector
			dstConnector = gfxLink.dstConnector
			self.nodeNet.removeLink ( gfxLink.link )
			if srcConnector is not None :
				if DEBUG_MODE : print '*** srcConnector.parentItem().node.label = %s ' % srcConnector.getNode ().label
				#self.emit( QtCore.SIGNAL( 'nodeConnectionChanged' ), srcConnector.parentItem(), srcConnector.param )
			if dstConnector is not None :
				if DEBUG_MODE : print '*** dstConnector.parentItem().node.label = %s ' % dstConnector.getNode ().label
				if usePyQt4 :
					self.emit ( QtCore.SIGNAL ( 'nodeConnectionChanged' ), dstConnector.getGfxNode (), dstConnector.param )
				else :
					self.nodeConnectionChanged.emit ( dstConnector.getGfxNode (), dstConnector.param )
	#
	# removeSelected
	#
	def removeSelected ( self ) :
		#
		if DEBUG_MODE : print '>> WorkArea.removeSelected: (before) nodes = %d links = %d' % ( len (  self.nodeNet.nodes.values () ), len ( self.nodeNet.links.values () ) )
		selected = self.scene().selectedItems()

		for item in selected:
			if ( isinstance ( item, GfxLink ) or
					 isinstance ( item, GfxNode ) or
					 isinstance ( item, GfxNote ) or
					 isinstance ( item, GfxSwatchNode ) or
				 ( isinstance ( item, GfxNodeConnector ) and item.isNode () ) ) : item.remove ()

		if DEBUG_MODE : print '>> WorkArea.removeSelected (after) nodes = %d links = %d' % ( len ( self.nodeNet.nodes.values ()), len ( self.nodeNet.links.values ()) )
	#
	# dragEnterEvent
	#
	def dragEnterEvent ( self, event ) :
		#
		print '>> WorkArea.onDragEnterEvent'
		#for form_str in event.mimeData().formats():
		#  print str ( form_str )
		#  if form_str == 'text/uri-list' :
		#    print event.mimeData().data( 'text/uri-list' )
		mimedata = event.mimeData ()

		if mimedata.hasFormat ( 'application/x-text' ) or mimedata.hasFormat ( 'text/uri-list' ):
			event.accept ()
		else:
			event.ignore ()
	#
	# dragMoveEvent
	#
	def dragMoveEvent ( self, event ) :
		#print ">> WorkArea.dragMoveEvent"
		mimedata = event.mimeData ()
		if mimedata.hasFormat ( 'application/x-text' ) or mimedata.hasFormat ( 'text/uri-list' ):
			event.setDropAction ( QtCore.Qt.CopyAction )
			event.accept ()
		else:
			event.ignore ()
	#
	# dropEvent
	#
	def dropEvent ( self, event ) :
		#
		import os
		if DEBUG_MODE : print ">> WorkArea.dropEvent"
		file_list = []
		mimedata = event.mimeData ()

		if mimedata.hasFormat ( 'application/x-text' ) :
			# decode drop stuff
			data = mimedata.data ( 'application/x-text' )
			stream = QtCore.QDataStream ( data, QtCore.QIODevice.ReadOnly )
			if usePyQt4 :
				filename = QtCore.QString ()
			else :
				filename = ''
			if not usePyQt5 :
				if usePySide :
					filename = stream.readString ()
				else :
					stream >> filename
			else :
				filename = stream.readBytes ()

			if DEBUG_MODE : print '* read itemFilename = %s' % ( filename )

			file_list.append ( filename )
			event.setDropAction ( QtCore.Qt.CopyAction )
			event.accept ()
		elif mimedata.hasFormat ( 'text/uri-list' ) :
			data = str ( mimedata.data( 'text/uri-list' ).data() )
			#print data
			for item in data.split () :
				filename = str ( QtCore.QUrl( item ).toLocalFile () )

				( name, ext ) = os.path.splitext( os.path.basename( filename ) )
				if DEBUG_MODE : print ':: %s (%s)' % ( filename, ext )
				if ext == '.xml' :
					file_list.append ( filename )
		else:
			event.ignore ()

		for file_name in file_list : self.insertNodeNet ( file_name, self.mapToScene( event.pos () ) )
	#
	# keyPressEvent
	#
	def keyPressEvent ( self, event ) :
		#print ">> WorkArea.keyPressEvent"
		QtModule.QGraphicsView.keyPressEvent ( self, event)
	#
	# wheelEvent
	#
	def wheelEvent ( self, event ) :
		#print ">> WorkArea.wheelEvent"
		# QtGui.QGraphicsView.wheelEvent( self, event)
		import sys, math
		scale = -1.0
		if 'linux' in sys.platform: scale = 1.0
		if  not usePyQt5 :
			scaleFactor = math.pow( 2.0, scale * event.delta () / 600.0 )
		else :
			delta = event.angleDelta ()
			#print ( '>> delta rx = %d ry = %d' % ( delta.x (), delta.y () ) )
			scaleFactor = math.pow( 2.0, scale * delta.y () / 600.0 )
		# self.matrix () is depicated
		factor = self.transform ().scale ( scaleFactor, scaleFactor ).mapRect ( QtCore.QRectF ( -1, -1, 2, 2 ) ).width ()
		if factor < 0.07 or factor > 100: return
		self.scale ( scaleFactor, scaleFactor )
	#
	# mousePressEvent
	#
	def mousePressEvent ( self, event ) :
		#print ">> WorkArea.mousePressEvent"
		#self.setFocus ()
		self.startPos = self.mapToScene ( event.pos () )
		self.pressed = True
		button = event.button ()
		modifiers = event.modifiers ()
		
		if ( button == QtCore.Qt.MidButton or ( button == QtCore.Qt.LeftButton and modifiers == QtCore.Qt.ShiftModifier ) ) :
			self.state = 'pan'
			return
		if button == QtCore.Qt.RightButton and modifiers == QtCore.Qt.ShiftModifier :
			self.state = 'zoom'
			return
		QtModule.QGraphicsView.mousePressEvent ( self, event )
	#
	# mouseDoubleClickEvent
	#
	def mouseDoubleClickEvent ( self, event ) :
		#
		#print ">> WorkArea.mouseDoubleClickEvent"
		selected = self.scene ().selectedItems ()

		QtModule.QGraphicsView.mouseDoubleClickEvent ( self, event )
	#
	# mouseMoveEvent
	#
	def mouseMoveEvent ( self, event ) :
		#print ">> WorkArea.mouseMoveEvent"
		#if self.pressed :
		currentPos = self.mapToScene( event.pos() )
		if self.state == 'pan' :
			deltaPos = currentPos - self.startPos
			self.setInteractive ( False )
			self.translate ( deltaPos.x (), deltaPos.y () )
			self.setInteractive ( True )
		
		elif self.state == 'zoom' :
			#
			import sys, math
			deltaPos = currentPos - self.startPos
			scale = -1.0
			if 'linux' in sys.platform: scale = 1.0
			scaleFactor = math.pow ( 2.0, scale * max ( deltaPos.x (), deltaPos.y () ) / 200.0  ) #
			factor = self.transform ().scale ( scaleFactor, scaleFactor ).mapRect ( QtCore.QRectF( -1, -1, 2, 2 ) ).width ()

			if factor < 0.07 or factor > 100: return
			# update view matrix
			self.setInteractive ( False )
			self.scale ( scaleFactor, scaleFactor )
			self.translate ( -deltaPos.x () * scaleFactor, -deltaPos.y () * scaleFactor )
			self.setInteractive ( True )
			#self.startPos = currentPos
		else :
			QtModule.QGraphicsView.mouseMoveEvent ( self, event )
	#
	# mouseReleaseEvent
	#
	def mouseReleaseEvent ( self, event ) :
		#print ">> WorkArea.mouseReleaseEvent"
		if self.state in [ 'pan', 'zoom' ] :
			self.state = 'idle'
			self.startPos = None
			self.pressed = False
		QtModule.QGraphicsView.mouseReleaseEvent ( self, event )
	#
	# resetZoom
	#
	def resetZoom ( self ) :
		#
		if DEBUG_MODE : print ( ">> WorkArea.resetZoom" )
		self.setInteractive ( False )
		self.resetTransform()
		self.centerOn ( 0.0, 0.0 )
		self.setInteractive ( True )
	#
	# viewportEvent
	#
	def viewportEvent ( self, event ) :
		#case QEvent::TouchBegin:
		# case QEvent::TouchUpdate:
		# case QEvent::TouchEnd:
		if event.type() == QtCore.QEvent.TouchBegin :
			if DEBUG_MODE : print ( ">> WorkArea.QEvent.TouchBegin" )
		return QtModule.QGraphicsView.viewportEvent ( self, event )
	#
	# deselectAllNodes
	#
	def deselectAllNodes ( self ) :
		selected = self.scene().selectedItems()
		for item in selected : item.setSelected ( False )
	#
	# openNodeNet
	#
	def openNodeNet ( self, filename, pos = None ) :
		#
		( nodes, links ) = self.nodeNet.open ( normPath ( filename ) )
		for node in nodes : self.addGfxNode ( node )
		for link in links : self.addGfxLink ( link )
	#
	# insertNodeNet
	#
	# Called by signal 'addNode'
	def insertNodeNet ( self, filename, pos = None ) :
		#
		if DEBUG_MODE : print ( '>> WorkArea.insertNodeNet filename = ' + filename )
		if DEBUG_MODE : print ( ">> WorkArea.insertNodeNet (before) nodes = %d links = %d" % ( len(self.nodeNet.nodes.values()), len(self.nodeNet.links.values()) ) )
		( nodes, links ) = self.nodeNet.insert ( normPath ( filename ) )

		if pos == None :
			# on dblclk -- insert node at left border of sceneBound
			sceneBound = self.scene().itemsBoundingRect ()
			if not sceneBound.isNull () :
				x_offset = sceneBound.x() - self.minGap
				pos = QtCore.QPointF ( x_offset, 0 )

		self.deselectAllNodes ()

		for node in nodes : self.addGfxNode ( node, pos )
		for link in links : self.addGfxLink ( link )

		if DEBUG_MODE : print ( '>> WorkArea.insertNodeNet (after) nodes = %d links = %d' % ( len ( self.nodeNet.nodes.values ()), len ( self.nodeNet.links.values () ) ) )
	#
	# copyNodes
	#
	def copyNodes ( self, clipboard, cutNodes = False ) :
		#
		if DEBUG_MODE : print ( '>> WorkArea.copyNodes ( cutNodes = %s )'  % str ( cutNodes ) )
		
		dupNodeNet = NodeNetwork ( 'clipboard' )
		
		for gfxNode in self.selectedNodes :
			dupNode = gfxNode.node.copy ()
			dupNodeNet.addNode ( dupNode )
			
		for gfxNode in self.selectedNodes :
			for link in gfxNode.node.getInputLinks () :
				#link.printInfo ()
				dupLink = link.copy ()
				dupDstNode = dupNodeNet.getNodeByID ( gfxNode.node.id )

				if dupDstNode is not None :
					dupDstParam = dupDstNode.getInputParamByName ( link.dstParam.name ) 
					dupLink.setDst ( dupDstNode, dupDstParam )
					
					( srcNode, srcParam ) = dupLink.getSrc ()
					dupSrcNode = dupNodeNet.getNodeByID ( srcNode.id )
					
					if dupSrcNode is not None :
						# if srcNode is inside dupNodeNet 
						dupSrcParam = dupSrcNode.getOutputParamByName ( srcParam.name )
						dupLink.setSrc ( dupSrcNode, dupSrcParam )
						dupNodeNet.addLink ( dupLink ) 
						
			
		dom = QtXml.QDomDocument ( dupNodeNet.name )
		dupNodeNet.parseToXML ( dom )
		
		clipboard.clear ()
		clipboard.setText ( dom.toString () ) # .	fromUtf16 () .fromUtf8 () encode( 'utf-8' ) unicode ( dom.toByteArray () ) toString ()
		
		if cutNodes : self.removeSelected ()
	#
	# pasteNodes
	#
	def pasteNodes ( self, clipboard ) :
		#
		if DEBUG_MODE : print ( '>> WorkArea.pasteNodes ...' )
		nodes = []
		links = []
		
		dom = QtXml.QDomDocument ( 'clipboard' )
		dom.setContent ( clipboard.text () ) 
		root = dom.documentElement ()
		if root.nodeName () == 'node' :
			nodes.append ( self.nodeNet.addNodeFromXML ( root ) )
			self.nodeNet.correct_id ( nodes, links )
		elif root.nodeName () == 'nodenet' :
			#print ':: parsing nodenet from XML ...'
			nodeNet = NodeNetwork ( 'tmp', root )
			( nodes, links ) = self.nodeNet.add ( nodeNet )
		else :
			print '!! unknown XML document format'
			return
			
		offsetPos = QtCore.QPointF ( self.minGap, self.minGap / 2 )
		self.deselectAllNodes ()

		for node in nodes : self.addGfxNode ( node, offsetPos )
		for link in links : self.addGfxLink ( link )
	#
	# duplicateNodes
	#
	def duplicateNodes ( self, preserveLinks = False ) :
		#
		if DEBUG_MODE : print ( '>> WorkArea.duplicateNode ( preserveLinks = %s )'  % str ( preserveLinks ) )
		
		dupNodeNet = NodeNetwork ( 'duplicate' )
		
		for gfxNode in self.selectedNodes :
			dupNode = gfxNode.node.copy ()
			dupNodeNet.addNode ( dupNode )
			
		
		for gfxNode in self.selectedNodes :
			for link in gfxNode.node.getInputLinks () :
				#link.printInfo ()
				dupLink = link.copy ()
				dupDstNode = dupNodeNet.getNodeByID ( gfxNode.node.id )

				if dupDstNode is not None :
					dupDstParam = dupDstNode.getInputParamByName ( link.dstParam.name ) 
					dupLink.setDst ( dupDstNode, dupDstParam )
					
					( srcNode, srcParam ) = dupLink.getSrc ()
					dupSrcNode = dupNodeNet.getNodeByID ( srcNode.id )
					
					if dupSrcNode is not None :
						# if srcNode is inside dupNodeNet 
						dupSrcParam = dupSrcNode.getOutputParamByName ( srcParam.name )
						dupLink.setSrc ( dupSrcNode, dupSrcParam )
						dupNodeNet.addLink ( dupLink ) 
					else :
						# if this is outside links
						if preserveLinks :
							dupNodeNet.addLink ( dupLink ) 
						else :
							dupLink.setSrc ( None, None )  
							dupLink.setDst ( None, None )    

		#if DEBUG_MODE : dupNodeNet.printInfo ()
		( nodes, links ) = self.nodeNet.add ( dupNodeNet )

		offsetPos = QtCore.QPointF ( self.minGap, self.minGap / 2 )

		self.deselectAllNodes ()

		for node in nodes : self.addGfxNode ( node, offsetPos )
		for link in links : self.addGfxLink ( link )
	#
	# newNodeNetFromList
	#
	def nodeNetFromSelected ( self, nodeNetName, preserveLinks = False ) :
		#
		if DEBUG_MODE : print ( '>> WorkArea.nodeNetFromSelected ( preserveLinks = %s )'  % str ( preserveLinks ) )
		dupNodeNet = NodeNetwork ( nodeNetName )
		
		for gfxNode in self.selectedNodes :
			dupNode = gfxNode.node.copy ()
			dupNodeNet.addNode ( dupNode )
			
		
		for gfxNode in self.selectedNodes :
			for link in gfxNode.node.getInputLinks () :
				#link.printInfo ()
				dupLink = link.copy ()
				dupDstNode = dupNodeNet.getNodeByID ( gfxNode.node.id )

				if dupDstNode is not None :
					dupDstParam = dupDstNode.getInputParamByName ( link.dstParam.name ) 
					dupLink.setDst ( dupDstNode, dupDstParam )
					
					( srcNode, srcParam ) = dupLink.getSrc ()
					dupSrcNode = dupNodeNet.getNodeByID ( srcNode.id )
					
					if dupSrcNode is not None :
						# if srcNode is inside dupNodeNet 
						dupSrcParam = dupSrcNode.getOutputParamByName ( srcParam.name )
						dupLink.setSrc ( dupSrcNode, dupSrcParam )
						dupNodeNet.addLink ( dupLink ) 
					else :
						# if this is outside links
						if preserveLinks :
							dupNodeNet.addLink ( dupLink ) 
						else :
							dupLink.setSrc ( None, None )  
							dupLink.setDst ( None, None )    
							
		return dupNodeNet          
示例#10
0
class NodeParamEditor(QtModule.QWidget):
    #
    # __init__
    #
    def __init__(self, parent):
        #
        QtModule.QWidget.__init__(self, parent)
        #
        # Define signals for PyQt5
        #
        if usePySide or usePyQt5:
            #
            self.changeParamName = Signal()
            self.changeParamLabel = Signal()
            self.changeParamIsShader = Signal()
            self.changeParamType = Signal()
            self.changeParamDetail = Signal()
            self.changeParamProvider = Signal()
            self.changeParamSubtype = Signal()
            self.changeParamRange = Signal()

            self.changeParamValue = Signal()
            self.changeParamDefValue = Signal()
        #
        self.param = None
        self.param_default = None
        self.paramWidgets = {
            'string': StringWidget,
            'image': StringWidget,
            'rib': StringWidget,
            'surface': StringWidget,
            'displacement': StringWidget,
            'light': StringWidget,
            'volume': StringWidget,
            'float': FloatWidget,
            'int': IntWidget,
            'color': ColorWidget,
            'normal': NormalWidget,
            'transform': PointWidget,
            'point': PointWidget,
            'vector': VectorWidget,
            'matrix': MatrixWidget,
            'text': TextWidget,
            'control': ControlWidget,
            'shader': StringWidget,
            'geom': StringWidget
        }

        self.buildGui()

    #
    #
    def __delete__(self, obj):
        #
        print '* NodeParamEditor closed... %s' % str(obj)

    #
    # buildGui
    #
    def buildGui(self):
        # build the gui created with QtDesigner
        self.ui = Ui_NodeParamEditor()
        self.ui.setupUi(self)

        # correct UI sizes for some controls
        self.ui.check_enabled.setMinimumSize(
            QtCore.QSize(UI.CHECK_WIDTH, UI.HEIGHT))
        self.ui.check_enabled.setMaximumSize(
            QtCore.QSize(UI.CHECK_WIDTH, UI.HEIGHT))

        self.ui.check_display.setMinimumSize(
            QtCore.QSize(UI.CHECK_WIDTH, UI.HEIGHT))
        self.ui.check_display.setMaximumSize(
            QtCore.QSize(UI.CHECK_WIDTH, UI.HEIGHT))

        self.ui.check_shader.setMinimumSize(
            QtCore.QSize(UI.CHECK_WIDTH, UI.HEIGHT))
        self.ui.check_shader.setMaximumSize(
            QtCore.QSize(UI.CHECK_WIDTH, UI.HEIGHT))

        for label in VALID_PARAM_TYPES:
            self.ui.type_comboBox.addItem(label)

        self.ui.type_comboBox.setCurrentIndex(-1)
        self.ui.type_comboBox.setMinimumSize(
            QtCore.QSize(UI.COMBO_WIDTH, UI.COMBO_HEIGHT))
        self.ui.type_comboBox.setMaximumSize(
            QtCore.QSize(UI.MAX, UI.COMBO_HEIGHT))

        # temporary disabled, until "how to do it gracefully" will be clear ...
        self.ui.type_comboBox.setEnabled(False)

        for label in [
                'None',
                'uniform',
                'varying',
        ]:
            self.ui.detail_comboBox.addItem(label)
        self.ui.detail_comboBox.setCurrentIndex(-1)
        self.ui.detail_comboBox.setMinimumSize(
            QtCore.QSize(UI.COMBO_WIDTH, UI.COMBO_HEIGHT))
        self.ui.detail_comboBox.setMaximumSize(
            QtCore.QSize(UI.MAX, UI.COMBO_HEIGHT))

        for label in [
                'None', 'internal', 'external', 'primitive', 'attribute'
        ]:
            self.ui.provider_comboBox.addItem(label)
        self.ui.provider_comboBox.setCurrentIndex(-1)
        self.ui.provider_comboBox.setMinimumSize(
            QtCore.QSize(UI.COMBO_WIDTH, UI.COMBO_HEIGHT))
        self.ui.provider_comboBox.setMaximumSize(
            QtCore.QSize(UI.MAX, UI.COMBO_HEIGHT))

        for label in [
                'None', 'slider', 'switch', 'selector', 'file', 'button'
        ]:
            self.ui.subtype_comboBox.addItem(label)
        self.ui.subtype_comboBox.setCurrentIndex(-1)
        self.ui.subtype_comboBox.setMinimumSize(
            QtCore.QSize(UI.COMBO_WIDTH, UI.COMBO_HEIGHT))
        self.ui.subtype_comboBox.setMaximumSize(
            QtCore.QSize(UI.MAX, UI.COMBO_HEIGHT))

    #
    # As paramWidet is monitoring a change of param.value only,
    # we need to cynchronize changing of param_default.value with param.default
    #
    def onParamDefValueChanged(self, param):
        #
        if DEBUG_MODE: print '* onParamDefValueChanged'
        self.param.default = self.param_default.value
        if usePyQt4:
            self.emit(QtCore.SIGNAL('changeParamDefValue'), self.param)
        else:
            self.changeParamDefValue.emit(self.param)

    #
    # onParamValueChanged
    #
    def onParamValueChanged(self, param):
        #
        if DEBUG_MODE: print '* onParamValueChanged'
        self.param.value = param.value
        if usePyQt4:
            self.emit(QtCore.SIGNAL('changeParamValue'), self.param)
        else:
            self.changeParamValue.emit(self.param)

    #
    # connectSignals
    #
    def connectSignals(self):
        #
        if usePyQt4:
            self.connect(self.param_default,
                         QtCore.SIGNAL('paramChangedSignal(QObject)'),
                         self.onParamDefValueChanged)
            self.connect(self.param,
                         QtCore.SIGNAL('paramChangedSignal(QObject)'),
                         self.onParamValueChanged)

            self.connect(self.ui.name_lineEdit,
                         QtCore.SIGNAL('editingFinished()'),
                         self.onEditParamName)
            self.connect(self.ui.label_lineEdit,
                         QtCore.SIGNAL('editingFinished()'),
                         self.onEditParamLabel)
            self.connect(self.ui.check_enabled,
                         QtCore.SIGNAL('stateChanged(int)'),
                         self.onEditParamEnabled)
            self.connect(self.ui.check_display,
                         QtCore.SIGNAL('stateChanged(int)'),
                         self.onEditParamDisplay)
            self.connect(self.ui.check_shader,
                         QtCore.SIGNAL('stateChanged(int)'),
                         self.onEditParamShader)
            self.connect(self.ui.type_comboBox,
                         QtCore.SIGNAL('activated(int)'), self.onEditParamType)
            self.connect(self.ui.detail_comboBox,
                         QtCore.SIGNAL('activated(int)'),
                         self.onEditParamDetail)
            self.connect(self.ui.provider_comboBox,
                         QtCore.SIGNAL('activated(int)'),
                         self.onEditParamProvider)
            self.connect(self.ui.subtype_comboBox,
                         QtCore.SIGNAL('activated(int)'),
                         self.onEditParamSubtype)
            self.connect(self.ui.range_lineEdit,
                         QtCore.SIGNAL('editingFinished()'),
                         self.onEditParamRange)
            self.connect(self.ui.descr_plainTextEdit,
                         QtCore.SIGNAL('textChanged()'), self.onEditParamHelp)
        else:
            self.param_default.paramChangedSignal.connect(
                self.onParamDefValueChanged)
            self.param.paramChangedSignal.connect(self.onParamValueChanged)

            self.ui.name_lineEdit.editingFinished.connect(self.onEditParamName)
            self.ui.label_lineEdit.editingFinished.connect(
                self.onEditParamLabel)
            self.ui.check_enabled.stateChanged.connect(self.onEditParamEnabled)
            self.ui.check_display.stateChanged.connect(self.onEditParamDisplay)
            self.ui.check_shader.stateChanged.connect(self.onEditParamShader)
            self.ui.type_comboBox.activated.connect(self.onEditParamType)
            self.ui.detail_comboBox.activated.connect(self.onEditParamDetail)
            self.ui.provider_comboBox.activated.connect(
                self.onEditParamProvider)
            self.ui.subtype_comboBox.activated.connect(self.onEditParamSubtype)
            self.ui.range_lineEdit.editingFinished.connect(
                self.onEditParamRange)
            self.ui.descr_plainTextEdit.textChanged.connect(
                self.onEditParamHelp)

    #
    # disconnectSignals
    #
    def disconnectSignals(self):
        #
        if usePyQt4:
            if self.param_default is not None:
                self.disconnect(self.param_default,
                                QtCore.SIGNAL('paramChangedSignal(QObject)'),
                                self.onParamDefValueChanged)
            if self.param is not None:
                self.disconnect(self.param,
                                QtCore.SIGNAL('paramChangedSignal(QObject)'),
                                self.onParamValueChanged)

                self.disconnect(self.ui.name_lineEdit,
                                QtCore.SIGNAL('editingFinished()'),
                                self.onEditParamName)
                self.disconnect(self.ui.label_lineEdit,
                                QtCore.SIGNAL('editingFinished()'),
                                self.onEditParamLabel)
                self.disconnect(self.ui.check_enabled,
                                QtCore.SIGNAL('stateChanged(int)'),
                                self.onEditParamEnabled)
                self.disconnect(self.ui.check_display,
                                QtCore.SIGNAL('stateChanged(int)'),
                                self.onEditParamDisplay)
                self.disconnect(self.ui.check_shader,
                                QtCore.SIGNAL('stateChanged(int)'),
                                self.onEditParamShader)
                self.disconnect(self.ui.type_comboBox,
                                QtCore.SIGNAL('activated(int)'),
                                self.onEditParamType)
                self.disconnect(self.ui.detail_comboBox,
                                QtCore.SIGNAL('activated(int)'),
                                self.onEditParamDetail)
                self.disconnect(self.ui.provider_comboBox,
                                QtCore.SIGNAL('activated(int)'),
                                self.onEditParamProvider)
                self.disconnect(self.ui.subtype_comboBox,
                                QtCore.SIGNAL('activated(int)'),
                                self.onEditParamSubtype)
                self.disconnect(self.ui.descr_plainTextEdit,
                                QtCore.SIGNAL('textChanged()'),
                                self.onEditParamHelp)
        else:
            if self.param_default is not None:
                self.param_default.paramChangedSignal.disconnect(
                    self.onParamDefValueChanged)
            if self.param is not None:
                self.param.paramChangedSignal.disconnect(
                    self.onParamValueChanged)

                self.ui.name_lineEdit.editingFinished.disconnect(
                    self.onEditParamName)
                self.ui.label_lineEdit.editingFinished.disconnect(
                    self.onEditParamLabel)
                self.ui.check_enabled.stateChanged.disconnect(
                    self.onEditParamEnabled)
                self.ui.check_display.stateChanged.disconnect(
                    self.onEditParamDisplay)
                self.ui.check_shader.stateChanged.disconnect(
                    self.onEditParamShader)
                self.ui.type_comboBox.activated.disconnect(
                    self.onEditParamType)
                self.ui.detail_comboBox.activated.disconnect(
                    self.onEditParamDetail)
                self.ui.provider_comboBox.activated.disconnect(
                    self.onEditParamProvider)
                self.ui.subtype_comboBox.activated.disconnect(
                    self.onEditParamSubtype)
                self.ui.range_lineEdit.editingFinished.disconnect(
                    self.onEditParamRange)
                self.ui.descr_plainTextEdit.textChanged.disconnect(
                    self.onEditParamHelp)

    #
    # reset
    #
    def reset(self):
        #
        self.ui.name_lineEdit.setText('')
        self.ui.label_lineEdit.setText('')

        self.ui.check_enabled.setChecked(True)
        self.ui.check_display.setChecked(True)
        self.ui.check_shader.setChecked(False)

        self.ui.type_comboBox.setCurrentIndex(-1)
        self.ui.detail_comboBox.setCurrentIndex(-1)
        self.ui.provider_comboBox.setCurrentIndex(-1)
        self.ui.subtype_comboBox.setCurrentIndex(-1)
        self.ui.range_lineEdit.setText('')

        doc = QtGui.QTextDocument()
        doc.setPlainText('')
        layout = QtModule.QPlainTextDocumentLayout(doc)
        doc.setDocumentLayout(layout)
        self.ui.descr_plainTextEdit.setDocument(doc)

    #
    # Remove stackedWidget's layout every time,
    # when current parameter (or it's type) is changing
    #
    def removeValueWidget(self):
        #
        while True:
            currentWidget = self.ui.value_stackedWidget.currentWidget()
            if currentWidget is not None:
                #print '> removeWidget: %s' % str( currentWidget )
                self.ui.value_stackedWidget.removeWidget(currentWidget)
            else:
                break

    #
    # setParam
    #
    def setParam(self, param):
        #
        self.removeValueWidget()
        self.disconnectSignals()
        self.param = param

        if self.param is not None:
            #import copy
            self.param_default = self.param.copy(
            )  # duplicate param for default value editing
            self.param_default.value = param.default

            self.ui.name_lineEdit.setText(self.param.name)
            self.ui.label_lineEdit.setText(self.param.label)

            self.ui.check_enabled.setChecked(self.param.enabled)
            self.ui.check_display.setChecked(self.param.display)
            self.ui.check_shader.setChecked(self.param.shaderParam)

            self.ui.type_comboBox.setCurrentIndex(
                self.ui.type_comboBox.findText(self.param.type))
            self.ui.detail_comboBox.setCurrentIndex(
                self.ui.detail_comboBox.findText(self.param.detail))
            self.ui.provider_comboBox.setCurrentIndex(
                self.ui.provider_comboBox.findText(self.param.provider))
            self.ui.subtype_comboBox.setCurrentIndex(
                self.ui.subtype_comboBox.findText(self.param.subtype))
            self.ui.range_lineEdit.setText(self.param.range)

            doc = QtGui.QTextDocument()
            help_text = ''
            if self.param.help != None: help_text = self.param.help

            doc.setPlainText(help_text)
            layout = QtModule.QPlainTextDocumentLayout(doc)
            doc.setDocumentLayout(layout)

            self.ui.descr_plainTextEdit.setDocument(doc)
            #
            # setup param values view
            #
            paramsLayout = QtModule.QGridLayout()
            paramsLayout.setContentsMargins(2, 2, 2, 2)
            paramsLayout.setSizeConstraint(QtModule.QLayout.SetNoConstraint)
            paramsLayout.setVerticalSpacing(4)
            paramsLayout.setColumnStretch(1, 1)
            paramsLayout.setRowStretch(2, 1)

            frame = QtModule.QFrame()
            frame.setLayout(paramsLayout)

            if self.param.type in self.paramWidgets.keys():
                print '>> Create %s param widget' % self.param.type

                # create paramWidget without GfxNode and ignoreSubtype = True
                self.ui.value_widget = apply(
                    self.paramWidgets[self.param.type],
                    [self.param, None, True])
                self.ui.value_widget.label.setText('Current Value')

                paramsLayout.addLayout(self.ui.value_widget.label_vl, 0, 0, 1,
                                       1)
                paramsLayout.addLayout(self.ui.value_widget.param_vl, 0, 1, 1,
                                       1)

                self.ui.def_value_widget = apply(
                    self.paramWidgets[self.param_default.type],
                    [self.param_default, None, True])
                self.ui.def_value_widget.label.setText('Default Value')

                paramsLayout.addLayout(self.ui.def_value_widget.label_vl, 1, 0,
                                       1, 1)
                paramsLayout.addLayout(self.ui.def_value_widget.param_vl, 1, 1,
                                       1, 1)

                spacer = QtModule.QSpacerItem(20, 20,
                                              QtModule.QSizePolicy.Minimum,
                                              QtModule.QSizePolicy.Expanding)
                paramsLayout.addItem(spacer, 2, 0, 1, 1)

            self.ui.value_stackedWidget.addWidget(frame)
            self.connectSignals()
        else:
            self.reset()

    #
    # onEditParamName
    #
    def onEditParamName(self):
        #
        # !!! ListWidget item for param also should be changed
        #
        oldName = self.param.name
        newName = str(self.ui.name_lineEdit.text()).strip()
        if newName == '':
            newName = oldName
            self.ui.name_lineEdit.setText(newName)
        if newName != oldName:
            self.param.name = newName
            if usePyQt4:
                self.emit(QtCore.SIGNAL('changeParamName'), oldName, newName)
            else:
                self.changeParamName.emit(oldName, newName)

    #
    # onEditParamLabel
    #
    def onEditParamLabel(self):
        #
        oldName = self.param.label
        newName = str(self.ui.label_lineEdit.text()).strip()
        if newName == '':
            newName = oldName
            self.ui.label_lineEdit.setText(newName)
        if newName != oldName:
            self.param.label = newName
            if usePyQt4:
                self.emit(QtCore.SIGNAL('changeParamLabel'), oldName, newName)
            else:
                self.changeParamLabel.emit(oldName, newName)

    #
    # onEditParamEnabled
    #
    def onEditParamEnabled(self, value):
        #
        self.param.enabled = self.ui.check_enabled.isChecked()

    #
    # onEditParamEnabled
    #
    def onEditParamDisplay(self, value):
        #
        self.param.display = self.ui.check_display.isChecked()

    #
    # onEditParamShader
    #
    def onEditParamShader(self, value):
        #
        self.param.shaderParam = self.ui.check_shader.isChecked()
        if usePyQt4:
            self.emit(QtCore.SIGNAL('changeParamIsShader'), self.param)
        else:
            self.changeParamIsShader.emit(self.param)

    #
    # onEditParamType
    #
    def onEditParamType(self, idx):
        #
        # !!! UI for param.value and param.default also should be changed
        #
        self.param.type = str(self.ui.type_comboBox.itemText(idx))
        if usePyQt4:
            self.emit(QtCore.SIGNAL('changeParamType'), self.param)
        else:
            self.changeParamType.emit(self.param)

    #
    # onEditParamDetail
    #
    def onEditParamDetail(self, idx):
        #
        self.param.detail = str(self.ui.detail_comboBox.itemText(idx))
        if usePyQt4:
            self.emit(QtCore.SIGNAL('changeParamDetail'), self.param)
        else:
            self.changeParamDetail.emit(self.param)

    #
    # onEditParamProvider
    #
    def onEditParamProvider(self, idx):
        #
        self.param.provider = str(self.ui.provider_comboBox.itemText(idx))
        if usePyQt4:
            self.emit(QtCore.SIGNAL('changeParamProvider'), self.param)
        else:
            self.changeParamProvider.emit(self.param)

    #
    # onEditParamSubtype
    #
    def onEditParamSubtype(self, idx):
        #
        self.param.subtype = str(self.ui.subtype_comboBox.itemText(idx))
        if usePyQt4:
            self.emit(QtCore.SIGNAL('changeParamSubtype'), self.param)
        else:
            self.changeParamSubtype.emit(self.param)

    #
    # onEditParamRange
    #
    def onEditParamRange(self):
        #
        self.param.range = str(self.ui.range_lineEdit.text())
        if usePyQt4:
            self.emit(QtCore.SIGNAL('changeParamRange'), self.param)
        else:
            self.changeParamRange.emit(self.param)

    #
    # onEditParamHelp
    #
    def onEditParamHelp(self):
        #
        self.param.help = str(self.ui.descr_plainTextEdit.toPlainText())
示例#11
0
class meRendererSetup(QtModule.QDialog):
    #
    # __init__
    #
    def __init__(self, rendererPreset):
        #
        QtModule.QDialog.__init__(self)
        #
        # Define signals for PyQt5
        #
        if usePySide or usePyQt5:
            #
            self.presetChanged = Signal()
            self.savePreset = Signal()
            #
        self.rendererPreset = rendererPreset
        self.labelsReady = False
        self.buildGui()

    #
    # buildGui
    #
    def buildGui(self):
        # build the gui created with QtDesigner
        import sys
        self.ui = Ui_meRendererSetup()
        self.ui.setupUi(self)

        font = QtGui.QFont()
        if (sys.platform == 'win32'):
            # Runing on windows, override font sizes from Designer to default
            font.setPointSize(8)
        else:
            font.setPointSize(10)
        self.ui.labelPreset.setFont(font)
        self.ui.listPreset.setFont(font)
        self.ui.newButton.setFont(font)
        self.ui.deleteButton.setFont(font)
        self.ui.cancelButton.setFont(font)
        self.ui.okButton.setFont(font)
        self.ui.saveButton.setFont(font)
        self.ui.tabs.setFont(font)
        self.ui.labelName.setFont(font)
        self.ui.labelCmd.setFont(font)
        self.ui.labelFlags.setFont(font)
        self.ui.labelCompiler.setFont(font)
        self.ui.labelShaderInfo.setFont(font)
        self.ui.labelDefines.setFont(font)
        self.ui.labelShaderExt.setFont(font)
        self.ui.labelShaderExt.setFont(font)
        self.ui.labelTexMake.setFont(font)
        self.ui.labelTexInfo.setFont(font)
        self.ui.labelTexViewer.setFont(font)
        self.ui.labelTexExt.setFont(font)

        self.labelsReady = False

        for label in self.rendererPreset.getPresetNames():
            self.ui.listPreset.addItem(label)

        self.labelsReady = True

        presetName = self.rendererPreset.getCurrentPresetName()
        idx = self.ui.listPreset.findText(presetName)
        print ">> buildGui:: set current renderer to: %s (%d)" % (presetName,
                                                                  idx)
        #self.ui.listPreset.setCurrentIndex ( -1 )
        self.ui.listPreset.setCurrentIndex(idx)

    #
    # getDataFromGui
    #
    def getDataFromGui(self):
        # ckeck if current_renderer still exists after deleting preset
        #print ">> getDataFromGui:: current renderer to: %s" % self.rendererPreset.getCurrentPresetName()

        self.rendererPreset.currentPreset.RendererName = str(
            self.ui.lineCmd.text())
        self.rendererPreset.currentPreset.RendererFlags = str(
            self.ui.lineFlags.text())
        self.rendererPreset.currentPreset.ShaderCompiler = str(
            self.ui.lineCompiler.text())
        self.rendererPreset.currentPreset.ShaderInfo = str(
            self.ui.lineShaderInfo.text())
        self.rendererPreset.currentPreset.ShaderDefines = str(
            self.ui.lineDefines.text())
        self.rendererPreset.currentPreset.ShaderExt = str(
            self.ui.lineShaderExt.text())
        self.rendererPreset.currentPreset.TextureMake = str(
            self.ui.lineTexMake.text())
        self.rendererPreset.currentPreset.TextureInfo = str(
            self.ui.lineTexInfo.text())
        self.rendererPreset.currentPreset.TextureViewer = str(
            self.ui.lineTexViewer.text())
        self.rendererPreset.currentPreset.TextureExt = str(
            self.ui.lineTexExt.text())

    #
    # onIndexChanged
    #
    def onIndexChanged(self, name):
        if DEBUG_MODE:
            print ">> onIndexChanged:: nam = %s self.labelsReady == %d" % (
                name, self.labelsReady)
        #if DEBUG_MODE : print self.ui.listPreset.currentText ()
        name = self.ui.listPreset.currentText()
        if (self.labelsReady and name != ''):
            # change current renderer
            self.rendererPreset.setCurrentPresetByName(str(name))
        self.updateGui()

    #
    # updateGui
    #
    def updateGui(self):
        # redraw gui elements
        #print ">> updateGui:: current renderer: %s" % self.rendererPreset.getCurrentPresetName()
        if len(self.rendererPreset.presetsList) > 0:
            if self.rendererPreset.currentPreset is not None:
                self.ui.lineName.setText(
                    self.rendererPreset.getCurrentPresetName())
                self.ui.lineCmd.setText(
                    self.rendererPreset.currentPreset.RendererName)
                self.ui.lineFlags.setText(
                    self.rendererPreset.currentPreset.RendererFlags)
                self.ui.lineCompiler.setText(
                    self.rendererPreset.currentPreset.ShaderCompiler)
                self.ui.lineShaderInfo.setText(
                    self.rendererPreset.currentPreset.ShaderInfo)
                self.ui.lineDefines.setText(
                    self.rendererPreset.currentPreset.ShaderDefines)
                self.ui.lineShaderExt.setText(
                    self.rendererPreset.currentPreset.ShaderExt)
                self.ui.lineTexMake.setText(
                    self.rendererPreset.currentPreset.TextureMake)
                self.ui.lineTexInfo.setText(
                    self.rendererPreset.currentPreset.TextureInfo)
                self.ui.lineTexViewer.setText(
                    self.rendererPreset.currentPreset.TextureViewer)
                self.ui.lineTexExt.setText(
                    self.rendererPreset.currentPreset.TextureExt)
                self.ui.deleteButton.setEnabled(True)
                self.ui.tab1.setEnabled(True)
                self.ui.tab2.setEnabled(True)
                self.ui.tab3.setEnabled(True)
        else:
            self.ui.deleteButton.setEnabled(False)
            self.ui.tab1.setEnabled(False)
            self.ui.tab2.setEnabled(False)
            self.ui.tab3.setEnabled(False)
            self.ui.lineName.clear()
            self.ui.lineCmd.clear()
            self.ui.lineFlags.clear()
            self.ui.lineCompiler.clear()
            self.ui.lineShaderInfo.clear()
            self.ui.lineDefines.clear()
            self.ui.lineShaderExt.clear()
            self.ui.lineTexMake.clear()
            self.ui.lineTexInfo.clear()
            self.ui.lineTexViewer.clear()
            self.ui.lineTexExt.clear()

    #
    # onNewPreset
    #
    def onNewPreset(self):
        # create new empty preset
        title = 'Untitled'
        newLabel = title
        #self.labelsReady = False
        i = 0
        while True:
            if newLabel in self.rendererPreset.getPresetNames():
                newLabel = title + str(i)
                i += 1
                continue
            else:
                break
        self.rendererPreset.addPreset(newLabel)
        #self.labelsReady = True
        self.ui.listPreset.addItem(newLabel)
        idx = self.ui.listPreset.findText(newLabel)
        self.ui.listPreset.setCurrentIndex(-1)
        self.ui.listPreset.setCurrentIndex(idx)
        #self.updateGui ()

    #
    # onDeletePreset
    #
    def onDeletePreset(self):
        # delete existing preset
        if len(self.rendererPreset.presetsList) > 0:
            msgBox = QtModule.QMessageBox()
            ret = msgBox.warning(self, 'Warning',
                                 "Do you really want to delete this preset?",
                                 QtGui.QMessageBox.Yes | QtGui.QMessageBox.No,
                                 QtGui.QMessageBox.No)

            if ret == QtModule.QMessageBox.Yes:
                self.rendererPreset.deleteCurrentPreset()
                i = self.ui.listPreset.currentIndex()
                self.ui.listPreset.removeItem(i)
                self.rendererPreset.setCurrentPresetByName(
                    str(self.ui.listPreset.currentText()))

    #
    # onEditLabel
    #
    def onEditLabel(self):
        # edit label
        newLabel = str(self.ui.lineName.text())
        if (self.rendererPreset.getCurrentPresetName() != newLabel):
            if newLabel not in self.rendererPreset.getPresetNames():
                self.rendererPreset.renameCurrentPreset(newLabel)
                # rename current preset ComboBox item to new label
                i = self.ui.listPreset.currentIndex()
                self.ui.listPreset.setItemText(i, newLabel)
            else:
                # this label already exists, so restore to previose
                self.ui.lineName.setText(
                    self.rendererPreset.getCurrentPresetName())

    #
    # onSave
    #
    def onSave(self):
        # get data from Gui for current renderer before saving
        self.getDataFromGui()
        if usePyQt4:
            self.emit(QtCore.SIGNAL('presetChanged'))
            self.emit(QtCore.SIGNAL('savePreset'))
        else:
            self.presetChanged.emit()
            self.savePreset.emit()
        #self.done ( 0 )

    #
    # onSelect
    #
    def onSelect(self):
        # get data from Gui for current renderer before saving
        self.getDataFromGui()
        if usePyQt4:
            self.emit(QtCore.SIGNAL('presetChanged'))
        else:
            self.presetChanged.emit()
        self.done(0)
示例#12
0
class NodeNamesEditor(QtModule.QWidget):
    #
    # __init__
    #
    def __init__(self, parent):
        #
        QtModule.QWidget.__init__(self, parent)
        #
        # Define signals for PyQt5
        #
        if usePySide or usePyQt5:
            #
            self.selectionChangedSignal = Signal()
            self.addItem = Signal()
            self.removeItem = Signal()
            self.renameItem = Signal()
        #
        self.saved_text = ''
        self.approvedNewName = ''
        self.buildGui()

    #
    # buildGui
    #
    def buildGui(self):
        # build the gui created with QtDesigner
        self.ui = Ui_NodeNamesEditor()
        self.ui.setupUi(self)

    #
    # setName
    #
    def setName(self, newName):
        #
        if newName == '':
            if self.saved_text != '':
                newName = self.saved_text

        self.ui.name_lineEdit.setText(newName)
        self.saved_text = newName

    #
    # onAddItem
    #
    def onAddItem(self):
        #
        if DEBUG_MODE: print('>> NodeNamesEditor: onAddItem')
        new_text = str(self.ui.name_lineEdit.text()).strip()
        if new_text != '':
            if usePyQt4:
                self.emit(QtCore.SIGNAL('addItem'), new_text)
            else:
                self.addItem.emit(new_text)

    #
    # onRemoveItem
    #
    def onRemoveItem(self):
        #
        if DEBUG_MODE: print('>> NodeNamesEditor::onRemoveItem')
        list_item = self.ui.listWidget.currentItem()

        if list_item is not None:
            item_text = str(list_item.text())
            #self.ui.listWidget.takeItem ( self.ui.listWidget.currentRow () )
            #self.ui.listWidget.removeItemWidget ( list_item )
            if usePyQt4:
                self.emit(QtCore.SIGNAL('removeItem'), item_text)
            else:
                self.removeItem.emit(item_text)

    #
    # onRenameItem
    #
    def onRenameItem(self):
        #
        if DEBUG_MODE: print('>> NodeNamesEditor.onRenameItem')
        new_text = str(self.ui.name_lineEdit.text()).strip()

        if new_text == '':
            if self.saved_text != '':
                new_text = self.saved_text
                self.ui.name_lineEdit.setText(new_text)

        list_item = self.ui.listWidget.currentItem()

        if list_item is not None:  # e.g. listWidget is not empty
            old_text = list_item.text()
            if new_text != old_text:
                if usePyQt4:
                    self.emit(QtCore.SIGNAL('renameItem'), old_text, new_text)
                else:
                    self.renameItem.emit(old_text, new_text)
            else:
                self.ui.listWidget.clearSelection()
                self.ui.listWidget.setCurrentItem(None)

    #
    # onSelectionChanged
    #
    def onSelectionChanged(self):
        #
        if DEBUG_MODE: print('>> NodeNamesEditor.onSelectionChanged')
        list_item = self.ui.listWidget.currentItem()

        if list_item is not None:
            self.saved_text = str(list_item.text())
            self.ui.name_lineEdit.setText(self.saved_text)
            if usePyQt4:
                self.emit(QtCore.SIGNAL('selectionChangedSignal'),
                          self.saved_text)
            else:
                self.selectionChangedSignal.emit(self.saved_text)
示例#13
0
class NodeParamView ( QtModule.QWidget ) :
	#
	# __init__
	#
	def __init__ ( self ) :
		#
		QtModule.QWidget.__init__ ( self )
		#
		# Define signals for PyQt5
		#
		if usePySide or usePyQt5 :
			#
			self.nodeParamChangedSignal = Signal ()
			self.nodeLabelChangedSignal = Signal ()
			#
		self.gfxNode = None
		
		self.inputParamListTab = None
		self.outputParamListTab = None
		
		self.showConnected = False
		self.buildGui ()
		self.updateGui ()
		self.connectSignals ()
	#
	# setNode
	#
	def setNode ( self, gfxNode ) :
		#
		#if DEBUG_MODE : print ">> NodeParamView.setNode"
		self.disconnectParamSignals ()
		self.gfxNode = gfxNode
		self.inputParamListTab.setNode ( gfxNode )
		self.outputParamListTab.setNode ( gfxNode )
		self.nameEdit.setEnabled ( self.gfxNode is not None )
		self.updateGui ()
		self.connectParamSignals ()
	#
	# connectSignals
	#
	def connectSignals ( self ) :
		#
		if usePyQt4 :
			self.connect ( self.nameEdit, QtCore.SIGNAL ( 'editingFinished()' ), self.nodeLabelChanged )
			self.connect ( self.showConnectButton, QtCore.SIGNAL ( 'toggled(bool)' ), self.showConnections )
		else :
			self.nameEdit.editingFinished.connect ( self.nodeLabelChanged )
			self.showConnectButton.toggled.connect ( self.showConnections )
	#
	# disconnectSignals
	#
	def disconnectSignals ( self ) :
		#
		if usePyQt4 :
			self.disconnect ( self.nameEdit, QtCore.SIGNAL ( 'editingFinished()' ), self.nodeLabelChanged )
			self.disconnect ( self.showConnectButton, QtCore.SIGNAL ( 'toggled(bool)' ), self.showConnections )
		else :
			self.nameEdit.editingFinished.disconnect ( self.nodeLabelChanged )
			self.showConnectButton.toggled.disconnect ( self.showConnections )
	#
	# connectParamSignals
	#
	def connectParamSignals ( self ) :
		#print ">> NodeParamView.connectParamSignals"
		if self.gfxNode is not None :
			for inputParam in self.gfxNode.node.inputParams :
				if usePyQt4 :
					self.connect ( inputParam, QtCore.SIGNAL ( 'paramChangedSignal(QObject)' ), self.onParamChanged )
				else :
					inputParam.paramChangedSignal.connect ( self.onParamChanged )
			for outputParam in self.gfxNode.node.outputParams :
				if usePyQt4 :
					self.connect ( outputParam, QtCore.SIGNAL ( 'paramChangedSignal(QObject)' ), self.onParamChanged )
				else :
					outputParam.paramChangedSignal.connect ( self.onParamChanged )
	#
	# disconnectParamSignals
	#
	def disconnectParamSignals ( self ) :
		#print ">> NodeParamView.disconnectParamSignals"
		if self.gfxNode is not None :
			for inputParam in self.gfxNode.node.inputParams :
				if usePyQt4 :
					self.disconnect ( inputParam, QtCore.SIGNAL ( 'paramChangedSignal(QObject)' ), self.onParamChanged )
				else :
					inputParam.paramChangedSignal.disconnect ( self.onParamChanged )
			for outputParam in self.gfxNode.node.outputParams :
				if usePyQt4 :
					self.disconnect ( outputParam, QtCore.SIGNAL ( 'paramChangedSignal(QObject)' ), self.onParamChanged )
				else :
					outputParam.paramChangedSignal.disconnect ( self.onParamChanged )
	#
	# showConnections
	#
	def showConnections ( self, show ) :
		#
		print ">> NodeParamView.showConnections %s" % show
		self.showConnected = show
		self.inputParamListTab.showConnected = show
		self.outputParamListTab.showConnected = show
		self.inputParamListTab.updateGui ()
		self.outputParamListTab.updateGui ()
	#
	# onParamChanged
	#
	def onParamChanged ( self, param ) :
		#
		if DEBUG_MODE : print ( ">> NodeParamView.onParamChanged node = %s param = %s" % ( self.gfxNode.node.label, param.name ) )
		if usePyQt4 :
			self.emit ( QtCore.SIGNAL ( 'nodeParamChangedSignal' ), self.gfxNode, param ) # .node
		else :
			self.nodeParamChangedSignal.emit ( self.gfxNode, param ) # .node
	#
	# nodeLabelChanged
	#
	def nodeLabelChanged ( self ) :
		#
		#if DEBUG_MODE : print ">> NodeParamView.nodeLabelChanged"
		if self.gfxNode is not None :
			from core.meCommon import getParsedLabel
			newLabel = getParsedLabel ( self.nameEdit.text () )
			#if DEBUG_MODE : print "** newLabel = %s" % newLabel
			if newLabel != '' :
				# update label only if realy changed
				if newLabel != self.gfxNode.node.label :
					# rename node label if same name exists in NodeNet
					if usePyQt4 :
						self.emit ( QtCore.SIGNAL ( 'nodeLabelChangedSignal' ), self.gfxNode, newLabel )
					else :
						self.nodeLabelChangedSignal.emit ( self.gfxNode, newLabel )
					self.nameEdit.clear ()
			self.nameEdit.setText ( self.gfxNode.node.label )
	#
	# buildGui
	#
	def buildGui ( self ) :
		#
		label = QtModule.QLabel ()
		label.setMinimumSize ( QtCore.QSize ( UI.NODE_LABEL_WIDTH, UI.HEIGHT ) )
		label.setMaximumSize ( QtCore.QSize ( UI.NODE_LABEL_WIDTH, UI.HEIGHT ) )

		font = QtGui.QFont ()
		label.setFont ( font )
		#label.setAlignment(QtCore.Qt.AlignCenter)
		label.setText ( 'Label' )

		self.nameEdit = QtModule.QLineEdit ()
		self.nameEdit.setMaximumSize ( QtCore.QSize ( UI.MAX, UI.HEIGHT ) )
		self.nameEdit.setEnabled ( False )
		
		self.showConnectButton = QtModule.QToolButton ( self )
		sizePolicy = QtModule.QSizePolicy ( QtModule.QSizePolicy.Fixed, QtModule.QSizePolicy.Fixed )
		sizePolicy.setHorizontalStretch ( 20 )
		sizePolicy.setVerticalStretch ( 20 )
		sizePolicy.setHeightForWidth ( self.showConnectButton.sizePolicy().hasHeightForWidth() )
		self.showConnectButton.setSizePolicy ( sizePolicy )
		self.showConnectButton.setMaximumSize ( QtCore.QSize ( 20, 20 ) )
		icon = QtGui.QIcon ()
		icon.addPixmap ( QtGui.QPixmap ( ':/show_icons/resources/show_connect.png' ), QtGui.QIcon.Normal, QtGui.QIcon.On )
		self.showConnectButton.setIcon ( icon )
		self.showConnectButton.setAutoRaise ( False )
		self.showConnectButton.setCheckable ( True )
		self.showConnectButton.setChecked ( self.showConnected ) 
		self.showConnectButton.setToolTip ( 'Show connected parameters' )
		#self.showConnectButton.setIconSize ( QtCore.QSize ( 16, 16 ) )
		self.showConnectButton.setObjectName ( 'showConnectButton' )

		headerLayout = QtModule.QHBoxLayout ()
		headerLayout.setSpacing ( UI.SPACING )
		headerLayout.setContentsMargins ( UI.SPACING, UI.SPACING, UI.SPACING, UI.SPACING )
		headerLayout.setStretch ( 1, 1 )

		headerLayout.addWidget ( label )
		headerLayout.addWidget ( self.nameEdit )
		headerLayout.addWidget ( self.showConnectButton )

		mainLayout = QtModule.QVBoxLayout ()
		mainLayout.addLayout ( headerLayout )
		
		self.params_tabs = QtModule.QTabWidget ( self )
		
		self.inputParamListTab = NodeParamListTab ( self, self.gfxNode, isInput = True, showConnected = self.showConnected )
		self.params_tabs.addTab ( self.inputParamListTab, 'Input' )
		
		self.outputParamListTab = NodeParamListTab ( self, self.gfxNode, isInput = False, showConnected = self.showConnected )
		self.params_tabs.addTab ( self.outputParamListTab, 'Output' )
		
		self.params_tabs.setCurrentIndex ( 0 )
		
		mainLayout.addWidget ( self.params_tabs )
		
		self.setLayout ( mainLayout )
	#
	# updateGui
	#
	def updateGui ( self ) :
		#
		#if DEBUG_MODE : print '>> NodeParamView.updateGui'
			
		self.nameEdit.clear ()
		if self.gfxNode is not None :
			self.nameEdit.setText ( self.gfxNode.node.label )
		
		self.inputParamListTab.updateGui ()
		self.outputParamListTab.updateGui ()
		
示例#14
0
class NodeNamesEditor ( QtModule.QWidget ) :
	#
	# __init__
	#
	def __init__ ( self, parent ) :
		#
		QtModule.QWidget.__init__ ( self, parent )
		#
		# Define signals for PyQt5
		#
		if usePySide or usePyQt5 :
			#
			self.selectionChangedSignal = Signal ()
			self.addItem = Signal ()
			self.removeItem = Signal ()
			self.renameItem = Signal ()
		#
		self.saved_text = ''
		self.approvedNewName = ''
		self.buildGui ()
	#
	# buildGui
	#
	def buildGui ( self ):
		# build the gui created with QtDesigner
		self.ui = Ui_NodeNamesEditor ( )
		self.ui.setupUi ( self )
	#
	# setName
	#
	def setName ( self, newName ) :
		#
		if newName == '' :
			if self.saved_text != '' :
				newName = self.saved_text

		self.ui.name_lineEdit.setText ( newName )
		self.saved_text = newName     
	#
	# onAddItem
	#
	def onAddItem ( self ) :
		#
		if DEBUG_MODE : print '>> NodeNamesEditor: onAddItem'
		new_text = str ( self.ui.name_lineEdit.text () ).strip ()
		if new_text != '' :
			if  usePyQt4 :
				self.emit ( QtCore.SIGNAL ( 'addItem' ), new_text )
			else :
				self.addItem.emit ( new_text ) 
	#  
	# onRemoveItem
	#
	def onRemoveItem ( self ) :
		#
		if DEBUG_MODE : print '>> NodeNamesEditor::onRemoveItem'
		list_item = self.ui.listWidget.currentItem ()
		
		if list_item is not None :
			item_text = str ( list_item.text () )
			#self.ui.listWidget.takeItem ( self.ui.listWidget.currentRow () )
			#self.ui.listWidget.removeItemWidget ( list_item )
			if  usePyQt4 :
				self.emit ( QtCore.SIGNAL ( 'removeItem' ), item_text )
			else :
				self.removeItem.emit ( item_text )
	#
	# onRenameItem
	#
	def onRenameItem ( self ) :
		#
		if DEBUG_MODE : print '>> NodeNamesEditor.onRenameItem'
		new_text = str ( self.ui.name_lineEdit.text () ).strip ()
		
		if new_text == '' :
			if self.saved_text != '' :
				new_text = self.saved_text
				self.ui.name_lineEdit.setText ( new_text )  
						
		list_item = self.ui.listWidget.currentItem ()
		
		if list_item is not None : # e.g. listWidget is not empty
			old_text = list_item.text ()
			if new_text != old_text :
				if  usePyQt4 :
					self.emit ( QtCore.SIGNAL( 'renameItem' ), old_text, new_text )
				else :
					self.renameItem.emit ( old_text, new_text )
			else :  
				self.ui.listWidget.clearSelection ()
				self.ui.listWidget.setCurrentItem ( None )
	#    
	# onSelectionChanged
	#
	def onSelectionChanged ( self ) :
		#
		if DEBUG_MODE : print '>> NodeNamesEditor.onSelectionChanged'
		list_item = self.ui.listWidget.currentItem ()
		
		if list_item is not None :
			self.saved_text = str ( list_item.text() )
			self.ui.name_lineEdit.setText ( self.saved_text  )
			if  usePyQt4 :
				self.emit ( QtCore.SIGNAL ( 'selectionChangedSignal' ), self.saved_text  ) 
			else :
				self.selectionChangedSignal.emit ( self.saved_text  ) 
class NodePropertiesEditor(QtModule.QWidget):
    #
    # __init__
    #
    def __init__(self, parent, editNode=None):
        #
        QtModule.QWidget.__init__(self, parent)
        #
        # Define signals for PyQt5
        #
        if usePySide or usePyQt5:
            #
            self.changeNodeLabel = Signal()
            #
        self.editNode = editNode

        #self.debugPrint()
        self.buildGui()
        self.setNode(editNode)

    #
    # buildGui
    #
    def buildGui(self):
        # build the gui created with QtDesigner
        self.ui = Ui_NodePropertiesEditor()
        self.ui.setupUi(self)

    #
    # setNode
    #
    def setNode(self, editNode):
        #
        self.disconnectSignals()
        self.editNode = editNode

        if self.editNode is not None:
            #
            name = self.editNode.name
            if self.editNode.name is None: name = ''
            self.ui.name_lineEdit.setText(name)

            label = self.editNode.label
            if self.editNode.label is None: label = ''
            self.ui.label_lineEdit.setText(label)

            author = self.editNode.author
            if self.editNode.author is None: author = ''
            self.ui.author_lineEdit.setText(author)

            master = self.editNode.master
            if self.editNode.master is None: master = ''
            self.ui.master_lineEdit.setText(master)

            icon = self.editNode.icon
            if self.editNode.icon is None: icon = ''
            self.ui.icon_lineEdit.setText(icon)
            # print '* self.editNode.help = %s' %  self.editNode.help

            doc = QtGui.QTextDocument()
            help_text = ''
            if self.editNode.help != None:
                help_text = self.editNode.help

            doc.setPlainText(help_text)
            layout = QtModule.QPlainTextDocumentLayout(doc)
            doc.setDocumentLayout(layout)

            self.ui.help_plainTextEdit.setDocument(doc)

            self.ui.id_lineEdit.setText(str(self.editNode.id))

            self.ui.type_comboBox.setEditable(False)
            self.ui.type_comboBox.setMinimumSize(
                QtCore.QSize(UI.COMBO_WIDTH, UI.COMBO_HEIGHT))
            self.ui.type_comboBox.setMaximumSize(
                QtCore.QSize(UI.MAX, UI.COMBO_HEIGHT))

            currentIdx = -1
            i = 0
            for label in VALID_NODE_TYPES:
                self.ui.type_comboBox.addItem(label)
                if label == self.editNode.type:
                    currentIdx = i
                i += 1

            self.ui.type_comboBox.setCurrentIndex(currentIdx)

            # temporary disabled, until "how to do it gracefully" will be clear ...
            self.ui.type_comboBox.setEnabled(False)

            self.connectSignals()

    #
    # connectSignals
    #
    def connectSignals(self):
        # QtCore.QObject.
        if usePyQt4:
            self.connect(self.ui.name_lineEdit,
                         QtCore.SIGNAL('editingFinished()'),
                         self.onEditNodeStrAttrName)
            self.connect(self.ui.label_lineEdit,
                         QtCore.SIGNAL('editingFinished()'),
                         self.onEditNodeStrAttrLabel)
            self.connect(self.ui.master_lineEdit,
                         QtCore.SIGNAL('editingFinished()'),
                         self.onEditNodeStrAttrMaster)
            self.connect(self.ui.author_lineEdit,
                         QtCore.SIGNAL('editingFinished()'),
                         self.onEditNodeStrAttrAuthor)
            self.connect(self.ui.icon_lineEdit,
                         QtCore.SIGNAL('editingFinished()'),
                         self.onEditNodeStrAttrIcon)
            self.connect(self.ui.type_comboBox,
                         QtCore.SIGNAL('activated(int)'), self.onEditNodeType)
            self.connect(self.ui.help_plainTextEdit,
                         QtCore.SIGNAL('textChanged()'),
                         self.onEditNodeTxtAttr)
        else:
            self.ui.name_lineEdit.editingFinished.connect(
                self.onEditNodeStrAttrName)
            self.ui.label_lineEdit.editingFinished.connect(
                self.onEditNodeStrAttrLabel)
            self.ui.master_lineEdit.editingFinished.connect(
                self.onEditNodeStrAttrMaster)
            self.ui.author_lineEdit.editingFinished.connect(
                self.onEditNodeStrAttrAuthor)
            self.ui.icon_lineEdit.editingFinished.connect(
                self.onEditNodeStrAttrIcon)
            self.ui.type_comboBox.activated.connect(self.onEditNodeType)
            self.ui.help_plainTextEdit.textChanged.connect(
                self.onEditNodeTxtAttr)

    #
    # disconnectSignals
    #
    def disconnectSignals(self):
        #
        if usePyQt4:
            if self.editNode is not None:
                self.disconnect(self.ui.name_lineEdit,
                                QtCore.SIGNAL('editingFinished()'),
                                self.onEditNodeStrAttrName)
                self.disconnect(self.ui.label_lineEdit,
                                QtCore.SIGNAL('editingFinished()'),
                                self.onEditNodeStrAttrLabel)
                self.disconnect(self.ui.master_lineEdit,
                                QtCore.SIGNAL('editingFinished()'),
                                self.onEditNodeStrAttrMaster)
                self.disconnect(self.ui.author_lineEdit,
                                QtCore.SIGNAL('editingFinished()'),
                                self.onEditNodeStrAttrAuthor)
                self.disconnect(self.ui.icon_lineEdit,
                                QtCore.SIGNAL('editingFinished()'),
                                self.onEditNodeStrAttrIcon)
                self.disconnect(self.ui.type_comboBox,
                                QtCore.SIGNAL('activated(int)'),
                                self.onEditNodeType)
                self.disconnect(self.ui.help_plainTextEdit,
                                QtCore.SIGNAL('textChanged()'),
                                self.onEditNodeTxtAttr)
        else:
            if self.editNode is not None:
                self.ui.name_lineEdit.editingFinished.disconnect(
                    self.onEditNodeStrAttrName)
                self.ui.label_lineEdit.editingFinished.disconnect(
                    self.onEditNodeStrAttrLabel)
                self.ui.master_lineEdit.editingFinished.disconnect(
                    self.onEditNodeStrAttrMaster)
                self.ui.author_lineEdit.editingFinished.disconnect(
                    self.onEditNodeStrAttrAuthor)
                self.ui.icon_lineEdit.editingFinished.disconnect(
                    self.onEditNodeStrAttrIcon)
                self.ui.type_comboBox.activated.disconnect(self.onEditNodeType)
                self.ui.help_plainTextEdit.textChanged.disconnect(
                    self.onEditNodeTxtAttr)

    #
    #
    # doesn't work ...
    #
    def onEditNodeStrAttr(self, attr=None):
        #
        if attr is not None and self.editNode is not None:
            if attr == 'name':
                self.editNode.name = str(self.ui.name_lineEdit.text())
            elif attr == 'label':
                self.editNode.label = str(self.ui.label_lineEdit.text())
            elif attr == 'master':
                self.editNode.master = str(self.ui.master_lineEdit.text())
            elif attr == 'author':
                self.editNode.author = str(self.ui.author_lineEdit.text())
            elif attr == 'icon':
                self.editNode.icon = str(self.ui.icon_lineEdit.text())

    #
    #
    #
    def onEditNodeStrAttrName(self):
        self.editNode.name = str(self.ui.name_lineEdit.text())

    def onEditNodeStrAttrLabel(self):
        #
        oldLabel = self.editNode.label
        newLabel = str(self.ui.label_lineEdit.text()).strip()
        if newLabel == '':
            if usePyQt4:
                self.disconnect(self.ui.label_lineEdit,
                                QtCore.SIGNAL('editingFinished()'),
                                self.onEditNodeStrAttrLabel)
            else:
                self.ui.label_lineEdit.editingFinished.disconnect(
                    self.onEditNodeStrAttrLabel)
            newLabel = oldLabel
            self.ui.label_lineEdit.setText(newLabel)
            if usePyQt4:
                self.connect(self.ui.label_lineEdit,
                             QtCore.SIGNAL('editingFinished()'),
                             self.onEditNodeStrAttrLabel)
            else:
                self.ui.label_lineEdit.editingFinished.connect(
                    self.onEditNodeStrAttrLabel)
        if newLabel != oldLabel:
            self.editNode.label = newLabel
            if usePyQt4:
                self.emit(QtCore.SIGNAL('changeNodeLabel'), oldLabel, newLabel)
            else:
                self.changeNodeLabel.emit(oldLabel, newLabel)

    #
    # onEditNodeStrAttrMaster
    #
    def onEditNodeStrAttrMaster(self):
        #
        self.editNode.master = str(self.ui.master_lineEdit.text())

    #
    # onEditNodeStrAttrAuthor
    #
    def onEditNodeStrAttrAuthor(self):
        #
        self.editNode.author = str(self.ui.author_lineEdit.text())

    #
    # onEditNodeStrAttrIcon
    #
    def onEditNodeStrAttrIcon(self):
        #
        self.editNode.icon = str(self.ui.icon_lineEdit.text())

    #
    # onEditNodeTxtAttr
    #
    def onEditNodeTxtAttr(self):
        #
        self.editNode.help = str(self.ui.help_plainTextEdit.toPlainText())

    #
    # onEditNodeType
    #
    def onEditNodeType(self, idx):
        #
        self.editNode.type = str(self.ui.type_comboBox.itemText(idx))
示例#16
0
class NodeParam ( QtCore.QObject ) :
	#
	isInput = True
	isRibParam = False
	id = 0
	#
	# __init__
	#
	def __init__ ( self, xml_param = None, isRibParam = False ) :
		#
		super ( NodeParam, self ).__init__ ()
		#
		# Define signals for PyQt5
		#
		if usePySide or usePyQt5 :
			#
			self.paramChangedSignal = Signal ()
			
		self.id = None
		self.name = None
		self.label = None
		self.type = None
		self.help = None  # short description

		self.default = None
		self.value = None
		self.shaderParam = False

		self.isRibParam = isRibParam
		self.display = True
		self.enabled = True
		self.removable = False

		# extra parameter description
		self.detail = '' # variable, uniform
		self.provider = '' # primitive, connection, constant, variable, expression

		# ui decorative parameters
		self.subtype = ''
		self.range = ''

		self.space = None # actual for color, point, vector, normal, matrix
		self.spaceDef = None # default value space

		self.arraySize = None # otherwise, it should be a list of values ( or empty list )

		self.defaultArray = []
		self.valueArray = []
		self.spaceArray = []			# array elements spaces
		self.spaceDefArray = []		# default array elements spaces

		if xml_param != None : self.parseFromXML ( xml_param )
	#
	# isArray
	#
	def isArray ( self ) : return ( self.arraySize is not None )
	#
	# setup
	#
	def setup ( self, name, label = '', detail = None, provider = None ) :
		#
		self.name = name
		if label == '' or label is None : 
			self.label = name
		else: 
			self.label = label
		self.detail = detail
		self.provider = provider
	#
	# copy
	#
	def copy ( self ) : assert 0, 'copy needs to be implemented!'
	#
	# copySetup
	#
	def copySetup ( self, newParam ) :
		#
		#if DEBUG_MODE : print '>> NodeParam( %s ).copySetup' % self.label
		newParam.id = self.id
		newParam.name = self.name
		newParam.label = self.label
		newParam.type = self.type
		newParam.help = self.help
		newParam.isInput = self.isInput
		newParam.shaderParam = self.shaderParam
		newParam.isRibParam = self.isRibParam
		newParam.display = self.display
		newParam.enabled = self.enabled
		newParam.removable = self.removable
		newParam.detail = self.detail
		newParam.provider = self.provider
		newParam.subtype = self.subtype
		newParam.range = self.range
		newParam.space = self.space
		newParam.spaceDef = self.spaceDef

		newParam.default = copy.deepcopy ( self.default )
		newParam.value = copy.deepcopy ( self.value )
		newParam.arraySize = self.arraySize
		newParam.defaultArray  = copy.deepcopy ( self.defaultArray )
		newParam.valueArray 	 = copy.deepcopy ( self.valueArray )   
		newParam.spaceArray 	 = copy.deepcopy ( self.spaceArray ) 
		newParam.spaceDefArray = copy.deepcopy ( self.spaceDefArray ) 
	#
	# typeToStr
	#
	def typeToStr ( self ) :
		#
		typeStr = self.detail + ' ' + self.type
		if self.isRibParam :
			if self.isArray () :
				arraySize = ''
				if self.arraySize > 0 :
					arraySize = str ( self.arraySize )
				typeStr += '[%s]' % arraySize
		return typeStr.lstrip ()
	#
	# encodedTypeStr
	#
	def encodedTypeStr ( self ) : assert 0, 'encodedStr needs to be implemented!'
	#
	# setValueFromStr
	#
	def setValueFromStr ( self, strValue ) : self.value = self.valueFromStr ( strValue )
	#
	# setDefaultFromStr
	#
	def setDefaultFromStr ( self, strValue ) : self.default = self.valueFromStr ( strValue )

	#
	# Virtual functions
	#

	#
	# valueFromStr
	#
	def valueFromStr ( self, strValue ) : return strValue
	#
	# getValueToStr
	#
	def getValueToStr ( self ) :
		#
		if self.value != None :
			return self.valueToStr ( self.value )
		else :
			return None
	#
	# getDefaultToStr
	#
	def getDefaultToStr ( self ) :
		#
		if self.default != None :
			return self.valueToStr ( self.default )
		else :
			return None
	#
	# virtual function
	#
	def valueToStr ( self, value ) : return str ( value )
	#
	# paramChanged
	#
	def paramChanged ( self, emitSignal = True ) :
		#
		if DEBUG_MODE : print ( '>> NodeParam.paramChanged (name = %s) emit = ' % self.name ), emitSignal
		if emitSignal :
			if  usePyQt4 :
				self.emit ( QtCore.SIGNAL ( 'paramChangedSignal(QObject)' ), self )
			else :
				self.paramChangedSignal.emit ( self )
	#
	# setupUI
	#
	def setupUI ( self, subtype, range ) :
		#
		self.subtype = subtype
		self.range = range
	#
	# setValue
	#
	def setValue ( self, value, emitSignal = True ) :
		#
		if self.value != value :
			self.value = value
			self.paramChanged ( emitSignal )
	#
	# removeItemFromRange
	#
	def removeItemFromRange ( self, item_label ) :
		#
		newRangeList = []
		if self.range != '' : # and self.subtype == 'selector':
			tmp_list = str ( self.range ).split ( ':' )
			for s in tmp_list :
				pair = s.split ( '=' )
				if len ( pair ) > 1 :
					label = pair [0]
					value = pair [1]
				else :
					label = s
					value = s
				#
				if label != item_label :
					newRangeList.append ( s )
			self.range = ( ':' ).join ( newRangeList )  
	#
	# renameItemInRange
	#
	def renameItemInRange ( self, item_label, newLabel ) :
		#
		newRangeList = []
		if self.range != '' : # and self.subtype == 'selector':
			tmp_list = str ( self.range ).split ( ':' )
			for s in tmp_list :
				pair = s.split ( '=' )
				if len ( pair ) > 1 :
					label = pair [0]
					value = pair [1]
				else :
					label = s
					value = s
				#
				if label == item_label :
					s = s.replace ( label, newLabel, 1 ) # replace only label
				newRangeList.append ( s )
			self.range = ( ':' ).join ( newRangeList )    
	#
	# parseFromXML
	#
	def parseFromXML ( self, xml_param ) :
		#
		self.name        = str ( xml_param.attributes ().namedItem ( 'name' ).nodeValue () )
		self.label       = str ( xml_param.attributes ().namedItem ( 'label' ).nodeValue () )
		if self.label == '' : self.label = self.name
		self.type        = str ( xml_param.attributes ().namedItem ( 'type' ).nodeValue () )
		self.shaderParam = xml_param.attributes ().namedItem ( 'shaderParam' ).nodeValue () == '1'

		self.detail      = str ( xml_param.attributes ().namedItem ( 'detail' ).nodeValue () )
		self.provider    = str ( xml_param.attributes ().namedItem ( 'provider' ).nodeValue () )
		self.subtype     = str ( xml_param.attributes ().namedItem ( 'subtype' ).nodeValue () )
		self.range       = str ( xml_param.attributes ().namedItem ( 'range' ).nodeValue () )

		self.display = True
		if not xml_param.attributes ().namedItem ( 'display' ).isNull () :
			self.display = xml_param.attributes ().namedItem ( 'display' ).nodeValue () == '1'

		self.enabled = True
		if not xml_param.attributes ().namedItem ( 'enabled' ).isNull () :
			self.enabled = xml_param.attributes ().namedItem ( 'enabled' ).nodeValue () == '1'
			
		self.removable = False
		if not xml_param.attributes ().namedItem ( 'removable' ).isNull () :
			self.removable = xml_param.attributes ().namedItem ( 'removable' ).nodeValue () == '1'

		if not xml_param.attributes ().namedItem ( 'space' ).isNull () :
			space = str ( xml_param.attributes ().namedItem ( 'space' ).nodeValue () )
			if space != '' :
				self.space = space
				self.spaceDef = space

		if not xml_param.attributes ().namedItem ( 'spaceDef' ).isNull () :
			spaceDef = str ( xml_param.attributes ().namedItem ( 'spaceDef' ).nodeValue () )
			if spaceDef != '' :
				self.spaceDef = space

		if not xml_param.attributes ().namedItem ( 'arraySize' ).isNull () :
			self.arraySize = int ( xml_param.attributes ().namedItem ( 'arraySize' ).nodeValue () )
		self.setDefaultFromStr ( xml_param.attributes ().namedItem ( 'default' ).nodeValue () )
		# after reading array values, space for each element is stored to self.spaceArray,
		# so we need to copy it to self.spaceDefArray for default value
		self.spaceDefArray 	 = copy.deepcopy ( self.spaceArray )

		if not xml_param.attributes ().namedItem ( 'value' ).isNull () :
			self.setValueFromStr ( xml_param.attributes ().namedItem ( 'value' ).nodeValue () )
		else :
			self.value = copy.deepcopy ( self.default ) 


		help_tag = xml_param.namedItem ( 'help' )

		if not help_tag.isNull () :
			self.help = str ( help_tag.toElement ().text () )
	#
	# parseToXML
	#
	def parseToXML ( self, dom ) :
		#
		xmlnode = dom.createElement( 'property' )

		if self.name != None   : xmlnode.setAttribute ( 'name', self.name )
		if self.label != None  : xmlnode.setAttribute ( 'label', self.label )
		if self.type != None   : xmlnode.setAttribute ( 'type', self.type )
		if self.shaderParam    : xmlnode.setAttribute ( 'shaderParam', True )
		if not self.display    : xmlnode.setAttribute ( 'display', False )
		if not self.enabled    : xmlnode.setAttribute ( 'enabled', False )
		if self.removable      : xmlnode.setAttribute ( 'removable', True )
		if self.detail != ''   : xmlnode.setAttribute ( 'detail', self.detail )
		if self.provider != '' : xmlnode.setAttribute ( 'provider', self.provider )
		# ui decorative parameters
		if self.subtype != ''  : xmlnode.setAttribute ( 'subtype', self.subtype )
		if self.range != ''    : xmlnode.setAttribute ( 'range', self.range )

		if self.space != None  :
			if self.space != ''  : xmlnode.setAttribute ( 'space', self.space )

		# write default value space only if it differs from value space
		if self.spaceDef != None  :
			if self.spaceDef != '' and  self.spaceDef != self.space : 
				xmlnode.setAttribute ( 'spaceDef', self.spaceDef )

		if self.default != None :
			value = self.getDefaultToStr ()
			if not self.type in VALID_RIB_NODE_TYPES : 
				value = value.strip ( '\"' )
			xmlnode.setAttribute ( 'default', value )

		if self.value != None :
			value = self.getValueToStr ()
			if not self.type in VALID_RIB_NODE_TYPES : 
				value = value.strip ( '\"' )
			xmlnode.setAttribute ( 'value', value )

		if self.arraySize != None :
			xmlnode.setAttribute ( 'arraySize', self.arraySize )
		if self.help != None :
			# append node help (short description)
			help_tag = dom.createElement ( 'help' )
			help_text = dom.createTextNode ( self.help )
			help_tag.appendChild ( help_text )
			xmlnode.appendChild ( help_tag )

		return xmlnode
示例#17
0
class NodeParam(QtCore.QObject):
    #
    isInput = True
    isRibParam = False
    id = 0

    #
    # __init__
    #
    def __init__(self, xml_param=None, isRibParam=False):
        #
        super(NodeParam, self).__init__()
        #
        # Define signals for PyQt5
        #
        if usePySide or usePyQt5:
            #
            self.paramChangedSignal = Signal()

        self.id = None
        self.name = None
        self.label = None
        self.type = None
        self.help = None  # short description

        self.default = None
        self.value = None
        self.shaderParam = False

        self.isRibParam = isRibParam
        self.display = True
        self.enabled = True
        self.removable = False

        # extra parameter description
        self.detail = ''  # variable, uniform
        self.provider = ''  # primitive, connection, constant, variable, expression

        # ui decorative parameters
        self.subtype = ''
        self.range = ''

        self.space = None  # actual for color, point, vector, normal, matrix
        self.spaceDef = None  # default value space

        self.arraySize = None  # otherwise, it should be a list of values ( or empty list )

        self.defaultArray = []
        self.valueArray = []
        #self.spaceArray = []
        #self.spaceDefArray = []

        if xml_param != None: self.parseFromXML(xml_param)

    #
    # isArray
    #
    def isArray(self):
        return (self.array is not None)

    #
    # setup
    #
    def setup(self, name, label='', detail=None, provider=None):
        #
        self.name = name
        if label == '' or label is None: self.label = name
        else: self.label = label

        self.detail = detail
        self.provider = provider

    #
    # copy
    #
    def copy(self):
        assert 0, 'copy needs to be implemented!'

    #
    # copySetup
    #
    def copySetup(self, newParam):
        #
        #if DEBUG_MODE : print '>> NodeParam( %s ).copySetup' % self.label
        newParam.id = self.id
        newParam.name = self.name
        newParam.label = self.label
        newParam.type = self.type
        newParam.help = self.help
        newParam.isInput = self.isInput
        newParam.shaderParam = self.shaderParam
        newParam.isRibParam = self.isRibParam
        newParam.display = self.display
        newParam.enabled = self.enabled
        newParam.removable = self.removable
        newParam.detail = self.detail
        newParam.provider = self.provider
        newParam.subtype = self.subtype
        newParam.range = self.range
        newParam.space = self.space
        newParam.spaceDef = self.spaceDef

        newParam.default = copy.deepcopy(self.default)
        newParam.value = copy.deepcopy(self.value)

    #
    # typeToStr
    #
    def typeToStr(self):
        #
        str = self.detail + ' ' + self.type
        return str.lstrip()

    #
    # encodedTypeStr
    #
    def encodedTypeStr(self):
        assert 0, 'encodedStr needs to be implemented!'

    #
    # setValueFromStr
    #
    def setValueFromStr(self, strValue):
        self.value = self.valueFromStr(strValue)

    #
    # setDefaultFromStr
    #
    def setDefaultFromStr(self, strValue):
        self.default = self.valueFromStr(strValue)

    #
    # Virtual functions
    #

    #
    # valueFromStr
    #
    def valueFromStr(self, strValue):
        return strValue

    #
    # getValueToStr
    #
    def getValueToStr(self):
        #
        if self.value != None:
            return self.valueToStr(self.value)
        else:
            return None

    #
    # getDefaultToStr
    #
    def getDefaultToStr(self):
        #
        if self.default != None:
            return self.valueToStr(self.default)
        else:
            return None

    #
    # virtual function
    #
    def valueToStr(self, value):
        return str(value)

    #
    # paramChanged
    #
    def paramChanged(self):
        #
        if DEBUG_MODE:
            print '>> NodeParam.paramChanged (name = %s)' % self.name
        if usePyQt4:
            self.emit(QtCore.SIGNAL('paramChangedSignal(QObject)'), self)
        else:
            self.paramChangedSignal.emit(self)

    #
    # setupUI
    #
    def setupUI(self, subtype, range):
        #
        self.subtype = subtype
        self.range = range

    #
    # setValue
    #
    def setValue(self, value):
        #
        if self.value != value:
            self.value = value
            self.paramChanged()

    #
    # removeItemFromRange
    #
    def removeItemFromRange(self, item_label):
        #
        newRangeList = []
        if self.range != '':  # and self.subtype == 'selector':
            tmp_list = str(self.range).split(':')
            for s in tmp_list:
                pair = s.split('=')
                if len(pair) > 1:
                    label = pair[0]
                    value = pair[1]
                else:
                    label = s
                    value = s
                #
                if label != item_label:
                    newRangeList.append(s)
            self.range = (':').join(newRangeList)

    #
    # renameItemInRange
    #
    def renameItemInRange(self, item_label, newLabel):
        #
        newRangeList = []
        if self.range != '':  # and self.subtype == 'selector':
            tmp_list = str(self.range).split(':')
            for s in tmp_list:
                pair = s.split('=')
                if len(pair) > 1:
                    label = pair[0]
                    value = pair[1]
                else:
                    label = s
                    value = s
                #
                if label == item_label:
                    s = s.replace(label, newLabel, 1)  # replace only label
                newRangeList.append(s)
            self.range = (':').join(newRangeList)

    #
    # parseFromXML
    #
    def parseFromXML(self, xml_param):
        #
        self.name = str(xml_param.attributes().namedItem('name').nodeValue())
        self.label = str(xml_param.attributes().namedItem('label').nodeValue())
        if self.label == '': self.label = self.name
        self.type = str(xml_param.attributes().namedItem('type').nodeValue())
        self.shaderParam = xml_param.attributes().namedItem(
            'shaderParam').nodeValue() == '1'

        self.detail = str(
            xml_param.attributes().namedItem('detail').nodeValue())
        self.provider = str(
            xml_param.attributes().namedItem('provider').nodeValue())
        self.subtype = str(
            xml_param.attributes().namedItem('subtype').nodeValue())
        self.range = str(xml_param.attributes().namedItem('range').nodeValue())

        self.display = True
        if not xml_param.attributes().namedItem('display').isNull():
            self.display = xml_param.attributes().namedItem(
                'display').nodeValue() == '1'

        self.enabled = True
        if not xml_param.attributes().namedItem('enabled').isNull():
            self.enabled = xml_param.attributes().namedItem(
                'enabled').nodeValue() == '1'

        self.removable = False
        if not xml_param.attributes().namedItem('removable').isNull():
            self.removable = xml_param.attributes().namedItem(
                'removable').nodeValue() == '1'

        if not xml_param.attributes().namedItem('space').isNull():
            space = str(xml_param.attributes().namedItem('space').nodeValue())
            if space != '':
                self.space = space
                self.spaceDef = space

        if not xml_param.attributes().namedItem('spaceDef').isNull():
            spaceDef = str(
                xml_param.attributes().namedItem('spaceDef').nodeValue())
            if spaceDef != '':
                self.spaceDef = space

        self.setDefaultFromStr(
            xml_param.attributes().namedItem('default').nodeValue())

        if not xml_param.attributes().namedItem('value').isNull():
            self.setValueFromStr(
                xml_param.attributes().namedItem('value').nodeValue())
        else:
            self.value = self.default

        #print ':: value = %s default = %s' % ( self.getValueToStr(), self.getDefaultToStr()  )

        help_tag = xml_param.namedItem('help')

        if not help_tag.isNull():
            self.help = str(help_tag.toElement().text())

    #
    # parseToXML
    #
    def parseToXML(self, dom):
        #
        xmlnode = dom.createElement('property')

        if self.name != None: xmlnode.setAttribute('name', self.name)
        if self.label != None: xmlnode.setAttribute('label', self.label)
        if self.type != None: xmlnode.setAttribute('type', self.type)
        if self.shaderParam: xmlnode.setAttribute('shaderParam', True)
        if not self.display: xmlnode.setAttribute('display', False)
        if not self.enabled: xmlnode.setAttribute('enabled', False)
        if self.removable: xmlnode.setAttribute('removable', True)
        if self.detail != '': xmlnode.setAttribute('detail', self.detail)
        if self.provider != '': xmlnode.setAttribute('provider', self.provider)
        # ui decorative parameters
        if self.subtype != '': xmlnode.setAttribute('subtype', self.subtype)
        if self.range != '': xmlnode.setAttribute('range', self.range)

        if self.space != None:
            if self.space != '': xmlnode.setAttribute('space', self.space)

        # write default value space only if it differs from value space
        if self.spaceDef != None:
            if self.spaceDef != '' and self.spaceDef != self.space:
                xmlnode.setAttribute('spaceDef', self.spaceDef)

        if self.default != None:
            value = self.getDefaultToStr()
            if not self.type in VALID_RIB_NODE_TYPES: value = value.strip('\"')
            xmlnode.setAttribute('default', value)

        if self.value != None:
            value = self.getValueToStr()
            if not self.type in VALID_RIB_NODE_TYPES: value = value.strip('\"')
            xmlnode.setAttribute('value', value)

        if self.help != None:
            # append node help (short description)
            help_tag = dom.createElement('help')
            help_text = dom.createTextNode(self.help)
            help_tag.appendChild(help_text)
            xmlnode.appendChild(help_tag)

        return xmlnode
示例#18
0
class ParamWidget(QtModule.QWidget):
    #
    # __init__
    #
    def __init__(self, param, gfxNode, ignoreSubtype=False):
        #
        QtModule.QWidget.__init__(self)
        #
        # Define signals for PyQt5
        #
        if usePySide or usePyQt5:
            #
            self.nodeParamRemoved = Signal()
            #
        self.param = param
        self.gfxNode = gfxNode
        self.ignoreSubtype = ignoreSubtype  # if widget is used in NodeEditor, then ignoreSubtype = True

        self.buildGeneralGui()
        self.buildGui()
        self.ui.updateGui(self.param.value)
        #self.connectSignals ()
        #self.connect( self.param, QtCore.SIGNAL( 'paramChanged(QObject)' ), self.onParamChanged )
        #if DEBUG_MODE : print ">> ParamWidget (%s.%s)  __init__" % ( self.gfxNode.node.label, self.param.label )

    #
    #  __del__
    #
    def __del__(self):
        #
        if DEBUG_MODE: print('>> ParamWidget( %s ).__del__ ' % self.param.name)

    #
    # connectSignals
    #
    def connectSignals(self):
        #
        pass

    #
    # setEnabled
    #
    def setEnabled(self, enabled=True):
        #
        for hl in self.param_vl.children():
            for i in range(hl.count()):
                obj = hl.itemAt(i).widget()
                if obj is not None:
                    obj.setEnabled(enabled)

    #
    # onParamChanged
    #
    def onParamChanged(self, param):
        #
        if DEBUG_MODE:
            print(">> ParamWidget( %s ).onParamChanged" % param.name)
        self.ui.disconnectSignals(self)
        self.ui.updateGui(self.param.value)
        self.ui.connectSignals(self)
        #self.emit ( QtCore.SIGNAL( 'onParamChanged(QObject)' ), param )

    #
    # buildGeneralGui
    #
    def buildGeneralGui(self):
        #if DEBUG_MODE : print ">> ParamWidget buildGeneralGui"

        self.label_vl = QtModule.QVBoxLayout()
        self.label_vl.setSpacing(UI.SPACING)
        self.label_vl.setContentsMargins(0, 0, 0, 0)
        self.label_vl.setAlignment(QtCore.Qt.AlignTop | QtCore.Qt.AlignLeft)

        self.hl = QtModule.QHBoxLayout()
        self.hl.setSpacing(UI.SPACING)
        self.hl.setContentsMargins(0, 0, 0, 0)
        self.hl.setAlignment(QtCore.Qt.AlignTop | QtCore.Qt.AlignLeft)

        # vertical layout for parametrs values (e.g. output links or matrix rows)
        self.param_vl = QtModule.QVBoxLayout()
        self.param_vl.setSpacing(UI.SPACING)
        self.param_vl.setContentsMargins(0, 0, 0, 0)
        self.param_vl.setAlignment(QtCore.Qt.AlignTop | QtCore.Qt.AlignLeft)
        #
        # add 'isShaderParam' check box only for RSL nodes
        #
        if self.gfxNode is not None:
            #
            # add "Use as Shader parameter" checkbox
            #
            #if ( self.gfxNode.node.type in VALID_RSL_NODE_TYPES ) and ( self.param.type in VALID_RSL_PARAM_TYPES ) and ( self.param.provider != 'attribute' ) :
            if ( self.gfxNode.node.format == 'rsl' ) and \
             ( self.param.type in VALID_RSL_PARAM_TYPES ) and \
             ( self.param.provider != 'attribute' ) :
                self.check = QtModule.QCheckBox(self)
                self.check.setMinimumSize(
                    QtCore.QSize(UI.CHECK_WIDTH, UI.HEIGHT))
                self.check.setMaximumSize(
                    QtCore.QSize(UI.CHECK_WIDTH, UI.HEIGHT))
                self.check.setToolTip('Use as Shader parameter')
                self.check.setChecked(self.param.shaderParam)
                if usePyQt4:
                    self.connect(self.check,
                                 QtCore.SIGNAL('stateChanged(int)'),
                                 self.onShaderParamChanged)
                else:
                    self.check.stateChanged.connect(self.onShaderParamChanged)
                self.hl.addWidget(self.check)
            else:
                spacer = QtModule.QSpacerItem(UI.LT_SPACE, UI.HEIGHT,
                                              QtModule.QSizePolicy.Minimum,
                                              QtModule.QSizePolicy.Minimum)
                self.hl.addItem(spacer)
            #
            # add 'remove' button for removable parameters
            #
            if self.param.removable:
                self.removeButton = QtModule.QToolButton(self)
                sizePolicy = QtModule.QSizePolicy(QtModule.QSizePolicy.Fixed,
                                                  QtModule.QSizePolicy.Fixed)
                sizePolicy.setHorizontalStretch(20)
                sizePolicy.setVerticalStretch(20)
                sizePolicy.setHeightForWidth(
                    self.removeButton.sizePolicy().hasHeightForWidth())
                self.removeButton.setSizePolicy(sizePolicy)
                self.removeButton.setMaximumSize(QtCore.QSize(20, 20))
                icon = QtGui.QIcon()
                icon.addPixmap(
                    QtGui.QPixmap(':/edit_icons/resources/del_list.png'),
                    QtGui.QIcon.Normal, QtGui.QIcon.On)
                self.removeButton.setIcon(icon)
                self.removeButton.setAutoRaise(True)
                self.removeButton.setToolTip('Remove parameter')
                self.removeButton.setIconSize(QtCore.QSize(16, 16))
                self.removeButton.setObjectName('removeButton')
                self.hl.addWidget(self.removeButton)
                if usePyQt4:
                    QtCore.QObject.connect(self.removeButton,
                                           QtCore.SIGNAL('clicked()'),
                                           self.onRemoveItem)
                else:
                    self.removeButton.clicked.connect(self.onRemoveItem)

        self.label = ParamLabel(self, self.param)

        self.helpMark = QtModule.QLabel(self)
        palette = QtGui.QPalette()
        palette.setColor(QtGui.QPalette.WindowText, QtGui.QColor(0, 140, 0))
        font1 = QtGui.QFont()
        font1.setBold(True)
        self.helpMark.setPalette(palette)
        self.helpMark.setFont(font1)
        self.helpMark.setText('')

        self.helpMark.setMinimumSize(QtCore.QSize(6, UI.HEIGHT))
        self.helpMark.setMaximumSize(QtCore.QSize(6, UI.HEIGHT))

        self.helpMark.setEnabled(False)

        if self.param.help is not None and self.param.help != '':
            self.label.setWhatsThis(self.param.help)
            self.helpMark.setWhatsThis(self.param.help)
            self.helpMark.setText('?')
            self.helpMark.setEnabled(True)

        self.label.setAlignment(QtCore.Qt.AlignLeading | QtCore.Qt.AlignLeft
                                | QtCore.Qt.AlignVCenter)
        #self.label.setMinimumSize ( QtCore.QSize ( UI.LABEL_WIDTH, UI.HEIGHT ) )
        #self.label.setMaximumSize ( QtCore.QSize ( UI.LABEL_WIDTH, UI.HEIGHT ) )

        #self.vl.addWidget ( self.gui )
        self.hl.addWidget(self.label)
        self.hl.addWidget(self.helpMark)
        #self.hl.addLayout ( self.param_vl )
        #sp = QtModule.QSpacerItem ( 20, 20, QtModule.QSizePolicy.Expanding, QtModule.QSizePolicy.Minimum )

        self.label_vl.addLayout(self.hl)
        sp_v = QtModule.QSpacerItem(0, 0, QtModule.QSizePolicy.Minimum,
                                    QtModule.QSizePolicy.Expanding)
        self.label_vl.addItem(sp_v)

    #
    # onShaderParamChanged
    #
    def onShaderParamChanged(self, value):
        #
        self.param.shaderParam = self.check.isChecked()
        self.gfxNode.updateGfxNodeParams(True)

    #
    # buildGui -- virtual method
    # should be overriden in inherited classes
    #
    def buildGui(self):
        #
        pass
        #spacer = QtModule.QSpacerItem ( 20, 20, QtModule.QSizePolicy.Expanding, QtModule.QSizePolicy.Minimum )
        #self.hl.addItem ( spacer )

    #
    # onRemoveItem
    #
    def onRemoveItem(self):
        #
        if DEBUG_MODE:
            print '>> ParamWidget( %s ).onRemoveItem ' % self.param.name
        if usePyQt4:
            self.emit(QtCore.SIGNAL('nodeParamRemoved'), self.param)
        else:
            self.nodeParamRemoved.emit(self.param)
示例#19
0
class WorkArea(QtModule.QGraphicsView):
    #
    # __init__
    #
    def __init__(self):
        #
        QtModule.QGraphicsView.__init__(self)
        #
        # Define signals for PyQt5
        #
        if usePySide or usePyQt5:
            #
            self.selectNodes = Signal()  #( list, list )
            self.nodeConnectionChanged = Signal(
            )  #QtCore.pyqtSignal ( QtModule.QGraphicsObject, QtCore.QObject )

            self.gfxNodeAdded = Signal()  #( QtModule.QGraphicsObject )
            self.gfxNodeRemoved = Signal()  #( QtModule.QGraphicsObject )
            #
        self.drawGrid = True
        self.gridSnap = False
        self.straightLinks = False
        self.reverseFlow = False

        self.gridSize = 10
        self.minGap = 120
        self.current_Z = 1

        self.state = 'idle'
        self.pressed = False
        self.startPos = None

        self.lastConnectCandidate = None
        self.currentGfxLink = None

        self.inspectedNode = None
        self.nodeNet = None

        self.selectedNodes = []
        self.selectedLinks = []

        # set scene
        scene = WorkAreaScene(self)

        scene.setSceneRect(-10000, -10000, 20000, 20000)
        #scene.setItemIndexMethod ( QtGui.QGraphicsScene.NoIndex )
        self.setScene(scene)

        # qt graphics stuff
        self.setCacheMode(QtModule.QGraphicsView.CacheBackground)
        self.setRenderHint(QtGui.QPainter.Antialiasing)

        self.setTransformationAnchor(QtModule.QGraphicsView.AnchorUnderMouse
                                     )  # QtGui.QGraphicsView.AnchorUnderMouse
        self.setResizeAnchor(
            QtModule.QGraphicsView.AnchorUnderMouse)  # AnchorViewCenter
        self.setDragMode(QtModule.QGraphicsView.RubberBandDrag)

        self.setMouseTracking(False)
        self.setAcceptDrops(True)
        """
		viewport = self.viewport()
		if viewport is not None :
			print ">> WorkArea viewport.setAcceptTouchEvents"
			#proxy = QtGui.QGraphicsProxyWidget ()
			proxy = viewport.graphicsProxyWidget ()
			if proxy is not None :
				proxy.setAcceptTouchEvents ( True )

			#self.setAttribute ( QtGui.AcceptTouchEvents, True )
			#viewport()->setAttribute(Qt::WA_AcceptTouchEvents);
			#setDragMode(ScrollHandDrag);
			#Qt::WA_AcceptTouchEvents
		"""
        self.viewBrush = QtGui.QBrush(QtGui.QColor(148, 148, 148))
        self.setBackgroundBrush(self.viewBrush)

        # self.connectSignals ()

        if DEBUG_MODE: print ">> WorkArea. __init__"

    #
    # connectSignals
    #
    def connectSignals(self):
        #
        pass

    #
    # drawBackground
    #
    def drawBackground(self, painter, rect):
        #
        sc_rect = self.sceneRect()
        bbrush = QtGui.QBrush(QtGui.QColor(148, 148,
                                           148))  ## painter.background()
        painter.fillRect(rect, bbrush)

        if self.drawGrid:
            #  print( "grid size = %d" % self.gridSize )
            gr_pen = QtGui.QPen(QtGui.QColor(180, 180, 180))
            gr_pen.setWidth(0)
            painter.setPen(gr_pen)
            for x in range(int(sc_rect.x()), int(sc_rect.right()),
                           self.gridSize):
                painter.drawLine(x, sc_rect.y(), x, sc_rect.bottom())
            for y in range(int(sc_rect.y()), int(sc_rect.bottom()),
                           self.gridSize):
                painter.drawLine(sc_rect.x(), y, sc_rect.right(), y)

    #
    # Returns a list of GfxNodes in the scene for given type
    # or all nodes if type == None
    #
    def getGfxNodesByType(self, type=None):
        #
        resultList = []
        for item in self.scene().items():
            if (isinstance(item, GfxNode) or isinstance(item, GfxSwatchNode)
                    or (isinstance(item, GfxNodeConnector) and item.isNode())):
                if type is None or item.node.type == type:
                    resultList.append(item)
        return resultList

    #
    # Returns a list of GfxNodes in the scene for given format
    # or all nodes if type == None
    #
    def getGfxNodesByFormat(self, format=None):
        #
        resultList = []
        for item in self.scene().items():
            if (isinstance(item, GfxNode) or isinstance(item, GfxSwatchNode)
                    or (isinstance(item, GfxNodeConnector) and item.isNode())):
                if format is None or item.node.format == format:
                    resultList.append(item)
        return resultList

    #
    # Returns GfxNodes for given Node
    #
    def getGfxNodesByNode(self, node=None):
        #
        gfxNode = None
        for item in self.scene().items():
            if (isinstance(item, GfxNode) or isinstance(item, GfxSwatchNode)
                    or (isinstance(item, GfxNodeConnector) and item.isNode())):
                if item.node == node:
                    gfxNode = item
                    break
        return gfxNode

    #
    # selectAllNodes
    #
    def getAllGfxNodes(self):
        return self.getGfxNodesByType(None)

    #
    # selectAllNodes
    #
    def selectAllNodes(self):
        #
        for item in self.getAllGfxNodes():
            item.setSelected(True)

    #
    # selectAbove
    #
    def selectAbove(self, upperGfxNode):
        #
        if DEBUG_MODE:
            print '>> WorkArea::selectAbove node (%s) links:' % upperGfxNode.node.label
        for link_list in upperGfxNode.node.outputLinks.values():
            for link in link_list:
                # link.printInfo ()
                if self.nodeNet.hasThisLink(link):
                    gfxNode = self.getGfxNodesByNode(link.dstNode)
                    gfxNode.setSelected(True)
                    self.selectAbove(gfxNode)
                else:
                    if DEBUG_MODE: print '!! invalid link ...'

    #
    # updateBelow
    #
    def updateBelow(self, upperGfxNode, removeLinks=False):
        #
        if DEBUG_MODE:
            print '>> WorkArea::updateBelow upperGfxNode.node (%s) children:' % upperGfxNode.node.label
        for node in upperGfxNode.node.childs:
            if DEBUG_MODE: print '* %s' % node.label
            gfxNode = self.getGfxNodesByNode(node)
            gfxNode.updateGfxNode(removeLinks)
            self.updateBelow(gfxNode, removeLinks)

    #
    # selectBelow
    #
    def selectBelow(self, upperGfxNode):
        #
        if DEBUG_MODE:
            print '>> WorkArea::selectBelow upperGfxNode.node (%s) children:' % upperGfxNode.node.label
        for node in upperGfxNode.node.childs:
            if DEBUG_MODE: print '* %s' % node.label
            gfxNode = self.getGfxNodesByNode(node)
            gfxNode.setSelected(True)
            self.selectBelow(gfxNode)

    #
    # setNodeNetwork
    #
    def setNodeNetwork(self, nodeNet):
        self.nodeNet = nodeNet

    #
    # clear
    #
    def clear(self):
        #
        if DEBUG_MODE: print '>> WorkArea:: clearing nodes ...'
        for item in self.scene().items():
            self.scene().removeItem(item)
        self.nodeNet.clear()
        self.state = 'idle'
        self.panStartPos = None
        self.lastConnectCandidate = None
        self.currentGfxLink = None
        self.inspectedNode = None

    #
    # addGfxLink
    #
    def addGfxLink(self, link):
        #
        if DEBUG_MODE: print '>> WorkArea::addGfxLink (id=%d)' % link.id
        gfxLink = GfxLink(link)
        (srcNode, srcParam) = link.getSrc()
        (dstNode, dstParam) = link.getDst()
        srcConnector = None
        dstConnector = None
        for item in self.scene().items():
            if isinstance(item, GfxNode) or isinstance(item, GfxSwatchNode):
                if item.node == srcNode:
                    srcConnector = item.getOutputConnectorByParam(srcParam)
                elif item.node == dstNode:
                    dstConnector = item.getInputConnectorByParam(dstParam)
            elif isinstance(item, GfxNodeConnector) and item.isNode():
                if item.node == srcNode:
                    srcConnector = item
                elif item.node == dstNode:
                    dstConnector = item
            if (srcConnector != None and dstConnector != None):
                break
        gfxLink.setSrcConnector(srcConnector)
        gfxLink.setDstConnector(dstConnector)
        gfxLink.adjust()
        self.scene().addItem(gfxLink)

    #
    # Node already in NodeNet, so add new GfxNode to scene
    #
    def addGfxNode(self, node, pos=None):
        #
        #print ( ">> WorkArea: addGfxNode %s" % node.label )
        if node.type == 'connector':
            gfxNode = GfxNodeConnector(node.inputParams[0], node=node)
        elif node.type == 'note':
            gfxNode = GfxNote(node)
        elif node.type == 'swatch':
            gfxNode = GfxSwatchNode(node)
        else:
            gfxNode = GfxNode(node)
        scene = self.scene()
        if pos != None: gfxNode.moveBy(pos.x(), pos.y())
        #for item in scene.selectedItems (): item.setSelected ( False )
        scene.addItem(gfxNode)
        gfxNode.setSelected(True)
        if usePyQt4:
            self.emit(QtCore.SIGNAL('gfxNodeAdded'), gfxNode)
        else:
            self.gfxNodeAdded.emit(gfxNode)

    #
    # adjustLinks
    #
    def adjustLinks(self):
        #
        for item in self.scene().items():
            if isinstance(item, GfxLink): item.adjust()

    #
    # fitGfxNodesInView
    #
    def fitGfxNodesInView(self, gfxNodeList):
        #
        nodeNetRect = QtCore.QRectF()
        for gfxNode in gfxNodeList:
            nodeRect = gfxNode.sceneBoundingRect()
            if nodeNetRect.isNull():
                nodeNetRect = nodeRect
            nodeNetRect = nodeNetRect.united(nodeRect)
        if nodeNetRect.isValid():
            self.fitInView(nodeNetRect, QtCore.Qt.KeepAspectRatio)

    #
    # onSelectionChanged
    #
    def onSelectionChanged(self):
        #
        #print ">> WorkArea: onSelectionChanged "
        self.selectedNodes = []
        self.selectedLinks = []
        selected = self.scene().selectedItems()

        for item in selected:
            if isinstance(item, GfxNode): self.selectedNodes.append(item)
            elif isinstance(item, GfxNote): self.selectedNodes.append(item)
            elif isinstance(item, GfxNodeConnector):
                self.selectedNodes.append(item)
            elif isinstance(item, GfxSwatchNode):
                self.selectedNodes.append(item)
            elif isinstance(item, GfxLink):
                self.selectedLinks.append(item)

        if usePyQt4:
            self.emit(QtCore.SIGNAL('selectNodes'), self.selectedNodes,
                      self.selectedLinks)
        else:
            self.selectNodes.emit(self.selectedNodes, self.selectedLinks)

    #
    # lastConnectCandidateReset
    #
    def lastConnectCandidateReset(self):
        #
        if self.lastConnectCandidate is not None:
            self.lastConnectCandidate.hilite(False)
        self.lastConnectCandidate = None

    #
    # isLinkAcceptable
    #
    def isLinkAcceptable(self, connector, connectCandidate):
        #
        isAcceptable = False
        if isinstance(connectCandidate, GfxNodeConnector):
            # do not connect to itself
            if connectCandidate != connector:
                # do not connect to the same node
                if connectCandidate.parentItem() != connector.parentItem():
                    # do not connect the same link to connector twice
                    if not connectCandidate.hasThisLink(self.currentGfxLink):
                        # connect only to similar type
                        if connector.param.encodedTypeStr(
                        ) == connectCandidate.param.encodedTypeStr():
                            if not connectCandidate.isNode():
                                # connect only input with output and vice versa
                                if connector.param.isInput != connectCandidate.param.isInput:
                                    isAcceptable = True
                            else:
                                # we have nodeConnector
                                isAcceptable = True

        return isAcceptable

    #
    # onStartNodeLink
    #
    #@QtCore.pyqtSlot( GfxNodeConnector )
    def onStartNodeLink(self, connector):
        #
        #if DEBUG_MODE : print '>> WorkArea::onStartNodeLink'
        #if DEBUG_MODE : print connector
        srcNode = connector.getNode()
        srcParam = connector.param
        if DEBUG_MODE:
            print '>> WorkArea::onStartNodeLink from %s (%s)' % (
                srcNode.label, srcParam.label)

        srcConnector = connector
        self.state = 'traceNodeLink'
        self.lastConnectCandidate = None

        if connector.isInput() and connector.isLinked():
            oldLink = connector.getFirstGfxLink()
            srcConnector = oldLink.srcConnector
            oldLink.remove()

        gfxLink = GfxLink(None, srcConnector)
        self.scene().addItem(gfxLink)
        self.currentGfxLink = gfxLink
        self.currentGfxLink.isLinkSelected = True

    #
    # onTraceNodeLink
    #
    def onTraceNodeLink(self, connector, scenePos):
        # node = connector.parentItem().node
        # print ">> WorkArea: onDrawNodeLink from %s (%d %d)" % ( node.label, scenePos.x(), scenePos.y() )
        if usePyQt4:
            connectCandidate = self.scene().itemAt(scenePos)
        else:
            connectCandidate = self.scene().itemAt(scenePos, self.transform())
        srcConnector = self.currentGfxLink.srcConnector
        swappedLink = False
        if srcConnector is None:  # link has swapped connectors
            srcConnector = self.currentGfxLink.dstConnector
            swappedLink = True

        if self.isLinkAcceptable(srcConnector, connectCandidate):
            if connectCandidate != self.lastConnectCandidate:
                self.lastConnectCandidateReset()
                connectCandidate.hilite(True)
                self.lastConnectCandidate = connectCandidate
                # link_node = connectCandidate.parentItem ().node
                # print ">> WorkArea: onDrawNodeLink to %s" % link_node.label
            else:
                scenePos = self.lastConnectCandidate.getCenterPoint(
                )  # snap to last position
                pass
                # self.lastConnectCandidateReset ()
        else:
            self.lastConnectCandidateReset()

        #if self.currentGfxLink is not None :
        if swappedLink:
            self.currentGfxLink.setSrcPoint(scenePos)
        else:
            self.currentGfxLink.setDstPoint(scenePos)

    #
    # onEndNodeLink
    #
    def onEndNodeLink(self, connector, scenePos):
        #
        srcConnector = self.currentGfxLink.srcConnector
        dstConnector = self.currentGfxLink.dstConnector
        swappedLink = False
        if srcConnector is None:  # link has swapped connectors
            swappedLink = True

        if self.lastConnectCandidate is None:
            self.currentGfxLink.remove()
            #self.emit( QtCore.SIGNAL( 'nodeParamChanged' ), srcConnector.parentItem(), srcConnector.param )
            #self.emit( QtCore.SIGNAL( 'nodeParamChanged' ), dstConnector.parentItem(), dstConnector.param )
        else:
            if self.lastConnectCandidate.isNode():
                # if connection was made to ConnectorNode
                if dstConnector is None:
                    self.lastConnectCandidate.removeInputGfxLinks()
            else:
                # remove old link first if it exists
                if self.lastConnectCandidate.isInput(
                ) and self.lastConnectCandidate.isLinked():
                    #oldLink = self.lastConnectCandidate.getFirstLink ()
                    #oldLink.remove ()
                    self.lastConnectCandidate.removeInputGfxLinks()

            self.currentGfxLink.isLinkSelected = False
            self.currentGfxLink.update()

            srcNode = dstNode = None
            srcParam = dstParam = None

            if swappedLink:
                srcNode = self.lastConnectCandidate.getNode()
                srcParam = self.lastConnectCandidate.param
                if self.lastConnectCandidate.isNode():
                    srcParam = self.lastConnectCandidate.getFirstOutputParam()
                dstNode = dstConnector.getNode()
                dstParam = dstConnector.param
                self.currentGfxLink.setSrcConnector(self.lastConnectCandidate)
            else:
                srcNode = srcConnector.getNode()
                srcParam = srcConnector.param
                dstNode = self.lastConnectCandidate.getNode()
                dstParam = self.lastConnectCandidate.param
                if self.lastConnectCandidate.isNode():
                    dstParam = self.lastConnectCandidate.getFirstInputParam()
                self.currentGfxLink.setDstConnector(self.lastConnectCandidate)

            link = NodeLink.build(srcNode, dstNode, srcParam, dstParam)

            #if not dstParam.isInput :
            # swap source and destination
            #  self.currentGfxLink.swapConnectors ()
            #  link.swapNodes ()

            self.currentGfxLink.link = link
            self.nodeNet.addLink(link)
            if usePyQt4:
                self.emit(QtCore.SIGNAL('nodeConnectionChanged'),
                          self.currentGfxLink.dstConnector.getGfxNode(),
                          self.currentGfxLink.dstConnector.param)
            else:
                self.nodeConnectionChanged.emit(
                    self.currentGfxLink.dstConnector.getGfxNode(),
                    self.currentGfxLink.dstConnector.param)

        self.lastConnectCandidateReset()
        self.currentGfxLink = None
        self.state = 'idle'

    #
    # onStartNodeConnector
    #
    def onStartNodeConnector(self, connector, scenePos):
        #
        if DEBUG_MODE: print '>> WorkArea::onStartNodeConnector'
        self.state = 'traceNodeConnector'

        newNode = ConnectorNode()
        self.nodeNet.addNode(newNode)

        newParam = connector.param.copy()
        newParam.isInput = False
        newInParam = newParam.copy()
        newOutParam = newParam.copy()

        newNode.addInputParam(newInParam)
        newNode.addOutputParam(newOutParam)

        newConnector = GfxNodeConnector(newParam,
                                        connector.radius,
                                        node=newNode)
        newConnector.brush = connector.brush
        newConnector.setPos(scenePos)
        newConnector.moveBy(-connector.radius, -connector.radius)

        self.lastConnectCandidate = newConnector
        self.scene().addItem(newConnector)
        newConnector.hilite(True)

        srcNode = connector.getNode()
        srcParam = connector.getOutputParam()
        dstNode = newConnector.getNode()
        dstParam = newConnector.getInputParam()

        #
        # swap link direction only for connectors
        # in open chain connected to input node parameter
        #
        swappedLink = False
        if connector.isConnectedToInput(
        ) and not connector.isConnectedToOutput():
            if DEBUG_MODE: print '*** swap link direction ***'
            swappedLink = True
            srcNode = newConnector.getNode()
            srcParam = newConnector.getOutputParam()
            dstNode = connector.getNode()
            dstParam = connector.getInputParam()

        link = NodeLink.build(srcNode, dstNode, srcParam, dstParam)
        # if swappedLink : link.swapNodes ()
        self.nodeNet.addLink(link)

        #if DEBUG_MODE : self.nodeNet.printInfo ()

        # preserve existing links for parameter connectors
        if connector.isLinked() and not connector.isNode():
            if connector.isInput():
                #print '*** preserve input ***'
                # TODO!!!
                # This is very rough code -- needs to be wrapped in functions
                gfxLinks = connector.getInputGfxLinks()

                for gfxLink in gfxLinks:
                    gfxLink.setDstConnector(newConnector)

                    # remove gfxLink from previouse connector
                    connector.removeGfxLink(gfxLink)

                    # adjust destination for node link
                    newConnector.getNode().attachInputParamToLink(
                        newConnector.getInputParam(), gfxLink.link)
                    newConnector.getNode().addChild(gfxLink.link.srcNode)
                    connector.getNode().removeChild(gfxLink.link.srcNode)

                    gfxLink.link.dstNode = newConnector.getNode()
                    gfxLink.link.dstParam = newConnector.getInputParam()
            else:
                #print '*** preserve output ***'
                gfxLinks = connector.getOutputGfxLinks()

                for gfxLink in gfxLinks:
                    gfxLink.setSrcConnector(newConnector)

                    # remove gfxLink from previouse connector
                    connector.removeGfxLink(gfxLink)

                    # adjust source for node link
                    connector.getNode().detachOutputParamFromLink(
                        gfxLink.link.srcParam, gfxLink.link)
                    newConnector.getNode().attachOutputParamToLink(
                        newConnector.getOutputParam(), gfxLink.link)
                    #newConnector.getNode ().childs.add ( connector.getNode () )
                    gfxLink.link.dstNode.addChild(newConnector.getNode())
                    gfxLink.link.dstNode.removeChild(connector.getNode())

                    gfxLink.link.srcNode = newConnector.getNode()
                    gfxLink.link.srcParam = newConnector.getOutputParam()

            #if DEBUG_MODE : self.nodeNet.printInfo ()

        gfxLink = GfxLink(link, connector, newConnector)
        self.scene().addItem(gfxLink)

    #
    # onTraceNodeConnector
    #
    def onTraceNodeConnector(self, connector, scenePos):
        #
        #if DEBUG_MODE : print '>> WorkArea::onTraceNodeConnector'
        if self.lastConnectCandidate is not None:
            self.lastConnectCandidate.setPos(scenePos)
            self.lastConnectCandidate.moveBy(-connector.radius,
                                             -connector.radius)
    #

    # onEndNodeConnector
    #

    def onEndNodeConnector(self, connector, scenePos):
        #
        if DEBUG_MODE: print '>> WorkArea::onEndNodeConnector'
        print '>> lastConnectCandidate.node.type = %s' % self.lastConnectCandidate.node.type
        self.lastConnectCandidateReset()
        self.state = 'idle'

    #
    # onRemoveNode
    #
    def onRemoveNode(self, gfxNode):
        #
        print ">> WorkArea.onRemoveNode %s (id = %d)" % (gfxNode.node.label,
                                                         gfxNode.node.id)
        if usePyQt4:
            self.emit(QtCore.SIGNAL('gfxNodeRemoved'), gfxNode)
        else:
            self.gfxNodeRemoved.emit(gfxNode)
        self.scene().removeItem(gfxNode)
        self.nodeNet.removeNode(gfxNode.node)

        #if DEBUG_MODE : self.nodeNet.printInfo ()

    #
    # onRemoveLink
    #
    def onRemoveLink(self, gfxLink):
        #
        print ">> WorkArea.onRemoveLink ..."
        self.scene().removeItem(gfxLink)

        if gfxLink.link is not None:
            print "*** (id = %d)" % (gfxLink.link.id)
            srcConnector = gfxLink.srcConnector
            dstConnector = gfxLink.dstConnector
            self.nodeNet.removeLink(gfxLink.link)
            if srcConnector is not None:
                if DEBUG_MODE:
                    print '*** srcConnector.parentItem().node.label = %s ' % srcConnector.getNode(
                    ).label
                #self.emit( QtCore.SIGNAL( 'nodeConnectionChanged' ), srcConnector.parentItem(), srcConnector.param )
            if dstConnector is not None:
                if DEBUG_MODE:
                    print '*** dstConnector.parentItem().node.label = %s ' % dstConnector.getNode(
                    ).label
                if usePyQt4:
                    self.emit(QtCore.SIGNAL('nodeConnectionChanged'),
                              dstConnector.getGfxNode(), dstConnector.param)
                else:
                    self.nodeConnectionChanged.emit(dstConnector.getGfxNode(),
                                                    dstConnector.param)

    #
    # removeSelected
    #
    def removeSelected(self):
        #
        if DEBUG_MODE:
            print '>> WorkArea.removeSelected: (before) nodes = %d links = %d' % (
                len(self.nodeNet.nodes.values()),
                len(self.nodeNet.links.values()))
        selected = self.scene().selectedItems()

        for item in selected:
            if (isinstance(item, GfxLink) or isinstance(item, GfxNode)
                    or isinstance(item, GfxNote)
                    or isinstance(item, GfxSwatchNode)
                    or (isinstance(item, GfxNodeConnector) and item.isNode())):
                item.remove()

        if DEBUG_MODE:
            print '>> WorkArea.removeSelected (after) nodes = %d links = %d' % (
                len(self.nodeNet.nodes.values()),
                len(self.nodeNet.links.values()))

    #
    # dragEnterEvent
    #
    def dragEnterEvent(self, event):
        #
        print '>> WorkArea.onDragEnterEvent'
        #for form_str in event.mimeData().formats():
        #  print str ( form_str )
        #  if form_str == 'text/uri-list' :
        #    print event.mimeData().data( 'text/uri-list' )
        mimedata = event.mimeData()

        if mimedata.hasFormat('application/x-text') or mimedata.hasFormat(
                'text/uri-list'):
            event.accept()
        else:
            event.ignore()

    #
    # dragMoveEvent
    #
    def dragMoveEvent(self, event):
        #print ">> WorkArea.dragMoveEvent"
        mimedata = event.mimeData()
        if mimedata.hasFormat('application/x-text') or mimedata.hasFormat(
                'text/uri-list'):
            event.setDropAction(QtCore.Qt.CopyAction)
            event.accept()
        else:
            event.ignore()

    #
    # dropEvent
    #
    def dropEvent(self, event):
        #
        import os
        if DEBUG_MODE: print ">> WorkArea.dropEvent"
        file_list = []
        mimedata = event.mimeData()

        if mimedata.hasFormat('application/x-text'):
            # decode drop stuff
            data = mimedata.data('application/x-text')
            stream = QtCore.QDataStream(data, QtCore.QIODevice.ReadOnly)
            if usePyQt4:
                filename = QtCore.QString()
            else:
                filename = ''
            if not usePyQt5:
                if usePySide:
                    filename = stream.readString()
                else:
                    stream >> filename
            else:
                filename = stream.readBytes()

            if DEBUG_MODE: print '* read itemFilename = %s' % (filename)

            file_list.append(filename)
            event.setDropAction(QtCore.Qt.CopyAction)
            event.accept()
        elif mimedata.hasFormat('text/uri-list'):
            data = str(mimedata.data('text/uri-list').data())
            #print data
            for item in data.split():
                filename = str(QtCore.QUrl(item).toLocalFile())

                (name, ext) = os.path.splitext(os.path.basename(filename))
                if DEBUG_MODE: print ':: %s (%s)' % (filename, ext)
                if ext == '.xml':
                    file_list.append(filename)
        else:
            event.ignore()

        for file_name in file_list:
            self.insertNodeNet(file_name, self.mapToScene(event.pos()))

    #
    # keyPressEvent
    #
    def keyPressEvent(self, event):
        #print ">> WorkArea.keyPressEvent"
        QtModule.QGraphicsView.keyPressEvent(self, event)

    #
    # wheelEvent
    #
    def wheelEvent(self, event):
        #print ">> WorkArea.wheelEvent"
        # QtGui.QGraphicsView.wheelEvent( self, event)
        import sys, math
        scale = -1.0
        if 'linux' in sys.platform: scale = 1.0
        if not usePyQt5:
            scaleFactor = math.pow(2.0, scale * event.delta() / 600.0)
        else:
            delta = event.angleDelta()
            #print ( '>> delta rx = %d ry = %d' % ( delta.x (), delta.y () ) )
            scaleFactor = math.pow(2.0, scale * delta.y() / 600.0)
        # self.matrix () is depicated
        factor = self.transform().scale(scaleFactor, scaleFactor).mapRect(
            QtCore.QRectF(-1, -1, 2, 2)).width()
        if factor < 0.07 or factor > 100: return
        self.scale(scaleFactor, scaleFactor)

    #
    # mousePressEvent
    #
    def mousePressEvent(self, event):
        #print ">> WorkArea.mousePressEvent"
        #self.setFocus ()
        self.startPos = self.mapToScene(event.pos())
        self.pressed = True
        button = event.button()
        modifiers = event.modifiers()

        if (button == QtCore.Qt.MidButton
                or (button == QtCore.Qt.LeftButton
                    and modifiers == QtCore.Qt.ShiftModifier)):
            self.state = 'pan'
            return
        if button == QtCore.Qt.RightButton and modifiers == QtCore.Qt.ShiftModifier:
            self.state = 'zoom'
            return
        QtModule.QGraphicsView.mousePressEvent(self, event)

    #
    # mouseDoubleClickEvent
    #
    def mouseDoubleClickEvent(self, event):
        #
        #print ">> WorkArea.mouseDoubleClickEvent"
        selected = self.scene().selectedItems()

        QtModule.QGraphicsView.mouseDoubleClickEvent(self, event)

    #
    # mouseMoveEvent
    #
    def mouseMoveEvent(self, event):
        #print ">> WorkArea.mouseMoveEvent"
        #if self.pressed :
        currentPos = self.mapToScene(event.pos())
        if self.state == 'pan':
            deltaPos = currentPos - self.startPos
            self.setInteractive(False)
            self.translate(deltaPos.x(), deltaPos.y())
            self.setInteractive(True)

        elif self.state == 'zoom':
            #
            import sys, math
            deltaPos = currentPos - self.startPos
            scale = -1.0
            if 'linux' in sys.platform: scale = 1.0
            scaleFactor = math.pow(2.0,
                                   scale * max(deltaPos.x(), deltaPos.y()) /
                                   200.0)  #
            factor = self.transform().scale(scaleFactor, scaleFactor).mapRect(
                QtCore.QRectF(-1, -1, 2, 2)).width()

            if factor < 0.07 or factor > 100: return
            # update view matrix
            self.setInteractive(False)
            self.scale(scaleFactor, scaleFactor)
            self.translate(-deltaPos.x() * scaleFactor,
                           -deltaPos.y() * scaleFactor)
            self.setInteractive(True)
            #self.startPos = currentPos
        else:
            QtModule.QGraphicsView.mouseMoveEvent(self, event)

    #
    # mouseReleaseEvent
    #
    def mouseReleaseEvent(self, event):
        #print ">> WorkArea.mouseReleaseEvent"
        if self.state in ['pan', 'zoom']:
            self.state = 'idle'
            self.startPos = None
            self.pressed = False
        QtModule.QGraphicsView.mouseReleaseEvent(self, event)

    #
    # resetZoom
    #
    def resetZoom(self):
        #
        if DEBUG_MODE: print(">> WorkArea.resetZoom")
        self.setInteractive(False)
        self.resetTransform()
        self.centerOn(0.0, 0.0)
        self.setInteractive(True)

    #
    # viewportEvent
    #
    def viewportEvent(self, event):
        #case QEvent::TouchBegin:
        # case QEvent::TouchUpdate:
        # case QEvent::TouchEnd:
        if event.type() == QtCore.QEvent.TouchBegin:
            if DEBUG_MODE: print(">> WorkArea.QEvent.TouchBegin")
        return QtModule.QGraphicsView.viewportEvent(self, event)

    #
    # deselectAllNodes
    #
    def deselectAllNodes(self):
        selected = self.scene().selectedItems()
        for item in selected:
            item.setSelected(False)

    #
    # openNodeNet
    #
    def openNodeNet(self, filename, pos=None):
        #
        (nodes, links) = self.nodeNet.open(normPath(filename))
        for node in nodes:
            self.addGfxNode(node)
        for link in links:
            self.addGfxLink(link)

    #
    # insertNodeNet
    #
    # Called by signal 'addNode'
    def insertNodeNet(self, filename, pos=None):
        #
        if DEBUG_MODE:
            print('>> WorkArea.insertNodeNet filename = ' + filename)
        if DEBUG_MODE:
            print(">> WorkArea.insertNodeNet (before) nodes = %d links = %d" %
                  (len(self.nodeNet.nodes.values()),
                   len(self.nodeNet.links.values())))
        (nodes, links) = self.nodeNet.insert(normPath(filename))

        if pos == None:
            # on dblclk -- insert node at left border of sceneBound
            sceneBound = self.scene().itemsBoundingRect()
            if not sceneBound.isNull():
                x_offset = sceneBound.x() - self.minGap
                pos = QtCore.QPointF(x_offset, 0)

        self.deselectAllNodes()

        for node in nodes:
            self.addGfxNode(node, pos)
        for link in links:
            self.addGfxLink(link)

        if DEBUG_MODE:
            print('>> WorkArea.insertNodeNet (after) nodes = %d links = %d' %
                  (len(self.nodeNet.nodes.values()),
                   len(self.nodeNet.links.values())))

    #
    # copyNodes
    #
    def copyNodes(self, clipboard, cutNodes=False):
        #
        if DEBUG_MODE:
            print('>> WorkArea.copyNodes ( cutNodes = %s )' % str(cutNodes))

        dupNodeNet = NodeNetwork('clipboard')

        for gfxNode in self.selectedNodes:
            dupNode = gfxNode.node.copy()
            dupNodeNet.addNode(dupNode)

        for gfxNode in self.selectedNodes:
            for link in gfxNode.node.getInputLinks():
                #link.printInfo ()
                dupLink = link.copy()
                dupDstNode = dupNodeNet.getNodeByID(gfxNode.node.id)

                if dupDstNode is not None:
                    dupDstParam = dupDstNode.getInputParamByName(
                        link.dstParam.name)
                    dupLink.setDst(dupDstNode, dupDstParam)

                    (srcNode, srcParam) = dupLink.getSrc()
                    dupSrcNode = dupNodeNet.getNodeByID(srcNode.id)

                    if dupSrcNode is not None:
                        # if srcNode is inside dupNodeNet
                        dupSrcParam = dupSrcNode.getOutputParamByName(
                            srcParam.name)
                        dupLink.setSrc(dupSrcNode, dupSrcParam)
                        dupNodeNet.addLink(dupLink)

        dom = QtXml.QDomDocument(dupNodeNet.name)
        dupNodeNet.parseToXML(dom)

        clipboard.clear()
        clipboard.setText(
            dom.toString()
        )  # .	fromUtf16 () .fromUtf8 () encode( 'utf-8' ) unicode ( dom.toByteArray () ) toString ()

        if cutNodes: self.removeSelected()

    #
    # pasteNodes
    #
    def pasteNodes(self, clipboard):
        #
        if DEBUG_MODE: print('>> WorkArea.pasteNodes ...')
        nodes = []
        links = []

        dom = QtXml.QDomDocument('clipboard')
        dom.setContent(clipboard.text())
        root = dom.documentElement()
        if root.nodeName() == 'node':
            nodes.append(self.nodeNet.addNodeFromXML(root))
            self.nodeNet.correct_id(nodes, links)
        elif root.nodeName() == 'nodenet':
            #print ':: parsing nodenet from XML ...'
            nodeNet = NodeNetwork('tmp', root)
            (nodes, links) = self.nodeNet.add(nodeNet)
        else:
            print '!! unknown XML document format'
            return

        offsetPos = QtCore.QPointF(self.minGap, self.minGap / 2)
        self.deselectAllNodes()

        for node in nodes:
            self.addGfxNode(node, offsetPos)
        for link in links:
            self.addGfxLink(link)

    #
    # duplicateNodes
    #
    def duplicateNodes(self, preserveLinks=False):
        #
        if DEBUG_MODE:
            print('>> WorkArea.duplicateNode ( preserveLinks = %s )' %
                  str(preserveLinks))

        dupNodeNet = NodeNetwork('duplicate')

        for gfxNode in self.selectedNodes:
            dupNode = gfxNode.node.copy()
            dupNodeNet.addNode(dupNode)

        for gfxNode in self.selectedNodes:
            for link in gfxNode.node.getInputLinks():
                #link.printInfo ()
                dupLink = link.copy()
                dupDstNode = dupNodeNet.getNodeByID(gfxNode.node.id)

                if dupDstNode is not None:
                    dupDstParam = dupDstNode.getInputParamByName(
                        link.dstParam.name)
                    dupLink.setDst(dupDstNode, dupDstParam)

                    (srcNode, srcParam) = dupLink.getSrc()
                    dupSrcNode = dupNodeNet.getNodeByID(srcNode.id)

                    if dupSrcNode is not None:
                        # if srcNode is inside dupNodeNet
                        dupSrcParam = dupSrcNode.getOutputParamByName(
                            srcParam.name)
                        dupLink.setSrc(dupSrcNode, dupSrcParam)
                        dupNodeNet.addLink(dupLink)
                    else:
                        # if this is outside links
                        if preserveLinks:
                            dupNodeNet.addLink(dupLink)
                        else:
                            dupLink.setSrc(None, None)
                            dupLink.setDst(None, None)

        #if DEBUG_MODE : dupNodeNet.printInfo ()
        (nodes, links) = self.nodeNet.add(dupNodeNet)

        offsetPos = QtCore.QPointF(self.minGap, self.minGap / 2)

        self.deselectAllNodes()

        for node in nodes:
            self.addGfxNode(node, offsetPos)
        for link in links:
            self.addGfxLink(link)

    #
    # newNodeNetFromList
    #
    def nodeNetFromSelected(self, nodeNetName, preserveLinks=False):
        #
        if DEBUG_MODE:
            print('>> WorkArea.nodeNetFromSelected ( preserveLinks = %s )' %
                  str(preserveLinks))
        dupNodeNet = NodeNetwork(nodeNetName)

        for gfxNode in self.selectedNodes:
            dupNode = gfxNode.node.copy()
            dupNodeNet.addNode(dupNode)

        for gfxNode in self.selectedNodes:
            for link in gfxNode.node.getInputLinks():
                #link.printInfo ()
                dupLink = link.copy()
                dupDstNode = dupNodeNet.getNodeByID(gfxNode.node.id)

                if dupDstNode is not None:
                    dupDstParam = dupDstNode.getInputParamByName(
                        link.dstParam.name)
                    dupLink.setDst(dupDstNode, dupDstParam)

                    (srcNode, srcParam) = dupLink.getSrc()
                    dupSrcNode = dupNodeNet.getNodeByID(srcNode.id)

                    if dupSrcNode is not None:
                        # if srcNode is inside dupNodeNet
                        dupSrcParam = dupSrcNode.getOutputParamByName(
                            srcParam.name)
                        dupLink.setSrc(dupSrcNode, dupSrcParam)
                        dupNodeNet.addLink(dupLink)
                    else:
                        # if this is outside links
                        if preserveLinks:
                            dupNodeNet.addLink(dupLink)
                        else:
                            dupLink.setSrc(None, None)
                            dupLink.setDst(None, None)

        return dupNodeNet
示例#20
0
class Node ( QtCore.QObject ) :
	#
	id = 0
	#
	# __init__
	#
	def __init__ ( self, xml_node = None, nodenet = None ) :
		#
		QtCore.QObject.__init__ ( self )
		#
		# Define signals for PyQt5
		#
		if usePySide or usePyQt5 :
			#
			self.nodeUpdated = Signal () # QtCore.pyqtSignal ( [QtCore.QObject] )
			self.nodeParamsUpdated = Signal () #QtCore.pyqtSignal ( [QtCore.QObject] )
			#
		self.id = None
		self.name = None
		self.label = None
		self.type = None
		
		self.version = None
		self.format = None
		self.parent = None
		self.dirty = False

		self.author = None
		self.help = None
		self.icon = None

		self.master = None

		self.code = None            # Node code (RSL, RIB, ... )
		self.control_code = None    # python code executed before node computation
		self.computed_code = None   # code collected after compute on all connected nodes
		
		self.event_code = {}
		#self.event_code [ 'ParamLabelRenamed' ] = None
		#self.event_code [ 'ParamAdded' ] = None
		#self.event_code [ 'ParamRemoved' ] = None

		self.display = True

		self.computedInputParams = None
		self.computedOutputParams = None
		self.computedLocalParams = None
		self.computedIncludes = None
		self.computedLocals = None
		self.computedCode = None

		#self.previewCode = None

		self.inputParams = []
		self.outputParams = []
		self.internals = []
		self.includes = []

		self.inputLinks = {}
		self.outputLinks = {}

		self.childs = set()

		self.nodenet = nodenet

		# position from GfxNode
		self.offset = ( 0, 0 )

		if xml_node != None :
			self.parseFromXML ( xml_node )
	#
	# __del__
	#
	def __del__ ( self ) :
		#
		if DEBUG_MODE : print ( '>> Node( %s ).__del__' % self.label )
	#
	# build
	#
	@classmethod
	def build ( cls ) :
		# set unique id while building
		node = cls ()
		Node.id += 1
		node.id = Node.id
		return node
	#
	# copy
	#
	def copy ( self ) : assert 0, 'copy needs to be implemented!'
	#
	# updateNode
	#
	def updateNode ( self, emit_signal = False ) : 
		#
		if DEBUG_MODE : print ( '>> Node( %s ).updateNode' % self.label  ), emit_signal
		if emit_signal :
			if DEBUG_MODE : print ( '** emit signal nodeUpdated' )
			if usePyQt4 :
				self.emit ( QtCore.SIGNAL ( 'nodeUpdated' ), self )
			else :
				self.nodeUpdated.emit ( self )
	#
	# updateNodeParams
	#
	def updateNodeParams ( self, emit_signal = False ) : 
		#
		if DEBUG_MODE : print ( '>> Node( %s ).updateNodeParams' % self.label ), emit_signal
		if emit_signal :
			if usePyQt4 :
				self.emit ( QtCore.SIGNAL ( 'nodeParamsUpdated' ), self )
			else :
				self.nodeParamsUpdated.emit ( self )
	#
	# addChild
	#
	def addChild ( self, node ) : self.childs.add ( node )
	#
	# removeChild
	#
	def removeChild ( self, node ) :
		#
		if node in self.childs :
			self.childs.remove ( node )
			if DEBUG_MODE : print ( '** Node(%s).removeChild %s' % ( self.label, node.label ) )
		else :
			if DEBUG_MODE : print ( '!! Node(%s).removeChild child %s is not in the list' % ( self.label, node.label ) )
	#
	# printInfo
	#
	def printInfo ( self ) :
		#
		print ( ':: Node (id = %d) label = %s' % ( self.id, self.label ) )
		print ( '** Node inputLinks:' )
		for param in self.inputLinks.keys () :
			print ( '\t* param: %s (%s) linked to ' % ( param.name, param.label ) )
			self.inputLinks [ param ].printInfo ()
		print ( '** Node outputLinks:' )
		#print '*****', self.outputLinks
		for param in self.outputLinks.keys () :
			print ( '\t* param: %s (%s) linked to ' % ( param.name, param.label ) )
			linklist = self.outputLinks [ param ]
			for link in linklist :
				link.printInfo ()
		print ( '** Node children:' )
		for child in self.childs :
			print ( '\t* %s' % child.label )
	#
	# addInputParam
	#
	def addInputParam ( self, param ) :
		#
		param.isInput = True
		# to be sure that name and label is unique
		if param.name in self.getParamsNames () : self.renameParamName ( param, param.name )
		if param.label in self.getParamsLabels () : self.renameParamLabel ( param, param.label )
		self.inputParams.append ( param )
		if self.event_code :
			if 'ParamAdded' in self.event_code.keys () :
				exec ( self.event_code [ 'ParamAdded' ], { 'param' : param, 'self' : self } )
	#
	# addOutputParam
	#
	def addOutputParam ( self, param ) :
		#
		param.isInput = False
		# to be sure that name and label is unique
		if param.name in self.getParamsNames () : self.renameParamName ( param, param.name )
		if param.label in self.getParamsLabels () : self.renameParamLabel ( param, param.label )
		self.outputParams.append ( param )
		if self.event_code :
			if 'ParamAdded' in self.event_code.keys () :
				exec ( self.event_code [ 'ParamAdded' ], { 'param' : param, 'self' : self } )
	#
	# addInternal
	#
	def addInternal ( self, newName ) :
		#print '--> add internal: %s' % internal
		internal = newName
		if internal != '' :
			from meCommon import getUniqueName
			internal = getUniqueName ( newName, self.internals )
			self.internals.append ( internal )
		return internal
	#
	# addInclude
	#
	def addInclude ( self, newName ) :
		#print '--> add include: %s' % include
		include = newName
		if include != '' :
			from meCommon import getUniqueName
			include = getUniqueName ( newName, self.includes )
			self.includes.append ( include )
		return include
	#
	# attachInputParamToLink
	#
	def attachInputParamToLink ( self, param, link ) :
		#
		self.inputLinks [ param ] = link
	#
	# attachOutputParamToLink
	#
	def attachOutputParamToLink ( self, param, link ) :
		#
		#if DEBUG_MODE : print ">> Node::attachOutputParamToLink param = %s" % param.name
		if not param in self.outputLinks.keys () :
			self.outputLinks [ param ] = []
		if not link in self.outputLinks [ param ] :
			self.outputLinks [ param ].append ( link )
	#
	# detachInputParam
	#
	def detachInputParam ( self, param ) :
		#
		removedLink = None
		if DEBUG_MODE : print ( ">> Node::detachInputParam param = %s" % param.name )
		if param in self.inputLinks.keys () :
			removedLink = self.inputLinks.pop ( param )
		return removedLink
	#
	# detachOutputParam
	#
	def detachOutputParam ( self, param ) :
		#
		removedLinks = []
		if param in self.outputLinks.keys () :
			outputLinks = self.outputLinks [ param ]
			for link in outputLinks :
				removedLinks.append ( link )
			self.outputLinks.pop ( param )
		return removedLinks
	#
	# detachOutputParamFromLink
	#
	def detachOutputParamFromLink ( self, param, link ) :
		#
		removedLink = None
		if param in self.outputLinks.keys () :
			outputLinks = self.outputLinks [ param ]
			if link in outputLinks :
				removedLink = link
				outputLinks.remove ( link )
		return removedLink
	#
	# isInputParamLinked
	#
	def isInputParamLinked ( self, param ) : return param in self.inputLinks.keys ()
	#
	# isOutputParamLinked
	#
	def isOutputParamLinked ( self, param ) : return param in self.outputLinks.keys ()
	#
	# getLinkedSrcNode
	#
	def getLinkedSrcNode ( self, param ) :
		# returns node linked to input parameter param,
		# skipping all ConnectorNode
		#
		#if DEBUG_MODE : print '* getLinkedSrcNode node = %s param = %s' % ( self.label, param.label )
		srcNode = None
		srcParam = None
		if self.isInputParamLinked ( param ) :
			#if DEBUG_MODE : print '* isInputParamLinked'
			link = self.inputLinks [ param ]
			if link.srcNode.type == 'connector' :
				if len ( link.srcNode.inputParams ) :
					firstParam = link.srcNode.inputParams [0]
					( srcNode, srcParam ) = link.srcNode.getLinkedSrcNode ( firstParam )
				else :
					if DEBUG_MODE : print ( '* no inputParams at connector %s' % ( link.srcNode.label ) )
			else :
				srcNode = link.srcNode
				srcParam = link.srcParam
		return ( srcNode, srcParam )
	#
	# getLinkedDstNodes
	#
	def getLinkedDstNodes ( self, param, dstConnections = [] ) :
		# returns nodes linked to output parameter param,
		# skipping all ConnectorNode
		#
		#if DEBUG_MODE : print '*** getLinkedDstNodese node = %s param = %s' % ( self.label, param.label )
		dstNode = None
		dstParam = None
		# dstConnections = []
		if self.isOutputParamLinked ( param ) :
			#if DEBUG_MODE : print '* isOutputParamLinked'
			dstLinks = self.getOutputLinks ( param )
			for link in dstLinks :
				if link.dstNode.type == 'connector' :
					#if DEBUG_MODE : print '* link.dstNode.type == connector'
					connectorOutputParams = link.dstNode.outputParams
					if len ( connectorOutputParams ) > 0 :
						for connectorOutputParam in connectorOutputParams :
							connectorDstConnections = []
							retList = link.dstNode.getLinkedDstNodes ( connectorOutputParam, connectorDstConnections )
							for ( retNode, retParam ) in retList : 
								dstConnections.append ( ( retNode, retParam ) )
					else :
						if DEBUG_MODE : print ( '* no outputParams at connector %s' % ( link.dstNode.label ) )
				else :
					dstNode = link.dstNode
					dstParam = link.dstParam
					dstConnections.append ( ( dstNode, dstParam ) )
		return dstConnections
	#
	# removeParam
	#
	def removeParam ( self, param ) :
		#
		if self.event_code :
			if 'ParamRemoving' in self.event_code.keys () :
				exec ( self.event_code [ 'ParamRemoving' ], { 'param' : param, 'self' : self } )
		
		removedLinks = []
		if param.isInput :
			link = self.detachInputParam ( param )
			if link is not None : removedLinks.append ( link )
			self.inputParams.remove ( param )
		else :
			removedLinks = self.detachOutputParam ( param )
			self.outputParams.remove ( param )
		if self.event_code :
			if 'ParamRemoved' in self.event_code.keys () :
				exec ( self.event_code [ 'ParamRemoved' ], { 'param' : param, 'self' : self } )
		return removedLinks
	#
	# getInputParamByName
	#
	def getInputParamByName ( self, name ) :
		#
		result = None
		for param in self.inputParams :
			if param.name == name :
				result = param
				break
		return result
	#
	# getOutputParamByName
	#
	def getOutputParamByName ( self, name ) :
		#
		result = None
		for param in self.outputParams :
			if param.name == name :
				result = param
				break
		return result
	#
	# getInputParamValueByName
	#
	def getInputParamValueByName ( self, name, CodeOnly = False ) :
		#
		result = None
		srcNode = srcParam = None
		param = self.getInputParamByName ( name )
		( srcNode, srcParam ) = self.getLinkedSrcNode ( param )
		if srcNode is not None :
			# computation may be skipped if we need only value
			#if compute :
			srcNode.computeNode ( CodeOnly )
			if self.computed_code is not None :
				self.computed_code += srcNode.computed_code
			result = srcNode.parseGlobalVars ( srcParam.getValueToStr () )
		else :
			result = param.getValueToStr ()

		return result
	#
	# return common list for input and output parameters
	#
	def getParamsList ( self ) :
		#
		params = self.inputParams + self.outputParams
		return params
	#
	# getParamsNames
	#
	def getParamsNames ( self ) :
		#
		names = []
		for pm in self.getParamsList () : names.append ( pm.name )
		return names
	#
	# getParamsLabels
	#
	def getParamsLabels ( self ) :
		#
		labels = []
		for pm in self.getParamsList () : labels.append ( pm.label )
		return labels
	#
	# getInputLinks
	#
	def getInputLinks ( self ) :
		#
		inputLinks = []
		for link in self.inputLinks.values () :
			inputLinks.append ( link )
		return inputLinks
	#
	# getOutputLinks
	#
	def getOutputLinks ( self, param = None ) :
		#
		outputLinks = []
		for link_list in self.outputLinks.values () :
			for link in link_list :
				if param is not None :
					if link.srcParam != param :
						continue
				outputLinks.append ( link )
		return outputLinks
	#
	# getInputLinkByID
	#
	def getInputLinkByID ( self, id ) :
		#
		result = None
		for link in self.getInputLinks () :
			if link.id == id :
				result = link
				break
		return result
	#
	# getOutputLinkByID
	#
	def getOutputLinkByID ( self, id ) :
		#
		result = None
		for link in self.getOutputLinks () :
			if link.id == id :
				result = link
				break
		return result
	#
	# renameParamName
	#
	def renameParamName ( self, param, newName ) :
		# assign new unique name to param
		from meCommon import getUniqueName
		param.name = getUniqueName ( newName, self.getParamsNames() )
		return param.name
	#
	# renameParamLabel
	#
	def renameParamLabel ( self, param, newLabel ) :
		#
		oldLabel = param.label
		if DEBUG_MODE : print ( ">> Node( %s ).renameParamLabel  oldLabel = %s newLabel = %s" % ( self.label, oldLabel, newLabel ) )
		if newLabel == '' : newLabel = self.param.name
		# assign new unique label to param
		from meCommon import getUniqueName
		param.label = getUniqueName ( newLabel, self.getParamsLabels () )
		if self.event_code :
			if 'ParamLabelRenamed' in self.event_code.keys () :
				exec ( self.event_code [ 'ParamLabelRenamed' ], { 'param' : param, 'self' : self, 'oldLabel' : oldLabel } )
		
		return param.label
	#
	# onParamChanged
	#
	def onParamChanged ( self, param ) :
		#
		if DEBUG_MODE : print ( ">> Node: onParamChanged node = %s param = %s (pass...)" % ( self.label, param.name ) )
		pass
		#self.emit( QtCore.SIGNAL( 'onNodeParamChanged(QObject,QObject)' ), self, param )
	#
	# getLabel
	#
	def getLabel ( self ) : return self.label
	#
	# getName
	#
	def getName ( self ) : return self.name
	#
	# getNodenetName
	#
	def getNodenetName ( self ) : return self.nodenet.getName ()
	#
	# getInstanceName
	#
	def getInstanceName ( self ) : return  getParsedLabel ( self.label )
	#
	# getParamName
	#
	def getParamName ( self, param ) :
		#
		if param.isRibParam  or param.provider == 'attribute':
			paramName = param.name
		elif param.provider == 'primitive' : 
			paramName = getParsedLabel ( param.label )
		else :
			paramName = self.getInstanceName () + '_' + getParsedLabel ( param.label )
		return paramName
	#
	# getParamDeclaration
	#
	def getParamDeclaration ( self, param ) :
		#
		result = ''
		result += param.typeToStr () + ' '
		result += self.getParamName ( param )
		if param.isArray () and not param.isRibParam :
			arraySize = ''
			if param.arraySize > 0 :
				arraySize = str ( param.arraySize )
			result += '[%s]' % arraySize
		result += ' = ' + param.getValueToStr () + ';\n'
		return result
	#
	# parseFromXML
	#
	def parseFromXML ( self, xml_node ) :
		#
		id_node = xml_node.attributes ().namedItem ( 'id' )
		if not id_node.isNull () :
			self.id = int ( id_node.nodeValue () )
		else :
			if DEBUG_MODE : print ( '>> Node::parseFromXML id is None' )

		self.name = str ( xml_node.attributes ().namedItem ( 'name' ).nodeValue () )
		self.label = str ( xml_node.attributes ().namedItem ( 'label' ).nodeValue () )
		if self.label == '' : self.label = self.name
		#print '-> parsing from XML node name= %s label= %s' % ( self.name, self.label )

		self.version = str ( xml_node.attributes ().namedItem ( 'version' ).nodeValue () )
		self.parent = str ( xml_node.attributes ().namedItem ( 'parent' ).nodeValue () )
		self.format = str ( xml_node.attributes ().namedItem ( 'format' ).nodeValue () )
		
		self.author = str ( xml_node.attributes ().namedItem ( 'author' ).nodeValue () )
		self.type = str ( xml_node.attributes ().namedItem ( 'type' ).nodeValue () )
		#
		# try to convert from old format nodes
		#
		if self.version == '' or self.version is None :
			if self.format == '' or self.format is None :
				( self.type, self.format ) = translateOldType ( self.type )
			
		help_tag = xml_node.namedItem ( 'help' )
		if not help_tag.isNull() :
			self.help = help_tag.toElement ().text ()
		self.icon = str ( xml_node.attributes ().namedItem ( 'icon' ).nodeValue () )

		input_tag = xml_node.namedItem ( 'input' )
		if not input_tag.isNull () :
			xml_paramList = input_tag.toElement ().elementsByTagName ( 'property' )
			for i in range ( 0, xml_paramList.length () ) :
				xml_param = xml_paramList.item ( i )
				#
				# some parameters (String, Color, Point, Vector, Normal, Matrix ...)
				# have different string interpretation in RIB
				#
				isRibParam = ( self.format == 'rib' )
				param = createParamFromXml ( xml_param, isRibParam, True ) # #param.isInput = True
				self.addInputParam ( param )

		output_tag = xml_node.namedItem ( 'output' )
		if not output_tag.isNull () :
			xml_paramList = output_tag.toElement ().elementsByTagName ( 'property' )
			for i in range ( 0, xml_paramList.length () ) :
				xml_param = xml_paramList.item ( i )
				#
				# some parameters (Color, Point, Vector, Normal, Matrix ...)
				# have different string interpretation in RIB
				#
				isRibParam = ( self.format == 'rib' )
				param = createParamFromXml ( xml_param, isRibParam, False ) # #param.isInput = False
				self.addOutputParam ( param )

		internal_tag = xml_node.namedItem ( 'internal' )
		if not internal_tag.isNull () :
			xml_internalList = internal_tag.toElement ().elementsByTagName ( 'variable' )
			for i in range ( 0, xml_internalList.length () ) :
				var_tag = xml_internalList.item ( i )
				var = str ( var_tag.attributes ().namedItem ( 'name' ).nodeValue () )
				self.addInternal ( var )

		include_tag = xml_node.namedItem ( 'include' )
		if not include_tag.isNull () :
			xml_includeList = include_tag.toElement ().elementsByTagName ( 'file' )
			for i in range ( 0, xml_includeList.length () ) :
				inc_tag = xml_includeList.item ( i )
				inc = str ( inc_tag.attributes ().namedItem ( 'name' ).nodeValue () )
				self.addInclude ( inc )

		offset_tag = xml_node.namedItem ( 'offset' )
		if not offset_tag.isNull() :
			x = float ( offset_tag.attributes ().namedItem ( 'x' ).nodeValue () )
			y = float ( offset_tag.attributes ().namedItem ( 'y' ).nodeValue () )
			self.offset = ( x, y )

		control_code_tag = xml_node.namedItem ( 'control_code' )
		if not control_code_tag.isNull () :
			code_str = str ( control_code_tag.toElement ().text () )
			if code_str.lstrip () == '' : code_str = None
			self.control_code = code_str
		else :
			# for temp. backward compatibility
			control_code_tag = xml_node.namedItem ( 'param_code' )
			if not control_code_tag.isNull() :
				code_str = str ( control_code_tag.toElement ().text () )
				if code_str.lstrip () == '' : code_str = None
				self.control_code = code_str
				
		code_tag = xml_node.namedItem ( 'code' )
		if not code_tag.isNull () :
			code_str = str ( code_tag.toElement ().text () )
			if code_str.lstrip () == '' : code_str = None
			self.code = code_str
			
		event_code_tag = xml_node.namedItem ( 'event_code' )
		if not event_code_tag.isNull () :
			xml_handlerList = event_code_tag.toElement ().elementsByTagName ( 'handler' )
			for i in range ( 0, xml_handlerList.length () ) :
				handler_tag = xml_handlerList.item ( i )
				handler_name = str ( handler_tag.attributes ().namedItem ( 'name' ).nodeValue () )
				code_str = str ( handler_tag.toElement ().text () ).lstrip ()
				if code_str == '' : code_str = None
				self.event_code [ handler_name ] = code_str
	#
	# parseToXML
	#
	def parseToXML ( self, dom ) :
		#
		xml_node = dom.createElement ( 'node' )
		if DEBUG_MODE : print ( '>> Node::parseToXML (id = %d)' % ( self.id ) )
		if self.id is None :
			if DEBUG_MODE : print ( '>> Node::parseToXML id is None' )
		xml_node.setAttribute ( 'id', str( self.id ) )
		xml_node.setAttribute ( 'name', self.name )
		if self.label != None : xml_node.setAttribute ( 'label', self.label )
		if self.type != None : xml_node.setAttribute ( 'type', self.type )
		if self.author != None : xml_node.setAttribute ( 'author', self.author )
		if self.icon != None : xml_node.setAttribute ( 'icon', self.icon )
			
		if self.version != None : xml_node.setAttribute ( 'version', self.version )
		if self.parent != None : xml_node.setAttribute ( 'parent', self.parent )
		if self.format != None : xml_node.setAttribute ( 'format', self.format )

		if self.help != None :
			# append node help (short description)
			help_tag = dom.createElement ( 'help' )
			help_text = dom.createTextNode ( self.help )
			help_tag.appendChild ( help_text )
			xml_node.appendChild ( help_tag )

		input_tag = dom.createElement ( 'input' )
		for param in self.inputParams :
			#print '--> parsing param to XML: %s ...' % param.name
			input_tag.appendChild ( param.parseToXML ( dom )  )
		xml_node.appendChild ( input_tag )

		output_tag = dom.createElement ( 'output' )
		for param in self.outputParams :
			#print '--> parsing param to XML: %s ...' % param.name
			output_tag.appendChild ( param.parseToXML ( dom )  )
		xml_node.appendChild ( output_tag )

		internal_tag = dom.createElement ( 'internal' )
		for var in self.internals :
			var_tag = dom.createElement( 'variable' )
			var_tag.setAttribute ( 'name', var )
			internal_tag.appendChild ( var_tag )
		xml_node.appendChild ( internal_tag )

		include_tag = dom.createElement ( 'include' )
		for inc in self.includes :
			inc_tag = dom.createElement( 'file' )
			inc_tag.setAttribute ( 'name', inc )
			include_tag.appendChild ( inc_tag )
		xml_node.appendChild ( include_tag )

		if self.control_code != None :
			control_code_tag = dom.createElement ( 'control_code' )
			control_code_data = dom.createCDATASection ( self.control_code )
			control_code_tag.appendChild ( control_code_data )
			xml_node.appendChild ( control_code_tag )

		if self.code != None :
			code_tag = dom.createElement ( 'code' )
			code_data = dom.createCDATASection ( self.code )
			code_tag.appendChild ( code_data )
			xml_node.appendChild ( code_tag )
			
		if self.event_code :
			event_code_tag = dom.createElement ( 'event_code' )
			print ( '*** write event_code' )
			for key in self.event_code.keys () :
				print ( '*** write handler "%s"' % key )
				handler_tag = dom.createElement( 'handler' )
				handler_tag.setAttribute ( 'name', key )
				event_code_tag.appendChild ( handler_tag )
				handler_data = dom.createCDATASection ( self.event_code [ key ] )
				handler_tag.appendChild ( handler_data )
			xml_node.appendChild ( event_code_tag )

		if self.offset != None :
			( x, y ) = self.offset
			offset_tag = dom.createElement ( 'offset' )
			offset_tag.setAttribute ( 'x', str (x) ) # have to use 'str' because PySide throws 
			offset_tag.setAttribute ( 'y', str (y) ) # Overflow error for negative values here
			xml_node.appendChild ( offset_tag )

		return xml_node
	#
	# getHeader
	#
	def getHeader ( self ) : assert 0, 'getHeader needs to be implemented!'

	#
	# getComputedCode
	#
	def getComputedCode ( self, CodeOnly = False ) : assert 0, 'getComputedCode needs to be implemented!'

	#
	# computeNode
	#
	def computeNode ( self, CodeOnly = False ) : assert 0, 'computeNode needs to be implemented!'
	#
	# collectComputed
	#
	def collectComputed ( self, computedCode, visitedNodes, CodeOnly = False ) :
		#
		print ( '>>> Node.collectComputed (empty)' )
	#
	# parseGlobalVars
	#
	def parseGlobalVars ( self, parsedStr ) :
		#
		print ( '>>> Node.parseGlobalVars (empty)' )
	#
	# execControlCode
	#
	def execControlCode ( self ) :
		#
		if self.control_code != None :
			control_code = self.control_code.lstrip ()
			if control_code != '' :
				exec control_code
	#
	# copySetup
	#
	def copySetup ( self, newNode ) :
		#
		if DEBUG_MODE : print ( '>> Node( %s ).copySetup ' % self.label )

		newNode.id = self.id

		name = self.name
		if name is None : name = str ( self.type )

		newNode.name = name

		label = self.label
		if label is None : label = name

		newNode.label  = label
		newNode.type   = self.type
		newNode.author = self.author
		newNode.help   = self.help
		newNode.icon   = self.icon
		newNode.master = self.master
		newNode.display = self.display
		
		newNode.format = self.format
		newNode.parent = self.parent
		newNode.dirty = self.dirty

		newNode.offset = self.offset

		import copy
		newNode.code         = copy.copy ( self.code )
		newNode.control_code = copy.copy ( self.control_code )
		newNode.event_code   = copy.copy ( self.event_code )
		#self.computed_code = None

		newNode.internals = copy.copy ( self.internals )
		newNode.includes  = copy.copy ( self.includes )

		newNode.inputLinks = {}
		newNode.outputLinks = {}

		#newNode.childs = set ()
		print ( '***newNode.childs: ', newNode.childs )
		#newNode.childs = copy.copy ( self.childs )

		newNode.inputParams = []
		for param in self.inputParams : newNode.inputParams.append ( param.copy () )

		newNode.outputParams = []
		for param in self.outputParams : newNode.outputParams.append ( param.copy () )

		return newNode
	#
	# save Node to .xml document
	#
	def save ( self ) :
		#
		result = False
	
		dom = QtXml.QDomDocument ( self.name )
		xml_code = self.parseToXML ( dom )
		dom.appendChild ( xml_code )
		
		file = QFile ( self.master )
		if file.open ( QtCore.QIODevice.WriteOnly ) :
			if file.write ( dom.toByteArray () ) != -1 :
				result = True
		file.close()
		return result
	#
	# getChildrenSet
	#
	def getChildrenSet ( self, children_set = set () ) :
		#
		for node in self.childs :
			children_set = node.getChildrenSet ( children_set )
			children_set.add ( node )
		return children_set  
	#
	# getChildrenList
	#
	def getChildrenList ( self, children_list = [] ) :
		#
		for node in self.childs :
			children_list = node.getChildrenList ( children_list )
			if node not in children_list :
				children_list.append ( node )
			
		return children_list  
示例#21
0
class NodeList ( QtModule.QWidget ) :
	#
	# __init__
	#
	def __init__ ( self, parent ) :
		#
		QtModule.QWidget.__init__ ( self, parent )
		#
		# Define signals for PyQt5
		#
		if usePySide or usePyQt5 :
			#
			self.setActiveNodeList = Signal ()
			self.addNode = Signal ()
			#
		self.nodesLib = ''
		self.nodesDir = ''
		# This is always the same
		self.ui = Ui_nodeList () 
		self.ui.setupUi ( self )
		self.ui.treeView.setDragEnabled ( True )
		#self.ui.treeView.setRootIsDecorated( True )
		self.connectSignals ()
		self.updateGui ()
	#
	# connectSignals
	#
	def connectSignals ( self ) :
		#
		if  usePyQt4 :
			QtCore.QObject.connect ( self.ui.treeView, QtCore.SIGNAL ( "pressed(QModelIndex)" ), self.clicked )
			QtCore.QObject.connect ( self.ui.treeView, QtCore.SIGNAL ( "doubleClicked(QModelIndex)" ), self.doubleClicked )
		else :
			self.ui.treeView.pressed.connect ( self.clicked )
			self.ui.treeView.doubleClicked.connect ( self.doubleClicked )
	#
	# updateGui
	#
	def updateGui ( self ) :
		#
		if self.nodesLib != '' :
			# self.ui.treeView.setupModel( self.nodesLib.model )
			
			self.ui.treeView.reset ()
			self.ui.treeView.setModel ( self.nodesLib.model ) 
			
			self.ui.infoText.clear ()
			#self.ui.infoText.setText( "<i>Node:</i><br /><i>Author:</i><br />" )
	#
	# setLibrary
	#
	def setLibrary ( self, dirName ) :
		#
		self.nodesDir = dirName
		self.nodesLib = NodeLibrary ( dirName )
		self.updateGui()
	#
	# reloadLibrary
	#
	def reloadLibrary ( self ) :
		#
		print '>> NodeList: reloadLibrary' 
		self.nodesLib = NodeLibrary ( self.nodesDir )
		self.updateGui ()
	#
	# clicked
	#
	def clicked ( self, index ) :
		#
		print ">> NodeList::clicked "
		item = self.nodesLib.model.itemFromIndex ( index ) 
		self.showDescription ( item )
		#
		# send signal to MainWindow to help distinguish which nodeList
		# is active for addNode getNode events
		#
		print ">> NodeList::emit setActiveNodeList"
		if  usePyQt4 :
			self.emit ( QtCore.SIGNAL ( "setActiveNodeList" ), self )
		else :
			self.setActiveNodeList.emit ( self )
	#      
	# doubleClicked
	#
	def doubleClicked ( self, index ) :
		#
		print ">> NodeList::doubleClicked "
		item = self.nodesLib.model.itemFromIndex ( index )
		nodeKind = item.whatsThis ()
		
		if nodeKind != 'folder' :
			if  usePyQt4 :
				nodeFilename = item.data ( QtCore.Qt.UserRole + 4 ).toString ()
			else :
				nodeFilename = item.data ( QtCore.Qt.UserRole + 4 )
			
			print ">> NodeList::emit addNode"
			if  usePyQt4 :
				self.emit ( QtCore.SIGNAL ( 'addNode' ), nodeFilename )
			else :
				self.addNode.emit ( nodeFilename )
	#    
	# showDescription
	#
	def showDescription ( self, item ) :
		#
		print ">> NodeList::showDescription "
		import os
		
		nodeName     = item.text ()
		nodeKind     = item.whatsThis ()
		if  usePyQt4 :
			nodeAuthor   = item.data ( QtCore.Qt.UserRole + 1 ).toString ()
			nodeType     = item.data ( QtCore.Qt.UserRole + 2 ).toString ()
			nodeHelp     = item.data ( QtCore.Qt.UserRole + 3 ).toString ()
			nodeFilename = item.data ( QtCore.Qt.UserRole + 4 ).toString ()
			nodeIcon     = item.data ( QtCore.Qt.UserRole + 5 ).toString ()
		else :
			nodeAuthor   = item.data ( QtCore.Qt.UserRole + 1 )
			nodeType     = item.data ( QtCore.Qt.UserRole + 2 )
			nodeHelp     = item.data ( QtCore.Qt.UserRole + 3 )
			nodeFilename = item.data ( QtCore.Qt.UserRole + 4 )
			nodeIcon     = item.data ( QtCore.Qt.UserRole + 5 )
		
		self.ui.infoText.clear ()
		
		description = ''
		
		if nodeKind != 'folder' :
			if nodeIcon != '' :
				iconFileName = os.path.join ( os.path.dirname ( str ( nodeFilename ) ), str ( nodeIcon ) ) 
				print str ( iconFileName )
				description += '<img src="' + iconFileName + '" />'  # width="128" height="128"

			description += "<table>"
			#description += "<tr>"
			#description += "<td align=right>name:</td>"
			#description += "<td><b>" + nodeName + "</b></td>"
			#description += "</tr>"
			#description += "<tr>"
			#description += "<td align=right>type:</td>"
			#description += "<td><b>" + nodeType +"</b></td>"
			#description += "</tr>"
			#description += "<tr>"
			#description += "<td align=right>filename:</td>"
			#description += "<td>" + nodeFilename +"</td>"
			#description += "</tr>"
			description += "<tr>"
			description += "<td align=left>author:</td>"
			description += "<td><i>" + nodeAuthor +"</i></td>"
			description += "</tr>"
			description += "</table><br />"
			
			description += "<br />" + nodeHelp +"</b><br />"
			
			self.ui.infoText.setText ( description )