Bitfocus AS
logo
logo
Bitfocus AS
logo
logo
Sign upSign in

Loading...

Bitfocus

Subscribe to our newsletter

The latest news, articles, and resources, sent to your inbox.

FacebookInstagramGitHubYouTubeLinkedIn

Products

  • Buttons
  • Companion

Integrations

  • Supported Devices
  • Developer Community
  • Connection Development

Support

  • Support Overview
  • Documentation
  • Video Tutorials
  • Community Forum

Sales

  • Resellers & Integrators
  • Buttons Pricing

Updates

  • Case Studies
  • Events & Trade Shows
  • Press Releases
  • Product Updates
  • Webinars

Legal

  • Legal Overview
  • Privacy Policy
  • Buttons EULA
  • Terms & Cookie Policy

Company

  • About us
  • Press kit
  • Careers

© 2026 Bitfocus AS. All rights reserved.

Build more capable button actions
Docs for
Overview
Getting started
What is Bitfocus Buttons?
Install Buttons and get started
Manage your Buttons license
Activate Buttons offline
Find your way around Buttons
Create your first backup
Add an ATEM connection
Choose a control method
Choose an installation path
Install Buttons on Debian or Ubuntu
Understand HA clustering
Kubernetes HA
Update or remove Buttons
Positions
Understand positions
Create a position
Add controls and sections to a position
Create your first button
Use a connection's presets
Build more capable button actions
Add more feedback to a button
Organize controls in a section
Shift Section
Organize controls with a Folder Section
Add a Popover Section
Build and reuse a Shared Section
Build a Router Section
Understand Custom Routers
Custom Router panel
Surfaces
Surface compatibility
Add and attach a surface
Device orientation
Connections
Update a connection's module safely
Monitor and troubleshoot a connection
Router integrations
VideoHub and AJA KUMO
Utah Scientific BPS
Generic SW-P-08
Nevion VideoIPath
Arkona BLADE//runner
Routing
Physical routing
Configure ports and labels
Take a physical route
Understand route status
Topology graph
Routing Presets
Get started with virtual routing
Configure Nested Shapes
Reverse routing
Tielines
Routing Projects
Routing settings
Troubleshoot a route
Tally
Understand the Tally system
Send ATEM tally and labels to a UMD
Interpret Active Tally state
TSL/UMD connections
Diagnose tally problems
NMOS
Understand NMOS in Buttons
Connect Buttons to an NMOS Registry
Built-in Registry Server
Configure NMOS connections
Discover and adopt
Browse the NMOS inventory
Manage NMOS multicast addresses
Diagnose NMOS problems
Understand Cuelists
Build a Cuelist
Read and advance a running Cuelist
Control a Cuelist from a Position
Workflows
Understand workflows
Build your first workflow
Reuse a group of workflow nodes safely
Troubleshoot a workflow
Recipes
Sequence a timed automation
Call an HTTP endpoint from a workflow
REST endpoint
Use variables
Understand variable scope
Understand nested variables
Update expressions for v1.8
Plan and use Tags
Access
Create and manage users
Create roles and assign permissions
Grant access to specific resources
Show different controls by role
Sessions
Set up PIN and NFC sign-in
SSO
Get started with SSO
Connect a generic OIDC provider
Connect LDAP or Active Directory
Map identity claims to roles
Secure a Buttons deployment
Integrations
External control
Connect to Bitfocus Listener
USB Relay
Install USB Relay on Windows
Install USB Relay on macOS
Install USB Relay on Linux
Install USB Relay on a Raspberry Pi
Get started with the Control API
Secure and monitor the Control API
Control API reference
API reference
Administration
Enable and manage installable features
Services and health
Configure and monitor scheduled backups
Restore a backup and verify it
Export or import Buttons configuration
Store and rotate connection secrets
Replace the HTTPS certificate
HA backup and recovery
Settings
Collect support information
Reference
Glossary
Button Inspector reference
Network ports reference
Expressions
Internal actions reference
Routing Presets panel reference
Startup configuration reference
Workflow nodes
Connection workflow nodes
Workflow workflow nodes
Internal workflow nodes
Position workflow nodes
API workflow nodes
Utility workflow nodes

