Exploring menu changing button state & button sending menu value: menu turns on other buttons & button resets menu?

Hi there!

I'm continuing to learn and grow as I use this program, and have a question for a sound board application I'm building (see JSON files below with examples):

I have a menu item with different values associated in its menu:
Screen Shot 2022-05-17 at 7.20.10 PM

Below it I have a toggle button.
Screen Shot 2022-05-17 at 7.24.50 PM

Here is what I am trying to achieve:

  1. When I select one of the menu items, send the value associated with the label over MIDI (i.e. [3, 11, 127]),
  2. Automatically set the state of the button below it to On (127 in this case)
  3. When desired, I would like to be able to click the button to its 'off' state, sending the value of the menu item, but with a different 3rd 'option' (i.e. [3, 11, 64]), then
  4. When desired, I would like to be able to click the button again into its 'on' state and send the original menu value (i.e. [3, 11, 127]).
  5. If I change the menu to another menu item, the same behavior should repeat (send menu item value [X, X, 127], set button state to on, make possible to tap button and turn it off, sending value [X, X, 64].

I've tried this two different ways below:

  1. Attempt 1:
    all on bug example.json (113.6 KB)
    Issues with this attempt:
  • multiple buttons turn on when menu's onValue: send('button_XX', 127) is activated.
  • while it allows sending [X, X, 64] when button tapped to 'off' position, it can't inherit the original value [X, X, 127] to be able to trigger the 'on' value again.
  1. Attempt 2:
    button reset menu example.json (23.9 KB)
    This attempt seems closer, but has the following major issue:
  • when button turned 'off', it resets the menu and therefore loses the [X, X, 127] value; some JS was added to circumvent this but it's still not working as intended

The practical application:
I use the menu widget to activate audio clips in Ableton Live. I want to be able to have it so that when a new menu item is selected, it triggers the clip and turns the start/stop button to 'on' so that it's visible which track is playing. Then I'd like to be able to stop and restart the clip from the start/stop button.

Hope this is well explained and helps for anyone trying to problem solve with me!

I've discovered what I think is the bug inside "attempt 2" above with the button auto-resetting:

I added the following code to the menu item. An example of the menu value is [ 3, 11 ]

var valueArray = get(this)
send('/note', valueArray[0], valueArray[1], 127)

After changing the menu's value (to say, [ 3 , 12]) the button resets to nothing and the following error occurs in the OSC launcher:

(ERROR, MIDI) Traceback (most recent call last):
  File "midi.py", line 268, in 
  File "midi.py", line 235, in send_midi
IndexError: list index out of range

and the following shows in the console:

| dropdown_5.onValue javascript error at line 6: TypeError: Cannot read properties of undefined (reading '0')

Line 6 is the send command above.

Why would the button auto-reset itself like this? Is this a bug, @jean-emmanuel ?

Hello,

I took a look at your first attempt and made some changes/optimizations:

  • working with only two menus to keep it simple and as a format to follow, naming widgets accordingly;
  • removed Menus OSC configuration, because the Menus won't send MIDI, they just activate buttons;
  • added default values for the menus, to avoid any MIDI error;
  • added 0 as default value to buttons;
  • changed on and off values of buttons to 127 and 0 (makes more sense to me 0 as off);
  • removed the 127 value from the menus option. This value will be sent by the button itself when set to on;
  • added dynamic preArgs for the "start-stop" buttons, so they can send the MIDI preArgs that are selected in the menu;

menu_button_interaction.json (38.1 KB)

Hope it helps,
Cheers

Thanks so much, @ClelsonLopes !

The issue I'm having with this version is that the menu doesn't update correctly. When selecting a menu item, it seems it sends the previously selected menu item's value. So in this case:

  • theme opens with button set to 'Submarine', [ 3, 1 ]
  • when I change to another menu item, say 'Rising', [ 3, 2 ], it sends the previous menu item's value of [ 3 ,1 ]
  • if I select the same menu item again ('Rising' in this case), then it send the correct value

I don't know what would need to be changed to have the preArgs value in the button update before the menu sends 127 to it. Any ideas? I'm still learning JS so a bit confused about the order of things. Would it be having an argument before the send argument that updates @{misc_menu} so that the preArgs are accurate for the now-selected menu item?

Oh, true.
So the menu's script is running before the buttons' preArgs are changed.
So it seems this is the order OSC is doing its thing.
We can add a delay to the menu's script wrapping that set function in a setTimeout(), like so:

setTimeout(() => set('misc_start-stop', 127))

That did it!! Thanks so much! I don't know a ton about setTimeout — does the () mean certain number of ms before the set function is activated? Why wouldn't we need to specify the timeout length?

Thanks so much @ClelsonLopes, you're the best!!

Last question!

When loading the JSON, it seems the buttons automatically load in the 'on' position, even if I set their default value to the 'off' value (in this case, 64). I'm guessing this is due to the menu widget changing as it loads? Any way to make it so that they load in the 'off' state?

I tried adding to onCreate the following, but it didn't work: set(this, 127)

Yeah, you can add the amount of ms to execute the callback function, but in this case it's not needed, meaning it'll execute in the "next" cycle".

Weird, this doesn't happen in the example I uploaded in the previous reply.
Make sure the button's off value is the same as its default one.

Odd, I had done that before but when reloading it worked! Funny :blush: Thanks so much again, my friend and I were getting so frustrated trying to figure this out! I learned a lot from trying and from your solution!

Ah no, sadly the issue persists.

At load, on PC it's perfect:

However after loading on PC then opening server on iPad it's the opposite of what I want (except for one menu???):

And another odd thing is that the code in the button widget's CSS to have the start-stop button flash when on:

@keyframes flash {
    0% {--alpha-fill-on:0.50;}
    100% {--alpha-fill-on:1;}
}

:host.on {
  animation: flash 1s steps(2) infinite;
}

...only seems to activate on the PC and not on the iPad...

So many odd bugs, what's happening here?

If you have the client opened, and opens the session in a new client, this issue happens. It seems that once the session is open, it's listening for messages, then loading a new session makes the widgets with the same id, when setting their default values, trigger the already opened widgets. If you open only one client, then it's fine.

Just replace --alpha-fill-on with opacity and it works fine.

@keyframes flash {
    0% {opacity: 0.50;}
    100% {opacity: 1;}
}

:host.on {
  animation: flash 1s steps(2) infinite;
}

As always, huge thanks on this @ClelsonLopes !

How do I do this? When I hit 'start' in the OSC initial window, it always opens an iteration on my PC... then I need to still open the server on my iPad. Is there a method for only starting the server and not loading the editor/client on the PC?

This worked perfectly, thanks!!

There is an option in the server configuration called no-gui. This prevents the built-in client to open when server is started.

1 Like

Amazing!! So simple. Thank you!