Skip to content

Commit

Permalink
DispatcherUI : Remove emulated "PlaybackRange" option
Browse files Browse the repository at this point in the history
The Dispatcher class itself doesn't support such an option, because the playback range is something only the UI knows about. We were then trying to emulate the PlaybackRange option by pushing the playback range into the frameRange plug, replacing any custom range the user might have entered. We did keep track of the old custom range so it could be restored when changing back, but we had a bug whereby the playback range could stomp over the user's custom range.

Rather than fix the problem, this commit just removes the PlaybackRange option entirely. It was problematic to implement anyway, and the only reason it had even a chance of working was that the DispatcherWindow was always around in the background to monitor changes to the playback range and push them into the frameFrame plug. In future we intend to allow Dispatcher nodes to exist in the node graph directly, at which point there will be no guarantee of a persistent UI, and the feature would be impossible rather than merely problematic.

I had intended to add a simple preset to the frameRange plug to copy in the current playback range as an alternative, but that is not possible because presets have access only to the plug, not a context. I've also removed the frame range preview feature because it was relying on access to the DispatcherWindow too. Both these should be reintroducable at the expense of further complexity, but personally I don't think it's worth it.
  • Loading branch information
johnhaddon committed Mar 2, 2017
1 parent b280c73 commit 654e0dc
Showing 1 changed file with 9 additions and 155 deletions.
164 changes: 9 additions & 155 deletions python/GafferDispatchUI/DispatcherUI.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@
of TaskNodes.
""",

"layout:activator:framesModeIsCustomRange", lambda node : node["framesMode"].getValue() == GafferDispatch.Dispatcher.FramesMode.CustomRange,

plugs = {

"user" : (
Expand All @@ -77,19 +79,22 @@
the frameRange plug.
""",

"plugValueWidget:type", "GafferUI.DispatcherUI._FramesModePlugValueWidget",
"preset:Current Frame", GafferDispatch.Dispatcher.FramesMode.CurrentFrame,
"preset:Full Range", GafferDispatch.Dispatcher.FramesMode.FullRange,
"preset:Custom Range", GafferDispatch.Dispatcher.FramesMode.CustomRange,

"plugValueWidget:type", "GafferUI.PresetsPlugValueWidget",

),

"frameRange" : (

"description",
"""
The frame range to be used when framedMode is "CustomRange".
The frame range to be used when framesMode is "CustomRange".
""",

"layout:activator", "customRange",
"plugValueWidget:type", "GafferUI.DispatcherUI._FrameRangePlugValueWidget",
"layout:visibilityActivator", "framesModeIsCustomRange",

),

Expand Down Expand Up @@ -344,157 +349,6 @@ def __clicked( self, button ) :

_showDispatcherWindow( [ self.__node ] )

########################################
# PlugValueWidgets for frame range plugs
########################################

# Much of this is copied from EnumPlugValueWidget, but we're not deriving because we
# want the ability to add in menu items that don't correspond to plug values directly.
class _FramesModePlugValueWidget( GafferUI.PlugValueWidget ) :

def __init__( self, plug, **kw ) :

self.__selectionMenu = GafferUI.MultiSelectionMenu( allowMultipleSelection = False, allowEmptySelection = False )
GafferUI.PlugValueWidget.__init__( self, self.__selectionMenu, plug, **kw )

self.__labelsAndValues = (
( "CurrentFrame", GafferDispatch.Dispatcher.FramesMode.CurrentFrame ),
( "FullRange", GafferDispatch.Dispatcher.FramesMode.FullRange ),
( "PlaybackRange", GafferDispatch.Dispatcher.FramesMode.CustomRange ),
( "CustomRange", GafferDispatch.Dispatcher.FramesMode.CustomRange ),
)

for label, value in self.__labelsAndValues :
self.__selectionMenu.append( label )

self.__updateFrameRangeConnection = None
self.__visibilityChangedConnection = self.visibilityChangedSignal().connect( Gaffer.WeakMethod( self.__visibilityChanged ) )
self.__selectionChangedConnection = self.__selectionMenu.selectionChangedSignal().connect( Gaffer.WeakMethod( self.__selectionChanged ) )

self._addPopupMenu( self.__selectionMenu )

# save the metadata in case the frameRange plug is set prior to enabling CustomRange mode
self.__customFrameRangeChanged( self.getPlug().node()["frameRange"] )

self._updateFromPlug()

def selectionMenu( self ) :

return self.__selectionMenu

def _updateFromPlug( self ) :

