|
MostlyHarmless 0.0.1
|
An opinionated subclass of WebviewBase, providing default impls for bidirectional comms. More...
#include <mostlyharmless_WebviewEditor.h>
Public Member Functions | |
| WebviewEditor (core::ISharedState *sharedState, std::uint32_t initialWidth, std::uint32_t initialHeight, Colour backgroundColour) | |
| ~WebviewEditor () noexcept override=default | |
| void | initialise () override |
| bool | allowResize () const noexcept override |
| void | onResizeRequested (std::uint32_t *newWidth, std::uint32_t *newHeight) override |
| void | onParamEvent (events::ProcToGuiParamEvent event) override |
| virtual void | sendEvent (events::WebEvent &&event) noexcept |
| Public Member Functions inherited from mostly_harmless::gui::WebviewBase | |
| WebviewBase (std::uint32_t initialWidth, std::uint32_t initialHeight, Colour backgroundColour) | |
| ~WebviewBase () noexcept override | |
| void | setOptions (Options &&options) noexcept |
| void | destroy () override |
| void | setSize (std::uint32_t width, std::uint32_t height) override |
| void | getSize (std::uint32_t *width, std::uint32_t *height) override |
| void | setParent (void *parentHandle) override |
| void | show () override |
| void | hide () override |
| Public Member Functions inherited from mostly_harmless::core::IEditor | |
| virtual | ~IEditor () noexcept=default |
Protected Member Functions | |
| virtual choc::value::Value | beginParamChangeGestureCallback (const choc::value::ValueView &args) |
| virtual choc::value::Value | paramChangeGestureCallback (const choc::value::ValueView &args) |
| virtual choc::value::Value | endParamChangeGestureCallback (const choc::value::ValueView &args) |
Protected Attributes | |
| core::ISharedState * | m_sharedState { nullptr } |
| struct { | |
| std::optional< std::pair< std::uint32_t, std::uint32_t > > lastMouseDownLocation {} | |
| std::optional< std::pair< std::uint32_t, std::uint32_t > > lastMousePosition {} | |
| } | m_cursorState |
| Protected Attributes inherited from mostly_harmless::gui::WebviewBase | |
| choc::ui::WebView * | m_internalWebview { nullptr } |
An opinionated subclass of WebviewBase, providing default impls for bidirectional comms.
Where WebviewBase handles lower level things like window creation / management, this class handles slightly higher level details - namely, an event system, and param updates.
To use it, you'll probably want to still subclass it, but the boilerplate will be fairly minimal. See WebviewBase for more fine grained details.
The default implementation establishes bindings to several javascript functions. Firstly the ones pertaining to parameter updates: beginParamGesture(), setParamValue(), and endParamGesture().
Each of these functions take an object as an arg, expected to be formatted as json containing the paramId to affect, and the value to set. For example:
beginParamGesture is expected to be called when a slider first begins being dragged, setParamValue while it is being changed, and endParamValue once the user stops dragging. These functions are bound to internal native functions (which you can override if you like), beginParamChangeGestureCallback(), paramChangeGestureCallback(), and endParamChangeGestureCallback(). These functions are actually promises, which we don't really leverage here, aside from to report errors in the case of an arg-parsing failure. The default implementation will attempt to parse the args (and assert fail if it failed), and then enqueue the param changes to the guiToProcQueue, for the host and audio side to pick up.
For what I've been calling "ouroborosing" the cursor position, and generally providing the facilities to hide the cursor, snap back to original mouse down position on a drag etc, we also provide some extra helpers here. beginScopedCursorMoveGesture() caches the mouse down position at the time of calling, and hides the cursor. endScopedCursorMoveGesture() restores the cached cursor position, and shows the cursor. These functions should be called as a pair, for a slider in mouseDown / mouseUp for example.
resetCursorPosition() does much the same as endScopedCursorMoveGesture(), except it doesn't zero any of the internally cached variables, and doesn't show the cursor. The use case is quite different, and is for forcing the cursor to be within a given area - this allows for "infinite drag", or "ouroborosing" without the cursor hitting the screen edges. If resetCursorPosition() is used, then to avoid unexpected jumps, use tickCursorMove(), and use its return value instead of the js side event.movementY variable. It updates the internal cache of the last mouse position, and then returns the difference between the old and new values. Call it every time mousemove is called for example. clearPreviousCursorPosition() in this paradigm should be called on mouseUp, and simply nulls the last mouse position stored in the cache, preparing it for a new gesture.
As the cursor cannot be hidden in Logic Pro or Garageband, we also provide a cacheCursorPosition() bindings - this is to allow you to use the same tick... system as outlined above, with minimal special case handling for these hosts.
The structure of an event in the default implementation is:
So to respond to this, you can register an event listener:
This function is called by the default implementation of onParamEvent(). The event is structured as:
for example,
| mostly_harmless::gui::WebviewEditor::WebviewEditor | ( | core::ISharedState * | sharedState, |
| std::uint32_t | initialWidth, | ||
| std::uint32_t | initialHeight, | ||
| Colour | backgroundColour ) |
| initialWidth | The initial width for the webview. |
| initialHeight | The initial height for the webview. |
| backgroundColour | The colour to paint the actual window beneath the webview. |
|
overridedefaultnoexcept |
Default destructor.
|
nodiscardoverridevirtualnoexcept |
See IEditor::allowResize for a detailed explanation, overridden here to demonstrate that it's still implementable in your editor.
Reimplemented from mostly_harmless::gui::WebviewBase.
|
protectedvirtual |
Called internally by any javascript side calls to beginParamGesture(). Informs the host/audio thread that a change gesture has started.
| context | The editor context. |
| args | The args provided by the frontend. |
|
protectedvirtual |
Called internally by any javascript side calls to 'endParamGesture()`. Informs the host/audio thread that a change gesture has ended.
| context | The editor context. |
| args | The args provided by the frontend. |
|
overridevirtual |
Called immediately after the gui has been created - use this to perform any post-creation initialisation.
Reimplemented from mostly_harmless::gui::WebviewBase.
|
overridevirtual |
Called when the host sends a param update, to inform the gui that a change has occurred.
Actually gets invoked from a timer thread, on the message thread.
This is still virtual, and can be overridden as you like, but the default implementation will call sendEvent() with a WebEvent constructed from the event passed from the param queue - see sendEvent() for more details.
| event | An event specifying |
Implements mostly_harmless::gui::WebviewBase.
|
overridevirtual |
See IEditor::onResizeRequested for a detailed explanation, overridden here to demonstrate that it's still implementable in your editor.
Reimplemented from mostly_harmless::gui::WebviewBase.
|
protectedvirtual |
Called internally by any javascript side calls to 'setParamValue()`. Informs the host/audio thread that an adjustment was made, as part of a change gesture.
| context | The editor context. |
| args | The args provided by the frontend. |
|
virtualnoexcept |
Sends a javascript event to the internal webview.
You're also totally free to overload this if you don't like the default impl - see events::WebEvent for details about the WebEvent structure.
| event | An rvalue ref to the event to dispatch - you can create arbitrary custom types of event. |
| std::optional<std::pair<std::uint32_t, std::uint32_t> > mostly_harmless::gui::WebviewEditor::lastMouseDownLocation {} |
| std::optional<std::pair<std::uint32_t, std::uint32_t> > mostly_harmless::gui::WebviewEditor::lastMousePosition {} |
| struct { ... } mostly_harmless::gui::WebviewEditor::m_cursorState |
|
protected |