| @@ -292,9 +292,8 @@ struct SquareLookAndFeel : public CustomLookAndFeel | |||||
| if (width > 0 && height > 0) | if (width > 0 && height > 0) | ||||
| { | { | ||||
| g.setGradientFill (ColourGradient (baseColour, 0.0f, 0.0f, | |||||
| baseColour.darker (0.1f), 0.0f, height, | |||||
| false)); | |||||
| g.setGradientFill (ColourGradient::vertical (baseColour, 0.0f, | |||||
| baseColour.darker (0.1f), height)); | |||||
| g.fillRect (button.getLocalBounds()); | g.fillRect (button.getLocalBounds()); | ||||
| } | } | ||||
| @@ -27,7 +27,7 @@ | |||||
| namespace juce | namespace juce | ||||
| { | { | ||||
| ColourGradient::ColourGradient() noexcept | |||||
| ColourGradient::ColourGradient() noexcept : isRadial (false) | |||||
| { | { | ||||
| #if JUCE_DEBUG | #if JUCE_DEBUG | ||||
| point1.setX (987654.0f); | point1.setX (987654.0f); | ||||
| @@ -37,6 +37,33 @@ ColourGradient::ColourGradient() noexcept | |||||
| #endif | #endif | ||||
| } | } | ||||
| ColourGradient::ColourGradient (const ColourGradient& other) | |||||
| : point1 (other.point1), point2 (other.point2), isRadial (other.isRadial), colours (other.colours) | |||||
| {} | |||||
| ColourGradient::ColourGradient (ColourGradient&& other) noexcept | |||||
| : point1 (other.point1), point2 (other.point2), isRadial (other.isRadial), | |||||
| colours (static_cast<Array<ColourPoint>&&> (other.colours)) | |||||
| {} | |||||
| ColourGradient& ColourGradient::operator= (const ColourGradient& other) | |||||
| { | |||||
| point1 = other.point1; | |||||
| point2 = other.point2; | |||||
| isRadial = other.isRadial; | |||||
| colours = other.colours; | |||||
| return *this; | |||||
| } | |||||
| ColourGradient& ColourGradient::operator= (ColourGradient&& other) noexcept | |||||
| { | |||||
| point1 = other.point1; | |||||
| point2 = other.point2; | |||||
| isRadial = other.isRadial; | |||||
| colours = static_cast<Array<ColourPoint>&&> (other.colours); | |||||
| return *this; | |||||
| } | |||||
| ColourGradient::ColourGradient (Colour colour1, float x1, float y1, | ColourGradient::ColourGradient (Colour colour1, float x1, float y1, | ||||
| Colour colour2, float x2, float y2, bool radial) | Colour colour2, float x2, float y2, bool radial) | ||||
| : ColourGradient (colour1, Point<float> (x1, y1), | : ColourGradient (colour1, Point<float> (x1, y1), | ||||
| @@ -50,12 +77,20 @@ ColourGradient::ColourGradient (Colour colour1, Point<float> p1, | |||||
| point2 (p2), | point2 (p2), | ||||
| isRadial (radial) | isRadial (radial) | ||||
| { | { | ||||
| colours.add (ColourPoint (0.0, colour1)); | |||||
| colours.add (ColourPoint (1.0, colour2)); | |||||
| colours.add ({ 0.0, colour1 }); | |||||
| colours.add ({ 1.0, colour2 }); | |||||
| } | |||||
| ColourGradient::~ColourGradient() {} | |||||
| ColourGradient ColourGradient::vertical (Colour c1, float y1, Colour c2, float y2) | |||||
| { | |||||
| return { c1, 0, y1, c2, 0, y2, false }; | |||||
| } | } | ||||
| ColourGradient::~ColourGradient() | |||||
| ColourGradient ColourGradient::horizontal (Colour c1, float x1, Colour c2, float x2) | |||||
| { | { | ||||
| return { c1, x1, 0, c2, x2, 0, false }; | |||||
| } | } | ||||
| bool ColourGradient::operator== (const ColourGradient& other) const noexcept | bool ColourGradient::operator== (const ColourGradient& other) const noexcept | ||||
| @@ -116,7 +151,7 @@ int ColourGradient::getNumColours() const noexcept | |||||
| return colours.size(); | return colours.size(); | ||||
| } | } | ||||
| double ColourGradient::getColourPosition (const int index) const noexcept | |||||
| double ColourGradient::getColourPosition (int index) const noexcept | |||||
| { | { | ||||
| if (isPositiveAndBelow (index, colours.size())) | if (isPositiveAndBelow (index, colours.size())) | ||||
| return colours.getReference (index).position; | return colours.getReference (index).position; | ||||
| @@ -124,7 +159,7 @@ double ColourGradient::getColourPosition (const int index) const noexcept | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| Colour ColourGradient::getColour (const int index) const noexcept | |||||
| Colour ColourGradient::getColour (int index) const noexcept | |||||
| { | { | ||||
| if (isPositiveAndBelow (index, colours.size())) | if (isPositiveAndBelow (index, colours.size())) | ||||
| return colours.getReference (index).colour; | return colours.getReference (index).colour; | ||||
| @@ -138,7 +173,7 @@ void ColourGradient::setColour (int index, Colour newColour) noexcept | |||||
| colours.getReference (index).colour = newColour; | colours.getReference (index).colour = newColour; | ||||
| } | } | ||||
| Colour ColourGradient::getColourAtPosition (const double position) const noexcept | |||||
| Colour ColourGradient::getColourAtPosition (double position) const noexcept | |||||
| { | { | ||||
| jassert (colours.getReference(0).position == 0.0); // the first colour specified has to go at position 0 | jassert (colours.getReference(0).position == 0.0); // the first colour specified has to go at position 0 | ||||
| @@ -223,12 +258,12 @@ bool ColourGradient::isInvisible() const noexcept | |||||
| return true; | return true; | ||||
| } | } | ||||
| bool ColourGradient::ColourPoint::operator== (const ColourPoint& other) const noexcept | |||||
| bool ColourGradient::ColourPoint::operator== (ColourPoint other) const noexcept | |||||
| { | { | ||||
| return position == other.position && colour == other.colour; | return position == other.position && colour == other.colour; | ||||
| } | } | ||||
| bool ColourGradient::ColourPoint::operator!= (const ColourPoint& other) const noexcept | |||||
| bool ColourGradient::ColourPoint::operator!= (ColourPoint other) const noexcept | |||||
| { | { | ||||
| return position != other.position || colour != other.colour; | return position != other.position || colour != other.colour; | ||||
| } | } | ||||
| @@ -36,6 +36,18 @@ namespace juce | |||||
| class JUCE_API ColourGradient final | class JUCE_API ColourGradient final | ||||
| { | { | ||||
| public: | public: | ||||
| /** Creates an uninitialised gradient. | |||||
| If you use this constructor instead of the other one, be sure to set all the | |||||
| object's public member variables before using it! | |||||
| */ | |||||
| ColourGradient() noexcept; | |||||
| ColourGradient (const ColourGradient&); | |||||
| ColourGradient (ColourGradient&&) noexcept; | |||||
| ColourGradient& operator= (const ColourGradient&); | |||||
| ColourGradient& operator= (ColourGradient&&) noexcept; | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Creates a gradient object. | /** Creates a gradient object. | ||||
| @@ -79,12 +91,13 @@ public: | |||||
| Colour colour2, Point<float> point2, | Colour colour2, Point<float> point2, | ||||
| bool isRadial); | bool isRadial); | ||||
| /** Creates an uninitialised gradient. | |||||
| /** Creates a vertical linear gradient between two Y coordinates */ | |||||
| static ColourGradient vertical (Colour colour1, float y1, | |||||
| Colour colour2, float y2); | |||||
| If you use this constructor instead of the other one, be sure to set all the | |||||
| object's public member variables before using it! | |||||
| */ | |||||
| ColourGradient() noexcept; | |||||
| /** Creates a horizontal linear gradient between two X coordinates */ | |||||
| static ColourGradient horizontal (Colour colour1, float x1, | |||||
| Colour colour2, float x2); | |||||
| /** Destructor */ | /** Destructor */ | ||||
| ~ColourGradient(); | ~ColourGradient(); | ||||
| @@ -182,13 +195,10 @@ private: | |||||
| struct ColourPoint | struct ColourPoint | ||||
| { | { | ||||
| ColourPoint() noexcept {} | ColourPoint() noexcept {} | ||||
| ColourPoint (double pos, Colour col) noexcept : position (pos), colour (col) {} | |||||
| ColourPoint (const double pos, Colour col) noexcept | |||||
| : position (pos), colour (col) | |||||
| {} | |||||
| bool operator== (const ColourPoint&) const noexcept; | |||||
| bool operator!= (const ColourPoint&) const noexcept; | |||||
| bool operator== (ColourPoint) const noexcept; | |||||
| bool operator!= (ColourPoint) const noexcept; | |||||
| double position; | double position; | ||||
| Colour colour; | Colour colour; | ||||
| @@ -42,6 +42,11 @@ FillType::FillType (const ColourGradient& g) | |||||
| { | { | ||||
| } | } | ||||
| FillType::FillType (ColourGradient&& g) | |||||
| : colour (0xff000000), gradient (new ColourGradient (static_cast<ColourGradient&&> (g))) | |||||
| { | |||||
| } | |||||
| FillType::FillType (const Image& im, const AffineTransform& t) noexcept | FillType::FillType (const Image& im, const AffineTransform& t) noexcept | ||||
| : colour (0xff000000), image (im), transform (t) | : colour (0xff000000), image (im), transform (t) | ||||
| { | { | ||||
| @@ -53,6 +53,11 @@ public: | |||||
| */ | */ | ||||
| FillType (const ColourGradient& gradient); | FillType (const ColourGradient& gradient); | ||||
| /** Creates a gradient fill type. | |||||
| @see setGradient | |||||
| */ | |||||
| FillType (ColourGradient&& gradient); | |||||
| /** Creates a tiled image fill type. The transform allows you to set the scaling, offset | /** Creates a tiled image fill type. The transform allows you to set the scaling, offset | ||||
| and rotation of the pattern. | and rotation of the pattern. | ||||
| @see setTiledImage | @see setTiledImage | ||||
| @@ -190,7 +190,7 @@ void Graphics::setColour (Colour newColour) | |||||
| context.setFill (newColour); | context.setFill (newColour); | ||||
| } | } | ||||
| void Graphics::setOpacity (const float newOpacity) | |||||
| void Graphics::setOpacity (float newOpacity) | |||||
| { | { | ||||
| saveStateIfPending(); | saveStateIfPending(); | ||||
| context.setOpacity (newOpacity); | context.setOpacity (newOpacity); | ||||
| @@ -201,6 +201,11 @@ void Graphics::setGradientFill (const ColourGradient& gradient) | |||||
| setFillType (gradient); | setFillType (gradient); | ||||
| } | } | ||||
| void Graphics::setGradientFill (ColourGradient&& gradient) | |||||
| { | |||||
| setFillType (static_cast<ColourGradient&&> (gradient)); | |||||
| } | |||||
| void Graphics::setTiledImageFill (const Image& imageToUse, const int anchorX, const int anchorY, const float opacity) | void Graphics::setTiledImageFill (const Image& imageToUse, const int anchorX, const int anchorY, const float opacity) | ||||
| { | { | ||||
| saveStateIfPending(); | saveStateIfPending(); | ||||
| @@ -82,10 +82,12 @@ public: | |||||
| */ | */ | ||||
| void setOpacity (float newOpacity); | void setOpacity (float newOpacity); | ||||
| /** Sets the context to use a gradient for its fill pattern. | |||||
| */ | |||||
| /** Sets the context to use a gradient for its fill pattern. */ | |||||
| void setGradientFill (const ColourGradient& gradient); | void setGradientFill (const ColourGradient& gradient); | ||||
| /** Sets the context to use a gradient for its fill pattern. */ | |||||
| void setGradientFill (ColourGradient&& gradient); | |||||
| /** Sets the context to use a tiled image pattern for filling. | /** Sets the context to use a tiled image pattern for filling. | ||||
| Make sure that you don't delete this image while it's still being used by | Make sure that you don't delete this image while it's still being used by | ||||
| this context! | this context! | ||||
| @@ -1273,8 +1273,7 @@ void LookAndFeel_V2::drawLinearSliderBackground (Graphics& g, int x, int y, int | |||||
| const float iy = y + height * 0.5f - sliderRadius * 0.5f; | const float iy = y + height * 0.5f - sliderRadius * 0.5f; | ||||
| const float ih = sliderRadius; | const float ih = sliderRadius; | ||||
| g.setGradientFill (ColourGradient (gradCol1, 0.0f, iy, | |||||
| gradCol2, 0.0f, iy + ih, false)); | |||||
| g.setGradientFill (ColourGradient::vertical (gradCol1, iy, gradCol2, iy + ih)); | |||||
| indent.addRoundedRectangle (x - sliderRadius * 0.5f, iy, | indent.addRoundedRectangle (x - sliderRadius * 0.5f, iy, | ||||
| width + sliderRadius, ih, | width + sliderRadius, ih, | ||||
| @@ -1285,8 +1284,7 @@ void LookAndFeel_V2::drawLinearSliderBackground (Graphics& g, int x, int y, int | |||||
| const float ix = x + width * 0.5f - sliderRadius * 0.5f; | const float ix = x + width * 0.5f - sliderRadius * 0.5f; | ||||
| const float iw = sliderRadius; | const float iw = sliderRadius; | ||||
| g.setGradientFill (ColourGradient (gradCol1, ix, 0.0f, | |||||
| gradCol2, ix + iw, 0.0f, false)); | |||||
| g.setGradientFill (ColourGradient::horizontal (gradCol1, ix, gradCol2, ix + iw)); | |||||
| indent.addRoundedRectangle (ix, y - sliderRadius * 0.5f, | indent.addRoundedRectangle (ix, y - sliderRadius * 0.5f, | ||||
| iw, height + sliderRadius, | iw, height + sliderRadius, | ||||
| @@ -1765,10 +1763,8 @@ void LookAndFeel_V2::drawDocumentWindowTitleBar (DocumentWindow& window, Graphic | |||||
| const bool isActive = window.isActiveWindow(); | const bool isActive = window.isActiveWindow(); | ||||
| g.setGradientFill (ColourGradient (window.getBackgroundColour(), | |||||
| 0.0f, 0.0f, | |||||
| window.getBackgroundColour().contrasting (isActive ? 0.15f : 0.05f), | |||||
| 0.0f, (float) h, false)); | |||||
| g.setGradientFill (ColourGradient::vertical (window.getBackgroundColour(), 0, | |||||
| window.getBackgroundColour().contrasting (isActive ? 0.15f : 0.05f), (float) h)); | |||||
| g.fillAll(); | g.fillAll(); | ||||
| Font font (h * 0.65f, Font::bold); | Font font (h * 0.65f, Font::bold); | ||||
| @@ -93,8 +93,8 @@ void LookAndFeel_V3::drawConcertinaPanelHeader (Graphics& g, const Rectangle<int | |||||
| { | { | ||||
| const Colour bkg (Colours::grey); | const Colour bkg (Colours::grey); | ||||
| g.setGradientFill (ColourGradient (Colours::white.withAlpha (isMouseOver ? 0.4f : 0.2f), 0, (float) area.getY(), | |||||
| Colours::darkgrey.withAlpha (0.1f), 0, (float) area.getBottom(), false)); | |||||
| g.setGradientFill (ColourGradient::vertical (Colours::white.withAlpha (isMouseOver ? 0.4f : 0.2f), (float) area.getY(), | |||||
| Colours::darkgrey.withAlpha (0.1f), (float) area.getBottom())); | |||||
| g.fillAll(); | g.fillAll(); | ||||
| g.setColour (bkg.contrasting().withAlpha (0.1f)); | g.setColour (bkg.contrasting().withAlpha (0.1f)); | ||||
| @@ -111,8 +111,8 @@ static void drawButtonShape (Graphics& g, const Path& outline, Colour baseColour | |||||
| const float mainBrightness = baseColour.getBrightness(); | const float mainBrightness = baseColour.getBrightness(); | ||||
| const float mainAlpha = baseColour.getFloatAlpha(); | const float mainAlpha = baseColour.getFloatAlpha(); | ||||
| g.setGradientFill (ColourGradient (baseColour.brighter (0.2f), 0.0f, 0.0f, | |||||
| baseColour.darker (0.25f), 0.0f, height, false)); | |||||
| g.setGradientFill (ColourGradient::vertical (baseColour.brighter (0.2f), 0.0f, | |||||
| baseColour.darker (0.25f), height)); | |||||
| g.fillPath (outline); | g.fillPath (outline); | ||||
| g.setColour (Colours::white.withAlpha (0.4f * mainAlpha * mainBrightness * mainBrightness)); | g.setColour (Colours::white.withAlpha (0.4f * mainAlpha * mainBrightness * mainBrightness)); | ||||
| @@ -213,8 +213,8 @@ void LookAndFeel_V3::drawTabButton (TabBarButton& button, Graphics& g, bool isMo | |||||
| default: jassertfalse; break; | default: jassertfalse; break; | ||||
| } | } | ||||
| g.setGradientFill (ColourGradient (bkg.brighter (0.2f), (float) p1.x, (float) p1.y, | |||||
| bkg.darker (0.1f), (float) p2.x, (float) p2.y, false)); | |||||
| g.setGradientFill (ColourGradient (bkg.brighter (0.2f), p1.toFloat(), | |||||
| bkg.darker (0.1f), p2.toFloat(), false)); | |||||
| } | } | ||||
| g.fillRect (activeArea); | g.fillRect (activeArea); | ||||
| @@ -403,12 +403,12 @@ void LookAndFeel_V3::drawLinearSlider (Graphics& g, int x, int y, int width, int | |||||
| else | else | ||||
| p.addRectangle (fx, fy, sliderPos - fx, fh); | p.addRectangle (fx, fy, sliderPos - fx, fh); | ||||
| Colour baseColour (slider.findColour (Slider::thumbColourId) | |||||
| auto baseColour = slider.findColour (Slider::thumbColourId) | |||||
| .withMultipliedSaturation (slider.isEnabled() ? 1.0f : 0.5f) | .withMultipliedSaturation (slider.isEnabled() ? 1.0f : 0.5f) | ||||
| .withMultipliedAlpha (0.8f)); | |||||
| .withMultipliedAlpha (0.8f); | |||||
| g.setGradientFill (ColourGradient (baseColour.brighter (0.08f), 0.0f, 0.0f, | |||||
| baseColour.darker (0.08f), 0.0f, (float) height, false)); | |||||
| g.setGradientFill (ColourGradient::vertical (baseColour.brighter (0.08f), 0.0f, | |||||
| baseColour.darker (0.08f), (float) height)); | |||||
| g.fillPath (p); | g.fillPath (p); | ||||
| g.setColour (baseColour.darker (0.2f)); | g.setColour (baseColour.darker (0.2f)); | ||||
| @@ -440,19 +440,17 @@ void LookAndFeel_V3::drawLinearSliderBackground (Graphics& g, int x, int y, int | |||||
| if (slider.isHorizontal()) | if (slider.isHorizontal()) | ||||
| { | { | ||||
| const float iy = y + height * 0.5f - sliderRadius * 0.5f; | |||||
| auto iy = y + height * 0.5f - sliderRadius * 0.5f; | |||||
| g.setGradientFill (ColourGradient (gradCol1, 0.0f, iy, | |||||
| gradCol2, 0.0f, iy + sliderRadius, false)); | |||||
| g.setGradientFill (ColourGradient::vertical (gradCol1, iy, gradCol2, iy + sliderRadius)); | |||||
| indent.addRoundedRectangle (x - sliderRadius * 0.5f, iy, width + sliderRadius, sliderRadius, 5.0f); | indent.addRoundedRectangle (x - sliderRadius * 0.5f, iy, width + sliderRadius, sliderRadius, 5.0f); | ||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| const float ix = x + width * 0.5f - sliderRadius * 0.5f; | |||||
| auto ix = x + width * 0.5f - sliderRadius * 0.5f; | |||||
| g.setGradientFill (ColourGradient (gradCol1, ix, 0.0f, | |||||
| gradCol2, ix + sliderRadius, 0.0f, false)); | |||||
| g.setGradientFill (ColourGradient::horizontal (gradCol1, ix, gradCol2, ix + sliderRadius)); | |||||
| indent.addRoundedRectangle (ix, y - sliderRadius * 0.5f, sliderRadius, height + sliderRadius, 5.0f); | indent.addRoundedRectangle (ix, y - sliderRadius * 0.5f, sliderRadius, height + sliderRadius, 5.0f); | ||||
| } | } | ||||
| @@ -477,7 +475,7 @@ void LookAndFeel_V3::drawPopupMenuBackground (Graphics& g, int width, int height | |||||
| void LookAndFeel_V3::drawMenuBarBackground (Graphics& g, int width, int height, | void LookAndFeel_V3::drawMenuBarBackground (Graphics& g, int width, int height, | ||||
| bool, MenuBarComponent& menuBar) | bool, MenuBarComponent& menuBar) | ||||
| { | { | ||||
| const Colour colour (menuBar.findColour (PopupMenu::backgroundColourId)); | |||||
| auto colour = menuBar.findColour (PopupMenu::backgroundColourId); | |||||
| Rectangle<int> r (width, height); | Rectangle<int> r (width, height); | ||||
| @@ -485,7 +483,7 @@ void LookAndFeel_V3::drawMenuBarBackground (Graphics& g, int width, int height, | |||||
| g.fillRect (r.removeFromTop (1)); | g.fillRect (r.removeFromTop (1)); | ||||
| g.fillRect (r.removeFromBottom (1)); | g.fillRect (r.removeFromBottom (1)); | ||||
| g.setGradientFill (ColourGradient (colour, 0, 0, colour.darker (0.08f), 0, (float) height, false)); | |||||
| g.setGradientFill (ColourGradient::vertical (colour, 0, colour.darker (0.08f), (float) height)); | |||||
| g.fillRect (r); | g.fillRect (r); | ||||
| } | } | ||||
| @@ -872,7 +872,7 @@ void LookAndFeel_V4::drawMenuBarBackground (Graphics& g, int width, int height, | |||||
| g.fillRect (r.removeFromTop (1)); | g.fillRect (r.removeFromTop (1)); | ||||
| g.fillRect (r.removeFromBottom (1)); | g.fillRect (r.removeFromBottom (1)); | ||||
| g.setGradientFill (ColourGradient (colour, 0, 0, colour.darker (0.2f), 0, (float) height, false)); | |||||
| g.setGradientFill (ColourGradient::vertical (colour, 0, colour.darker (0.2f), (float) height)); | |||||
| g.fillRect (r); | g.fillRect (r); | ||||
| } | } | ||||
| @@ -1132,8 +1132,8 @@ void LookAndFeel_V4::drawConcertinaPanelHeader (Graphics& g, const Rectangle<int | |||||
| const auto bkg = Colours::grey; | const auto bkg = Colours::grey; | ||||
| g.setGradientFill (ColourGradient (Colours::white.withAlpha (isMouseOver ? 0.4f : 0.2f), 0, (float) area.getY(), | |||||
| Colours::darkgrey.withAlpha (0.1f), 0, (float) area.getBottom(), false)); | |||||
| g.setGradientFill (ColourGradient::vertical (Colours::white.withAlpha (isMouseOver ? 0.4f : 0.2f), (float) area.getY(), | |||||
| Colours::darkgrey.withAlpha (0.1f), (float) area.getBottom())); | |||||
| g.fillPath (p); | g.fillPath (p); | ||||
| } | } | ||||