git clone https://git.lucas.co/hou-control.git
hc: trigger navigation fallback if current node is off-screen
python3.11libs/hc/hcnetworkeditor.py | 27 ++++++++++++++++++++++++++-
1 file changed, 26 insertions(+), 1 deletion(-)
diff --git a/python3.11libs/hc/hcnetworkeditor.py b/python3.11libs/hc/hcnetworkeditor.py
index d414be7..4eb4a96 100644
--- a/python3.11libs/hc/hcnetworkeditor.py
+++ b/python3.11libs/hc/hcnetworkeditor.py
@@ -25,11 +25,29 @@ class HCNetworkEditor(HCPathTab):
def _traversalTarget(self, direction, from_node=None):
"""Find the next node via wire traversal from from_node (default: the
- editor's current node). up = first input; down = first output;
+ editor's current node). If no node is current or visible, falls back
+ to the node nearest to the viewport center.
+ up = first input; down = first output;
left/right = cycle through nodes sharing a downstream child (ordered
by x-position)."""
if from_node is None:
from_node = self.hou_tab.currentNode()
+
+ # Check if from_node is visible in the current viewport
+ is_visible = False
+ if from_node is not None:
+ # itemRect returns coordinates in network space
+ # visibleBounds returns the viewport in network space
+ if self.hou_tab.visibleBounds().intersects(self.hou_tab.itemRect(from_node)):
+ is_visible = True
+
+ # Fallback to viewport center if no node is current OR current node is off-screen
+ if from_node is None or not is_visible:
+ nearest = self._nearestNodeToViewportCenter()
+ if nearest:
+ # If the current node was off-screen, the first press brings us to the center
+ return nearest
+
if from_node is None:
return None
@@ -59,6 +77,7 @@ class HCNetworkEditor(HCPathTab):
def navigateDirection(self, direction):
target = self._traversalTarget(direction)
if target is not None:
+ target.setSelected(True)
self.hou_tab.setCurrentNode(target)
self._frameSelectionInView()
self.updateCurrentNodeOverlay()
@@ -213,7 +232,13 @@ class HCNetworkEditor(HCPathTab):
current node no longer matches the anchor."""
parent = self.hou_tab.pwd()
current = self.hou_tab.currentNode()
+
+ # If no current node, find the nearest one to start the selection
if current is None:
+ current = self._nearestNodeToViewportCenter()
+ if current:
+ current.setSelected(True)
+ self.hou_tab.setCurrentNode(current)
return
key = parent.path()