I'd like one of my HDA's to execute some custom code whenever it is clicked/double clicked.
In Type Properties>Scripts, I see we can handle events like "On Created" or "On Deleted", as pictured in my screen cap.
But can we handle events like clicking/dragging?
Custom onClick handler for HDA
1414 6 0- wyhinton1
- Member
- 61 posts
- Joined: Feb. 2020
- Offline
- wyhinton1
- Member
- 61 posts
- Joined: Feb. 2020
- Offline
After more investigation I see several additional event types are covered for nodes via the hou.nodeEventType [www.sidefx.com] class...while several events not covered in the Event Handler drop down I posted earlier are covered here, I still don't see anything for custom handling of click or double click events...
Suprisingly, nothing in hou.NetworkMoveableItem [www.sidefx.com] either regarding handling clicks.
I'm imaging that there must be some code somewhere which defines click behavior for different network items. Say, when a sticky note is clicked vs when a subnetwork is clicked.
Any thoughts on where I might find that code?
Suprisingly, nothing in hou.NetworkMoveableItem [www.sidefx.com] either regarding handling clicks.
I'm imaging that there must be some code somewhere which defines click behavior for different network items. Say, when a sticky note is clicked vs when a subnetwork is clicked.
Any thoughts on where I might find that code?
Edited by wyhinton1 - Sept. 26, 2022 20:02:31
- tamte
- Member
- 8449 posts
- Joined: July 2007
- Offline
- wyhinton1
- Member
- 61 posts
- Joined: Feb. 2020
- Offline
tamte
https://www.sidefx.com/docs/houdini/hom/network.html [www.sidefx.com]
Thanks, that's exactly what I needed!
- wyhinton1
- Member
- 61 posts
- Joined: Feb. 2020
- Offline
I think the docs [www.sidefx.com] are outdated?
The example in "Extending the Node Editor" says to add the example code to
I assume they mean
I tried editing
Saving the file and restarting Houdini, and I'm not getting anything to print. I tried copy-pasting the "Ctrl+Shift+H" example from the docs as as well, and it doesn't seem to work either.
Am I doing something wrong here? It seems like these new event handlers are not being correctly registered?
The example in "Extending the Node Editor" says to add the example code to
$HOUDINI_USER_PREF_DIR/python2.7libs/nodegraphhooks.py
. I assume they mean
$HOUDINI_USER_PREF_DIR/python3.7libs/nodegraphhooks.py
. I tried editing
nodegraphhooks.py
to do a simple print statement:# inside nodegraphhooks.py def createEventHandler(uievent, pending_actions): print(uievent) return None, False
Saving the file and restarting Houdini, and I'm not getting anything to print. I tried copy-pasting the "Ctrl+Shift+H" example from the docs as as well, and it doesn't seem to work either.
Am I doing something wrong here? It seems like these new event handlers are not being correctly registered?
Edited by wyhinton1 - Sept. 29, 2022 16:47:16
- wyhinton1
- Member
- 61 posts
- Joined: Feb. 2020
- Offline
Looking at an example from the Marking Menue's nodegraphhooks.py helped me figure it out. Here's what I ended up with:
Note that I thought that there was a type for a "doubleclick" for uievent.eventtype...however I could never seem to get this event to trigger? I just ended up checking for a middle mouse down on the object merge node instead of a doubleclick.
def buildObjectMergeClickHandler(uievent, pending_actions): import nodegraph # to avoid circular imports class ObjectMergeClickHandler(nodegraph.NodeMouseHandler): def handleEvent(self, uievent, pending_actions): if isinstance(uievent, MouseEvent): obj_merge_node = uievent.selected.item obj_parm = obj_merge_node.parm("objpath1") rel_path = obj_parm.eval() referenced_node = obj_merge_node.node(rel_path) if referenced_node is not None: center_node(referenced_node) return None return nodegraph.NodeMouseHandler.handleEvent( self, uievent, pending_actions) return ObjectMergeClickHandler(uievent) def createEventHandler(uievent, pending_actions): if isinstance(uievent, MouseEvent) and uievent.eventtype == 'mousedown' and \ uievent.mousestate.mmb and \ isinstance(uievent.selected.item, hou.Node) and \ uievent.selected.item.type().name() == "object_merge" : if uievent.selected.item is not None: b = buildObjectMergeClickHandler(uievent, pending_actions) return b, True else: return None, False
Note that I thought that there was a type for a "doubleclick" for uievent.eventtype...however I could never seem to get this event to trigger? I just ended up checking for a middle mouse down on the object merge node instead of a doubleclick.
- animatrix_
- Member
- 4460 posts
- Joined: Feb. 2012
- Online
wyhinton1
Looking at an example from the Marking Menue's nodegraphhooks.py helped me figure it out. Here's what I ended up with:def buildObjectMergeClickHandler(uievent, pending_actions): import nodegraph # to avoid circular imports class ObjectMergeClickHandler(nodegraph.NodeMouseHandler): def handleEvent(self, uievent, pending_actions): if isinstance(uievent, MouseEvent): obj_merge_node = uievent.selected.item obj_parm = obj_merge_node.parm("objpath1") rel_path = obj_parm.eval() referenced_node = obj_merge_node.node(rel_path) if referenced_node is not None: center_node(referenced_node) return None return nodegraph.NodeMouseHandler.handleEvent( self, uievent, pending_actions) return ObjectMergeClickHandler(uievent) [quote=wyhinton1]Looking at an example from the Marking Menue's nodegraphhooks.py helped me figure it out. Here's what I ended up with: [code python] def buildObjectMergeClickHandler(uievent, pending_actions): import nodegraph # to avoid circular imports class ObjectMergeClickHandler(nodegraph.NodeMouseHandler): def handleEvent(self, uievent, pending_actions): if isinstance(uievent, MouseEvent): obj_merge_node = uievent.selected.item obj_parm = obj_merge_node.parm("objpath1") rel_path = obj_parm.eval() referenced_node = obj_merge_node.node(rel_path) if referenced_node is not None: center_node(referenced_node) return None return nodegraph.NodeMouseHandler.handleEvent( self, uievent, pending_actions) return ObjectMergeClickHandler(uievent) def createEventHandler(uievent, pending_actions): if isinstance(uievent, MouseEvent) and uievent.eventtype == 'mousedown' and \ uievent.mousestate.mmb and \ isinstance(uievent.selected.item, hou.Node) and \ uievent.selected.item.type().name() == "object_merge" : if uievent.selected.item is not None: b = buildObjectMergeClickHandler(uievent, pending_actions) return b, True else: return None, False [/code] Note that I thought that there was a type for a "doubleclick" for uievent.eventtype...however I could never seem to get this event to trigger? I just ended up checking for a middle mouse down on the object merge node instead of a doubleclick.[/quote] def createEventHandler(uievent, pending_actions): if isinstance(uievent, MouseEvent) and uievent.eventtype == 'mousedown' and \ uievent.mousestate.mmb and \ isinstance(uievent.selected.item, hou.Node) and \ uievent.selected.item.type().name() == "object_merge" : if uievent.selected.item is not None: b = buildObjectMergeClickHandler(uievent, pending_actions) return b, True else: return None, False
Note that I thought that there was a type for a "doubleclick" for uievent.eventtype...however I could never seem to get this event to trigger? I just ended up checking for a middle mouse down on the object merge node instead of a doubleclick.
I also had some issues with double click I think, it was long ago, have to double check.
I customize this module extensively also. You can also use modifier keys to further customize behaviour:
def createEventHandler(uievent, pending_actions): if not isinstance(uievent.editor, hou.NetworkEditor): return None, False if uievent.eventtype == 'mousedown' and uievent.selected.item is None: hou.session.networkEditorVisibleBounds = uievent.editor.visibleBounds() hou.session.mouseDownEventTime = uievent.time return CustomBackgroundMouseHandler(uievent), True if getSessionVariable("useRMBToSelectDisplayNodes") and uievent.eventtype == 'mousedown' and uievent.mousestate.rmb: node = uievent.selected.item category = node.type().category().name() if category in hou.nodeTypeCategories().keys() and category != "Vop": if uievent.modifierstate.ctrl: if uievent.modifierstate.shift: utility_generic.selectableTemplateNearestNodeInEditor(nearestNode=node) if uievent.modifierstate.alt: utility_generic.bypassNearestNodeInEditor(nearestNode=node) else: utility_generic.templateNearestNodeInEditor(nearestNode=node) elif uievent.modifierstate.shift: utility_generic.displayNearestNodeInEditor(nearestNode=node) elif uievent.modifierstate.alt: utility_generic.showNodeMenuNearestNodeInEditor() else: utility_generic.selectDisplayNearestNodeInEditor(nearestNode=node) return None, True if isinstance(uievent, KeyboardEvent): key = utility_generic.getUnshiftedKey(uievent.key, uievent.modifierstate) hou.session.spaceKeyIsDown = uievent.editor.isVolatileKeyDown('Space') if uievent.eventtype == 'keyhit': return utility_hotkey_system.invokeActionFromKey(uievent) return None, False
Senior FX TD @ Industrial Light & Magic
Get to the NEXT level in Houdini & VEX with Pragmatic VEX! [www.pragmatic-vfx.com]
youtube.com/@pragmaticvfx | patreon.com/animatrix | animatrix2k7.gumroad.com
Get to the NEXT level in Houdini & VEX with Pragmatic VEX! [www.pragmatic-vfx.com]
youtube.com/@pragmaticvfx | patreon.com/animatrix | animatrix2k7.gumroad.com
-
- Quick Links