Loading...

Previous
← Use a connection's presets
Next
Add more feedback to a button →
Contact support →
You are viewing documentation for Buttons 1.8.See the docs for Buttons 1.6
Buttons/Positions/Build more capable button actions

Build more capable button actions

Create your first button covers a single action on Press. This page covers everything beyond that: running several actions per press, branching on a condition, generating a whole row of buttons from one, and using an encoder's rotation as an action's input.

Before you begin#

  • A button with at least one action added. See Create your first button.

Run more than one action#

Every action handler (Press, Release, Left, Right, Encoder, and any Hold group) runs its actions as numbered steps.
  • Select + next to Step 1 to add another step, or duplicate the current step to start from a copy.
  • Set each step's own delay as Absolute (a fixed time after the button was pressed) or Relative (a fixed time after the previous action started).
  • Double-click a step's name to rename it.
  • Open the step's cogwheel to reorder steps or turn on auto-progress, which advances to the next step on every press instead of always running step 1.

Fire different actions based on how long a button is held#

Select Hold next to Press/Release to add a duration-based action group, useful for a button that should do one thing on a quick tap and something else on a longer press: the same model Companion presets use.
  • Each Hold group has its own threshold in milliseconds. Once at least one group exists, the plain Release handler relabels itself Short release to make clear it now only covers a press shorter than every configured group.
  • Run while held (off by default for a new group) decides when the group's actions fire:
  • Off: the group's actions fire on release, but only if the button was held at least that long, and only for the longest group whose threshold was reached. A shorter group's actions don't also fire.
  • On: the group's actions fire as soon as the button has been held that long, without waiting for release. If the button is released afterward, that same group's actions don't fire a second time.
  • Add more than one Hold group to cover several thresholds at once: for example a 1000 ms group and a 3000 ms group on the same button behave like Companion's own short-press/long-press/longer-press pattern.

Fire an action on a single or double click#

Select Single and/or Double next to Press/Release for a simpler alternative to Press/Release: a Single click handler fires on any press you let go of, and a Double click handler fires on two quick taps close together. Use them on their own or alongside Press, Release, and Hold: they don't replace each other, they're an independent way of reacting to the same button.
  • A press held for 5 seconds or longer is never a click: this safety cap keeps a stuck or forgotten press from firing Single click or starting a Double click.
  • With only Single click configured, it fires as soon as you release, no matter how long the press was (short of the 5-second cap).
  • With only Double click configured, two presses each under 400 ms, released within 400 ms of each other, fire it. A lone tap with no second press within that window fires nothing.
  • With both configured, a quick tap (under 400 ms) waits up to 400 ms for a second quick tap: a second one arriving in time fires Double click; otherwise Single click fires once the window closes. A press of 400 ms or longer fires Single click immediately, since it can't be the first half of a double click.
  • Single click and Double click stay pinned to the step you were on when you pressed, even if Press or Release has since auto-progressed to a different step.

Group actions together#

