Change LED widget color based on status

Hello all, and sorry if this subject was already posted anywhere else or addressed. I’ve been looking the forum but couldn’t find a clear answer to it.

Making it simple, I have a midi controller with RGB leds, and I typically use 2-3 colors on a led to display different status (for example, in a looper, green could mean “clear”, red “recording” and and orange “play”).

Is there any way to replicate this behaviour with widgets, or the only solution is to put tree “LED” widgets, each with its own color, that will light or turn off accordingly to the status. The last option can work, but will make the rackspace too busy… would be great to have the option to have widgets changing colors…

Thank you,

Pedro

Hi @pgargate,

welcome the the family :wink:

The LED widgets only have 1 color, no way to influence that.

1 Like

There is a way to simulate this using hidden Pad widgets, and GP Script to un-hide the appropriate widget based on your controller input.

Here’s an example:

In this example, I’ve set up 3 hidden widgets to receive the MIDI input from a controller, and three hidden Pad widgets–one for each color you mentioned, stacked on top of each other.

Var
   red : Widget
   green : Widget
   orange : Widget
   ron : Widget
   oron : Widget
   gon : Widget

   // Called when a single widget value has changed
On WidgetValueChanged(newValue : double) from ron
If newValue > 0.5 then SetWidgetHideOnPresentation(red, false)
SetWidgetHideOnPresentation(green, true)
SetWidgetHideOnPresentation(orange, true)
End
end

On WidgetValueChanged(newValue : double) from gon
If newValue > 0.5 then SetWidgetHideOnPresentation(green, false)
SetWidgetHideOnPresentation(red, true)
SetWidgetHideOnPresentation(orange, true)
End
end

On WidgetValueChanged(newValue : double) from oron
If newValue > 0.5 then SetWidgetHideOnPresentation(orange, false)
SetWidgetHideOnPresentation(red, true)
SetWidgetHideOnPresentation(green, true)
End
end
7 Likes

thank you so much for your time @edm11. ant thankyou @pianopaul for the welcoming to the forum! I’m long time regsitered, but couldn’t focus on gig performer for the past year.

I need to study a bit the code you wrote, as I’m very new to the programming part, but it seems to be exactly this that I need :slight_smile:

Will keep you posted If i have any difficulty, but this looks very promising!

thank you,

Pedro

1 Like

Just a quick heads up. I’ve tested your code @edm11 and it works perfectly. once again thank you for your help. This will open a lot of possibilities :slight_smile:

1 Like

And to close the topic, just a small variation on @edm11 code to use a single widget that controls all LEDs. For me, it looks simpler (less widgets), as I can control all LED from a single point by sending the same CC to a single location, but with different values. Both solutions work well

Var
   red : Widget
   green : Widget
   orange : Widget
   ron : Widget

   // Called when a single widget value has changed
On WidgetValueChanged(newValue : double) from ron
If newValue > 0.25 then SetWidgetHideOnPresentation(red, false)
SetWidgetHideOnPresentation(green, true)
SetWidgetHideOnPresentation(orange, true)
End

If newValue > 0.5 then SetWidgetHideOnPresentation(green, false)
SetWidgetHideOnPresentation(red, true)
SetWidgetHideOnPresentation(orange, true)
End

If newValue > 0.75 then SetWidgetHideOnPresentation(orange, false)
SetWidgetHideOnPresentation(red, true)
SetWidgetHideOnPresentation(green, true)
End
End
2 Likes