self.__selectionMenu.setEnabled( self._editable() )

if self.getPlug() is None :
return

with self.getContext() :
plugValue = self.getPlug().getValue()

for labelAndValue in self.__labelsAndValues :
if labelAndValue[1] == plugValue :
with Gaffer.BlockedConnection( self.__selectionChangedConnection ) :
self.__selectionMenu.setSelection( labelAndValue[0] )
break

def __frameRangeWidget( self ) :

nodeUI = self.ancestor( GafferUI.NodeUI )
if nodeUI :
return nodeUI.plugValueWidget( self.getPlug().node()["frameRange"], lazy = False )

return None

def __selectionChanged( self, selectionMenu ) :

label = selectionMenu.getSelection()[0]
value = self.__labelsAndValues[ selectionMenu.index( label ) ][1]

Gaffer.Metadata.registerValue(
self.getPlug().node(),
"layout:activator:customRange",
label == "CustomRange",
)

with Gaffer.BlockedConnection( self._plugConnections() ) :
self.getPlug().setValue( value )

self.__updateFrameRangeConnection = None

window = self.ancestor( GafferUI.ScriptWindow )
if not window :
return

script = window.scriptNode()
context = script.context()

if label == "CurrentFrame" :
self.__updateFrameRangeConnection = context.changedSignal().connect( Gaffer.WeakMethod( self.__contextChanged ) )
self.__contextChanged( context, "frame" )
elif label == "FullRange" :
self.__updateFrameRangeConnection = script.plugDirtiedSignal().connect( Gaffer.WeakMethod( self.__scriptPlugDirtied ) )
self.__scriptPlugDirtied( script["frameRange"] )
elif label == "PlaybackRange" :
playback = GafferUI.Playback.acquire( context )
self.__updateFrameRangeConnection = playback.frameRangeChangedSignal().connect( Gaffer.WeakMethod( self.__playbackFrameRangeChanged ) )
self.__playbackFrameRangeChanged( playback )
else :
frameRange = Gaffer.Metadata.value( self.getPlug(), "dispatcherWindow:frameRange" )
if frameRange is not None :
self.getPlug().node()["frameRange"].setValue( frameRange )
self.__updateFrameRangeConnection = self.getPlug().node().plugDirtiedSignal().connect( Gaffer.WeakMethod( self.__customFrameRangeChanged ) )

def __visibilityChanged( self, widget ) :

if self.visible() :
self.__selectionChanged( self.__selectionMenu )
else :
self.__updateFrameRangeConnection = None

def __contextChanged( self, context, key ) :

if key == "frame" :
frameRangeWidget = self.__frameRangeWidget()
if frameRangeWidget :
frameRangeWidget.textWidget().setText( str(int(context.getFrame())) )

def __playbackFrameRangeChanged( self, playback ) :

frameRange = playback.getFrameRange()
frameRange = str(IECore.frameListFromList( range(frameRange[0], frameRange[1]+1) ))
self.getPlug().node()["frameRange"].setValue( frameRange )
frameRangeWidget = self.__frameRangeWidget()
if frameRangeWidget :
frameRangeWidget.textWidget().setText( str(frameRange) )

def __scriptPlugDirtied( self, plug ) :

script = plug.ancestor( Gaffer.ScriptNode )
if script and plug.isSame( script["frameRange"] ) or plug.parent().isSame( script["frameRange"] ) :
frameRangeWidget = self.__frameRangeWidget()
if frameRangeWidget :
frameRangeWidget.textWidget().setText( str(IECore.FrameRange( script["frameRange"]["start"].getValue(), script["frameRange"]["end"].getValue() )) )

def __customFrameRangeChanged( self, plug ) :

if plug.isSame( self.getPlug().node()["frameRange"] ) :
with self.getContext() :
Gaffer.Metadata.registerValue( self.getPlug(), "dispatcherWindow:frameRange", plug.getValue() )

class _FrameRangePlugValueWidget( GafferUI.StringPlugValueWidget ) :

def _updateFromPlug( self ) :

with self.getContext() :
framesMode = self.getPlug().node()["framesMode"].getValue()

# we need to disable the normal update in CurrentFrame and FullRange modes
if framesMode == GafferDispatch.Dispatcher.FramesMode.CustomRange :
GafferUI.StringPlugValueWidget._updateFromPlug( self )

self.textWidget().setEditable( self._editable() )

##########################################################################
# Implementation Details
##########################################################################
Expand Down

0 comments on commit 654e0dc

Please sign in to comment.