cc_
10-13-2009, 06:46 AM
As requested, here's my spinner control, a text control you change by dragging like a knob. It's all pretty obvious except for the altParameter - that can be used when you don't have a real plugin parameter, but want the control to display like a parameter - eg an enumerated field or an integer.
In IControl.h:
/* Spinner is text you can change like a knob. Usually it displays
* the value of the parameter it is linked to. If showParam == false
* it doesn't show the parameter, you can set what it displays just
* like a TextControl. If it isn't linked to a parameter you can
* specify a pointer to an IParam altParameter which it will use instead
* (having a parameter makes it much more useful because it can display
* enums, or integers or whatever).
* If altParameter is specified then it will be kept updated as the
* control changes - there's no locking, so this parameter should only
* be used from the gui code (but that's what you wanted or you would
* have used a real parameter)
*/
class ISpinnerControl : public ITextControl
{
public:
ISpinnerControl(IPlugBase* pPlug, IRECT* pR, int paramIdx,
IText* pText, IParam *altParam=NULL, bool showParam = true,
bool showParamLabel = true,
EDirection direction = kVertical,double gearing = DEFAULT_GEARING);
~ISpinnerControl() {}
virtual void OnMouseDrag(int x, int y, int dX, int dY, IMouseMod* pMod);
virtual void OnMouseWheel(int x, int y, IMouseMod* pMod, int d);
virtual bool Draw(IGraphics* pGraphics);
protected:
EDirection mDirection;
double mGearing;
bool mShowParam;
bool mShowParamLabel;
IParam *mAltParam;
};
In IControl.cpp:
ISpinnerControl::ISpinnerControl (IPlugBase* pPlug, IRECT* pR, int paramIdx,
IText* pText, IParam *altParam, bool showParam,
bool showParamLabel,
EDirection direction,double gearing)
: ITextControl(pPlug, pR, pText),
mAltParam(altParam),mShowParam(showParam),mShowPar amLabel(showParamLabel),
mDirection(direction), mGearing(gearing)
{
mParamIdx=paramIdx;
}
void ISpinnerControl::OnMouseDrag(int x, int y, int dX, int dY, IMouseMod* pMod)
{
double delta = (mDirection == kVertical) ?
(double) dY / (double) (mRECT.T - mRECT.B) / mGearing :
(double) dX / (double) (mRECT.R - mRECT.L) / mGearing;
mValue += delta;
SetDirty();
}
void ISpinnerControl::OnMouseWheel(int x, int y, IMouseMod* pMod, int d)
{
double step = 0.01;
if (mParamIdx >= 0) {
step = mPlug->GetParam(mParamIdx)->GetStep();
}
else if (mAltParam) {
step = mAltParam->GetStep();
}
// parameters of type double return a step of 0
if (step != 0.0) {
// 30/3/9: currently this doesn't work very well because
// the mouse wheel stuff in IPlug doesn't handle fractions
// as it should
mValue += d * step;
}
else {
if (pMod->C || pMod->S) {
mValue += 0.001 * d;
}
else {
mValue += 0.01 * d;
}
}
mValue = BOUNDED(mValue,0.0,1.0);
SetDirty();
}
bool ISpinnerControl::Draw(IGraphics* pGraphics)
{
if ( mAltParam ) {
mAltParam->SetNormalized(mValue);
}
// if it's linked to a paramter we can draw it using ICaptionControl
// otherwise just use the text stored ITextControl (which can
// be updated using SetTextFromPlug)
if (mShowParam) {
IParam* pParam= ( mParamIdx>=0 ) ? mPlug->GetParam(mParamIdx) :
mAltParam;
if ( pParam ) {
char cStr[32];
pParam->GetDisplayForHost(cStr);
mStr.Set(cStr);
if (mShowParamLabel) {
mStr.Append(" ");
mStr.Append(pParam->GetLabelForHost());
}
}
}
return ITextControl::Draw(pGraphics);
}
Hope it works, I had to modify it slightly because mine isn't in IControl, but that's were it makes sense to put it really.
In IControl.h:
/* Spinner is text you can change like a knob. Usually it displays
* the value of the parameter it is linked to. If showParam == false
* it doesn't show the parameter, you can set what it displays just
* like a TextControl. If it isn't linked to a parameter you can
* specify a pointer to an IParam altParameter which it will use instead
* (having a parameter makes it much more useful because it can display
* enums, or integers or whatever).
* If altParameter is specified then it will be kept updated as the
* control changes - there's no locking, so this parameter should only
* be used from the gui code (but that's what you wanted or you would
* have used a real parameter)
*/
class ISpinnerControl : public ITextControl
{
public:
ISpinnerControl(IPlugBase* pPlug, IRECT* pR, int paramIdx,
IText* pText, IParam *altParam=NULL, bool showParam = true,
bool showParamLabel = true,
EDirection direction = kVertical,double gearing = DEFAULT_GEARING);
~ISpinnerControl() {}
virtual void OnMouseDrag(int x, int y, int dX, int dY, IMouseMod* pMod);
virtual void OnMouseWheel(int x, int y, IMouseMod* pMod, int d);
virtual bool Draw(IGraphics* pGraphics);
protected:
EDirection mDirection;
double mGearing;
bool mShowParam;
bool mShowParamLabel;
IParam *mAltParam;
};
In IControl.cpp:
ISpinnerControl::ISpinnerControl (IPlugBase* pPlug, IRECT* pR, int paramIdx,
IText* pText, IParam *altParam, bool showParam,
bool showParamLabel,
EDirection direction,double gearing)
: ITextControl(pPlug, pR, pText),
mAltParam(altParam),mShowParam(showParam),mShowPar amLabel(showParamLabel),
mDirection(direction), mGearing(gearing)
{
mParamIdx=paramIdx;
}
void ISpinnerControl::OnMouseDrag(int x, int y, int dX, int dY, IMouseMod* pMod)
{
double delta = (mDirection == kVertical) ?
(double) dY / (double) (mRECT.T - mRECT.B) / mGearing :
(double) dX / (double) (mRECT.R - mRECT.L) / mGearing;
mValue += delta;
SetDirty();
}
void ISpinnerControl::OnMouseWheel(int x, int y, IMouseMod* pMod, int d)
{
double step = 0.01;
if (mParamIdx >= 0) {
step = mPlug->GetParam(mParamIdx)->GetStep();
}
else if (mAltParam) {
step = mAltParam->GetStep();
}
// parameters of type double return a step of 0
if (step != 0.0) {
// 30/3/9: currently this doesn't work very well because
// the mouse wheel stuff in IPlug doesn't handle fractions
// as it should
mValue += d * step;
}
else {
if (pMod->C || pMod->S) {
mValue += 0.001 * d;
}
else {
mValue += 0.01 * d;
}
}
mValue = BOUNDED(mValue,0.0,1.0);
SetDirty();
}
bool ISpinnerControl::Draw(IGraphics* pGraphics)
{
if ( mAltParam ) {
mAltParam->SetNormalized(mValue);
}
// if it's linked to a paramter we can draw it using ICaptionControl
// otherwise just use the text stored ITextControl (which can
// be updated using SetTextFromPlug)
if (mShowParam) {
IParam* pParam= ( mParamIdx>=0 ) ? mPlug->GetParam(mParamIdx) :
mAltParam;
if ( pParam ) {
char cStr[32];
pParam->GetDisplayForHost(cStr);
mStr.Set(cStr);
if (mShowParamLabel) {
mStr.Append(" ");
mStr.Append(pParam->GetLabelForHost());
}
}
}
return ITextControl::Draw(pGraphics);
}
Hope it works, I had to modify it slightly because mine isn't in IControl, but that's were it makes sense to put it really.