Simple Right Click Menus in TouchDesigner

Building user interfaces in TouchDesigner has been getting much more interesting over the past year. The release of Widgets have given us a whole new avenue for creating quick and easy user interfaces that have complex functionality and are aesthetically pleasing. There has been one UI element that has alluded many of us for quite some time though: right-click popup menus. There is a lot that goes into creating a right-click popup menu, which is why it’s often recommended against building one from scratch. Well, lucky us, we have one already built and ready to be customized for us! This post will get you setup as quickly as possible with this great tool.

Palette popMenu

This is where we get started. Inside of the TouchDesigner Palette (open with hotkey Alt + L), scroll down and find the UI section in the top left. Then in the bottom left section you’ll see a component called popMenu. Let’s start off by dragging and dropping this into our project:

Now we can go to the parameters of the popMenu and immediately test out to see if this works by clicking the Open pulse button. Whenever you’re working with your UI, until you’ve got some scripting setup, this is the best and quickest way to test out your menu because the viewer in the COMP isn’t always accurate when displaying the UI:

So we’ve got it working but what about customizing the menu??

Setting up your menu

There’s three ways you can approach setting up your menu:

  1. Through the lists and dictionaries in the custom parameters
  2. Through Python scripting
  3. By feeding in a Table DAT input

Today we’re going to look at #1 and #3 as those are the easiest to get setup. Let’s start with #3. Setting up a Table DAT and plugging it in is easy. You just need 1 column with all your menu items inside of it under the header named name. Then we plug it in and watch the magic unfold:

That’s all you need to get started quickly. Unfortunately, the Table DAT input doesn’t allow us to access a lot of the more advanced functionality, but it does get us up and running very quickly. Before we look at the custom parameter setup, let’s quickly access the values!

Accessing the output values

You can get the values pretty easily by plugging in a Null CHOP and a Null DAT to the output connections on the popMenu. When the value changes, both the CHOP and DAT will display what is selected. One important thing to note is that when the menu is opened, it will reset the value until an item is selected:

There are many ways you could use this. For example I could connect a CHOP Execute DAT to the null1 CHOP and write a quick script to change a Switch TOP based on the index:

Inside of the CHOP Execute DAT, I have this script written in the onValueChange() function:

def onValueChange(channel, sampleIndex, val, prev):
	if val >= 0:
		op('switch1').par.index = val
	return

All it does is check if the value is 0 or above, and then writes that value to the Switch TOP index. This way we can avoid the -1 values. You could do a very similar process using a DAT Execute DAT and the table output of the popMenu, as this would allow you to do selections and changes to your network based on the name of the item and it would also help future-proof it against changing the order of the items in the popMenu.

Custom parameters

If you’d like to access a lot of the more advanced functionality and options of the popMenu, then you’ll need to spend a little bit of time with it’s custom parameters or it’s Python methods and members. Start off by unhooking the Table DAT we plugged in, as that overrides the custom parameters. And let’s dive into a few of the parameters. These are really the ones we want to work with on the popMenu:

Each one of these parameters is responsible for activating or deactivating a different state. The first thing you should do is build a list of all of your menu items in the Items parameter. This is a Python list, so it needs to start and end with square brackets ( [ ] ), and each item needs to be surrounded by quotation marks ( ‘ ‘ ), and the items need to be separated by a comma ( , ). If we recreate our example from above but with a few more items, we would enter something like this:

['Butterfly','Banana','Grid', 'Something else!']

From here, all of the other custom parameters are optional states you can enable and disable on the items listed in the Items parameter. For example if I wanted to have Grid highlighted in the menu, I would make a list in the Highlighted Items parameter with only Grid inside of it, like this:

['Grid']

Similarly, if I wanted a dividing line to be added to the menu in-between Grid and Something else!, I could add Grid again to a list for the Dividers After Items parameter:

['Grid']

By now your parameters should like something like this, as you can clear out the other parameters you’re not using:

And then we can test out our menu and see all those extra options added without any further fuss on our part:

Even with just these few simple options, you can create a pretty rich right-click menu without having to go full-tilt into Python!

JOIN THE INTERACTIVE & IMMERSIVE HQ PRO

Want to take your TouchDesigner career to the next level?

The HQ PRO is the only comprehensive TouchDesigner training resource available.

If I’d had access to the tutorials, workshops, coaching and community found in the HQ PRO when I first started with TouchDesigner, I would have hit my career goals years sooner

Accessing your popMenu

We’ve done all this talk about how to set it up and using different aspects of it, but how in the world do you even access this menu from your user interface?? Luckily this is also easy and a lot of the advanced functionality is built into the popMenu component. All we have to do is create a very short script or reference that clicks the Open button in the parameters. Yup! The very same Open button we’ve been using for our testing is actually quite magical. If we click on it from a script or use a reference from a CHOP to pulse it, it will automatically figure out where our mouse is and it will open the menu at the correct location.

Even without Python, it can be as simple as having a Panel CHOP selecting the rselect channel from the Container COMP that will hold your UI, and then drag-and-drop referencing that value on our Open parameter:

That’s it! Just like that, if we right click inside of our Container COMP, we will trigger opening up the popMenu!

Wrap up

This popMenu tool is awesome. I remember starting out in TouchDesigner and wanting to build cool UI’s but always feeling discouraged by how difficult it was to create things that every other app had built in. Now that we’re getting more and more awesome tools released in the Palette, a lot of those hard things are becoming quick and painless. This is especially true with dynamic right click menus in our user interfaces. And we only just scratched the surface of popMenu. It has a rich set of members and methods that can be accessed through Python to create updating menus based on the different factors in your project. I highlight recommend giving it a try across simple and more complex projects!

Reference

If you’re liking the experience of working with the popMenu, here are further resources and links to help you get deeper into customizing and controlling them:

https://docs.derivative.ca/index.php?title=Palette:popMenu

https://docs.derivative.ca/PopMenu_Custom_COMP_Examples