companion icon indicating copy to clipboard operation
companion copied to clipboard

Add variables in the scope of a button

Open BryanCrotaz opened this issue 2 years ago • 23 comments

Is this a feature relevant to companion itself, and not a module?

  • [X] I believe this to be a feature for companion, not a module

Is there an existing issue for this?

  • [X] I have searched the existing issues

Describe the feature

Variables: $(button:text) $(button:enabled) $(button:disabled) $(button:page) $(button:number) $(button:col) $(button:row)

These variables are only valid within a button (not within a trigger for example)

Usecases

External system sets up button names and wants to know when each one is pressed.

Set up a page of buttons with OSC actions with a path of /my-action/$(button:text) or /my-action/$(button:page)/$(button:number Copy paste now works without post-editing the buttons.

Then using OSC or http, push all the available names into the page. When the button is pressed, you know which one it was

In my example it's a sports team and the OBS script loads video stingers from a folder and puts the filename on a button. When that button is pressed it looks up the video by name and plays it. With 32 on each team it takes AGES to set up the companion page manually.

BryanCrotaz avatar Feb 13 '22 17:02 BryanCrotaz

+1

I would LOVE for this to be added to the stable version of Companion. My use case would be to use the page number and button number to automate variable actions.

I have a more complicated use case, but a simple example is as follows: I am using vMix to cut cameras/inputs/etc., and also have feedbacks to change the color of the button to green or red depending on if it is in preview or program. I use the button number to substitute my manually entered number. This way, I can copy and paste the button and it will automatically be using the current page/button numbers to trigger/feedback the respective input.

My expression would look like this: (($(internal:this-page-num)-1) * 32) + $(internal:this-button-num)

That way, I can copy and paste to any page and it would increment by 1/32. And of course you can do any other calculation to get more custom results!

PS: I love that companion has the modulo operator available! It would be so cool if they could somehow add ternary operators, and possibly conditional operators too in the future!

jsjoen7896 avatar Sep 02 '22 21:09 jsjoen7896

I would also like to handle page numbers as variables. In my case I want to step around pages with one! button action. e.g. I have three pages I want to step trough, starting with page 1, the next press should go to page 2 ... when in page 3 the next press should go to page 1 again.

sstaub avatar Nov 24 '22 13:11 sstaub

I have a big spanner to throw into this idea, that I don't have a solution for currently.

In 3.1/3.2 I am planning to do an overhaul of pages, and while doing so I want to allow for a looser form of #27, #1676 and some similar things.
The concept is being able to define a button once, and assign it to multiple buttons. That could be the same page, different pages, different sets of pages, or maybe the 'button' isnt on any page and is a trigger or can only be called via the http api.

This means that a $(button:page) doesn't have a simple single value. The value becomes very context dependent. This could be acceptable or not, depending on the use case. This could simply be a documented limitation, it doesn't mean that this can't be done as there will still be values that would be useful in various scenarios

Julusian avatar Nov 24 '22 15:11 Julusian

Context is exactly what we need here.

The button that triggered the script is the important thing here.

Suggestion: You seem to be designing a virtual button that can be mapped to multiple real buttons.

I think that's the wrong model. How about instead you can make an action or feedback "module" or "script" that can be included within another button as a single action or single feedback line? That's a lot more flexible. You could make one button do two things this way, or you could have central definition of feedback styling. You could pass variables down to the script too.

BryanCrotaz avatar Nov 24 '22 16:11 BryanCrotaz

The button that triggered the script is the important thing here.

Yes a lot of the time the button will be used in a way that has a location, but my point is that its not always. Whether feedbacks can use these variables will depend on how the drawing is implemented; do we draw once for all uses of that button, or draw each placement individually?

You seem to be designing a virtual button that can be mapped to multiple real buttons. I think that's the wrong model. How about instead you can make an action or feedback "module" or "script" that can be included within another button as a single action or single feedback line? That's a lot more flexible. You could make one button do two things this way, or you could have central definition of feedback styling. You could pass variables down to the script too.

I think that is a solution to a different problem. I am open to this being done too (perhaps this is https://github.com/bitfocus/companion/issues/1793?)

The use-case for this 'virtual button' concept is to make the same button present on multiple pages. While that would be achievable with your solution, I think it will be much better than what is possible today by using the internal actions to press/release another button.

We aren't explicitly working towards these 'virtual buttons', but they mostly just happen to fit into place with the db restructuring being done.

Julusian avatar Nov 24 '22 17:11 Julusian

yes a lot of the time the button will be used in a way that has a location, but my point is that its not always

Then the context wouldn't contain a page and button reference! If you're writing an integration that requires the button location to work (e.g. operating a vision mixer and using the page column as the input number) then naturally that script isn't going to work from a trigger that doesn't involve a button, and you it simply doesn't make sense to use it in that fashion.

Your argument is like saying that you can't use English to talk to a Frenchman, so we won't implement English.

However if someone triggers the button push (page 1, bank 2) then the context would contain those two variables.

BryanCrotaz avatar Nov 24 '22 18:11 BryanCrotaz

I'm not saying it won't/can't be done, just that there are some limitations and potential complexities. Also I am avoiding doing this myself before the internal page restructuring is done otherwise behaviours will change once that refactoring done.

Julusian avatar Nov 24 '22 22:11 Julusian

+1

Would love to have this in addition to math in the input fields. That way you can e.g. set bank 25 (lower left corner) to:

  • Name: $(vmix:input_$($(button:number)-24)_name)
  • Action and feedback: $($(button:number)-24)

Or however the math is supposed to be implemented

And copy the button to the 6 next buttons and they will all dynamically change the input number

Haavard15 avatar Nov 28 '22 14:11 Haavard15

Also step should handled $(button:step)

sstaub avatar Dec 18 '22 09:12 sstaub

+1

xyvidbilling avatar Jan 13 '23 20:01 xyvidbilling

+1 Getting the value of the last pressed button would be very helpful

yannok avatar Apr 07 '23 10:04 yannok

Another problem with doing this is that the way that modules parse variables does not let companion know any context for that. Due to the async nature of modules in 3.0, there isnt a way to directly tie variable parsing to an action execution without updating modules to support it. It is a fairly simple change to make in modules, but means that it will also be up to the module to parse in the correct way to support it.

Again, doesnt mean it cant or shouldnt be done, just another concern/case to think about

Julusian avatar Apr 26 '23 19:04 Julusian

Message ID: @.***>Pass the context as an extra optional blob so that old modules can ignore it

BryanCrotaz avatar Apr 26 '23 20:04 BryanCrotaz

Yes, we already have this context provided as the second parameter to the relevant action and feedback functions, but as far Im aware no module is using it for actions. Currently there is no benefit to using it. Its not a problem of potentially breaking old modules, but that the new scoped variables will only work with some modules and it will be confusing to users. More of a comment/observation that anything

Julusian avatar Apr 26 '23 20:04 Julusian

Message ID: @.***>If no one is using it yet, you could add a capabilities hash on a module spec do the app can tell the user what features the module supports

BryanCrotaz avatar Apr 26 '23 20:04 BryanCrotaz

As suggested by @Luuccc in https://github.com/bitfocus/companion-module-base/issues/52 there is a useful addition to this request:

Modules should be able to set variables only valid in the scope of a control.

Possible workflow: A user sets up an action with some options. The subscribe function will be called. In the subscribe function the module can set a variable to control. The user can use this variable in the button.

Example: User sets up action to adjust volume of channel 1. The channel number is an option. The module can check the name of channel 1 and set it to a local variable "channelname". The user can set the button text to "Set vol $(button:channelname)" and will always see the name of the selected channel. This can be provided in presets and also saves definition of many global variables.

I guess module name would have to be added as a namespace to avoid naming conflicts.

dnmeid avatar Jun 12 '23 22:06 dnmeid

Feature Request

Summary of #2827 for reference here:

I'd quite like to see custom variables that are stored within a button. It would make creating (in my case) vMix buttons much easier by having one place per button to store a variable such as an input number which can then be refered to in the button's text, actions and feedbacks. When copying the button, this value would then only need to be changed once rather than in however many places it's used. The mock up below would have the UI from the custom variables in the top area of the editor, although it might be better placed as a tab alongside actions, steps and feedbacks.

In Head

josh-justjosh avatar Apr 08 '24 10:04 josh-justjosh

custom variables that are stored within a button

Button 'arguments' in this: context. This would make template buttons much easier to build. Create a button and use that reference in the label, actions, and feedbacks. Then there is only 1 item to change instead of 4 or more.

istnv avatar Apr 08 '24 17:04 istnv

I'd quite like to see custom variables that are stored within a button.

I want to question if these need to be 'custom variables', or if it should be 'readonly' local variables. The difference being that 'custom variables' are an existing concept and allow users to set the value of the variables from actions. Do we need that functionality here? If so, do we need to be able to set them from elsewhere, or only from within the button?

Either way, it probably makes sense to call them something different (local variables?), to differentiate them from the 'global' custom variables system that already exists

Julusian avatar Apr 08 '24 18:04 Julusian

It definitely needs a different label. Button only arguments, parameters? The 'Preset' name already confuses a lot of people.

Read only: I can imagine a combination of things from this discussion, where a button 'arg' is set to 'this:button' (number).

istnv avatar Apr 08 '24 18:04 istnv

Read only, but able to be set to the value of an expression using other variables

BryanCrotaz avatar Apr 08 '24 19:04 BryanCrotaz

I also think that this: is a good namespace for local custom variables.

Read only, but able to be set to the value of an expression using other variables

Actually that means read/write, which off course would be a good thing, if you can change the value of such a variable on the fly. It should be possible to make the variable setting actions from the internal module work with this:..... What I don't see is access to a local variable from the outside, neither from an action running on a different control nor from the api. I would consider a local variable something like a private class field. If you really want to access it, the user can do it in a getter/setter way e.g. at different steps.

I would call it a 'local variable' and also call all the location based variables 'local variables'. I wouldn't invent too much names for things which actually are the same. There is this issue #2812 about naming variables with a few valid concerns. Long term I'd rather try to reduce naming complexity.

dnmeid avatar Apr 09 '24 21:04 dnmeid

I also think that this: is a good namespace for local custom variables.

My one concern there will be the chance of name collisions. If the user defines the variable $(this:name) locally, then a few releases later we add a builtin variable $(this:name), then there will be a clash. I suppose that theirs could override the builtin one, but could that cause other weirdness that we should try to avoid?

I would call it a 'local variable' and also call all the location based variables 'local variable

Good call, I'll go through and rename that in the betas now. I think its a little odd to call the current variables 'local' variables, as that name suggests to me that the user can define these variables, but it doesnt bother me enough.

Julusian avatar Apr 09 '24 22:04 Julusian