Custom layouts

What is a layout?

The layout of the dial display is controlled by a JSON file that defines all the display objects involved, as well as the properties that determine how and where each object is displayed. Layouts are available only for dials.

The plugin includes a number of bundled layout files that cover the various looks of the dial display when using built-in designs, such as fader, V-pot, and others. The bundled layout files typically include multiple items to accommodate various configuration scenarios (e.g., icons in the fader layout), which are displayed or hidden depending on the current situation.

What is a custom layout?

A custom layout is a layout JSON file you create yourself and use with any of the "single" dial actions; multi-dials do not have the custom layout feature.

Please note that this is an advanced topic that requires a thorough understanding of the layout file syntax and how the plugin populates the display objects. The Stream Deck software is very particular about file syntax, and even the slightest issue will result in the layout being ignored.

Why create a custom layout?

You might not be satisfied with certain aspects of the built-in layouts; you may want to reposition the text, provide larger spacing for it, or adjust the size and placement of other elements in the layout.

Or you want to design a unique layout and manage it using a script.

Or your reason may, of course, fall anywhere between the two examples mentioned above.

Layout file components

The JSON layout file defines all the objects that, when combined, create the final image displayed for the dial. Four different object types are used: text, pixmap (image), bar (without a triangle indicator), and gbar (with a triangle indicator).

Each object type has its own unique set of properties that determine how, and whether, the object is displayed.

A short example of a text item in a layout:

{
      "key": "l_toptext_full_width",
      "type": "text",
      "rect": [ 5, 0, 190, 33 ],
      "font": { "size": 26,  "weight": 600 },
      "alignment": "center",
      "value": "",
      "text-overflow": "clip",
      "enabled": false,
      "zOrder": 30
},

Elgato provides excellent documentation for all properties, so I see no reason to repeat all that information here, but some important bits of information about the layout and its properties:

  • "id" for the layout is a "unique identifier associated with the layout." I’m not entirely sure what it’s used for, but it probably relates to the caching of layouts. If you create custom layouts, I recommend you set this "unique identifier" to something unique.  😁
  • "key", "type" and "rect" define the name, type, position, and size of the object. These properties cannot be altered at runtime. If you access the layout object from a script, the "key" value represents the name of a layout variable that references the layout object.
  • The "rect" property is defining the item's coordinates in the format [x, y, width, height]; coordinates must be within the canvas size of 200 x 100, e.g., [0, 0, 200, 100]. 
  • "value" is the value, and the content varies according to "type". For text objects, it represents the text to be displayed; for images, it refers to the path of an image file; and for bars, it indicates the position on the bar.
  • For text objects, the plugin will always adjust the font size to fit the text within the available space (on one line). If you want a fixed font size, you must set the font size explicitly using a script. 
  • "enabled" controls the visibility of an object. true=visible, false=hidden.
  • "zOrder" is used to layer items within a layout and must be between 0 and 700. Objects with a higher zOrder will be positioned above those with a lower zOrder. 

Items with the same zOrder must not overlap, and objects must not extend beyond the canvas area.
The Stream Deck software is very particular about this and will reject the entire layout if even a single object extends beyond the canvas area or if objects with the same zOrder overlap, even if it's just by a pixel. In my experience, this is one of the most common errors that lead to a layout being rejected. I strongly recommend assigning a unique zOrder level to each object.

 

Example

A request I have received a number of times is to have the title field on a dial fader span the entire width of the fader, rather than just half of it. I use this as an example of how you can use custom layouts.

Step 1: Make a copy of the fader layout file (fader.json) located in the Layouts folder within the plugin folder. Save the copy elsewhere, such as in the Trevliga Spel folder in your Documents folder.

Step 2: Open the file in a text editor of your choice.

Step 3: Change the "id" field to something unique.

Step 4: Locate the objects that represent the upper text row on the fader. The objects have descriptive names, and the ones you are looking for are "l_fadertext_left_side_upper_row" and "l_fadertext_left_side_upper_row_background" :

{
      "key": "l_fadertext_left_side_upper_row",
      "type": "text",
      "rect": [ 10, 49, 90, 24 ],
      "font": { "size": 20, "weight": 400 },
      "alignment": "left",
      "text-overflow": "clip",
      "enabled": false,
      "zOrder": 50
},
{
      "key": "l_fadertext_left_side_upper_row_background",
      "type": "pixmap",
      "rect": [ 8, 49, 94, 24 ],
      "enabled": false,
      "zOrder": 40
},

To have these objects, the text and the background, fill the entire width, you need to change the "rect" properties, which define the position and size of the objects.

Step 5: Adjust the "rect" properties for the objects. 

The rect for the text object can be adjusted to "rect": [ 10, 49, 180, 24 ],
and the rect for the background object to "rect": [ 8, 49, 184, 24 ],

This will cause the text object to fill the entire width, with a 10-pixel padding on each side, while the background object will extend an additional 2 pixels on each side.

Step 6: Save the adjusted profile, create a Generic Midi dial and configure it to use your custom layout file.

Step 7: An important step. Configure the dial to show either the value or the title on the fader, and set the "avoid collisions" dropdown to "Do nothing". This will ensure the plugin consistently uses the objects you adjusted, rather than hiding them and activating the right-side pair of text and background objects when the fader position is below midway.