Browse Source

Added SliderLayout to LookAndFeel to allow flexible slider/textbox positioning. Refactored Slider to separate this functionality.

tags/2021-05-28
Timur Doumler 10 years ago
parent
commit
b68b4670b9
4 changed files with 106 additions and 81 deletions
  1. +65
    -0
      modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.cpp
  2. +1
    -0
      modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.h
  3. +26
    -81
      modules/juce_gui_basics/widgets/juce_Slider.cpp
  4. +14
    -0
      modules/juce_gui_basics/widgets/juce_Slider.h

+ 65
- 0
modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.cpp View File

@@ -1492,6 +1492,71 @@ int LookAndFeel_V2::getSliderPopupPlacement (Slider&)
| BubbleComponent::right;
}
//==============================================================================
Slider::SliderLayout LookAndFeel_V2::getSliderLayout (Slider& slider)
{
// 1. compute the actually visible textBox size from the slider textBox size and some additional constraints
int minXSpace = 0;
int minYSpace = 0;
Slider::TextEntryBoxPosition textBoxPos = slider.getTextBoxPosition();
if (textBoxPos == Slider::TextBoxLeft || textBoxPos == Slider::TextBoxRight)
minXSpace = 30;
else
minYSpace = 15;
Rectangle<int> localBounds = slider.getLocalBounds();
const int textBoxWidth = jmax (0, jmin (slider.getTextBoxWidth(), localBounds.getWidth() - minXSpace));
const int textBoxHeight = jmax (0, jmin (slider.getTextBoxHeight(), localBounds.getHeight() - minYSpace));
Slider::SliderStyle style = slider.getSliderStyle();
Slider::SliderLayout layout;
// 2. set the textBox bounds
if (textBoxPos != Slider::NoTextBox)
{
if (style == Slider::LinearBar || style == Slider::LinearBarVertical)
{
layout.textBoxBounds = localBounds;
}
else
{
layout.textBoxBounds.setWidth (textBoxWidth);
layout.textBoxBounds.setHeight (textBoxHeight);
if (textBoxPos == Slider::TextBoxLeft) layout.textBoxBounds.setX (0);
else if (textBoxPos == Slider::TextBoxRight) layout.textBoxBounds.setX (localBounds.getWidth() - textBoxWidth);
else /* above or below -> centre horizontally */ layout.textBoxBounds.setX ((localBounds.getWidth() - textBoxWidth) / 2);
if (textBoxPos == Slider::TextBoxAbove) layout.textBoxBounds.setY (0);
else if (textBoxPos == Slider::TextBoxBelow) layout.textBoxBounds.setY (localBounds.getHeight() - textBoxHeight);
else /* left or right -> centre vertically */ layout.textBoxBounds.setY ((localBounds.getHeight() - textBoxHeight) / 2);
}
}
// 3. set the slider bounds
layout.sliderBounds = localBounds;
if (! slider.isBar())
{
if (textBoxPos == Slider::TextBoxLeft) layout.sliderBounds.removeFromLeft (textBoxWidth);
else if (textBoxPos == Slider::TextBoxRight) layout.sliderBounds.removeFromRight (textBoxWidth);
else if (textBoxPos == Slider::TextBoxAbove) layout.sliderBounds.removeFromTop (textBoxHeight);
else if (textBoxPos == Slider::TextBoxBelow) layout.sliderBounds.removeFromBottom (textBoxHeight);
}
if (slider.isBar()) layout.sliderBounds.reduce (1, 1); // bar indent
else if (slider.isHorizontal()) layout.sliderBounds.reduce (getSliderThumbRadius (slider), 0);
else if (slider.isVertical()) layout.sliderBounds.reduce (0, getSliderThumbRadius (slider));
return layout;
}
//==============================================================================
Rectangle<int> LookAndFeel_V2::getTooltipBounds (const String& tipText, Point<int> screenPos, Rectangle<int> parentArea)
{


+ 1
- 0
modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.h View File

@@ -193,6 +193,7 @@ public:
ImageEffectFilter* getSliderEffect (Slider&) override;
Font getSliderPopupFont (Slider&) override;
int getSliderPopupPlacement (Slider&) override;
Slider::SliderLayout getSliderLayout (Slider&) override;
//==============================================================================
Rectangle<int> getTooltipBounds (const String& tipText, Point<int> screenPos, Rectangle<int> parentArea) override;


+ 26
- 81
modules/juce_gui_basics/widgets/juce_Slider.cpp View File

@@ -99,6 +99,12 @@ public:
|| style == RotaryHorizontalVerticalDrag;
}
bool isBar() const noexcept
{
return style == LinearBar
|| style == LinearBarVertical;
}
bool incDecDragDirectionIsHorizontal() const noexcept
{
return incDecButtonMode == incDecButtonsDraggable_Horizontal
@@ -740,7 +746,7 @@ public:
void handleAbsoluteDrag (const MouseEvent& e)
{
const float mousePos = (isHorizontal() || style == RotaryHorizontalDrag) ? e.position.x : e.position.y;
double newPos = (mousePos - sliderRegionStart) / (double) sliderRegionSize;
double newPos = 0;
if (style == RotaryHorizontalDrag
|| style == RotaryVerticalDrag
@@ -774,6 +780,8 @@ public:
}
else
{
newPos = (mousePos - sliderRegionStart) / (double) sliderRegionSize;
if (isVertical())
newPos = 1.0 - newPos;
}
@@ -1120,98 +1128,34 @@ public:
}
}
void resized (const Rectangle<int>& localBounds, LookAndFeel& lf)
//==============================================================================
void resized (LookAndFeel& lf)
{
int minXSpace = 0;
int minYSpace = 0;
SliderLayout layout = lf.getSliderLayout (owner);
if (textBoxPos == TextBoxLeft || textBoxPos == TextBoxRight)
minXSpace = 30;
else
minYSpace = 15;
const int tbw = jmax (0, jmin (textBoxWidth, localBounds.getWidth() - minXSpace));
const int tbh = jmax (0, jmin (textBoxHeight, localBounds.getHeight() - minYSpace));
sliderRect = layout.sliderBounds;
if (style == LinearBar || style == LinearBarVertical)
{
if (valueBox != nullptr)
valueBox->setBounds (localBounds);
}
else
{
if (textBoxPos == NoTextBox)
{
sliderRect = localBounds;
}
else if (textBoxPos == TextBoxLeft)
{
valueBox->setBounds (0, (localBounds.getHeight() - tbh) / 2, tbw, tbh);
sliderRect.setBounds (tbw, 0, localBounds.getWidth() - tbw, localBounds.getHeight());
}
else if (textBoxPos == TextBoxRight)
{
valueBox->setBounds (localBounds.getWidth() - tbw, (localBounds.getHeight() - tbh) / 2, tbw, tbh);
sliderRect.setBounds (0, 0, localBounds.getWidth() - tbw, localBounds.getHeight());
}
else if (textBoxPos == TextBoxAbove)
{
valueBox->setBounds ((localBounds.getWidth() - tbw) / 2, 0, tbw, tbh);
sliderRect.setBounds (0, tbh, localBounds.getWidth(), localBounds.getHeight() - tbh);
}
else if (textBoxPos == TextBoxBelow)
{
valueBox->setBounds ((localBounds.getWidth() - tbw) / 2, localBounds.getHeight() - tbh, tbw, tbh);
sliderRect.setBounds (0, 0, localBounds.getWidth(), localBounds.getHeight() - tbh);
}
}
const int indent = lf.getSliderThumbRadius (owner);
if (style == LinearBar)
{
const int barIndent = 1;
sliderRegionStart = barIndent;
sliderRegionSize = localBounds.getWidth() - barIndent * 2;
sliderRect.setBounds (sliderRegionStart, barIndent,
sliderRegionSize, localBounds.getHeight() - barIndent * 2);
}
else if (style == LinearBarVertical)
{
const int barIndent = 1;
sliderRegionStart = barIndent;
sliderRegionSize = localBounds.getHeight() - barIndent * 2;
if (valueBox != nullptr)
valueBox->setBounds (layout.textBoxBounds);
sliderRect.setBounds (barIndent, sliderRegionStart,
localBounds.getWidth() - barIndent * 2, sliderRegionSize);
}
else if (isHorizontal())
if (isHorizontal())
{
sliderRegionStart = sliderRect.getX() + indent;
sliderRegionSize = jmax (1, sliderRect.getWidth() - indent * 2);
sliderRect.setBounds (sliderRegionStart, sliderRect.getY(),
sliderRegionSize, sliderRect.getHeight());
sliderRegionStart = layout.sliderBounds.getX();
sliderRegionSize = layout.sliderBounds.getWidth();
}
else if (isVertical())
{
sliderRegionStart = sliderRect.getY() + indent;
sliderRegionSize = jmax (1, sliderRect.getHeight() - indent * 2);
sliderRect.setBounds (sliderRect.getX(), sliderRegionStart,
sliderRect.getWidth(), sliderRegionSize);
sliderRegionStart = layout.sliderBounds.getY();
sliderRegionSize = layout.sliderBounds.getHeight();
}
else
else if (style == IncDecButtons)
{
sliderRegionStart = 0;
sliderRegionSize = 100;
}
if (style == IncDecButtons)
resizeIncDecButtons();
}
}
//==============================================================================
void resizeIncDecButtons()
{
Rectangle<int> buttonRect (sliderRect);
@@ -1582,12 +1526,13 @@ void Slider::setScrollWheelEnabled (const bool enabled) { pimpl->scrollWheel
bool Slider::isHorizontal() const noexcept { return pimpl->isHorizontal(); }
bool Slider::isVertical() const noexcept { return pimpl->isVertical(); }
bool Slider::isRotary() const noexcept { return pimpl->isRotary(); }
bool Slider::isBar() const noexcept { return pimpl->isBar(); }
float Slider::getPositionOfValue (const double value) { return pimpl->getPositionOfValue (value); }
//==============================================================================
void Slider::paint (Graphics& g) { pimpl->paint (g, getLookAndFeel()); }
void Slider::resized() { pimpl->resized (getLocalBounds(), getLookAndFeel()); }
void Slider::resized() { pimpl->resized (getLookAndFeel()); }
void Slider::focusOfChildComponentChanged (FocusChangeType) { repaint(); }


+ 14
- 0
modules/juce_gui_basics/widgets/juce_Slider.h View File

@@ -756,6 +756,8 @@ public:
bool isVertical() const noexcept;
/** True if the slider is in a rotary mode. */
bool isRotary() const noexcept;
/** True if the slider is in a linear bar mode. */
bool isBar() const noexcept;
//==============================================================================
/** A set of colour IDs to use to change the colour of various aspects of the slider.
@@ -780,6 +782,16 @@ public:
textBoxOutlineColourId = 0x1001700 /**< The colour to use for a border around the text-editor box. */
};
//==============================================================================
/** A struct defining the placement of the slider area and the text box area
relative to the bounds of the whole Slider component.
*/
struct SliderLayout
{
Rectangle<int> sliderBounds;
Rectangle<int> textBoxBounds;
};
//==============================================================================
/** This abstract base class is implemented by LookAndFeel classes to provide
slider drawing functionality.
@@ -830,6 +842,8 @@ public:
virtual Font getSliderPopupFont (Slider&) = 0;
virtual int getSliderPopupPlacement (Slider&) = 0;
virtual SliderLayout getSliderLayout (Slider&) = 0;
#if JUCE_CATCH_DEPRECATED_CODE_MISUSE
// These methods' parameters have changed: see the new method signatures.
virtual void createSliderButton (bool) {}


Loading…
Cancel
Save