Initial release
This commit is contained in:
@@ -0,0 +1,770 @@
|
||||
// This file is part of VSTGUI. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this
|
||||
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
|
||||
|
||||
#include "cswitch.h"
|
||||
#include "../cdrawcontext.h"
|
||||
#include "../cbitmap.h"
|
||||
#include "../cvstguitimer.h"
|
||||
#include "../events.h"
|
||||
#include "../algorithm.h"
|
||||
|
||||
namespace VSTGUI {
|
||||
|
||||
#if VSTGUI_ENABLE_DEPRECATED_METHODS
|
||||
bool CSwitchBase::useLegacyIndexCalculation = false;
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
CSwitchBase::CSwitchBase (const CRect& size, IControlListener* listener, int32_t tag,
|
||||
CBitmap* background)
|
||||
: CControl (size, listener, tag, background)
|
||||
{
|
||||
setDefaultValue (0.f);
|
||||
setWantsFocus (true);
|
||||
}
|
||||
|
||||
#if VSTGUI_ENABLE_DEPRECATED_METHODS
|
||||
//------------------------------------------------------------------------
|
||||
CSwitchBase::CSwitchBase (const CRect& size, IControlListener* listener, int32_t tag,
|
||||
int32_t subPixmaps, CCoord heightOfOneImage, int32_t iMaxPositions,
|
||||
CBitmap* background, const CPoint& offset)
|
||||
: CControl (size, listener, tag, background), offset (offset)
|
||||
{
|
||||
setNumSubPixmaps (subPixmaps);
|
||||
setHeightOfOneImage (heightOfOneImage);
|
||||
setDefaultValue (0.f);
|
||||
setWantsFocus (true);
|
||||
}
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
CSwitchBase::CSwitchBase (const CSwitchBase& other) : CControl (other)
|
||||
{
|
||||
#if VSTGUI_ENABLE_DEPRECATED_METHODS
|
||||
offset = other.offset;
|
||||
setNumSubPixmaps (other.subPixmaps);
|
||||
setHeightOfOneImage (other.heightOfOneImage);
|
||||
#endif
|
||||
setWantsFocus (true);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
int32_t CSwitchBase::normalizedToIndex (float norm) const
|
||||
{
|
||||
if (auto mfb = dynamic_cast<CMultiFrameBitmap*> (getDrawBackground ()))
|
||||
{
|
||||
return getMultiFrameBitmapIndex (*mfb, norm);
|
||||
}
|
||||
#if VSTGUI_ENABLE_DEPRECATED_METHODS
|
||||
#include "../private/disabledeprecatedmessage.h"
|
||||
if (useLegacyIndexCalculation)
|
||||
#include "../private/enabledeprecatedmessage.h"
|
||||
return static_cast<int32_t> (norm * (getNumSubPixmaps () - 1) + 0.5f);
|
||||
return normalizedToSteps (norm, getNumSubPixmaps () - 1);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
float CSwitchBase::indexToNormalized (int32_t index) const
|
||||
{
|
||||
if (auto mfb = dynamic_cast<CMultiFrameBitmap*> (getDrawBackground ()))
|
||||
{
|
||||
return getNormValueFromMultiFrameBitmapIndex (*mfb, static_cast<uint16_t> (index));
|
||||
}
|
||||
#if VSTGUI_ENABLE_DEPRECATED_METHODS
|
||||
return static_cast<float> (index) / static_cast<float> (getNumSubPixmaps () - 1);
|
||||
#else
|
||||
return 0.f;
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void CSwitchBase::draw (CDrawContext* pContext)
|
||||
{
|
||||
if (auto bitmap = getDrawBackground ())
|
||||
{
|
||||
float norm = getValueNormalized ();
|
||||
if (auto mfb = dynamic_cast<CMultiFrameBitmap*> (bitmap))
|
||||
{
|
||||
auto frameIndex = getMultiFrameBitmapIndex (*mfb, norm);
|
||||
if (inverseBitmap)
|
||||
frameIndex = getInverseIndex (*mfb, frameIndex);
|
||||
mfb->drawFrame (pContext, frameIndex, getViewSize ().getTopLeft ());
|
||||
}
|
||||
else
|
||||
{
|
||||
#if VSTGUI_ENABLE_DEPRECATED_METHODS
|
||||
if (inverseBitmap)
|
||||
norm = 1.f - norm;
|
||||
// source position in bitmap
|
||||
CPoint where (0, heightOfOneImage * normalizedToIndex (norm));
|
||||
bitmap->draw (pContext, getViewSize (), where);
|
||||
#else
|
||||
bitmap->draw (pContext, getViewSize ());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
setDirty (false);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool CSwitchBase::sizeToFit ()
|
||||
{
|
||||
if (auto bitmap = getDrawBackground ())
|
||||
{
|
||||
CRect vs (getViewSize ());
|
||||
if (auto mfb = dynamic_cast<CMultiFrameBitmap*> (bitmap))
|
||||
{
|
||||
vs.setSize (mfb->getFrameSize ());
|
||||
}
|
||||
else
|
||||
{
|
||||
vs.setWidth (bitmap->getWidth ());
|
||||
#if VSTGUI_ENABLE_DEPRECATED_METHODS
|
||||
vs.setHeight (getHeightOfOneImage ());
|
||||
#else
|
||||
vs.setHeight (bitmap->getHeight ());
|
||||
#endif
|
||||
}
|
||||
setViewSize (vs);
|
||||
setMouseableArea (vs);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
CMouseEventResult CSwitchBase::onMouseDown (CPoint& where, const CButtonState& buttons)
|
||||
{
|
||||
if (!(buttons & kLButton))
|
||||
return kMouseEventNotHandled;
|
||||
|
||||
coef = calculateCoef ();
|
||||
|
||||
beginEdit ();
|
||||
|
||||
mouseStartValue = getValue ();
|
||||
return onMouseMoved (where, buttons);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
CMouseEventResult CSwitchBase::onMouseUp (CPoint& where, const CButtonState& buttons)
|
||||
{
|
||||
if (isEditing ())
|
||||
endEdit ();
|
||||
return kMouseEventHandled;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
CMouseEventResult CSwitchBase::onMouseCancel ()
|
||||
{
|
||||
if (isEditing ())
|
||||
{
|
||||
value = mouseStartValue;
|
||||
if (isDirty ())
|
||||
{
|
||||
valueChanged ();
|
||||
invalid ();
|
||||
}
|
||||
endEdit ();
|
||||
}
|
||||
return kMouseEventHandled;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
CMouseEventResult CSwitchBase::onMouseMoved (CPoint& where, const CButtonState& buttons)
|
||||
{
|
||||
if (isEditing ())
|
||||
{
|
||||
float norm = calcNormFromPoint (where);
|
||||
if (inverseBitmap)
|
||||
norm = 1.f - norm;
|
||||
value = getMin () + norm * (getMax () - getMin ());
|
||||
bounceValue ();
|
||||
|
||||
if (isDirty ())
|
||||
{
|
||||
valueChanged ();
|
||||
invalid ();
|
||||
}
|
||||
}
|
||||
return kMouseEventHandled;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void CSwitchBase::setInverseBitmap (bool state)
|
||||
{
|
||||
if (inverseBitmap != state)
|
||||
{
|
||||
inverseBitmap = state;
|
||||
invalid ();
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// CVerticalSwitch
|
||||
//------------------------------------------------------------------------
|
||||
/*! @class CVerticalSwitch
|
||||
Define a switch with a given number of positions, the current position is defined by the position
|
||||
of the last click on this object (the object is divided in its height by the number of position).
|
||||
Each position has its subbitmap, each subbitmap is stacked in the given handle bitmap.
|
||||
By clicking Alt+Left Mouse the default value is used.
|
||||
Use a CMultiFrameBitmap for its background bitmap.
|
||||
*/
|
||||
//------------------------------------------------------------------------
|
||||
/**
|
||||
* CVerticalSwitch constructor.
|
||||
* @param size the size of this view
|
||||
* @param listener the listener
|
||||
* @param tag the control tag
|
||||
* @param background the switch bitmap
|
||||
* @param offset unused
|
||||
*/
|
||||
//------------------------------------------------------------------------
|
||||
CVerticalSwitch::CVerticalSwitch (const CRect& size, IControlListener* listener, int32_t tag,
|
||||
CBitmap* background)
|
||||
: CSwitchBase (size, listener, tag, background)
|
||||
{
|
||||
#if VSTGUI_ENABLE_DEPRECATED_METHODS
|
||||
heightOfOneImage = size.getHeight ();
|
||||
setNumSubPixmaps (
|
||||
background ? static_cast<int32_t> (background->getHeight () / heightOfOneImage) : 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if VSTGUI_ENABLE_DEPRECATED_METHODS
|
||||
//------------------------------------------------------------------------
|
||||
/**
|
||||
* CVerticalSwitch constructor.
|
||||
* @param size the size of this view
|
||||
* @param listener the listener
|
||||
* @param tag the control tag
|
||||
* @param subPixmaps number of sub bitmaps in background
|
||||
* @param heightOfOneImage height of one sub bitmap
|
||||
* @param iMaxPositions TODO
|
||||
* @param background the switch bitmap
|
||||
* @param offset unused
|
||||
*/
|
||||
//------------------------------------------------------------------------
|
||||
CVerticalSwitch::CVerticalSwitch (const CRect& size, IControlListener* listener, int32_t tag,
|
||||
int32_t subPixmaps, CCoord heightOfOneImage,
|
||||
int32_t iMaxPositions, CBitmap* background, const CPoint& offset)
|
||||
: CSwitchBase (size, listener, tag, subPixmaps, heightOfOneImage, iMaxPositions, background, offset)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
CVerticalSwitch::CVerticalSwitch (const CVerticalSwitch& v)
|
||||
: CSwitchBase (v)
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
double CVerticalSwitch::calculateCoef () const
|
||||
{
|
||||
if (auto mfb = dynamic_cast<CMultiFrameBitmap*> (getDrawBackground ()))
|
||||
{
|
||||
return mfb->getFrameSize ().y / static_cast<double> (getMultiFrameBitmapRangeLength (*mfb));
|
||||
}
|
||||
#if VSTGUI_ENABLE_DEPRECATED_METHODS
|
||||
return static_cast<double> (heightOfOneImage) / static_cast<double> (getNumSubPixmaps ());
|
||||
#else
|
||||
return 1.;
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
float CVerticalSwitch::calcNormFromPoint (const CPoint& where) const
|
||||
{
|
||||
if (auto mfb = dynamic_cast<CMultiFrameBitmap*> (getDrawBackground ()))
|
||||
{
|
||||
return static_cast<int32_t> ((where.y - getViewSize ().top) / getCoef ()) /
|
||||
static_cast<float> (getMultiFrameBitmapRangeLength (*mfb) - 1);
|
||||
}
|
||||
#if VSTGUI_ENABLE_DEPRECATED_METHODS
|
||||
return static_cast<int32_t> ((where.y - getViewSize ().top) / getCoef ()) /
|
||||
static_cast<float> (getNumSubPixmaps () - 1);
|
||||
#else
|
||||
return 0.f;
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void CVerticalSwitch::onKeyboardEvent (KeyboardEvent& event)
|
||||
{
|
||||
if (event.type != EventType::KeyDown || event.modifiers.empty () == false)
|
||||
return;
|
||||
float norm = getValueNormalized ();
|
||||
int32_t currentIndex = normalizedToIndex (norm);
|
||||
if (event.virt == VirtualKey::Up && currentIndex > 0)
|
||||
{
|
||||
--currentIndex;
|
||||
norm = indexToNormalized (currentIndex);
|
||||
value = (getMax () - getMin ()) * norm + getMin ();
|
||||
bounceValue ();
|
||||
}
|
||||
if (event.virt == VirtualKey::Down && norm < 1.f)
|
||||
{
|
||||
++currentIndex;
|
||||
norm = indexToNormalized (currentIndex);
|
||||
value = (getMax () - getMin ()) * norm + getMin ();
|
||||
bounceValue ();
|
||||
}
|
||||
if (isDirty ())
|
||||
{
|
||||
invalid ();
|
||||
beginEdit ();
|
||||
valueChanged ();
|
||||
endEdit ();
|
||||
event.consumed = true;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// CHorizontalSwitch
|
||||
//------------------------------------------------------------------------
|
||||
/*! @class CHorizontalSwitch
|
||||
Same as the CVerticalSwitch but horizontal.
|
||||
Use a CMultiFrameBitmap for its background bitmap.
|
||||
*/
|
||||
//------------------------------------------------------------------------
|
||||
/**
|
||||
* CHorizontalSwitch constructor.
|
||||
* @param size the size of this view
|
||||
* @param listener the listener
|
||||
* @param tag the control tag
|
||||
* @param background the bitmap of the switch
|
||||
* @param offset unused
|
||||
*/
|
||||
//------------------------------------------------------------------------
|
||||
CHorizontalSwitch::CHorizontalSwitch (const CRect& size, IControlListener* listener, int32_t tag,
|
||||
CBitmap* background)
|
||||
: CSwitchBase (size, listener, tag, background)
|
||||
{
|
||||
#if VSTGUI_ENABLE_DEPRECATED_METHODS
|
||||
heightOfOneImage = size.getWidth ();
|
||||
setNumSubPixmaps (background ? (int32_t) (background->getWidth () / heightOfOneImage) : 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if VSTGUI_ENABLE_DEPRECATED_METHODS
|
||||
//------------------------------------------------------------------------
|
||||
/**
|
||||
* CHorizontalSwitch constructor.
|
||||
* @param size the size of this view
|
||||
* @param listener the listener
|
||||
* @param tag the control tag
|
||||
* @param subPixmaps number of sub bitmaps in background
|
||||
* @param heightOfOneImage height of one sub bitmap
|
||||
* @param iMaxPositions ignored
|
||||
* @param background the switch bitmap
|
||||
* @param offset unused
|
||||
*/
|
||||
//------------------------------------------------------------------------
|
||||
CHorizontalSwitch::CHorizontalSwitch (const CRect& size, IControlListener* listener, int32_t tag,
|
||||
int32_t subPixmaps, CCoord heightOfOneImage,
|
||||
int32_t iMaxPositions, CBitmap* background,
|
||||
const CPoint& offset)
|
||||
: CSwitchBase (size, listener, tag, subPixmaps, heightOfOneImage, iMaxPositions, background, offset)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
CHorizontalSwitch::CHorizontalSwitch (const CHorizontalSwitch& v)
|
||||
: CSwitchBase (v)
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
double CHorizontalSwitch::calculateCoef () const
|
||||
{
|
||||
if (auto mfb = dynamic_cast<CMultiFrameBitmap*> (getDrawBackground ()))
|
||||
{
|
||||
return mfb->getFrameSize ().x / static_cast<double> (getMultiFrameBitmapRangeLength (*mfb));
|
||||
}
|
||||
#if VSTGUI_ENABLE_DEPRECATED_METHODS
|
||||
return getDrawBackground ()->getWidth () / static_cast<double> (getNumSubPixmaps ());
|
||||
#else
|
||||
return 1.;
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
float CHorizontalSwitch::calcNormFromPoint (const CPoint& where) const
|
||||
{
|
||||
if (auto mfb = dynamic_cast<CMultiFrameBitmap*> (getDrawBackground ()))
|
||||
{
|
||||
return static_cast<int32_t> ((where.x - getViewSize ().left) / getCoef ()) /
|
||||
static_cast<float> (getMultiFrameBitmapRangeLength (*mfb) - 1);
|
||||
}
|
||||
#if VSTGUI_ENABLE_DEPRECATED_METHODS
|
||||
return static_cast<int32_t> ((where.x - getViewSize ().left) / getCoef ()) /
|
||||
static_cast<float> (getNumSubPixmaps () - 1);
|
||||
#else
|
||||
return 0.f;
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void CHorizontalSwitch::onKeyboardEvent(KeyboardEvent &event)
|
||||
{
|
||||
if (event.type != EventType::KeyDown || event.modifiers.empty () == false)
|
||||
return;
|
||||
float norm = getValueNormalized ();
|
||||
int32_t currentIndex = normalizedToIndex (norm);
|
||||
if (event.virt == VirtualKey::Left && currentIndex > 0)
|
||||
{
|
||||
--currentIndex;
|
||||
norm = indexToNormalized (currentIndex);
|
||||
value = (getMax () - getMin ()) * norm + getMin ();
|
||||
bounceValue ();
|
||||
}
|
||||
if (event.virt == VirtualKey::Right && norm < 1.f)
|
||||
{
|
||||
++currentIndex;
|
||||
norm = indexToNormalized (currentIndex);
|
||||
value = (getMax () - getMin ()) * norm + getMin ();
|
||||
bounceValue ();
|
||||
}
|
||||
if (isDirty ())
|
||||
{
|
||||
invalid ();
|
||||
beginEdit ();
|
||||
valueChanged ();
|
||||
endEdit ();
|
||||
event.consumed = true;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// CRockerSwitch
|
||||
//------------------------------------------------------------------------
|
||||
/*! @class CRockerSwitch
|
||||
Define a rocker switch with 3 states using 3 subbitmaps.
|
||||
One click on its leftside, then the first subbitmap is displayed.
|
||||
One click on its rightside, then the third subbitmap is displayed.
|
||||
When the mouse button is relaxed, the second subbitmap is framed. */
|
||||
//------------------------------------------------------------------------
|
||||
/**
|
||||
* CRockerSwitch constructor.
|
||||
* @param size the size of this view
|
||||
* @param listener the listener
|
||||
* @param tag the control tag
|
||||
* @param background bitmap with 3 stacked images of the rocker switch
|
||||
* @param style
|
||||
*/
|
||||
//------------------------------------------------------------------------
|
||||
CRockerSwitch::CRockerSwitch (const CRect& size, IControlListener* listener, int32_t tag,
|
||||
CBitmap* background, const int32_t style)
|
||||
: CControl (size, listener, tag, background), style (style), resetValueTimer (nullptr)
|
||||
{
|
||||
#if VSTGUI_ENABLE_DEPRECATED_METHODS
|
||||
setNumSubPixmaps (3);
|
||||
setHeightOfOneImage (size.getHeight ());
|
||||
#endif
|
||||
setWantsFocus (true);
|
||||
setMin (-1.f);
|
||||
setMax (1.f);
|
||||
setValue ((getMax () - getMin ()) / 2.f + getMin ());
|
||||
}
|
||||
|
||||
#if VSTGUI_ENABLE_DEPRECATED_METHODS
|
||||
//------------------------------------------------------------------------
|
||||
/**
|
||||
* CRockerSwitch constructor.
|
||||
* @param size the size of this view
|
||||
* @param listener the listener
|
||||
* @param tag the control tag
|
||||
* @param background bitmap with 3 stacked images of the rocker switch
|
||||
* @param offset
|
||||
* @param style
|
||||
*/
|
||||
//------------------------------------------------------------------------
|
||||
CRockerSwitch::CRockerSwitch (const CRect& size, IControlListener* listener, int32_t tag, CBitmap* background, const CPoint &offset, const int32_t style)
|
||||
: CControl (size, listener, tag, background)
|
||||
, offset (offset)
|
||||
, style (style)
|
||||
, resetValueTimer (nullptr)
|
||||
{
|
||||
#if VSTGUI_ENABLE_DEPRECATED_METHODS
|
||||
setNumSubPixmaps (3);
|
||||
setHeightOfOneImage (size.getHeight ());
|
||||
#endif
|
||||
setWantsFocus (true);
|
||||
setMin (-1.f);
|
||||
setMax (1.f);
|
||||
setValue ((getMax () - getMin ()) / 2.f + getMin ());
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/**
|
||||
* CRockerSwitch constructor.
|
||||
* @param size the size of this view
|
||||
* @param listener the listener
|
||||
* @param tag the control tag
|
||||
* @param heightOfOneImage height of one image in pixel
|
||||
* @param background bitmap with 3 stacked images of the rocker switch
|
||||
* @param offset
|
||||
* @param style
|
||||
*/
|
||||
//------------------------------------------------------------------------
|
||||
CRockerSwitch::CRockerSwitch (const CRect& size, IControlListener* listener, int32_t tag, CCoord heightOfOneImage, CBitmap* background, const CPoint &offset, const int32_t style)
|
||||
: CControl (size, listener, tag, background)
|
||||
, offset (offset)
|
||||
, style (style)
|
||||
, resetValueTimer (nullptr)
|
||||
{
|
||||
setNumSubPixmaps (3);
|
||||
setHeightOfOneImage (heightOfOneImage);
|
||||
setWantsFocus (true);
|
||||
setMin (-1.f);
|
||||
setMax (1.f);
|
||||
setValue ((getMax () - getMin ()) / 2.f + getMin ());
|
||||
}
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
CRockerSwitch::CRockerSwitch (const CRockerSwitch& v)
|
||||
: CControl (v), style (v.style), resetValueTimer (nullptr)
|
||||
{
|
||||
#if VSTGUI_ENABLE_DEPRECATED_METHODS
|
||||
offset = v.offset;
|
||||
setHeightOfOneImage (v.heightOfOneImage);
|
||||
#endif
|
||||
setWantsFocus (true);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
CRockerSwitch::~CRockerSwitch () noexcept
|
||||
{
|
||||
if (resetValueTimer)
|
||||
resetValueTimer->forget ();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void CRockerSwitch::draw (CDrawContext *pContext)
|
||||
{
|
||||
if (auto bitmap = getDrawBackground ())
|
||||
{
|
||||
if (auto mfb = dynamic_cast<CMultiFrameBitmap*> (bitmap))
|
||||
{
|
||||
uint16_t frameIndex = getMultiFrameBitmapIndex (*mfb, getValueNormalized ());
|
||||
mfb->drawFrame (pContext, frameIndex, getViewSize ().getTopLeft ());
|
||||
}
|
||||
#if VSTGUI_ENABLE_DEPRECATED_METHODS
|
||||
CPoint where (offset.x, offset.y);
|
||||
|
||||
if (value == getMax ())
|
||||
where.y += 2 * heightOfOneImage;
|
||||
else if (value == (getMax () - getMin ()) / 2.f + getMin ())
|
||||
where.y += heightOfOneImage;
|
||||
|
||||
bitmap->draw (pContext, getViewSize (), where);
|
||||
#else
|
||||
bitmap->draw (pContext, getViewSize ());
|
||||
#endif
|
||||
}
|
||||
setDirty (false);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
CMouseEventResult CRockerSwitch::onMouseDown (CPoint& where, const CButtonState& buttons)
|
||||
{
|
||||
if (!(buttons & kLButton))
|
||||
return kMouseEventNotHandled;
|
||||
mouseStartValue = value;
|
||||
beginEdit ();
|
||||
return onMouseMoved (where, buttons);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
CMouseEventResult CRockerSwitch::onMouseUp (CPoint& where, const CButtonState& buttons)
|
||||
{
|
||||
if (isEditing ())
|
||||
{
|
||||
value = (getMax () - getMin ()) / 2.f + getMin ();
|
||||
if (isDirty ())
|
||||
invalid ();
|
||||
endEdit ();
|
||||
}
|
||||
return kMouseEventHandled;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
CMouseEventResult CRockerSwitch::onMouseCancel ()
|
||||
{
|
||||
if (isEditing ())
|
||||
{
|
||||
value = mouseStartValue;
|
||||
if (isDirty ())
|
||||
{
|
||||
valueChanged ();
|
||||
invalid ();
|
||||
}
|
||||
endEdit ();
|
||||
}
|
||||
return kMouseEventHandled;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
CMouseEventResult CRockerSwitch::onMouseMoved (CPoint& where, const CButtonState& buttons)
|
||||
{
|
||||
if (isEditing ())
|
||||
{
|
||||
CCoord width_2 = getViewSize ().getWidth () / 2;
|
||||
CCoord height_2 = getViewSize ().getHeight () / 2;
|
||||
|
||||
if (style & kHorizontal)
|
||||
{
|
||||
if (where.x >= getViewSize ().left && where.y >= getViewSize ().top &&
|
||||
where.x <= (getViewSize ().left + width_2) && where.y <= getViewSize ().bottom)
|
||||
value = getMin ();
|
||||
else if (where.x >= (getViewSize ().left + width_2) && where.y >= getViewSize ().top &&
|
||||
where.x <= getViewSize ().right && where.y <= getViewSize ().bottom)
|
||||
value = getMax ();
|
||||
else
|
||||
value = mouseStartValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (where.x >= getViewSize ().left && where.y >= getViewSize ().top &&
|
||||
where.x <= getViewSize ().right && where.y <= (getViewSize ().top + height_2))
|
||||
value = getMin ();
|
||||
else if (where.x >= getViewSize ().left && where.y >= (getViewSize ().top + height_2) &&
|
||||
where.x <= getViewSize ().right && where.y <= getViewSize ().bottom)
|
||||
value = getMax ();
|
||||
else
|
||||
value = mouseStartValue;
|
||||
}
|
||||
|
||||
if (isDirty ())
|
||||
{
|
||||
valueChanged ();
|
||||
invalid ();
|
||||
}
|
||||
}
|
||||
return kMouseEventHandled;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void CRockerSwitch::onKeyboardEvent (KeyboardEvent& event)
|
||||
{
|
||||
if (event.modifiers.empty () == false)
|
||||
return;
|
||||
if (event.type == EventType::KeyDown)
|
||||
{
|
||||
if (style & kHorizontal &&
|
||||
(event.virt == VirtualKey::Left || event.virt == VirtualKey::Right))
|
||||
{
|
||||
value = event.virt == VirtualKey::Left ? getMin () : getMax ();
|
||||
invalid ();
|
||||
beginEdit ();
|
||||
valueChanged ();
|
||||
event.consumed = true;
|
||||
}
|
||||
if (style & kVertical && (event.virt == VirtualKey::Up || event.virt == VirtualKey::Down))
|
||||
{
|
||||
value = event.virt == VirtualKey::Up ? getMin () : getMax ();
|
||||
invalid ();
|
||||
beginEdit ();
|
||||
valueChanged ();
|
||||
event.consumed = true;
|
||||
}
|
||||
}
|
||||
else if (event.type == EventType::KeyUp)
|
||||
{
|
||||
if ((style & kHorizontal &&
|
||||
(event.virt == VirtualKey::Left || event.virt == VirtualKey::Right)) ||
|
||||
(style & kVertical && (event.virt == VirtualKey::Up || event.virt == VirtualKey::Down)))
|
||||
{
|
||||
value = (getMax () - getMin ()) / 2.f + getMin ();
|
||||
invalid ();
|
||||
valueChanged ();
|
||||
endEdit ();
|
||||
event.consumed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void CRockerSwitch::onMouseWheelEvent (MouseWheelEvent& event)
|
||||
{
|
||||
auto distance = event.deltaY;
|
||||
if (distance == 0.)
|
||||
return;
|
||||
|
||||
if (distance > 0)
|
||||
value = getMin ();
|
||||
else
|
||||
value = getMax ();
|
||||
|
||||
if (isDirty ())
|
||||
{
|
||||
invalid ();
|
||||
if (!isEditing ())
|
||||
beginEdit ();
|
||||
valueChanged ();
|
||||
}
|
||||
|
||||
if (resetValueTimer == nullptr)
|
||||
resetValueTimer = new CVSTGUITimer (this, 200);
|
||||
resetValueTimer->stop ();
|
||||
resetValueTimer->start ();
|
||||
|
||||
event.consumed = true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
CMessageResult CRockerSwitch::notify (CBaseObject* sender, IdStringPtr message)
|
||||
{
|
||||
if (sender == resetValueTimer)
|
||||
{
|
||||
float newValue = (getMax () - getMin ()) / 2.f + getMin ();
|
||||
if (value != newValue)
|
||||
{
|
||||
value = newValue;
|
||||
if (!isEditing ())
|
||||
beginEdit ();
|
||||
valueChanged ();
|
||||
endEdit ();
|
||||
setDirty (true);
|
||||
}
|
||||
resetValueTimer->forget ();
|
||||
resetValueTimer = nullptr;
|
||||
return kMessageNotified;
|
||||
}
|
||||
return CControl::notify (sender, message);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
bool CRockerSwitch::sizeToFit ()
|
||||
{
|
||||
if (auto bitmap = getDrawBackground ())
|
||||
{
|
||||
CRect vs (getViewSize ());
|
||||
if (auto mfb = dynamic_cast<CMultiFrameBitmap*> (bitmap))
|
||||
{
|
||||
vs.setSize (mfb->getFrameSize ());
|
||||
}
|
||||
else
|
||||
{
|
||||
vs.setWidth (bitmap->getWidth ());
|
||||
#if VSTGUI_ENABLE_DEPRECATED_METHODS
|
||||
vs.setHeight (getHeightOfOneImage ());
|
||||
#else
|
||||
vs.setHeight (bitmap->getHeight ());
|
||||
#endif
|
||||
}
|
||||
setViewSize (vs);
|
||||
setMouseableArea (vs);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // VSTGUI
|
||||
Reference in New Issue
Block a user