ASPiK SDK
Loading...
Searching...
No Matches
Alter the PluginGUI Object

With the object designed and the ICustomView interface implemented, you can turn your attention to the plugingui.cpp file. The function that is called to give the object the first opportunity to create a custom view is named createView( ):

CView* PluginGUI::createView(const UIAttributes& attributes, const IUIDescription* description)

The attributes and description arguments come from the GUI class factory that calls the method and contains all the information gleaned from the XML description file. One piece of that information is the custom view name, which is what we use to decode the data and instantiate the view. We’ve already setup a secondary function createUserCustomView( ) that will do some of the decoding work for you. You may either append your custom views to that function, or modify the function above. In the case of the waveform and spectrum views we’ll use the secondary function. For other controls, you will need to work inside of createView( ) where you can have access to all of the attribute and description information. You can see that this function is simple - we just decode the name string and then create a new object.

CView* PluginGUI::createUserCustomView(std::string viewname, const CRect rect, IControlListener* listener, int32_t tag)
{
if (viewname.compare("CustomWaveView") == 0)
{
// --- create our custom view
return new WaveView(rect, listener, tag);
}
return nullptr;
}
//

The part of createView that calls this function is shown here. This is where the ICustomView pointer is obtained from the newly created object and safely sent to the plugin shell using the IGUIPluginConnector interface pointer that it obtained during its creation:

// --- try a user view first
CView* userCV = createUserCustomView(viewname, rect, listener, tag);
if (userCV)
{
// --- register custom view it with the plugin for updates
if (hasICustomView(userCV))
{
if (guiPluginConnector)
guiPluginConnector->registerCustomView(viewname, dynamic_cast<ICustomView*>(userCV));
}
return userCV;
}
//
@enecode
In this case, the ICustomView is obtained by simply casting the custom view object and that is registered with the IGUIPluginConnector interface. <br>
<br>
The SpectrumView object is designed in a similar manner but uses a double-ring-free-buffer scheme (mostly as an example) in its implementation. The <strong>createUserCustomView</strong> function is then modified to decode the custom view name "CustomSpectrumView" and similarly creates and registers the custom view - see the demo project example for all of the details.<br>
<br>
The custom knob view object is designed by subclassing CAnimKnob from VSGUI4 and deriving it from ICustomView so that it exposes the interface. For the knob example, we are just going to show how to set up a communication system with *ANY* custom view so it does not contain any specialized drawing code. We will simply "talk" to the knob object and get a reply from it as proof of concept for your own custom views. You can find the code that decodes, creates and registers this custom knob in the <strong>PluginGUI::createView( )</strong> function, just below the portion of code that calls our added function <strong>createUserCustomView( )</strong> above.<br>
<br>
*/
Custom View interface to allow plugin core to create safe communication channels with GUI custom view...
Definition: pluginstructures.h:1462
Custom interface so that GUI can pass information to plugin shell in a thread-safe manner.
Definition: pluginstructures.h:1540

The next step is to pick up these pointers when the native plugin shell registers them with the plugin core object. This is done in the plugincore.cpp file inside of the PluginCore::processMessage( ) which handles GUI events from the native plugin shell (don't worry, this is thread-safe). There are numerous messages that are decoded in this function, but we only need to deal with a couple of them:

PLUGINGUI_REGISTER_CUSTOMVIEW: this message is sent once per custom view, each time the GUI is opened. Once you have stored a custom view interface pointer, you don't need to ever re-copy or re-store it. However this function WILL be called when the GUI is opened so you can use it (in part) to know a bit about the lifecycle of the GUI.

PLUGINGUI_TIMERPING: this message is sent on every GUI update interval (50 msec) and is called from the GUI thread. This is where we will feed audio samples into the custom views and call the methods to update (repaint) these windows. Since this function is called from the GUI thread, we need that lock-free ring buffer on our plugin side to hold audio data from the audio processing thread.

To pick up and store the interface pointers, you modify the code for the PLUGINGUI_REGISTER_CUSTOMVIEW to decode the incoming name string and store the pointer. This code is just for the two custom audio viewers; we'll address the custom knob later. User the example below to see how the pointers are passed into the message system - make sure you understand this if you want to modify it for your own custom messaging or other uses.

{
// code snipped out
case PLUGINGUI_REGISTER_CUSTOMVIEW:
{
// --- decode name string
if (messageInfo.inMessageString.compare("CustomWaveView") == 0)
{
// --- (1) get the custom view interface via incoming message data*
if (waveView != static_cast<ICustomView*>(messageInfo.inMessageData))
waveView = static_cast<ICustomView*>(messageInfo.inMessageData);
if (!waveView) return false;
// --- registered!
return true;
}
if (messageInfo.inMessageString.compare("CustomSpectrumView") == 0)
{
// --- (1) get the custom view interface via incoming message data*
if (spectrumView != static_cast<ICustomView*>(messageInfo.inMessageData))
spectrumView = static_cast<ICustomView*>(messageInfo.inMessageData);
if (!spectrumView) return false;
// --- registered!
return true;
}
//
virtual bool processMessage(MessageInfo &messageInfo)
For Custom View and Custom Sub-Controller Operations.
Definition: plugincore.cpp:546
Information that includes the message code as well as the message data.
Definition: pluginstructures.h:706
void * inMessageData
incoming message data (interpretation depends on message)
Definition: pluginstructures.h:733
std::string inMessageString
incoming message data as a std::string (interpretation depends on message)
Definition: pluginstructures.h:736