Add an ActionGroup (from + Add Action...'s own ActionGroup button, alongside the recently-used-actions list) to run several actions as one unit:
  • Mode: Concurrent runs every action in the group at once; Sequential runs them one after another.
  • Group Delay: a delay applied to the whole group before it starts.
Drop actions into the group's own Actions list, either from + Add Action... inside it or by dragging an existing action in.

Run an action only when a condition is true#

Add an ActionLogic the same way, from the ActionLogic button next to ActionGroup. It has three parts:
  • Condition: drop in any feedback, or the Internal Expression feedback to test a variable directly, such as $(time.hh) >= 12.
  • When true: actions that run only when the condition is true.
  • Else: actions that run when it isn't.
The condition's header shows its live state, true or false, next to its label, so you can confirm it evaluates the way you expect before relying on it. Unlike a button feedback, a condition has no Preview section or Test button, because a condition never styles the button. Stack more than one ActionLogic to test several conditions in the same step.

Generate a row of buttons from one#

When an action's own field is a dropdown of choices (such as an ATEM input selector), its ... menu offers Create Button Repeater from choices. This turns the button into a master, and generates one button per choice in the dropdown, each targeting a different value.
  • The Repeater tab (visible once a repeater exists) lists every Action Repeater or Feedback Repeater feeding the layout under Data Sources: a button can combine a repeated action with a repeated feedback, as long as both use the same option list, so the two stay aligned row for row.
  • Direction controls whether generated buttons lay out left-to-right or top-to-bottom.
  • Customize Data & Labels opens an editor with two views: Generated Buttons shows exactly what will be created and lets you hide entries you don't need or override a specific button's label, icon, or color; All Available Data is for aligning more than one data source by hand when their choices don't naturally correspond row for row.
Inside the repeated buttons' own text or actions, reference the position with:
  • $(self.repeatIndex): the button's position in the generated set, starting at 0.
  • $(self.repeatDataId): the underlying value of that button's choice.
  • $(self.repeatDataLabel): the display label of that button's choice.
A repeat index can also be substituted directly into another variable's own name using % as a placeholder, for example $(mixer.channel_name%) on the button repeated at index 3 reads as $(mixer.channel_name3). This is a repeater-specific substitution, separate from the general nested-variable mechanisms in Understand nested variables; use a literal \% if you need an actual percent sign in the same field.

Use an encoder's rotation as a value#

Turn on the Encoder action handler to use a surface's encoder (such as a Stream Deck Studio or Stream Deck Plus) instead of, or alongside, Press and Release:
  • Initial, Min, and Max set the encoder's range; Current shows its live value once applied.
  • Assignment decides which physical encoder controls this button: Click Select (press the button to assign the nearest free encoder, the default), a specific location, or a specific encoder number.
  • Display shapes how the encoder's LED ring reflects the value: Single (one LED lit per step), Start/End (LEDs fill from one end), or Split (a pan/balance-style indicator).
  • Active Style controls how the assigned button itself looks while assigned: Highlight (a white outline, the default), Ignore (no change), or Value on white background (shows the live value and text on a white background).
Reference the live turned value inside the encoder's own actions with $(self.encoderValue), using the action field's expression mode. For example, an action expecting 0–255 from an encoder ranging 0–20 could use $(self.encoderValue) * 12.75.

Let the encoder pick from a dropdown directly#

When an encoder action's own field is a dropdown of choices, its ... menu also offers Create Encoder Selector from choices, turning the encoder into a direct selector across those choices, rather than a numeric range. Reference the selected choice with $(self.encoderSelectorValue) (the value) and $(self.encoderSelectorLabel) (the label).

Test without a surface#

Hold Shift and select a button in the editor to fire its actions directly: the same Execute Mode used elsewhere in the editor. You can also run a single action from inside its own settings, without touching the button at all.

If you get stuck#

What you see
What to try
A repeated button's action targets the wrong choice.
Confirm the Repeater's Data Sources entry actually points at the field you meant: a button can have more than one dropdown field.
An encoder action doesn't respond to any physical encoder.
Check Assignment: with Click Select, you need to press the button first to claim a free encoder before turning it.
An ActionGroup's actions don't run in the order you expect.
Check Mode: Concurrent runs them all at once; only Sequential guarantees order.
A step's delay doesn't line up with the others.
Confirm whether it's set to Absolute or Relative: they measure from different starting points.

Where to go next#

  • Add feedback so a button reflects real state, for the same set of ideas applied to feedback.
  • Button Inspector reference, for every field on the Design and Repeater tabs.
  • Understand nested variables.

Was this helpful?

Was this helpful?

0 of 0 users found this page helpful