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_), : owner (owner_),
style (style_), style (style_),
lastCurrentValue (0), lastValueMin (0), lastValueMax (0), 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), skewFactor (1.0), velocityModeSensitivity (1.0),
velocityModeOffset (0.0), velocityModeThreshold (1), velocityModeOffset (0.0), velocityModeThreshold (1),
rotaryStart (float_Pi * 1.2f), rotaryStart (float_Pi * 1.2f),
@@ -69,7 +69,7 @@ public:
} }
//============================================================================== //==============================================================================
void init()
void registerListeners()
{ {
currentValue.addListener (this); currentValue.addListener (this);
valueMin.addListener (this); valueMin.addListener (this);
@@ -91,7 +91,21 @@ public:
|| style == ThreeValueVertical; || 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()) 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; minimum = newMin;
maximum = newMax; maximum = newMax;
@@ -155,9 +165,7 @@ public:
return currentValue.getValue(); 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() // for a two-value style slider, you should use the setMinValue() and setMaxValue()
// methods to set the two values. // 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. // The maximum value only applies to sliders that are in two- or three-value mode.
jassert (style == TwoValueHorizontal || style == TwoValueVertical jassert (style == TwoValueHorizontal || style == TwoValueVertical
@@ -358,13 +367,10 @@ public:
{ {
if (style == IncDecButtons) 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(); sendDragEnd();
} }
} }
@@ -415,35 +421,35 @@ public:
return value; return value;
} }
float getLinearSliderPos (const double value)
float getLinearSliderPos (const double value) const
{ {
double sliderPosProportional;
double pos;
if (maximum > minimum) if (maximum > minimum)
{ {
if (value < minimum) if (value < minimum)
{ {
sliderPosProportional = 0.0;
pos = 0.0;
} }
else if (value > maximum) else if (value > maximum)
{ {
sliderPosProportional = 1.0;
pos = 1.0;
} }
else else
{ {
sliderPosProportional = owner.valueToProportionOfLength (value);
jassert (sliderPosProportional >= 0 && sliderPosProportional <= 1.0);
pos = owner.valueToProportionOfLength (value);
jassert (pos >= 0 && pos <= 1.0);
} }
} }
else else
{ {
sliderPosProportional = 0.5;
pos = 0.5;
} }
if (isVertical() || style == IncDecButtons) 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) void setSliderStyle (const SliderStyle newStyle)
@@ -617,35 +623,46 @@ public:
owner.repaint(); owner.repaint();
} }
bool incDecDragDirectionIsHorizontal() const
{
return incDecButtonMode == incDecButtonsDraggable_Horizontal
|| (incDecButtonMode == incDecButtonsDraggable_AutoDirection && incDecButtonsSideBySide);
}
void showPopupMenu() void showPopupMenu()
{ {
menuShown = true; menuShown = true;
PopupMenu m; PopupMenu m;
m.setLookAndFeel (&owner.getLookAndFeel()); m.setLookAndFeel (&owner.getLookAndFeel());
m.addItem (1, TRANS ("velocity-sensitive mode"), true, isVelocityBased);
m.addItem (1, TRANS ("Velocity-sensitive mode"), true, isVelocityBased);
m.addSeparator(); m.addSeparator();
if (style == Rotary || style == RotaryHorizontalDrag || style == RotaryVerticalDrag)
if (isRotary())
{ {
PopupMenu rotaryMenu; 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(), m.showMenuAsync (PopupMenu::Options(),
ModalCallbackFunction::forComponent (sliderMenuCallback, &owner)); 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) int getThumbIndexAt (const MouseEvent& e)
{ {
const bool isTwoValue = (style == TwoValueHorizontal || style == TwoValueVertical); const bool isTwoValue = (style == TwoValueHorizontal || style == TwoValueVertical);
@@ -722,8 +739,7 @@ public:
void handleAbsoluteDrag (const MouseEvent& e) void handleAbsoluteDrag (const MouseEvent& e)
{ {
const int mousePos = (isHorizontal() || style == RotaryHorizontalDrag) ? e.x : e.y; 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 if (style == RotaryHorizontalDrag
|| style == RotaryVerticalDrag || style == RotaryVerticalDrag
@@ -738,10 +754,8 @@ public:
? e.x - mouseDragStartPos.x ? e.x - mouseDragStartPos.x
: mouseDragStartPos.y - e.y; : 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) if (style == IncDecButtons)
{ {
@@ -749,21 +763,31 @@ public:
decButton->setState (mouseDiff > 0 ? Button::buttonNormal : Button::buttonDown); 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 else
{ {
if (isVertical()) 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) 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); const double maxSpeed = jmax (200, sliderRegionSize);
double speed = jlimit (0.0, maxSpeed, (double) abs (mouseDiff)); double speed = jlimit (0.0, maxSpeed, (double) abs (mouseDiff));
@@ -998,22 +1022,16 @@ public:
: (double) currentValue.getValue()); : (double) currentValue.getValue());
Point<int> mousePos; Point<int> mousePos;
if (style == RotaryHorizontalDrag || style == RotaryVerticalDrag)
if (isRotary())
{ {
mousePos = Desktop::getLastMouseDownPosition(); 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 else
{ {
@@ -1032,7 +1050,7 @@ public:
{ {
if (style != IncDecButtons) if (style != IncDecButtons)
{ {
if (style == Rotary || style == RotaryHorizontalDrag || style == RotaryVerticalDrag)
if (isRotary())
{ {
const float sliderPos = (float) owner.valueToProportionOfLength (lastCurrentValue); const float sliderPos = (float) owner.valueToProportionOfLength (lastCurrentValue);
jassert (sliderPos >= 0 && sliderPos <= 1.0f); jassert (sliderPos >= 0 && sliderPos <= 1.0f);
@@ -1268,21 +1286,6 @@ public:
std::abs (a1 + double_Pi * 2.0 - a2), std::abs (a1 + double_Pi * 2.0 - a2),
std::abs (a2 + double_Pi * 2.0 - a1)); 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(); Slider::lookAndFeelChanged();
updateText(); updateText();
pimpl->init();
pimpl->registerListeners();
} }
Slider::~Slider() {} Slider::~Slider() {}


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

@@ -61,28 +61,30 @@ public:
*/ */
enum SliderStyle 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. /** The position of the slider's text-entry box.


Loading…
Cancel
Save