Browse Source

Added a setNormalisableRange method to Slider

tags/2021-05-28
Tom Poole 7 years ago
parent
commit
284fdc51df
3 changed files with 114 additions and 109 deletions
  1. +41
    -3
      modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp
  2. +67
    -106
      modules/juce_gui_basics/widgets/juce_Slider.cpp
  3. +6
    -0
      modules/juce_gui_basics/widgets/juce_Slider.h

+ 41
- 3
modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp View File

@@ -422,10 +422,48 @@ struct AudioProcessorValueTreeState::SliderAttachment::Pimpl : private Attached
: AttachedControlBase (s, p), slider (sl), ignoreCallbacks (false)
{
NormalisableRange<float> range (s.getParameterRange (paramID));
slider.setRange (range.start, range.end, range.interval);
slider.setSkewFactor (range.skew, range.symmetricSkew);
if (AudioProcessorParameter* param = state.getParameter (paramID))
if (range.interval != 0 || range.skew != 0)
{
slider.setRange (range.start, range.end, range.interval);
slider.setSkewFactor (range.skew, range.symmetricSkew);
}
else
{
auto convertFrom0To1Function = [range] (double currentRangeStart,
double currentRangeEnd,
double normalisedValue) mutable
{
range.start = (float) currentRangeStart;
range.end = (float) currentRangeEnd;
return (double) range.convertFrom0to1 ((float) normalisedValue);
};
auto convertTo0To1Function = [range] (double currentRangeStart,
double currentRangeEnd,
double mappedValue) mutable
{
range.start = (float) currentRangeStart;
range.end = (float) currentRangeEnd;
return (double) range.convertTo0to1 ((float) mappedValue);
};
auto snapToLegalValueFunction = [range] (double currentRangeStart,
double currentRangeEnd,
double valueToSnap) mutable
{
range.start = (float) currentRangeStart;
range.end = (float) currentRangeEnd;
return (double) range.snapToLegalValue ((float) valueToSnap);
};
slider.setNormalisableRange ({ (double) range.start, (double) range.end,
convertFrom0To1Function,
convertTo0To1Function,
snapToLegalValueFunction });
}
if (auto* param = state.getParameter (paramID))
slider.setDoubleClickReturnValue (true, range.convertFrom0to1 (param->getDefaultValue()));
sendInitialUpdate();


+ 67
- 106
modules/juce_gui_basics/widgets/juce_Slider.cpp View File

@@ -103,45 +103,47 @@ public:
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
@@ -423,26 +425,18 @@ public:
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
{
double pos;
if (maximum <= minimum)
if (normRange.end <= normRange.start)
pos = 0.5;
else if (value < minimum)
else if (value < normRange.start)
pos = 0.0;
else if (value > maximum)
else if (value > normRange.end)
pos = 1.0;
else
pos = owner.valueToProportionOfLength (value);
@@ -475,13 +469,6 @@ public:
modifierToSwapModes = newModifierToSwapModes;
}
void setSkewFactorFromMidPoint (double sliderValueToShowAtMidPoint)
{
if (maximum > minimum)
skewFactor = std::log (0.5) / std::log ((sliderValueToShowAtMidPoint - minimum)
/ (maximum - minimum));
}
void setIncDecButtonsMode (IncDecButtonMode mode)
{
if (incDecButtonMode != mode)
@@ -592,8 +579,8 @@ public:
owner.addAndMakeVisible (incButton.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)
{
@@ -835,7 +822,7 @@ public:
{
mouseDoubleClick();
}
else if (maximum > minimum)
else if (normRange.end > normRange.start)
{
useDragEvents = true;
@@ -871,7 +858,7 @@ public:
void mouseDrag (const MouseEvent& e)
{
if (useDragEvents && maximum > minimum
if (useDragEvents && normRange.end > normRange.start
&& ! ((style == LinearBar || style == LinearBarVertical)
&& e.mouseWasClicked() && valueBox != nullptr && valueBox->isEditable()))
{
@@ -892,7 +879,7 @@ public:
mouseDragStartPos = e.position;
}
if (isAbsoluteDragMode (e.mods) || (maximum - minimum) / sliderRegionSize < interval)
if (isAbsoluteDragMode (e.mods) || (normRange.end - normRange.start) / sliderRegionSize < normRange.interval)
{
dragMode = absoluteDrag;
handleAbsoluteDrag (e);
@@ -904,7 +891,7 @@ public:
}
}
valueWhenLastDragged = jlimit (minimum, maximum, valueWhenLastDragged);
valueWhenLastDragged = jlimit (normRange.start, normRange.end, valueWhenLastDragged);
if (sliderBeingDragged == 0)
{
@@ -940,7 +927,7 @@ public:
{
if (owner.isEnabled()
&& useDragEvents
&& (maximum > minimum)
&& (normRange.end > normRange.start)
&& (style != IncDecButtons || incDecDragged))
{
restoreMouseIfHidden();
@@ -1034,8 +1021,8 @@ public:
{
return doubleClickToValue
&& style != IncDecButtons
&& minimum <= doubleClickReturnValue
&& maximum >= doubleClickReturnValue;
&& normRange.start <= doubleClickReturnValue
&& normRange.end >= doubleClickReturnValue;
}
void mouseDoubleClick()
@@ -1050,7 +1037,7 @@ public:
double getMouseWheelDelta (double value, double wheelAmount)
{
if (style == IncDecButtons)
return interval * wheelAmount;
return normRange.interval * wheelAmount;
auto proportionDelta = wheelAmount * 0.15;
auto currentPos = owner.valueToProportionOfLength (value);
@@ -1069,7 +1056,7 @@ public:
{
lastMouseWheelTime = e.eventTime;
if (maximum > minimum && ! e.mods.isAnyMouseButtonDown())
if (normRange.end > normRange.start && ! e.mods.isAnyMouseButtonDown())
{
if (valueBox != nullptr)
valueBox->hideEditor (false);
@@ -1080,7 +1067,7 @@ public:
* (wheel.isReversed ? -1.0f : 1.0f));
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);
setValue (owner.snapValue (newValue, notDragging), sendNotificationSync);
@@ -1242,9 +1229,9 @@ public:
ListenerList<Slider::Listener> listeners;
Value currentValue, valueMin, valueMax;
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;
int velocityModeThreshold = 1;
RotaryParameters rotaryParams;
@@ -1426,19 +1413,18 @@ void Slider::setVelocityModeParameters (double sensitivity, int threshold,
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)
{
pimpl->skewFactor = factor;
pimpl->symmetricSkew = symmetricSkew;
pimpl->normRange.skew = factor;
pimpl->normRange.symmetricSkew = symmetricSkew;
}
void Slider::setSkewFactorFromMidPoint (double sliderValueToShowAtMidPoint)
{
pimpl->setSkewFactorFromMidPoint (sliderValueToShowAtMidPoint);
pimpl->symmetricSkew = false;
pimpl->normRange.setSkewForCentre (sliderValueToShowAtMidPoint);
}
int Slider::getMouseDragSensitivity() const noexcept { return pimpl->pixelsForFullDragExtent; }
@@ -1490,13 +1476,14 @@ void Slider::lookAndFeelChanged() { pimpl->lookAndFeelChanged (getLookAndFeel(
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(); }
Value& Slider::getValueObject() noexcept { return pimpl->currentValue; }
@@ -1574,38 +1561,12 @@ double Slider::getValueFromText (const String& text)
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)
{
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)


+ 6
- 0
modules/juce_gui_basics/widgets/juce_Slider.h View File

@@ -416,6 +416,12 @@ public:
*/
void setRange (Range<double> newRange, double newInterval);
/** Sets a NormalisableRange to use for the Slider values.
@param newNormalisableRange the NormalisableRange to use
*/
void setNormalisableRange (NormalisableRange<double> newNormalisableRange);
/** Returns the slider's range. */
Range<double> getRange() const noexcept;


Loading…
Cancel
Save