def _updateFromSet( self ) : GafferUI.NodeSetEditor._updateFromSet( self ) del self.__column[:] self.__nodeUI = None self.__nameWidget = None node = self._lastAddedNode() if not node : return with self.__column : with GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Horizontal, borderWidth=8, spacing=4 ) : GafferUI.Label( "<h4>Node Name</h4>" ) self.__nameWidget = GafferUI.NameWidget( node ) ## \todo Make NameWidget support the readOnly metadata internally itself. # We can't do that easily right now, because it would need to be managing # the exact same `setEditable()` call that we're using here to propagate # our Widget readonlyness. Really our Widget readonlyness mechanism is a # bit lacking, and it should really be inherited automatically so we don't # have to propagate it like this. self.__nameWidget.setEditable( not self.getReadOnly() and not Gaffer.readOnly( node ) ) with GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Horizontal, spacing=4 ) as infoSection : GafferUI.Label( "<h4>" + node.typeName().rpartition( ":" )[-1] + "</h4>" ) button = GafferUI.Button( image = "info.png", hasFrame = False ) url = Gaffer.Metadata.value( node, "documentation:url" ) if url : button.clickedSignal().connect( lambda button : GafferUI.showURL( url ), scoped = False ) toolTip = "<h3>" + node.typeName().rpartition( ":" )[2] + "</h3>" description = Gaffer.Metadata.nodeDescription( node ) if description : toolTip += "\n\n" + description infoSection.setToolTip( toolTip ) GafferUI.MenuButton( image = "gear.png", hasFrame = False, menu = GafferUI.Menu( Gaffer.WeakMethod( self.__menuDefinition ) ) ) frame = GafferUI.Frame( borderStyle=GafferUI.Frame.BorderStyle.None, borderWidth=0 ) self.__column.append( frame, expand=True ) self.__nodeUI = GafferUI.NodeUI.create( node ) self.__nodeUI.setReadOnly( self.getReadOnly() ) frame.setChild( self.__nodeUI )
def __init__(self, plugOrPlugs, **kw): self.__row = GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Horizontal, spacing=4) GafferUI.PlugValueWidget.__init__(self, self.__row, plugOrPlugs) plugs = self.getPlugs() # If all cells have enabled plugs, we need to add a switch for them. # If cells adopt the enabled plug from their value plug, we rely on the # PlugValueWidget drawing the switch for us. # However, in cases where the widget for the value plug doesn't support # multiple plugs, we don't show a value, and so need to add our own # switch so people can at least edit enabled state the cells. cellEnabledPlugs = {p["enabled"] for p in plugs if "enabled" in p} valuePlugs = {p["value"] for p in plugs} addCellEnabledSwitch = len(cellEnabledPlugs) == len(valuePlugs) if self.canEdit(plugs): plugValueWidget = self.__createValueWidget(valuePlugs) if plugValueWidget is not None: # Apply some fixed widths for some widgets, otherwise they're # a bit too eager to grow. \todo Should we change the underlying # behaviour of the widgets themselves? self.__applyFixedWidths(plugValueWidget) self.__row.append(plugValueWidget) else: self.__row.append( GafferUI.Label( "Unable to edit multiple plugs of this type")) addCellEnabledSwitch = True else: self.__row.append( GafferUI.Label("Unable to edit plugs with mixed types")) addCellEnabledSwitch = True if addCellEnabledSwitch: self.__enabledPlugValueWidget = GafferUI.BoolPlugValueWidget( [p.enabledPlug() for p in plugs], displayMode=GafferUI.BoolWidget.DisplayMode.Switch) self.__enabledPlugValueWidget.setEnabled( _Algo.cellsCanBeDisabled(plugs)) self.__row.insert(0, self.__enabledPlugValueWidget, verticalAlignment=GafferUI.VerticalAlignment.Top) else: self.__enabledPlugValueWidget = None self._updateFromPlugs()
def __init__(self, plug, **kw): frame = GafferUI.Frame(borderWidth=4) GafferUI.PlugValueWidget.__init__(self, frame, plug, **kw) # Style selector specificity rules seem to preclude us styling this # based on gafferClass. frame._qtWidget().setObjectName("gafferColorInspector") with frame: with GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Horizontal, spacing=4): GafferUI.Spacer(imath.V2i(0, 10)) self.__positionLabel = GafferUI.Label() self.__positionLabel._qtWidget().setFixedWidth(90) self.__swatch = GafferUI.ColorSwatch() self.__swatch._qtWidget().setFixedWidth(12) self.__swatch._qtWidget().setFixedHeight(12) self.__busyWidget = GafferUI.BusyWidget(size=12) self.__rgbLabel = GafferUI.Label() GafferUI.Spacer(imath.V2i(20, 10), imath.V2i(20, 10)) self.__hsvLabel = GafferUI.Label() GafferUI.Spacer(imath.V2i(0, 10)) self.__pixel = imath.V2f(0) viewportGadget = plug.parent().viewportGadget() viewportGadget.mouseMoveSignal().connect(Gaffer.WeakMethod( self.__mouseMove), scoped=False) imageGadget = viewportGadget.getPrimaryChild() imageGadget.buttonPressSignal().connect(Gaffer.WeakMethod( self.__buttonPress), scoped=False) imageGadget.dragBeginSignal().connect(Gaffer.WeakMethod( self.__dragBegin), scoped=False) imageGadget.dragEndSignal().connect(Gaffer.WeakMethod(self.__dragEnd), scoped=False) self.__updateLabels(imath.V2i(0), imath.Color4f(0, 0, 0, 1))
def __init__(self, plug, **kw): grid = GafferUI.GridContainer(spacing=4) GafferUI.PlugValueWidget.__init__(self, grid, plug, **kw) self.__menuButton = GafferUI.MenuButton( menu=GafferUI.Menu(Gaffer.WeakMethod(self.__menuDefinition))) grid[0:2, 0] = self.__menuButton self.__minLabel = GafferUI.Label("Min") grid.addChild(self.__minLabel, index=(0, 1), alignment=(GafferUI.HorizontalAlignment.Right, GafferUI.VerticalAlignment.Center)) self.__minWidget = GafferUI.CompoundNumericPlugValueWidget( plug["displayWindow"]["min"]) grid[1, 1] = self.__minWidget self.__maxLabel = GafferUI.Label("Max") grid.addChild(self.__maxLabel, index=(0, 2), alignment=(GafferUI.HorizontalAlignment.Right, GafferUI.VerticalAlignment.Center)) self.__maxWidget = GafferUI.CompoundNumericPlugValueWidget( plug["displayWindow"]["max"]) grid[1, 2] = self.__maxWidget self.__pixelAspectLabel = GafferUI.Label("Pixel Aspect") grid.addChild(self.__pixelAspectLabel, index=(0, 3), alignment=(GafferUI.HorizontalAlignment.Right, GafferUI.VerticalAlignment.Center)) self.__pixelAspectWidget = GafferUI.NumericPlugValueWidget( plug["pixelAspect"]) grid[1, 3] = self.__pixelAspectWidget self.__plugMetadataChangedConnection = Gaffer.Metadata.plugValueChangedSignal( ).connect(Gaffer.WeakMethod(self.__plugMetadataChanged)) # If the plug hasn't got an input, the PlugValueWidget base class assumes we're not # sensitive to contex changes and omits calls to _updateFromPlug(). But the default # format mechanism uses the context, so we must arrange to do updates ourselves when # necessary. self.__contextChangedConnection = self.getContext().changedSignal( ).connect(Gaffer.WeakMethod(self.__contextChanged)) self._addPopupMenu(self.__menuButton) self._updateFromPlug()
def __init__(self, scriptNode, **kw): self.__column = GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Vertical) GafferUI.NodeSetEditor.__init__(self, self.__column, scriptNode, **kw) with self.__column: with GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Horizontal, borderWidth=8, spacing=4) as self.__header: GafferUI.Label("<h4>Node Name</h4>") self.__nameWidget = GafferUI.NameWidget(None) with GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Horizontal, spacing=4, parenting={ "horizontalAlignment": GafferUI.HorizontalAlignment.Right }, ) as self.__infoSection: self.__typeLabel = GafferUI.Label() infoButton = GafferUI.Button(image="info.png", hasFrame=False) infoButton.clickedSignal().connect(Gaffer.WeakMethod( self.__infoButtonClicked), scoped=False) GafferUI.MenuButton(image="gear.png", hasFrame=False, menu=GafferUI.Menu( Gaffer.WeakMethod( self.__menuDefinition))) self.__nodeUIFrame = GafferUI.Frame( borderStyle=GafferUI.Frame.BorderStyle.None_, borderWidth=0, parenting={"expand": True}) self.__nodeUI = None self.__readOnly = False self._updateFromSet()
def __init__(self, scriptNode, **kw): self.__column = GafferUI.ListContainer(borderWidth=8, spacing=6) GafferUI.EditorWidget.__init__(self, self.__column, scriptNode, **kw) with self.__column: GafferUI.Image("%s/pipeBrowser.png" % pipe.name()) with GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Horizontal, spacing=6): GafferUI.Label("Role") modeMenu = GafferUI.SelectionMenu() for mode in self.__modes: modeMenu.addItem(mode[0]) self.__modeChangedConnection = modeMenu.currentIndexChangedSignal( ).connect(Gaffer.WeakMethod(self.__modeChanged)) self.__pathChooser = GafferUI.PathChooserWidget( Gaffer.DictPath({}, "/"), previewTypes=GafferUI.PathPreviewWidget.types()) self.__pathChooser.pathWidget().setVisible(True) # turns the listmode and path string invisible! self.__pathChooser.directoryPathWidget().parent().setVisible(True) self.__modeInstances = {} self.__currentModeInstance = None self.__modeChanged(modeMenu)
def __init__( self, childPlug ) : column = GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Vertical, spacing=4 ) GafferUI.PlugValueWidget.__init__( self, column, childPlug ) with column : with GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Horizontal, spacing=4 ) as header : collapseButton = GafferUI.Button( image = "collapsibleArrowRight.png", hasFrame=False ) collapseButton.__clickedConnection = collapseButton.clickedSignal().connect( Gaffer.WeakMethod( self.__collapseButtonClicked ) ) GafferUI.PlugValueWidget.create( childPlug["active"] ) self.__label = GafferUI.Label( self.__namePlug().getValue() ) GafferUI.Spacer( imath.V2i( 1 ), maximumSize = imath.V2i( 100000, 1 ), parenting = { "expand" : True } ) self.__deleteButton = GafferUI.Button( image = "delete.png", hasFrame=False ) self.__deleteButton.__clickedConnection = self.__deleteButton.clickedSignal().connect( Gaffer.WeakMethod( self.__deleteButtonClicked ) ) self.__deleteButton.setVisible( False ) with GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Vertical, spacing= 4 ) as self.__detailsColumn : GafferUI.PlugWidget( self.__namePlug() ) GafferUI.PlugWidget( self.__fileNamePlug() ) GafferUI.PlugWidget( childPlug["type"] ) GafferUI.PlugWidget( childPlug["data"] ) GafferUI.CompoundDataPlugValueWidget( childPlug["parameters"] ) GafferUI.Divider( GafferUI.Divider.Orientation.Horizontal ) self.__detailsColumn.setVisible( False ) self.__enterConnection = header.enterSignal().connect( Gaffer.WeakMethod( self.__enter ) ) self.__leaveConnection = header.leaveSignal().connect( Gaffer.WeakMethod( self.__leave ) )
def __init__(self, node, **kw): row = GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Horizontal, spacing=4) GafferUI.Widget.__init__(self, row, **kw) self.__node = node with row: label = GafferUI.Label( "File", horizontalAlignment=GafferUI.Label.HorizontalAlignment.Right) label._qtWidget().setFixedWidth(GafferUI.PlugWidget.labelWidth()) self.__textWidget = GafferUI.TextWidget(node.fileName(), editable=False) loadButton = GafferUI.Button(image="pathChooser.png", hasFrame=False) loadButton.setToolTip("Load") self.__loadButtonClickedConnection = loadButton.clickedSignal( ).connect(Gaffer.WeakMethod(self.__loadClicked)) self.__reloadButton = GafferUI.Button(image="refresh.png", hasFrame=False) self.__reloadButton.setToolTip("Reload") self.__reloadButtonClickedConnection = self.__reloadButton.clickedSignal( ).connect(Gaffer.WeakMethod(self.__reloadClicked)) self.__referenceLoadedConnection = node.referenceLoadedSignal( ).connect(Gaffer.WeakMethod(self.__referenceLoaded))
def __init__(self, title, message, cancelLabel="Cancel", confirmLabel="OK", sizeMode=GafferUI.Window.SizeMode.Automatic, details=None, **kw): GafferUI.Dialogue.__init__(self, title, sizeMode=sizeMode, **kw) with GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Vertical, spacing=8) as column: GafferUI.Label(message) if details is not None: with GafferUI.Collapsible(label="Details", collapsed=True): GafferUI.MultiLineTextWidget( text=details, editable=False, ) self._setWidget(column) self._addButton(cancelLabel) self.__confirmButton = self._addButton(confirmLabel)
def update( self, section ) : widgets = list( section.widgets ) for name, subsection in section.subsections.items() : collapsible = self.__collapsibles.get( name ) if collapsible is None : collapsible = GafferUI.Collapsible( name, _CollapsibleLayout( self.orientation() ), borderWidth = 2, collapsed = True ) collapsible.setCornerWidget( GafferUI.Label(), True ) ## \todo This is fighting the default sizing applied in the Label constructor. Really we need a standard # way of controlling size behaviours for all widgets in the public API. collapsible.getCornerWidget()._qtWidget().setSizePolicy( QtGui.QSizePolicy.Ignored, QtGui.QSizePolicy.Fixed ) if subsection.restoreState( "collapsed" ) is False : collapsible.setCollapsed( False ) collapsible.__stateChangedConnection = collapsible.stateChangedSignal().connect( functools.partial( Gaffer.WeakMethod( self.__collapsibleStateChanged ), subsection = subsection ) ) self.__collapsibles[name] = collapsible collapsible.getChild().update( subsection ) collapsible.getCornerWidget().setText( "<small>" + " ( " + subsection.summary + " )</small>" if subsection.summary else "" ) widgets.append( collapsible ) self.__column[:] = widgets
def __init__(self, title, message, details=None, **kw): GafferUI.Dialogue.__init__(self, title, sizeMode=GafferUI.Window.SizeMode.Manual, **kw) column = GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Vertical, spacing=8) messageWidget = GafferUI.Label(IECore.StringUtil.wrap(message, 60)) messageFrame = GafferUI.Frame(child=messageWidget, borderWidth=8) column.append(messageFrame) if details is not None: detailsWidget = GafferUI.MultiLineTextWidget( text=details, editable=False, ) detailsFrame = GafferUI.Frame(child=detailsWidget, borderWidth=8) column.append( GafferUI.Collapsible(label="Details", collapsed=True, child=detailsFrame)) self._setWidget(column) self.__closeButton = self._addButton("Close")
def __init__(self, **kw): GafferUI.Window.__init__(self, **kw) self.__dispatcher = Gaffer.Dispatcher.dispatcher("Local") self.__nodes = [] with self: with GafferUI.ListContainer( orientation=GafferUI.ListContainer.Orientation.Vertical, spacing=2, borderWidth=4): with GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Horizontal, spacing=4): GafferUI.Label("Dispatcher") dispatchersMenu = GafferUI.MultiSelectionMenu( allowMultipleSelection=False, allowEmptySelection=False) dispatchersMenu.append(Gaffer.Dispatcher.dispatcherNames()) dispatchersMenu.setSelection(["Local"]) self.__dispatchersMenuSelectionChangedConnection = dispatchersMenu.selectionChangedSignal( ).connect(Gaffer.WeakMethod(self.__dispatcherChanged)) self.__frame = GafferUI.Frame( borderStyle=GafferUI.Frame.BorderStyle.None, borderWidth=0) self.__dispatchButton = GafferUI.Button("Dispatch") self.__dispatchClickedConnection = self.__dispatchButton.clickedSignal( ).connect(Gaffer.WeakMethod(self.__dispatchClicked)) self.__update()
def __init__(self, scriptNode, **kw): self.__column = GafferUI.ListContainer(borderWidth=8, spacing=6) GafferUI.EditorWidget.__init__(self, self.__column, scriptNode, **kw) with self.__column: with GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Horizontal, spacing=6): GafferUI.Label("Location") modeMenu = GafferUI.MultiSelectionMenu( allowMultipleSelection=False, allowEmptySelection=False, ) for mode in self.__modes: modeMenu.append(mode[0]) self.__modeChangedConnection = modeMenu.selectionChangedSignal( ).connect(Gaffer.WeakMethod(self.__modeChanged)) self.__pathChooser = GafferUI.PathChooserWidget( Gaffer.DictPath({}, "/"), previewTypes=GafferUI.PathPreviewWidget.types()) self.__pathChooser.pathWidget().setVisible(False) self.__modeInstances = {} self.__currentModeInstance = None modeMenu.setSelection([self.__modes[0][0]])
def __init__(self, plug, **kw): row = GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Horizontal, spacing=4) GafferUI.PlugValueWidget.__init__(self, row, plug, **kw) with row: self.__label = GafferUI.Label("") GafferUI.Spacer(IECore.V2i(1, 30), parenting={"expand": True}) loadButton = GafferUI.Button(image="pathChooser.png", hasFrame=False) loadButton.setToolTip("Load") self.__loadButtonClickedConnection = loadButton.clickedSignal( ).connect(Gaffer.WeakMethod(self.__loadClicked)) self.__reloadButton = GafferUI.Button(image="refresh.png", hasFrame=False) self.__reloadButton.setToolTip("Reload") self.__reloadButtonClickedConnection = self.__reloadButton.clickedSignal( ).connect(Gaffer.WeakMethod(self.__reloadClicked)) self._updateFromPlug()
def __init__( self, **kw ) : GafferUI.Window.__init__( self, **kw ) self.__dispatchers = {} for dispatcherType in GafferDispatch.Dispatcher.registeredDispatchers() : dispatcher = GafferDispatch.Dispatcher.create( dispatcherType ) Gaffer.NodeAlgo.applyUserDefaults( dispatcher ) self.__dispatchers[dispatcherType] = dispatcher defaultType = GafferDispatch.Dispatcher.getDefaultDispatcherType() self.__currentDispatcher = self.__dispatchers[ defaultType ] self.__nodes = [] with self : with GafferUI.ListContainer( orientation = GafferUI.ListContainer.Orientation.Vertical, spacing = 2, borderWidth = 6 ) : with GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Horizontal, spacing = 4 ) : GafferUI.Label( "Dispatcher" ) self.__dispatchersMenu = GafferUI.MultiSelectionMenu( allowMultipleSelection = False, allowEmptySelection = False ) self.__dispatchersMenu.append( self.__dispatchers.keys() ) self.__dispatchersMenu.setSelection( [ defaultType ] ) self.__dispatchersMenu.selectionChangedSignal().connect( Gaffer.WeakMethod( self.__dispatcherChanged ), scoped = False ) self.__frame = GafferUI.Frame( borderStyle=GafferUI.Frame.BorderStyle.None, borderWidth=0 ) self.__dispatchButton = GafferUI.Button( "Dispatch" ) self.__dispatchButton.clickedSignal().connect( Gaffer.WeakMethod( self.__dispatchClicked ), scoped = False ) self.__update( resizeToFit = True )
def testHtmlInText(self): w = GafferUI.Label("<h3>hello</h3>") self.assertEqual(w.getText(), "<h3>hello</h3>") w.setText("<h2>goodbye</h2>") self.assertEqual(w.getText(), "<h2>goodbye</h2>")
def testShortcutDiscoveryOptimisations(self): callCounts = {"MenuA": 0, "MenuB": 0} def buildMenu(identifier): callCounts[identifier] += 1 smd = IECore.MenuDefinition() smd.append("/%s_item" % identifier, {}) return smd definition = IECore.MenuDefinition() definition.append("/MenuA", {"subMenu": functools.partial(buildMenu, "MenuA")}) definition.append( "/MenuB", { "subMenu": functools.partial(buildMenu, "MenuB"), "hasShortCuts": False }) with GafferUI.Window() as window: with GafferUI.ListContainer(): menuBar = GafferUI.MenuBar(definition) label = GafferUI.Label("test") window.setVisible(True) self.waitForIdle(1000) self.__simulateShortcut(label) self.waitForIdle(1000) self.assertEqual(callCounts, {"MenuA": 1, "MenuB": 0})
def __init__( self, parameter ) : self.__parameter = parameter grid = GafferUI.GridContainer( spacing = 2 ) GafferUI.Widget.__init__( self, grid ) self.__inspectors = [] with grid : label = GafferUI.Label( ## \todo Prettify label text (remove snake case) text = "<h5>" + IECore.CamelCase.toSpaced( parameter ) + "</h5>", parenting = { "index" : ( slice( 0, 2 ), 0 ) } ) label._qtWidget().setMaximumWidth( 140 ) self.__editButton = GafferUI.Button( image = "editOff.png", hasFrame = False, parenting = { "index" : ( 0, 1 ), "alignment" : ( GafferUI.HorizontalAlignment.Center, GafferUI.VerticalAlignment.Center ) } ) self.__editButton.clickedSignal().connect( Gaffer.WeakMethod( self.__editButtonClicked ), scoped = False ) self.__valueWidget = _ValueWidget( parenting = { "index" : ( 1, 1 ) } ) self.__valueWidget.buttonReleaseSignal().connect( Gaffer.WeakMethod( self.__valueWidgetClicked ), scoped = False ) self.update( [] )
def __init__(self, parameterHandler): PresetDialogue.__init__(self, "Delete Preset", parameterHandler) with GafferUI.ListContainer(spacing=4) as column: with GafferUI.ListContainer( orientation=GafferUI.ListContainer.Orientation.Horizontal, spacing=4): GafferUI.Label("<h3>Location</h3>", horizontalAlignment=GafferUI.Label. HorizontalAlignment.Right) self._locationMenu(owned=True) presetListing = self._presetListing(allowMultipleSelection=True) self.__selectionChangedConnection = presetListing.selectionChangedSignal( ).connect(Gaffer.WeakMethod(self.__selectionChanged)) self._setWidget(column) self._addButton("Close") self.__deleteButton = self._addButton("Delete") self.__deleteButton.setEnabled(False) self.__deleteButtonPressedConnection = self.__deleteButton.clickedSignal( ).connect(Gaffer.WeakMethod(self.__delete))
def __init__( self, node, **kw ) : column = GafferUI.ListContainer( spacing = 4 ) GafferUI.Widget.__init__( self, column ) self.__node = node with column : with GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Horizontal, spacing = 4 ) : GafferUI.Label( "Language" ) self.__languageMenu = GafferUI.MenuButton( "", menu = GafferUI.Menu( Gaffer.WeakMethod( self.__languageMenuDefinition ) ) ) self.__textWidget = GafferUI.MultiLineTextWidget() self.__activatedConnection = self.__textWidget.activatedSignal().connect( Gaffer.WeakMethod( self.__activated ) ) self.__editingFinishedConnection = self.__textWidget.editingFinishedSignal().connect( Gaffer.WeakMethod( self.__editingFinished ) ) self.__dropTextConnection = self.__textWidget.dropTextSignal().connect( Gaffer.WeakMethod( self.__dropText ) ) self.__messageWidget = GafferUI.MessageWidget() self.__expressionChangedConnection = self.__node.expressionChangedSignal().connect( Gaffer.WeakMethod( self.__expressionChanged ) ) self.__errorConnection = self.__node.errorSignal().connect( Gaffer.WeakMethod( self.__error ) ) self.__update()
def _updateFromSet(self): GafferUI.NodeSetEditor._updateFromSet(self) del self.__column[:] self.__nodeUI = None self.__nameWidget = None node = self._lastAddedNode() if not node: return with self.__column: with GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Horizontal, borderWidth=8, spacing=4): GafferUI.Label("<h4>Node Name</h4>") self.__nameWidget = GafferUI.NameWidget(node) self.__nameWidget.setEditable(not self.getReadOnly()) with GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Horizontal, spacing=4) as infoSection: GafferUI.Label("<h4>" + node.typeName().rpartition(":")[-1] + "</h4>") GafferUI.Image("info.png") toolTip = "<h3>" + node.typeName().rpartition(":")[2] + "</h3>" description = Gaffer.Metadata.nodeDescription(node) if description: toolTip += "\n\n" + description infoSection.setToolTip(toolTip) GafferUI.MenuButton(image="gear.png", hasFrame=False, menu=GafferUI.Menu( Gaffer.WeakMethod( self.__menuDefinition))) frame = GafferUI.Frame(borderStyle=GafferUI.Frame.BorderStyle.None, borderWidth=0) self.__column.append(frame, expand=True) self.__nodeUI = GafferUI.NodeUI.create(node) self.__nodeUI.setReadOnly(self.getReadOnly()) frame.setChild(self.__nodeUI)
def __init__( self, plugs, warning=None, **kw ) : assert( len(plugs) > 0 ) container = GafferUI.ListContainer( spacing = 4 ) GafferUI.Window.__init__( self, "", child = container, borderWidth = 8, sizeMode=GafferUI.Window.SizeMode.Automatic, **kw ) self.visibilityChangedSignal().connect( Gaffer.WeakMethod( self.__visibilityChanged ), scoped = False ) for p in plugs : ## \todo Figure out when/if this is about to happen, and disable # editing beforehand. assert( isinstance( p, plugs[0].__class__ ) ) self._qtWidget().setWindowFlags( QtCore.Qt.Popup ) self._qtWidget().setAttribute( QtCore.Qt.WA_TranslucentBackground ) self._qtWidget().paintEvent = Gaffer.WeakMethod( self.__paintEvent ) with container : # Label to tell folks what they're editing. # TODO: This could do with some of the niceties TransformToolUI applies finding # common ancestors, as well as more general beautifying. script = plugs[0].ancestor( Gaffer.ScriptNode ) labels = { p.relativeName( script ) for p in plugs } label = GafferUI.Label() if len( labels ) == 1 : message = next( iter( labels ) ) toolTip = "" else : editScope = self.__commonEditScope( plugs ) if editScope is not None : message ="{} ({} plugs)".format( editScope.relativeName( script ), len( plugs ) ) else : message ="{} plugs".format( len( plugs ) ) toolTip = "\n".join( "- " + l for l in labels ) label.setText( "<h4>{}</h4>".format( message ) ) label.setToolTip( toolTip ) with GafferUI.ListContainer( spacing = 4, orientation = GafferUI.ListContainer.Orientation.Horizontal ) : # An alert (if required) if warning : warningBadge = GafferUI.Image( "warningSmall.png" ) warningBadge.setToolTip( warning ) # Widget for editing plugs self.__plugValueWidget = GafferUI.PlugValueWidget.create( plugs ) if isinstance( self.__plugValueWidget, GafferSceneUI.TweakPlugValueWidget ) : ## \todo We have this same hack in SpreadsheetUI. Should we instead # do something with metadata when we add the column to the spreadsheet? self.__plugValueWidget.setNameVisible( False ) self.keyPressSignal().connect( Gaffer.WeakMethod( self.__keyPress ), scoped = False )
def __init__( self, title, message, cancelLabel="Cancel", confirmLabel="OK", sizeMode=GafferUI.Window.SizeMode.Automatic, **kw ) : GafferUI.Dialogue.__init__( self, title, sizeMode=sizeMode, **kw ) self._setWidget( GafferUI.Label( message ) ) self._addButton( cancelLabel ) self.__confirmButton = self._addButton( confirmLabel )
def __init__(self, headings, toolTipOverride=""): GafferUI.ListContainer.__init__( self, GafferUI.ListContainer.Orientation.Horizontal, spacing=4) with self: GafferUI.Label("<h4><b>" + headings[0] + "</b></h4>", toolTip=toolTipOverride)._qtWidget().setFixedWidth( GafferUI.PlugWidget.labelWidth()) GafferUI.Spacer(imath.V2i( 25, 2)) # approximate width of a BoolWidget Switch self.addChild( GafferUI.Label("<h4><b>" + headings[1] + "</b></h4>", toolTip=toolTipOverride), expand=True, horizontalAlignment=GafferUI.HorizontalAlignment.Left) GafferUI.Label("<h4><b>" + headings[2] + "</b></h4>", toolTip=toolTipOverride)._qtWidget().setFixedWidth( _variationsPlugValueWidgetWidth())
def __init__( self, messageLevel = IECore.MessageHandler.Level.Info, role = Role.Messages, toolbars = False, follow = False, **kw ) : rows = GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Vertical, spacing=4 ) GafferUI.Widget.__init__( self, rows, **kw ) upperToolbar = None with rows : if toolbars : upperToolbar = GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Horizontal, spacing = 4 ) with upperToolbar : GafferUI.Label( "Show" ) self.__levelWidget = _MessageLevelWidget() self.__levelWidget.messageLevelChangedSignal().connect( Gaffer.WeakMethod( self.__messageLevelChanged ), scoped = False ) GafferUI.Spacer( imath.V2i( 6 ), preferredSize = imath.V2i( 100, 0 ) ) self.__table = _MessageTableView( follow = follow, expandRows = role is MessageWidget.Role.Messages ) if toolbars : with GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Horizontal ) : shortcuts = self.__table.eventNavigationShortcuts() toolTips = { l : "Click to jump to next {} message [{}]".format( l, shortcuts[l] ) for l in _messageLevels } self.__summaryWidget = MessageSummaryWidget( displayLevel = IECore.MessageHandler.Level.Debug, hideUnusedLevels = False, buttonToolTip = toolTips ) self.__summaryWidget.levelButtonClickedSignal().connect( Gaffer.WeakMethod( self.__levelButtonClicked ), scoped = False ) GafferUI.Spacer( imath.V2i( 0 ) ) self.__toEndButton = GafferUI.Button( image = "scrollToBottom.png", hasFrame = False ) self.__toEndButton.setToolTip( "Scroll to bottom and follow new messages [B]" ) self.__toEndButton.buttonPressSignal().connect( Gaffer.WeakMethod( self.__table.scrollToLatest ), scoped = False ) GafferUI.Spacer( imath.V2i( 3 ), imath.V2i( 3 ) ) if toolbars : upperToolbar.addChild( self.__table.searchWidget() ) self.__table.messageLevelChangedSignal().connect( Gaffer.WeakMethod( self.__messageLevelChanged ), scoped = False ) self.__table.messagesChangedSignal().connect( Gaffer.WeakMethod( self.__messagesChanged ), scoped = False ) if follow : # When following, we manage the enabled state of the toEndButton based on the auto-scroll # state of the table view. If we're not, then it should remain active the whole time. self.__isFollowingMessagesChanged( self.__table ) self.__table.isFollowingMessagesChangedSignal().connect( Gaffer.WeakMethod( self.__isFollowingMessagesChanged ), scoped = False ) self.__messageHandler = _MessageHandler( self ) self.setMessageLevel( messageLevel ) self.setMessages( Gaffer.Private.IECorePreview.Messages() )
def __init__( self, plug, **kw ) : column = GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Vertical, spacing = 4 ) GafferUI.PlugValueWidget.__init__( self, column, plug, **kw ) with column : with GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Horizontal, spacing = 4 ) : GafferUI.Label( "Display Mode" ) drawModeWidget = GafferUI.MultiSelectionMenu( allowMultipleSelection = False, allowEmptySelection = False ) drawModeWidget.append( "Ramp" ) drawModeWidget.append( "Curves" ) drawModeWidget.setSelection( "Ramp" ) self.__drawModeChangedConnection = drawModeWidget.selectionChangedSignal().connect( Gaffer.WeakMethod( self.__drawModeChanged ) ) GafferUI.Spacer( imath.V2i( 0 ), parenting = { "expand" : True } ) # TODO: Since we don't have a good way to register metadata on child plugs, we just write the # metadata on this child plug right before constructing a widget for it. There should probably # be some way to do this genericly during initialization Gaffer.Metadata.registerValue( plug['interpolation'], "plugValueWidget:type", "GafferUI.PresetsPlugValueWidget", persistent=False ) for name, value in sorted( Gaffer.SplineDefinitionInterpolation.names.items() ): Gaffer.Metadata.registerValue( plug['interpolation'], "preset:" + name, value, persistent=False ) GafferUI.PlugWidget( GafferUI.PlugValueWidget.create( plug["interpolation"] ) ) self.__splineWidget = GafferUI.SplineWidget() if isinstance( plug, ( Gaffer.SplinefColor3fPlug, Gaffer.SplinefColor4fPlug ) ) : self.__splineWidget.setDrawMode( self.__splineWidget.DrawMode.Ramp ) else: self.__splineWidget.setDrawMode( self.__splineWidget.DrawMode.Splines ) self.__splineWidget._qtWidget().setMinimumHeight( 50 ) self.__slider = GafferUI.Slider() self.__slider.setSizeEditable( True ) self.__slider.setMinimumSize( 2 ) self.__positionsChangedConnection = self.__slider.positionChangedSignal().connect( Gaffer.WeakMethod( self.__positionsChanged ) ) self.__indexRemovedConnection = self.__slider.indexRemovedSignal().connect( Gaffer.WeakMethod( self.__indexRemoved ) ) self.__selectedIndexChangedConnection = self.__slider.selectedIndexChangedSignal().connect( Gaffer.WeakMethod( self.__selectedIndexChanged ) ) self.__lastPositionChangedReason = None self.__positionsMergeGroupId = 0 with GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Horizontal, spacing = 4 ) : self.__positionLabel = GafferUI.LabelPlugValueWidget( plug.pointXPlug( 0 ) ) self.__positionField = GafferUI.NumericPlugValueWidget( plug.pointXPlug( 0 ) ) self.__valueLabel = GafferUI.LabelPlugValueWidget( plug.pointYPlug( 0 ) ) if isinstance( plug.pointYPlug( 0 ), Gaffer.FloatPlug ): self.__valueField = GafferUI.NumericPlugValueWidget( plug.pointYPlug( 0 ) ) else: self.__valueField = GafferUI.ColorPlugValueWidget( plug.pointYPlug( 0 ) ) self.setPlug( plug )
def update( self, targets ) : self.__target = targets[0] self.__connections = [] if self.__target.path is None : return history = [] target = self.__target while target is not None : history.append( self.__HistoryItem( target, self.__inspector( target ) ) ) target = self.__sourceTarget( target ) history.reverse() rows = [] for i in range( 0, len( history ) ) : if i >= 2 and history[i].value == history[i-1].value and history[i].value == history[i-2].value : if i != len( history ) - 1 : # if the last line we output was a gap, and this one would be too, then # just skip it. continue row = Row( borderWidth = 0, alternate = len( rows ) % 2 ) rows.append( row ) with row.listContainer() : if i == 0 : _Rail( _Rail.Type.Top if len( history ) > 1 else _Rail.Type.Single ) elif i == len( history ) - 1 : _Rail( _Rail.Type.Bottom ) else : if history[i-1].value == history[i].value : _Rail( _Rail.Type.Gap ) else : _Rail( _Rail.Type.Middle ) if i == 0 or i == ( len( history ) - 1 ) or history[i-1].value != history[i].value : GafferUI.NameLabel( history[i].target.scene.node(), formatter = lambda l : ".".join( x.getName() for x in l ) ) else : GafferUI.Label( "..." ) GafferUI.Spacer( IECore.V2i( 0 ), parenting = { "expand" : True } ) diff = TextDiff() diff.update( [ history[i-1].value if i > 0 else None, history[i].value ] ) if i == 0 or history[i-1].value != history[i].value : diff.frame( 0 if history[i].value is not None else 1 ).setVisible( False ) self._mainColumn()[:] = rows
def testParentChange(self): commandInvocations = [] def command(arg): commandInvocations.append(arg) definition = IECore.MenuDefinition([ ("/test/command", { "command": functools.partial(command, "test"), "shortCut": "Ctrl+A" }), ]) with GafferUI.Window() as window: with GafferUI.ListContainer(): with GafferUI.ListContainer() as container1: menuBar = GafferUI.MenuBar(definition) label1 = GafferUI.Label("test") with GafferUI.ListContainer() as container2: label2 = GafferUI.Label("test") window.setVisible(True) self.waitForIdle(1000) self.__simulateShortcut(label1) self.waitForIdle(1000) self.assertEqual(len(commandInvocations), 1) self.__simulateShortcut(label2) self.waitForIdle(1000) self.assertEqual(len(commandInvocations), 1) container2.insert(0, menuBar) self.__simulateShortcut(label1) self.waitForIdle(1000) self.assertEqual(len(commandInvocations), 1) self.__simulateShortcut(label2) self.waitForIdle(1000) self.assertEqual(len(commandInvocations), 2)
def testLifespan(self): w = GafferUI.Label("hi") r = weakref.ref(w) w.linkActivatedSignal() self.failUnless(r() is w) del w self.failUnless(r() is None)
def testAlignment(self): l = GafferUI.Label() self.assertEqual(l.getAlignment(), (GafferUI.Label.HorizontalAlignment.Left, GafferUI.Label.VerticalAlignment.Center)) l = GafferUI.Label( horizontalAlignment=GafferUI.Label.HorizontalAlignment.Right, verticalAlignment=GafferUI.Label.VerticalAlignment.Top) self.assertEqual(l.getAlignment(), (GafferUI.Label.HorizontalAlignment.Right, GafferUI.Label.VerticalAlignment.Top)) l.setAlignment(GafferUI.Label.HorizontalAlignment.Center, GafferUI.Label.VerticalAlignment.Center) self.assertEqual(l.getAlignment(), (GafferUI.Label.HorizontalAlignment.Center, GafferUI.Label.VerticalAlignment.Center))