def _updateFromPlugs(self): self.__menuButton.setEnabled(self._editable()) if not self.getPlugs(): self.__menuButton.setText("") return with self.getContext(): currentPreset = sole((Gaffer.NodeAlgo.currentPreset(p) or "" for p in self.getPlugs())) allowCustom = sole( (Gaffer.Metadata.value(p, "presetsPlugValueWidget:allowCustom") for p in self.getPlugs())) isCustom = any( Gaffer.Metadata.value(p, "presetsPlugValueWidget:isCustom") for p in self.getPlugs()) isCustom = allowCustom and (isCustom or currentPreset == "") self.__customValuePlugWidget.setVisible(isCustom) if isCustom: self.__menuButton.setText("Custom") elif currentPreset: self.__menuButton.setText(currentPreset) elif currentPreset is None: self.__menuButton.setText("---") else: self.__menuButton.setText("Invalid")
def __menuDefinition(self): result = IECore.MenuDefinition() if not self.getPlugs(): return result # Required for context-sensitive dynamic presets with self.getContext(): currentPreset = sole((Gaffer.NodeAlgo.currentPreset(p) or "" for p in self.getPlugs())) allowCustom = sole( (Gaffer.Metadata.value(p, "presetsPlugValueWidget:allowCustom") for p in self.getPlugs())) isCustom = all( Gaffer.Metadata.value(p, "presetsPlugValueWidget:isCustom") for p in self.getPlugs()) isCustom = allowCustom and (isCustom or currentPreset == "") # Find the union of the presets across all plugs, # and count how many times they occur. presets = [] presetCounts = collections.Counter() for plug in self.getPlugs(): for preset in Gaffer.NodeAlgo.presets(plug): if not presetCounts[preset]: presets.append(preset) presetCounts[preset] += 1 # Build menu. We'll list every preset we found, but disable # any which aren't available for all plugs. for preset in presets: menuPath = preset if preset.startswith("/") else "/" + preset result.append( menuPath, { "command": functools.partial(Gaffer.WeakMethod(self.__applyPreset), preset=preset), "checkBox": preset == currentPreset and not isCustom, "active": presetCounts[preset] == len(self.getPlugs()) }) if allowCustom: result.append("/CustomDivider", {"divider": True}) result.append( "/Custom", { "command": Gaffer.WeakMethod(self.__applyCustomPreset), "checkBox": isCustom, }) return result
def __updateKeyFrame(self): # if multiple keys selected display "---" unless all selected keys have same value # which can only happen when all the keys have different parent curves selectedKeys = self.parent().curveGadget().selectedKeys() time = sole(key.getTime() for key in selectedKeys) if time is not None: context = selectedKeys[0].parent().ancestor( Gaffer.ScriptNode).context() frame = int(round(time * context.getFramesPerSecond())) with Gaffer.BlockedConnection(self.__frameConnection): self.__frameEditor.setValue(frame) else: with Gaffer.BlockedConnection(self.__frameConnection): self.__frameEditor.setText("") self.__frameEditor._qtWidget().setPlaceholderText("---") # set enabled when all selected keys have different parent curves enabled = bool(selectedKeys) curves = set() for key in selectedKeys: if key.parent() in curves: enabled = False break curves.add(key.parent()) self.__frameEditor.setEnabled(enabled)
def __toggleBooleans( self, plugs ) : if not plugs : return with self.ancestor( GafferUI.PlugValueWidget ).getContext() : checked = sole( [ plug.getValue() for plug in plugs ] ) with Gaffer.UndoScope( next( iter( plugs ) ).ancestor( Gaffer.ScriptNode ) ) : self.__setPlugValues( plugs, not checked )
def __syncUI(self): plugs = self.getPlugs() tabsVisible = sole([ Gaffer.Metadata.value(p, self.tabsVisibleMetadataKey) for p in plugs ]) if tabsVisible is None: tabsVisible = False self.__setTabsVisible(tabsVisible, persist=False) currentTab = sole([ Gaffer.Metadata.value(p, self.currentTabMetadataKey) for p in plugs ]) if currentTab is not None: with Gaffer.BlockedConnection(self.__currentTabChangedConnection): self.__switchToTab(currentTab)
def _updateFromPlugs(self): # Value and error status errored = False value = None with self.getContext(): try: value = sole(p.getValue() for p in self.getPlugs()) except: errored = True with Gaffer.BlockedConnection(self.__stateChangedConnection): self.__boolWidget.setState(value if value is not None else self. __boolWidget.State.Indeterminate) self.__boolWidget.setErrored(errored) # Animation state animated = any(Gaffer.Animation.isAnimated(p) for p in self.getPlugs()) ## \todo Perhaps this styling should be provided by the BoolWidget itself? widgetAnimated = GafferUI._Variant.fromVariant( self.__boolWidget._qtWidget().property("gafferAnimated")) or False if widgetAnimated != animated: self.__boolWidget._qtWidget().setProperty( "gafferAnimated", GafferUI._Variant.toVariant(bool(animated))) self.__boolWidget._repolish() # Display mode and enabled status displayMode = sole( Gaffer.Metadata.value(p, "boolPlugValueWidget:displayMode") for p in self.getPlugs()) if displayMode is not None: displayMode = { "switch": self.__boolWidget.DisplayMode.Switch, "checkBox": self.__boolWidget.DisplayMode.CheckBox, "tool": self.__boolWidget.DisplayMode.Tool, }.get(displayMode, self.__boolWidget.DisplayMode.CheckBox) self.__boolWidget.setDisplayMode(displayMode) self.__boolWidget.setEnabled(self._editable(canEditAnimation=True))
def _updateFromPlugs(self): if all(["enabled" in plug for plug in self.getPlugs()]): with self.getContext(): enabled = sole( [plug["enabled"].getValue() for plug in self.getPlugs()]) if isinstance(self.__row[0], GafferUI.StringPlugValueWidget): self.__row[0].setEnabled(enabled is True) self.__row[-1].setEnabled(enabled is True)
def _updateFromPlugs(self): if self.__enabledPlugValueWidget is None: return enabledPlugs = [p.enabledPlug() for p in self.getPlugs()] enabled = False with self.getContext(): with IECore.IgnoredExceptions(Exception): enabled = sole([p.getValue() for p in enabledPlugs]) self.__row[-1].setEnabled(enabled is True)
def _updateFromPlugs(self): value = None errored = False with self.getContext(): try: value = sole(p.getValue() for p in self.getPlugs()) except: errored = True text = value or "" if text != self.__textWidget.getText(): # Setting the text moves the cursor to the end, # even if the new text is the same. We must avoid # calling setText() in this situation, otherwise the # cursor is always moving to the end whenever a key is # pressed in continuousUpdate mode. self.__textWidget.setText(text) self.__textWidget.setErrored(errored) self.__textChangedConnection.block( any(not Gaffer.Metadata.value( p, "stringPlugValueWidget:continuousUpdate") for p in self.getPlugs())) placeHolder = "" if value is None and len(self.getPlugs()): placeHolder = "---" else: placeHolder = sole( Gaffer.Metadata.value(p, "stringPlugValueWidget:placeholderText") for p in self.getPlugs()) or "" self.textWidget()._qtWidget().setPlaceholderText(placeHolder) self.__textWidget.setEditable(self._editable())
def __updateKeyValue(self): # if multiple keys selected display "---" unless all selected keys have same value selectedKeys = self.parent().curveGadget().selectedKeys() value = sole(key.getValue() for key in selectedKeys) if value is not None: with Gaffer.BlockedConnection(self.__valueConnection): self.__valueEditor.setValue(value) else: with Gaffer.BlockedConnection(self.__valueConnection): self.__valueEditor.setText("") self.__valueEditor._qtWidget().setPlaceholderText("---") # set disabled when no selected keys self.__valueEditor.setEnabled(bool(selectedKeys))
def canEdit(cls, cellPlugs): if not cellPlugs: return False if len(cellPlugs) == 1: return True def plugStructure(cell): return [p.__class__ for p in Gaffer.Plug.RecursiveRange(cell)] if sole([plugStructure(c) for c in cellPlugs]) is None: return False return True
def _updateFromPlugs(self): # Get value and error state value = None errored = False with self.getContext(): try: value = sole(p.getValue() for p in self.getPlugs()) except: errored = True with Gaffer.BlockedConnection(self.__valueChangedConnection): # Always give the widget a value, even if we have multiple, because # the _type_ (int or float) is important, and affects interaction # with the widget. if value is not None: self.__numericWidget.setValue(value) elif self.getPlugs(): self.__numericWidget.setValue( next(iter(self.getPlugs())).defaultValue()) # But if there are multiple values or an error, clear the actual # display so we don't show anything misleading. if errored or value is None: self.__numericWidget.setText("") self.__numericWidget._qtWidget().setPlaceholderText("---") else: self.__numericWidget._qtWidget().setPlaceholderText("") self.__numericWidget.setErrored(errored) # Update animation and enabled state animated = any(Gaffer.Animation.isAnimated(p) for p in self.getPlugs()) ## \todo Perhaps this styling should be provided by the NumericWidget itself? widgetAnimated = GafferUI._Variant.fromVariant( self.__numericWidget._qtWidget().property( "gafferAnimated")) or False if widgetAnimated != animated: self.__numericWidget._qtWidget().setProperty( "gafferAnimated", GafferUI._Variant.toVariant(bool(animated))) self.__numericWidget._repolish() self.__numericWidget.setEditable(self._editable(canEditAnimation=True))
def _convertValue( self, value ) : result = GafferUI.PlugValueWidget._convertValue( self, value ) if result is not None : return result if isinstance( value, IECore.Data ) and hasattr( value, "value" ) : value = value.value if hasattr( value, "dimensions" ) and isinstance( value.dimensions(), int ) : with self.getContext() : result = sole( p.getValue() for p in self.getPlugs() ) if result is None : return None componentType = type( result[0] ) for i in range( 0, min( result.dimensions(), value.dimensions() ) ) : result[i] = componentType( value[i] ) return result return None
def __updateTangentScale(self, direction): # if multiple keys selected display "---" unless all selected keys have same scale for tangent direction selectedKeys = self.parent().curveGadget().selectedKeys() value = sole(key.tangent(direction).getScale() for key in selectedKeys) if value is not None: with Gaffer.BlockedConnection(self.__scaleConnection[direction]): self.__scaleEditor[direction].setValue(value) else: with Gaffer.BlockedConnection(self.__scaleConnection[direction]): self.__scaleEditor[direction].setText("") self.__scaleEditor[direction]._qtWidget().setPlaceholderText( "---") # set disabled when no selected keys or scale is constrained by interpolation mode enabled = bool(selectedKeys) for key in selectedKeys: if key.tangent(direction).scaleIsConstrained(): enabled = False break self.__scaleEditor[direction].setEnabled(enabled)
def _updateFromPlugs(self): value = None errored = False with self.getContext(): try: value = sole(p.getValue() for p in self.getPlugs()) except: errored = True text = value or "" if text != self.__textWidget.getText(): # Setting the text moves the cursor to the end, # even if the new text is the same. We must avoid # calling setText() in this situation, otherwise the # cursor is always moving to the end whenever a key is # pressed in continuousUpdate mode. with Gaffer.BlockedConnection(self.__textChangedConnection): self.__textWidget.setText(text) self.__textWidget.setErrored(errored) self.__continuousUpdate = all( Gaffer.Metadata.value(p, "stringPlugValueWidget:continuousUpdate") for p in self.getPlugs()) placeHolder = "" if value is None and len(self.getPlugs()): placeHolder = "---" # Mixed values require interaction before we commit the widget # value to the plugs. This prevents mixed values being overriden # by the empty string in the widget when it loses focus. self.__editRequiresInteraction = True else: placeHolder = self.__placeholderText() self.__editRequiresInteraction = False self.textWidget()._qtWidget().setPlaceholderText(placeHolder) self.__textWidget.setEditable(self._editable())
def __init__(self, plugs, displayMode=GafferUI.BoolWidget.DisplayMode.CheckBox, **kw): if plugs is None: plugs = set() elif isinstance(plugs, Gaffer.Plug): plugs = {plugs} self.__boolWidget = GafferUI.BoolWidget( displayMode=displayMode, image=sole( Gaffer.Metadata.value(p, "boolPlugValueWidget:image") for p in plugs)) GafferUI.PlugValueWidget.__init__(self, self.__boolWidget, plugs, **kw) self._addPopupMenu(self.__boolWidget) self.__stateChangedConnection = self.__boolWidget.stateChangedSignal( ).connect(Gaffer.WeakMethod(self.__stateChanged)) self._updateFromPlugs()
def __placeholderText(self): return sole( Gaffer.Metadata.value(p, "stringPlugValueWidget:placeholderText") for p in self.getPlugs()) or ""
def getInterpolationForSelectedKeys(self): # if multiple keys selected check if all have same interpolation otherwise return None return sole(key.getInterpolation() for key in self.parent().curveGadget().selectedKeys())
def getTieModeForSelectedKeys(self): # if multiple keys selected check if all have same tie mode otherwise return None return sole(key.getTieMode() for key in self.parent().curveGadget().selectedKeys())