hey there,
id like to create a composition (Parent) class which contains child classes in order to attach a whole set of controls with one Parent Control Class.
Later a Parent Structure should contain many classes and they are all connected together in the parentclass constructor. The Goal is, that when you create a new project, you just include your parentclass of your module and are able to attach it with one line. So you might have a Parentclass EQ which contains everything your EQ Module needs. Later you have modules like EQ, distortion, arpeggiator etc. and you can easily swap them around your projects.
it should be possible for the structure to integrate predefined Iplug Controls and self written controls as well.
here is an example of how i try to achieve it:
Code:
//in plug.h:
ParentClass *PClass;
//in Plug.cpp in mLayoutFunc:
PClass = new ParentClass(this, pGraphics, b, 1, 2);
class ParentClass : public IControl
{
public:
class ToggleButton;
ToggleButton *TButton1;
ToggleButton *TButton2;
ParentClass(IGEditorDelegate *pPlug, IGraphics *pGraphics, IRECT pRect, int Button1Idx,int Button2Idx)
: IControl(*pPlug, pRect) {
TButton1 = new ToggleButton(pPlug, IRECT(pRect.L, pRect.T, pRect.R / 2, pRect.B), Button1Idx);
TButton2 = new ToggleButton(pPlug, IRECT(pRect.R/2, pRect.T, pRect.R, pRect.B), Button2Idx);
pGraphics->AttachControl(TButton1);
pGraphics->AttachControl(TButton2);
}
virtual void Draw(IGraphics& Graphics) override {}
///ChildClass Definition
class ToggleButton : public IControl
{
private:
IGEditorDelegate *pP;
IRECT pR;
bool mState;
public:
ToggleButton(IGEditorDelegate* pPlug, IRECT pRect, int paramIdx)
: IControl(*pPlug, pRect, paramIdx)
{
mDblAsSingleClick = true;
pP = pPlug;
pR = pRect;
}
virtual void Draw(IGraphics& Graphics) override {
if (mState && mValue == 0) {mState = false;}
if (!mState && mValue == 1) {mState = true;}
if (mState) {Graphics.FillRoundRect(COLOR_BLUE, pR, pR.H()*0.2, 0);}
else {Graphics.FillRoundRect(COLOR_ORANGE, pR, pR.H()*0.2, 0);}
}
void OnMouseDown(float x, float y, const IMouseMod& mod) override
{
if (!mState) {mState = true;mValue = 1.0;}
else{mState = false;mValue = 0.0;}
SetDirty();
}
bool GetState() {
return mState;
}
};
};
Description:
i created a class ToggleButton. This class can be used on its own directly from mLayoutFunc. In this case ToggleButton is defined within the Parentclass ParentClass ,so its code is as close by as possible.
Then two ToggleButtons are attached in the ParentClass Constructor.
So far so good. The Problem(s):
this example works - except for when a function of its members gets called from within process block before mLayoutFunc has been executed. e.g. PClass->TButton1->GetState();
On Plug Startup processblock gets called before mLayoutFunc. So if there is a Function in the Processblock eg:
if(Grid->SamplePosIsInGrid(1,16) {
PClass->TButton1->GetState();
}
it crashes because, the ParentClass Pointer (PClass) has yet no Adress of a ParentClass.
So my workaround for this was: bypassing everything in processblock until mlayountfunc is finished attaching all controls. but i think thats not very elegant.
in my world having access to pGraphics before processblock gets called, would solve it - but my c++/iplug/dsp knowledge is small and i was told, that this is not the way how to approach the goal.
The hints i got so far are:
its not adviseable to call UI stuff from the audio thread. - i dont understand how to achieve something like, a circle changes color every 1/16th, when not calling the function changecolor from the audiothread, when the samplePos is the right one for 1/16th.
it seems i have a fundamental missunderstanding of how this works, and i have trouble to get my head around it - so id be eternally thankful for help to clear this up a little more :-)