| @@ -52,9 +52,9 @@ static void showBubbleMessage (Component* targetComponent, const String& textToS | |||||
| */ | */ | ||||
| struct SnappingSlider : public Slider | struct SnappingSlider : public Slider | ||||
| { | { | ||||
| double snapValue (double attemptedValue, bool userIsDragging) override | |||||
| double snapValue (double attemptedValue, DragMode dragMode) override | |||||
| { | { | ||||
| if (! userIsDragging) | |||||
| if (dragMode == notDragging) | |||||
| return attemptedValue; // if they're entering the value in the text-box, don't mess with it. | return attemptedValue; // if they're entering the value in the text-box, don't mess with it. | ||||
| if (attemptedValue > 40 && attemptedValue < 60) | if (attemptedValue > 40 && attemptedValue < 60) | ||||
| @@ -375,7 +375,7 @@ public: | |||||
| const double delta = (button == incButton) ? interval : -interval; | const double delta = (button == incButton) ? interval : -interval; | ||||
| DragInProgress drag (*this); | DragInProgress drag (*this); | ||||
| setValue (owner.snapValue (getValue() + delta, false), sendNotificationSync); | |||||
| setValue (owner.snapValue (getValue() + delta, notDragging), sendNotificationSync); | |||||
| } | } | ||||
| } | } | ||||
| @@ -394,7 +394,7 @@ public: | |||||
| void labelTextChanged (Label* label) override | void labelTextChanged (Label* label) override | ||||
| { | { | ||||
| const double newValue = owner.snapValue (owner.getValueFromText (label->getText()), false); | |||||
| const double newValue = owner.snapValue (owner.getValueFromText (label->getText()), notDragging); | |||||
| if (newValue != (double) currentValue.getValue()) | if (newValue != (double) currentValue.getValue()) | ||||
| { | { | ||||
| @@ -873,6 +873,8 @@ public: | |||||
| && ! ((style == LinearBar || style == LinearBarVertical) | && ! ((style == LinearBar || style == LinearBarVertical) | ||||
| && e.mouseWasClicked() && valueBox != nullptr && valueBox->isEditable())) | && e.mouseWasClicked() && valueBox != nullptr && valueBox->isEditable())) | ||||
| { | { | ||||
| DragMode dragMode = notDragging; | |||||
| if (style == Rotary) | if (style == Rotary) | ||||
| { | { | ||||
| handleRotaryDrag (e); | handleRotaryDrag (e); | ||||
| @@ -889,21 +891,27 @@ public: | |||||
| } | } | ||||
| if (isAbsoluteDragMode (e.mods) || (maximum - minimum) / sliderRegionSize < interval) | if (isAbsoluteDragMode (e.mods) || (maximum - minimum) / sliderRegionSize < interval) | ||||
| { | |||||
| dragMode = notDragging; | |||||
| handleAbsoluteDrag (e); | handleAbsoluteDrag (e); | ||||
| } | |||||
| else | else | ||||
| { | |||||
| dragMode = velocityDrag; | |||||
| handleVelocityDrag (e); | handleVelocityDrag (e); | ||||
| } | |||||
| } | } | ||||
| valueWhenLastDragged = jlimit (minimum, maximum, valueWhenLastDragged); | valueWhenLastDragged = jlimit (minimum, maximum, valueWhenLastDragged); | ||||
| if (sliderBeingDragged == 0) | if (sliderBeingDragged == 0) | ||||
| { | { | ||||
| setValue (owner.snapValue (valueWhenLastDragged, true), | |||||
| setValue (owner.snapValue (valueWhenLastDragged, dragMode), | |||||
| sendChangeOnlyOnRelease ? dontSendNotification : sendNotificationSync); | sendChangeOnlyOnRelease ? dontSendNotification : sendNotificationSync); | ||||
| } | } | ||||
| else if (sliderBeingDragged == 1) | else if (sliderBeingDragged == 1) | ||||
| { | { | ||||
| setMinValue (owner.snapValue (valueWhenLastDragged, true), | |||||
| setMinValue (owner.snapValue (valueWhenLastDragged, dragMode), | |||||
| sendChangeOnlyOnRelease ? dontSendNotification : sendNotificationAsync, true); | sendChangeOnlyOnRelease ? dontSendNotification : sendNotificationAsync, true); | ||||
| if (e.mods.isShiftDown()) | if (e.mods.isShiftDown()) | ||||
| @@ -913,7 +921,7 @@ public: | |||||
| } | } | ||||
| else if (sliderBeingDragged == 2) | else if (sliderBeingDragged == 2) | ||||
| { | { | ||||
| setMaxValue (owner.snapValue (valueWhenLastDragged, true), | |||||
| setMaxValue (owner.snapValue (valueWhenLastDragged, dragMode), | |||||
| sendChangeOnlyOnRelease ? dontSendNotification : sendNotificationAsync, true); | sendChangeOnlyOnRelease ? dontSendNotification : sendNotificationAsync, true); | ||||
| if (e.mods.isShiftDown()) | if (e.mods.isShiftDown()) | ||||
| @@ -994,7 +1002,7 @@ public: | |||||
| delta = -delta; | delta = -delta; | ||||
| DragInProgress drag (*this); | DragInProgress drag (*this); | ||||
| setValue (owner.snapValue (value + delta, false), sendNotificationSync); | |||||
| setValue (owner.snapValue (value + delta, notDragging), sendNotificationSync); | |||||
| } | } | ||||
| return true; | return true; | ||||
| @@ -1534,7 +1542,7 @@ double Slider::valueToProportionOfLength (double value) | |||||
| return skew == 1.0 ? n : pow (n, skew); | return skew == 1.0 ? n : pow (n, skew); | ||||
| } | } | ||||
| double Slider::snapValue (double attemptedValue, const bool) | |||||
| double Slider::snapValue (double attemptedValue, DragMode) | |||||
| { | { | ||||
| return attemptedValue; | return attemptedValue; | ||||
| } | } | ||||
| @@ -97,6 +97,16 @@ public: | |||||
| TextBoxBelow /**< Puts the text box below the slider, horizontally centred. */ | TextBoxBelow /**< Puts the text box below the slider, horizontally centred. */ | ||||
| }; | }; | ||||
| /** Describes the type of mouse-dragging that is happening when a value is being changed. | |||||
| @see snapValue | |||||
| */ | |||||
| enum DragMode | |||||
| { | |||||
| notDragging, /**< Dragging is not active. */ | |||||
| absoluteDrag, /**< The dragging corresponds directly to the value that is displayed. */ | |||||
| velocityDrag /**< The dragging value change is relative to the velocity of the mouse mouvement. */ | |||||
| }; | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Creates a slider. | /** Creates a slider. | ||||
| When created, you can set up the slider's style and range with setSliderStyle(), setRange(), etc. | When created, you can set up the slider's style and range with setSliderStyle(), setRange(), etc. | ||||
| @@ -157,7 +167,7 @@ public: | |||||
| int getMouseDragSensitivity() const noexcept; | int getMouseDragSensitivity() const noexcept; | ||||
| //============================================================================== | //============================================================================== | ||||
| /** Changes the way the the mouse is used when dragging the slider. | |||||
| /** Changes the way the mouse is used when dragging the slider. | |||||
| If true, this will turn on velocity-sensitive dragging, so that | If true, this will turn on velocity-sensitive dragging, so that | ||||
| the faster the mouse moves, the bigger the movement to the slider. This | the faster the mouse moves, the bigger the movement to the slider. This | ||||
| @@ -720,12 +730,13 @@ public: | |||||
| a given position, and allows a subclass to sanity-check this value, possibly | a given position, and allows a subclass to sanity-check this value, possibly | ||||
| returning a different value to use instead. | returning a different value to use instead. | ||||
| @param attemptedValue the value the user is trying to enter | |||||
| @param userIsDragging true if the user is dragging with the mouse; false if | |||||
| they are entering the value using the text box | |||||
| @returns the value to use instead | |||||
| @param attemptedValue the value the user is trying to enter | |||||
| @param dragMode indicates whether the user is dragging with | |||||
| the mouse; notDragging if they are entering the value | |||||
| using the text box or other non-dragging interaction | |||||
| @returns the value to use instead | |||||
| */ | */ | ||||
| virtual double snapValue (double attemptedValue, bool userIsDragging); | |||||
| virtual double snapValue (double attemptedValue, DragMode dragMode); | |||||
| //============================================================================== | //============================================================================== | ||||
| @@ -874,6 +885,7 @@ private: | |||||
| JUCE_DEPRECATED (void setMaxValue (double, bool)); | JUCE_DEPRECATED (void setMaxValue (double, bool)); | ||||
| JUCE_DEPRECATED (void setMinAndMaxValues (double, double, bool, bool)); | JUCE_DEPRECATED (void setMinAndMaxValues (double, double, bool, bool)); | ||||
| JUCE_DEPRECATED (void setMinAndMaxValues (double, double, bool)); | JUCE_DEPRECATED (void setMinAndMaxValues (double, double, bool)); | ||||
| virtual void snapValue (double, bool) {} | |||||
| #endif | #endif | ||||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Slider) | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Slider) | ||||