Mutually exclusive buttons & open window

is there a script example of having mutually exclusive buttons?

say two buttons and one can only ever be on at a time and clicking either of them will force the other off?

is there a script example for when you un-bypass a plugin it also opens that plugin’s window?

Search the forum for “radio buttons” and you will find various examples! :wink:
It’s one of my most desired long-term wishes for a future version of GigPerformer, but we can already make this work with scripting.

I would love to have radio buttons in GP for many reasons and use cases, but in your situation why couldn’t you use a single switch widget? (don’t only think of a switch as an ON/OFF widget, à bistable switch can be whatever you want 1/2, a/b, slow/fast, etc…)


In my case I have two buttons and each is bypassing a midiin block with different velocities. I don’t ever need them both to be on or off… just one at a time on-always. I have two buttons now which show me visually which is on of course… but I’d like these to be mutually exclusive to each other or ‘radio buttons’.

OK, here it is… a small gig with just two buttons that work radio-wise.
I hope, this helps… :slight_smile:double_radio_button.gig (5.6 KB)

1 Like

Brilliant @schamass thank you. Works fantastically.

So this is in essence two scripts one for each button, correct? They just both follow the var line?

I think in reading the script I understand what all the syntax is doing but what I don’t follow is what “double” means. Would love to learn that.

1 Like

It’s all in the manual.

Take the time to study the scripts you’ve been given already and really get a firm understanding why they work the way they do. Make learning it’s own priority, rather than simply moving onto the next thing you want to do. You get a lot more out of it, and will probably figure out most of these things on your own.

A “script” always consists of diffrent “blocks” which have a certain functionality, but it is always handled as “a whole”.
The first block is the definition of “global” variables (that’s the “var”), where i say which variables i use in my script (here just two widgets, but there are many other types of variables).
When i say “global” it means that those variables are available (read and write value into them) for each of the separate “code blocks”. Those global variables have to be defined at the start of the script.

Then there are two so called “call backs” - these are routines that are automatically called when a certain thing is happening in GP. Here those routines are always “called” when the value of a widget has changed its value (we use buttons, so they can be 0=OFF or 1=ON).

If you enter the Edit mode for your panel and you look at the “advanced” tab of a widgets properties, you can see that i named those two buttons with the same names that i used for the variables in the script. If you enter a name here, then it makes this widget available for the use in a script (no name, no script!) - and the names of the widgets and the variables must correlate!

So coming back to these “callbacks” in the script:
Each one of those is for the corresponding widget (you can see there is a “from” term in the first callback-line - this says “from” which widget this callback is triggered. The other element in the first callback line is a local variable of the type “double”. The name of the variable is freely chooseable (i used ‘bval’ for a short version of ButtonValue, caus the value comes from a button, but i could have named it “Igor” and it would work too). The ‘type’ (double) of that variable is required and is given by the type of the callback (or a function in general) - you can read this in the documentary.
The type “double” means, that this variable will hold a numeric value that is handled as a floating point value and it will be able to hold numbers up to 19 digits long. There are many other types for variables:

But GPScript is NOT C! (I just used this link because of the nice table of data types) :slight_smile:

OK, this variable holds then the new value that the widget has gotten.
If the button was switchend ON then this callback would have a value of 1 into the variable ‘bval’ or if it was switched of, ‘bval’ would have the value 0.

And this value is what i am testing for with the “If” clauses.
This is the callback for the button #2

On WidgetValueChanged (bval: double) from btn_vel2
    If bval == 1.0 Then
        SetWidgetValue(btn_vel1, 0)
    Elsif bval == 0 and GetWidgetValue (btn_vel1) == 0 Then
        SetWidgetValue(btn_vel2, 1)

This means, if the button #2 is switched ON (bval=1) then button #1 will be switched off (SetWidgetValue (btn_vel1,0)).
The callback for button #1 does the same but vice versa.

So this would already work in most cases, but what will hapen if a button is switched ON and you switch it OFF? Then both buttons would be OFF and what about your velocity selection then? :wink:
This exception leads to the additional clause in the line with “Elsif”, which handles a second condition that is not just the opposite of the first one.

Here i had to test for two other conditions at once/combined.
So it’s testing for itself (button #2) being switched OFF (bval=0) ‘and’ (at same time) if button #1 is also switched off - and if both conditions are true then it will just switch itself ON again.
And now you can’t switch an active button off anymore, and the script should be working safely.


@schamass Excellent tutorship!


This is an invaluable explanation of not only the script you wrote but also the fundamentals of scripts that is very easy to understand. It explains the why? which I appreciate. I hope others find the same value in this. Perhaps this should the in the manual :wink:

Many thanks!

I have been studying the scripts I currently use closely to deconstruct them. Starting from the standpoint of no background in scripting, frankly not much about this is intuitive.

While the manual does reference things like setting plugin handles and naming widgets, it doesn’t necessarily explain that step by step in the scripting manual or cross referenced to other parts of the manual, so there is a fair amount that has to be discovered on ones own. The scripting manual assumes a fair amount IMO.

Necessity (or want) of a feature is the mother of learning for me. I tried to read the manual cold and it was not my cup of tea but now that I see where these examples apply to my creative needs, I am learning more.


Is there a way to add a modifier key to a button action where by holding down option runs a script but not holding option doesn’t?

What are you trying to accomplish? In general one needs a script to react as fast as possible to an event so adding extra tests before a script can run doesn’t seem like a good ideas

My button right now does two things, it un-bypasses/bypasses and it opens the plugin window. I would like the second function to be optional by holding a modifier key when I want that to happen and otherwise, it only does the bypass toggle.

So why can’t you use the ModifierKeys() function?

1 Like

that’s what I am after, thanks.

Ok… I hacked at this a good while but not coming up with something that will compile.
The ModiferKeys() is a function but does it need to be defined as a var?
I have this so far, not working of course… right now the syntax error is “If is expecting End”.
This is only one of many things I have attempted.


    btn_b3x : widget
    B3X : PluginBlock

On WidgetValueChanged (btval : double) from btn_b3x
    If btval > 0.5
    ElsIF ModifierKeys(true)
        then OpenPlugin(B3X)
        Else ClosePlugin(B3X)

The goal here is to only have this script do anything if the modifer key is held down but I am unclear on how to define what modifier key that is (var?) and since the function returns the state, how to make that function act as the variable that allows/disallows the OpenPlugin/ClosePlugin to pass through.

The function as defined takes no parameters and returns an integer that represents the state (up or down) of the various modifier keys. So it makes no sense to pass the argument ‘true’ into it nor to test whether its result is ‘true’

Try instead…

 if ModifierKeys() == 1  // 1 means the SHIFT key
    then ...


1 Like

I guess you could check the corresponding Integer values by printing the ModifierKeys() out to the log window?
But if the keys and values were mentioned in the documentation it would be even better.

1 Like

Thank you @dhj This now works using the shift key:

 On WidgetValueChanged (btval : double) from btn_b3x  
        if ModifierKeys() == 1  
            and btval > 0.5
        then OpenPlugin(B3X)
        Else ClosePlugin(B3X)

@schamass you lost me there… how do you print out the modifier keys?

Ideally knowing what CTRL and ALT are would be useful… I’d like to see if I can get this to modify when I “right-click” or hold down CTRL.