Browse Source

Silder bugfix, addition of new dragging mode, and a bit of internal tidying-up.

tags/2021-05-28
jules 13 years ago
parent
commit
a84c446738
2 changed files with 110 additions and 105 deletions
  1. +86
    -83
      modules/juce_gui_basics/widgets/juce_Slider.cpp
  2. +24
    -22
      modules/juce_gui_basics/widgets/juce_Slider.h

+ 86
- 83
modules/juce_gui_basics/widgets/juce_Slider.cpp View File

@@ -33,7 +33,7 @@ public:
: owner (owner_),
style (style_),
lastCurrentValue (0), lastValueMin (0), lastValueMax (0),
minimum (0), maximum (10), interval (0),
minimum (0), maximum (10), interval (0), doubleClickReturnValue (0),
skewFactor (1.0), velocityModeSensitivity (1.0),
velocityModeOffset (0.0), velocityModeThreshold (1),
rotaryStart (float_Pi * 1.2f),
@@ -69,7 +69,7 @@ public:
}
//==============================================================================
void init()
void registerListeners()
{
currentValue.addListener (this);
valueMin.addListener (this);
@@ -91,7 +91,21 @@ public:
|| style == ThreeValueVertical;
}
float getPositionOfValue (const double value)
bool isRotary() const noexcept
{
return style == Rotary
|| style == RotaryHorizontalDrag
|| style == RotaryVerticalDrag
|| style == RotaryHorizontalVerticalDrag;
}
bool incDecDragDirectionIsHorizontal() const noexcept
{
return incDecButtonMode == incDecButtonsDraggable_Horizontal
|| (incDecButtonMode == incDecButtonsDraggable_AutoDirection && incDecButtonsSideBySide);
}
float getPositionOfValue (const double value) const
{
if (isHorizontal() || isVertical())
{
@@ -104,13 +118,9 @@ public:
}
}
void setRange (const double newMin,
const double newMax,
const double newInt)
void setRange (const double newMin, const double newMax, const double newInt)
{
if (minimum != newMin
|| maximum != newMax
|| interval != newInt)
if (minimum != newMin || maximum != newMax || interval != newInt)
{
minimum = newMin;
maximum = newMax;
@@ -155,9 +165,7 @@ public:
return currentValue.getValue();
}
void setValue (double newValue,
const bool sendUpdateMessage,
const bool sendMessageSynchronously)
void setValue (double newValue, const bool sendUpdateMessage, const bool sendMessageSynchronously)
{
// for a two-value style slider, you should use the setMinValue() and setMaxValue()
// methods to set the two values.
@@ -235,7 +243,8 @@ public:
}
}
void setMaxValue (double newValue, const bool sendUpdateMessage, const bool sendMessageSynchronously, const bool allowNudgingOfOtherValues)
void setMaxValue (double newValue, const bool sendUpdateMessage,
const bool sendMessageSynchronously, const bool allowNudgingOfOtherValues)
{
// The maximum value only applies to sliders that are in two- or three-value mode.
jassert (style == TwoValueHorizontal || style == TwoValueVertical
@@ -358,13 +367,10 @@ public:
{
if (style == IncDecButtons)
{
sendDragStart();
if (button == incButton)
setValue (owner.snapValue (getValue() + interval, false), true, true);
else if (button == decButton)
setValue (owner.snapValue (getValue() - interval, false), true, true);
const double delta = (button == incButton) ? interval : -interval;
sendDragStart();
setValue (owner.snapValue (getValue() + delta, false), true, true);
sendDragEnd();
}
}
@@ -415,35 +421,35 @@ public:
return value;
}
float getLinearSliderPos (const double value)
float getLinearSliderPos (const double value) const
{
double sliderPosProportional;
double pos;
if (maximum > minimum)
{
if (value < minimum)
{
sliderPosProportional = 0.0;
pos = 0.0;
}
else if (value > maximum)
{
sliderPosProportional = 1.0;
pos = 1.0;
}
else
{
sliderPosProportional = owner.valueToProportionOfLength (value);
jassert (sliderPosProportional >= 0 && sliderPosProportional <= 1.0);
pos = owner.valueToProportionOfLength (value);
jassert (pos >= 0 && pos <= 1.0);
}
}
else
{
sliderPosProportional = 0.5;
pos = 0.5;
}
if (isVertical() || style == IncDecButtons)
sliderPosProportional = 1.0 - sliderPosProportional;
pos = 1.0 - pos;
return (float) (sliderRegionStart + sliderPosProportional * sliderRegionSize);
return (float) (sliderRegionStart + pos * sliderRegionSize);
}
void setSliderStyle (const SliderStyle newStyle)
@@ -617,35 +623,46 @@ public:
owner.repaint();
}
bool incDecDragDirectionIsHorizontal() const
{
return incDecButtonMode == incDecButtonsDraggable_Horizontal
|| (incDecButtonMode == incDecButtonsDraggable_AutoDirection && incDecButtonsSideBySide);
}
void showPopupMenu()
{
menuShown = true;
PopupMenu m;
m.setLookAndFeel (&owner.getLookAndFeel());
m.addItem (1, TRANS ("velocity-sensitive mode"), true, isVelocityBased);
m.addItem (1, TRANS ("Velocity-sensitive mode"), true, isVelocityBased);
m.addSeparator();
if (style == Rotary || style == RotaryHorizontalDrag || style == RotaryVerticalDrag)
if (isRotary())
{
PopupMenu rotaryMenu;
rotaryMenu.addItem (2, TRANS ("use circular dragging"), true, style == Rotary);
rotaryMenu.addItem (3, TRANS ("use left-right dragging"), true, style == RotaryHorizontalDrag);
rotaryMenu.addItem (4, TRANS ("use up-down dragging"), true, style == RotaryVerticalDrag);
rotaryMenu.addItem (2, TRANS ("Use circular dragging"), true, style == Rotary);
rotaryMenu.addItem (3, TRANS ("Use left-right dragging"), true, style == RotaryHorizontalDrag);
rotaryMenu.addItem (4, TRANS ("Use up-down dragging"), true, style == RotaryVerticalDrag);
rotaryMenu.addItem (5, TRANS ("Use left-right/up-down dragging"), true, style == RotaryHorizontalVerticalDrag);
m.addSubMenu (TRANS ("rotary mode"), rotaryMenu);
m.addSubMenu (TRANS ("Rotary mode"), rotaryMenu);
}
m.showMenuAsync (PopupMenu::Options(),
ModalCallbackFunction::forComponent (sliderMenuCallback, &owner));
}
static void sliderMenuCallback (const int result, Slider* slider)
{
if (slider != nullptr)
{
switch (result)
{
case 1: slider->setVelocityBasedMode (! slider->getVelocityBasedMode()); break;
case 2: slider->setSliderStyle (Rotary); break;
case 3: slider->setSliderStyle (RotaryHorizontalDrag); break;
case 4: slider->setSliderStyle (RotaryVerticalDrag); break;
case 5: slider->setSliderStyle (RotaryHorizontalVerticalDrag); break;
default: break;
}
}
}
int getThumbIndexAt (const MouseEvent& e)
{
const bool isTwoValue = (style == TwoValueHorizontal || style == TwoValueVertical);
@@ -722,8 +739,7 @@ public:
void handleAbsoluteDrag (const MouseEvent& e)
{
const int mousePos = (isHorizontal() || style == RotaryHorizontalDrag) ? e.x : e.y;
double scaledMousePos = (mousePos - sliderRegionStart) / (double) sliderRegionSize;
double newPos = (mousePos - sliderRegionStart) / (double) sliderRegionSize;
if (style == RotaryHorizontalDrag
|| style == RotaryVerticalDrag
@@ -738,10 +754,8 @@ public:
? e.x - mouseDragStartPos.x
: mouseDragStartPos.y - e.y;
double newPos = owner.valueToProportionOfLength (valueOnMouseDown)
+ mouseDiff * (1.0 / pixelsForFullDragExtent);
valueWhenLastDragged = owner.proportionOfLengthToValue (jlimit (0.0, 1.0, newPos));
newPos = owner.valueToProportionOfLength (valueOnMouseDown)
+ mouseDiff * (1.0 / pixelsForFullDragExtent);
if (style == IncDecButtons)
{
@@ -749,21 +763,31 @@ public:
decButton->setState (mouseDiff > 0 ? Button::buttonNormal : Button::buttonDown);
}
}
else if (style == RotaryHorizontalVerticalDrag)
{
const int mouseDiff = (e.x - mouseDragStartPos.x) + (mouseDragStartPos.y - e.y);
newPos = owner.valueToProportionOfLength (valueOnMouseDown)
+ mouseDiff * (1.0 / pixelsForFullDragExtent);
}
else
{
if (isVertical())
scaledMousePos = 1.0 - scaledMousePos;
valueWhenLastDragged = owner.proportionOfLengthToValue (jlimit (0.0, 1.0, scaledMousePos));
newPos = 1.0 - newPos;
}
valueWhenLastDragged = owner.proportionOfLengthToValue (jlimit (0.0, 1.0, newPos));
}
void handleVelocityDrag (const MouseEvent& e)
{
const int mouseDiff = (isHorizontal() || style == RotaryHorizontalDrag
|| (style == IncDecButtons && incDecDragDirectionIsHorizontal()))
? e.x - mousePosWhenLastDragged.x
: e.y - mousePosWhenLastDragged.y;
const int mouseDiff = style == RotaryHorizontalVerticalDrag
? (e.x - mousePosWhenLastDragged.x) + (mousePosWhenLastDragged.y - e.y)
: (isHorizontal()
|| style == RotaryHorizontalDrag
|| (style == IncDecButtons && incDecDragDirectionIsHorizontal()))
? e.x - mousePosWhenLastDragged.x
: e.y - mousePosWhenLastDragged.y;
const double maxSpeed = jmax (200, sliderRegionSize);
double speed = jlimit (0.0, maxSpeed, (double) abs (mouseDiff));
@@ -998,22 +1022,16 @@ public:
: (double) currentValue.getValue());
Point<int> mousePos;
if (style == RotaryHorizontalDrag || style == RotaryVerticalDrag)
if (isRotary())
{
mousePos = Desktop::getLastMouseDownPosition();
if (style == RotaryHorizontalDrag)
{
const double posDiff = owner.valueToProportionOfLength (pos)
- owner.valueToProportionOfLength (valueOnMouseDown);
mousePos += Point<int> (roundToInt (pixelsForFullDragExtent * posDiff), 0);
}
else
{
const double posDiff = owner.valueToProportionOfLength (valueOnMouseDown)
- owner.valueToProportionOfLength (pos);
mousePos += Point<int> (0, roundToInt (pixelsForFullDragExtent * posDiff));
}
const int delta = roundToInt (pixelsForFullDragExtent * (owner.valueToProportionOfLength (valueOnMouseDown)
- owner.valueToProportionOfLength (pos)));
if (style == RotaryHorizontalDrag) mousePos += Point<int> (-delta, 0);
else if (style == RotaryVerticalDrag) mousePos += Point<int> (0, delta);
else mousePos += Point<int> (delta / -2, delta / 2);
}
else
{
@@ -1032,7 +1050,7 @@ public:
{
if (style != IncDecButtons)
{
if (style == Rotary || style == RotaryHorizontalDrag || style == RotaryVerticalDrag)
if (isRotary())
{
const float sliderPos = (float) owner.valueToProportionOfLength (lastCurrentValue);
jassert (sliderPos >= 0 && sliderPos <= 1.0f);
@@ -1268,21 +1286,6 @@ public:
std::abs (a1 + double_Pi * 2.0 - a2),
std::abs (a2 + double_Pi * 2.0 - a1));
}
static void sliderMenuCallback (const int result, Slider* slider)
{
if (slider != nullptr)
{
switch (result)
{
case 1: slider->setVelocityBasedMode (! slider->getVelocityBasedMode()); break;
case 2: slider->setSliderStyle (Rotary); break;
case 3: slider->setSliderStyle (RotaryHorizontalDrag); break;
case 4: slider->setSliderStyle (RotaryVerticalDrag); break;
default: break;
}
}
}
};
@@ -1312,7 +1315,7 @@ void Slider::init (SliderStyle style, TextEntryBoxPosition textBoxPos)
Slider::lookAndFeelChanged();
updateText();
pimpl->init();
pimpl->registerListeners();
}
Slider::~Slider() {}


+ 24
- 22
modules/juce_gui_basics/widgets/juce_Slider.h View File

@@ -61,28 +61,30 @@ public:
*/
enum SliderStyle
{
LinearHorizontal, /**< A traditional horizontal slider. */
LinearVertical, /**< A traditional vertical slider. */
LinearBar, /**< A horizontal bar slider with the text label drawn on top of it. */
Rotary, /**< A rotary control that you move by dragging the mouse in a circular motion, like a knob.
@see setRotaryParameters */
RotaryHorizontalDrag, /**< A rotary control that you move by dragging the mouse left-to-right.
@see setRotaryParameters */
RotaryVerticalDrag, /**< A rotary control that you move by dragging the mouse up-and-down.
@see setRotaryParameters */
IncDecButtons, /**< A pair of buttons that increment or decrement the slider's value by the increment set in setRange(). */
TwoValueHorizontal, /**< A horizontal slider that has two thumbs instead of one, so it can show a minimum and maximum value.
@see setMinValue, setMaxValue */
TwoValueVertical, /**< A vertical slider that has two thumbs instead of one, so it can show a minimum and maximum value.
@see setMinValue, setMaxValue */
ThreeValueHorizontal, /**< A horizontal slider that has three thumbs instead of one, so it can show a minimum and maximum
value, with the current value being somewhere between them.
@see setMinValue, setMaxValue */
ThreeValueVertical, /**< A vertical slider that has three thumbs instead of one, so it can show a minimum and maximum
value, with the current value being somewhere between them.
@see setMinValue, setMaxValue */
LinearHorizontal, /**< A traditional horizontal slider. */
LinearVertical, /**< A traditional vertical slider. */
LinearBar, /**< A horizontal bar slider with the text label drawn on top of it. */
Rotary, /**< A rotary control that you move by dragging the mouse in a circular motion, like a knob.
@see setRotaryParameters */
RotaryHorizontalDrag, /**< A rotary control that you move by dragging the mouse left-to-right.
@see setRotaryParameters */
RotaryVerticalDrag, /**< A rotary control that you move by dragging the mouse up-and-down.
@see setRotaryParameters */
RotaryHorizontalVerticalDrag, /**< A rotary control that you move by dragging the mouse up-and-down or left-to-right.
@see setRotaryParameters */
IncDecButtons, /**< A pair of buttons that increment or decrement the slider's value by the increment set in setRange(). */
TwoValueHorizontal, /**< A horizontal slider that has two thumbs instead of one, so it can show a minimum and maximum value.
@see setMinValue, setMaxValue */
TwoValueVertical, /**< A vertical slider that has two thumbs instead of one, so it can show a minimum and maximum value.
@see setMinValue, setMaxValue */
ThreeValueHorizontal, /**< A horizontal slider that has three thumbs instead of one, so it can show a minimum and maximum
value, with the current value being somewhere between them.
@see setMinValue, setMaxValue */
ThreeValueVertical, /**< A vertical slider that has three thumbs instead of one, so it can show a minimum and maximum
value, with the current value being somewhere between them.
@see setMinValue, setMaxValue */
};
/** The position of the slider's text-entry box.


Loading…
Cancel
Save