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)
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))
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 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 )
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 )
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 () )
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()
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
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())
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)
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 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 ()
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))
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
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
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)
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
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
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 )