def _initialPath(self): scriptWindow = self.browser().ancestor(GafferUI.ScriptWindow) scriptNode = scriptWindow.scriptNode() return Gaffer.GraphComponentPath( scriptNode, "/", filter=Gaffer.CompoundPathFilter( filters=[ Gaffer.FileNamePathFilter([re.compile("^[^__].*")], leafOnly=False, userData={ "UI": { "label": "Show hidden", "invertEnabled": True, } }), Gaffer.InfoPathFilter( infoKey="name", matcher=None, # the ui will fill this in leafOnly=False, ), ], ), )
def testModelNoSignallingForUnchangedPaths(self): # Make a widget showing a small hierarchy. root = Gaffer.GraphComponent() root["c"] = Gaffer.GraphComponent() root["c"]["d"] = Gaffer.GraphComponent() widget = GafferUI.PathListingWidget( path=Gaffer.GraphComponentPath(root, "/"), columns=[GafferUI.PathListingWidget.defaultNameColumn], ) _GafferUI._pathListingWidgetAttachTester( GafferUI._qtAddress(widget._qtWidget())) self.__expandModel(widget._qtWidget().model(), queryData=True) # Fake a change to the path. Since nothing has truly changed, # the model should not signal any changes. changes = [] def changed(*args): changes.append(args) widget._qtWidget().model().layoutChanged.connect( functools.partial(changed)) widget._qtWidget().model().dataChanged.connect( functools.partial(changed)) self.__emitPathChanged(widget) self.assertEqual(changes, [])
def testProperties(self): r = Gaffer.GraphComponent() r["d"] = Gaffer.GraphComponent() p = Gaffer.GraphComponentPath(r, "/d") self.assertEqual(p.propertyNames(), ["name", "fullName", "graphComponent:graphComponent"]) self.assertEqual(p.property("name"), "d") self.assertEqual(p.property("fullName"), "/d") self.assertEqual(p.property("graphComponent:graphComponent"), r["d"]) p = Gaffer.GraphComponentPath(r, "/") self.assertEqual(p.propertyNames(), ["name", "fullName", "graphComponent:graphComponent"]) self.assertEqual(p.property("name"), "") self.assertEqual(p.property("fullName"), "/") self.assertEqual(p.property("graphComponent:graphComponent"), r)
def testChildrenInheritFilter(self): r = Gaffer.GraphComponent() r["d"] = Gaffer.GraphComponent() r["d"]["e"] = Gaffer.GraphComponent() p = Gaffer.GraphComponentPath(r, "/d", filter=Gaffer.PathFilter()) child = p.children()[0] self.assertTrue(isinstance(child.getFilter(), Gaffer.PathFilter))
def testRelative( self ) : r = Gaffer.GraphComponent() r["d"] = Gaffer.GraphComponent() r["d"]["e"] = Gaffer.GraphComponent() p = Gaffer.GraphComponentPath( r, "d" ) self.assertEqual( str( p ), "d" ) self.assertEqual( p.root(), "" ) self.assertEqual( [ str( c ) for c in p.children() ], [ "d/e" ] ) p2 = p.copy() self.assertEqual( str( p2 ), "d" ) self.assertEqual( p2.root(), "" ) self.assertEqual( [ str( c ) for c in p2.children() ], [ "d/e" ] )
def __editablePlugAdded(self, standardSet, curvePlug): curves = curvePlug.children() if not curves: return connected = curves[0].outputs() if not connected: return previousSelection = self.__curveList.getSelectedPaths() newPath = Gaffer.GraphComponentPath( self.__scriptNode, connected[0].relativeName(self.__scriptNode).replace('.', '/')) previousSelection.append(newPath) self.__curveList.setSelectedPaths(previousSelection)
def _updateFromSet(self): GafferUI.NodeSetEditor._updateFromSet(self) nodeSet = self.getNodeSet() if len(nodeSet) == 0: pathRoot = self.scriptNode() else: pathRoot = nodeSet[0].parent() for node in nodeSet[1:]: if not pathRoot.isAncestorOf(node): pathRoot = pathRoot.commonAncestor(node) self.__curveList.setPath( Gaffer.GraphComponentPath(pathRoot, "/", filter=_AnimationPathFilter(nodeSet))) # Trigger sychronization onto self.__animationGadget self.__expansionChanged(self.__curveList)
def _updateFromSet(self): GafferUI.NodeSetEditor._updateFromSet(self) nodeSet = self.getNodeSet() if len(nodeSet) == 0: pathRoot = self.scriptNode() else: pathRoot = nodeSet[0].parent() for node in nodeSet[1:]: if not pathRoot.isAncestorOf(node): pathRoot = pathRoot.commonAncestor(node) self.__curveList.setPath( Gaffer.GraphComponentPath(pathRoot, "/", filter=_AnimationPathFilter(nodeSet))) self.__pathChangedConnection = self.__curveList.getPath( ).pathChangedSignal().connect(Gaffer.WeakMethod( self.__updateGadgetSets), scoped=True) self.__updateGadgetSets()
def __init__(self, scriptNode, **kw): self.__main = GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Horizontal, borderWidth=5, spacing=5) self.__scriptNode = scriptNode GafferUI.NodeSetEditor.__init__(self, self.__main, self.__scriptNode, **kw) # Set up widget for curve names on the left self.__animationFilter = _AnimationPathFilter(scriptNode) self.__curveList = GafferUI.PathListingWidget( Gaffer.GraphComponentPath(scriptNode, '/', filter=self.__animationFilter), columns=(GafferUI.PathListingWidget.defaultNameColumn, ), displayMode=GafferUI.PathListingWidget.DisplayMode.Tree, allowMultipleSelection=True) self.__curveList._qtWidget().setMinimumSize(160, 0) self.__curveList._qtWidget().setSizePolicy( QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Ignored) self.__expansionChangedConnection = self.__curveList.expansionChangedSignal( ).connect(Gaffer.WeakMethod(self.__expansionChanged)) self.__selectionChangedConnection = self.__curveList.selectionChangedSignal( ).connect(Gaffer.WeakMethod(self.__selectionChanged)) # Set up the widget responsible for actual curve drawing self.__animationGadget = GafferUI.AnimationGadget() # Set up signals needed to update selection state in PathListingWidget editable = self.__animationGadget.editablePlugs() self.__editablePlugAddedConnection = editable.memberAddedSignal( ).connect(Gaffer.WeakMethod(self.__editablePlugAdded)) self.__gadgetWidget = GafferUI.GadgetWidget(bufferOptions=set([ GafferUI.GLWidget.BufferOptions.Depth, GafferUI.GLWidget.BufferOptions.Double, ]), ) self.__gadgetWidget.getViewportGadget().setPrimaryChild( self.__animationGadget) self.__gadgetWidget.getViewportGadget().setVariableAspectZoom(True) # Assemble UI self.__splitter = GafferUI.SplitContainer( orientation=GafferUI.SplitContainer.Orientation.Horizontal) self.__main.addChild(self.__splitter) self.__splitter.append(self.__curveList) self.__splitter.append(self.__gadgetWidget) # Initial allocation of screen space: # If there's enough space for the list to get 160 pixels give the rest to the AnimationGadget. # If that's not the case, divide the space 50/50 # \todo: do we want to preserve that ratio when maximizing the window as being done currently? self.__splitter.setSizes((1, 1)) currentSizes = self.__splitter.getSizes() if currentSizes[0] > 160: total = sum(currentSizes) betterSize = [float(x) / total for x in [160, total - 160]] self.__splitter.setSizes(betterSize) # set initial state self.__visiblePlugs = None self.__editablePlugs = None self._updateFromSet() self._updateFromContext(["frame"]) self.__curveList._qtWidget().adjustSize() # \todo: is this a reasonable initial framing? bound = imath.Box3f(imath.V3f(-1, -1, 0), imath.V3f(10, 10, 0)) self.__gadgetWidget.getViewportGadget().frame(bound)
def testModelPathSwap(self): # Make a model for a small hierarchy, and expand the # model fully. root1 = Gaffer.GraphComponent() root1["c"] = Gaffer.GraphComponent() root1["c"]["d"] = Gaffer.GraphComponent() widget = GafferUI.PathListingWidget( path=Gaffer.GraphComponentPath(root1, "/"), columns=[GafferUI.PathListingWidget.defaultNameColumn], displayMode=GafferUI.PathListingWidget.DisplayMode.Tree, ) _GafferUI._pathListingWidgetAttachTester( GafferUI._qtAddress(widget._qtWidget())) path = Gaffer.GraphComponentPath(root1, "/") self.assertEqual(path.property("graphComponent:graphComponent"), root1) path.append("c") self.assertEqual(path.property("graphComponent:graphComponent"), root1["c"]) path.append("d") self.assertEqual(path.property("graphComponent:graphComponent"), root1["c"]["d"]) model = widget._qtWidget().model() self.__expandModel(model) # Get an index for `/c/d` and check that we can retrieve # the right path for it. def assertIndexRefersTo(index, graphComponent): if isinstance(index, QtCore.QPersistentModelIndex): index = QtCore.QModelIndex(index) path = widget._PathListingWidget__pathForIndex(index) self.assertEqual(path.property("graphComponent:graphComponent"), graphComponent) dIndex = model.index(0, 0, model.index(0, 0)) assertIndexRefersTo(dIndex, root1["c"]["d"]) persistentDIndex = QtCore.QPersistentModelIndex(dIndex) assertIndexRefersTo(persistentDIndex, root1["c"]["d"]) # Replace the path with another one referencing an identical hierarchy. root2 = Gaffer.GraphComponent() root2["c"] = Gaffer.GraphComponent() root2["c"]["d"] = Gaffer.GraphComponent() widget.setPath(Gaffer.GraphComponentPath(root2, "/")) _GafferUI._pathModelWaitForPendingUpdates(GafferUI._qtAddress(model)) # Check that the model now references the new path and the # new hierarchy. dIndex = model.index(0, 0, model.index(0, 0)) assertIndexRefersTo(dIndex, root2["c"]["d"]) assertIndexRefersTo(persistentDIndex, root2["c"]["d"])
def testModelSorting(self): # Make a widget with sorting enabled. root = Gaffer.GraphComponent() root["c"] = Gaffer.GraphComponent() root["b"] = Gaffer.GraphComponent() path = Gaffer.GraphComponentPath(root, "/") widget = GafferUI.PathListingWidget( path, columns=[GafferUI.PathListingWidget.defaultNameColumn], sortable=True) _GafferUI._pathListingWidgetAttachTester( GafferUI._qtAddress(widget._qtWidget())) model = widget._qtWidget().model() self.__expandModel(model) self.assertEqual(model.rowCount(), 2) self.assertEqual(model.columnCount(), 1) # Check that the paths appear in sorted order. self.assertEqual(model.data(model.index(0, 0)), "b") self.assertEqual(model.data(model.index(1, 0)), "c") bIndex = QtCore.QPersistentModelIndex(model.index(0, 0)) cIndex = QtCore.QPersistentModelIndex(model.index(1, 0)) # And sorting is maintained when adding another path. root["a"] = Gaffer.GraphComponent() self.__emitPathChanged(widget) self.assertEqual(model.rowCount(), 3) self.assertEqual(model.columnCount(), 1) self.assertEqual(model.data(model.index(0, 0)), "a") self.assertEqual(model.data(model.index(1, 0)), "b") self.assertEqual(model.data(model.index(2, 0)), "c") self.assertTrue(bIndex.isValid()) self.assertTrue(cIndex.isValid()) self.assertEqual(model.data(bIndex), "b") self.assertEqual(model.data(cIndex), "c") # Turning sorting off should revert to the order in # the path itself. aIndex = QtCore.QPersistentModelIndex(model.index(0, 0)) widget.setSortable(False) _GafferUI._pathModelWaitForPendingUpdates(GafferUI._qtAddress(model)) self.assertEqual(model.rowCount(), 3) self.assertEqual(model.columnCount(), 1) self.assertTrue(aIndex.isValid()) self.assertTrue(bIndex.isValid()) self.assertTrue(cIndex.isValid()) self.assertEqual(model.data(aIndex), "a") self.assertEqual(model.data(bIndex), "b") self.assertEqual(model.data(cIndex), "c") self.assertEqual(model.data(model.index(0, 0)), "c") self.assertEqual(model.data(model.index(1, 0)), "b") self.assertEqual(model.data(model.index(2, 0)), "a")
def testModel(self): root = Gaffer.GraphComponent() root["a"] = Gaffer.GraphComponent() path = Gaffer.GraphComponentPath(root, "/") widget = GafferUI.PathListingWidget( path, columns=[GafferUI.PathListingWidget.defaultNameColumn], sortable=False, displayMode=GafferUI.PathListingWidget.DisplayMode.Tree, ) _GafferUI._pathListingWidgetAttachTester( GafferUI._qtAddress(widget._qtWidget())) model = widget._qtWidget().model() self.__expandModel(model) self.assertEqual(model.rowCount(), 1) self.assertEqual(model.columnCount(), 1) # If we add a new child to the path, it should appear in the # model. And if we have a persistent index for the original child, that # should remain valid. aIndex = QtCore.QPersistentModelIndex(model.index(0, 0)) root["b"] = Gaffer.GraphComponent() self.__emitPathChanged(widget) self.assertEqual(model.rowCount(), 2) self.assertEqual(model.columnCount(), 1) self.assertTrue(aIndex.isValid()) self.assertEqual(aIndex.row(), 0) # If we delete `a`, it should be gone from the model, but a # persistent index to `b` should remain valid. bIndex = QtCore.QPersistentModelIndex(model.index(1, 0)) del root["a"] self.__emitPathChanged(widget) self.assertEqual(model.rowCount(), 1) self.assertEqual(model.columnCount(), 1) self.assertFalse(aIndex.isValid()) self.assertTrue(bIndex.isValid()) self.assertEqual(model.rowCount(bIndex), 0) # If we add a child to `b`, the model should update to reflect # that too. root["b"]["c"] = Gaffer.GraphComponent() self.__emitPathChanged(widget) self.assertTrue(bIndex.isValid()) self.assertEqual(model.rowCount(bIndex), 1) self.assertEqual(model.columnCount(bIndex), 1) self.assertEqual(model.data(model.index(0, 0, bIndex)), "c") # We should be able to add and remove children from `c` # and see it reflected in the model. cIndex = QtCore.QPersistentModelIndex(model.index(0, 0, bIndex)) self.assertEqual(model.data(cIndex), "c") self.assertEqual(model.rowCount(cIndex), 0) root["b"]["c"]["d"] = Gaffer.GraphComponent() self.__emitPathChanged(widget) self.assertTrue(cIndex.isValid()) self.assertEqual(model.rowCount(cIndex), 1) self.assertEqual(model.columnCount(cIndex), 1) self.assertEqual(model.data(model.index(0, 0, cIndex)), "d") dIndex = QtCore.QPersistentModelIndex(model.index(0, 0, cIndex)) del root["b"]["c"]["d"] self.__emitPathChanged(widget) self.assertTrue(cIndex.isValid()) self.assertEqual(model.rowCount(cIndex), 0) self.assertFalse(dIndex.isValid())