Careful… was missing an END
(I just corrected :wink:

1 Like

You could also use a text label or rectangle widget and just change the color value (and/or the text). This would offer even more options…

2 Likes

This is why I recommend the following indentation style for GP Script best practice. It’s easy to see if everything is there

On WidgetValueChanged(newValue : double) from ron

   If newValue > 0.25 
      then 
         SetWidgetHideOnPresentation(red, false)
         SetWidgetHideOnPresentation(green, true)
         SetWidgetHideOnPresentation(orange, true)
   End

End

That said, may I recommend some improvements to this code?


First improvement: in this version, we reverse the tests and once one of them is true, the rest of the tests can stop — in other words, use else clauses

On WidgetValueChanged(newValue : double) from ron

    If newValue > 0.75 
       then 
          SetWidgetHideOnPresentation(orange, false)
          SetWidgetHideOnPresentation(red, true)
          SetWidgetHideOnPresentation(green, true)
       elsif newValue > 0.5 
          then 
             SetWidgetHideOnPresentation(orange, true)
             SetWidgetHideOnPresentation(red, true)
             SetWidgetHideOnPresentation(green, false)

       elsif newValue > 0.25 
          then 
             SetWidgetHideOnPresentation(orange, true)
             SetWidgetHideOnPresentation(red, false)
             SetWidgetHideOnPresentation(green, true)
    End   
   
End

Second improvement: use a function to reduce the repeated code

Var
   red : Widget
   green : Widget
   orange : Widget
   ron : Widget

   LEDs : widget array = [red, green, orange]
   
Function SetTrueExcept(thisOne : widget)
var
   index : integer   
   for index = 0; index < Size(LEDs); index = index + 1 do
      SetWidgetHideOnPresentation(LEDs[index], LEDs[index] != thisOne)
   end   
End
   
On WidgetValueChanged(newValue : double) from ron
    If newValue > 0.75 
       then 
          SetTrueExcept(orange)
       elsif newValue > 0.5 
          then 
             SetTrueExcept(green)
       elsif newValue > 0.25 
          then 
             SetTrueExcept(red)
    End      
End

Third improvement - use a Select Do instead of If Then – the result is both shorter and much clearer

Var
   red : Widget
   green : Widget
   orange : Widget
   ron : Widget

   LEDs : widget array = [red, green, orange]
   
Function SetTrueExcept(thisOne : widget)
var
   index : integer   
   for index = 0; index < Size(LEDs); index = index + 1 do
      SetWidgetHideOnPresentation(LEDs[index], LEDs[index] != thisOne)
   end   
End

On WidgetValueChanged(newValue : double) from ron
    Select 
       newValue > 0.75 do SetTrueExcept(orange) 
       newValue > 0.5  do SetTrueExcept(green) 
       newValue > 0.25 do SetTrueExcept(red)
    End   
End

One caveat – not sure this is deliberate on your part but your original code doesn’t handle the option where the value is actually less than 0.25 in which case the current colors won’t change at all from whatever they were at.

5 Likes

thank you… i guess I just copy pasted from the script editor and missed the end…

I truly thank you all your support and time on this. I’m no code expert but I will definitely look into all these options. Quite like the idea of simplifying the code to the most.

actually for the moment is just “proof of concept”, so I was not particularly worried with the values, but I agree that I need a response from 0.00 to 1.00. My goal here is to replicate the midi controller response on screen so that I can have proper feedback of all equipment and plugins in a single location. the first part was addressing the LED color change. Now I will need to repeat this code for all buttons and adjust the response values to the midi commands I’m sending, but I think I can manage that part :slight_smile:
again thank you all for all the code options

1 Like

Another way to approach this could be to put a shape widget overtop of a pad widget. You can then use scripting to change the background color of the shape widget to whatever color you’d like.

Those shape widgets are “transparent to touch”, meaning if you touch it or click on it that touch/click is going to go through to whatever is immediately behind it. Thus the pad widget behind it to capture the click/touch if you need that.

That said, I’d love to have an option on those shape widgets to make them toggles.

2 Likes

Me too, especially because I do what you suggest and it is sometimes difficult to cover the whole surface of a shape widget with a pad widget. :wink:

You can come very close to that though… the click-sensitive shape of a pad/knob is not the graphic itself but the “frame” around it (when you resize it). So you can get any rectangle shaped size you need. :wink:

1 Like

Oh really, I will have to try that! :+1:

Yeah i stumbled on this when i was making my “Soundboard”… don’t know if it’s a bug or a feature, but it’s quite handy for this special purpose!

2 Likes

Here is an example where i used a text-label widget to show a status change by using a diffrent message text as well as the color of the text box.
According to the discussion, i realized two diffrent aproaches…

  1. turn a knob to set four diffrent status-conditions (at 0%, 25%, 50%, 75%)
    or
  2. step through the four conditions by clicking multiple times on the text-widget. :wink:
    Actually the click will trigger a pad widget which is sitting under the text label, but since shape and label widgets are “click-transparent”, the click will hit the element below.

status_color

This is the script:

var
lbl_status, knb_status, pad_condition, lbl_status2 : widget
color_red, color_green, color_yellow, color_neutral : integer
cond_value : double = 0

Function SetStatus (target : widget, text : string,  color : integer)
    SetWidgetFillColor(target, color)
    SetWidgetLabel (target, text)
End

Function GetCondition (target: widget, con_val : double)
    Select 
       con_val > 0.75 do SetStatus (target, "Condition 3", color_red) 
       con_val > 0.5  do SetStatus (target, "Condition 2", color_yellow)
       con_val > 0.25 do SetStatus (target, "Condition 1", color_green)
       con_val > 0.0 do SetStatus (target, "Condition 0", color_neutral)
    End   
End


Initialization
color_red = RGBToColor(0.8, 0.0, 0.0, 1.0)
color_green = RGBToColor(0.0, 0.8, 0.0, 1.0)
color_yellow = RGBToColor(0.8, 0.8, 0.0, 1.0)
color_neutral = RGBToColor(0.8, 0.8, 0.8, 1.0)

GetCondition (lbl_status, GetWidgetValue (knb_status))
GetCondition (lbl_status2, 0)
End

On WidgetValueChanged (knb_val :double) from knb_status
    GetCondition (lbl_status, knb_val)
End

On WidgetValueChanged (pad_val :double) from pad_condition
    If pad_val > 0.6 Then
        cond_value = cond_value + 0.25
        GetCondition (lbl_status2, cond_value)
    end
    If cond_value >= 1.0 Then cond_value = 0.0 end
End

Here is the gig file so you’ll have something to play with:
shape color as status.gig (85.8 KB)

Cheers!
Erik

7 Likes

If it is still of interest, just sharing the evolution of the code here :slight_smile:

I took the principles of @schamass and rewrote part of it to achieve the following:

  • replace the need of widget knobs / button by an external midi event trigger
  • be able to control different LEDs depending on received Midi CC number
  • be able to change the color based on CC value

As stated before, this is still work in progress / proof of concept, so values are just indicative of the potential. the idea is to have a sufficiently flexible code to add additional LEDs without need of duplicating / re-writing code.
for the next step I will also split the response of LED color from LED Status, as i want to associate Status to the MIDI controller presets (to display the purpose of the LED accordingly to the selected preset: AMP / Looper / overdrive, etc…) and the LED color to its activation.

//VARIABLES -----------------------------------------------------------------------------

var
    LED01, STATUS01, LED02, STATUS02  : widget
    color_red, color_green, color_orange, color_neutral, CCValue : integer
    MidiTest: MidiInBlock
    
    LedArray : widget Array =[LED01, LED02]
    StatusArray : widget Array =[STATUS01, STATUS02]
    
    LedCount: integer
    MidiCount: integer

//SUPPORT FUNCTIONS ---------------------------------------------------------------------    

//  03a - function to change widget color
Function 
    SetColor (target : widget,  color : integer) 
    SetWidgetFillColor(target, color)
End

//  03b - function to change widget text
Function 
    SetText (target : widget, text : string)     
    SetWidgetLabel (target, text)
End

//  02a - function condition to select color (reads function 03a)
Function GetConditionColor (target: widget, con_val : double)  
    Select 
       con_val > 60.00 do SetColor (target, color_red) 
       con_val > 40.00 do SetColor (target, color_orange)
       con_val > 10.00 do SetColor (target, color_green)
       con_val > 00.00 do SetColor (target, color_neutral)
    End   
End

//  02b - function condition to select text (reads function 03b)
Function GetConditionText (target: widget, con_val : double)  
    Select 
       con_val > 60.00 do SetText (target, "Condition 3") 
       con_val > 40.00 do SetText (target, "Condition 2")
       con_val > 10.00 do SetText (target, "Condition 1")
       con_val > 00.00 do SetText (target, "Condition 0")
    End   
End

//RUNNING CODE ---------------------------------------------------------------------  

//  00 - Sets Initial status
Initialization                                              
    color_red = RGBToColor(0.8, 0.0, 0.0, 1.0)
    color_green = RGBToColor(0.0, 0.8, 0.0, 1.0)
    color_orange = RGBToColor(0.8, 0.8, 0.0, 1.0)
    color_neutral = RGBToColor(0.8, 0.8, 0.8, 1.0)
    CCValue = 0
    GetConditionColor (LED01, CCValue)
    GetConditionText  (STATUS01, CCValue)
End

//  01 - Called when a CC message is received at some MidiIn block (reads functions 02a & 02b)
On ControlChangeEvent(m : ControlChangeMessage) from MidiTest
LedCount = 0                                   //Resets LED counts
    for MidiCount = 11; MidiCount < 21; MidiCount=MidiCount+1 do        //filtes midi messages from CC11 to CC21
        if GetCCNumber(m) == MidiCount then     //Responds to messages from CC11 to CC21
           CCValue = GetCCValue(m)      //Stores CC value
           GetConditionColor (LedArray[LedCount], CCValue) //applies function to associated LED
           GetConditionText  (StatusArray[LedCount], CCValue) //applies function to associated LED
        end
    LedCount = LedCount+1             //increments LED number count associates each LED to one CC
    end
end

First time digging on Gig Performer script, but really finding the amazing possibilities it offers :slight_smile:

Also below the gig file
Test LEDS.gig (72.2 KB)

1 Like

Help please, The function does not recognize me “SetWidgetFillColor(target, color)”, Why ?

What version of Gig Performer are you running?

Most probably because there’s something wrong.
…Sorry but because of the huge amount of context, information and sample code you have provided, that’s all I can answer.

1 Like