ScriptPanel
Create a reference to a Panel UI component and modify its values.
const var Panel1 = Content.getComponent("Panel1");
Class methods
addChildPanel
Adds a child panel to this panel.
ScriptPanel.addChildPanel()
This function will create and return an anonymous panel and add it to the panel as child component (similar to setting the parentComponent
property). However there are two important differences:
- You can call this function any time and add (and remove) these panels after the onInit callback.
- The panels that you create with this method will not be listed in the component list (and therefore can not store / restore their value with user presets et al).
The main use case for this method is to create dynamic components which have a varying amount of sub-elements: tables with modulation connections, effect slots, and basically anything that has a dynamic amount that can be changed in your script.
Be aware that these panels are not accessible to the interface designer, so you have to set every property using scripting API calls.
You can call this method again on the new panel and create a nested architecture of child panels. In order to delete the panel (and any child panel), use the removeFromParent() method.
For an example use case, take a look at the Horizontal List Recipe
addToMacroControl
Adds the knob / button to a macro controller (from 0 to 7).
ScriptPanel.addToMacroControl(int macroIndex)
changed
Call this to indicate that the value has changed (the onControl callback will be executed.
ScriptPanel.changed()
closeAsPopup
Closes the popup manually.
ScriptPanel.closeAsPopup()
createLocalLookAndFeel
Returns a local look and feel if it was registered before.
ScriptPanel.createLocalLookAndFeel(ScriptContentComponent *contentComponent, Component *componentToRegister)
fadeComponent
Toggles the visibility and fades a component using the global animator.
ScriptPanel.fadeComponent(bool shouldBeVisible, int milliseconds)
get
returns the value of the property.
ScriptPanel.get(String propertyName)
getAllProperties
Returns a list of all property IDs as array.
ScriptPanel.getAllProperties()
getAnimationData
Returns a JSON object containing the data of the animation object.
ScriptPanel.getAnimationData()
This method will return an object containing the properties of the current animation in this panel:
Property | Description |
active
|
whether an animation is active. This might be false if the animation couldn't be loaded. |
currentFrame
|
the current frame that is displayed. You can use this in the timer callback to increase it in order to create a moving image. |
numFrames
|
the total number of frames in this animation. |
frameRate
|
the suggested framerate. You don't need to use this value, but you might want to call Panel.startTimer(1000.0 / data.frameRate)
with it. |
These properties will be updated if you load another animation or change the frame, so you just need to call this method once and then access its properties.
getChildComponents
Returns list of component's children
ScriptPanel.getChildComponents()
getChildPanelList
Returns a list of all panels that have been added as child panel.
ScriptPanel.getChildPanelList()
This creates an array with references to all panels that have been created using addChildPanel()
. Be aware that this only takes one level of hierarchy into account, so if you have nested child panels, the list will only contain the top level panels.
See addChildPanel()
, getParentPanel()
and removeFromParent()
getGlobalPositionX
Returns the absolute x-position relative to the interface.
ScriptPanel.getGlobalPositionX()
getGlobalPositionY
Returns the absolute y-position relative to the interface.
ScriptPanel.getGlobalPositionY()
getHeight
Returns the height of the component.
ScriptPanel.getHeight()
getId
Returns the ID of the component.
ScriptPanel.getId()
getLocalBounds
Returns a [x, y, w, h] array that was reduced by the given amount.
ScriptPanel.getLocalBounds(float reduceAmount)
getParentPanel
Returns the panel that this panel has been added to with addChildPanel.
ScriptPanel.getParentPanel()
getValue
Returns the current value.
ScriptPanel.getValue()
getValueNormalized
Returns the normalized value.
ScriptPanel.getValueNormalized()
getWidth
Returns the width of the component.
ScriptPanel.getWidth()
grabFocus
Call this method in order to grab the keyboard focus for this component.
ScriptPanel.grabFocus()
isImageLoaded
Checks if the image has been loaded into the panel
ScriptPanel.isImageLoaded(String prettyName)
isVisibleAsPopup
Returns true if the popup is currently showing.
ScriptPanel.isVisibleAsPopup()
loadImage
Loads a image which can be drawn with the paint function later on.
ScriptPanel.loadImage(String imageName, String prettyName)
loseFocus
Call this method in order to give away the focus for this component.
ScriptPanel.loseFocus()
removeFromParent
Removes the panel from its parent panel if it was created with addChildPanel().
ScriptPanel.removeFromParent()
If you want to remove a panel from the interface that has been created with addChildPanel()
, call this method and it will remove the panel from the parent and update the UI.
repaint
Triggers an asynchronous repaint.
ScriptPanel.repaint()
repaintImmediately
Calls the paint routine immediately.
ScriptPanel.repaintImmediately()
set
Sets the property.
ScriptPanel.set(String propertyName, var value)
setAnimation
Sets an JSON animation.
ScriptPanel.setAnimation(String base64LottieAnimation)
You can use Lottie
animation files to be displayed in a ScriptPanel.
Just load an animation into the Lottie Developer Panel , compress it to a Base64 string and give it to this method and you can start using the frames inside the animation with setAnimationFrame .
Be aware that there is no built in animation functionality, but you can easily create "moving images" by using the timer callback
for it.
setAnimationFrame
Sets a frame to be displayed.
ScriptPanel.setAnimationFrame(int numFrame)
Once you've loaded an animation into the panel with setAnimation
, you can call this method and supply the frame index you want to display.
Calling this method will pick the frame and immediately repaint the panel.
In order to find out, which frame you want to display, use the getAnimationData method which returns an object with the animation specs.
setColour
sets the colour of the component (BG, IT1, IT2, TXT).
ScriptPanel.setColour(int colourId, int colourAs32bitHex)
setConsumedKeyPresses
Registers a selection of key presses to be consumed by this component.
ScriptPanel.setConsumedKeyPresses(var listOfKeys)
A key stroke from your computer keyboard can be registered to fire a callback using ScriptPanel.setKeyPressCallback()
. However if you do this, you most likely want this key stroke to be "consumed" (so it won't trigger other actions as it progresses upwards the component tree).
Before this method was introduced, you had to return true
in the callback for a consumed key press (the JUCE keyboard callbacks work similar to this so I copied the behaviour), but that forced the callback to run synchronously in the message thread which is not ideal - also if you forget to return true (which everybody
did), the callback ended up being fired multiple times which caused some irritations.
So instead this method was introduced that you must call before
calling setKeyPressCallback()
with either a single key press "object" or an array of key presses. A key press object can be either a string description of the key press like it's supplied in the callback argument or a JSON object like the callback parameter.
You can also use the special string "all"
to make the component consume every single key stroke, which is the default behaviour when you don't call this method (so compiled plugins will still work as they don't report compilation errors).
There is another special string "all_nonexclusive"
that you can pass into this function which will fire the script callback for each key press but not consume it so it can be processed further (a use case for this would be to attach additional functionality to a ScriptLabel
)
By using the same format as the callback parameter you can use this procedure for creating the filter list:
- Call this function with "all".
- Register a key callback, then dump the parameter JSON object.
- Hit the key combination(s) that you want to consume.
- Copy the JSON objects from the console into this function call.
- Cleanup and paste the objects back into the first function call
So if you use this:
const var panel = Content.addPanel("p", 0, 0);
panel.setConsumedKeyPresses("all");
panel.setKeyPressCallback(function(obj)
{
Console.print(trace(obj));
});
then clicking on the panel (to gain focus) and pressing any key will yield something like this output:
Interface: {
"isFocusChange": false,
"character": "",
"specialKey": true,
"isWhitespace": false,
"isLetter": false,
"isDigit": false,
"keyCode": 63238,
"description": "shift + F3",
"shift": true,
"cmd": false,
"alt": false
}
This JSON object is a bit noisy as it provides additional information that we don't really need so we can reduce the number of required properties and paste it back into our first function call:
panel.setConsumedKeyPresses({
"keyCode": 63238,
"shift": true,
"cmd": false,
"alt": false
});
So from now on, the function will only react on "Shift + F3 key presses". If you use a single key press this also brings the additional benefit of not having to branch at all so you can just rawdog your logic into the callback without any if checks.
setControlCallback
Pass a inline function for a custom callback event.
ScriptPanel.setControlCallback(var controlFunction)
setDraggingBounds
If allowedDragging
is enabled, it will define the boundaries where the panel can be dragged.
ScriptPanel.setDraggingBounds(var area)
setFileDropCallback
Sets a file drop callback.
ScriptPanel.setFileDropCallback(String callbackLevel, String wildcard, var dropFunction)
This function allows a file to be dropped on the panel that you can use for any purpose. It's basically the same functionality as the FileSystem.browse()
call, but with a different UX that some people might prefer over the native file dialogue.
The function expects three parameters, the first one will determine at which events the callback will be exeucted and must be one of these Strings (similar to the callbackLevel
property):
String | Description |
"No Callbacks"
|
Ignore all file drag operations (default). |
"Drop Only"
|
Only fires the callback when the file was dropped. |
"Drop & Hover"
|
Additionally fires a callback when a dragged file enters / exits the panel. |
"All Callbacks"
|
Also fires the callback when you move the dragged file inside the panel. |
If you pass in an empty String, it will deactivate the callback like "No Callbacks"
. You can use this parameter to limit the execution of the callback to match your implementation: if you only want to react to a file being dropped, then use "Drop Only"
and the other callback levels offer a way for you to change the UI to let the user know that the file can be dropped (on top of the OS-native mouse cursor change).
The second parameter is a wildcard that filters the file types that can be dropped on the panel. The format is the usual file wildcard format, so *.txt
or *.*
.
If you want multiple wildcards, use a semicolon or comma: *.aiff,*.wav,*.mp3
.
The third parameter is the function that is executed at all events specified by the callback level parameter. It must be a (inline) function with a single parameter that contains a JSON object with the file drop status information:
Property | Type | Event | Description |
x
|
int
|
Move, Enter, Drop | the x
position relative to the top left of the panel of the drag event. |
y
|
int
|
Move, Enter, Drop | the y
position relative to the top left of the panel of the drag event. |
hover
|
bool
|
Move, Enter, Drop, Exit | true
if the file is currently being dragged over the panel. |
drop
|
bool
|
Move, Enter, Drop, Exit | true
if the file is being dropped. |
fileName
|
String
|
Drop | The absolute path of the file being dropped. |
If you need a File object from the file being dropped, just use the new FileSystem.fromAbsolutePath() method
If you want to store the filename as value in a user preset, you need to wrap the String into a JSON object like this:
Panel1.setFileDropCallback("All Callbacks", "*.wav", function(f)
{
if(f.drop)
{
// We can't pass in only the filename
// (a String is forbidden as preset value in order
// to prevent subtle bugs) so we need to create
// a simple object with a single property
var x = {};
x.fileName = f.fileName;
// We could also just have passed in f to the function,
// but this reduces the noise a bit
this.setValue(x);
this.changed();
}
});
inline function onPanel1Control(component, value)
{
// This might be empty (at initialisation or for whatever reason)...
if(isDefined(value.fileName))
{
var myFile = FileSystem.fromAbsolutePath(value.fileName);
// Do something with myFile...
}
};
setImage
Disables the paint routine and just uses the given (clipped) image.
ScriptPanel.setImage(String imageName, int xOffset, int yOffset)
setIsModalPopup
If this is set to true, the popup will be modal with a dark background that can be clicked to close.
ScriptPanel.setIsModalPopup(bool shouldBeModal)
setKeyPressCallback
Adds a callback to react on key presses (when this component is focused).
ScriptPanel.setKeyPressCallback(var keyboardFunction)
If you want the Panel to react on key strokes (from the computer keyboard, not the MIDI controller), you can attach a function with this method.
The function you pass in must have a single parameter which will contain the details of the key that was pressed (see below).
You will also need to call setConsumedKeyPresses() and supply a list of key presses that you expect this component to consume (and not doing this will cause a compilation error to ensure that you don't accidentaly forget this and cause other issues later down the line).
This is a breaking change introduced in May 2024 to ensure that the callbacks can be executed asynchronously to match the behaviour of Content.setKeyPress() .
If it is not consumed, the key press will trickle down the parent hierarchy until it finds a suitable target, so in order to avoid multiple actions with a single key press, make sure to register any key press if appropriate.
Also be aware that this function can be used with each component type (Labels, Buttons, etc), it's not limited to ScriptPanels
In addition to the event of a key press, this function will also be called when the keyboard focus shifts towards or from this component. This can be used to refresh the appearance and indicate in some way that the Panel is focused (or not).
Property | Type | Description |
isFocusChange
|
bool
|
whether this callback was invoked because of a focus change (or a key press) |
hasFocus
|
bool
|
if the callback was invoked because of a focus change, this will indicate whether it has the focus or not. |
character
|
String
|
a character representation for the given key press. This is case sensitive, so pressing Shift+A will result in A
, while pressing A
without the shift modifier will result in a
. |
keyCode
|
int
|
the ASCII code for the key press. This can be also used to check for special keys. |
specialKey
|
bool
|
this is true if the key press is not a printable character, eg. F5
or backspace
. You can still fetch the key codes to distinguish the events. |
description
|
String
|
A textual representation of the key press, which is helpful during debugging. |
shift
|
bool
|
whether the shift key was held down. |
cmd
|
bool
|
whether the command (or ctrl) key was held down. |
alt
|
bool
|
whether the alt key was held down. |
If you want to "complete" the text input, you might want to call ScriptPanel.loseFocus() from inside the callback.
This example snippet will turn a Panel into a very simple Label:
const var Panel1 = Content.getComponent("Panel1");
Panel1.setPaintRoutine(function(g)
{
g.fillAll(0x22FFFFFF);
g.setColour(0x55FFFFFF);
if(this.data.hasFocus)
g.drawRect(this.getLocalBounds(0), 1.0);
g.setColour(Colours.white);
g.drawAlignedText(this.data.text, this.getLocalBounds(0), "centred");
});
Panel1.setKeyPressCallback(function(obj)
{
// Take a look at this in the console
Console.print(trace(obj));
if(obj.isFocusChange)
{
this.data.hasFocus = obj.hasFocus;
}
else
{
switch(obj.keyCode)
{
// ESCAPE: Delete the text
case 27: this.data.text = "";
break;
// RETURN KEY: just lose the focus
case 13: this.loseFocus();
break;
// BACKSPACE: Remove the last character
case 8: this.data.text = this.data.text.substring(0, this.data.text.length-1);
break;
// Append any non-special character
default: if(!obj.specialKey)
this.data.text += obj.character;
}
}
this.repaint();
});
setLoadingCallback
Sets a loading callback that will be called when the preloading starts or finishes.
ScriptPanel.setLoadingCallback(var loadingCallback)
The loading of samples will be executed asynchronously on a background thread (in fact the same thread used for streaming the samples).
If you call Sampler.loadSampleMap()
or any other function that changes the sample content, it will kill all voices, load it on the background thread.
If you want your UI to reflect this behaviour, you can use a ScriptPanel as "loading indicator". Just register a function with this method and change the appearance accordingly:
// Example: Preloading callback
// this code will add a panel which will flash white during the preloading of new samples.
const var panel = Content.addPanel("Panel", 0, 0);
panel.data.colour = Colours.grey;
panel.setPaintRoutine(function(g)
{
g.fillAll(this.data.colour);
});
// This function will be executed whenever the preload state changes
panel.setLoadingCallback(function(isPreloading)
{
if(isPreloading)
this.data.colour = Colours.white;
else
this.data.colour = Colours.grey;
// Update the UI
this.repaint();
});
Note that there is now a better way of handling events of a samplemap. This function is suited for displaying progress bars and other "soft" targets, but if you want to implement some kind of data logic that depends on the correct order of execution, take a look at Broadcaster.attachToSampleMap() for a much more fine-grained tool for the job.
setLocalLookAndFeel
Attaches the local look and feel to this component.
ScriptPanel.setLocalLookAndFeel(var lafObject)
setMouseCallback
Sets a mouse callback.
ScriptPanel.setMouseCallback(var mouseCallbackFunction)
setMouseCursor
Sets a Path as mouse cursor for this panel.
ScriptPanel.setMouseCursor(var pathIcon, var colour, var hitPoint)
setPaintRoutine
Sets a paint routine (a function with one parameter).
ScriptPanel.setPaintRoutine(var paintFunction)
setPanelValueWithUndo
Sets a new value, stores this action in the undo manager and calls the control callbacks.
ScriptPanel.setPanelValueWithUndo(var oldValue, var newValue, var actionName)
setPopupData
Sets a FloatingTile that is used as popup. The position is a array [x , y, width, height] that is used for the popup dimension
ScriptPanel.setPopupData(var jsonData, var position)
setPosition
Sets the position of the component.
ScriptPanel.setPosition(int x, int y, int w, int h)
setPropertiesFromJSON
Restores all properties from a JSON object.
ScriptPanel.setPropertiesFromJSON( var jsonData)
setStyleSheetClass
Sets the given class selectors for the component stylesheet.
ScriptPanel.setStyleSheetClass( String classIds)
setStyleSheetProperty
Sets a variable for this component that can be queried from a style sheet.
ScriptPanel.setStyleSheetProperty( String variableId, var value, String type)
setStyleSheetPseudoState
Programatically sets a pseudo state (:hover, :active, :checked, :focus, :disabled) that will be used by the CSS renderer.
ScriptPanel.setStyleSheetPseudoState( String pseudoState)
setTimerCallback
Sets a timer callback.
ScriptPanel.setTimerCallback(var timerCallback)
setTooltip
Shows a informative text on mouse hover.
ScriptPanel.setTooltip( String tooltip)
setValue
Sets the current value
ScriptPanel.setValue(var newValue)
setValueNormalized
Sets the current value from a range 0.0 ... 1.0.
ScriptPanel.setValueNormalized(double normalizedValue)
setValueWithUndo
Sets the current value and adds it to the undo list. Don't call this from onControl!
ScriptPanel.setValueWithUndo(var newValue)
setZLevel
Changes the depth hierarchy (z-axis) of sibling components (Back, Default, Front or AlwaysOnTop).
ScriptPanel.setZLevel(String zLevel)
showAsPopup
Opens the panel as popup.
ScriptPanel.showAsPopup(bool closeOtherPopups)
showControl
Hides / Shows the control.
ScriptPanel.showControl(bool shouldBeVisible)
startExternalFileDrag
Starts dragging an external file (or a number of files).
ScriptPanel.startExternalFileDrag(var fileOrFilesToDrag, bool moveOriginalFiles, var finishCallback)
startInternalDrag
Starts dragging something inside the UI.
ScriptPanel.startInternalDrag(var dragData)
unloadAllImages
Unload all images from the panel.
ScriptPanel.unloadAllImages()
updateContentPropertyInternal
This updates the internal content data object from the script processor.
ScriptPanel.updateContentPropertyInternal(int propertyId, var newValue)
updateValueFromProcessorConnection
Updates the value from the processor connection. Call this method whenever the module state has changed and you want to refresh the knob value to show the current state.
ScriptPanel.updateValueFromProcessorConnection()