sliders and buttons control panel with presets

Here’s a pretty useful little UI component that creates a control panel with sliders and buttons as well as a preset system.

The gadgets attributes can be defined in one table or within each gadget. Presets can then be recalled or stored for the entire control panel.


I’ve added a new button gadget that can be a number of different types of buttons. It hasn’t been test very thoroughly yet so if anyone finds any problems, I’ll be happy to fix them.

ControlPanelWithPresets.toe (35.1 KB)
SlidersWithPresets.toe (14.2 KB)

1 Like

Thanks Keith! love it :slight_smile:

Cool, this is a nice easy setup. So you don’t have to keep track of the wires, I’d replace the Merge CHOP with a Select CHOP and a pattern to get all the channels (like */out1)

Good call Greg, that would be even cleaner.


This is really handy, thanks!

No problem! I’ve just uploaded a newer version that also has buttons.

Hey, this is awesome Keith, thanks! Happy it supports an external input too, so I can use my grab bag of controllers :ugeek:

The obvious tweaks for me - which you may have done already in your new cool tool - a fade time for preset recalls (tween the value based controls) and a preset name field.


Thanks for sharing this, Kieth!

I made a small edit, so that it can make sense of floats/negatives/empty cells in the setUpGadgets table. Before, using isdigit(), any cell with a ‘-’ or ‘.’ in it’s value would fail to be written as a float, or passed over altogether by the replicator, so only positive integers worked for range, default, etc.

In ‘…/controlPanel/repScriptSlider’ and ‘…/controlPanel/sourceGadgets/slider/datexec1’ I swapped the: if value.isdigit(): value = float(value) else: value = somethingelse for: try: value = float(value) except ValueError: value = somethingelse

Also there same thing is happening next door to the buttons, and the default ‘-1’ is being written to the Attr as a str. Does default do anything for the buttons?
ControlPanelWithPresets.25.toe (35.6 KB)

Yeah I found that bug a while back as well. Forgot to update the online version. I have a function that I use in a bunch of places called setToType that I put in there. It takes care of all data types.

I can’t remember for sure but I think the -1 is in the button so it when it is in exclusive mode then all buttons are off.

I’ve also found some other problems when updating the master createGadgets table that have also been fixed. When I have some time in the near future I’ll make sure the new one is working properly and post it.


came up here to this fantastic tool, thanks Keithlostracco,
I’m messing around trying to control externally the preset radio button but when going inside the object I can’t see any CHOP, just DATs and can’t figure out how to control it from for example an external MIDI device or just from a Constant CHOP,
would be super useful!

The re-call is happening here in /project1/sliderBank/presets. Recalling a preset happens when you left click on a button. This runs a script in /project1/sliderBank. Left click calls the text DAT called recallPreset, right clicking calls the text DAT called storePreset.

'This takes an arg that’s the cell over id + 1. You can call this same script like this:

recallVal = 2 op('sliderBank/recallPreset').run(recallVal)

Similarly you could create / store a preset this way with

storeVal = 2 op('sliderBank/storePreset').run(storeVal)

Perfect thanks Matt.

If you want the radio button to be visually updated as well you can set

op('presets/radio/cellId')[0, 0] = presetIndex

thanks all,

I’m pretty stuck with that,
I’ve created my constant1 Chop with just one channel to control recallVal,
I’ve created my text DAT with the following script inside
everything works by entering a specific number after recallVal and ctlr+r,
but nothing happens when I hit ctrl+r to run the script with the
op TD module instead of the number,

recallVal = op( 'constant1' )[ 'chan1' ]


any further hint is appreciated!

Hey vertexshining - can you post a tox with what you’re stuck with? These things are usually easier to sort out when you can see what someone is up to.


I’ve basically tried out three ways

Attempt 1: is the only one working, and my base point. Changing the number & running the script recall the expected preset values

Attempt 2: tried to make the recallVal variable “dynamic” and controller by a chop but not working

Attempt 3: tried to use a CHOP Execute to change recallVal but doesn’t working.

It’s pretty evident I am missing something essential
RecallVal.3.tox (14.3 KB)

Sorry for the delay in responding, I was on a plane. :slight_smile:

The tox you posted doesn’t seem to have anything inside of it when I try to open it up - can double check the version that’s uploaded to make sure it’s working for you?

sorry raganmd,

this should work fine :slight_smile:
have a nice trip!
RecallVal_bueno.tox (11 KB)

I see two issues in this example that I think should help you resolve the issue:

The first to consider is that 0 is not a valid entry - if you look at the storage keys you’ll see that the presets all start at 1 - preset1, preset2, etc.

Looking closely at the recall script we can see that we’re joining the word “preset” with an integer in order to reconstruct the string that we’re using as a key.

The second, and probably more important thing to know / think about, is that chops are floats. So while it may look like an integer to you, under the hood it’s evaluated as a a float… so 1 becomes 1.0. Subsequently you end up with a key that’s preset1.0, which doesn’t have a match in the dictionary.

If you cast your chop channel to an integer first, it looks like things all work as expected:

[code]# attempt 2: doesn’t working

this should grab the chan1 from constant1 chop

but doesn’t seems to work

recallVal = int(op( ‘constant1’ )[ ‘chan1’ ])



Does that all make sense?

yes it’s clear and working!
Now I’m trying to make it work inside the Exec Chop

Nice work, could you upload the file with all the improvements until now? Thank you!