| @@ -52,9 +52,9 @@ static void showBubbleMessage (Component* targetComponent, const String& textToS | |||
| */ | |||
| 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. | |||
| if (attemptedValue > 40 && attemptedValue < 60) | |||
| @@ -375,7 +375,7 @@ public: | |||
| const double delta = (button == incButton) ? interval : -interval; | |||
| 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 | |||
| { | |||
| 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()) | |||
| { | |||
| @@ -873,6 +873,8 @@ public: | |||
| && ! ((style == LinearBar || style == LinearBarVertical) | |||
| && e.mouseWasClicked() && valueBox != nullptr && valueBox->isEditable())) | |||
| { | |||
| DragMode dragMode = notDragging; | |||
| if (style == Rotary) | |||
| { | |||
| handleRotaryDrag (e); | |||
| @@ -889,21 +891,27 @@ public: | |||
| } | |||
| if (isAbsoluteDragMode (e.mods) || (maximum - minimum) / sliderRegionSize < interval) | |||
| { | |||
| dragMode = notDragging; | |||
| handleAbsoluteDrag (e); | |||
| } | |||
| else | |||
| { | |||
| dragMode = velocityDrag; | |||
| handleVelocityDrag (e); | |||
| } | |||
| } | |||
| valueWhenLastDragged = jlimit (minimum, maximum, valueWhenLastDragged); | |||
| if (sliderBeingDragged == 0) | |||
| { | |||
| setValue (owner.snapValue (valueWhenLastDragged, true), | |||
| setValue (owner.snapValue (valueWhenLastDragged, dragMode), | |||
| sendChangeOnlyOnRelease ? dontSendNotification : sendNotificationSync); | |||
| } | |||
| else if (sliderBeingDragged == 1) | |||
| { | |||
| setMinValue (owner.snapValue (valueWhenLastDragged, true), | |||
| setMinValue (owner.snapValue (valueWhenLastDragged, dragMode), | |||
| sendChangeOnlyOnRelease ? dontSendNotification : sendNotificationAsync, true); | |||
| if (e.mods.isShiftDown()) | |||
| @@ -913,7 +921,7 @@ public: | |||
| } | |||
| else if (sliderBeingDragged == 2) | |||
| { | |||
| setMaxValue (owner.snapValue (valueWhenLastDragged, true), | |||
| setMaxValue (owner.snapValue (valueWhenLastDragged, dragMode), | |||
| sendChangeOnlyOnRelease ? dontSendNotification : sendNotificationAsync, true); | |||
| if (e.mods.isShiftDown()) | |||
| @@ -994,7 +1002,7 @@ public: | |||
| delta = -delta; | |||
| DragInProgress drag (*this); | |||
| setValue (owner.snapValue (value + delta, false), sendNotificationSync); | |||
| setValue (owner.snapValue (value + delta, notDragging), sendNotificationSync); | |||
| } | |||
| return true; | |||
| @@ -1534,7 +1542,7 @@ double Slider::valueToProportionOfLength (double value) | |||
| return skew == 1.0 ? n : pow (n, skew); | |||
| } | |||
| double Slider::snapValue (double attemptedValue, const bool) | |||
| double Slider::snapValue (double attemptedValue, DragMode) | |||
| { | |||
| return attemptedValue; | |||
| } | |||
| @@ -97,6 +97,16 @@ public: | |||
| 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. | |||
| 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; | |||
| //============================================================================== | |||
| /** 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 | |||
| 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 | |||
| 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 setMinAndMaxValues (double, double, bool, bool)); | |||
| JUCE_DEPRECATED (void setMinAndMaxValues (double, double, bool)); | |||
| virtual void snapValue (double, bool) {} | |||
| #endif | |||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Slider) | |||