SideFX Houdini customization package
git clone https://git.lucas.co/hou-control.git
keycam: refit the aspect ratio on LayoutChanged
Houdini's own ctrl+1..4 layout hotkeys raise SizeChanged and
LayoutChanged while the viewports still have their old size; they are
resized one event-loop tick later with no further event. Keycam only
refitted on SizeChanged, so it fitted the stale size and was left one
layout behind. Defer the fit from LayoutChanged instead; keycam's own
layout actions ride on the same event and lose their private deferrals.
Co-Authored-By: Claude Opus 5 <[email protected]>
viewer_states/keycam.py | 37 ++++++++++++++++---------------------
1 file changed, 16 insertions(+), 21 deletions(-)
diff --git a/viewer_states/keycam.py b/viewer_states/keycam.py
index 441d853..38888d5 100644
--- a/viewer_states/keycam.py
+++ b/viewer_states/keycam.py
@@ -110,6 +110,20 @@ class State(object):
if event_type == hou.sceneViewerEvent.SizeChanged:
self.cam.fitAspectRatio()
self.guides.update()
+ elif event_type == hou.sceneViewerEvent.LayoutChanged:
+ # A layout change (ctrl+1..4, or keycam's own layout actions)
+ # raises SizeChanged and LayoutChanged while the viewports still
+ # have their old size; they are resized one event-loop tick later
+ # with no further event, so fit from there.
+ state = self
+
+ def _deferredFit():
+ state.cam.fitAspectRatio()
+ state.guides.update()
+ hou.ui.removeEventLoopCallback(_deferredFit)
+ return False
+
+ hou.ui.addEventLoopCallback(_deferredFit)
def onKeyEvent(self, kwargs):
"""Keys are now handled via PluginHotkeyDefinitions and onMenuAction."""
@@ -218,7 +232,7 @@ class State(object):
'trans_up': self.cam.translateUp,
'trans_down': self.cam.translateDown,
'toggle_proj': self.cam.toggleProjection,
- 'cycle_layout': self._cycleLayoutWithAspectFit,
+ 'cycle_layout': self.scene_viewer.nextLayout,
'set_layout_single': lambda: self._setLayout('Single'),
'set_layout_doubleside': lambda: self._setLayout('DoubleSide'),
'set_layout_doublestack': lambda: self._setLayout('DoubleStack'),
@@ -260,28 +274,9 @@ class State(object):
self.cam.setView()
return True
- def _cycleLayoutWithAspectFit(self):
- self.scene_viewer.nextLayout()
- state = self
-
- def _deferredFit():
- state.cam.fitAspectRatio()
- hou.ui.removeEventLoopCallback(_deferredFit)
- return False
-
- hou.ui.addEventLoopCallback(_deferredFit)
- return True
-
def _setLayout(self, layout_name):
+ # The aspect refit rides on the LayoutChanged event (_onViewerEvent).
self.scene_viewer.setLayout(layout_name)
- state = self
-
- def _deferredFit():
- state.cam.fitAspectRatio()
- hou.ui.removeEventLoopCallback(_deferredFit)
- return False
-
- hou.ui.addEventLoopCallback(_deferredFit)
return True
def onMenuPreOpen(self, kwargs):