ScriptWebView
The WebView
component allows you to render parts of your UI with the native browser technology on your OS. The integration into HISE is pretty straightforward and it allows bidirectional communication and resource management.
In order to use the Webview, just create it, set its bounds and then give it a root directory and a initial file to render.
Component Properties
There are a few special component properties that can be used to define the behaviour of the WebView
Property | Description |
rootDirectory
|
A folder on your harddrive that will be used as root folder for all URLs |
indexFile
|
A relative file path from the root directory to the HTML file you want to display initially. |
enableCache
|
If this is true, then it will not reload the files from disk and cache every resource that you have requested. Usually you want to keep this off during development and then set it to true when you're done (this property needs to be enabled when you want to embed & export the web resources) |
enablePersistence
|
if true, then every function call and JS code passed into evaluate() will be logged and called when a new webview is created. This allows a persistent state (see below for a more detailed explanation |
In addition to the "trivial" integration of a native webview handle into HISE there are a few quality of life improvements that will make working with a webview in HISE morestraightforward:
Resource management
During development, the files will be loaded from disk but for a compiled plugin you can embed all the resources into your plugin and load it from memory (so that you won't have to distribute the web files to the end user).
The embedding of the resources is purely optional and depends on whether the web resource root directory is a child of the HISE project folder - if it is, then we'll assume that the end user will not have your HISE project folder and embed it, but if the web root is somewhere else (eg. the app data folder) then we'll assume that you will prefer installing the web files on the end user's machine.
Also keep in mind that if you want to embed the resources that have to be loaded at the time you export the plugin.
Automatic scaling
We're still living in plugin-world where responsiveness is not the status quo and the only thing that people have started to expect is to resize the UI while keeping the aspect ratio the same. The zoom level system of HISE is extended into the webview, which means that whenever you change the scaling factor it will resize the UI handle and change the browser's zoom level to match the scale factor (exactly as if you would use Ctrl+/- in your browser).
Persistence
The lifetime of the webview is decoupled from the application state so we need to find a way to tell a webview that was created later to be updated to the current app state. For example if you show the value of a slider in the web view you would want it to display the correct slider value if you close and reopen the plugin window. The way that HISE handles this is that it keeps track of all communication between the HISE layer and the webview and then "repeats" every message after a new webview has been created (think of it as a "recap of everything that happened until now").
There are a few things to keep in mind:
- The WebView should be considered as a pure, stateless UI element that can be destroyed and recreated without interrupting the data model or signal processing of your plugin (since that's how plugins work). Updating the data model will always be the responsibility of HISE.
- The Webview is a native UI handle that is placed on top of the plugin interface. This means that you can't use any alpha blending or masking and put UI elements behind / infront of it.
- During development, this might create a few glitches (the scale factor might be off if you're displaying a webview in the Interface designer, or it might overlap
components there.
Make sure to checkout the tutorial project in the HISE tutorial repo which contains multiple use cases
Class methods
addToMacroControl
Adds the knob / button to a macro controller (from 0 to 7). Edit on GitHub
ScriptWebView.addToMacroControl(int macroIndex)
bindCallback
Binds a HiseScript function to a Javascript callback id.
ScriptWebView.bindCallback( String callbackId, var functionToCall)
This will bind a callable HiseScript object (so either a function, an inline function or a broadcaster) to a function id in the WebView so you can call it from within JS in the web browser. In order to use this, just pass in a function ID that you will then use in JS to call this and a function with a single parameter. This parameter will be an array with all arguments that you pass into the JS function. You can also return a value which will then be used in a JS Promise to be evaluated asynchronously later:
Javascript in your webview:
someFunction({"value": Math.random()}).then ((result) =>
{
console.log(result);
});
HiseScript
wv.bindCallback("someFunction", function(args)
{
Console.print(args.value);
return args.value * 2.0;
});
callFunction
Calls the JS function (in the global scope) with the given arguments.
ScriptWebView.callFunction( String javascriptFunction, var args)
You can use this method in order to (asynchronously) call a JS function that is visible to the global scope (=attached to the global windows). This function should not be called on the audio thread as it involves string allocation and JSON parsing, so make sure you defer the call if you want to react on a MIDI input (or signal cable).
HiseScript
wv.callFunction("someFunction", {"value": Math.random()});
Javascript in your webview:
You will need to define a JS function in your webview code somewhere like this:
// I'm not a web guy, but tucking it to the window object raises the chances of it being
// resolved correctly...
window.someFunction = function(args)
{
console.log(args.value); // something between 0 and 1...
};
Note that there is no return value (because it can't be guaranteed that there is a webview present and if it is the function will be executed asynchronously on the message thread.
changed
Call this to indicate that the value has changed (the onControl callback will be executed. Edit on GitHub
ScriptWebView.changed()
createLocalLookAndFeel
Returns a local look and feel if it was registered before. Edit on GitHub
ScriptWebView.createLocalLookAndFeel(ScriptContentComponent *contentComponent, Component *componentToRegister)
evaluate
Evaluates the code in the web view. You need to pass in an unique identifier so that it will initialise new web views correctly.
ScriptWebView.evaluate( String identifier, String jsCode)
You can tell the WebView to execute any chunk of JS code with this method - it will pass the string to the native browser API so make sure you follow the conventions here (I'm not a web guy lol).
One thing to keep in mind is that you need to pass in a unique ID for each time you call this function. This will store the JS string into a dictionary and then call it with the last JS code when a new WebView is created (to allow persistence).
fadeComponent
Toggles the visibility and fades a component using the global animator. Edit on GitHub
ScriptWebView.fadeComponent(bool shouldBeVisible, int milliseconds)
get
returns the value of the property. Edit on GitHub
ScriptWebView.get(String propertyName)
getAllProperties
Returns a list of all property IDs as array. Edit on GitHub
ScriptWebView.getAllProperties()
getChildComponents
Returns list of component's children Edit on GitHub
ScriptWebView.getChildComponents()
getGlobalPositionX
Returns the absolute x-position relative to the interface. Edit on GitHub
ScriptWebView.getGlobalPositionX()
getGlobalPositionY
Returns the absolute y-position relative to the interface. Edit on GitHub
ScriptWebView.getGlobalPositionY()
getHeight
Returns the height of the component. Edit on GitHub
ScriptWebView.getHeight()
getId
Returns the ID of the component. Edit on GitHub
ScriptWebView.getId()
getLocalBounds
Returns a [x, y, w, h] array that was reduced by the given amount. Edit on GitHub
ScriptWebView.getLocalBounds(float reduceAmount)
getValue
Returns the current value. Edit on GitHub
ScriptWebView.getValue()
getValueNormalized
Returns the normalized value. Edit on GitHub
ScriptWebView.getValueNormalized()
getWidth
Returns the width of the component. Edit on GitHub
ScriptWebView.getWidth()
grabFocus
Call this method in order to grab the keyboard focus for this component. Edit on GitHub
ScriptWebView.grabFocus()
loseFocus
Call this method in order to give away the focus for this component. Edit on GitHub
ScriptWebView.loseFocus()
reset
Resets the entire webview.
ScriptWebView.reset()
This will clear all internal caches of the web view data model which might help with some glitches during development.
sendRepaintMessage
Manually sends a repaint message for the component. Edit on GitHub
ScriptWebView.sendRepaintMessage()
set
Sets the property. Edit on GitHub
ScriptWebView.set(String propertyName, var value)
setColour
sets the colour of the component (BG, IT1, IT2, TXT). Edit on GitHub
ScriptWebView.setColour(int colourId, int colourAs32bitHex)
setConsumedKeyPresses
Registers a selection of key presses to be consumed by this component. Edit on GitHub
ScriptWebView.setConsumedKeyPresses(var listOfKeys)
setControlCallback
Pass a inline function for a custom callback event. Edit on GitHub
ScriptWebView.setControlCallback(var controlFunction)
setIndexFile
Sets the file to be displayed by the WebView. Edit on GitHub
ScriptWebView.setIndexFile(var indexFile)
setKeyPressCallback
Adds a callback to react on key presses (when this component is focused). Edit on GitHub
ScriptWebView.setKeyPressCallback(var keyboardFunction)
setLocalLookAndFeel
Attaches the local look and feel to this component. Edit on GitHub
ScriptWebView.setLocalLookAndFeel(var lafObject)
setPosition
Sets the position of the component. Edit on GitHub
ScriptWebView.setPosition(int x, int y, int w, int h)
setPropertiesFromJSON
Restores all properties from a JSON object. Edit on GitHub
ScriptWebView.setPropertiesFromJSON( var jsonData)
setStyleSheetClass
Sets the given class selectors for the component stylesheet. Edit on GitHub
ScriptWebView.setStyleSheetClass( String classIds)
setStyleSheetProperty
Sets a variable for this component that can be queried from a style sheet. Edit on GitHub
ScriptWebView.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. Edit on GitHub
ScriptWebView.setStyleSheetPseudoState( String pseudoState)
setTooltip
Shows a informative text on mouse hover. Edit on GitHub
ScriptWebView.setTooltip( String tooltip)
setValue
Sets the current value Edit on GitHub
ScriptWebView.setValue(var newValue)
setValueNormalized
Sets the current value from a range 0.0 ... 1.0. Edit on GitHub
ScriptWebView.setValueNormalized(double normalizedValue)
setValueWithUndo
Sets the current value and adds it to the undo list. Don't call this from onControl! Edit on GitHub
ScriptWebView.setValueWithUndo(var newValue)
setZLevel
Changes the depth hierarchy (z-axis) of sibling components (Back, Default, Front or AlwaysOnTop). Edit on GitHub
ScriptWebView.setZLevel(String zLevel)
showControl
Hides / Shows the control. Edit on GitHub
ScriptWebView.showControl(bool shouldBeVisible)
updateContentPropertyInternal
This updates the internal content data object from the script processor. Edit on GitHub
ScriptWebView.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. Edit on GitHub
ScriptWebView.updateValueFromProcessorConnection()