Scripting a button color change for lineOverride

Hello! Ableset 3.1.4 here, and new to scripting in OSC. I’m working on a scenario where I’d like to have a button toggle the setLineOverride function so that I can scroll lyrics in a song that doesn’t have tracks also playing.

Looking to have one button to toggle this on and off - and I’ve got this working with the “/devices/setLineOverride all toggle” command - works great.

However I’d like the button background to change as well depending on the state. For example - red background when lineOverride is on, green when it’s off. I can’t seem to wrap my head around how to do this - again new to coding in OSC and so I’m wondering if there should be an if statement in there? Ie in the dynamic background line - a concept like if setLineOverride = true, then “red-600” otherwise “green-850”? Or if it’s something more like ${osc(“/devices/setLineOverride”) ? etc etc?

Appreciate someone pointing me in the right direction.

Thanks!

Hey @BennyTheBassman, welcome to the forum!

The way around this is to track the state yourself in a shared variable, and have one button flip that variable and fire the command at the same time. That means switching your button from OSC to Script.

Script on Press

// Flip our own state, then toggle the override
setShared("lineOverride", !shared("lineOverride", false));
sendOsc("/devices/setLineOverride", "all", "toggle");

Dynamic Background Color

Enable the Dynamic toggle under Background Color, then paste this in:

${shared("lineOverride", false) ? "red-600" : "green-800"}

That’s your ternary — just checking the shared variable instead of an osc() call.

One small thing: green-850 isn’t a valid shade. The steps are 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950, so green-800 or green-900 is what you’re after.

Optional: dynamic label

The Label field takes the same templating, so the button can say what it’s doing:

${shared("lineOverride", false) ? "Pinned" : "Follow"}

Ready-made button

If you’d rather not build it by hand, copy this and paste it straight into your canvas:

[{"type":"button","buttonType":"script","label":"${shared(\"lineOverride\", false) ? \"Pinned\" : \"Follow\"}","textColor":{"type":"preset","color":"white"},"backgroundColor":{"type":"dynamic","template":"${shared(\"lineOverride\", false) ? \"red-600\" : \"green-800\"}"},"font":{"size":32},"width":200,"height":200,"x":100,"y":100,"zIndex":10,"scriptOnPress":"setShared(\"lineOverride\", !shared(\"lineOverride\", false));\nsendOsc(\"/devices/setLineOverride\", \"all\", \"toggle\");"}]

This behaves exactly like the anchor button in the Lyrics view, with the color following along.

Keep in mind that the shared variable only hears about toggles that go through this button. If you also pin lines with ⇧M or the anchor button inside the Lyrics view, the button’s color can end up showing the opposite of the real state. So in this case it’s recommended to make this button your only way of toggling it.

One last heads-up if you ever try the 3.2 beta: the Canvas Lyrics element gains a Line Override field there that accepts a template, controlling the same override. That opens up some nicer options than the shared-variable approach, so it’s worth a look once you’re on it.

Would that work for your use case?