Hello all,
I read the earlier discussion, but must beg for the important data members of Slider to be made protected rather than private, i.e., to remove line 675 of src/juce_appframework/gui/components/controls/juce_Slider.h that says
private:
For an app we built in a class, we needed a subclass (shown in action below) that handles the min and max values differently - to set the base value and random distribution range of probability distributions. For this, we wanted the look the remain, but the feel of having the min and max constrained had to change. I got it to work with just a bit of code (attached), but I had to make the data members of Slider visible to the subclass, since there are no setter/getter methods for them.
stp
//
// A RangeSlider interprets its two markers as base value and range, rather than min/max
//
class RangeSlider : public Slider {
public:
RangeSlider (const String& componentName) : Slider(componentName) { };
~RangeSlider() { };
double getBaseValue();
double getRangeValue();
void setBaseValue (double newValue, const bool sendUpdateMessage = true, const bool sendMessageSynchronously = true);
void setRangeValue (double newValue, const bool sendUpdateMessage = true, const bool sendMessageSynchronously = true);
protected:
void mouseDown (const MouseEvent& e);
void mouseDrag (const MouseEvent& e);
double baseValue, rangeValue;
};
///////////////////////////////////////////////////////////////////////
// RangeSlider methods
//
// Answer the base value
double RangeSlider::getBaseValue() {
return baseValue;
}
// answer the range (normalized to 0 - 1 -- not certain if there's a single way to do this, or if we need another state flag
double RangeSlider::getRangeValue() {
return (rangeValue - minimum) / (maximum - minimum);
}
void RangeSlider::mouseDown (const MouseEvent& e) {
float mousePos;
float maxPosDistance;
float minPosDistance;
mouseWasHidden = false;
incDecDragged = false;
if (isEnabled()) {
menuShown = false;
if (valueBox != 0)
valueBox->hideEditor (true);
sliderBeingDragged = 0;
mousePos = (float) (isVertical() ? e.y : e.x);
maxPosDistance = fabsf (getLinearSliderPos (valueMax) - 0.1f - mousePos);
minPosDistance = fabsf (getLinearSliderPos (valueMin) + 0.1f - mousePos);
if (maxPosDistance <= minPosDistance)
sliderBeingDragged = 2;
else
sliderBeingDragged = 1;
}
minMaxDiff = valueMax - valueMin;
mouseXWhenLastDragged = e.x;
mouseYWhenLastDragged = e.y;
if (sliderBeingDragged == 2)
valueWhenLastDragged = currentValue;
else if (sliderBeingDragged == 1)
valueWhenLastDragged = baseValue;
valueOnMouseDown = valueWhenLastDragged;
sendDragStart();
mouseDrag (e);
}
void RangeSlider::mouseDrag (const MouseEvent& e) {
if (isEnabled() && (! menuShown)) {
const int mousePos = (isHorizontal() || style == RotaryHorizontalDrag) ? e.x : e.y;
double scaledMousePos = (mousePos - sliderRegionStart) / (double) sliderRegionSize;
if (style == LinearVertical)
scaledMousePos = 1.0 - scaledMousePos;
valueWhenLastDragged = proportionOfLengthToValue (jlimit (0.0, 1.0, scaledMousePos));
mouseXWhenLastDragged = e.x;
mouseYWhenLastDragged = e.y;
valueWhenLastDragged = jlimit (minimum, maximum, valueWhenLastDragged);
if (sliderBeingDragged == 1)
setBaseValue(valueWhenLastDragged, ! sendChangeOnlyOnRelease, false);
else if (sliderBeingDragged == 2)
setRangeValue(valueWhenLastDragged, ! sendChangeOnlyOnRelease, false);
mouseXWhenLastDragged = e.x;
mouseYWhenLastDragged = e.y;
}
}
void RangeSlider::setBaseValue (double newValue, const bool sendUpdateMessage, const bool sendMessageSynchronously) {
if (baseValue != newValue) {
baseValue = newValue;
valueMin = newValue;
currentValue = newValue;
repaint();
if (sendUpdateMessage)
triggerChangeMessage (sendMessageSynchronously);
}
}
void RangeSlider::setRangeValue (double newValue, const bool sendUpdateMessage, const bool sendMessageSynchronously) {
if (rangeValue != newValue) {
rangeValue = newValue;
valueMax = newValue;
repaint();
if (sendUpdateMessage)
triggerChangeMessage (sendMessageSynchronously);
}
}