Widgets
Overview
Beyond supporting custom JavaScript/HTML frameworks, Cabbage provides a declarative JSON syntax to define plugin properties and a robust set of native widgets.
Cabbage JSON
Section titled “Cabbage JSON”A Cabbage UI is defined by a root JSON object and must contain a widgets array, which contains all the UI elements in the plugin interface:
<Cabbage>{ "widgets": [ { "type": "rotarySlider", "id": "mainGain", "channels": [{ "id": "gain", "range": {"min": 0, "max": 1, "value": 0.5} }] } ]}</Cabbage>Apart from the “widgets” array, the <Cabbage> block can also contain top-level configuration properties:
Plugin ID
Section titled “Plugin ID”"pluginId": "MyPl"The unique identifier for the plugin. This is required for all plugins. If the ID is exactly 4 characters, it will be automatically prefixed with com.cabbageaudio. (e.g., "MyPl" becomes com.cabbageaudio.MyPl). If longer than 4 characters, it’s assumed to be a complete reversed domain name (e.g., "com.mycompany.myplugin").
Package Object
Section titled “Package Object”"package" : { "include": [ {"src": "sample", "dest": "samples"} ], "cabzOutputDir":""}The package object is used to manage the resources required by your instruments when they are exported. The package accepts an array of src/dest pairs. The src value may be a relative or absolute path and can include file wildcards (for example, * or **).
"include": [ {"src": "/Users/me/cabbage3-recipes/samples/*.wav", "dest": "audioSamples"} ]This example copies all .wav files from the samples folder into an audioSamples folder located at the top level of the exported plugin’s resources directory. The dest directory is always the top level directory. If your src is a folder, and you leave out the dest dir, all the files from that folder will be placed in the top-level plugin resource directory. cabzOutputDir is the output location for encrypted resource, available only in the Cabbage pro add-on.
Channel Configuration
Section titled “Channel Configuration”"channelConfig": [ { "name": "Stereo", "ins": "2", "outs": "2" }, { "name": "Mono", "ins": "1", "outs": "1" }]Defines the preferred audio I/O bus configuration for the plugin. In this example, the plugin indicates that both stereo and mono layouts are supported.
See the Audio Channel Configuration documentation for detailed information.
Developer Tools
Section titled “Developer Tools”"enableDevTools": trueWhen set to true, enables the browser developer tools in the plugin window (plugin mode only). Useful for debugging custom JavaScript interfaces.
Logger
Section titled “Logger”"logger": { "enabled": true, "file": "debug.log", "replace": false}Configures file-based logging for debugging (plugin mode only):
enabled: Whether to write debug logs to a filefile: Path to the log file (relative to the .csd file location, or absolute)replace: Iftrue, overwrites the existing log file on plugin initialization; iffalse, appends to it
Complete Example
Section titled “Complete Example”A complete Cabbage JSON structure with top-level configuration:
<Cabbage>{ "pluginId": "MyPl", "channelConfig": [ { "name": "Stereo", "ins": "2", "outs": "2" } ], "widgets": [ { "type": "form", "caption": "My Plugin", "size": {"width": 600, "height": 400} }, { "type": "rotarySlider", "id": "mainGain", "channels": [{ "id": "gain", "range": {"min": 0, "max": 1, "value": 0.5} }] } ], "enableDevTools": false, "logger": { "enabled": false, "file": "debug.log", "replace": true }, "package": { "include": [ {"src": "samples", "dest": "samples"} ] }}</Cabbage>Widget Channels
Section titled “Widget Channels”Each widget has a unique set of properties and associated Csound software channels, defined in JSON format. These channels define parameters and serve as the communication bridge between Cabbage’s graphical interface and the Csound audio engine. Most widget properties can be modified at any time to adjust their appearance or behavior.
Named channels are a central part of the Cabbage architecture: they carry values and parameter updates between the GUI and Csound, forming a software “bus” for data transfer. Every widget must have a channel id. Channel ids can be set at the widget’s top level, but more often they are defined within channel objects that form part of the channels array. The channels array allows multiple channels to be associated with a single widget, enabling extended interactions.
range objects are defined within channel objects. These are used both to name plugin parameters and to define their ranges. A typical channel definition with an embedded range object might look like this:
{ "type": "rotarySlider", "channels": [ { "id": "Gain", "range": { "min": 0, "max": 1, "value": 0, "skew": 1, "increment": 0.01 } } ]}channel.id, in this case "Gain", will be registered as a plugin parameter in a host DAW, with 0 and 1 defining its minimum and maximum range. The cabbageSetValue and cabbageGetValue opcodes can be used to send values back and forth to these channels.
Certain widgets, such as a groupBox, will rarely be set up to function as parameters. In these cases, a top-level id can be set. For example:
{ "type": "groupBox", "id": "adsrPanel"}In such cases, the cabbageSet and cabbageGet opcodes can be used to send JSON data back and forth. Widgets can also combine a top-level id with channel ids. Consider an image widget for example, with multiple channels defined:
{ "type": "image", "channels": [ { "id": "mouseX", "event": "mouseMoveX", "range": {"min": 0, "max": 1000, "defaultValue": 0, "skew": 1, "increment": 0.01} }, { "id": "mouseY", "event": "mouseMoveY", "range": {"min": 0, "max": 1000, "defaultValue": 0, "skew": 1, "increment": 0.01} }, { "id": "image1MousePress", "event": "mousePressLeft" } ]}If no top-level id is set, the channels[0].id channel can be used, but the resulting code might not be very intuitive, for instance, calling cabbageSet to set the color of mouseX doesn’t make much sense. In such cases, it helps to define a more appropriately named top-level id:
{ "type": "image", "id": "frequencyXyPad", "channels": [ { "id": "mouseX", "event": "mouseMoveX", "range": {"min": 0, "max": 1000, "defaultValue": 0, "skew": 1, "increment": 0.01} }, { "id": "mouseY", "event": "mouseMoveY", "range": {"min": 0, "max": 1000, "defaultValue": 0, "skew": 1, "increment": 0.01} }, { "id": "image1MousePress", "event": "mousePressLeft" } ]}Using well-named top-level ids to manage a widget’s visual state offers many benefits, not least when it comes to debugging complex instruments.
JSON doesn’t support comments. If you wish to add comments to your JSON, use a "//" : "This is a comment....." property. The extension will highlight this line to make it stands out from the rest of the JSON code.
Widget Properties
Section titled “Widget Properties”Each and every Cabbage widget has a set of properties that define its behavior and appearance. All properties, except for channels and automatable, can be updated dynamically during run-time. The following properties are common to all widgets:
Bounds
"bounds": {"left":0, "top":0, "width":100, "height":100}- Sets the placement and dimensions of the widget within the main form.
Visible
"visible": true- Determines whether the component is visible.
Active
"active": true- Will disable a widget if set to
false. Interaction is not supported with widgets that haveactiveset tofalse.
Automatable
"automatable": true- Defaults to
true. Determines if a widget is automatable by a host DAW. Automatable widgets show up as plug-in parameters in the host. Non-automatable widgets can still communicate with Csound but are not accessible by the host. Note that hosts do not allow this parameter to change dynamically. If you change this setting, the plugin will need to be reloaded.
Z-Index
"zIndex": 1- Sets the stacking order of the widget. Widgets with higher
zIndexvalues appear in front of widgets with lower values. The default is1.
Each widget also has a unique set of styling properties accessed through the style object. Here, users can control how their widgets look. In a break from Cabbage 2 convention, and to align with CSS/HTML naming schemes, all style properties use CSS-style spelling—for example, background color is listed as backgroundColor. A full list of supported styles, along with all other properties, can be found in each widget’s manual entry.
Plugin Parameters and Automation
Section titled “Plugin Parameters and Automation”All widgets include an automatable property. Only widgets with automatable set to true will appear as automatable parameters in a host environment. Through the named channels, these widgets can be controlled or modulated by the host, ensuring synchronisation between the interface and the audio engine. Many of the stock widgets that ship with Cabbage have their automatable property set to true by default.
Widgets with automatable: false can still send and receive data over named channels, but they will not appear in the list of plugin parameters presented in the DAW. A fileButton is a good example of one such widget. It makes little sense to give the DAW control to open a native file browser dialog. Note that this property cannot be toggled on and off; the host needs to know what is automatable when it loads.
Examples and Documentation
Section titled “Examples and Documentation”Each widget in Cabbage is documented with its properties and available channels. Example .csd files are provided to demonstrate how to integrate the widget into a project and use its channels in practice.