cc_
04-19-2010, 09:30 AM
I have made a Fader control that uses multiple images to do the sliding, so you can do things like the one on the right:
http://burbleland.com/tmp/fadermulti.png
IControl.h
// A multibitmap fader. The bitmap cycles through states as the mouse drags, and snaps to clicks.
// The handleLen is the length in pixels of the handle of the fader.
// By default the handle is expected to move from one extreme of the bitmap to the other. If it
// does not, then use SetTargetArea() and set the area to exactly the area swept out by the fader
// (eg for vertical: from its bottom in the lowest position to its top in the highest position)
class IFaderMultiControl : public IControl
{
public:
IFaderMultiControl(IPlugBase* pPlug, int x, int y, int handleLen, int paramIdx, IBitmap* pBitmap,
EDirection direction = kVertical);
~IFaderMultiControl() {}
virtual void OnMouseDown(int x, int y, IMouseMod* pMod);
virtual void OnMouseDrag(int x, int y, int dX, int dY, IMouseMod* pMod);
virtual bool Draw(IGraphics* pGraphics);
protected:
void SnapToMouse(int x, int y);
int mHandleLen;
IBitmap mBitmap;
EDirection mDirection;
int mOffset;
};
IControl.cpp:
IFaderMultiControl::IFaderMultiControl(IPlugBase* pPlug, int x, int y, int handleLen, int paramIdx, IBitmap* pBitmap, EDirection direction)
: IControl(pPlug, &IRECT(), paramIdx), mHandleLen(handleLen), mBitmap(*pBitmap), mDirection(direction)
{
mRECT = mTargetRECT = IRECT(x, y, pBitmap);
}
void IFaderMultiControl::OnMouseDown(int x, int y, IMouseMod* pMod)
{
if (pMod->R) {
PromptUserInput();
return;
}
int pos,mouse;
if (mDirection == kVertical) {
pos = int((1.0-mValue) * (double) (mTargetRECT.H() - mHandleLen));
mouse = y - mTargetRECT.T;
}
else {
pos = int((1.0-mValue) * (double) (mTargetRECT.W() - mHandleLen));
mouse = x - mTargetRECT.L;
}
if ( (mouse > pos) && (mouse < (pos + mHandleLen))) {
// if the click is inside the fader handle then remember the offset so that
// the fader doesn't jump when you click it
mOffset = mouse-pos;
}
else {
// outside the fader just snap to the centre
mOffset = mHandleLen/2;
}
return SnapToMouse(x, y);
}
void IFaderMultiControl::OnMouseDrag(int x, int y, int dX, int dY, IMouseMod* pMod)
{
return SnapToMouse(x, y);
}
void IFaderMultiControl::SnapToMouse(int x, int y)
{
if (mDirection == kVertical) {
mValue = 1.0 - (double) (y - mTargetRECT.T - mOffset) / (double) (mTargetRECT.H() - mHandleLen);
}
else {
mValue = (double) (x - mTargetRECT.L - mOffset) / (double) (mTargetRECT.W() - mHandleLen);
}
SetDirty();
}
// Same as IBitmapControl::Draw.
bool IFaderMultiControl::Draw(IGraphics* pGraphics)
{
int i = 1 + int(0.5 + mValue * (double) (mBitmap.N - 1));
i = BOUNDED(i, 1, mBitmap.N);
return pGraphics->DrawBitmap(&mBitmap, &mRECT, i, &mBlend);
}
To use:
// multi image fader control
bitmap = pGraphics->LoadIBitmap(MFADER_ID, MFADER_FN, 140);
IControl *MultiFader = new IFaderMultiControl(this, kGainR_X, kGainR_Y, 20, kGainR, &bitmap, kVertical);
// it is important to set the control's target area to exactly the area covered by the fader
// handle, from its bottom in the lowest position to its top in the highest position
MultiFader->SetTargetArea( &IRECT( kGainR_X, kGainR_Y +22, kGainR_X+32, kGainR_Y+178));
pGraphics->AttachControl(MultiFader);
http://burbleland.com/tmp/fadermulti.png
IControl.h
// A multibitmap fader. The bitmap cycles through states as the mouse drags, and snaps to clicks.
// The handleLen is the length in pixels of the handle of the fader.
// By default the handle is expected to move from one extreme of the bitmap to the other. If it
// does not, then use SetTargetArea() and set the area to exactly the area swept out by the fader
// (eg for vertical: from its bottom in the lowest position to its top in the highest position)
class IFaderMultiControl : public IControl
{
public:
IFaderMultiControl(IPlugBase* pPlug, int x, int y, int handleLen, int paramIdx, IBitmap* pBitmap,
EDirection direction = kVertical);
~IFaderMultiControl() {}
virtual void OnMouseDown(int x, int y, IMouseMod* pMod);
virtual void OnMouseDrag(int x, int y, int dX, int dY, IMouseMod* pMod);
virtual bool Draw(IGraphics* pGraphics);
protected:
void SnapToMouse(int x, int y);
int mHandleLen;
IBitmap mBitmap;
EDirection mDirection;
int mOffset;
};
IControl.cpp:
IFaderMultiControl::IFaderMultiControl(IPlugBase* pPlug, int x, int y, int handleLen, int paramIdx, IBitmap* pBitmap, EDirection direction)
: IControl(pPlug, &IRECT(), paramIdx), mHandleLen(handleLen), mBitmap(*pBitmap), mDirection(direction)
{
mRECT = mTargetRECT = IRECT(x, y, pBitmap);
}
void IFaderMultiControl::OnMouseDown(int x, int y, IMouseMod* pMod)
{
if (pMod->R) {
PromptUserInput();
return;
}
int pos,mouse;
if (mDirection == kVertical) {
pos = int((1.0-mValue) * (double) (mTargetRECT.H() - mHandleLen));
mouse = y - mTargetRECT.T;
}
else {
pos = int((1.0-mValue) * (double) (mTargetRECT.W() - mHandleLen));
mouse = x - mTargetRECT.L;
}
if ( (mouse > pos) && (mouse < (pos + mHandleLen))) {
// if the click is inside the fader handle then remember the offset so that
// the fader doesn't jump when you click it
mOffset = mouse-pos;
}
else {
// outside the fader just snap to the centre
mOffset = mHandleLen/2;
}
return SnapToMouse(x, y);
}
void IFaderMultiControl::OnMouseDrag(int x, int y, int dX, int dY, IMouseMod* pMod)
{
return SnapToMouse(x, y);
}
void IFaderMultiControl::SnapToMouse(int x, int y)
{
if (mDirection == kVertical) {
mValue = 1.0 - (double) (y - mTargetRECT.T - mOffset) / (double) (mTargetRECT.H() - mHandleLen);
}
else {
mValue = (double) (x - mTargetRECT.L - mOffset) / (double) (mTargetRECT.W() - mHandleLen);
}
SetDirty();
}
// Same as IBitmapControl::Draw.
bool IFaderMultiControl::Draw(IGraphics* pGraphics)
{
int i = 1 + int(0.5 + mValue * (double) (mBitmap.N - 1));
i = BOUNDED(i, 1, mBitmap.N);
return pGraphics->DrawBitmap(&mBitmap, &mRECT, i, &mBlend);
}
To use:
// multi image fader control
bitmap = pGraphics->LoadIBitmap(MFADER_ID, MFADER_FN, 140);
IControl *MultiFader = new IFaderMultiControl(this, kGainR_X, kGainR_Y, 20, kGainR, &bitmap, kVertical);
// it is important to set the control's target area to exactly the area covered by the fader
// handle, from its bottom in the lowest position to its top in the highest position
MultiFader->SetTargetArea( &IRECT( kGainR_X, kGainR_Y +22, kGainR_X+32, kGainR_Y+178));
pGraphics->AttachControl(MultiFader);