|
|
@@ -103,45 +103,47 @@ public: |
|
|
return 0.0f;
|
|
|
return 0.0f;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
void setRange (double newMin, double newMax, double newInt)
|
|
|
|
|
|
|
|
|
void updateRange()
|
|
|
{
|
|
|
{
|
|
|
if (minimum != newMin || maximum != newMax || interval != newInt)
|
|
|
|
|
|
{
|
|
|
|
|
|
minimum = newMin;
|
|
|
|
|
|
maximum = newMax;
|
|
|
|
|
|
interval = newInt;
|
|
|
|
|
|
|
|
|
|
|
|
// figure out the number of DPs needed to display all values at this
|
|
|
|
|
|
// interval setting.
|
|
|
|
|
|
numDecimalPlaces = 7;
|
|
|
|
|
|
|
|
|
// figure out the number of DPs needed to display all values at this
|
|
|
|
|
|
// interval setting.
|
|
|
|
|
|
numDecimalPlaces = 7;
|
|
|
|
|
|
|
|
|
if (newInt != 0.0)
|
|
|
|
|
|
{
|
|
|
|
|
|
int v = std::abs (roundToInt (newInt * 10000000));
|
|
|
|
|
|
|
|
|
|
|
|
if (v > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
while ((v % 10) == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
--numDecimalPlaces;
|
|
|
|
|
|
v /= 10;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
if (normRange.interval != 0.0)
|
|
|
|
|
|
{
|
|
|
|
|
|
int v = std::abs (roundToInt (normRange.interval * 10000000));
|
|
|
|
|
|
|
|
|
// keep the current values inside the new range..
|
|
|
|
|
|
if (style != TwoValueHorizontal && style != TwoValueVertical)
|
|
|
|
|
|
{
|
|
|
|
|
|
setValue (getValue(), dontSendNotification);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
|
while ((v % 10) == 0)
|
|
|
{
|
|
|
{
|
|
|
setMinValue (getMinValue(), dontSendNotification, false);
|
|
|
|
|
|
setMaxValue (getMaxValue(), dontSendNotification, false);
|
|
|
|
|
|
|
|
|
--numDecimalPlaces;
|
|
|
|
|
|
v /= 10;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
updateText();
|
|
|
|
|
|
|
|
|
// keep the current values inside the new range..
|
|
|
|
|
|
if (style != TwoValueHorizontal && style != TwoValueVertical)
|
|
|
|
|
|
{
|
|
|
|
|
|
setValue (getValue(), dontSendNotification);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
setMinValue (getMinValue(), dontSendNotification, false);
|
|
|
|
|
|
setMaxValue (getMaxValue(), dontSendNotification, false);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
updateText();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void setRange (double newMin, double newMax, double newInt)
|
|
|
|
|
|
{
|
|
|
|
|
|
normRange = NormalisableRange<double> (newMin, newMax, newInt);
|
|
|
|
|
|
updateRange();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void setNormalisableRange (NormalisableRange<double> newRange)
|
|
|
|
|
|
{
|
|
|
|
|
|
normRange = newRange;
|
|
|
|
|
|
updateRange();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
double getValue() const
|
|
|
double getValue() const
|
|
|
@@ -423,26 +425,18 @@ public: |
|
|
|
|
|
|
|
|
double constrainedValue (double value) const
|
|
|
double constrainedValue (double value) const
|
|
|
{
|
|
|
{
|
|
|
if (interval > 0)
|
|
|
|
|
|
value = minimum + interval * std::floor ((value - minimum) / interval + 0.5);
|
|
|
|
|
|
|
|
|
|
|
|
if (value <= minimum || maximum <= minimum)
|
|
|
|
|
|
value = minimum;
|
|
|
|
|
|
else if (value >= maximum)
|
|
|
|
|
|
value = maximum;
|
|
|
|
|
|
|
|
|
|
|
|
return value;
|
|
|
|
|
|
|
|
|
return normRange.snapToLegalValue (value);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
float getLinearSliderPos (double value) const
|
|
|
float getLinearSliderPos (double value) const
|
|
|
{
|
|
|
{
|
|
|
double pos;
|
|
|
double pos;
|
|
|
|
|
|
|
|
|
if (maximum <= minimum)
|
|
|
|
|
|
|
|
|
if (normRange.end <= normRange.start)
|
|
|
pos = 0.5;
|
|
|
pos = 0.5;
|
|
|
else if (value < minimum)
|
|
|
|
|
|
|
|
|
else if (value < normRange.start)
|
|
|
pos = 0.0;
|
|
|
pos = 0.0;
|
|
|
else if (value > maximum)
|
|
|
|
|
|
|
|
|
else if (value > normRange.end)
|
|
|
pos = 1.0;
|
|
|
pos = 1.0;
|
|
|
else
|
|
|
else
|
|
|
pos = owner.valueToProportionOfLength (value);
|
|
|
pos = owner.valueToProportionOfLength (value);
|
|
|
@@ -475,13 +469,6 @@ public: |
|
|
modifierToSwapModes = newModifierToSwapModes;
|
|
|
modifierToSwapModes = newModifierToSwapModes;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
void setSkewFactorFromMidPoint (double sliderValueToShowAtMidPoint)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (maximum > minimum)
|
|
|
|
|
|
skewFactor = std::log (0.5) / std::log ((sliderValueToShowAtMidPoint - minimum)
|
|
|
|
|
|
/ (maximum - minimum));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void setIncDecButtonsMode (IncDecButtonMode mode)
|
|
|
void setIncDecButtonsMode (IncDecButtonMode mode)
|
|
|
{
|
|
|
{
|
|
|
if (incDecButtonMode != mode)
|
|
|
if (incDecButtonMode != mode)
|
|
|
@@ -592,8 +579,8 @@ public: |
|
|
owner.addAndMakeVisible (incButton.get());
|
|
|
owner.addAndMakeVisible (incButton.get());
|
|
|
owner.addAndMakeVisible (decButton.get());
|
|
|
owner.addAndMakeVisible (decButton.get());
|
|
|
|
|
|
|
|
|
incButton->onClick = [this] { incrementOrDecrement (interval); };
|
|
|
|
|
|
decButton->onClick = [this] { incrementOrDecrement (-interval); };
|
|
|
|
|
|
|
|
|
incButton->onClick = [this] { incrementOrDecrement (normRange.interval); };
|
|
|
|
|
|
decButton->onClick = [this] { incrementOrDecrement (-normRange.interval); };
|
|
|
|
|
|
|
|
|
if (incDecButtonMode != incDecButtonsNotDraggable)
|
|
|
if (incDecButtonMode != incDecButtonsNotDraggable)
|
|
|
{
|
|
|
{
|
|
|
@@ -835,7 +822,7 @@ public: |
|
|
{
|
|
|
{
|
|
|
mouseDoubleClick();
|
|
|
mouseDoubleClick();
|
|
|
}
|
|
|
}
|
|
|
else if (maximum > minimum)
|
|
|
|
|
|
|
|
|
else if (normRange.end > normRange.start)
|
|
|
{
|
|
|
{
|
|
|
useDragEvents = true;
|
|
|
useDragEvents = true;
|
|
|
|
|
|
|
|
|
@@ -871,7 +858,7 @@ public: |
|
|
|
|
|
|
|
|
void mouseDrag (const MouseEvent& e)
|
|
|
void mouseDrag (const MouseEvent& e)
|
|
|
{
|
|
|
{
|
|
|
if (useDragEvents && maximum > minimum
|
|
|
|
|
|
|
|
|
if (useDragEvents && normRange.end > normRange.start
|
|
|
&& ! ((style == LinearBar || style == LinearBarVertical)
|
|
|
&& ! ((style == LinearBar || style == LinearBarVertical)
|
|
|
&& e.mouseWasClicked() && valueBox != nullptr && valueBox->isEditable()))
|
|
|
&& e.mouseWasClicked() && valueBox != nullptr && valueBox->isEditable()))
|
|
|
{
|
|
|
{
|
|
|
@@ -892,7 +879,7 @@ public: |
|
|
mouseDragStartPos = e.position;
|
|
|
mouseDragStartPos = e.position;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
if (isAbsoluteDragMode (e.mods) || (maximum - minimum) / sliderRegionSize < interval)
|
|
|
|
|
|
|
|
|
if (isAbsoluteDragMode (e.mods) || (normRange.end - normRange.start) / sliderRegionSize < normRange.interval)
|
|
|
{
|
|
|
{
|
|
|
dragMode = absoluteDrag;
|
|
|
dragMode = absoluteDrag;
|
|
|
handleAbsoluteDrag (e);
|
|
|
handleAbsoluteDrag (e);
|
|
|
@@ -904,7 +891,7 @@ public: |
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
valueWhenLastDragged = jlimit (minimum, maximum, valueWhenLastDragged);
|
|
|
|
|
|
|
|
|
valueWhenLastDragged = jlimit (normRange.start, normRange.end, valueWhenLastDragged);
|
|
|
|
|
|
|
|
|
if (sliderBeingDragged == 0)
|
|
|
if (sliderBeingDragged == 0)
|
|
|
{
|
|
|
{
|
|
|
@@ -940,7 +927,7 @@ public: |
|
|
{
|
|
|
{
|
|
|
if (owner.isEnabled()
|
|
|
if (owner.isEnabled()
|
|
|
&& useDragEvents
|
|
|
&& useDragEvents
|
|
|
&& (maximum > minimum)
|
|
|
|
|
|
|
|
|
&& (normRange.end > normRange.start)
|
|
|
&& (style != IncDecButtons || incDecDragged))
|
|
|
&& (style != IncDecButtons || incDecDragged))
|
|
|
{
|
|
|
{
|
|
|
restoreMouseIfHidden();
|
|
|
restoreMouseIfHidden();
|
|
|
@@ -1034,8 +1021,8 @@ public: |
|
|
{
|
|
|
{
|
|
|
return doubleClickToValue
|
|
|
return doubleClickToValue
|
|
|
&& style != IncDecButtons
|
|
|
&& style != IncDecButtons
|
|
|
&& minimum <= doubleClickReturnValue
|
|
|
|
|
|
&& maximum >= doubleClickReturnValue;
|
|
|
|
|
|
|
|
|
&& normRange.start <= doubleClickReturnValue
|
|
|
|
|
|
&& normRange.end >= doubleClickReturnValue;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
void mouseDoubleClick()
|
|
|
void mouseDoubleClick()
|
|
|
@@ -1050,7 +1037,7 @@ public: |
|
|
double getMouseWheelDelta (double value, double wheelAmount)
|
|
|
double getMouseWheelDelta (double value, double wheelAmount)
|
|
|
{
|
|
|
{
|
|
|
if (style == IncDecButtons)
|
|
|
if (style == IncDecButtons)
|
|
|
return interval * wheelAmount;
|
|
|
|
|
|
|
|
|
return normRange.interval * wheelAmount;
|
|
|
|
|
|
|
|
|
auto proportionDelta = wheelAmount * 0.15;
|
|
|
auto proportionDelta = wheelAmount * 0.15;
|
|
|
auto currentPos = owner.valueToProportionOfLength (value);
|
|
|
auto currentPos = owner.valueToProportionOfLength (value);
|
|
|
@@ -1069,7 +1056,7 @@ public: |
|
|
{
|
|
|
{
|
|
|
lastMouseWheelTime = e.eventTime;
|
|
|
lastMouseWheelTime = e.eventTime;
|
|
|
|
|
|
|
|
|
if (maximum > minimum && ! e.mods.isAnyMouseButtonDown())
|
|
|
|
|
|
|
|
|
if (normRange.end > normRange.start && ! e.mods.isAnyMouseButtonDown())
|
|
|
{
|
|
|
{
|
|
|
if (valueBox != nullptr)
|
|
|
if (valueBox != nullptr)
|
|
|
valueBox->hideEditor (false);
|
|
|
valueBox->hideEditor (false);
|
|
|
@@ -1080,7 +1067,7 @@ public: |
|
|
* (wheel.isReversed ? -1.0f : 1.0f));
|
|
|
* (wheel.isReversed ? -1.0f : 1.0f));
|
|
|
if (delta != 0.0)
|
|
|
if (delta != 0.0)
|
|
|
{
|
|
|
{
|
|
|
auto newValue = value + jmax (interval, std::abs (delta)) * (delta < 0 ? -1.0 : 1.0);
|
|
|
|
|
|
|
|
|
auto newValue = value + jmax (normRange.interval, std::abs (delta)) * (delta < 0 ? -1.0 : 1.0);
|
|
|
|
|
|
|
|
|
DragInProgress drag (*this);
|
|
|
DragInProgress drag (*this);
|
|
|
setValue (owner.snapValue (newValue, notDragging), sendNotificationSync);
|
|
|
setValue (owner.snapValue (newValue, notDragging), sendNotificationSync);
|
|
|
@@ -1242,9 +1229,9 @@ public: |
|
|
ListenerList<Slider::Listener> listeners;
|
|
|
ListenerList<Slider::Listener> listeners;
|
|
|
Value currentValue, valueMin, valueMax;
|
|
|
Value currentValue, valueMin, valueMax;
|
|
|
double lastCurrentValue = 0, lastValueMin = 0, lastValueMax = 0;
|
|
|
double lastCurrentValue = 0, lastValueMin = 0, lastValueMax = 0;
|
|
|
double minimum = 0, maximum = 10, interval = 0, doubleClickReturnValue = 0;
|
|
|
|
|
|
double valueWhenLastDragged = 0, valueOnMouseDown = 0, skewFactor = 1.0, lastAngle = 0;
|
|
|
|
|
|
bool symmetricSkew = false;
|
|
|
|
|
|
|
|
|
NormalisableRange<double> normRange { 0.0, 10.0 };
|
|
|
|
|
|
double doubleClickReturnValue = 0;
|
|
|
|
|
|
double valueWhenLastDragged = 0, valueOnMouseDown = 0, lastAngle = 0;
|
|
|
double velocityModeSensitivity = 1.0, velocityModeOffset = 0, minMaxDiff = 0;
|
|
|
double velocityModeSensitivity = 1.0, velocityModeOffset = 0, minMaxDiff = 0;
|
|
|
int velocityModeThreshold = 1;
|
|
|
int velocityModeThreshold = 1;
|
|
|
RotaryParameters rotaryParams;
|
|
|
RotaryParameters rotaryParams;
|
|
|
@@ -1426,19 +1413,18 @@ void Slider::setVelocityModeParameters (double sensitivity, int threshold, |
|
|
userCanPressKeyToSwapMode, modifierToSwapModes);
|
|
|
userCanPressKeyToSwapMode, modifierToSwapModes);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
double Slider::getSkewFactor() const noexcept { return pimpl->skewFactor; }
|
|
|
|
|
|
bool Slider::isSymmetricSkew() const noexcept { return pimpl->symmetricSkew; }
|
|
|
|
|
|
|
|
|
double Slider::getSkewFactor() const noexcept { return pimpl->normRange.skew; }
|
|
|
|
|
|
bool Slider::isSymmetricSkew() const noexcept { return pimpl->normRange.symmetricSkew; }
|
|
|
|
|
|
|
|
|
void Slider::setSkewFactor (double factor, bool symmetricSkew)
|
|
|
void Slider::setSkewFactor (double factor, bool symmetricSkew)
|
|
|
{
|
|
|
{
|
|
|
pimpl->skewFactor = factor;
|
|
|
|
|
|
pimpl->symmetricSkew = symmetricSkew;
|
|
|
|
|
|
|
|
|
pimpl->normRange.skew = factor;
|
|
|
|
|
|
pimpl->normRange.symmetricSkew = symmetricSkew;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
void Slider::setSkewFactorFromMidPoint (double sliderValueToShowAtMidPoint)
|
|
|
void Slider::setSkewFactorFromMidPoint (double sliderValueToShowAtMidPoint)
|
|
|
{
|
|
|
{
|
|
|
pimpl->setSkewFactorFromMidPoint (sliderValueToShowAtMidPoint);
|
|
|
|
|
|
pimpl->symmetricSkew = false;
|
|
|
|
|
|
|
|
|
pimpl->normRange.setSkewForCentre (sliderValueToShowAtMidPoint);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
int Slider::getMouseDragSensitivity() const noexcept { return pimpl->pixelsForFullDragExtent; }
|
|
|
int Slider::getMouseDragSensitivity() const noexcept { return pimpl->pixelsForFullDragExtent; }
|
|
|
@@ -1490,13 +1476,14 @@ void Slider::lookAndFeelChanged() { pimpl->lookAndFeelChanged (getLookAndFeel( |
|
|
void Slider::enablementChanged() { repaint(); pimpl->updateTextBoxEnablement(); }
|
|
|
void Slider::enablementChanged() { repaint(); pimpl->updateTextBoxEnablement(); }
|
|
|
|
|
|
|
|
|
//==============================================================================
|
|
|
//==============================================================================
|
|
|
Range<double> Slider::getRange() const noexcept { return { pimpl->minimum, pimpl->maximum }; }
|
|
|
|
|
|
double Slider::getMaximum() const noexcept { return pimpl->maximum; }
|
|
|
|
|
|
double Slider::getMinimum() const noexcept { return pimpl->minimum; }
|
|
|
|
|
|
double Slider::getInterval() const noexcept { return pimpl->interval; }
|
|
|
|
|
|
|
|
|
Range<double> Slider::getRange() const noexcept { return { pimpl->normRange.start, pimpl->normRange.end }; }
|
|
|
|
|
|
double Slider::getMaximum() const noexcept { return pimpl->normRange.end; }
|
|
|
|
|
|
double Slider::getMinimum() const noexcept { return pimpl->normRange.start; }
|
|
|
|
|
|
double Slider::getInterval() const noexcept { return pimpl->normRange.interval; }
|
|
|
|
|
|
|
|
|
void Slider::setRange (double newMin, double newMax, double newInt) { pimpl->setRange (newMin, newMax, newInt); }
|
|
|
|
|
|
void Slider::setRange (Range<double> newRange, double newInt) { pimpl->setRange (newRange.getStart(), newRange.getEnd(), newInt); }
|
|
|
|
|
|
|
|
|
void Slider::setRange (double newMin, double newMax, double newInt) { pimpl->setRange (newMin, newMax, newInt); }
|
|
|
|
|
|
void Slider::setRange (Range<double> newRange, double newInt) { pimpl->setRange (newRange.getStart(), newRange.getEnd(), newInt); }
|
|
|
|
|
|
void Slider::setNormalisableRange (NormalisableRange<double> newRange) { pimpl->setNormalisableRange (newRange); }
|
|
|
|
|
|
|
|
|
double Slider::getValue() const { return pimpl->getValue(); }
|
|
|
double Slider::getValue() const { return pimpl->getValue(); }
|
|
|
Value& Slider::getValueObject() noexcept { return pimpl->currentValue; }
|
|
|
Value& Slider::getValueObject() noexcept { return pimpl->currentValue; }
|
|
|
@@ -1574,38 +1561,12 @@ double Slider::getValueFromText (const String& text) |
|
|
|
|
|
|
|
|
double Slider::proportionOfLengthToValue (double proportion)
|
|
|
double Slider::proportionOfLengthToValue (double proportion)
|
|
|
{
|
|
|
{
|
|
|
auto skew = getSkewFactor();
|
|
|
|
|
|
|
|
|
|
|
|
if (! isSymmetricSkew())
|
|
|
|
|
|
{
|
|
|
|
|
|
if (skew != 1.0 && proportion > 0.0)
|
|
|
|
|
|
proportion = std::exp (std::log (proportion) / skew);
|
|
|
|
|
|
|
|
|
|
|
|
return getMinimum() + (getMaximum() - getMinimum()) * proportion;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
double distanceFromMiddle = 2.0 * proportion - 1.0;
|
|
|
|
|
|
|
|
|
|
|
|
if (skew != 1.0 && distanceFromMiddle != 0.0)
|
|
|
|
|
|
distanceFromMiddle = std::exp (std::log (std::abs (distanceFromMiddle)) / skew)
|
|
|
|
|
|
* (distanceFromMiddle < 0 ? -1 : 1);
|
|
|
|
|
|
|
|
|
|
|
|
return getMinimum() + (getMaximum() - getMinimum()) / 2.0 * (1 + distanceFromMiddle);
|
|
|
|
|
|
|
|
|
return pimpl->normRange.convertFrom0to1 (proportion);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
double Slider::valueToProportionOfLength (double value)
|
|
|
double Slider::valueToProportionOfLength (double value)
|
|
|
{
|
|
|
{
|
|
|
auto n = (value - getMinimum()) / (getMaximum() - getMinimum());
|
|
|
|
|
|
auto skew = getSkewFactor();
|
|
|
|
|
|
|
|
|
|
|
|
if (skew == 1.0)
|
|
|
|
|
|
return n;
|
|
|
|
|
|
|
|
|
|
|
|
if (! isSymmetricSkew())
|
|
|
|
|
|
return std::pow (n, skew);
|
|
|
|
|
|
|
|
|
|
|
|
double distanceFromMiddle = 2.0 * n - 1.0;
|
|
|
|
|
|
return (1.0 + std::pow (std::abs (distanceFromMiddle), skew) * (distanceFromMiddle < 0 ? -1 : 1)) / 2.0;
|
|
|
|
|
|
|
|
|
return pimpl->normRange.convertTo0to1 (value);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
double Slider::snapValue (double attemptedValue, DragMode)
|
|
|
double Slider::snapValue (double attemptedValue, DragMode)
|
|
|
|