From f812060d5bf85362e67b7599f74ec8ed401268d0 Mon Sep 17 00:00:00 2001 From: Eric Mehl Date: Fri, 18 Oct 2024 12:45:13 -0400 Subject: [PATCH 1/4] InteractiveRenderUI : Stop render on `Escape` --- Changes.md | 1 + doc/source/Interface/ControlsAndShortcuts/index.md | 9 +++++++++ python/GafferSceneUI/InteractiveRenderUI.py | 11 +++++++++++ 3 files changed, 21 insertions(+) diff --git a/Changes.md b/Changes.md index b8870df0ba..62a1ec280e 100644 --- a/Changes.md +++ b/Changes.md @@ -18,6 +18,7 @@ Improvements - PythonEditor, PythonCommand, Expression, UIEditor, OSLCode : Added line numbers to code editors (#6091). - CyclesOptions : Added `denoiseDevice` plug for configuring the device used for denoising. - AttributeTweaks : Added tooltips and presets for all attribute values. +- InteractiveRenderer : Added Esc hotkey handling to pause an interactive render. This is in addition to the existing behavior of pausing the image viewer. Fixes ----- diff --git a/doc/source/Interface/ControlsAndShortcuts/index.md b/doc/source/Interface/ControlsAndShortcuts/index.md index d758a346a8..4998f4d3e4 100644 --- a/doc/source/Interface/ControlsAndShortcuts/index.md +++ b/doc/source/Interface/ControlsAndShortcuts/index.md @@ -310,6 +310,15 @@ Duplicate current Catalogue image | {kbd}`Ctrl` + {kbd}`D` Toggle image comparison | {kbd}`Q` Toggle wipes | {kbd}`W` +### Interactive Render Viewer ### + +> Note : +> For the following controls and shortcuts, the cursor must hover over the Viewer. + +Action | Control or shortcut +-------------------------------------|-------------------- +Pause active render | {kdb}`Escape` + ### Crop window tool ### Action | Control or shortcut diff --git a/python/GafferSceneUI/InteractiveRenderUI.py b/python/GafferSceneUI/InteractiveRenderUI.py index b71777c6a6..f601f77125 100644 --- a/python/GafferSceneUI/InteractiveRenderUI.py +++ b/python/GafferSceneUI/InteractiveRenderUI.py @@ -104,6 +104,9 @@ def __init__( self, view, **kwargs ) : if isinstance( self.__view["in"], GafferImage.ImagePlug ) : view.plugDirtiedSignal().connect( Gaffer.WeakMethod( self.__viewPlugDirtied ) ) + if isinstance( self.__view, GafferUI.View ) : + self.__view.viewportGadget().keyPressSignal().connect( Gaffer.WeakMethod( self.__keyPress ) ) + self.__update() def __update( self ) : @@ -179,6 +182,14 @@ def __renderNodePlugDirtied( self, plug ) : if plug.getName() == "state" : self.__updateLazily(); + def __keyPress( self, widget, event ) : + + if event.key == "Escape" : + renderNode = self._interactiveRenderNode( self.__view ) + if renderNode is not None : + statePlug = renderNode["state"].source() + statePlug.setValue( GafferScene.InteractiveRender.State.Paused ) + ########################################################################## # UI for the state plug that allows setting the state through buttons ########################################################################## From 06f97da4a569b2b3b6187ad12afa5eb7d84c1746 Mon Sep 17 00:00:00 2001 From: Eric Mehl Date: Fri, 18 Oct 2024 17:15:20 -0400 Subject: [PATCH 2/4] InteractiveRenderUI : Hotkey for render / pause --- Changes.md | 4 +++- doc/source/Interface/ControlsAndShortcuts/index.md | 1 + python/GafferSceneUI/InteractiveRenderUI.py | 11 +++++++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/Changes.md b/Changes.md index 62a1ec280e..c8498050ba 100644 --- a/Changes.md +++ b/Changes.md @@ -18,7 +18,9 @@ Improvements - PythonEditor, PythonCommand, Expression, UIEditor, OSLCode : Added line numbers to code editors (#6091). - CyclesOptions : Added `denoiseDevice` plug for configuring the device used for denoising. - AttributeTweaks : Added tooltips and presets for all attribute values. -- InteractiveRenderer : Added Esc hotkey handling to pause an interactive render. This is in addition to the existing behavior of pausing the image viewer. +- InteractiveRenderer : + - Added Esc hotkey handling to pause an interactive render. This is in addition to the existing behavior of pausing the image viewer. + - Added Ctrl + \ hotkey handling to toggle the interactive renderer between paused and running. If the new state is `Running`, the image viewer will also be unpaused. Fixes ----- diff --git a/doc/source/Interface/ControlsAndShortcuts/index.md b/doc/source/Interface/ControlsAndShortcuts/index.md index 4998f4d3e4..1dc15c75b7 100644 --- a/doc/source/Interface/ControlsAndShortcuts/index.md +++ b/doc/source/Interface/ControlsAndShortcuts/index.md @@ -318,6 +318,7 @@ Toggle wipes | {kbd}`W` Action | Control or shortcut -------------------------------------|-------------------- Pause active render | {kdb}`Escape` +Toggle render running / paused | {kdb}`Ctrl` + {kbd}`\` ### Crop window tool ### diff --git a/python/GafferSceneUI/InteractiveRenderUI.py b/python/GafferSceneUI/InteractiveRenderUI.py index f601f77125..40d993c9a6 100644 --- a/python/GafferSceneUI/InteractiveRenderUI.py +++ b/python/GafferSceneUI/InteractiveRenderUI.py @@ -189,6 +189,17 @@ def __keyPress( self, widget, event ) : if renderNode is not None : statePlug = renderNode["state"].source() statePlug.setValue( GafferScene.InteractiveRender.State.Paused ) + elif event.key == "Backslash" and event.modifiers == event.modifiers.Control : + renderNode = self._interactiveRenderNode( self.__view ) + if renderNode is not None : + statePlug = renderNode["state"].source() + state = statePlug.getValue() + if state == GafferScene.InteractiveRender.State.Running : + statePlug.setValue( GafferScene.InteractiveRender.State.Paused ) + else : + statePlug.setValue( GafferScene.InteractiveRender.State.Running ) + if isinstance( self.__view, GafferImageUI.ImageView ) : + self.__view.imageGadget().setPaused( False ) ########################################################################## # UI for the state plug that allows setting the state through buttons From 51b2c0e431c3acddec1d47744c13f9a79d23f4fc Mon Sep 17 00:00:00 2001 From: Eric Mehl Date: Tue, 22 Oct 2024 11:19:18 -0400 Subject: [PATCH 3/4] InteractiveRenderUI : Remove errant `;` --- python/GafferSceneUI/InteractiveRenderUI.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/GafferSceneUI/InteractiveRenderUI.py b/python/GafferSceneUI/InteractiveRenderUI.py index 40d993c9a6..90a6a5fed3 100644 --- a/python/GafferSceneUI/InteractiveRenderUI.py +++ b/python/GafferSceneUI/InteractiveRenderUI.py @@ -180,7 +180,7 @@ def __viewPlugDirtied( self, plug ) : def __renderNodePlugDirtied( self, plug ) : if plug.getName() == "state" : - self.__updateLazily(); + self.__updateLazily() def __keyPress( self, widget, event ) : From 92efe5b8f627aab677a4a0828c8da72f8f7b523f Mon Sep 17 00:00:00 2001 From: Eric Mehl Date: Tue, 22 Oct 2024 11:55:24 -0400 Subject: [PATCH 4/4] InteractiveRenderUI : Unpause viewer on play press --- Changes.md | 1 + python/GafferSceneUI/InteractiveRenderUI.py | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Changes.md b/Changes.md index c8498050ba..61c72c6890 100644 --- a/Changes.md +++ b/Changes.md @@ -21,6 +21,7 @@ Improvements - InteractiveRenderer : - Added Esc hotkey handling to pause an interactive render. This is in addition to the existing behavior of pausing the image viewer. - Added Ctrl + \ hotkey handling to toggle the interactive renderer between paused and running. If the new state is `Running`, the image viewer will also be unpaused. + - Starting or unpausing the render using the viewer control play button will also unpause the image viewer. Fixes ----- diff --git a/python/GafferSceneUI/InteractiveRenderUI.py b/python/GafferSceneUI/InteractiveRenderUI.py index 90a6a5fed3..1cf7031855 100644 --- a/python/GafferSceneUI/InteractiveRenderUI.py +++ b/python/GafferSceneUI/InteractiveRenderUI.py @@ -96,7 +96,7 @@ def __init__( self, view, **kwargs ) : with GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Horizontal, spacing = 4 ) : GafferUI.Spacer( imath.V2i( 1, 1 ), imath.V2i( 1, 1 ) ) self.__label = GafferUI.Label( "Render" ) - self.__stateWidget = _StatePlugValueWidget( None ) + self.__stateWidget = _StatePlugValueWidget( None, view ) self.__messagesWidget = _MessageSummaryPlugValueWidget( None ) self.__view = view @@ -207,7 +207,7 @@ def __keyPress( self, widget, event ) : class _StatePlugValueWidget( GafferUI.PlugValueWidget ) : - def __init__( self, plug, *args, **kwargs) : + def __init__( self, plug, view = None, *args, **kwargs) : row = GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Horizontal ) GafferUI.PlugValueWidget.__init__( self, row, plug ) @@ -236,6 +236,7 @@ def __init__( self, plug, *args, **kwargs) : } self.__state = None + self.__view = view def _updateFromValues( self, values, exception ) : @@ -257,6 +258,8 @@ def __startPauseClicked( self, button ) : # Not enabling undo here is done so that users won't accidentally restart/stop their renderings. if state != GafferScene.InteractiveRender.State.Running: self.getPlug().setValue( GafferScene.InteractiveRender.State.Running ) + if isinstance( self.__view, GafferImageUI.ImageView ) : + self.__view.imageGadget().setPaused( False ) else: self.getPlug().setValue( GafferScene.InteractiveRender.State.Paused )