Friends, I feel like an idiot.
So many of the posts on this site are about creating custom gizmos to replace the native nodes inside of Nuke. But they've never completely satisfied their mission because, until now, I didn't know how to tell Nuke, "Hey, when I call a FrameHold give me my FrameHold_DS gizmo instead". So my FrameHold_DS gimzo has lived alongside the native FrameHold node since its creation. Which, by the way, is super annoying because it shows up lower in the tab-search results than the native node.
The alternative I've used — to a lesser degree of success — is to customize native nodes with the addOnUserCreate
python function. While that has been effective at adding features to the native nodes, it's entirely python based and results in all my customizations being banished to a properties tab named "User". Just the sight of which makes me sad.
The good news is, I have finally figured out how to actually tell Nuke "Hey, when I call a FrameHold give me my FrameHold_DS gizmo instead". The bad news is, it's so incredibly, stupidly easy, I can't believe it took me this long to figure it out.
I was reading the Assigning a Hotkey section of the "Customizing the UI" python guide and saw this:
To assign a hotkey to an existing menu item, you effectively replace the whole menu item.
Let’s assign a hotkey to the Axis2 node.
nuke.menu( 'Nodes' ).addCommand( '3D/Axis', nuke.createNode( 'Axis2' ), 'a')
Pressing a on the keyboard now creates an Axis node.
I've known for a long time that I could add custom hotkeys to nodes, but the tab-search method was always fast enough for me that I've never wanted to do so.
But what caught my eye was the line of code. Before adding the hotkey, it defines the application's menu path to the node, then the createNode
call for the node itself.
I thought to myself, there's no way I could just swap out the node name in the createNode
call with the name of one of my gizmos. It couldn't possibly be that easy.
It is.
By adding the single line of code —
nuke.menu( 'Nodes' ).addCommand( 'Time/FrameHold', "nuke.createNode( 'FrameHold_DS' )")
— to my Menu.py file, calling a FrameHold node will now result in my FrameHold_DS gizmo being added instead.
Now, rather than debating which half-assed method for creating custom nodes is more suited to the tool I'm trying to create, I will create custom gizmos and remap their calls using this method.
I've been wanting to do this for so long. It's a very exciting discovery for me, only slightly overshadowed by feeling like a total doofus for not figuring it out sooner.
Postscript
"But what if I want to be able to call the native node at some point, too?"
Well, I have no desire to do that, but if you do, you could always add a second line of code to rename the native node to something else, like:
nuke.menu( 'Nodes' ).addCommand( 'Time/Dumb-Stupid-Native-FrameHold', "nuke.createNode( 'FrameHold' )")
That way it won't show up when you hit tab and start typing "Fra", but you will be able to find it if you need it.