So, recently I stumbled upon a djx blog blost about custom hotkeys and marking menus in different editors in maya. I had been thinking about having a custom hotkey marking menu, but was never really sure how to approach this, so after reading that post I thought I’d give it a go and share my process.
tl;dr: We can create a runtime command which builds our marking menu and have a hotkey to call that command. Thus, giving us the option to invoke custom marking menus with our own custom hotkeys, such as Shift+W or T for example, and a mouse click.
Disclaimer: I have been having a super annoying issue with this setup, where the “release” command does not always get called, so the marking menu is not always deleted. What this means is that if you are using a modifier like Shift, Control or Alt sometimes your marking menu will still be bound to it after it has been closed. Therefore, if you are using something like Shift+H+LMB, just pressing Shift+LMB will open it up, so you lose the usual add to selection functionality. Sure, to fix it you just have to press and release your hotkey again, but it definitely gets on your nerve after a while.
If anyone has a solution, please let me know.
I have written about building custom marking menus in Maya previously, so feel free to have a look as I will try to not repeat myself here. There I also talked about why I prefer to script my marking menus, instead of using the Marking menu editor, and that’s valid here as well.
So, let us have a look then.
The first thing we need to do is define a runTimeCommand, so we can run it with a hotkey. That is what happens if you do it through the Marking menu editor and set Use marking menu in to Hotkey Editor, as well.
There a couple of ways we can do that.
On the right hand side of the hotkey editor there is a tab called Runtime Command Editor. If you go on that one you can create and edit runTime commands.
Scripting it in Python
If you have multiple marking menus that you want to crate, the hotkey editor might seem as a bit of a slow solution. Additionally, if changes need to be made I always find it more intuitive to look at code in my favourite text editor (which is sublime by the way).
To create a runTime command we run the
runTimeCommand function which for some reason does not appear in the Python docs, but I’ have been using
All we need to provide is a
name for the command, some annotation –
ann, a string with some code –
c and a language –
Here is an example
mc.runTimeCommand("exampleRunTimeCommand", ann="Example runTime command", c=commandString, cl="python")
Something we need to keep in mind when working with runTime commands is that we cannot pass external functions to them. We can import modules and use them once inside, but I cannot pass a reference to an actual function to the
c flag, as I would do to
menuItems for example. That means that we need to pass our code as a string.
Press and release
Now, that we know how to create the
runTimeCommands let us see what we need these commands for.
As I mentioned, they are needed so we can access them by a hotkey. What that hotkey should do is initialize our marking menu, but once we release the key it should get rid of it, so it does not interfere with other functions. Therefore we need two of them – Press and Release.
Let us say we are building a custom hotkey marking menu for weight painting. In that case we will have something similar to the following.
mmWeightPainting_PressrunTimeCommand – to initialize our marking menu
mmWeightPainting_ReleaserunTimeCommand – to delete our marking menu
The way we bind the release command to the release of a hotkey is by pressing the small arrow to the side of the hotkey field.
The Press command
import maya.cmds as mc # Optional if it is already imported name = "mmWeightPainting" if mc.popupMenu(name, ex=1): mc.deleteUI(name) popup = mc.popupMenu(name, b=1, sh=1, alt=0, ctl=0, aob=1, p="viewPanes", mm=1) import mmWeightPainting reload(mmWeightPainting)
So, essentially what we do is every time we press our hotkey, we delete our old marking menu and rebuild it. We do this, because we want to make sure that our latest changes are applied.
Now, the lower part of the command is where it gets cool, I think. We can store our whole marking menu build – all
menuItems – inside a file somewhere in our
MAYA_SCRIPT_PATH and then just import it from the
runTimeCommand as in this piece of code. What this gives us, is again, the ability to really easily update stuff (not that it is a big deal with marking menus once you set them up). Additionally, I quite like the modularity, as it means we can have very simple
runTimeCommands not cluttered with the actual marking menu build. This is the way that creating through the Marking menu editor works as well, but obviously it loads a
MEL file instead.
So, literally that
mmWeightPainting file is as simple as creating all our marking menu items.
import maya.cmds as mc mc.menuItem(l="first item") mc.menuItem(l="second item") mc.menuItem(l="North radial position", rp="N") ...
And that takes care of building our marking menu when we press our hotkey + the specified modifiers and mouse button. What, we do not yet have is deleting it on release, so it does not interfere with the other functionality tied to modifier + click combo. That is where the
runTimeCommand comes in.
The Release command
## mmWeightPainting_Release runTimeCommand name = "mmWeightPainting" if mc.popupMenu(name, ex=1): mc.deleteUI(name)
Yep, it is a really simple one. We just delete the marking menu, so it does not interfere with anything else. Essentially, the idea is we have it available only while the hotkey is pressed.
All that is left to be done is to assign a hotkey to the commands. There are a couple of things to have in mind.
If you are using modifiers for the
popupMenu command –
alt – then the same modifiers need to be present in your hotkey as otherwise, even though the
runTimeCommand will run successfully, the
popupMenu will not be triggered.
In the above example
mc.popupMenu(name, b=1, sh=1, alt=0, ctl=0, aob=1, p="viewPanes", mm=1)
we have specified the
sh modifier. Therefore, the Shift key needs to be present in our hotkey.
Also, obviously be careful which hotkeys you overwrite, so you do not end up causing yourself more harm than good.
That’s it, it really is quite simple, but it helps a lot once you get used to your menus. Honestly, trying to do stuff without them feels so tedious afterwards.