def testCornerWidget( self ) : c = GafferUI.Collapsible( collapsed = True ) self.assertEqual( c.getCornerWidget(), None ) b1 = GafferUI.Button() self.assertEqual( b1.parent(), None ) b2 = GafferUI.Button() self.assertEqual( b1.parent(), None ) c.setCornerWidget( b1 ) self.assertTrue( c.getCornerWidget() is b1 ) self.assertTrue( b1.parent() is c ) c.setCornerWidget( None ) self.assertIsNone( c.getCornerWidget() ) self.assertIsNone( b1.parent() ) c.setCornerWidget( b1 ) self.assertTrue( c.getCornerWidget() is b1 ) self.assertTrue( b1.parent() is c ) c.setCornerWidget( b2 ) self.assertTrue( c.getCornerWidget() is b2 ) self.assertTrue( b2.parent() is c ) self.assertIsNone( b1.parent() ) c.removeChild( b2 ) self.assertIsNone( c.getCornerWidget() ) self.assertIsNone( b2.parent() )
def __init__(self, plug, collapsed=True, label=None, summary=None, **kw): self.__column = GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Vertical, spacing=4) self.__label = label if label else IECore.CamelCase.toSpaced( plug.getName()) self.__collapsible = None if collapsed is not None: self.__collapsible = GafferUI.Collapsible( self.__label, collapsed=self.__getStoredCollapseState(plug, collapsed), ) self.__collapsible.setChild(self.__column) self.__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. self.__collapsible.getCornerWidget()._qtWidget().setSizePolicy( QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed) self.__collapseStateChangedConnection = self.__collapsible.stateChangedSignal( ).connect(Gaffer.WeakMethod(self.__collapseStateChanged)) GafferUI.PlugValueWidget.__init__( self, self.__collapsible if self.__collapsible is not None else self.__column, plug, **kw) self.__plugAddedConnection = plug.childAddedSignal().connect( Gaffer.WeakMethod(self.__childAddedOrRemoved)) self.__plugRemovedConnection = plug.childRemovedSignal().connect( Gaffer.WeakMethod(self.__childAddedOrRemoved)) self.__childrenChangedPending = False # arrange to build the rest of the ui in a deferred fashion. this means that we will be # fully constructed when we call _childPlugWidget etc, rather than expecting derived # class' implementations to work even before their constructor has completed. # it also means we don't pay the cost of building huge uis upfront, and rather do it incrementally # as the user opens up sections. for non-collapsed uis, we build when a parent is received, which # allows the top level window to get the sizing right, and for collapsed uis we build when the # the ui first becomes visible due to being opened. if collapsed == True: self.__visibilityChangedConnection = self.__column.visibilityChangedSignal( ).connect(Gaffer.WeakMethod(self.__visibilityChanged)) else: self.__parentChangedConnection = self.parentChangedSignal( ).connect(Gaffer.WeakMethod(self.__parentChanged)) self.__visibilityChangedConnection = self.__column.visibilityChangedSignal( ).connect(Gaffer.WeakMethod(self.__visibilityChanged)) self.__childPlugUIs = {} # mapping from child plug name to PlugWidget self.__summary = summary CompoundPlugValueWidget._updateFromPlug(self)
def __init__(self, title, message=None, details=None, messages=None, closeLabel="Close", **kw): GafferUI.Dialogue.__init__(self, title, sizeMode=GafferUI.Window.SizeMode.Manual, **kw) with GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Vertical, spacing=8) as column: GafferUI.Image("failure.png", parenting={ "horizontalAlignment": GafferUI.HorizontalAlignment.Center, "expand": True, }) GafferUI.Spacer(imath.V2i(250, 1)) if message is not None: GafferUI.Label( "<b>" + IECore.StringUtil.wrap(message, 60).replace("\n", "<br>") + "</b>", parenting={ "horizontalAlignment": GafferUI.HorizontalAlignment.Center }) if messages is not None: messageWidget = GafferUI.MessageWidget() for m in messages: messageWidget.messageHandler().handle( m.level, m.context, m.message) if details is not None: with GafferUI.Collapsible(label="Details", collapsed=True): GafferUI.MultiLineTextWidget( text=details, editable=False, ) self._setWidget(column) self.__closeButton = self._addButton(closeLabel)
def testWithContext(self): with GafferUI.Window() as window: with GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Vertical) as column: with GafferUI.Frame() as frame: button1 = GafferUI.Button() with GafferUI.Collapsible() as collapsible: button2 = GafferUI.Button() with GafferUI.TabbedContainer() as tabbed: button3 = GafferUI.Button() button4 = GafferUI.Button() with GafferUI.ScrolledContainer() as scrolled: button5 = GafferUI.Button() with GafferUI.SplitContainer() as split: button6 = GafferUI.Button() button7 = GafferUI.Button() self.failUnless(isinstance(window, GafferUI.Window)) self.failUnless(isinstance(column, GafferUI.ListContainer)) self.failUnless(isinstance(frame, GafferUI.Frame)) self.failUnless(isinstance(collapsible, GafferUI.Collapsible)) self.failUnless(isinstance(tabbed, GafferUI.TabbedContainer)) self.failUnless(isinstance(scrolled, GafferUI.ScrolledContainer)) self.failUnless(isinstance(split, GafferUI.SplitContainer)) self.failUnless(column.parent() is window) self.failUnless(frame.parent() is column) self.failUnless(button1.parent() is frame) self.failUnless(collapsible.parent() is column) self.failUnless(button2.parent() is collapsible) self.failUnless(tabbed.parent() is column) self.failUnless(button3.parent() is tabbed) self.failUnless(button4.parent() is tabbed) self.failUnless(button5.parent() is scrolled) self.failUnless(button6.parent() is split) self.failUnless(button7.parent() is split)
def __init__( self, parameterHandler ) : PresetDialogue.__init__( self, "Save Preset", parameterHandler ) with GafferUI.ListContainer( spacing = 8 ) as column : with GafferUI.GridContainer( spacing = 6 ) : GafferUI.Label( "<h3>Location</h3>", parenting = { "index" : ( 0, 0 ), "alignment" : ( GafferUI.Label.HorizontalAlignment.Right, GafferUI.Label.VerticalAlignment.None, ), } ) self._locationMenu( writable=True, parenting = { "index" : ( slice( 1, 3 ), 0 ) } ) GafferUI.Label( "<h3>Name</h3>", parenting = { "index" : ( 0, 1 ), "alignment" : ( GafferUI.Label.HorizontalAlignment.Right, GafferUI.Label.VerticalAlignment.None, ), } ) self.__presetNameWidget = GafferUI.TextWidget( self.__defaultName, parenting = { "index" : ( 1, 1 ) } ) self.__presetNameWidget.setSelection( None, None ) # select all self.__presetNameChangedConnection = self.__presetNameWidget.textChangedSignal().connect( Gaffer.WeakMethod( self.__presetNameChanged ) ) self.__loadAutomaticallyWidget = GafferUI.BoolWidget( "Load automatically", parenting = { "index" : ( 2, 1 ) } ) self.__loadAutomaticallyChangedConnection = self.__loadAutomaticallyWidget.stateChangedSignal().connect( Gaffer.WeakMethod( self.__loadAutomaticallyChanged ) ) GafferUI.Label( "<h3>Description</h3>", parenting = { "index" : ( 0, 2 ), "alignment" : ( GafferUI.Label.HorizontalAlignment.Right, GafferUI.Label.VerticalAlignment.Top, ), } ) self.__presetDescriptionWidget = GafferUI.MultiLineTextWidget( parenting = { "index" : ( slice( 1, 3 ), 2 ) } ) self.__presetDescriptionChangedConnection = self.__presetDescriptionWidget.textChangedSignal().connect( Gaffer.WeakMethod( self.__updateSaveButton ) ) with GafferUI.Collapsible( "Parameters To Save", collapsed=True ) as cl : # forcing CompoundVectorParameter to act as a leaf, because allowing the selection of some children but not others # makes no sense (because they must all have the same length). parameterPath = GafferCortex.ParameterPath( parameterHandler.parameter(), "/", forcedLeafTypes = ( IECore.CompoundVectorParameter, ) ) self.__parameterListing = GafferUI.PathListingWidget( parameterPath, columns = [ GafferUI.PathListingWidget.defaultNameColumn ], allowMultipleSelection = True, displayMode = GafferUI.PathListingWidget.DisplayMode.Tree ) self.__parameterListing.setSelectedPaths( self.__allPaths( parameterPath ) ) self.__haveSelectedParameters = True self.__selectionChangedConnection = self.__parameterListing.selectionChangedSignal().connect( Gaffer.WeakMethod( self.__selectionChanged ) ) self._setWidget( column ) self._addButton( "Cancel" ) self.__saveButton = self._addButton( "Save" ) self.__saveButton.setEnabled( False )
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 testConstructor( self ) : b = GafferUI.Button( "Hide Me" ) c = GafferUI.Collapsible( child = b, collapsed=True ) self.assertTrue( c.getChild() is b ) self.assertEqual( c.getCollapsed(), True )
def testSetCollapsed( self ) : c = GafferUI.Collapsible( collapsed=True ) self.assertEqual( c.getCollapsed(), True ) c.setCollapsed( False ) self.assertEqual( c.getCollapsed(), False )
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 __init__( self, collapsed = False, label = None, **kw ) : self.__mainColumn = GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Vertical, spacing = 0 ) self.__collapsible = None if collapsed is not None : self.__collapsible = GafferUI.Collapsible( label=label, collapsed=collapsed ) self.__collapsible.setChild( self.__mainColumn ) GafferUI.Widget.__init__( self, self.__collapsible if self.__collapsible is not None else self.__mainColumn, **kw ) self.__numRows = 0
def __enter__(self): cl = GafferUI.Collapsible(self.__label, collapsed=True) co = GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Vertical) cl.setChild(co) self.__prevColumn = self.__nodeUI._currentColumn self.__nodeUI._currentColumn.append(cl) self.__nodeUI._currentColumn = co
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()), collapsed=True) # Hack to add margins at the top and bottom but not at the sides. ## \todo This is exposed in the public API via the borderWidth # parameter to the Collapsible. That parameter sucks because a) it # makes a margin rather than a border, and b) it doesn't allow per-edge # control. Either make that make sense, or remove it and find a way # of deferring all this to the style. collapsible._qtWidget().layout().setContentsMargins(0, 2, 0, 2) 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( QtWidgets.QSizePolicy.Ignored, QtWidgets.QSizePolicy.Fixed) if subsection.restoreState("collapsed") is False: collapsible.setCollapsed(False) collapsible.stateChangedSignal().connect(functools.partial( Gaffer.WeakMethod(self.__collapsibleStateChanged), subsection=subsection), scoped=False) self.__collapsibles[name] = collapsible collapsible.getChild().update(subsection) collapsible.getCornerWidget().setText( "<small>" + " ( " + subsection.summary + " )</small>" if subsection.summary else "") currentValueChanged = collapsible._qtWidget().property( "gafferValueChanged") if subsection.valuesChanged != currentValueChanged: collapsible._qtWidget().setProperty( "gafferValueChanged", GafferUI._Variant.toVariant(subsection.valuesChanged)) collapsible._repolish() widgets.append(collapsible) self.__column[:] = widgets
def testTransferChildren( self ) : c = GafferUI.Collapsible() b = GafferUI.Button() l = GafferUI.ListContainer() self.assertEqual( b.parent(), None ) l.append( b ) self.assertTrue( b.parent() is l ) c.setChild( b ) self.assertTrue( b.parent() is c ) self.assertEqual( len( l ), 0 )
def testStateChangedSignal( self ) : self.__states = [] def stateChanged( widget ) : self.__states.append( widget.getCollapsed( ) ) c = GafferUI.Collapsible( collapsed=True ) stateChangedConnection = c.stateChangedSignal().connect( stateChanged ) c.setCollapsed( False ) self.assertEqual( self.__states, [ False ] ) c.setCollapsed( False ) # shouldn't trigger as state is the same self.assertEqual( self.__states, [ False ] ) c.setCollapsed( True ) self.assertEqual( self.__states, [ False, True ] )
def __init__(self, title, message, details=None, **kw): GafferUI.Dialogue.__init__(self, title, sizeMode=GafferUI.Window.SizeMode.Manual, **kw) with GafferUI.Frame() as frame: with GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Vertical, spacing=8) as column: GafferUI.Spacer(IECore.V2i(1), parenting={"expand": True}) GafferUI.Image("failure.png", parenting={ "horizontalAlignment": GafferUI.HorizontalAlignment.Center, "expand": True, }) GafferUI.Spacer(IECore.V2i(250, 1), parenting={"expand": True}) GafferUI.Label( "<b>" + IECore.StringUtil.wrap(message, 60).replace("\n", "<br>") + "</b>", parenting={ "horizontalAlignment": GafferUI.HorizontalAlignment.Center }) if details is not None: with GafferUI.Collapsible(label="Details", collapsed=True): GafferUI.MultiLineTextWidget( text=details, editable=False, ) self._setWidget(frame) self.__closeButton = self._addButton("Close")
def __init__( self, title, message, details=None, **kw ) : GafferUI.Dialogue.__init__( self, title, sizeMode=GafferUI.Window.SizeMode.Manual, **kw ) with GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Vertical, spacing = 8 ) as column : with GafferUI.Frame( borderWidth = 8 ) : with GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Horizontal ) : GafferUI.Spacer( IECore.V2i( 1 ) ) GafferUI.Label( IECore.StringUtil.wrap( message, 60 ) ) GafferUI.Spacer( IECore.V2i( 1 ) ) if details is not None : with GafferUI.Collapsible( label = "Details", collapsed = True ) : with GafferUI.Frame( borderWidth=8 ) : GafferUI.MultiLineTextWidget( text = details, editable = False, ) self._setWidget( column ) self.__closeButton = self._addButton( "Close" )
def __init__(self, plug, **kw): self.__column = GafferUI.ListContainer(spacing=4) GafferUI.PlugValueWidget.__init__(self, self.__column, plug, **kw) with self.__column: self.__pathListing = GafferUI.PathListingWidget( _ImagesPath(self.__images(), []), columns=(GafferUI.PathListingWidget.defaultNameColumn, ), ) self.__pathListing.setSortable(False) self.__pathListing.setHeaderVisible(False) self.__pathListingSelectionChangedConnection = self.__pathListing.selectionChangedSignal( ).connect(Gaffer.WeakMethod(self.__pathListingSelectionChanged)) self.__pathListingDragEnterConnection = self.__pathListing.dragEnterSignal( ).connect(Gaffer.WeakMethod(self.__pathListingDragEnter)) self.__pathListingDragLeaveConnection = self.__pathListing.dragLeaveSignal( ).connect(Gaffer.WeakMethod(self.__pathListingDragLeave)) self.__pathListingDropConnection = self.__pathListing.dropSignal( ).connect(Gaffer.WeakMethod(self.__pathListingDrop)) with GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Horizontal, spacing=4): addButton = GafferUI.Button(image="pathChooser.png", hasFrame=False, toolTip="Load image") self.__addClickedConnection = addButton.clickedSignal( ).connect(Gaffer.WeakMethod(self.__addClicked)) self.__duplicateButton = GafferUI.Button( image="duplicate.png", hasFrame=False, toolTip="Duplicate selected image") self.__duplicateButton.setEnabled(False) self.__duplicateButtonClickedConnection = self.__duplicateButton.clickedSignal( ).connect(Gaffer.WeakMethod(self.__duplicateClicked)) self.__exportButton = GafferUI.Button( image="export.png", hasFrame=False, toolTip="Export selected image") self.__exportButton.setEnabled(False) self.__exportButtonClickedConnection = self.__exportButton.clickedSignal( ).connect(Gaffer.WeakMethod(self.__exportClicked)) GafferUI.Spacer(IECore.V2i(0), parenting={"expand": True}) self.__removeButton = GafferUI.Button( image="delete.png", hasFrame=False, toolTip="Remove selected image") self.__removeButton.setEnabled(False) self.__removeClickedConnection = self.__removeButton.clickedSignal( ).connect(Gaffer.WeakMethod(self.__removeClicked)) GafferUI.Divider() with GafferUI.Collapsible(label="Image Properties", collapsed=False): with GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Vertical, spacing=4): with GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Horizontal, spacing=4): GafferUI.Label("Name") self.__nameWidget = GafferUI.NameWidget( graphComponent=None) GafferUI.Label("Description") self.__descriptionWidget = GafferUI.MultiLineStringPlugValueWidget( plug=None) self._updateFromPlug()
class DispatchDialogue(GafferUI.Dialogue): ## Defines what happens when the tasks have been successfully dispatched : # # Close : The dialogue is closed immediately. # # Confirm : The dialogue remains open confirming success, with a button for returning to the editing state. PostDispatchBehaviour = IECore.Enum.create("Close", "Confirm") __dispatchDialogueMenuDefinition = None def __init__(self, tasks, dispatchers, nodesToShow, postDispatchBehaviour=PostDispatchBehaviour.Confirm, title="Dispatch Tasks", sizeMode=GafferUI.Window.SizeMode.Manual, **kw): GafferUI.Dialogue.__init__(self, title, sizeMode=sizeMode, **kw) self._getWidget().setBorderStyle(GafferUI.Frame.BorderStyle.None) self.__dispatchers = dispatchers self.__tasks = tasks self.__nodesToShow = nodesToShow self.__script = tasks[0].scriptNode() # hold a reference to the script window so plugs which launch child windows work properly. # this is necessary for PlugValueWidgets like color swatches and ramps. Ideally those widgets # wouldn't rely on the existence of a ScriptWindow and we could drop this acquisition. self.__scriptWindow = GafferUI.ScriptWindow.acquire(self.__script) self.__postDispatchBehaviour = postDispatchBehaviour # build tabs for all the node, dispatcher, and context settings with GafferUI.ListContainer() as self.__settings: mainMenu = GafferUI.MenuBar(self.menuDefinition()) mainMenu.setVisible(False) with GafferUI.TabbedContainer() as self.__tabs: for node in self.__nodesToShow: nodeFrame = GafferUI.Frame( borderStyle=GafferUI.Frame.BorderStyle.None, borderWidth=0) nodeFrame.addChild(self.__nodeEditor(node)) # remove the per-node execute button Gaffer.Metadata.registerValue( node, "layout:customWidget:dispatchButton:widgetType", "", persistent=False) self.__tabs.setLabel(nodeFrame, node.relativeName(self.__script)) with GafferUI.ListContainer() as dispatcherTab: with GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Horizontal, spacing=2, borderWidth=4) as dispatcherMenuColumn: GafferUI.Label("<h4>Dispatcher</h4>") self.__dispatchersMenu = GafferUI.MultiSelectionMenu( allowMultipleSelection=False, allowEmptySelection=False) self.__dispatchersMenu.append( [x.getName() for x in self.__dispatchers]) self.__dispatchersMenu.setSelection( [self.__dispatchers[0].getName()]) self.__dispatchersMenuChanged = self.__dispatchersMenu.selectionChangedSignal( ).connect(Gaffer.WeakMethod(self.__dispatcherChanged)) dispatcherMenuColumn.setVisible( len(self.__dispatchers) > 1) self.__dispatcherFrame = GafferUI.Frame( borderStyle=GafferUI.Frame.BorderStyle.None, borderWidth=0) self.__tabs.setLabel(dispatcherTab, "Dispatcher") with GafferUI.Frame( borderStyle=GafferUI.Frame.BorderStyle.None, borderWidth=4) as contextTab: GafferUI.PlugValueWidget.create(self.__script["variables"]) self.__tabs.setLabel(contextTab, "Context Variables") # build a ui element for progress feedback and messages with GafferUI.ListContainer(spacing=4) as self.__progressUI: with GafferUI.ListContainer( parenting={ "horizontalAlignment": GafferUI.HorizontalAlignment.Center, "verticalAlignment": GafferUI.VerticalAlignment.Center }): self.__progressIconFrame = GafferUI.Frame( borderStyle=GafferUI.Frame.BorderStyle.None, parenting={ "horizontalAlignment": GafferUI.HorizontalAlignment.Center }) self.__progressLabel = GafferUI.Label(parenting={ "horizontalAlignment": GafferUI.HorizontalAlignment.Center }) with GafferUI.Collapsible( "Details", collapsed=True, parenting={"expand": True}) as self.__messageCollapsible: self.__messageWidget = GafferUI.MessageWidget() # connect to the collapsible state change so we can increase the window # size when the details pane is first shown. self.__messageCollapsibleConneciton = self.__messageCollapsible.stateChangedSignal( ).connect(Gaffer.WeakMethod(self.__messageCollapsibleChanged)) self.__backButton = self._addButton("Back") self.__backButtonConnection = self.__backButton.clickedSignal( ).connect(0, Gaffer.WeakMethod(self.__initiateSettings)) self.__primaryButton = self._addButton("Dispatch") self.__setDispatcher(dispatchers[0]) self.__initiateSettings(self.__primaryButton)
def __init__(self, opInstanceOrOpHolderInstance, title=None, sizeMode=GafferUI.Window.SizeMode.Manual, postExecuteBehaviour=PostExecuteBehaviour.FromUserData, executeInBackground=False, **kw): # sort out our op and op holder if isinstance(opInstanceOrOpHolderInstance, IECore.Op): opInstance = opInstanceOrOpHolderInstance self.__node = Gaffer.ParameterisedHolderNode() self.__node.setParameterised(opInstance) else: self.__node = opInstanceOrOpHolderInstance opInstance = self.__node.getParameterised()[0] # initialise the dialogue if title is None: title = IECore.CamelCase.toSpaced(opInstance.typeName()) GafferUI.Dialogue.__init__(self, title, sizeMode=sizeMode, **kw) # decide what we'll do after execution. if postExecuteBehaviour == self.PostExecuteBehaviour.FromUserData: postExecuteBehaviour = self.PostExecuteBehaviour.DisplayResult d = None with IECore.IgnoredExceptions(KeyError): d = opInstance.userData()["UI"]["postExecuteBehaviour"] if d is not None: for v in self.PostExecuteBehaviour.values(): if str(v).lower() == d.value.lower(): postExecuteBehaviour = v break else: # backwards compatibility with batata with IECore.IgnoredExceptions(KeyError): d = opInstance.userData()["UI"]["closeAfterExecution"] if d is not None: postExecuteBehaviour = self.PostExecuteBehaviour.Close if d.value else self.PostExecuteBehaviour.DisplayResult self.__postExecuteBehaviour = postExecuteBehaviour self.__executeInBackground = executeInBackground # make a frame to contain our main ui element. this will # contain different elements depending on our state. self.__frame = GafferUI.Frame() self._setWidget(self.__frame) # get the ui for the op - we'll use this when we want # the user to edit parameters. self.__parameterEditingUI = GafferUI.NodeUI.create(self.__node) # build a ui element for progress feedback and suchlike. # we'll use this when executing and displaying the result. with GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Vertical, spacing=4) as self.__progressUI: center = { "horizontalAlignment": GafferUI.HorizontalAlignment.Center } GafferUI.Spacer(IECore.V2i(1), parenting={"expand": True}) self.__progressIconFrame = GafferUI.Frame( borderStyle=GafferUI.Frame.BorderStyle.None, parenting={ "horizontalAlignment": GafferUI.HorizontalAlignment.Center }) self.__progressLabel = GafferUI.Label( parenting={ "expand": True, "horizontalAlignment": GafferUI.HorizontalAlignment.Center, }) GafferUI.Spacer(IECore.V2i(1), expand=True) with GafferUI.Collapsible( "Details", collapsed=True) as self.__messageCollapsible: self.__messageWidget = GafferUI.MessageWidget() # add buttons. our buttons mean different things depending on our current state, # but they equate roughly to going forwards or going backwards. self.__backButton = self._addButton("Back") self.__forwardButton = self._addButton("Forward") self.__opExecutedSignal = Gaffer.Signal1() self.__initiateParameterEditing()
def __init__( self, about ) : GafferUI.Window.__init__( self, title = "About " + about.name() ) frame = GafferUI.Frame( borderWidth = 30 ) column = GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Vertical, spacing=10 ) frame.setChild( column ) name = GafferUI.Label( text = about.name() + " " + about.versionString() ) name.setFont( size=GafferUI.Widget.FontSize.Large, weight=GafferUI.Widget.FontWeight.Bold ) column.append( name ) copy = GafferUI.Label( text = about.copyright() ) copy.setFont( size=GafferUI.Widget.FontSize.Medium, weight=GafferUI.Widget.FontWeight.Bold ) column.append( copy ) url = GafferUI.URLWidget( about.url() ) column.append( url ) dependencies = about.dependencies() if dependencies : collapsible = GafferUI.Collapsible( label="Dependencies", collapsed=False ) scrollable = GafferUI.ScrolledContainer( horizontalMode=GafferUI.ScrolledContainer.ScrollMode.Never, verticalMode=GafferUI.ScrolledContainer.ScrollMode.Always, borderWidth = 5 ) depColumn = GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Vertical, spacing=5, borderWidth=10 ) scrollable.setChild( depColumn ) collapsible.setChild( scrollable ) depColumn.append( GafferUI.Label( IECore.StringUtil.wrap( about.dependenciesPreamble(), 60 ), alignment = IECore.V2f( 0 ), ) ) for d in dependencies : spacer = GafferUI.Label( text = "" ) depColumn.append( spacer ) name = GafferUI.Label( text = d["name"], alignment=IECore.V2f( 0 ) ) name.setFont( size=name.FontSize.Medium, weight=name.FontWeight.Bold ) depColumn.append( name ) if "credit" in d : credit = GafferUI.Label( text=IECore.StringUtil.wrap( d["credit"], 60 ), alignment=IECore.V2f( 0 ) ) depColumn.append( credit ) if "license" in d : license = GafferUI.URLWidget( url="file://" + os.path.expandvars( d["license"] ), label="License", alignment=IECore.V2f( 0 ) ) depColumn.append( license ) if "url" in d : url = GafferUI.URLWidget( d["url"], alignment=IECore.V2f( 0 ) ) depColumn.append( url ) if "source" in d : source = GafferUI.URLWidget( url=d["source"], label="Source", alignment=IECore.V2f( 0 ) ) depColumn.append( source ) column.append( collapsible, expand=True ) self.setChild( frame )
def __init__(self, plug, **kw): self.__column = GafferUI.ListContainer(spacing=4) GafferUI.PlugValueWidget.__init__(self, self.__column, plug, **kw) with self.__column: columns = self.__listingColumns() self.__pathListing = GafferUI.PathListingWidget( _ImagesPath(self.__images(), []), columns=columns, allowMultipleSelection=True, sortable=False, horizontalScrollMode=GafferUI.ScrollMode.Automatic) self.__pathListing.setDragPointer("") self.__pathListing.setHeaderVisible(True) self.__pathListing.selectionChangedSignal().connect( Gaffer.WeakMethod(self.__pathListingSelectionChanged), scoped=False) self.__pathListing.dragEnterSignal().connect(Gaffer.WeakMethod( self.__pathListingDragEnter), scoped=False) self.__pathListing.dragLeaveSignal().connect(Gaffer.WeakMethod( self.__pathListingDragLeave), scoped=False) self.__pathListing.dragMoveSignal().connect(Gaffer.WeakMethod( self.__pathListingDragMove), scoped=False) self.__pathListing.dropSignal().connect(Gaffer.WeakMethod( self.__pathListingDrop), scoped=False) self.keyPressSignal().connect(Gaffer.WeakMethod(self.__keyPress), scoped=False) with GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Horizontal, spacing=4): addButton = GafferUI.Button(image="pathChooser.png", hasFrame=False, toolTip="Load image") addButton.clickedSignal().connect(Gaffer.WeakMethod( self.__addClicked), scoped=False) self.__duplicateButton = GafferUI.Button( image="duplicate.png", hasFrame=False, toolTip= "Duplicate selected image, hold <kbd>alt</kbd> to view copy. [<kbd>Ctrl-D</kbd>]" ) self.__duplicateButton.setEnabled(False) self.__duplicateButton.clickedSignal().connect( Gaffer.WeakMethod(self.__duplicateClicked), scoped=False) self.__exportButton = GafferUI.Button( image="export.png", hasFrame=False, toolTip="Export selected image") self.__exportButton.setEnabled(False) self.__exportButton.clickedSignal().connect(Gaffer.WeakMethod( self.__exportClicked), scoped=False) self.__extractButton = GafferUI.Button( image="extract.png", hasFrame=False, toolTip="Create CatalogueSelect node for selected image") self.__extractButton.setEnabled(False) self.__extractButton.clickedSignal().connect(Gaffer.WeakMethod( self.__extractClicked), scoped=False) GafferUI.Spacer(imath.V2i(0), parenting={"expand": True}) self.__removeButton = GafferUI.Button( image="delete.png", hasFrame=False, toolTip="Remove selected image [<kbd>Delete</kbd>]") self.__removeButton.setEnabled(False) self.__removeButton.clickedSignal().connect(Gaffer.WeakMethod( self.__removeClicked), scoped=False) GafferUI.Divider() with GafferUI.Collapsible(label="Image Properties", collapsed=False): with GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Vertical, spacing=4): with GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Horizontal, spacing=4): GafferUI.Label("Name") self.__nameWidget = GafferUI.NameWidget( graphComponent=None) GafferUI.Label("Description") self.__descriptionWidget = GafferUI.MultiLineStringPlugValueWidget( plug=None) Gaffer.Metadata.plugValueChangedSignal(plug.node()).connect( Gaffer.WeakMethod(self.__plugMetadataValueChanged), scoped=False) self.contextMenuSignal().connect(Gaffer.WeakMethod(self.__contextMenu), scoped=False) self._updateFromPlug()
def __init__( self, opInstanceOrOpHolderInstance, title=None, sizeMode=GafferUI.Window.SizeMode.Manual, postExecuteBehaviour = PostExecuteBehaviour.FromUserData, executeInBackground = False, defaultButton = DefaultButton.FromUserData, executeImmediately = False, **kw ) : # sort out our op and op holder if isinstance( opInstanceOrOpHolderInstance, IECore.Op ) : opInstance = opInstanceOrOpHolderInstance self.__node = GafferCortex.ParameterisedHolderNode() self.__node.setParameterised( opInstance ) # set the current plug values as userDefaults to provide # a clean NodeUI based on the initial settings of the Op. # we assume that if an OpHolder was passed directly then # the metadata has already been setup as preferred. self.__setUserDefaults( self.__node ) else : self.__node = opInstanceOrOpHolderInstance opInstance = self.__node.getParameterised()[0] # initialise the dialogue if title is None : title = IECore.CamelCase.toSpaced( opInstance.typeName() ) GafferUI.Dialogue.__init__( self, title, sizeMode=sizeMode, **kw ) # decide what we'll do after execution. if postExecuteBehaviour == self.PostExecuteBehaviour.FromUserData : postExecuteBehaviour = self.PostExecuteBehaviour.DisplayResult d = None with IECore.IgnoredExceptions( KeyError ) : d = opInstance.userData()["UI"]["postExecuteBehaviour"] if d is not None : for v in self.PostExecuteBehaviour.values() : if str( v ).lower() == d.value.lower() : postExecuteBehaviour = v break else : # backwards compatibility with batata with IECore.IgnoredExceptions( KeyError ) : d = opInstance.userData()["UI"]["closeAfterExecution"] if d is not None : postExecuteBehaviour = self.PostExecuteBehaviour.Close if d.value else self.PostExecuteBehaviour.DisplayResult self.__postExecuteBehaviour = postExecuteBehaviour self.__executeInBackground = executeInBackground self.__defaultButton = defaultButton # make a frame to contain our main ui element. this will # contain different elements depending on our state. self.__frame = GafferUI.Frame() self._setWidget( self.__frame ) # get the ui for the op - we'll use this when we want # the user to edit parameters. self.__parameterEditingUI = GafferUI.NodeUI.create( self.__node ) # build a ui element for progress feedback and suchlike. # we'll use this when executing and displaying the result. with GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Vertical, spacing = 4 ) as self.__progressUI : GafferUI.Spacer( imath.V2i( 1 ), preferredSize = imath.V2i( 1, 1 ) ) self.__progressIconFrame = GafferUI.Frame( borderStyle = GafferUI.Frame.BorderStyle.None_, parenting = { "horizontalAlignment" : GafferUI.HorizontalAlignment.Center } ) self.__progressLabel = GafferUI.Label( parenting = { "expand" : True, "horizontalAlignment" : GafferUI.HorizontalAlignment.Center, } ) GafferUI.Spacer( imath.V2i( 250, 1 ), preferredSize = imath.V2i( 250, 1 ) ) with GafferUI.Collapsible( "Details", collapsed = True ) as self.__messageCollapsible : self.__messageWidget = GafferUI.MessageWidget( toolbars = True ) # connect to the collapsible state change so we can increase the window # size when the details pane is first shown. self.__messageCollapsibleStateChangedConnection = self.__messageCollapsible.stateChangedSignal().connect( Gaffer.WeakMethod( self.__messageCollapsibleStateChanged ) ) # add buttons. our buttons mean different things depending on our current state, # but they equate roughly to going forwards or going backwards. self.__backButton = self._addButton( "Back" ) self.__forwardButton = self._addButton( "Forward" ) self.__preExecuteSignal = GafferUI.WidgetSignal() self.__postExecuteSignal = Gaffer.Signal2() self.__opExecutedSignal = Gaffer.Signal1() self.__haveResizedToFitParameters = False if executeImmediately : self.__initiateExecution() else : self.__initiateParameterEditing()