upgrade to JUCE 5.4.3. Remove (probably) unused JUCE modules. Remove VST2 target (it's been end-of-life'd by Steinberg and by JUCE)
This commit is contained in:
		@ -107,7 +107,7 @@ public:
 | 
			
		||||
        JUCE code in there - put your startup/shutdown code in initialise() and
 | 
			
		||||
        shutdown() instead.
 | 
			
		||||
    */
 | 
			
		||||
    ~JUCEApplication();
 | 
			
		||||
    ~JUCEApplication() override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Returns the global instance of the application object being run. */
 | 
			
		||||
 | 
			
		||||
@ -36,14 +36,14 @@ ArrowButton::ArrowButton (const String& name, float arrowDirectionInRadians, Col
 | 
			
		||||
 | 
			
		||||
ArrowButton::~ArrowButton() {}
 | 
			
		||||
 | 
			
		||||
void ArrowButton::paintButton (Graphics& g, bool /*isMouseOverButton*/, bool isButtonDown)
 | 
			
		||||
void ArrowButton::paintButton (Graphics& g, bool /*shouldDrawButtonAsHighlighted*/, bool shouldDrawButtonAsDown)
 | 
			
		||||
{
 | 
			
		||||
    Path p (path);
 | 
			
		||||
 | 
			
		||||
    const float offset = isButtonDown ? 1.0f : 0.0f;
 | 
			
		||||
    const float offset = shouldDrawButtonAsDown ? 1.0f : 0.0f;
 | 
			
		||||
    p.applyTransform (path.getTransformToScaleToFit (offset, offset, getWidth() - 3.0f, getHeight() - 3.0f, false));
 | 
			
		||||
 | 
			
		||||
    DropShadow (Colours::black.withAlpha (0.3f), isButtonDown ? 2 : 4, Point<int>()).drawForPath (g, p);
 | 
			
		||||
    DropShadow (Colours::black.withAlpha (0.3f), shouldDrawButtonAsDown ? 2 : 4, Point<int>()).drawForPath (g, p);
 | 
			
		||||
 | 
			
		||||
    g.setColour (colour);
 | 
			
		||||
    g.fillPath (p);
 | 
			
		||||
 | 
			
		||||
@ -51,10 +51,10 @@ public:
 | 
			
		||||
                 Colour arrowColour);
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~ArrowButton();
 | 
			
		||||
    ~ArrowButton() override;
 | 
			
		||||
 | 
			
		||||
    /** @internal */
 | 
			
		||||
    void paintButton (Graphics&, bool isMouseOverButton, bool isButtonDown) override;
 | 
			
		||||
    void paintButton (Graphics&, bool, bool) override;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    Colour colour;
 | 
			
		||||
 | 
			
		||||
@ -54,7 +54,7 @@ protected:
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    virtual ~Button();
 | 
			
		||||
    ~Button() override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Changes the button's text.
 | 
			
		||||
@ -166,7 +166,7 @@ public:
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
        /** Destructor. */
 | 
			
		||||
        virtual ~Listener()  {}
 | 
			
		||||
        virtual ~Listener() = default;
 | 
			
		||||
 | 
			
		||||
        /** Called when the button is clicked. */
 | 
			
		||||
        virtual void buttonClicked (Button*) = 0;
 | 
			
		||||
@ -367,26 +367,30 @@ public:
 | 
			
		||||
    */
 | 
			
		||||
    struct JUCE_API  LookAndFeelMethods
 | 
			
		||||
    {
 | 
			
		||||
        virtual ~LookAndFeelMethods() {}
 | 
			
		||||
        virtual ~LookAndFeelMethods() = default;
 | 
			
		||||
 | 
			
		||||
        virtual void drawButtonBackground (Graphics&, Button&, const Colour& backgroundColour,
 | 
			
		||||
                                           bool isMouseOverButton, bool isButtonDown) = 0;
 | 
			
		||||
                                           bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown) = 0;
 | 
			
		||||
 | 
			
		||||
        virtual Font getTextButtonFont (TextButton&, int buttonHeight) = 0;
 | 
			
		||||
        virtual int getTextButtonWidthToFitText (TextButton&, int buttonHeight) = 0;
 | 
			
		||||
 | 
			
		||||
        /** Draws the text for a TextButton. */
 | 
			
		||||
        virtual void drawButtonText (Graphics&, TextButton&, bool isMouseOverButton, bool isButtonDown) = 0;
 | 
			
		||||
        virtual void drawButtonText (Graphics&, TextButton&,
 | 
			
		||||
                                     bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown) = 0;
 | 
			
		||||
 | 
			
		||||
        /** Draws the contents of a standard ToggleButton. */
 | 
			
		||||
        virtual void drawToggleButton (Graphics&, ToggleButton&, bool isMouseOverButton, bool isButtonDown) = 0;
 | 
			
		||||
        virtual void drawToggleButton (Graphics&, ToggleButton&,
 | 
			
		||||
                                       bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown) = 0;
 | 
			
		||||
 | 
			
		||||
        virtual void changeToggleButtonWidthToFitText (ToggleButton&) = 0;
 | 
			
		||||
 | 
			
		||||
        virtual void drawTickBox (Graphics&, Component&, float x, float y, float w, float h,
 | 
			
		||||
                                  bool ticked, bool isEnabled, bool isMouseOverButton, bool isButtonDown) = 0;
 | 
			
		||||
                                  bool ticked, bool isEnabled,
 | 
			
		||||
                                  bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown) = 0;
 | 
			
		||||
 | 
			
		||||
        virtual void drawDrawableButton (Graphics&, DrawableButton&, bool isMouseOverButton, bool isButtonDown) = 0;
 | 
			
		||||
        virtual void drawDrawableButton (Graphics&, DrawableButton&,
 | 
			
		||||
                                         bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown) = 0;
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
       #if JUCE_CATCH_DEPRECATED_CODE_MISUSE
 | 
			
		||||
@ -424,14 +428,13 @@ protected:
 | 
			
		||||
        It's better to use this than the paint method, because it gives you information
 | 
			
		||||
        about the over/down state of the button.
 | 
			
		||||
 | 
			
		||||
        @param g                    the graphics context to use
 | 
			
		||||
        @param isMouseOverButton    true if the button is either in the 'over' or
 | 
			
		||||
                                    'down' state
 | 
			
		||||
        @param isButtonDown         true if the button should be drawn in the 'down' position
 | 
			
		||||
        @param g                                the graphics context to use
 | 
			
		||||
        @param shouldDrawButtonAsHighlighted    true if the button is either in the 'over' or 'down' state
 | 
			
		||||
        @param shouldDrawButtonAsDown           true if the button should be drawn in the 'down' position
 | 
			
		||||
    */
 | 
			
		||||
    virtual void paintButton (Graphics& g,
 | 
			
		||||
                              bool isMouseOverButton,
 | 
			
		||||
                              bool isButtonDown) = 0;
 | 
			
		||||
                              bool shouldDrawButtonAsHighlighted,
 | 
			
		||||
                              bool shouldDrawButtonAsDown) = 0;
 | 
			
		||||
 | 
			
		||||
    /** Called when the button's up/down/over state changes.
 | 
			
		||||
 | 
			
		||||
@ -482,8 +485,6 @@ private:
 | 
			
		||||
    ListenerList<Listener> buttonListeners;
 | 
			
		||||
 | 
			
		||||
    struct CallbackHelper;
 | 
			
		||||
    friend struct CallbackHelper;
 | 
			
		||||
    friend struct ContainerDeletePolicy<CallbackHelper>;
 | 
			
		||||
    std::unique_ptr<CallbackHelper> callbackHelper;
 | 
			
		||||
    uint32 buttonPressTime = 0, lastRepeatTime = 0;
 | 
			
		||||
    ApplicationCommandManager* commandManagerToUse = nullptr;
 | 
			
		||||
 | 
			
		||||
@ -176,8 +176,8 @@ void DrawableButton::colourChanged()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void DrawableButton::paintButton (Graphics& g,
 | 
			
		||||
                                  const bool isMouseOverButton,
 | 
			
		||||
                                  const bool isButtonDown)
 | 
			
		||||
                                  const bool shouldDrawButtonAsHighlighted,
 | 
			
		||||
                                  const bool shouldDrawButtonAsDown)
 | 
			
		||||
{
 | 
			
		||||
    auto& lf = getLookAndFeel();
 | 
			
		||||
 | 
			
		||||
@ -185,9 +185,9 @@ void DrawableButton::paintButton (Graphics& g,
 | 
			
		||||
        lf.drawButtonBackground (g, *this,
 | 
			
		||||
                                 findColour (getToggleState() ? TextButton::buttonOnColourId
 | 
			
		||||
                                                              : TextButton::buttonColourId),
 | 
			
		||||
                                 isMouseOverButton, isButtonDown);
 | 
			
		||||
                                 shouldDrawButtonAsHighlighted, shouldDrawButtonAsDown);
 | 
			
		||||
    else
 | 
			
		||||
        lf.drawDrawableButton (g, *this, isMouseOverButton, isButtonDown);
 | 
			
		||||
        lf.drawDrawableButton (g, *this, shouldDrawButtonAsHighlighted, shouldDrawButtonAsDown);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
 | 
			
		||||
@ -68,7 +68,7 @@ public:
 | 
			
		||||
                    ButtonStyle buttonStyle);
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~DrawableButton();
 | 
			
		||||
    ~DrawableButton() override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Sets up the images to draw for the various button states.
 | 
			
		||||
@ -169,7 +169,7 @@ public:
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** @internal */
 | 
			
		||||
    void paintButton (Graphics&, bool isMouseOverButton, bool isButtonDown) override;
 | 
			
		||||
    void paintButton (Graphics&, bool, bool) override;
 | 
			
		||||
    /** @internal */
 | 
			
		||||
    void buttonStateChanged() override;
 | 
			
		||||
    /** @internal */
 | 
			
		||||
 | 
			
		||||
@ -104,13 +104,13 @@ void HyperlinkButton::clicked()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void HyperlinkButton::paintButton (Graphics& g,
 | 
			
		||||
                                   bool isMouseOverButton,
 | 
			
		||||
                                   bool isButtonDown)
 | 
			
		||||
                                   bool shouldDrawButtonAsHighlighted,
 | 
			
		||||
                                   bool shouldDrawButtonAsDown)
 | 
			
		||||
{
 | 
			
		||||
    const Colour textColour (findColour (textColourId));
 | 
			
		||||
 | 
			
		||||
    if (isEnabled())
 | 
			
		||||
        g.setColour ((isMouseOverButton) ? textColour.darker ((isButtonDown) ? 1.3f : 0.4f)
 | 
			
		||||
        g.setColour ((shouldDrawButtonAsHighlighted) ? textColour.darker ((shouldDrawButtonAsDown) ? 1.3f : 0.4f)
 | 
			
		||||
                                         : textColour);
 | 
			
		||||
    else
 | 
			
		||||
        g.setColour (textColour.withMultipliedAlpha (0.4f));
 | 
			
		||||
 | 
			
		||||
@ -44,7 +44,7 @@ public:
 | 
			
		||||
 | 
			
		||||
        @param linkText     the text that will be displayed in the button - this is
 | 
			
		||||
                            also set as the Component's name, but the text can be
 | 
			
		||||
                            changed later with the Button::getButtonText() method
 | 
			
		||||
                            changed later with the Button::setButtonText() method
 | 
			
		||||
        @param linkURL      the URL to launch when the user clicks the button
 | 
			
		||||
    */
 | 
			
		||||
    HyperlinkButton (const String& linkText,
 | 
			
		||||
@ -54,7 +54,7 @@ public:
 | 
			
		||||
    HyperlinkButton();
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~HyperlinkButton();
 | 
			
		||||
    ~HyperlinkButton() override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Changes the font to use for the text.
 | 
			
		||||
@ -109,7 +109,7 @@ protected:
 | 
			
		||||
    /** @internal */
 | 
			
		||||
    void colourChanged() override;
 | 
			
		||||
    /** @internal */
 | 
			
		||||
    void paintButton (Graphics&, bool isMouseOver, bool isButtonDown) override;
 | 
			
		||||
    void paintButton (Graphics&, bool, bool) override;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
 | 
			
		||||
@ -109,13 +109,13 @@ Image ImageButton::getDownImage() const
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ImageButton::paintButton (Graphics& g,
 | 
			
		||||
                               bool isMouseOverButton,
 | 
			
		||||
                               bool isButtonDown)
 | 
			
		||||
                               bool shouldDrawButtonAsHighlighted,
 | 
			
		||||
                               bool shouldDrawButtonAsDown)
 | 
			
		||||
{
 | 
			
		||||
    if (! isEnabled())
 | 
			
		||||
    {
 | 
			
		||||
        isMouseOverButton = false;
 | 
			
		||||
        isButtonDown = false;
 | 
			
		||||
        shouldDrawButtonAsHighlighted = false;
 | 
			
		||||
        shouldDrawButtonAsDown = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Image im (getCurrentImage());
 | 
			
		||||
@ -168,14 +168,14 @@ void ImageButton::paintButton (Graphics& g,
 | 
			
		||||
 | 
			
		||||
        imageBounds.setBounds (x, y, w, h);
 | 
			
		||||
 | 
			
		||||
        const bool useDownImage = isButtonDown || getToggleState();
 | 
			
		||||
        const bool useDownImage = shouldDrawButtonAsDown || getToggleState();
 | 
			
		||||
 | 
			
		||||
        getLookAndFeel().drawImageButton (g, &im, x, y, w, h,
 | 
			
		||||
                                          useDownImage ? downOverlay
 | 
			
		||||
                                                       : (isMouseOverButton ? overOverlay
 | 
			
		||||
                                                       : (shouldDrawButtonAsHighlighted ? overOverlay
 | 
			
		||||
                                                                            : normalOverlay),
 | 
			
		||||
                                          useDownImage ? downOpacity
 | 
			
		||||
                                                       : (isMouseOverButton ? overOpacity
 | 
			
		||||
                                                       : (shouldDrawButtonAsHighlighted ? overOpacity
 | 
			
		||||
                                                                            : normalOpacity),
 | 
			
		||||
                                          *this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -52,7 +52,7 @@ public:
 | 
			
		||||
    explicit ImageButton (const String& name = String());
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~ImageButton();
 | 
			
		||||
    ~ImageButton() override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Sets up the images to draw in various states.
 | 
			
		||||
@ -131,7 +131,7 @@ public:
 | 
			
		||||
    /** This abstract base class is implemented by LookAndFeel classes. */
 | 
			
		||||
    struct JUCE_API  LookAndFeelMethods
 | 
			
		||||
    {
 | 
			
		||||
        virtual ~LookAndFeelMethods() {}
 | 
			
		||||
        virtual ~LookAndFeelMethods() = default;
 | 
			
		||||
 | 
			
		||||
        virtual void drawImageButton (Graphics&, Image*,
 | 
			
		||||
                                      int imageX, int imageY, int imageW, int imageH,
 | 
			
		||||
@ -143,7 +143,7 @@ protected:
 | 
			
		||||
    /** @internal */
 | 
			
		||||
    bool hitTest (int x, int y) override;
 | 
			
		||||
    /** @internal */
 | 
			
		||||
    void paintButton (Graphics&, bool isMouseOver, bool isButtonDown) override;
 | 
			
		||||
    void paintButton (Graphics&, bool, bool) override;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
 | 
			
		||||
@ -82,7 +82,7 @@ void ShapeButton::setShape (const Path& newShape,
 | 
			
		||||
 | 
			
		||||
    if (resizeNowToFitThisShape)
 | 
			
		||||
    {
 | 
			
		||||
        Rectangle<float> newBounds (shape.getBounds());
 | 
			
		||||
        auto newBounds = shape.getBounds();
 | 
			
		||||
 | 
			
		||||
        if (hasShadow)
 | 
			
		||||
            newBounds = newBounds.expanded (4.0f);
 | 
			
		||||
@ -97,20 +97,22 @@ void ShapeButton::setShape (const Path& newShape,
 | 
			
		||||
    repaint();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ShapeButton::paintButton (Graphics& g, bool isMouseOverButton, bool isButtonDown)
 | 
			
		||||
void ShapeButton::paintButton (Graphics& g, bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown)
 | 
			
		||||
{
 | 
			
		||||
    if (! isEnabled())
 | 
			
		||||
    {
 | 
			
		||||
        isMouseOverButton = false;
 | 
			
		||||
        isButtonDown = false;
 | 
			
		||||
        shouldDrawButtonAsHighlighted = false;
 | 
			
		||||
        shouldDrawButtonAsDown = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Rectangle<float> r (border.subtractedFrom (getLocalBounds()).toFloat().reduced (outlineWidth * 0.5f));
 | 
			
		||||
    auto r = border.subtractedFrom (getLocalBounds())
 | 
			
		||||
                   .toFloat()
 | 
			
		||||
                   .reduced (outlineWidth * 0.5f);
 | 
			
		||||
 | 
			
		||||
    if (getComponentEffect() != nullptr)
 | 
			
		||||
        r = r.reduced (2.0f);
 | 
			
		||||
 | 
			
		||||
    if (isButtonDown)
 | 
			
		||||
    if (shouldDrawButtonAsDown)
 | 
			
		||||
    {
 | 
			
		||||
        const float sizeReductionWhenPressed = 0.04f;
 | 
			
		||||
 | 
			
		||||
@ -118,11 +120,11 @@ void ShapeButton::paintButton (Graphics& g, bool isMouseOverButton, bool isButto
 | 
			
		||||
                       sizeReductionWhenPressed * r.getHeight());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const AffineTransform trans (shape.getTransformToScaleToFit (r, maintainShapeProportions));
 | 
			
		||||
    auto trans = shape.getTransformToScaleToFit (r, maintainShapeProportions);
 | 
			
		||||
 | 
			
		||||
    if      (isButtonDown)      g.setColour (getToggleState() && useOnColours ? downColourOn   : downColour);
 | 
			
		||||
    else if (isMouseOverButton) g.setColour (getToggleState() && useOnColours ? overColourOn   : overColour);
 | 
			
		||||
    else                        g.setColour (getToggleState() && useOnColours ? normalColourOn : normalColour);
 | 
			
		||||
    if      (shouldDrawButtonAsDown)        g.setColour (getToggleState() && useOnColours ? downColourOn   : downColour);
 | 
			
		||||
    else if (shouldDrawButtonAsHighlighted) g.setColour (getToggleState() && useOnColours ? overColourOn   : overColour);
 | 
			
		||||
    else                                    g.setColour (getToggleState() && useOnColours ? normalColourOn : normalColour);
 | 
			
		||||
 | 
			
		||||
    g.fillPath (shape, trans);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -52,7 +52,7 @@ public:
 | 
			
		||||
                 Colour downColour);
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~ShapeButton();
 | 
			
		||||
    ~ShapeButton() override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Sets the shape to use.
 | 
			
		||||
@ -108,7 +108,7 @@ public:
 | 
			
		||||
    void setBorderSize (BorderSize<int> border);
 | 
			
		||||
 | 
			
		||||
    /** @internal */
 | 
			
		||||
    void paintButton (Graphics&, bool isMouseOverButton, bool isButtonDown) override;
 | 
			
		||||
    void paintButton (Graphics&, bool, bool) override;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
 | 
			
		||||
@ -44,15 +44,15 @@ TextButton::~TextButton()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TextButton::paintButton (Graphics& g, bool isMouseOverButton, bool isButtonDown)
 | 
			
		||||
void TextButton::paintButton (Graphics& g, bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown)
 | 
			
		||||
{
 | 
			
		||||
    LookAndFeel& lf = getLookAndFeel();
 | 
			
		||||
    auto& lf = getLookAndFeel();
 | 
			
		||||
 | 
			
		||||
    lf.drawButtonBackground (g, *this,
 | 
			
		||||
                             findColour (getToggleState() ? buttonOnColourId : buttonColourId),
 | 
			
		||||
                             isMouseOverButton, isButtonDown);
 | 
			
		||||
                             shouldDrawButtonAsHighlighted, shouldDrawButtonAsDown);
 | 
			
		||||
 | 
			
		||||
    lf.drawButtonText (g, *this, isMouseOverButton, isButtonDown);
 | 
			
		||||
    lf.drawButtonText (g, *this, shouldDrawButtonAsHighlighted, shouldDrawButtonAsDown);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TextButton::colourChanged()
 | 
			
		||||
 | 
			
		||||
@ -59,7 +59,7 @@ public:
 | 
			
		||||
    TextButton (const String& buttonName, const String& toolTip);
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~TextButton();
 | 
			
		||||
    ~TextButton() override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** A set of colour IDs to use to change the colour of various aspects of the button.
 | 
			
		||||
@ -99,7 +99,7 @@ public:
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** @internal */
 | 
			
		||||
    void paintButton (Graphics&, bool isMouseOverButton, bool isButtonDown) override;
 | 
			
		||||
    void paintButton (Graphics&, bool, bool) override;
 | 
			
		||||
    /** @internal */
 | 
			
		||||
    void colourChanged() override;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -43,9 +43,9 @@ ToggleButton::~ToggleButton()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ToggleButton::paintButton (Graphics& g, bool isMouseOverButton, bool isButtonDown)
 | 
			
		||||
void ToggleButton::paintButton (Graphics& g, bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown)
 | 
			
		||||
{
 | 
			
		||||
    getLookAndFeel().drawToggleButton (g, *this, isMouseOverButton, isButtonDown);
 | 
			
		||||
    getLookAndFeel().drawToggleButton (g, *this, shouldDrawButtonAsHighlighted, shouldDrawButtonAsDown);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ToggleButton::changeWidthToFitText()
 | 
			
		||||
 | 
			
		||||
@ -54,7 +54,7 @@ public:
 | 
			
		||||
    explicit ToggleButton (const String& buttonText);
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~ToggleButton();
 | 
			
		||||
    ~ToggleButton() override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Resizes the button to fit neatly around its current text.
 | 
			
		||||
@ -74,13 +74,13 @@ public:
 | 
			
		||||
    {
 | 
			
		||||
        textColourId            = 0x1006501,  /**< The colour to use for the button's text. */
 | 
			
		||||
        tickColourId            = 0x1006502,  /**< The colour to use for the tick mark. */
 | 
			
		||||
        tickDisabledColourId    = 0x1006503   /**< The colour to use for the disabled tick mark. */
 | 
			
		||||
        tickDisabledColourId    = 0x1006503   /**< The colour to use for the disabled tick mark and/or outline. */
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** @internal */
 | 
			
		||||
    void paintButton (Graphics&, bool isMouseOverButton, bool isButtonDown) override;
 | 
			
		||||
    void paintButton (Graphics&, bool, bool) override;
 | 
			
		||||
    /** @internal */
 | 
			
		||||
    void colourChanged() override;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -66,7 +66,7 @@ public:
 | 
			
		||||
                   Drawable* toggledOnImage);
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~ToolbarButton();
 | 
			
		||||
    ~ToolbarButton() override;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
 | 
			
		||||
@ -35,7 +35,7 @@ namespace juce
 | 
			
		||||
    @see ApplicationCommandInfo, ApplicationCommandManager,
 | 
			
		||||
         ApplicationCommandTarget, KeyPressMappingSet
 | 
			
		||||
*/
 | 
			
		||||
typedef int CommandID;
 | 
			
		||||
using CommandID = int;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
 | 
			
		||||
@ -185,7 +185,7 @@ bool ApplicationCommandManager::invoke (const ApplicationCommandTarget::Invocati
 | 
			
		||||
{
 | 
			
		||||
    // This call isn't thread-safe for use from a non-UI thread without locking the message
 | 
			
		||||
    // manager first..
 | 
			
		||||
    jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager());
 | 
			
		||||
    JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED
 | 
			
		||||
 | 
			
		||||
    bool ok = false;
 | 
			
		||||
    ApplicationCommandInfo commandInfo (0);
 | 
			
		||||
 | 
			
		||||
@ -102,7 +102,7 @@ public:
 | 
			
		||||
        Make sure that you don't delete this if pointers to it are still being used by
 | 
			
		||||
        objects such as PopupMenus or Buttons.
 | 
			
		||||
    */
 | 
			
		||||
    virtual ~ApplicationCommandManager();
 | 
			
		||||
    ~ApplicationCommandManager() override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Clears the current list of all commands.
 | 
			
		||||
@ -338,7 +338,7 @@ class JUCE_API  ApplicationCommandManagerListener
 | 
			
		||||
public:
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    virtual ~ApplicationCommandManagerListener()  {}
 | 
			
		||||
    virtual ~ApplicationCommandManagerListener() = default;
 | 
			
		||||
 | 
			
		||||
    /** Called when an app command is about to be invoked. */
 | 
			
		||||
    virtual void applicationCommandInvoked (const ApplicationCommandTarget::InvocationInfo&) = 0;
 | 
			
		||||
 | 
			
		||||
@ -108,7 +108,7 @@ public:
 | 
			
		||||
    KeyPressMappingSet (const KeyPressMappingSet&);
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~KeyPressMappingSet();
 | 
			
		||||
    ~KeyPressMappingSet() override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    ApplicationCommandManager& getCommandManager() const noexcept       { return commandManager; }
 | 
			
		||||
 | 
			
		||||
@ -42,8 +42,8 @@ namespace juce
 | 
			
		||||
class JUCE_API  CachedComponentImage
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    CachedComponentImage() noexcept {}
 | 
			
		||||
    virtual ~CachedComponentImage() {}
 | 
			
		||||
    CachedComponentImage() = default;
 | 
			
		||||
    virtual ~CachedComponentImage() = default;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Called as part of the parent component's paint method, this must draw
 | 
			
		||||
 | 
			
		||||
@ -65,9 +65,42 @@ public:
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template <typename ...Params>
 | 
			
		||||
    // g++ 4.8 cannot deduce the parameter pack inside the function pointer when it has more than one element
 | 
			
		||||
   #if defined(__GNUC__) && __GNUC__ < 5 && ! defined(__clang__)
 | 
			
		||||
    template <typename... Params>
 | 
			
		||||
    static void sendMouseEvent (Component& comp, Component::BailOutChecker& checker,
 | 
			
		||||
                                void (MouseListener::*eventMethod) (Params...), Params... params)
 | 
			
		||||
                                void (MouseListener::*eventMethod) (const MouseEvent&),
 | 
			
		||||
                                Params... params)
 | 
			
		||||
    {
 | 
			
		||||
        sendMouseEvent <decltype (eventMethod), Params...> (comp, checker, eventMethod, params...);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template <typename... Params>
 | 
			
		||||
    static void sendMouseEvent (Component& comp, Component::BailOutChecker& checker,
 | 
			
		||||
                                void (MouseListener::*eventMethod) (const MouseEvent&, const MouseWheelDetails&),
 | 
			
		||||
                                Params... params)
 | 
			
		||||
    {
 | 
			
		||||
        sendMouseEvent <decltype (eventMethod), Params...> (comp, checker, eventMethod, params...);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template <typename... Params>
 | 
			
		||||
    static void sendMouseEvent (Component& comp, Component::BailOutChecker& checker,
 | 
			
		||||
                                void (MouseListener::*eventMethod) (const MouseEvent&, float),
 | 
			
		||||
                                Params... params)
 | 
			
		||||
    {
 | 
			
		||||
        sendMouseEvent <decltype (eventMethod), Params...> (comp, checker, eventMethod, params...);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template <typename EventMethod, typename... Params>
 | 
			
		||||
    static void sendMouseEvent (Component& comp, Component::BailOutChecker& checker,
 | 
			
		||||
                                EventMethod eventMethod,
 | 
			
		||||
                                Params... params)
 | 
			
		||||
   #else
 | 
			
		||||
    template <typename... Params>
 | 
			
		||||
    static void sendMouseEvent (Component& comp, Component::BailOutChecker& checker,
 | 
			
		||||
                                void (MouseListener::*eventMethod) (Params...),
 | 
			
		||||
                                Params... params)
 | 
			
		||||
   #endif
 | 
			
		||||
    {
 | 
			
		||||
        if (checker.shouldBailOut())
 | 
			
		||||
            return;
 | 
			
		||||
@ -456,7 +489,7 @@ void Component::setName (const String& name)
 | 
			
		||||
{
 | 
			
		||||
    // if component methods are being called from threads other than the message
 | 
			
		||||
    // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
 | 
			
		||||
    ASSERT_MESSAGE_MANAGER_IS_LOCKED_OR_OFFSCREEN
 | 
			
		||||
    JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED_OR_OFFSCREEN
 | 
			
		||||
 | 
			
		||||
    if (componentName != name)
 | 
			
		||||
    {
 | 
			
		||||
@ -482,7 +515,7 @@ void Component::setVisible (bool shouldBeVisible)
 | 
			
		||||
    {
 | 
			
		||||
        // if component methods are being called from threads other than the message
 | 
			
		||||
        // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
 | 
			
		||||
        ASSERT_MESSAGE_MANAGER_IS_LOCKED_OR_OFFSCREEN
 | 
			
		||||
        JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED_OR_OFFSCREEN
 | 
			
		||||
 | 
			
		||||
        const WeakReference<Component> safePointer (this);
 | 
			
		||||
        flags.visibleFlag = shouldBeVisible;
 | 
			
		||||
@ -562,7 +595,7 @@ void Component::addToDesktop (int styleWanted, void* nativeWindowToAttachTo)
 | 
			
		||||
{
 | 
			
		||||
    // if component methods are being called from threads other than the message
 | 
			
		||||
    // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
 | 
			
		||||
    ASSERT_MESSAGE_MANAGER_IS_LOCKED
 | 
			
		||||
    JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED
 | 
			
		||||
 | 
			
		||||
    if (isOpaque())
 | 
			
		||||
        styleWanted &= ~ComponentPeer::windowIsSemiTransparent;
 | 
			
		||||
@ -663,10 +696,12 @@ void Component::removeFromDesktop()
 | 
			
		||||
{
 | 
			
		||||
    // if component methods are being called from threads other than the message
 | 
			
		||||
    // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
 | 
			
		||||
    ASSERT_MESSAGE_MANAGER_IS_LOCKED_OR_OFFSCREEN
 | 
			
		||||
    JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED_OR_OFFSCREEN
 | 
			
		||||
 | 
			
		||||
    if (flags.hasHeavyweightPeerFlag)
 | 
			
		||||
    {
 | 
			
		||||
        ComponentHelpers::releaseAllCachedImageResources (*this);
 | 
			
		||||
 | 
			
		||||
        auto* peer = ComponentPeer::getPeerFor (this);
 | 
			
		||||
        jassert (peer != nullptr);
 | 
			
		||||
 | 
			
		||||
@ -839,7 +874,7 @@ void Component::toFront (bool setAsForeground)
 | 
			
		||||
{
 | 
			
		||||
    // if component methods are being called from threads other than the message
 | 
			
		||||
    // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
 | 
			
		||||
    ASSERT_MESSAGE_MANAGER_IS_LOCKED_OR_OFFSCREEN
 | 
			
		||||
    JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED_OR_OFFSCREEN
 | 
			
		||||
 | 
			
		||||
    if (flags.hasHeavyweightPeerFlag)
 | 
			
		||||
    {
 | 
			
		||||
@ -1009,7 +1044,7 @@ int Component::getParentHeight() const noexcept
 | 
			
		||||
 | 
			
		||||
Rectangle<int> Component::getParentMonitorArea() const
 | 
			
		||||
{
 | 
			
		||||
    return Desktop::getInstance().getDisplays().getDisplayContaining (getScreenBounds().getCentre()).userArea;
 | 
			
		||||
    return Desktop::getInstance().getDisplays().findDisplayForRect (getScreenBounds()).userArea;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int Component::getScreenX() const                       { return getScreenPosition().x; }
 | 
			
		||||
@ -1030,7 +1065,7 @@ void Component::setBounds (int x, int y, int w, int h)
 | 
			
		||||
{
 | 
			
		||||
    // if component methods are being called from threads other than the message
 | 
			
		||||
    // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
 | 
			
		||||
    ASSERT_MESSAGE_MANAGER_IS_LOCKED_OR_OFFSCREEN
 | 
			
		||||
    JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED_OR_OFFSCREEN
 | 
			
		||||
 | 
			
		||||
    if (w < 0) w = 0;
 | 
			
		||||
    if (h < 0) h = 0;
 | 
			
		||||
@ -1344,7 +1379,9 @@ void Component::addChildComponent (Component& child, int zOrder)
 | 
			
		||||
{
 | 
			
		||||
    // if component methods are being called from threads other than the message
 | 
			
		||||
    // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
 | 
			
		||||
    ASSERT_MESSAGE_MANAGER_IS_LOCKED_OR_OFFSCREEN
 | 
			
		||||
    JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED_OR_OFFSCREEN
 | 
			
		||||
 | 
			
		||||
    jassert (this != &child); // adding a component to itself!?
 | 
			
		||||
 | 
			
		||||
    if (child.parentComponent != this)
 | 
			
		||||
    {
 | 
			
		||||
@ -1420,7 +1457,7 @@ Component* Component::removeChildComponent (int index, bool sendParentEvents, bo
 | 
			
		||||
{
 | 
			
		||||
    // if component methods are being called from threads other than the message
 | 
			
		||||
    // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
 | 
			
		||||
    ASSERT_MESSAGE_MANAGER_IS_LOCKED_OR_OFFSCREEN
 | 
			
		||||
    JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED_OR_OFFSCREEN
 | 
			
		||||
 | 
			
		||||
    auto* child = childComponentList [index];
 | 
			
		||||
 | 
			
		||||
@ -1607,7 +1644,7 @@ void Component::enterModalState (bool shouldTakeKeyboardFocus,
 | 
			
		||||
{
 | 
			
		||||
    // if component methods are being called from threads other than the message
 | 
			
		||||
    // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
 | 
			
		||||
    ASSERT_MESSAGE_MANAGER_IS_LOCKED
 | 
			
		||||
    JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED
 | 
			
		||||
 | 
			
		||||
    if (! isCurrentlyModal (false))
 | 
			
		||||
    {
 | 
			
		||||
@ -1784,7 +1821,7 @@ void Component::internalRepaintUnchecked (Rectangle<int> area, bool isEntireComp
 | 
			
		||||
{
 | 
			
		||||
    // if component methods are being called from threads other than the message
 | 
			
		||||
    // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
 | 
			
		||||
    ASSERT_MESSAGE_MANAGER_IS_LOCKED
 | 
			
		||||
    JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED
 | 
			
		||||
 | 
			
		||||
    if (flags.visibleFlag)
 | 
			
		||||
    {
 | 
			
		||||
@ -2013,8 +2050,8 @@ void Component::setComponentEffect (ImageEffectFilter* newEffect)
 | 
			
		||||
LookAndFeel& Component::getLookAndFeel() const noexcept
 | 
			
		||||
{
 | 
			
		||||
    for (auto* c = this; c != nullptr; c = c->parentComponent)
 | 
			
		||||
        if (c->lookAndFeel != nullptr)
 | 
			
		||||
            return *(c->lookAndFeel);
 | 
			
		||||
        if (auto lf = c->lookAndFeel.get())
 | 
			
		||||
            return *lf;
 | 
			
		||||
 | 
			
		||||
    return LookAndFeel::getDefaultLookAndFeel();
 | 
			
		||||
}
 | 
			
		||||
@ -2164,10 +2201,12 @@ void Component::addComponentListener (ComponentListener* newListener)
 | 
			
		||||
{
 | 
			
		||||
    // if component methods are being called from threads other than the message
 | 
			
		||||
    // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
 | 
			
		||||
    #if JUCE_DEBUG || JUCE_LOG_ASSERTIONS
 | 
			
		||||
   #if JUCE_DEBUG || JUCE_LOG_ASSERTIONS
 | 
			
		||||
    if (getParentComponent() != nullptr)
 | 
			
		||||
        ASSERT_MESSAGE_MANAGER_IS_LOCKED;
 | 
			
		||||
    #endif
 | 
			
		||||
    {
 | 
			
		||||
        JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED
 | 
			
		||||
    }
 | 
			
		||||
   #endif
 | 
			
		||||
 | 
			
		||||
    componentListeners.add (newListener);
 | 
			
		||||
}
 | 
			
		||||
@ -2218,7 +2257,7 @@ void Component::addMouseListener (MouseListener* newListener,
 | 
			
		||||
{
 | 
			
		||||
    // if component methods are being called from threads other than the message
 | 
			
		||||
    // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
 | 
			
		||||
    ASSERT_MESSAGE_MANAGER_IS_LOCKED
 | 
			
		||||
    JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED
 | 
			
		||||
 | 
			
		||||
    // If you register a component as a mouselistener for itself, it'll receive all the events
 | 
			
		||||
    // twice - once via the direct callback that all components get anyway, and then again as a listener!
 | 
			
		||||
@ -2234,7 +2273,7 @@ void Component::removeMouseListener (MouseListener* listenerToRemove)
 | 
			
		||||
{
 | 
			
		||||
    // if component methods are being called from threads other than the message
 | 
			
		||||
    // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
 | 
			
		||||
    ASSERT_MESSAGE_MANAGER_IS_LOCKED
 | 
			
		||||
    JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED
 | 
			
		||||
 | 
			
		||||
    if (mouseListeners != nullptr)
 | 
			
		||||
        mouseListeners->removeListener (listenerToRemove);
 | 
			
		||||
@ -2734,7 +2773,7 @@ void Component::grabKeyboardFocus()
 | 
			
		||||
{
 | 
			
		||||
    // if component methods are being called from threads other than the message
 | 
			
		||||
    // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
 | 
			
		||||
    ASSERT_MESSAGE_MANAGER_IS_LOCKED
 | 
			
		||||
    JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED
 | 
			
		||||
 | 
			
		||||
    grabFocusInternal (focusChangedDirectly, true);
 | 
			
		||||
 | 
			
		||||
@ -2749,7 +2788,7 @@ void Component::moveKeyboardFocusToSibling (bool moveToNext)
 | 
			
		||||
{
 | 
			
		||||
    // if component methods are being called from threads other than the message
 | 
			
		||||
    // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
 | 
			
		||||
    ASSERT_MESSAGE_MANAGER_IS_LOCKED
 | 
			
		||||
    JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED
 | 
			
		||||
 | 
			
		||||
    if (parentComponent != nullptr)
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
@ -63,7 +63,7 @@ public:
 | 
			
		||||
        callback. Any ComponentListener objects that have registered with it will also have their
 | 
			
		||||
        ComponentListener::componentBeingDeleted() methods called.
 | 
			
		||||
    */
 | 
			
		||||
    virtual ~Component();
 | 
			
		||||
    ~Component() override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Creates a component, setting its name at the same time.
 | 
			
		||||
@ -867,8 +867,8 @@ public:
 | 
			
		||||
 | 
			
		||||
    /** Changes the default return value for the hitTest() method.
 | 
			
		||||
 | 
			
		||||
        Setting this to false is an easy way to make a component pass its mouse-clicks
 | 
			
		||||
        through to the components behind it.
 | 
			
		||||
        Setting this to false is an easy way to make a component pass all its mouse events
 | 
			
		||||
        (not just clicks) through to the components behind it.
 | 
			
		||||
 | 
			
		||||
        When a component is created, the default setting for this is true.
 | 
			
		||||
 | 
			
		||||
@ -1480,7 +1480,7 @@ public:
 | 
			
		||||
                     the source component in which it occurred
 | 
			
		||||
        @see mouseEnter, mouseExit, mouseDrag, contains
 | 
			
		||||
    */
 | 
			
		||||
    virtual void mouseMove (const MouseEvent& event) override;
 | 
			
		||||
    void mouseMove (const MouseEvent& event) override;
 | 
			
		||||
 | 
			
		||||
    /** Called when the mouse first enters a component.
 | 
			
		||||
 | 
			
		||||
@ -1496,7 +1496,7 @@ public:
 | 
			
		||||
                     the source component in which it occurred
 | 
			
		||||
        @see mouseExit, mouseDrag, mouseMove, contains
 | 
			
		||||
    */
 | 
			
		||||
    virtual void mouseEnter (const MouseEvent& event) override;
 | 
			
		||||
    void mouseEnter (const MouseEvent& event) override;
 | 
			
		||||
 | 
			
		||||
    /** Called when the mouse moves out of a component.
 | 
			
		||||
 | 
			
		||||
@ -1511,7 +1511,7 @@ public:
 | 
			
		||||
                      the source component in which it occurred
 | 
			
		||||
        @see mouseEnter, mouseDrag, mouseMove, contains
 | 
			
		||||
    */
 | 
			
		||||
    virtual void mouseExit (const MouseEvent& event) override;
 | 
			
		||||
    void mouseExit (const MouseEvent& event) override;
 | 
			
		||||
 | 
			
		||||
    /** Called when a mouse button is pressed.
 | 
			
		||||
 | 
			
		||||
@ -1526,7 +1526,7 @@ public:
 | 
			
		||||
                      the source component in which it occurred
 | 
			
		||||
        @see mouseUp, mouseDrag, mouseDoubleClick, contains
 | 
			
		||||
    */
 | 
			
		||||
    virtual void mouseDown (const MouseEvent& event) override;
 | 
			
		||||
    void mouseDown (const MouseEvent& event) override;
 | 
			
		||||
 | 
			
		||||
    /** Called when the mouse is moved while a button is held down.
 | 
			
		||||
 | 
			
		||||
@ -1538,7 +1538,7 @@ public:
 | 
			
		||||
                      the source component in which it occurred
 | 
			
		||||
        @see mouseDown, mouseUp, mouseMove, contains, setDragRepeatInterval
 | 
			
		||||
    */
 | 
			
		||||
    virtual void mouseDrag (const MouseEvent& event) override;
 | 
			
		||||
    void mouseDrag (const MouseEvent& event) override;
 | 
			
		||||
 | 
			
		||||
    /** Called when a mouse button is released.
 | 
			
		||||
 | 
			
		||||
@ -1553,7 +1553,7 @@ public:
 | 
			
		||||
                      the source component in which it occurred
 | 
			
		||||
        @see mouseDown, mouseDrag, mouseDoubleClick, contains
 | 
			
		||||
    */
 | 
			
		||||
    virtual void mouseUp (const MouseEvent& event) override;
 | 
			
		||||
    void mouseUp (const MouseEvent& event) override;
 | 
			
		||||
 | 
			
		||||
    /** Called when a mouse button has been double-clicked on a component.
 | 
			
		||||
 | 
			
		||||
@ -1565,7 +1565,7 @@ public:
 | 
			
		||||
                      the source component in which it occurred
 | 
			
		||||
        @see mouseDown, mouseUp
 | 
			
		||||
    */
 | 
			
		||||
    virtual void mouseDoubleClick (const MouseEvent& event) override;
 | 
			
		||||
    void mouseDoubleClick (const MouseEvent& event) override;
 | 
			
		||||
 | 
			
		||||
    /** Called when the mouse-wheel is moved.
 | 
			
		||||
 | 
			
		||||
@ -1582,8 +1582,8 @@ public:
 | 
			
		||||
        @param event   details about the mouse event
 | 
			
		||||
        @param wheel   details about the mouse wheel movement
 | 
			
		||||
    */
 | 
			
		||||
    virtual void mouseWheelMove (const MouseEvent& event,
 | 
			
		||||
                                 const MouseWheelDetails& wheel) override;
 | 
			
		||||
    void mouseWheelMove (const MouseEvent& event,
 | 
			
		||||
                         const MouseWheelDetails& wheel) override;
 | 
			
		||||
 | 
			
		||||
    /** Called when a pinch-to-zoom mouse-gesture is used.
 | 
			
		||||
 | 
			
		||||
@ -1596,7 +1596,7 @@ public:
 | 
			
		||||
                            should be changed. A value of 1.0 would indicate no change,
 | 
			
		||||
                            values greater than 1.0 mean it should be enlarged.
 | 
			
		||||
    */
 | 
			
		||||
    virtual void mouseMagnify (const MouseEvent& event, float scaleFactor) override;
 | 
			
		||||
    void mouseMagnify (const MouseEvent& event, float scaleFactor) override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Ensures that a non-stop stream of mouse-drag events will be sent during the
 | 
			
		||||
@ -2123,7 +2123,7 @@ public:
 | 
			
		||||
        and you can test whether it's null before using it to see if something has deleted
 | 
			
		||||
        it.
 | 
			
		||||
 | 
			
		||||
        The ComponentType typedef must be Component, or some subclass of Component.
 | 
			
		||||
        The ComponentType template parameter must be Component, or some subclass of Component.
 | 
			
		||||
 | 
			
		||||
        You may also want to use a WeakReference<Component> object for the same purpose.
 | 
			
		||||
    */
 | 
			
		||||
@ -2132,7 +2132,7 @@ public:
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
        /** Creates a null SafePointer. */
 | 
			
		||||
        SafePointer() noexcept {}
 | 
			
		||||
        SafePointer() = default;
 | 
			
		||||
 | 
			
		||||
        /** Creates a SafePointer that points at the given component. */
 | 
			
		||||
        SafePointer (ComponentType* component)                : weakRef (component) {}
 | 
			
		||||
@ -2205,7 +2205,7 @@ public:
 | 
			
		||||
        /** Creates a Positioner which can control the specified component. */
 | 
			
		||||
        explicit Positioner (Component& component) noexcept;
 | 
			
		||||
        /** Destructor. */
 | 
			
		||||
        virtual ~Positioner() {}
 | 
			
		||||
        virtual ~Positioner() = default;
 | 
			
		||||
 | 
			
		||||
        /** Returns the component that this positioner controls. */
 | 
			
		||||
        Component& getComponent() const noexcept    { return component; }
 | 
			
		||||
@ -2249,7 +2249,7 @@ public:
 | 
			
		||||
 | 
			
		||||
    /** Sets a flag to indicate whether mouse drag events on this Component should be ignored when it is inside a
 | 
			
		||||
        Viewport with drag-to-scroll functionality enabled. This is useful for Components such as sliders that
 | 
			
		||||
        should not move their parent Viewport when dragged.
 | 
			
		||||
        should not move when their parent Viewport when dragged.
 | 
			
		||||
    */
 | 
			
		||||
    void setViewportIgnoreDragFlag (bool ignoreDrag) noexcept           { flags.viewportIgnoreDragFlag = ignoreDrag; }
 | 
			
		||||
 | 
			
		||||
@ -2280,8 +2280,6 @@ private:
 | 
			
		||||
    std::unique_ptr<CachedComponentImage> cachedImage;
 | 
			
		||||
 | 
			
		||||
    class MouseListenerList;
 | 
			
		||||
    friend class MouseListenerList;
 | 
			
		||||
    friend struct ContainerDeletePolicy<MouseListenerList>;
 | 
			
		||||
    std::unique_ptr<MouseListenerList> mouseListeners;
 | 
			
		||||
    std::unique_ptr<Array<KeyListener*>> keyListeners;
 | 
			
		||||
    ListenerList<ComponentListener> componentListeners;
 | 
			
		||||
 | 
			
		||||
@ -44,7 +44,7 @@ class JUCE_API  ComponentListener
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    virtual ~ComponentListener()  {}
 | 
			
		||||
    virtual ~ComponentListener() = default;
 | 
			
		||||
 | 
			
		||||
    /** Called when the component's position or size changes.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -254,7 +254,7 @@ bool ModalComponentManager::cancelAllModalComponents()
 | 
			
		||||
int ModalComponentManager::runEventLoopForCurrentComponent()
 | 
			
		||||
{
 | 
			
		||||
    // This can only be run from the message thread!
 | 
			
		||||
    jassert (MessageManager::getInstance()->isThisTheMessageThread());
 | 
			
		||||
    JUCE_ASSERT_MESSAGE_THREAD
 | 
			
		||||
 | 
			
		||||
    int returnValue = 0;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -57,10 +57,10 @@ public:
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
        /** */
 | 
			
		||||
        Callback() {}
 | 
			
		||||
        Callback() = default;
 | 
			
		||||
 | 
			
		||||
        /** Destructor. */
 | 
			
		||||
        virtual ~Callback() {}
 | 
			
		||||
        virtual ~Callback() = default;
 | 
			
		||||
 | 
			
		||||
        /** Called to indicate that a modal component has been dismissed.
 | 
			
		||||
 | 
			
		||||
@ -134,17 +134,16 @@ protected:
 | 
			
		||||
    ModalComponentManager();
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~ModalComponentManager();
 | 
			
		||||
    ~ModalComponentManager() override;
 | 
			
		||||
 | 
			
		||||
    /** @internal */
 | 
			
		||||
    void handleAsyncUpdate() override;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    struct ModalItem;
 | 
			
		||||
 | 
			
		||||
    friend class Component;
 | 
			
		||||
    friend struct ContainerDeletePolicy<ModalItem>;
 | 
			
		||||
 | 
			
		||||
    struct ModalItem;
 | 
			
		||||
    OwnedArray<ModalItem> stack;
 | 
			
		||||
 | 
			
		||||
    void startModal (Component*, bool autoDelete);
 | 
			
		||||
@ -161,7 +160,7 @@ private:
 | 
			
		||||
 | 
			
		||||
    @tags{GUI}
 | 
			
		||||
*/
 | 
			
		||||
class ModalCallbackFunction
 | 
			
		||||
class JUCE_API ModalCallbackFunction
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    /** This is a utility function to create a ModalComponentManager::Callback that will
 | 
			
		||||
 | 
			
		||||
@ -70,7 +70,7 @@ Component* Desktop::getComponent (int index) const noexcept
 | 
			
		||||
 | 
			
		||||
Component* Desktop::findComponentAt (Point<int> screenPosition) const
 | 
			
		||||
{
 | 
			
		||||
    ASSERT_MESSAGE_MANAGER_IS_LOCKED
 | 
			
		||||
    JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED
 | 
			
		||||
 | 
			
		||||
    for (int i = desktopComponents.size(); --i >= 0;)
 | 
			
		||||
    {
 | 
			
		||||
@ -91,20 +91,21 @@ Component* Desktop::findComponentAt (Point<int> screenPosition) const
 | 
			
		||||
//==============================================================================
 | 
			
		||||
LookAndFeel& Desktop::getDefaultLookAndFeel() noexcept
 | 
			
		||||
{
 | 
			
		||||
    if (currentLookAndFeel == nullptr)
 | 
			
		||||
    {
 | 
			
		||||
        if (defaultLookAndFeel == nullptr)
 | 
			
		||||
            defaultLookAndFeel.reset (new LookAndFeel_V4());
 | 
			
		||||
    if (auto lf = currentLookAndFeel.get())
 | 
			
		||||
        return *lf;
 | 
			
		||||
 | 
			
		||||
        currentLookAndFeel = defaultLookAndFeel.get();
 | 
			
		||||
    }
 | 
			
		||||
    if (defaultLookAndFeel == nullptr)
 | 
			
		||||
        defaultLookAndFeel.reset (new LookAndFeel_V4());
 | 
			
		||||
 | 
			
		||||
    return *currentLookAndFeel;
 | 
			
		||||
    auto lf = defaultLookAndFeel.get();
 | 
			
		||||
    jassert (lf != nullptr);
 | 
			
		||||
    currentLookAndFeel = lf;
 | 
			
		||||
    return *lf;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Desktop::setDefaultLookAndFeel (LookAndFeel* newDefaultLookAndFeel)
 | 
			
		||||
{
 | 
			
		||||
    ASSERT_MESSAGE_MANAGER_IS_LOCKED
 | 
			
		||||
    JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED
 | 
			
		||||
    currentLookAndFeel = newDefaultLookAndFeel;
 | 
			
		||||
 | 
			
		||||
    for (int i = getNumComponents(); --i >= 0;)
 | 
			
		||||
@ -193,7 +194,7 @@ void Desktop::handleAsyncUpdate()
 | 
			
		||||
    // The component may be deleted during this operation, but we'll use a SafePointer rather than a
 | 
			
		||||
    // BailOutChecker so that any remaining listeners will still get a callback (with a null pointer).
 | 
			
		||||
    WeakReference<Component> currentFocus (Component::getCurrentlyFocusedComponent());
 | 
			
		||||
    focusListeners.call ([&] (FocusChangeListener& l) { l.globalFocusChanged (currentFocus); });
 | 
			
		||||
    focusListeners.call ([&] (FocusChangeListener& l) { l.globalFocusChanged (currentFocus.get()); });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
@ -215,14 +216,14 @@ ListenerList<MouseListener>& Desktop::getMouseListeners()
 | 
			
		||||
 | 
			
		||||
void Desktop::addGlobalMouseListener (MouseListener* listener)
 | 
			
		||||
{
 | 
			
		||||
    ASSERT_MESSAGE_MANAGER_IS_LOCKED
 | 
			
		||||
    JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED
 | 
			
		||||
    mouseListeners.add (listener);
 | 
			
		||||
    resetTimer();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Desktop::removeGlobalMouseListener (MouseListener* listener)
 | 
			
		||||
{
 | 
			
		||||
    ASSERT_MESSAGE_MANAGER_IS_LOCKED
 | 
			
		||||
    JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED
 | 
			
		||||
    mouseListeners.remove (listener);
 | 
			
		||||
    resetTimer();
 | 
			
		||||
}
 | 
			
		||||
@ -260,95 +261,6 @@ void Desktop::sendMouseMove()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
Desktop::Displays::Displays (Desktop& desktop)   { init (desktop); }
 | 
			
		||||
Desktop::Displays::~Displays()  {}
 | 
			
		||||
 | 
			
		||||
const Desktop::Displays::Display& Desktop::Displays::getMainDisplay() const noexcept
 | 
			
		||||
{
 | 
			
		||||
    ASSERT_MESSAGE_MANAGER_IS_LOCKED
 | 
			
		||||
    jassert (displays.getReference(0).isMain);
 | 
			
		||||
    return displays.getReference(0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const Desktop::Displays::Display& Desktop::Displays::getDisplayContaining (Point<int> position) const noexcept
 | 
			
		||||
{
 | 
			
		||||
    ASSERT_MESSAGE_MANAGER_IS_LOCKED
 | 
			
		||||
    auto* best = &displays.getReference(0);
 | 
			
		||||
    double bestDistance = 1.0e10;
 | 
			
		||||
 | 
			
		||||
    for (auto& d : displays)
 | 
			
		||||
    {
 | 
			
		||||
        if (d.totalArea.contains (position))
 | 
			
		||||
        {
 | 
			
		||||
            best = &d;
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        auto distance = d.totalArea.getCentre().getDistanceFrom (position);
 | 
			
		||||
 | 
			
		||||
        if (distance < bestDistance)
 | 
			
		||||
        {
 | 
			
		||||
            bestDistance = distance;
 | 
			
		||||
            best = &d;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return *best;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RectangleList<int> Desktop::Displays::getRectangleList (bool userAreasOnly) const
 | 
			
		||||
{
 | 
			
		||||
    ASSERT_MESSAGE_MANAGER_IS_LOCKED
 | 
			
		||||
    RectangleList<int> rl;
 | 
			
		||||
 | 
			
		||||
    for (auto& d : displays)
 | 
			
		||||
        rl.addWithoutMerging (userAreasOnly ? d.userArea : d.totalArea);
 | 
			
		||||
 | 
			
		||||
    return rl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Rectangle<int> Desktop::Displays::getTotalBounds (bool userAreasOnly) const
 | 
			
		||||
{
 | 
			
		||||
    return getRectangleList (userAreasOnly).getBounds();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool operator== (const Desktop::Displays::Display& d1, const Desktop::Displays::Display& d2) noexcept;
 | 
			
		||||
bool operator== (const Desktop::Displays::Display& d1, const Desktop::Displays::Display& d2) noexcept
 | 
			
		||||
{
 | 
			
		||||
    return d1.userArea == d2.userArea
 | 
			
		||||
        && d1.totalArea == d2.totalArea
 | 
			
		||||
        && d1.scale == d2.scale
 | 
			
		||||
        && d1.isMain == d2.isMain;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool operator!= (const Desktop::Displays::Display& d1, const Desktop::Displays::Display& d2) noexcept;
 | 
			
		||||
bool operator!= (const Desktop::Displays::Display& d1, const Desktop::Displays::Display& d2) noexcept
 | 
			
		||||
{
 | 
			
		||||
    return ! (d1 == d2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Desktop::Displays::init (Desktop& desktop)
 | 
			
		||||
{
 | 
			
		||||
    findDisplays (desktop.getGlobalScaleFactor());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Desktop::Displays::refresh()
 | 
			
		||||
{
 | 
			
		||||
    Array<Display> oldDisplays;
 | 
			
		||||
    oldDisplays.swapWith (displays);
 | 
			
		||||
 | 
			
		||||
    init (Desktop::getInstance());
 | 
			
		||||
 | 
			
		||||
    if (oldDisplays != displays)
 | 
			
		||||
    {
 | 
			
		||||
        for (int i = ComponentPeer::getNumPeers(); --i >= 0;)
 | 
			
		||||
            if (auto* peer = ComponentPeer::getPeer (i))
 | 
			
		||||
                peer->handleScreenSizeChange();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
void Desktop::setKioskModeComponent (Component* componentToUse, bool allowMenusAndBars)
 | 
			
		||||
{
 | 
			
		||||
@ -411,7 +323,7 @@ bool Desktop::isOrientationEnabled (DisplayOrientation orientation) const noexce
 | 
			
		||||
 | 
			
		||||
void Desktop::setGlobalScaleFactor (float newScaleFactor) noexcept
 | 
			
		||||
{
 | 
			
		||||
    ASSERT_MESSAGE_MANAGER_IS_LOCKED
 | 
			
		||||
    JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED
 | 
			
		||||
 | 
			
		||||
    if (masterScaleFactor != newScaleFactor)
 | 
			
		||||
    {
 | 
			
		||||
@ -40,7 +40,7 @@ class JUCE_API  FocusChangeListener
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    virtual ~FocusChangeListener()  {}
 | 
			
		||||
    virtual ~FocusChangeListener() = default;
 | 
			
		||||
 | 
			
		||||
    /** Callback to indicate that the currently focused component has changed. */
 | 
			
		||||
    virtual void globalFocusChanged (Component* focusedComponent) = 0;
 | 
			
		||||
@ -51,7 +51,6 @@ public:
 | 
			
		||||
/**
 | 
			
		||||
    Describes and controls aspects of the computer's desktop.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    @tags{GUI}
 | 
			
		||||
*/
 | 
			
		||||
class JUCE_API  Desktop  : private DeletedAtShutdown,
 | 
			
		||||
@ -327,69 +326,6 @@ public:
 | 
			
		||||
    bool isOrientationEnabled (DisplayOrientation orientation) const noexcept;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Manages details about connected display devices */
 | 
			
		||||
    class JUCE_API  Displays
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
        /** Contains details about a display device. */
 | 
			
		||||
        struct Display
 | 
			
		||||
        {
 | 
			
		||||
            /** This is the bounds of the area of this display which isn't covered by
 | 
			
		||||
                OS-dependent objects like the taskbar, menu bar, etc. */
 | 
			
		||||
            Rectangle<int> userArea;
 | 
			
		||||
 | 
			
		||||
            /** This is the total physical area of this display, including any taskbars, etc */
 | 
			
		||||
            Rectangle<int> totalArea;
 | 
			
		||||
 | 
			
		||||
            /** This is the scale-factor of this display.
 | 
			
		||||
                If you create a component with size 1x1, this scale factor indicates the actual
 | 
			
		||||
                size of the component in terms of physical pixels.
 | 
			
		||||
                For higher-resolution displays, it may be a value greater than 1.0
 | 
			
		||||
            */
 | 
			
		||||
            double scale;
 | 
			
		||||
 | 
			
		||||
            /** The DPI of the display.
 | 
			
		||||
                This is the number of physical pixels per inch. To get the number of logical
 | 
			
		||||
                pixels per inch, divide this by the Display::scale value.
 | 
			
		||||
            */
 | 
			
		||||
            double dpi;
 | 
			
		||||
 | 
			
		||||
            /** This will be true if this is the user's main screen. */
 | 
			
		||||
            bool isMain;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        /** Returns the display which acts as user's main screen. */
 | 
			
		||||
        const Display& getMainDisplay() const noexcept;
 | 
			
		||||
 | 
			
		||||
        /** Returns the display which contains a particular point.
 | 
			
		||||
            If the point lies outside all the displays, the nearest one will be returned.
 | 
			
		||||
        */
 | 
			
		||||
        const Display& getDisplayContaining (Point<int> position) const noexcept;
 | 
			
		||||
 | 
			
		||||
        /** Returns a RectangleList made up of all the displays. */
 | 
			
		||||
        RectangleList<int> getRectangleList (bool userAreasOnly) const;
 | 
			
		||||
 | 
			
		||||
        /** Returns the smallest bounding box which contains all the displays. */
 | 
			
		||||
        Rectangle<int> getTotalBounds (bool userAreasOnly) const;
 | 
			
		||||
 | 
			
		||||
        /** The list of displays. */
 | 
			
		||||
        Array<Display> displays;
 | 
			
		||||
 | 
			
		||||
       #ifndef DOXYGEN
 | 
			
		||||
        /** @internal */
 | 
			
		||||
        void refresh();
 | 
			
		||||
        /** @internal */
 | 
			
		||||
        ~Displays();
 | 
			
		||||
       #endif
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
        friend class Desktop;
 | 
			
		||||
        Displays (Desktop&);
 | 
			
		||||
 | 
			
		||||
        void init (Desktop&);
 | 
			
		||||
        void findDisplays (float masterScale);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    const Displays& getDisplays() const noexcept        { return *displays; }
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
@ -421,6 +357,7 @@ private:
 | 
			
		||||
    friend class MouseInputSourceInternal;
 | 
			
		||||
    friend class DeletedAtShutdown;
 | 
			
		||||
    friend class TopLevelWindowManager;
 | 
			
		||||
    friend class Displays;
 | 
			
		||||
 | 
			
		||||
    std::unique_ptr<MouseInputSource::SourceList> mouseSources;
 | 
			
		||||
 | 
			
		||||
@ -471,7 +408,7 @@ private:
 | 
			
		||||
    static double getDefaultMasterScale();
 | 
			
		||||
 | 
			
		||||
    Desktop();
 | 
			
		||||
    ~Desktop();
 | 
			
		||||
    ~Desktop() override;
 | 
			
		||||
 | 
			
		||||
    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Desktop)
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										380
									
								
								modules/juce_gui_basics/desktop/juce_Displays.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										380
									
								
								modules/juce_gui_basics/desktop/juce_Displays.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,380 @@
 | 
			
		||||
/*
 | 
			
		||||
  ==============================================================================
 | 
			
		||||
 | 
			
		||||
   This file is part of the JUCE library.
 | 
			
		||||
   Copyright (c) 2017 - ROLI Ltd.
 | 
			
		||||
 | 
			
		||||
   JUCE is an open source library subject to commercial or open-source
 | 
			
		||||
   licensing.
 | 
			
		||||
 | 
			
		||||
   By using JUCE, you agree to the terms of both the JUCE 5 End-User License
 | 
			
		||||
   Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
 | 
			
		||||
   27th April 2017).
 | 
			
		||||
 | 
			
		||||
   End User License Agreement: www.juce.com/juce-5-licence
 | 
			
		||||
   Privacy Policy: www.juce.com/juce-5-privacy-policy
 | 
			
		||||
 | 
			
		||||
   Or: You may also use this code under the terms of the GPL v3 (see
 | 
			
		||||
   www.gnu.org/licenses).
 | 
			
		||||
 | 
			
		||||
   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
 | 
			
		||||
   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
 | 
			
		||||
   DISCLAIMED.
 | 
			
		||||
 | 
			
		||||
  ==============================================================================
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
namespace juce
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
Displays::Displays (Desktop& desktop)
 | 
			
		||||
{
 | 
			
		||||
    init (desktop);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Displays::init (Desktop& desktop)
 | 
			
		||||
{
 | 
			
		||||
    findDisplays (desktop.getGlobalScaleFactor());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const Displays::Display& Displays::findDisplayForRect (Rectangle<int> rect, bool isPhysical) const noexcept
 | 
			
		||||
{
 | 
			
		||||
    int maxArea = -1;
 | 
			
		||||
    Display* retVal = nullptr;
 | 
			
		||||
 | 
			
		||||
    for (auto& display : displays)
 | 
			
		||||
    {
 | 
			
		||||
        auto displayArea = display.totalArea;
 | 
			
		||||
 | 
			
		||||
        if (isPhysical)
 | 
			
		||||
            displayArea = (displayArea.withZeroOrigin() * display.scale) + display.topLeftPhysical;
 | 
			
		||||
 | 
			
		||||
        displayArea = displayArea.getIntersection (rect);
 | 
			
		||||
        auto area = displayArea.getWidth() * displayArea.getHeight();
 | 
			
		||||
 | 
			
		||||
        if (area >= maxArea)
 | 
			
		||||
        {
 | 
			
		||||
            maxArea = area;
 | 
			
		||||
            retVal = &display;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return *retVal;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const Displays::Display& Displays::findDisplayForPoint (Point<int> point, bool isPhysical) const noexcept
 | 
			
		||||
{
 | 
			
		||||
    auto minDistance = std::numeric_limits<int>::max();
 | 
			
		||||
    Display* retVal = nullptr;
 | 
			
		||||
 | 
			
		||||
    for (auto& display : displays)
 | 
			
		||||
    {
 | 
			
		||||
        auto displayArea = display.totalArea;
 | 
			
		||||
 | 
			
		||||
        if (isPhysical)
 | 
			
		||||
            displayArea = (displayArea.withZeroOrigin() * display.scale) + display.topLeftPhysical;
 | 
			
		||||
 | 
			
		||||
        if (displayArea.contains (point))
 | 
			
		||||
            return display;
 | 
			
		||||
 | 
			
		||||
        auto distance = displayArea.getCentre().getDistanceFrom (point);
 | 
			
		||||
        if (distance <= minDistance)
 | 
			
		||||
        {
 | 
			
		||||
            minDistance = distance;
 | 
			
		||||
            retVal = &display;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return *retVal;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Rectangle<int> Displays::physicalToLogical (Rectangle<int> rect, const Display* useScaleFactorOfDisplay) const noexcept
 | 
			
		||||
{
 | 
			
		||||
    auto& display = useScaleFactorOfDisplay != nullptr ? *useScaleFactorOfDisplay
 | 
			
		||||
                                                       : findDisplayForRect (rect, true);
 | 
			
		||||
 | 
			
		||||
    auto globalScale = Desktop::getInstance().getGlobalScaleFactor();
 | 
			
		||||
 | 
			
		||||
    return ((rect.toFloat() - display.topLeftPhysical.toFloat()) / (display.scale / globalScale)).toNearestInt() + (display.totalArea.getTopLeft() * globalScale);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Rectangle<int> Displays::logicalToPhysical (Rectangle<int> rect, const Display* useScaleFactorOfDisplay) const noexcept
 | 
			
		||||
{
 | 
			
		||||
    auto& display = useScaleFactorOfDisplay != nullptr ? *useScaleFactorOfDisplay
 | 
			
		||||
                                                       : findDisplayForRect (rect, false);
 | 
			
		||||
 | 
			
		||||
    auto globalScale = Desktop::getInstance().getGlobalScaleFactor();
 | 
			
		||||
 | 
			
		||||
    return ((rect.toFloat() - (display.totalArea.getTopLeft().toFloat() * globalScale)) * (display.scale / globalScale)).toNearestInt() + display.topLeftPhysical;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename ValueType>
 | 
			
		||||
Point<ValueType> Displays::physicalToLogical (Point<ValueType> point, const Display* useScaleFactorOfDisplay) const noexcept
 | 
			
		||||
{
 | 
			
		||||
    auto& display = useScaleFactorOfDisplay != nullptr ? *useScaleFactorOfDisplay
 | 
			
		||||
                                                       : findDisplayForPoint (point.roundToInt(), true);
 | 
			
		||||
 | 
			
		||||
    auto globalScale = Desktop::getInstance().getGlobalScaleFactor();
 | 
			
		||||
 | 
			
		||||
    Point<ValueType> logicalTopLeft  (display.totalArea.getX(),       display.totalArea.getY());
 | 
			
		||||
    Point<ValueType> physicalTopLeft (display.topLeftPhysical.getX(), display.topLeftPhysical.getY());
 | 
			
		||||
 | 
			
		||||
    return ((point - physicalTopLeft) / (display.scale / globalScale)) + (logicalTopLeft * globalScale);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename ValueType>
 | 
			
		||||
Point<ValueType> Displays::logicalToPhysical (Point<ValueType> point, const Display* useScaleFactorOfDisplay)  const noexcept
 | 
			
		||||
{
 | 
			
		||||
    auto& display = useScaleFactorOfDisplay != nullptr ? *useScaleFactorOfDisplay
 | 
			
		||||
                                                       : findDisplayForPoint (point.roundToInt(), false);
 | 
			
		||||
 | 
			
		||||
    auto globalScale = Desktop::getInstance().getGlobalScaleFactor();
 | 
			
		||||
 | 
			
		||||
    Point<ValueType> logicalTopLeft  (display.totalArea.getX(),       display.totalArea.getY());
 | 
			
		||||
    Point<ValueType> physicalTopLeft (display.topLeftPhysical.getX(), display.topLeftPhysical.getY());
 | 
			
		||||
 | 
			
		||||
    return ((point - (logicalTopLeft * globalScale)) * (display.scale / globalScale)) + physicalTopLeft;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const Displays::Display& Displays::getMainDisplay() const noexcept
 | 
			
		||||
{
 | 
			
		||||
    JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED
 | 
			
		||||
 | 
			
		||||
    for (auto& d : displays)
 | 
			
		||||
        if (d.isMain)
 | 
			
		||||
            return d;
 | 
			
		||||
 | 
			
		||||
    // no main display!
 | 
			
		||||
    jassertfalse;
 | 
			
		||||
    return displays.getReference (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RectangleList<int> Displays::getRectangleList (bool userAreasOnly) const
 | 
			
		||||
{
 | 
			
		||||
    JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED
 | 
			
		||||
    RectangleList<int> rl;
 | 
			
		||||
 | 
			
		||||
    for (auto& d : displays)
 | 
			
		||||
        rl.addWithoutMerging (userAreasOnly ? d.userArea : d.totalArea);
 | 
			
		||||
 | 
			
		||||
    return rl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Rectangle<int> Displays::getTotalBounds (bool userAreasOnly) const
 | 
			
		||||
{
 | 
			
		||||
    return getRectangleList (userAreasOnly).getBounds();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Displays::refresh()
 | 
			
		||||
{
 | 
			
		||||
    Array<Display> oldDisplays;
 | 
			
		||||
    oldDisplays.swapWith (displays);
 | 
			
		||||
 | 
			
		||||
    init (Desktop::getInstance());
 | 
			
		||||
 | 
			
		||||
    if (oldDisplays != displays)
 | 
			
		||||
    {
 | 
			
		||||
        for (auto i = ComponentPeer::getNumPeers(); --i >= 0;)
 | 
			
		||||
            if (auto* peer = ComponentPeer::getPeer (i))
 | 
			
		||||
                peer->handleScreenSizeChange();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool operator== (const Displays::Display& d1, const Displays::Display& d2) noexcept;
 | 
			
		||||
bool operator== (const Displays::Display& d1, const Displays::Display& d2) noexcept
 | 
			
		||||
{
 | 
			
		||||
    return d1.isMain          == d2.isMain
 | 
			
		||||
        && d1.totalArea       == d2.totalArea
 | 
			
		||||
        && d1.userArea        == d2.userArea
 | 
			
		||||
        && d1.topLeftPhysical == d2.topLeftPhysical
 | 
			
		||||
        && d1.scale           == d2.scale
 | 
			
		||||
        && d1.dpi             == d2.dpi;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool operator!= (const Displays::Display& d1, const Displays::Display& d2) noexcept;
 | 
			
		||||
bool operator!= (const Displays::Display& d1, const Displays::Display& d2) noexcept    { return ! (d1 == d2); }
 | 
			
		||||
 | 
			
		||||
// Deprecated method
 | 
			
		||||
const Displays::Display& Displays::getDisplayContaining (Point<int> position) const noexcept
 | 
			
		||||
{
 | 
			
		||||
    JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED
 | 
			
		||||
    auto* best = &displays.getReference (0);
 | 
			
		||||
    auto bestDistance = std::numeric_limits<int>::max();
 | 
			
		||||
 | 
			
		||||
    for (auto& d : displays)
 | 
			
		||||
    {
 | 
			
		||||
        if (d.totalArea.contains (position))
 | 
			
		||||
        {
 | 
			
		||||
            best = &d;
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        auto distance = d.totalArea.getCentre().getDistanceFrom (position);
 | 
			
		||||
 | 
			
		||||
        if (distance < bestDistance)
 | 
			
		||||
        {
 | 
			
		||||
            bestDistance = distance;
 | 
			
		||||
            best = &d;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return *best;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
// These methods are used for converting the totalArea and userArea Rectangles in Display from physical to logical
 | 
			
		||||
// pixels. We do this by constructing a graph of connected displays where the root node has position (0, 0); this can be
 | 
			
		||||
// safely converted to logical pixels using its scale factor and we can then traverse the graph and work out the logical pixels
 | 
			
		||||
// for all the other connected displays. We need to do this as the logical bounds of a display depend not only on its scale
 | 
			
		||||
// factor but also the scale factor of the displays connected to it.
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
    Represents a node in our graph of displays.
 | 
			
		||||
*/
 | 
			
		||||
struct DisplayNode
 | 
			
		||||
{
 | 
			
		||||
    /** The Display object that this represents. */
 | 
			
		||||
    Displays::Display* display;
 | 
			
		||||
 | 
			
		||||
    /** True if this represents the 'root' display with position (0, 0). */
 | 
			
		||||
    bool isRoot = false;
 | 
			
		||||
 | 
			
		||||
    /** The parent node of this node in our display graph. This will have a correct logicalArea. */
 | 
			
		||||
    DisplayNode* parent = nullptr;
 | 
			
		||||
 | 
			
		||||
    /** The logical area to be calculated. This will be valid after processDisplay() has
 | 
			
		||||
        been called on this node.
 | 
			
		||||
    */
 | 
			
		||||
    Rectangle<double> logicalArea;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** Recursive - will calculate and set the logicalArea member of current. */
 | 
			
		||||
static void processDisplay (DisplayNode* currentNode, const Array<DisplayNode>& allNodes)
 | 
			
		||||
{
 | 
			
		||||
    const auto physicalArea = currentNode->display->totalArea.toDouble();
 | 
			
		||||
    const auto scale = currentNode->display->scale;
 | 
			
		||||
 | 
			
		||||
    if (! currentNode->isRoot)
 | 
			
		||||
    {
 | 
			
		||||
        const auto logicalWidth  = physicalArea.getWidth() / scale;
 | 
			
		||||
        const auto logicalHeight = physicalArea.getHeight() / scale;
 | 
			
		||||
 | 
			
		||||
        const auto physicalParentArea = currentNode->parent->display->totalArea.toDouble();
 | 
			
		||||
        const auto logicalParentArea  = currentNode->parent->logicalArea; // logical area of parent has already been calculated
 | 
			
		||||
        const auto parentScale        = currentNode->parent->display->scale;
 | 
			
		||||
 | 
			
		||||
        Rectangle<double> logicalArea (0.0, 0.0, logicalWidth, logicalHeight);
 | 
			
		||||
 | 
			
		||||
        if      (physicalArea.getRight() == physicalParentArea.getX())     logicalArea.setPosition ({ logicalParentArea.getX() - logicalWidth, physicalArea.getY() / parentScale });  // on left
 | 
			
		||||
        else if (physicalArea.getX() == physicalParentArea.getRight())     logicalArea.setPosition ({ logicalParentArea.getRight(),  physicalArea.getY() / parentScale });            // on right
 | 
			
		||||
        else if (physicalArea.getBottom() == physicalParentArea.getY())    logicalArea.setPosition ({ physicalArea.getX() / parentScale, logicalParentArea.getY() - logicalHeight }); // on top
 | 
			
		||||
        else if (physicalArea.getY() == physicalParentArea.getBottom())    logicalArea.setPosition ({ physicalArea.getX() / parentScale, logicalParentArea.getBottom() });            // on bottom
 | 
			
		||||
        else                                                               jassertfalse;
 | 
			
		||||
 | 
			
		||||
        currentNode->logicalArea = logicalArea;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        // If currentNode is the root (position (0, 0)) then we can just scale the physical area
 | 
			
		||||
        currentNode->logicalArea = physicalArea / scale;
 | 
			
		||||
        currentNode->parent = currentNode;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Find child nodes
 | 
			
		||||
    Array<DisplayNode*> children;
 | 
			
		||||
    for (auto& node : allNodes)
 | 
			
		||||
    {
 | 
			
		||||
        // Already calculated
 | 
			
		||||
        if (node.parent != nullptr)
 | 
			
		||||
            continue;
 | 
			
		||||
 | 
			
		||||
        const auto otherPhysicalArea = node.display->totalArea.toDouble();
 | 
			
		||||
 | 
			
		||||
        // If the displays are touching on any side
 | 
			
		||||
        if (otherPhysicalArea.getX() == physicalArea.getRight()  || otherPhysicalArea.getRight() == physicalArea.getX()
 | 
			
		||||
            || otherPhysicalArea.getY() == physicalArea.getBottom() || otherPhysicalArea.getBottom() == physicalArea.getY())
 | 
			
		||||
        {
 | 
			
		||||
            node.parent = currentNode;
 | 
			
		||||
            children.add (&node);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Recursively process all child nodes
 | 
			
		||||
    for (auto child : children)
 | 
			
		||||
        processDisplay (child, allNodes);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** This is called when the displays Array has been filled out with the info for all connected displays and the
 | 
			
		||||
    totalArea and userArea Rectangles need to be converted from physical to logical coordinates.
 | 
			
		||||
*/
 | 
			
		||||
void Displays::updateToLogical()
 | 
			
		||||
{
 | 
			
		||||
    if (displays.size() == 1)
 | 
			
		||||
    {
 | 
			
		||||
        auto& display = displays.getReference (0);
 | 
			
		||||
 | 
			
		||||
        display.totalArea = (display.totalArea.toDouble() / display.scale).toNearestInt();
 | 
			
		||||
        display.userArea  = (display.userArea.toDouble()  / display.scale).toNearestInt();
 | 
			
		||||
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Array<DisplayNode> displayNodes;
 | 
			
		||||
 | 
			
		||||
    for (auto& d : displays)
 | 
			
		||||
    {
 | 
			
		||||
        DisplayNode node;
 | 
			
		||||
 | 
			
		||||
        node.display = &d;
 | 
			
		||||
 | 
			
		||||
        if (d.totalArea.getTopLeft() == Point<int>())
 | 
			
		||||
            node.isRoot = true;
 | 
			
		||||
 | 
			
		||||
        displayNodes.add (node);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    auto* root = [&displayNodes]() -> DisplayNode*
 | 
			
		||||
    {
 | 
			
		||||
        for (auto& node : displayNodes)
 | 
			
		||||
            if (node.isRoot)
 | 
			
		||||
                return &node;
 | 
			
		||||
 | 
			
		||||
        auto minDistance = std::numeric_limits<int>::max();
 | 
			
		||||
        DisplayNode* retVal = nullptr;
 | 
			
		||||
 | 
			
		||||
        for (auto& node : displayNodes)
 | 
			
		||||
        {
 | 
			
		||||
            auto distance = node.display->totalArea.getTopLeft().getDistanceFrom ({});
 | 
			
		||||
 | 
			
		||||
            if (distance < minDistance)
 | 
			
		||||
            {
 | 
			
		||||
                minDistance = distance;
 | 
			
		||||
                retVal = &node;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        retVal->isRoot = true;
 | 
			
		||||
        return retVal;
 | 
			
		||||
    }();
 | 
			
		||||
 | 
			
		||||
    // Must have a root node!
 | 
			
		||||
    jassert (root != nullptr);
 | 
			
		||||
 | 
			
		||||
    // Recursively traverse the display graph from the root and work out logical bounds
 | 
			
		||||
    processDisplay (root, displayNodes);
 | 
			
		||||
 | 
			
		||||
    for (auto& node : displayNodes)
 | 
			
		||||
    {
 | 
			
		||||
        // All of the nodes should have a parent
 | 
			
		||||
        jassert (node.parent != nullptr);
 | 
			
		||||
 | 
			
		||||
        auto relativeUserArea = (node.display->userArea.toDouble() - node.display->totalArea.toDouble().getTopLeft()) / node.display->scale;
 | 
			
		||||
 | 
			
		||||
        // Now set Display::totalArea and ::userArea using the logical area that we have calculated
 | 
			
		||||
        node.display->topLeftPhysical = node.display->totalArea.getTopLeft();
 | 
			
		||||
        node.display->totalArea       = node.logicalArea.toNearestInt();
 | 
			
		||||
        node.display->userArea        = (relativeUserArea + node.logicalArea.getTopLeft()).toNearestInt();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace juce
 | 
			
		||||
							
								
								
									
										145
									
								
								modules/juce_gui_basics/desktop/juce_Displays.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								modules/juce_gui_basics/desktop/juce_Displays.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,145 @@
 | 
			
		||||
/*
 | 
			
		||||
  ==============================================================================
 | 
			
		||||
 | 
			
		||||
   This file is part of the JUCE library.
 | 
			
		||||
   Copyright (c) 2017 - ROLI Ltd.
 | 
			
		||||
 | 
			
		||||
   JUCE is an open source library subject to commercial or open-source
 | 
			
		||||
   licensing.
 | 
			
		||||
 | 
			
		||||
   By using JUCE, you agree to the terms of both the JUCE 5 End-User License
 | 
			
		||||
   Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
 | 
			
		||||
   27th April 2017).
 | 
			
		||||
 | 
			
		||||
   End User License Agreement: www.juce.com/juce-5-licence
 | 
			
		||||
   Privacy Policy: www.juce.com/juce-5-privacy-policy
 | 
			
		||||
 | 
			
		||||
   Or: You may also use this code under the terms of the GPL v3 (see
 | 
			
		||||
   www.gnu.org/licenses).
 | 
			
		||||
 | 
			
		||||
   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
 | 
			
		||||
   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
 | 
			
		||||
   DISCLAIMED.
 | 
			
		||||
 | 
			
		||||
  ==============================================================================
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
namespace juce
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
/**
 | 
			
		||||
    Manages details about connected display devices.
 | 
			
		||||
 | 
			
		||||
    @tags{GUI}
 | 
			
		||||
*/
 | 
			
		||||
class JUCE_API  Displays
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
    Displays (Desktop&);
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    /** Represents a connected display device. */
 | 
			
		||||
    struct Display
 | 
			
		||||
    {
 | 
			
		||||
        /** This will be true if this is the user's main display device. */
 | 
			
		||||
        bool isMain;
 | 
			
		||||
 | 
			
		||||
        /** The total area of this display in logical pixels including any OS-dependent objects
 | 
			
		||||
            like the taskbar, menu bar, etc. */
 | 
			
		||||
        Rectangle<int> totalArea;
 | 
			
		||||
 | 
			
		||||
        /** The total area of this display in logical pixels which isn't covered by OS-dependent
 | 
			
		||||
            objects like the taskbar, menu bar, etc.
 | 
			
		||||
        */
 | 
			
		||||
        Rectangle<int> userArea;
 | 
			
		||||
 | 
			
		||||
        /** The top-left of this display in physical coordinates. */
 | 
			
		||||
        Point<int> topLeftPhysical;
 | 
			
		||||
 | 
			
		||||
        /** The scale factor of this display.
 | 
			
		||||
 | 
			
		||||
            For higher-resolution displays, or displays with a user-defined scale factor set,
 | 
			
		||||
            this may be a value other than 1.0.
 | 
			
		||||
 | 
			
		||||
            This value is used to convert between physical and logical pixels. For example, a Component
 | 
			
		||||
            with size 10x10 will use 20x20 physical pixels on a display with a scale factor of 2.0.
 | 
			
		||||
        */
 | 
			
		||||
        double scale;
 | 
			
		||||
 | 
			
		||||
        /** The DPI of the display.
 | 
			
		||||
 | 
			
		||||
            This is the number of physical pixels per inch. To get the number of logical
 | 
			
		||||
            pixels per inch, divide this by the Display::scale value.
 | 
			
		||||
        */
 | 
			
		||||
        double dpi;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /** Converts a Rectangle from physical to logical pixels.
 | 
			
		||||
 | 
			
		||||
        If useScaleFactorOfDisplay is not null then its scale factor will be used for the conversion
 | 
			
		||||
        regardless of the display that the Rectangle to be converted is on.
 | 
			
		||||
    */
 | 
			
		||||
    Rectangle<int> physicalToLogical (Rectangle<int>, const Display* useScaleFactorOfDisplay = nullptr) const noexcept;
 | 
			
		||||
 | 
			
		||||
    /** Converts a Rectangle from logical to physical pixels.
 | 
			
		||||
 | 
			
		||||
        If useScaleFactorOfDisplay is not null then its scale factor will be used for the conversion
 | 
			
		||||
        regardless of the display that the Rectangle to be converted is on.
 | 
			
		||||
    */
 | 
			
		||||
    Rectangle<int> logicalToPhysical (Rectangle<int>, const Display* useScaleFactorOfDisplay = nullptr) const noexcept;
 | 
			
		||||
 | 
			
		||||
    /** Converts a Point from physical to logical pixels. */
 | 
			
		||||
    template <typename ValueType>
 | 
			
		||||
    Point<ValueType> physicalToLogical (Point<ValueType>, const Display* useScaleFactorOfDisplay = nullptr) const noexcept;
 | 
			
		||||
 | 
			
		||||
    /** Converts a Point from logical to physical pixels. */
 | 
			
		||||
    template <typename ValueType>
 | 
			
		||||
    Point<ValueType> logicalToPhysical (Point<ValueType>, const Display* useScaleFactorOfDisplay = nullptr) const noexcept;
 | 
			
		||||
 | 
			
		||||
    /** Returns the Display object representing the display containing a given Rectangle (either
 | 
			
		||||
        in logical or physical pixels).
 | 
			
		||||
 | 
			
		||||
        If the Rectangle lies outside all the displays then the nearest one will be returned.
 | 
			
		||||
    */
 | 
			
		||||
    const Display& findDisplayForRect (Rectangle<int>, bool isPhysical = false)  const noexcept;
 | 
			
		||||
 | 
			
		||||
    /** Returns the Display object representing the display containing a given Point (either
 | 
			
		||||
        in logical or physical pixels).
 | 
			
		||||
 | 
			
		||||
        If the Point lies outside all the displays then the nearest one will be returned.
 | 
			
		||||
    */
 | 
			
		||||
    const Display& findDisplayForPoint (Point<int>, bool isPhysical = false)  const noexcept;
 | 
			
		||||
 | 
			
		||||
    /** Returns the Display object representing the display acting as the user's main screen. */
 | 
			
		||||
    const Display& getMainDisplay() const noexcept;
 | 
			
		||||
 | 
			
		||||
    /** Returns a RectangleList made up of all the displays in LOGICAL pixels. */
 | 
			
		||||
    RectangleList<int> getRectangleList (bool userAreasOnly) const;
 | 
			
		||||
 | 
			
		||||
    /** Returns the smallest bounding box which contains all the displays in LOGICAL pixels. */
 | 
			
		||||
    Rectangle<int> getTotalBounds (bool userAreasOnly) const;
 | 
			
		||||
 | 
			
		||||
    /** An Array containing the Display objects for all of the connected displays. */
 | 
			
		||||
    Array<Display> displays;
 | 
			
		||||
 | 
			
		||||
   #ifndef DOXYGEN
 | 
			
		||||
    /** @internal */
 | 
			
		||||
    void refresh();
 | 
			
		||||
    /** @internal */
 | 
			
		||||
    ~Displays() = default;
 | 
			
		||||
    // This method has been deprecated - use the findDisplayForPoint() or findDisplayForRect() methods instead
 | 
			
		||||
    // as they can deal with converting between logical and physical pixels
 | 
			
		||||
    JUCE_DEPRECATED (const Display& getDisplayContaining (Point<int> position) const noexcept);
 | 
			
		||||
   #endif
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    friend class Desktop;
 | 
			
		||||
 | 
			
		||||
    void init (Desktop&);
 | 
			
		||||
    void findDisplays (float masterScale);
 | 
			
		||||
 | 
			
		||||
    void updateToLogical();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace juce
 | 
			
		||||
@ -47,7 +47,7 @@ protected:
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    virtual ~Drawable();
 | 
			
		||||
    ~Drawable() override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Creates a deep copy of this Drawable object.
 | 
			
		||||
 | 
			
		||||
@ -51,7 +51,7 @@ public:
 | 
			
		||||
    DrawableComposite (const DrawableComposite&);
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~DrawableComposite();
 | 
			
		||||
    ~DrawableComposite() override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Sets the parallelogram that defines the target position of the content rectangle when the drawable is rendered.
 | 
			
		||||
 | 
			
		||||
@ -43,7 +43,7 @@ public:
 | 
			
		||||
    DrawableImage (const DrawableImage&);
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~DrawableImage();
 | 
			
		||||
    ~DrawableImage() override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Sets the image that this drawable will render. */
 | 
			
		||||
 | 
			
		||||
@ -48,7 +48,7 @@ void DrawablePath::setPath (const Path& newPath)
 | 
			
		||||
 | 
			
		||||
void DrawablePath::setPath (Path&& newPath)
 | 
			
		||||
{
 | 
			
		||||
    path = static_cast<Path&&> (newPath);
 | 
			
		||||
    path = std::move (newPath);
 | 
			
		||||
    pathChanged();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -46,7 +46,7 @@ public:
 | 
			
		||||
    DrawablePath (const DrawablePath&);
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~DrawablePath();
 | 
			
		||||
    ~DrawablePath() override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Changes the path that will be drawn.
 | 
			
		||||
@ -67,7 +67,7 @@ public:
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** @internal */
 | 
			
		||||
    Drawable* createCopy() const;
 | 
			
		||||
    Drawable* createCopy() const override;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
 | 
			
		||||
@ -45,7 +45,7 @@ public:
 | 
			
		||||
    DrawableRectangle (const DrawableRectangle&);
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~DrawableRectangle();
 | 
			
		||||
    ~DrawableRectangle() override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Sets the rectangle's bounds. */
 | 
			
		||||
@ -62,7 +62,7 @@ public:
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** @internal */
 | 
			
		||||
    Drawable* createCopy() const;
 | 
			
		||||
    Drawable* createCopy() const override;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    Parallelogram<float> bounds;
 | 
			
		||||
 | 
			
		||||
@ -45,7 +45,7 @@ protected:
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~DrawableShape();
 | 
			
		||||
    ~DrawableShape() override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Sets a fill type for the path.
 | 
			
		||||
 | 
			
		||||
@ -44,7 +44,7 @@ public:
 | 
			
		||||
    DrawableText (const DrawableText&);
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~DrawableText();
 | 
			
		||||
    ~DrawableText() override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Sets the text to display.*/
 | 
			
		||||
 | 
			
		||||
@ -937,8 +937,7 @@ private:
 | 
			
		||||
 | 
			
		||||
        FillType type (gradient);
 | 
			
		||||
 | 
			
		||||
        auto gradientTransform = parseTransform (fillXml->getStringAttribute ("gradientTransform"))
 | 
			
		||||
                                   .followedBy (transform);
 | 
			
		||||
        auto gradientTransform = parseTransform (fillXml->getStringAttribute ("gradientTransform"));
 | 
			
		||||
 | 
			
		||||
        if (gradient.isRadial)
 | 
			
		||||
        {
 | 
			
		||||
@ -1202,12 +1201,18 @@ private:
 | 
			
		||||
                auto* di = new DrawableImage();
 | 
			
		||||
 | 
			
		||||
                setCommonAttributes (*di, xml);
 | 
			
		||||
                di->setImage (image);
 | 
			
		||||
 | 
			
		||||
                Rectangle<float> imageBounds ((float) xml->getDoubleAttribute ("x", 0.0),                  (float) xml->getDoubleAttribute ("y", 0.0),
 | 
			
		||||
                                              (float) xml->getDoubleAttribute ("width", image.getWidth()), (float) xml->getDoubleAttribute ("height", image.getHeight()));
 | 
			
		||||
 | 
			
		||||
                di->setImage (image.rescaled ((int) imageBounds.getWidth(), (int) imageBounds.getHeight()));
 | 
			
		||||
 | 
			
		||||
                di->setTransformToFit (imageBounds, RectanglePlacement (parsePlacementFlags (xml->getStringAttribute ("preserveAspectRatio").trim())));
 | 
			
		||||
 | 
			
		||||
                if (additionalTransform != nullptr)
 | 
			
		||||
                    di->setTransform (transform.followedBy (*additionalTransform));
 | 
			
		||||
                    di->setTransform (di->getTransform().followedBy (transform).followedBy (*additionalTransform));
 | 
			
		||||
                else
 | 
			
		||||
                    di->setTransform (transform);
 | 
			
		||||
                    di->setTransform (di->getTransform().followedBy (transform));
 | 
			
		||||
 | 
			
		||||
                return di;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@ -111,9 +111,7 @@ private:
 | 
			
		||||
 | 
			
		||||
        if (tempFile.create().wasOk())
 | 
			
		||||
        {
 | 
			
		||||
            std::unique_ptr<FileOutputStream> outputStream (tempFile.createOutputStream());
 | 
			
		||||
 | 
			
		||||
            if (outputStream != nullptr)
 | 
			
		||||
            if (auto outputStream = std::unique_ptr<FileOutputStream> (tempFile.createOutputStream()))
 | 
			
		||||
            {
 | 
			
		||||
                size_t pos = 0;
 | 
			
		||||
                size_t totalSize = data.getSize();
 | 
			
		||||
@ -185,7 +183,7 @@ void ContentSharer::startNewShare (std::function<void (bool, const String&)> cal
 | 
			
		||||
 | 
			
		||||
    // You need to pass a valid callback.
 | 
			
		||||
    jassert (callbackToUse);
 | 
			
		||||
    callback = static_cast<std::function<void (bool, const String&)>&&> (callbackToUse);
 | 
			
		||||
    callback = std::move (callbackToUse);
 | 
			
		||||
 | 
			
		||||
    pimpl.reset (createPimpl());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -139,13 +139,6 @@ private:
 | 
			
		||||
 | 
			
		||||
    void deleteTemporaryFiles();
 | 
			
		||||
    void sharingFinished (bool, const String&);
 | 
			
		||||
 | 
			
		||||
  #if JUCE_ANDROID
 | 
			
		||||
    friend void* juce_contentSharerOpenFile (void*, void*, void*);
 | 
			
		||||
    friend void* juce_contentSharerQuery (void*, void*, void*, void*, void*, void*);
 | 
			
		||||
    friend void* juce_contentSharerGetStreamTypes (void*, void*);
 | 
			
		||||
    friend void  juce_contentSharingCompleted (int);
 | 
			
		||||
  #endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace juce
 | 
			
		||||
 | 
			
		||||
@ -28,9 +28,7 @@ namespace juce
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
DirectoryContentsList::DirectoryContentsList (const FileFilter* f, TimeSliceThread& t)
 | 
			
		||||
   : fileFilter (f), thread (t),
 | 
			
		||||
     fileTypeFlags (File::ignoreHiddenFiles | File::findFiles),
 | 
			
		||||
     shouldStop (true)
 | 
			
		||||
   : fileFilter (f), thread (t)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -55,7 +53,7 @@ void DirectoryContentsList::setDirectory (const File& directory,
 | 
			
		||||
                                          const bool includeDirectories,
 | 
			
		||||
                                          const bool includeFiles)
 | 
			
		||||
{
 | 
			
		||||
    jassert (includeDirectories || includeFiles); // you have to speciify at least one of these!
 | 
			
		||||
    jassert (includeDirectories || includeFiles); // you have to specify at least one of these!
 | 
			
		||||
 | 
			
		||||
    if (directory != root)
 | 
			
		||||
    {
 | 
			
		||||
@ -67,9 +65,13 @@ void DirectoryContentsList::setDirectory (const File& directory,
 | 
			
		||||
        fileTypeFlags &= ~(File::findDirectories | File::findFiles);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int newFlags = fileTypeFlags;
 | 
			
		||||
    if (includeDirectories) newFlags |= File::findDirectories;  else newFlags &= ~File::findDirectories;
 | 
			
		||||
    if (includeFiles)       newFlags |= File::findFiles;        else newFlags &= ~File::findFiles;
 | 
			
		||||
    auto newFlags = fileTypeFlags;
 | 
			
		||||
 | 
			
		||||
    if (includeDirectories) newFlags |= File::findDirectories;
 | 
			
		||||
    else                    newFlags &= ~File::findDirectories;
 | 
			
		||||
 | 
			
		||||
    if (includeFiles)       newFlags |= File::findFiles;
 | 
			
		||||
    else                    newFlags &= ~File::findFiles;
 | 
			
		||||
 | 
			
		||||
    setTypeFlags (newFlags);
 | 
			
		||||
}
 | 
			
		||||
@ -103,7 +105,9 @@ void DirectoryContentsList::clear()
 | 
			
		||||
 | 
			
		||||
void DirectoryContentsList::refresh()
 | 
			
		||||
{
 | 
			
		||||
    clear();
 | 
			
		||||
    stopSearching();
 | 
			
		||||
    wasEmpty = files.isEmpty();
 | 
			
		||||
    files.clear();
 | 
			
		||||
 | 
			
		||||
    if (root.isDirectory())
 | 
			
		||||
    {
 | 
			
		||||
@ -123,7 +127,6 @@ void DirectoryContentsList::setFileFilter (const FileFilter* newFileFilter)
 | 
			
		||||
int DirectoryContentsList::getNumFiles() const noexcept
 | 
			
		||||
{
 | 
			
		||||
    const ScopedLock sl (fileListLock);
 | 
			
		||||
 | 
			
		||||
    return files.size();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -174,7 +177,7 @@ void DirectoryContentsList::changed()
 | 
			
		||||
//==============================================================================
 | 
			
		||||
int DirectoryContentsList::useTimeSlice()
 | 
			
		||||
{
 | 
			
		||||
    const uint32 startTime = Time::getApproximateMillisecondCounter();
 | 
			
		||||
    auto startTime = Time::getApproximateMillisecondCounter();
 | 
			
		||||
    bool hasChanged = false;
 | 
			
		||||
 | 
			
		||||
    for (int i = 100; --i >= 0;)
 | 
			
		||||
@ -218,6 +221,9 @@ bool DirectoryContentsList::checkNextFile (bool& hasChanged)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        fileFindHandle.reset();
 | 
			
		||||
 | 
			
		||||
        if (! wasEmpty && files.isEmpty())
 | 
			
		||||
            hasChanged = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return false;
 | 
			
		||||
@ -234,14 +240,14 @@ bool DirectoryContentsList::addFile (const File& file, const bool isDir,
 | 
			
		||||
         || ((! isDir) && fileFilter->isFileSuitable (file))
 | 
			
		||||
         || (isDir && fileFilter->isDirectorySuitable (file)))
 | 
			
		||||
    {
 | 
			
		||||
        std::unique_ptr<FileInfo> info (new FileInfo());
 | 
			
		||||
        auto info = std::make_unique<FileInfo>();
 | 
			
		||||
 | 
			
		||||
        info->filename = file.getFileName();
 | 
			
		||||
        info->fileSize = fileSize;
 | 
			
		||||
        info->filename         = file.getFileName();
 | 
			
		||||
        info->fileSize         = fileSize;
 | 
			
		||||
        info->modificationTime = modTime;
 | 
			
		||||
        info->creationTime = creationTime;
 | 
			
		||||
        info->isDirectory = isDir;
 | 
			
		||||
        info->isReadOnly = isReadOnly;
 | 
			
		||||
        info->creationTime     = creationTime;
 | 
			
		||||
        info->isDirectory      = isDir;
 | 
			
		||||
        info->isReadOnly       = isReadOnly;
 | 
			
		||||
 | 
			
		||||
        for (int i = files.size(); --i >= 0;)
 | 
			
		||||
            if (files.getUnchecked(i)->filename == info->filename)
 | 
			
		||||
 | 
			
		||||
@ -66,7 +66,7 @@ public:
 | 
			
		||||
                           TimeSliceThread& threadToUse);
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~DirectoryContentsList();
 | 
			
		||||
    ~DirectoryContentsList() override;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
@ -201,15 +201,17 @@ public:
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    File root;
 | 
			
		||||
    const FileFilter* fileFilter;
 | 
			
		||||
    const FileFilter* fileFilter = nullptr;
 | 
			
		||||
    TimeSliceThread& thread;
 | 
			
		||||
    int fileTypeFlags;
 | 
			
		||||
    int fileTypeFlags = File::ignoreHiddenFiles | File::findFiles;
 | 
			
		||||
 | 
			
		||||
    CriticalSection fileListLock;
 | 
			
		||||
    OwnedArray<FileInfo> files;
 | 
			
		||||
 | 
			
		||||
    std::unique_ptr<DirectoryIterator> fileFindHandle;
 | 
			
		||||
    bool volatile shouldStop;
 | 
			
		||||
    std::atomic<bool> shouldStop { true };
 | 
			
		||||
 | 
			
		||||
    bool wasEmpty = true;
 | 
			
		||||
 | 
			
		||||
    int useTimeSlice() override;
 | 
			
		||||
    void stopSearching();
 | 
			
		||||
 | 
			
		||||
@ -88,7 +88,7 @@ public:
 | 
			
		||||
                          FilePreviewComponent* previewComp);
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~FileBrowserComponent();
 | 
			
		||||
    ~FileBrowserComponent() override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Returns the number of files that the user has got selected.
 | 
			
		||||
@ -183,7 +183,7 @@ public:
 | 
			
		||||
    */
 | 
			
		||||
    struct JUCE_API  LookAndFeelMethods
 | 
			
		||||
    {
 | 
			
		||||
        virtual ~LookAndFeelMethods() {}
 | 
			
		||||
        virtual ~LookAndFeelMethods() = default;
 | 
			
		||||
 | 
			
		||||
        // These return a pointer to an internally cached drawable - make sure you don't keep
 | 
			
		||||
        // a copy of this pointer anywhere, as it may become invalid in the future.
 | 
			
		||||
 | 
			
		||||
@ -39,10 +39,11 @@ public:
 | 
			
		||||
 | 
			
		||||
          filter (selectsFiles ? owner.filters : String(), selectsDirectories ? "*" : String(), {}),
 | 
			
		||||
          browserComponent (flags, owner.startingFile, &filter, preview),
 | 
			
		||||
          dialogBox (owner.title, {}, browserComponent, warnAboutOverwrite, browserComponent.findColour (AlertWindow::backgroundColourId))
 | 
			
		||||
          dialogBox (owner.title, {}, browserComponent, warnAboutOverwrite,
 | 
			
		||||
                     browserComponent.findColour (AlertWindow::backgroundColourId), owner.parent)
 | 
			
		||||
    {}
 | 
			
		||||
 | 
			
		||||
    ~NonNative()
 | 
			
		||||
    ~NonNative() override
 | 
			
		||||
    {
 | 
			
		||||
        dialogBox.exitModalState (0);
 | 
			
		||||
    }
 | 
			
		||||
@ -92,10 +93,12 @@ FileChooser::FileChooser (const String& chooserBoxTitle,
 | 
			
		||||
                          const File& currentFileOrDirectory,
 | 
			
		||||
                          const String& fileFilters,
 | 
			
		||||
                          const bool useNativeBox,
 | 
			
		||||
                          const bool treatFilePackagesAsDirectories)
 | 
			
		||||
                          const bool treatFilePackagesAsDirectories,
 | 
			
		||||
                          Component* parentComponentToUse)
 | 
			
		||||
    : title (chooserBoxTitle),
 | 
			
		||||
      filters (fileFilters),
 | 
			
		||||
      startingFile (currentFileOrDirectory),
 | 
			
		||||
      parent (parentComponentToUse),
 | 
			
		||||
      useNativeDialogBox (useNativeBox && isPlatformDialogAvailable()),
 | 
			
		||||
      treatFilePackagesAsDirs (treatFilePackagesAsDirectories)
 | 
			
		||||
{
 | 
			
		||||
@ -175,7 +178,7 @@ void FileChooser::launchAsync (int flags, std::function<void (const FileChooser&
 | 
			
		||||
    // you cannot run two file chooser dialog boxes at the same time
 | 
			
		||||
    jassert (asyncCallback == nullptr);
 | 
			
		||||
 | 
			
		||||
    asyncCallback = static_cast<std::function<void (const FileChooser&)>&&> (callback);
 | 
			
		||||
    asyncCallback = std::move (callback);
 | 
			
		||||
 | 
			
		||||
    pimpl.reset (createPimpl (flags, previewComp));
 | 
			
		||||
    pimpl->launch();
 | 
			
		||||
 | 
			
		||||
@ -75,7 +75,7 @@ public:
 | 
			
		||||
                                              initialFileOrDirectory will be used as the initial
 | 
			
		||||
                                              directory of the native file chooser.
 | 
			
		||||
 | 
			
		||||
                                              Note: on iOS when saving a file, a user will not
 | 
			
		||||
                                              Note: On iOS when saving a file, a user will not
 | 
			
		||||
                                              be able to change a file name, so it may be a good
 | 
			
		||||
                                              idea to include at least a valid file name in
 | 
			
		||||
                                              initialFileOrDirectory. When no filename is found,
 | 
			
		||||
@ -107,6 +107,11 @@ public:
 | 
			
		||||
                                              selection of files inside packages when
 | 
			
		||||
                                              invoked on OS X and when using native dialog
 | 
			
		||||
                                              boxes.
 | 
			
		||||
        @param parentComponent                An optional component which should be the parent
 | 
			
		||||
                                              for the file chooser. If this is a nullptr then the
 | 
			
		||||
                                              FileChooser will be a top-level window. AUv3s on iOS
 | 
			
		||||
                                              must specify this parameter as opening a top-level window
 | 
			
		||||
                                              in an AUv3 is forbidden due to sandbox restrictions.
 | 
			
		||||
 | 
			
		||||
        @see browseForFileToOpen, browseForFileToSave, browseForDirectory
 | 
			
		||||
    */
 | 
			
		||||
@ -114,7 +119,8 @@ public:
 | 
			
		||||
                 const File& initialFileOrDirectory = File(),
 | 
			
		||||
                 const String& filePatternsAllowed = String(),
 | 
			
		||||
                 bool useOSNativeDialogBox = true,
 | 
			
		||||
                 bool treatFilePackagesAsDirectories = false);
 | 
			
		||||
                 bool treatFilePackagesAsDirectories = false,
 | 
			
		||||
                 Component* parentComponent = nullptr);
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~FileChooser();
 | 
			
		||||
@ -245,7 +251,7 @@ public:
 | 
			
		||||
        may return a URL to a remote document. If a local file is chosen then you can
 | 
			
		||||
        convert this file to a JUCE File class via the URL::getLocalFile method.
 | 
			
		||||
 | 
			
		||||
        Note: on iOS you must use the returned URL object directly (you are also
 | 
			
		||||
        Note: On iOS you must use the returned URL object directly (you are also
 | 
			
		||||
        allowed to copy- or move-construct another URL from the returned URL), rather
 | 
			
		||||
        than just storing the path as a String and then creating a new URL from that
 | 
			
		||||
        String. This is because the returned URL contains internally a security
 | 
			
		||||
@ -268,7 +274,7 @@ public:
 | 
			
		||||
        This array may be empty if no files were chosen, or can contain multiple entries
 | 
			
		||||
        if multiple files were chosen.
 | 
			
		||||
 | 
			
		||||
        Note: on iOS you must use the returned URL object directly (you are also
 | 
			
		||||
        Note: On iOS you must use the returned URL object directly (you are also
 | 
			
		||||
        allowed to copy- or move-construct another URL from the returned URL), rather
 | 
			
		||||
        than just storing the path as a String and then creating a new URL from that
 | 
			
		||||
        String. This is because the returned URL contains internally a security
 | 
			
		||||
@ -300,6 +306,7 @@ private:
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    String title, filters;
 | 
			
		||||
    File startingFile;
 | 
			
		||||
    Component* parent;
 | 
			
		||||
    Array<URL> results;
 | 
			
		||||
    const bool useNativeDialogBox;
 | 
			
		||||
    const bool treatFilePackagesAsDirs;
 | 
			
		||||
@ -311,7 +318,7 @@ private:
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    struct Pimpl
 | 
			
		||||
    {
 | 
			
		||||
        virtual ~Pimpl() {}
 | 
			
		||||
        virtual ~Pimpl() = default;
 | 
			
		||||
 | 
			
		||||
        virtual void launch()     = 0;
 | 
			
		||||
        virtual void runModally() = 0;
 | 
			
		||||
 | 
			
		||||
@ -94,8 +94,9 @@ FileChooserDialogBox::FileChooserDialogBox (const String& name,
 | 
			
		||||
                                            const String& instructions,
 | 
			
		||||
                                            FileBrowserComponent& chooserComponent,
 | 
			
		||||
                                            bool shouldWarn,
 | 
			
		||||
                                            Colour backgroundColour)
 | 
			
		||||
    : ResizableWindow (name, backgroundColour, true),
 | 
			
		||||
                                            Colour backgroundColour,
 | 
			
		||||
                                            Component* parentComponent)
 | 
			
		||||
    : ResizableWindow (name, backgroundColour, parentComponent == nullptr),
 | 
			
		||||
      warnAboutOverwritingExistingFiles (shouldWarn)
 | 
			
		||||
{
 | 
			
		||||
    content = new ContentComponent (name, instructions, chooserComponent);
 | 
			
		||||
@ -111,6 +112,9 @@ FileChooserDialogBox::FileChooserDialogBox (const String& name,
 | 
			
		||||
    content->chooserComponent.addListener (this);
 | 
			
		||||
 | 
			
		||||
    FileChooserDialogBox::selectionChanged();
 | 
			
		||||
 | 
			
		||||
    if (parentComponent != nullptr)
 | 
			
		||||
        parentComponent->addAndMakeVisible (this);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
FileChooserDialogBox::~FileChooserDialogBox()
 | 
			
		||||
 | 
			
		||||
@ -81,6 +81,11 @@ public:
 | 
			
		||||
                                if they try to select a file that already exists. (This
 | 
			
		||||
                                flag is only used when saving files)
 | 
			
		||||
        @param backgroundColour the background colour for the top level window
 | 
			
		||||
        @param parentComponent  an optional component which should be the parent
 | 
			
		||||
                                for the file chooser. If this is a nullptr then the
 | 
			
		||||
                                dialog box will be a top-level window. AUv3s on iOS
 | 
			
		||||
                                must specify this parameter as opening a top-level window
 | 
			
		||||
                                in an AUv3 is forbidden due to sandbox restrictions.
 | 
			
		||||
 | 
			
		||||
        @see FileBrowserComponent, FilePreviewComponent
 | 
			
		||||
    */
 | 
			
		||||
@ -88,10 +93,11 @@ public:
 | 
			
		||||
                          const String& instructions,
 | 
			
		||||
                          FileBrowserComponent& browserComponent,
 | 
			
		||||
                          bool warnAboutOverwritingExistingFiles,
 | 
			
		||||
                          Colour backgroundColour);
 | 
			
		||||
                          Colour backgroundColour,
 | 
			
		||||
                          Component* parentComponent = nullptr);
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~FileChooserDialogBox();
 | 
			
		||||
    ~FileChooserDialogBox() override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
   #if JUCE_MODAL_LOOPS_PERMITTED
 | 
			
		||||
 | 
			
		||||
@ -109,7 +109,7 @@ public:
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~ItemComponent()
 | 
			
		||||
    ~ItemComponent() override
 | 
			
		||||
    {
 | 
			
		||||
        thread.removeTimeSliceClient (this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -52,7 +52,7 @@ public:
 | 
			
		||||
    FileListComponent (DirectoryContentsList& listToShow);
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~FileListComponent();
 | 
			
		||||
    ~FileListComponent() override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Returns the number of files the user has got selected.
 | 
			
		||||
 | 
			
		||||
@ -49,7 +49,7 @@ public:
 | 
			
		||||
    FilePreviewComponent();
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~FilePreviewComponent();
 | 
			
		||||
    ~FilePreviewComponent() override;
 | 
			
		||||
 | 
			
		||||
    /** Called to indicate that the user's currently selected file has changed.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -47,7 +47,7 @@ public:
 | 
			
		||||
    FileSearchPathListComponent();
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~FileSearchPathListComponent();
 | 
			
		||||
    ~FileSearchPathListComponent() override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Returns the path as it is currently shown. */
 | 
			
		||||
 | 
			
		||||
@ -63,7 +63,7 @@ public:
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~FileListTreeItem()
 | 
			
		||||
    ~FileListTreeItem() override
 | 
			
		||||
    {
 | 
			
		||||
        thread.removeTimeSliceClient (this);
 | 
			
		||||
        clearSubItems();
 | 
			
		||||
 | 
			
		||||
@ -51,7 +51,7 @@ public:
 | 
			
		||||
    FileTreeComponent (DirectoryContentsList& listToShow);
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~FileTreeComponent();
 | 
			
		||||
    ~FileTreeComponent() override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Returns the number of files the user has got selected.
 | 
			
		||||
 | 
			
		||||
@ -42,7 +42,7 @@ class JUCE_API  FilenameComponentListener
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    virtual ~FilenameComponentListener() {}
 | 
			
		||||
    virtual ~FilenameComponentListener() = default;
 | 
			
		||||
 | 
			
		||||
    /** This method is called after the FilenameComponent's file has been changed. */
 | 
			
		||||
    virtual void filenameComponentChanged (FilenameComponent* fileComponentThatHasChanged) = 0;
 | 
			
		||||
@ -100,7 +100,7 @@ public:
 | 
			
		||||
                       const String& textWhenNothingSelected);
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~FilenameComponent();
 | 
			
		||||
    ~FilenameComponent() override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Returns the currently displayed filename. */
 | 
			
		||||
@ -191,7 +191,7 @@ public:
 | 
			
		||||
    /** This abstract base class is implemented by LookAndFeel classes. */
 | 
			
		||||
    struct JUCE_API  LookAndFeelMethods
 | 
			
		||||
    {
 | 
			
		||||
        virtual ~LookAndFeelMethods() {}
 | 
			
		||||
        virtual ~LookAndFeelMethods() = default;
 | 
			
		||||
 | 
			
		||||
        virtual Button* createFilenameComponentBrowseButton (const String& text) = 0;
 | 
			
		||||
        virtual void layoutFilenameComponent (FilenameComponent&, ComboBox* filenameBox, Button* browseButton) =  0;
 | 
			
		||||
 | 
			
		||||
@ -38,12 +38,12 @@ ImagePreviewComponent::~ImagePreviewComponent()
 | 
			
		||||
//==============================================================================
 | 
			
		||||
void ImagePreviewComponent::getThumbSize (int& w, int& h) const
 | 
			
		||||
{
 | 
			
		||||
    const int availableW = proportionOfWidth (0.97f);
 | 
			
		||||
    const int availableH = getHeight() - 13 * 4;
 | 
			
		||||
    auto availableW = proportionOfWidth (0.97f);
 | 
			
		||||
    auto availableH = getHeight() - 13 * 4;
 | 
			
		||||
 | 
			
		||||
    const double scale = jmin (1.0,
 | 
			
		||||
                               availableW / (double) w,
 | 
			
		||||
                               availableH / (double) h);
 | 
			
		||||
    auto scale = jmin (1.0,
 | 
			
		||||
                       availableW / (double) w,
 | 
			
		||||
                       availableH / (double) h);
 | 
			
		||||
 | 
			
		||||
    w = roundToInt (scale * w);
 | 
			
		||||
    h = roundToInt (scale * h);
 | 
			
		||||
@ -66,18 +66,18 @@ void ImagePreviewComponent::timerCallback()
 | 
			
		||||
    currentDetails.clear();
 | 
			
		||||
    repaint();
 | 
			
		||||
 | 
			
		||||
    std::unique_ptr<FileInputStream> in (fileToLoad.createInputStream());
 | 
			
		||||
    FileInputStream in (fileToLoad);
 | 
			
		||||
 | 
			
		||||
    if (in != nullptr && in->getFile().existsAsFile())
 | 
			
		||||
    if (in.openedOk() && fileToLoad.existsAsFile())
 | 
			
		||||
    {
 | 
			
		||||
        if (ImageFileFormat* const format = ImageFileFormat::findImageFormatForStream (*in))
 | 
			
		||||
        if (auto format = ImageFileFormat::findImageFormatForStream (in))
 | 
			
		||||
        {
 | 
			
		||||
            currentThumbnail = format->decodeImage (*in);
 | 
			
		||||
            currentThumbnail = format->decodeImage (in);
 | 
			
		||||
 | 
			
		||||
            if (currentThumbnail.isValid())
 | 
			
		||||
            {
 | 
			
		||||
                int w = currentThumbnail.getWidth();
 | 
			
		||||
                int h = currentThumbnail.getHeight();
 | 
			
		||||
                auto w = currentThumbnail.getWidth();
 | 
			
		||||
                auto h = currentThumbnail.getHeight();
 | 
			
		||||
 | 
			
		||||
                currentDetails
 | 
			
		||||
                    << fileToLoad.getFileName() << "\n"
 | 
			
		||||
@ -99,13 +99,13 @@ void ImagePreviewComponent::paint (Graphics& g)
 | 
			
		||||
    {
 | 
			
		||||
        g.setFont (13.0f);
 | 
			
		||||
 | 
			
		||||
        int w = currentThumbnail.getWidth();
 | 
			
		||||
        int h = currentThumbnail.getHeight();
 | 
			
		||||
        auto w = currentThumbnail.getWidth();
 | 
			
		||||
        auto h = currentThumbnail.getHeight();
 | 
			
		||||
        getThumbSize (w, h);
 | 
			
		||||
 | 
			
		||||
        const int numLines = 4;
 | 
			
		||||
        const int totalH = 13 * numLines + h + 4;
 | 
			
		||||
        const int y = (getHeight() - totalH) / 2;
 | 
			
		||||
        auto totalH = 13 * numLines + h + 4;
 | 
			
		||||
        auto y = (getHeight() - totalH) / 2;
 | 
			
		||||
 | 
			
		||||
        g.drawImageWithin (currentThumbnail,
 | 
			
		||||
                           (getWidth() - w) / 2, y, w, h,
 | 
			
		||||
 | 
			
		||||
@ -44,7 +44,7 @@ public:
 | 
			
		||||
    ImagePreviewComponent();
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~ImagePreviewComponent();
 | 
			
		||||
    ~ImagePreviewComponent() override;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
 | 
			
		||||
@ -135,15 +135,13 @@
 | 
			
		||||
 #undef KeyPress
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <map>
 | 
			
		||||
#include <set>
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
#define ASSERT_MESSAGE_MANAGER_IS_LOCKED \
 | 
			
		||||
    jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager());
 | 
			
		||||
 | 
			
		||||
#define ASSERT_MESSAGE_MANAGER_IS_LOCKED_OR_OFFSCREEN \
 | 
			
		||||
    jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager() || getPeer() == nullptr);
 | 
			
		||||
#define JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED_OR_OFFSCREEN \
 | 
			
		||||
    jassert ((MessageManager::getInstanceWithoutCreating() != nullptr \
 | 
			
		||||
               && MessageManager::getInstanceWithoutCreating()->currentThreadHasLockedMessageManager()) \
 | 
			
		||||
              || getPeer() == nullptr);
 | 
			
		||||
 | 
			
		||||
namespace juce
 | 
			
		||||
{
 | 
			
		||||
@ -153,7 +151,8 @@ namespace juce
 | 
			
		||||
#include "components/juce_Component.cpp"
 | 
			
		||||
#include "components/juce_ComponentListener.cpp"
 | 
			
		||||
#include "mouse/juce_MouseInputSource.cpp"
 | 
			
		||||
#include "components/juce_Desktop.cpp"
 | 
			
		||||
#include "desktop/juce_Displays.cpp"
 | 
			
		||||
#include "desktop/juce_Desktop.cpp"
 | 
			
		||||
#include "components/juce_ModalComponentManager.cpp"
 | 
			
		||||
#include "mouse/juce_ComponentDragger.cpp"
 | 
			
		||||
#include "mouse/juce_DragAndDropContainer.cpp"
 | 
			
		||||
 | 
			
		||||
@ -35,7 +35,7 @@
 | 
			
		||||
 | 
			
		||||
  ID:               juce_gui_basics
 | 
			
		||||
  vendor:           juce
 | 
			
		||||
  version:          5.3.2
 | 
			
		||||
  version:          5.4.3
 | 
			
		||||
  name:             JUCE GUI core classes
 | 
			
		||||
  description:      Basic user-interface components and related classes.
 | 
			
		||||
  website:          http://www.juce.com/juce
 | 
			
		||||
@ -111,6 +111,13 @@
 | 
			
		||||
 #define JUCE_USE_XCURSOR 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/** Config: JUCE_WIN_PER_MONITOR_DPI_AWARE
 | 
			
		||||
    Enables per-monitor DPI awareness on Windows 8.1 and above.
 | 
			
		||||
*/
 | 
			
		||||
#ifndef JUCE_WIN_PER_MONITOR_DPI_AWARE
 | 
			
		||||
 #define JUCE_WIN_PER_MONITOR_DPI_AWARE 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
namespace juce
 | 
			
		||||
{
 | 
			
		||||
@ -148,6 +155,7 @@ namespace juce
 | 
			
		||||
    class KeyPressMappingSet;
 | 
			
		||||
    class ApplicationCommandManagerListener;
 | 
			
		||||
    class DrawableButton;
 | 
			
		||||
    class Displays;
 | 
			
		||||
 | 
			
		||||
    class FlexBox;
 | 
			
		||||
    #if JUCE_HAS_CONSTEXPR
 | 
			
		||||
@ -168,7 +176,8 @@ namespace juce
 | 
			
		||||
#include "components/juce_CachedComponentImage.h"
 | 
			
		||||
#include "components/juce_Component.h"
 | 
			
		||||
#include "layout/juce_ComponentAnimator.h"
 | 
			
		||||
#include "components/juce_Desktop.h"
 | 
			
		||||
#include "desktop/juce_Desktop.h"
 | 
			
		||||
#include "desktop/juce_Displays.h"
 | 
			
		||||
#include "layout/juce_ComponentBoundsConstrainer.h"
 | 
			
		||||
#include "mouse/juce_ComponentDragger.h"
 | 
			
		||||
#include "mouse/juce_DragAndDropTarget.h"
 | 
			
		||||
 | 
			
		||||
@ -44,7 +44,7 @@ public:
 | 
			
		||||
    CaretComponent (Component* keyFocusOwner);
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~CaretComponent();
 | 
			
		||||
    ~CaretComponent() override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Sets the caret's position to place it next to the given character.
 | 
			
		||||
 | 
			
		||||
@ -42,7 +42,7 @@ class JUCE_API  KeyListener
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    virtual ~KeyListener()  {}
 | 
			
		||||
    virtual ~KeyListener() = default;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Called to indicate that a key has been pressed.
 | 
			
		||||
 | 
			
		||||
@ -27,10 +27,6 @@
 | 
			
		||||
namespace juce
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
KeyPress::KeyPress() noexcept
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
KeyPress::KeyPress (int code, ModifierKeys m, juce_wchar textChar) noexcept
 | 
			
		||||
    : keyCode (code), mods (m), textCharacter (textChar)
 | 
			
		||||
{
 | 
			
		||||
@ -40,19 +36,6 @@ KeyPress::KeyPress (const int code) noexcept  : keyCode (code)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
KeyPress::KeyPress (const KeyPress& other) noexcept
 | 
			
		||||
    : keyCode (other.keyCode), mods (other.mods), textCharacter (other.textCharacter)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
KeyPress& KeyPress::operator= (const KeyPress& other) noexcept
 | 
			
		||||
{
 | 
			
		||||
    keyCode = other.keyCode;
 | 
			
		||||
    mods = other.mods;
 | 
			
		||||
    textCharacter = other.textCharacter;
 | 
			
		||||
    return *this;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool KeyPress::operator== (int otherKeyCode) const noexcept
 | 
			
		||||
{
 | 
			
		||||
    return keyCode == otherKeyCode && ! mods.isAnyModifierKeyDown();
 | 
			
		||||
 | 
			
		||||
@ -45,7 +45,10 @@ public:
 | 
			
		||||
 | 
			
		||||
        @see isValid
 | 
			
		||||
    */
 | 
			
		||||
    KeyPress() noexcept;
 | 
			
		||||
    KeyPress() = default;
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~KeyPress() = default;
 | 
			
		||||
 | 
			
		||||
    /** Creates a KeyPress for a key and some modifiers.
 | 
			
		||||
 | 
			
		||||
@ -74,10 +77,10 @@ public:
 | 
			
		||||
    explicit KeyPress (int keyCode) noexcept;
 | 
			
		||||
 | 
			
		||||
    /** Creates a copy of another KeyPress. */
 | 
			
		||||
    KeyPress (const KeyPress& other) noexcept;
 | 
			
		||||
    KeyPress (const KeyPress&) = default;
 | 
			
		||||
 | 
			
		||||
    /** Copies this KeyPress from another one. */
 | 
			
		||||
    KeyPress& operator= (const KeyPress& other) noexcept;
 | 
			
		||||
    KeyPress& operator= (const KeyPress&) = default;
 | 
			
		||||
 | 
			
		||||
    /** Compares two KeyPress objects. */
 | 
			
		||||
    bool operator== (const KeyPress& other) const noexcept;
 | 
			
		||||
 | 
			
		||||
@ -29,15 +29,7 @@ namespace juce
 | 
			
		||||
 | 
			
		||||
ModifierKeys ModifierKeys::currentModifiers;
 | 
			
		||||
 | 
			
		||||
ModifierKeys::ModifierKeys() noexcept                            : flags (0)           {}
 | 
			
		||||
ModifierKeys::ModifierKeys (int rawFlags) noexcept               : flags (rawFlags)    {}
 | 
			
		||||
ModifierKeys::ModifierKeys (const ModifierKeys& other) noexcept  : flags (other.flags) {}
 | 
			
		||||
 | 
			
		||||
ModifierKeys& ModifierKeys::operator= (const ModifierKeys other) noexcept
 | 
			
		||||
{
 | 
			
		||||
    flags = other.flags;
 | 
			
		||||
    return *this;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ModifierKeys::getNumMouseButtonsDown() const noexcept
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
@ -43,7 +43,7 @@ class JUCE_API  ModifierKeys
 | 
			
		||||
public:
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Creates a ModifierKeys object with no flags set. */
 | 
			
		||||
    ModifierKeys() noexcept;
 | 
			
		||||
    ModifierKeys() = default;
 | 
			
		||||
 | 
			
		||||
    /** Creates a ModifierKeys object from a raw set of flags.
 | 
			
		||||
 | 
			
		||||
@ -54,10 +54,10 @@ public:
 | 
			
		||||
    ModifierKeys (int flags) noexcept;
 | 
			
		||||
 | 
			
		||||
    /** Creates a copy of another object. */
 | 
			
		||||
    ModifierKeys (const ModifierKeys& other) noexcept;
 | 
			
		||||
    ModifierKeys (const ModifierKeys&) = default;
 | 
			
		||||
 | 
			
		||||
    /** Copies this object from another one. */
 | 
			
		||||
    ModifierKeys& operator= (const ModifierKeys other) noexcept;
 | 
			
		||||
    ModifierKeys& operator= (const ModifierKeys&) = default;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Checks whether the 'command' key flag is set (or 'ctrl' on Windows/Linux).
 | 
			
		||||
@ -206,7 +206,7 @@ public:
 | 
			
		||||
    static ModifierKeys getCurrentModifiersRealtime() noexcept;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    int flags;
 | 
			
		||||
    int flags = 0;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace juce
 | 
			
		||||
 | 
			
		||||
@ -43,10 +43,10 @@ class JUCE_API  TextInputTarget
 | 
			
		||||
public:
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** */
 | 
			
		||||
    TextInputTarget() {}
 | 
			
		||||
    TextInputTarget() = default;
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    virtual ~TextInputTarget() {}
 | 
			
		||||
    virtual ~TextInputTarget() = default;
 | 
			
		||||
 | 
			
		||||
    /** Returns true if this input target is currently accepting input.
 | 
			
		||||
        For example, a text editor might return false if it's in read-only mode.
 | 
			
		||||
 | 
			
		||||
@ -55,9 +55,8 @@ class AnimatedPosition  : private Timer
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    AnimatedPosition()
 | 
			
		||||
        : position(), grabbedPos(), releaseVelocity(),
 | 
			
		||||
          range (-std::numeric_limits<double>::max(),
 | 
			
		||||
                  std::numeric_limits<double>::max())
 | 
			
		||||
        :  range (-std::numeric_limits<double>::max(),
 | 
			
		||||
                   std::numeric_limits<double>::max())
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -134,7 +133,7 @@ public:
 | 
			
		||||
    class Listener
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
        virtual ~Listener() {}
 | 
			
		||||
        virtual ~Listener() = default;
 | 
			
		||||
 | 
			
		||||
        /** Called synchronously when an AnimatedPosition changes. */
 | 
			
		||||
        virtual void positionChanged (AnimatedPosition&, double newPosition) = 0;
 | 
			
		||||
@ -154,7 +153,7 @@ public:
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    double position, grabbedPos, releaseVelocity;
 | 
			
		||||
    double position = 0.0, grabbedPos = 0.0, releaseVelocity = 0.0;
 | 
			
		||||
    Range<double> range;
 | 
			
		||||
    Time lastUpdate, lastDrag;
 | 
			
		||||
    ListenerList<Listener> listeners;
 | 
			
		||||
 | 
			
		||||
@ -46,9 +46,7 @@ namespace AnimatedPositionBehaviours
 | 
			
		||||
    */
 | 
			
		||||
    struct ContinuousWithMomentum
 | 
			
		||||
    {
 | 
			
		||||
        ContinuousWithMomentum() noexcept
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
        ContinuousWithMomentum() = default;
 | 
			
		||||
 | 
			
		||||
        /** Sets the friction that damps the movement of the value.
 | 
			
		||||
            A typical value is 0.08; higher values indicate more friction.
 | 
			
		||||
@ -114,9 +112,7 @@ namespace AnimatedPositionBehaviours
 | 
			
		||||
    */
 | 
			
		||||
    struct SnapToPageBoundaries
 | 
			
		||||
    {
 | 
			
		||||
        SnapToPageBoundaries() noexcept   : targetSnapPosition()
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
        SnapToPageBoundaries() = default;
 | 
			
		||||
 | 
			
		||||
        /** Called by the AnimatedPosition class. This tells us the position and
 | 
			
		||||
            velocity at which the user is about to release the object.
 | 
			
		||||
@ -154,7 +150,7 @@ namespace AnimatedPositionBehaviours
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
        double targetSnapPosition;
 | 
			
		||||
        double targetSnapPosition = 0.0;
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -159,8 +159,7 @@ public:
 | 
			
		||||
            else
 | 
			
		||||
                jassertfalse; // seem to be trying to animate a component that's not visible..
 | 
			
		||||
 | 
			
		||||
            auto scale = (float) Desktop::getInstance().getDisplays()
 | 
			
		||||
                                  .getDisplayContaining (getScreenBounds().getCentre()).scale;
 | 
			
		||||
            auto scale = (float) Desktop::getInstance().getDisplays().findDisplayForRect (getScreenBounds()).scale;
 | 
			
		||||
 | 
			
		||||
            image = c.createComponentSnapshot (c.getLocalBounds(), false, scale);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -59,7 +59,7 @@ public:
 | 
			
		||||
    ComponentAnimator();
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~ComponentAnimator();
 | 
			
		||||
    ~ComponentAnimator() override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Starts a component moving from its current position to a specified position.
 | 
			
		||||
@ -87,7 +87,7 @@ public:
 | 
			
		||||
                                    component, or if there's a chance the parent might decide to delete its children.
 | 
			
		||||
        @param startSpeed           a value to indicate the relative start speed of the animation. If this is 0,
 | 
			
		||||
                                    the component will start by accelerating from rest; higher values mean that it
 | 
			
		||||
                                    will have an initial speed greater than zero. If the value if greater than 1, it
 | 
			
		||||
                                    will have an initial speed greater than zero. If the value is greater than 1, it
 | 
			
		||||
                                    will decelerate towards the middle of its journey. To move the component at a
 | 
			
		||||
                                    constant rate for its entire animation, set both the start and end speeds to 1.0
 | 
			
		||||
        @param endSpeed             a relative speed at which the component should be moving when the animation finishes.
 | 
			
		||||
 | 
			
		||||
@ -117,7 +117,7 @@ void ComponentBoundsConstrainer::setBoundsForComponent (Component* component,
 | 
			
		||||
        if (auto* peer = component->getPeer())
 | 
			
		||||
            border = peer->getFrameSize();
 | 
			
		||||
 | 
			
		||||
        auto screenBounds = Desktop::getInstance().getDisplays().getDisplayContaining (targetBounds.getCentre()).userArea;
 | 
			
		||||
        auto screenBounds = Desktop::getInstance().getDisplays().findDisplayForPoint (targetBounds.getCentre()).userArea;
 | 
			
		||||
 | 
			
		||||
        limits = component->getLocalArea (nullptr, screenBounds) + component->getPosition();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -59,7 +59,7 @@ public:
 | 
			
		||||
    ComponentBuilder();
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~ComponentBuilder();
 | 
			
		||||
    ~ComponentBuilder() override;
 | 
			
		||||
 | 
			
		||||
    /** This is the ValueTree data object that the builder is working with. */
 | 
			
		||||
    ValueTree state;
 | 
			
		||||
@ -186,8 +186,8 @@ public:
 | 
			
		||||
    class JUCE_API  ImageProvider
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
        ImageProvider() {}
 | 
			
		||||
        virtual ~ImageProvider() {}
 | 
			
		||||
        ImageProvider() = default;
 | 
			
		||||
        virtual ~ImageProvider() = default;
 | 
			
		||||
 | 
			
		||||
        /** Retrieves the image associated with this identifier, which could be any
 | 
			
		||||
            kind of string, number, filename, etc.
 | 
			
		||||
 | 
			
		||||
@ -49,10 +49,10 @@ class JUCE_API  ComponentMovementWatcher    : public ComponentListener
 | 
			
		||||
public:
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Creates a ComponentMovementWatcher to watch a given target component. */
 | 
			
		||||
    ComponentMovementWatcher (Component* component);
 | 
			
		||||
    ComponentMovementWatcher (Component* componentToWatch);
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~ComponentMovementWatcher();
 | 
			
		||||
    ~ComponentMovementWatcher() override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** This callback happens when the component that is being watched is moved
 | 
			
		||||
@ -68,7 +68,7 @@ public:
 | 
			
		||||
    virtual void componentVisibilityChanged() = 0;
 | 
			
		||||
 | 
			
		||||
    /** Returns the component that's being watched. */
 | 
			
		||||
    Component* getComponent() const noexcept         { return component; }
 | 
			
		||||
    Component* getComponent() const noexcept         { return component.get(); }
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** @internal */
 | 
			
		||||
 | 
			
		||||
@ -46,7 +46,7 @@ public:
 | 
			
		||||
    ConcertinaPanel();
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~ConcertinaPanel();
 | 
			
		||||
    ~ConcertinaPanel() override;
 | 
			
		||||
 | 
			
		||||
    /** Adds a component to the panel.
 | 
			
		||||
        @param insertIndex          the index at which this component will be inserted, or
 | 
			
		||||
@ -113,7 +113,7 @@ public:
 | 
			
		||||
    /** This abstract base class is implemented by LookAndFeel classes. */
 | 
			
		||||
    struct JUCE_API  LookAndFeelMethods
 | 
			
		||||
    {
 | 
			
		||||
        virtual ~LookAndFeelMethods() {}
 | 
			
		||||
        virtual ~LookAndFeelMethods() = default;
 | 
			
		||||
 | 
			
		||||
        virtual void drawConcertinaPanelHeader (Graphics&, const Rectangle<int>& area,
 | 
			
		||||
                                                bool isMouseOver, bool isMouseDown,
 | 
			
		||||
@ -125,11 +125,6 @@ private:
 | 
			
		||||
 | 
			
		||||
    class PanelHolder;
 | 
			
		||||
    struct PanelSizes;
 | 
			
		||||
    friend class PanelHolder;
 | 
			
		||||
    friend struct PanelSizes;
 | 
			
		||||
    friend struct ContainerDeletePolicy<PanelSizes>;
 | 
			
		||||
    friend struct ContainerDeletePolicy<PanelHolder>;
 | 
			
		||||
 | 
			
		||||
    std::unique_ptr<PanelSizes> currentSizes;
 | 
			
		||||
    OwnedArray<PanelHolder> holders;
 | 
			
		||||
    ComponentAnimator animator;
 | 
			
		||||
 | 
			
		||||
@ -298,7 +298,12 @@ struct Grid::PlacementHelpers
 | 
			
		||||
                                    const std::map<juce::String, LineArea>& namedAreas)
 | 
			
		||||
    {
 | 
			
		||||
        if (item.area.isNotEmpty() && ! grid.templateAreas.isEmpty())
 | 
			
		||||
        {
 | 
			
		||||
            // Must be a named area!
 | 
			
		||||
            jassert (namedAreas.count (item.area) != 0);
 | 
			
		||||
 | 
			
		||||
            return namedAreas.at (item.area);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return { deduceLineRange (item.column, grid.templateColumns),
 | 
			
		||||
                 deduceLineRange (item.row,    grid.templateRows) };
 | 
			
		||||
@ -349,11 +354,7 @@ struct Grid::PlacementHelpers
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    if (string == emptyAreaCharacter)
 | 
			
		||||
                    {
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                    else if (string == area.name)
 | 
			
		||||
                    if (string == area.name)
 | 
			
		||||
                    {
 | 
			
		||||
                        area.lines.row.end = stringsArrays.indexOf (stringArray) + 2;
 | 
			
		||||
                        area.lines.column.end = stringArray.indexOf (string) + 2;
 | 
			
		||||
@ -532,9 +533,9 @@ struct Grid::AutoPlacement
 | 
			
		||||
    {
 | 
			
		||||
        struct Cell { int column, row; };
 | 
			
		||||
 | 
			
		||||
        OccupancyPlane (int highestColumnToUse, int highestRowToUse, bool isColoumnFirst)
 | 
			
		||||
            : highestCrossDimension (isColoumnFirst ? highestRowToUse : highestColumnToUse),
 | 
			
		||||
              columnFirst (isColoumnFirst)
 | 
			
		||||
        OccupancyPlane (int highestColumnToUse, int highestRowToUse, bool isColumnFirst)
 | 
			
		||||
            : highestCrossDimension (isColumnFirst ? highestRowToUse : highestColumnToUse),
 | 
			
		||||
              columnFirst (isColumnFirst)
 | 
			
		||||
        {}
 | 
			
		||||
 | 
			
		||||
        Grid::PlacementHelpers::LineArea setCell (Cell cell, int columnSpan, int rowSpan)
 | 
			
		||||
 | 
			
		||||
@ -27,16 +27,15 @@
 | 
			
		||||
namespace juce
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
struct GridTests  : public juce::UnitTest
 | 
			
		||||
struct GridTests  : public UnitTest
 | 
			
		||||
{
 | 
			
		||||
    GridTests() : juce::UnitTest ("Grid class") {}
 | 
			
		||||
    GridTests() : UnitTest ("Grid class") {}
 | 
			
		||||
 | 
			
		||||
    void runTest() override
 | 
			
		||||
    {
 | 
			
		||||
        using Fr = juce::Grid::Fr;
 | 
			
		||||
        using Tr = juce::Grid::TrackInfo;
 | 
			
		||||
        using Rect = juce::Rectangle<float>;
 | 
			
		||||
        using Grid = juce::Grid;
 | 
			
		||||
        using Fr = Grid::Fr;
 | 
			
		||||
        using Tr = Grid::TrackInfo;
 | 
			
		||||
        using Rect = Rectangle<float>;
 | 
			
		||||
 | 
			
		||||
        {
 | 
			
		||||
            Grid grid;
 | 
			
		||||
@ -47,7 +46,7 @@ struct GridTests  : public juce::UnitTest
 | 
			
		||||
            grid.items.addArray ({ GridItem().withArea (1, 1),
 | 
			
		||||
                                   GridItem().withArea (2, 1) });
 | 
			
		||||
 | 
			
		||||
            grid.performLayout (juce::Rectangle<int> (200, 400));
 | 
			
		||||
            grid.performLayout (Rectangle<int> (200, 400));
 | 
			
		||||
 | 
			
		||||
            beginTest ("Layout calculation test: 1 column x 2 rows: no gap");
 | 
			
		||||
            expect (grid.items[0].currentBounds == Rect (0.0f, 0.0f,  200.f, 20.0f));
 | 
			
		||||
@ -61,7 +60,7 @@ struct GridTests  : public juce::UnitTest
 | 
			
		||||
                                    GridItem().withArea (3, 1),
 | 
			
		||||
                                    GridItem().withArea (3, 2) });
 | 
			
		||||
 | 
			
		||||
            grid.performLayout (juce::Rectangle<int> (150, 170));
 | 
			
		||||
            grid.performLayout (Rectangle<int> (150, 170));
 | 
			
		||||
 | 
			
		||||
            beginTest ("Layout calculation test: 2 columns x 3 rows: no gap");
 | 
			
		||||
            expect (grid.items[0].currentBounds == Rect (0.0f,   0.0f,  100.0f, 20.0f));
 | 
			
		||||
@ -74,7 +73,7 @@ struct GridTests  : public juce::UnitTest
 | 
			
		||||
            grid.columnGap = 20_px;
 | 
			
		||||
            grid.rowGap    = 10_px;
 | 
			
		||||
 | 
			
		||||
            grid.performLayout (juce::Rectangle<int> (200, 310));
 | 
			
		||||
            grid.performLayout (Rectangle<int> (200, 310));
 | 
			
		||||
 | 
			
		||||
            beginTest ("Layout calculation test: 2 columns x 3 rows: rowGap of 10 and columnGap of 20");
 | 
			
		||||
            expect (grid.items[0].currentBounds == Rect (0.0f, 0.0f, 130.0f, 20.0f));
 | 
			
		||||
 | 
			
		||||
@ -48,7 +48,7 @@ public:
 | 
			
		||||
                    const String& labelText = String());
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~GroupComponent();
 | 
			
		||||
    ~GroupComponent() override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Changes the text that's shown at the top of the component. */
 | 
			
		||||
@ -89,7 +89,7 @@ public:
 | 
			
		||||
    /** This abstract base class is implemented by LookAndFeel classes. */
 | 
			
		||||
    struct JUCE_API  LookAndFeelMethods
 | 
			
		||||
    {
 | 
			
		||||
        virtual ~LookAndFeelMethods() {}
 | 
			
		||||
        virtual ~LookAndFeelMethods() = default;
 | 
			
		||||
 | 
			
		||||
        virtual void drawGroupComponentOutline (Graphics&, int w, int h, const String& text,
 | 
			
		||||
                                                const Justification&, GroupComponent&) = 0;
 | 
			
		||||
 | 
			
		||||
@ -51,7 +51,7 @@ public:
 | 
			
		||||
    MultiDocumentPanelWindow (Colour backgroundColour);
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~MultiDocumentPanelWindow();
 | 
			
		||||
    ~MultiDocumentPanelWindow() override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** @internal */
 | 
			
		||||
@ -106,7 +106,7 @@ public:
 | 
			
		||||
        before closing, then you should call closeAllDocuments (true) and check that
 | 
			
		||||
        it returns true before deleting the panel.
 | 
			
		||||
    */
 | 
			
		||||
    ~MultiDocumentPanel();
 | 
			
		||||
    ~MultiDocumentPanel() override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Tries to close all the documents.
 | 
			
		||||
 | 
			
		||||
@ -27,10 +27,8 @@
 | 
			
		||||
namespace juce
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
ResizableBorderComponent::Zone::Zone() noexcept  : zone (0) {}
 | 
			
		||||
 | 
			
		||||
ResizableBorderComponent::Zone::Zone (const int zoneFlags) noexcept  : zone (zoneFlags) {}
 | 
			
		||||
 | 
			
		||||
ResizableBorderComponent::Zone::Zone() noexcept {}
 | 
			
		||||
ResizableBorderComponent::Zone::Zone (int zoneFlags) noexcept  : zone (zoneFlags) {}
 | 
			
		||||
ResizableBorderComponent::Zone::Zone (const ResizableBorderComponent::Zone& other) noexcept  : zone (other.zone) {}
 | 
			
		||||
 | 
			
		||||
ResizableBorderComponent::Zone& ResizableBorderComponent::Zone::operator= (const ResizableBorderComponent::Zone& other) noexcept
 | 
			
		||||
@ -42,8 +40,8 @@ ResizableBorderComponent::Zone& ResizableBorderComponent::Zone::operator= (const
 | 
			
		||||
bool ResizableBorderComponent::Zone::operator== (const ResizableBorderComponent::Zone& other) const noexcept      { return zone == other.zone; }
 | 
			
		||||
bool ResizableBorderComponent::Zone::operator!= (const ResizableBorderComponent::Zone& other) const noexcept      { return zone != other.zone; }
 | 
			
		||||
 | 
			
		||||
ResizableBorderComponent::Zone ResizableBorderComponent::Zone::fromPositionOnBorder (const Rectangle<int>& totalSize,
 | 
			
		||||
                                                                                     const BorderSize<int>& border,
 | 
			
		||||
ResizableBorderComponent::Zone ResizableBorderComponent::Zone::fromPositionOnBorder (Rectangle<int> totalSize,
 | 
			
		||||
                                                                                     BorderSize<int> border,
 | 
			
		||||
                                                                                     Point<int> position)
 | 
			
		||||
{
 | 
			
		||||
    int z = 0;
 | 
			
		||||
@ -51,13 +49,15 @@ ResizableBorderComponent::Zone ResizableBorderComponent::Zone::fromPositionOnBor
 | 
			
		||||
    if (totalSize.contains (position)
 | 
			
		||||
         && ! border.subtractedFrom (totalSize).contains (position))
 | 
			
		||||
    {
 | 
			
		||||
        const int minW = jmax (totalSize.getWidth() / 10, jmin (10, totalSize.getWidth() / 3));
 | 
			
		||||
        auto minW = jmax (totalSize.getWidth() / 10, jmin (10, totalSize.getWidth() / 3));
 | 
			
		||||
 | 
			
		||||
        if (position.x < jmax (border.getLeft(), minW) && border.getLeft() > 0)
 | 
			
		||||
            z |= left;
 | 
			
		||||
        else if (position.x >= totalSize.getWidth() - jmax (border.getRight(), minW) && border.getRight() > 0)
 | 
			
		||||
            z |= right;
 | 
			
		||||
 | 
			
		||||
        const int minH = jmax (totalSize.getHeight() / 10, jmin (10, totalSize.getHeight() / 3));
 | 
			
		||||
        auto minH = jmax (totalSize.getHeight() / 10, jmin (10, totalSize.getHeight() / 3));
 | 
			
		||||
 | 
			
		||||
        if (position.y < jmax (border.getTop(), minH) && border.getTop() > 0)
 | 
			
		||||
            z |= top;
 | 
			
		||||
        else if (position.y >= totalSize.getHeight() - jmax (border.getBottom(), minH) && border.getBottom() > 0)
 | 
			
		||||
@ -69,7 +69,7 @@ ResizableBorderComponent::Zone ResizableBorderComponent::Zone::fromPositionOnBor
 | 
			
		||||
 | 
			
		||||
MouseCursor ResizableBorderComponent::Zone::getMouseCursor() const noexcept
 | 
			
		||||
{
 | 
			
		||||
    MouseCursor::StandardCursorType mc = MouseCursor::NormalCursor;
 | 
			
		||||
    auto mc = MouseCursor::NormalCursor;
 | 
			
		||||
 | 
			
		||||
    switch (zone)
 | 
			
		||||
    {
 | 
			
		||||
@ -141,7 +141,7 @@ void ResizableBorderComponent::mouseDrag (const MouseEvent& e)
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const Rectangle<int> newBounds (mouseZone.resizeRectangleBy (originalBounds, e.getOffsetFromDragStart()));
 | 
			
		||||
    auto newBounds = mouseZone.resizeRectangleBy (originalBounds, e.getOffsetFromDragStart());
 | 
			
		||||
 | 
			
		||||
    if (constrainer != nullptr)
 | 
			
		||||
    {
 | 
			
		||||
@ -153,8 +153,8 @@ void ResizableBorderComponent::mouseDrag (const MouseEvent& e)
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        if (Component::Positioner* const pos = component->getPositioner())
 | 
			
		||||
            pos->applyNewBounds (newBounds);
 | 
			
		||||
        if (auto* p = component->getPositioner())
 | 
			
		||||
            p->applyNewBounds (newBounds);
 | 
			
		||||
        else
 | 
			
		||||
            component->setBounds (newBounds);
 | 
			
		||||
    }
 | 
			
		||||
@ -190,7 +190,7 @@ BorderSize<int> ResizableBorderComponent::getBorderThickness() const
 | 
			
		||||
 | 
			
		||||
void ResizableBorderComponent::updateMouseZone (const MouseEvent& e)
 | 
			
		||||
{
 | 
			
		||||
    Zone newZone (Zone::fromPositionOnBorder (getLocalBounds(), borderSize, e.getPosition()));
 | 
			
		||||
    auto newZone = Zone::fromPositionOnBorder (getLocalBounds(), borderSize, e.getPosition());
 | 
			
		||||
 | 
			
		||||
    if (mouseZone != newZone)
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
@ -70,7 +70,7 @@ public:
 | 
			
		||||
                              ComponentBoundsConstrainer* constrainer);
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~ResizableBorderComponent();
 | 
			
		||||
    ~ResizableBorderComponent() override;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
@ -119,8 +119,8 @@ public:
 | 
			
		||||
        /** Given a point within a rectangle with a resizable border, this returns the
 | 
			
		||||
            zone that the point lies within.
 | 
			
		||||
        */
 | 
			
		||||
        static Zone fromPositionOnBorder (const Rectangle<int>& totalSize,
 | 
			
		||||
                                          const BorderSize<int>& border,
 | 
			
		||||
        static Zone fromPositionOnBorder (Rectangle<int> totalSize,
 | 
			
		||||
                                          BorderSize<int> border,
 | 
			
		||||
                                          Point<int> position);
 | 
			
		||||
 | 
			
		||||
        /** Returns an appropriate mouse-cursor for this resize zone. */
 | 
			
		||||
@ -160,7 +160,7 @@ public:
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
        //==============================================================================
 | 
			
		||||
        int zone;
 | 
			
		||||
        int zone = centre;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /** Returns the zone in which the mouse was last seen. */
 | 
			
		||||
 | 
			
		||||
@ -65,7 +65,7 @@ public:
 | 
			
		||||
                              ComponentBoundsConstrainer* constrainer);
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~ResizableCornerComponent();
 | 
			
		||||
    ~ResizableCornerComponent() override;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
 | 
			
		||||
@ -77,7 +77,7 @@ void ResizableEdgeComponent::mouseDrag (const MouseEvent& e)
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Rectangle<int> newBounds (originalBounds);
 | 
			
		||||
    auto newBounds = originalBounds;
 | 
			
		||||
 | 
			
		||||
    switch (edge)
 | 
			
		||||
    {
 | 
			
		||||
@ -98,8 +98,8 @@ void ResizableEdgeComponent::mouseDrag (const MouseEvent& e)
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        if (Component::Positioner* const pos = component->getPositioner())
 | 
			
		||||
            pos->applyNewBounds (newBounds);
 | 
			
		||||
        if (auto* p = component->getPositioner())
 | 
			
		||||
            p->applyNewBounds (newBounds);
 | 
			
		||||
        else
 | 
			
		||||
            component->setBounds (newBounds);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -74,7 +74,7 @@ public:
 | 
			
		||||
                            Edge edgeToResize);
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~ResizableEdgeComponent();
 | 
			
		||||
    ~ResizableEdgeComponent() override;
 | 
			
		||||
 | 
			
		||||
    bool isVertical() const noexcept;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -308,7 +308,7 @@ void ScrollBar::resized()
 | 
			
		||||
 | 
			
		||||
    if (upButton != nullptr)
 | 
			
		||||
    {
 | 
			
		||||
        Rectangle<int> r (getLocalBounds());
 | 
			
		||||
        auto r = getLocalBounds();
 | 
			
		||||
 | 
			
		||||
        if (vertical)
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
@ -61,7 +61,7 @@ public:
 | 
			
		||||
    ScrollBar (bool isVertical);
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~ScrollBar();
 | 
			
		||||
    ~ScrollBar() override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Returns true if the scrollbar is vertical, false if it's horizontal. */
 | 
			
		||||
@ -305,7 +305,7 @@ public:
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
        /** Destructor. */
 | 
			
		||||
        virtual ~Listener() {}
 | 
			
		||||
        virtual ~Listener() = default;
 | 
			
		||||
 | 
			
		||||
        /** Called when a ScrollBar is moved.
 | 
			
		||||
 | 
			
		||||
@ -328,7 +328,7 @@ public:
 | 
			
		||||
    */
 | 
			
		||||
    struct JUCE_API  LookAndFeelMethods
 | 
			
		||||
    {
 | 
			
		||||
        virtual ~LookAndFeelMethods() {}
 | 
			
		||||
        virtual ~LookAndFeelMethods() = default;
 | 
			
		||||
 | 
			
		||||
        virtual bool areScrollbarButtonsVisible() = 0;
 | 
			
		||||
 | 
			
		||||
@ -420,7 +420,6 @@ private:
 | 
			
		||||
    int initialDelayInMillisecs = 100, repeatDelayInMillisecs = 50, minimumDelayInMillisecs = 10;
 | 
			
		||||
    bool vertical, isDraggingThumb = false, autohides = true, userVisibilityFlag = false;
 | 
			
		||||
    class ScrollbarButton;
 | 
			
		||||
    friend struct ContainerDeletePolicy<ScrollbarButton>;
 | 
			
		||||
    std::unique_ptr<ScrollbarButton> upButton, downButton;
 | 
			
		||||
    ListenerList<Listener> listeners;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -62,7 +62,7 @@ public:
 | 
			
		||||
               bool deleteComponentWhenNoLongerNeeded = true);
 | 
			
		||||
 | 
			
		||||
    /** Destructor */
 | 
			
		||||
    ~SidePanel();
 | 
			
		||||
    ~SidePanel() override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Sets the component that this SidePanel will contain.
 | 
			
		||||
@ -161,7 +161,7 @@ public:
 | 
			
		||||
     */
 | 
			
		||||
    struct JUCE_API  LookAndFeelMethods
 | 
			
		||||
    {
 | 
			
		||||
        virtual ~LookAndFeelMethods() {}
 | 
			
		||||
        virtual ~LookAndFeelMethods() = default;
 | 
			
		||||
 | 
			
		||||
        virtual Font getSidePanelTitleFont (SidePanel&) = 0;
 | 
			
		||||
        virtual Justification getSidePanelTitleJustification (SidePanel&) = 0;
 | 
			
		||||
 | 
			
		||||
@ -60,7 +60,7 @@ public:
 | 
			
		||||
                                 bool isBarVertical);
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~StretchableLayoutResizerBar();
 | 
			
		||||
    ~StretchableLayoutResizerBar() override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** This is called when the bar is dragged.
 | 
			
		||||
@ -79,7 +79,7 @@ public:
 | 
			
		||||
    /** This abstract base class is implemented by LookAndFeel classes. */
 | 
			
		||||
    struct JUCE_API  LookAndFeelMethods
 | 
			
		||||
    {
 | 
			
		||||
        virtual ~LookAndFeelMethods() {}
 | 
			
		||||
        virtual ~LookAndFeelMethods() = default;
 | 
			
		||||
 | 
			
		||||
        virtual void drawStretchableLayoutResizerBar (Graphics&, int w, int h,
 | 
			
		||||
                                                      bool isVerticalBar, bool isMouseOver, bool isMouseDragging) = 0;
 | 
			
		||||
 | 
			
		||||
@ -39,9 +39,9 @@ int TabBarButton::getIndex() const                      { return owner.indexOfTa
 | 
			
		||||
Colour TabBarButton::getTabBackgroundColour() const     { return owner.getTabBackgroundColour (getIndex()); }
 | 
			
		||||
bool TabBarButton::isFrontTab() const                   { return getToggleState(); }
 | 
			
		||||
 | 
			
		||||
void TabBarButton::paintButton (Graphics& g, const bool isMouseOverButton, const bool isButtonDown)
 | 
			
		||||
void TabBarButton::paintButton (Graphics& g, const bool shouldDrawButtonAsHighlighted, const bool shouldDrawButtonAsDown)
 | 
			
		||||
{
 | 
			
		||||
    getLookAndFeel().drawTabButton (*this, g, isMouseOverButton, isButtonDown);
 | 
			
		||||
    getLookAndFeel().drawTabButton (*this, g, shouldDrawButtonAsHighlighted, shouldDrawButtonAsDown);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TabBarButton::clicked (const ModifierKeys& mods)
 | 
			
		||||
 | 
			
		||||
@ -49,7 +49,7 @@ public:
 | 
			
		||||
    TabBarButton (const String& name, TabbedButtonBar& ownerBar);
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~TabBarButton();
 | 
			
		||||
    ~TabBarButton() override;
 | 
			
		||||
 | 
			
		||||
    /** Returns the bar that contains this button. */
 | 
			
		||||
    TabbedButtonBar& getTabbedButtonBar() const   { return owner; }
 | 
			
		||||
@ -109,7 +109,7 @@ public:
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** @internal */
 | 
			
		||||
    void paintButton (Graphics&, bool isMouseOverButton, bool isButtonDown) override;
 | 
			
		||||
    void paintButton (Graphics&, bool, bool) override;
 | 
			
		||||
    /** @internal */
 | 
			
		||||
    void clicked (const ModifierKeys&) override;
 | 
			
		||||
    /** @internal */
 | 
			
		||||
@ -173,7 +173,7 @@ public:
 | 
			
		||||
    TabbedButtonBar (Orientation orientation);
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~TabbedButtonBar();
 | 
			
		||||
    ~TabbedButtonBar() override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Changes the bar's orientation.
 | 
			
		||||
@ -308,7 +308,7 @@ public:
 | 
			
		||||
    */
 | 
			
		||||
    struct JUCE_API  LookAndFeelMethods
 | 
			
		||||
    {
 | 
			
		||||
        virtual ~LookAndFeelMethods() {}
 | 
			
		||||
        virtual ~LookAndFeelMethods() = default;
 | 
			
		||||
 | 
			
		||||
        virtual int getTabButtonSpaceAroundImage() = 0;
 | 
			
		||||
        virtual int getTabButtonOverlap (int tabDepth) = 0;
 | 
			
		||||
@ -359,8 +359,6 @@ private:
 | 
			
		||||
    int currentTabIndex = -1;
 | 
			
		||||
 | 
			
		||||
    class BehindFrontTabComp;
 | 
			
		||||
    friend class BehindFrontTabComp;
 | 
			
		||||
    friend struct ContainerDeletePolicy<BehindFrontTabComp>;
 | 
			
		||||
    std::unique_ptr<BehindFrontTabComp> behindFrontTab;
 | 
			
		||||
    std::unique_ptr<Button> extraTabsButton;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -31,14 +31,14 @@ namespace TabbedComponentHelpers
 | 
			
		||||
{
 | 
			
		||||
    const Identifier deleteComponentId ("deleteByTabComp_");
 | 
			
		||||
 | 
			
		||||
    static void deleteIfNecessary (Component* const comp)
 | 
			
		||||
    static void deleteIfNecessary (Component* comp)
 | 
			
		||||
    {
 | 
			
		||||
        if (comp != nullptr && (bool) comp->getProperties() [deleteComponentId])
 | 
			
		||||
            delete comp;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static Rectangle<int> getTabArea (Rectangle<int>& content, BorderSize<int>& outline,
 | 
			
		||||
                                      const TabbedButtonBar::Orientation orientation, const int tabDepth)
 | 
			
		||||
                                      TabbedButtonBar::Orientation orientation, int tabDepth)
 | 
			
		||||
    {
 | 
			
		||||
        switch (orientation)
 | 
			
		||||
        {
 | 
			
		||||
@ -71,7 +71,7 @@ struct TabbedComponent::ButtonBar  : public TabbedButtonBar
 | 
			
		||||
        owner.popupMenuClickOnTab (tabIndex, tabName);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Colour getTabBackgroundColour (const int tabIndex)
 | 
			
		||||
    Colour getTabBackgroundColour (int tabIndex)
 | 
			
		||||
    {
 | 
			
		||||
        return owner.tabs->getTabBackgroundColour (tabIndex);
 | 
			
		||||
    }
 | 
			
		||||
@ -88,7 +88,7 @@ struct TabbedComponent::ButtonBar  : public TabbedButtonBar
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
TabbedComponent::TabbedComponent (const TabbedButtonBar::Orientation orientation)
 | 
			
		||||
TabbedComponent::TabbedComponent (TabbedButtonBar::Orientation orientation)
 | 
			
		||||
{
 | 
			
		||||
    tabs.reset (new ButtonBar (*this, orientation));
 | 
			
		||||
    addAndMakeVisible (tabs.get());
 | 
			
		||||
@ -101,7 +101,7 @@ TabbedComponent::~TabbedComponent()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
void TabbedComponent::setOrientation (const TabbedButtonBar::Orientation orientation)
 | 
			
		||||
void TabbedComponent::setOrientation (TabbedButtonBar::Orientation orientation)
 | 
			
		||||
{
 | 
			
		||||
    tabs->setOrientation (orientation);
 | 
			
		||||
    resized();
 | 
			
		||||
@ -112,7 +112,7 @@ TabbedButtonBar::Orientation TabbedComponent::getOrientation() const noexcept
 | 
			
		||||
    return tabs->getOrientation();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TabbedComponent::setTabBarDepth (const int newDepth)
 | 
			
		||||
void TabbedComponent::setTabBarDepth (int newDepth)
 | 
			
		||||
{
 | 
			
		||||
    if (tabDepth != newDepth)
 | 
			
		||||
    {
 | 
			
		||||
@ -121,7 +121,7 @@ void TabbedComponent::setTabBarDepth (const int newDepth)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TabBarButton* TabbedComponent::createTabButton (const String& tabName, const int /*tabIndex*/)
 | 
			
		||||
TabBarButton* TabbedComponent::createTabButton (const String& tabName, int /*tabIndex*/)
 | 
			
		||||
{
 | 
			
		||||
    return new TabBarButton (tabName, *tabs);
 | 
			
		||||
}
 | 
			
		||||
@ -132,7 +132,7 @@ void TabbedComponent::clearTabs()
 | 
			
		||||
    if (panelComponent != nullptr)
 | 
			
		||||
    {
 | 
			
		||||
        panelComponent->setVisible (false);
 | 
			
		||||
        removeChildComponent (panelComponent);
 | 
			
		||||
        removeChildComponent (panelComponent.get());
 | 
			
		||||
        panelComponent = nullptr;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -146,9 +146,9 @@ void TabbedComponent::clearTabs()
 | 
			
		||||
 | 
			
		||||
void TabbedComponent::addTab (const String& tabName,
 | 
			
		||||
                              Colour tabBackgroundColour,
 | 
			
		||||
                              Component* const contentComponent,
 | 
			
		||||
                              const bool deleteComponentWhenNotNeeded,
 | 
			
		||||
                              const int insertIndex)
 | 
			
		||||
                              Component* contentComponent,
 | 
			
		||||
                              bool deleteComponentWhenNotNeeded,
 | 
			
		||||
                              int insertIndex)
 | 
			
		||||
{
 | 
			
		||||
    contentComponents.insert (insertIndex, WeakReference<Component> (contentComponent));
 | 
			
		||||
 | 
			
		||||
@ -159,22 +159,22 @@ void TabbedComponent::addTab (const String& tabName,
 | 
			
		||||
    resized();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TabbedComponent::setTabName (const int tabIndex, const String& newName)
 | 
			
		||||
void TabbedComponent::setTabName (int tabIndex, const String& newName)
 | 
			
		||||
{
 | 
			
		||||
    tabs->setTabName (tabIndex, newName);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TabbedComponent::removeTab (const int tabIndex)
 | 
			
		||||
void TabbedComponent::removeTab (int tabIndex)
 | 
			
		||||
{
 | 
			
		||||
    if (isPositiveAndBelow (tabIndex, contentComponents.size()))
 | 
			
		||||
    {
 | 
			
		||||
        TabbedComponentHelpers::deleteIfNecessary (contentComponents.getReference (tabIndex));
 | 
			
		||||
        TabbedComponentHelpers::deleteIfNecessary (contentComponents.getReference (tabIndex).get());
 | 
			
		||||
        contentComponents.remove (tabIndex);
 | 
			
		||||
        tabs->removeTab (tabIndex);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TabbedComponent::moveTab (const int currentIndex, const int newIndex, const bool animate)
 | 
			
		||||
void TabbedComponent::moveTab (int currentIndex, int newIndex, bool animate)
 | 
			
		||||
{
 | 
			
		||||
    contentComponents.move (currentIndex, newIndex);
 | 
			
		||||
    tabs->moveTab (currentIndex, newIndex, animate);
 | 
			
		||||
@ -190,17 +190,17 @@ StringArray TabbedComponent::getTabNames() const
 | 
			
		||||
    return tabs->getTabNames();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Component* TabbedComponent::getTabContentComponent (const int tabIndex) const noexcept
 | 
			
		||||
Component* TabbedComponent::getTabContentComponent (int tabIndex) const noexcept
 | 
			
		||||
{
 | 
			
		||||
    return contentComponents [tabIndex];
 | 
			
		||||
    return contentComponents[tabIndex].get();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Colour TabbedComponent::getTabBackgroundColour (const int tabIndex) const noexcept
 | 
			
		||||
Colour TabbedComponent::getTabBackgroundColour (int tabIndex) const noexcept
 | 
			
		||||
{
 | 
			
		||||
    return tabs->getTabBackgroundColour (tabIndex);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TabbedComponent::setTabBackgroundColour (const int tabIndex, Colour newColour)
 | 
			
		||||
void TabbedComponent::setTabBackgroundColour (int tabIndex, Colour newColour)
 | 
			
		||||
{
 | 
			
		||||
    tabs->setTabBackgroundColour (tabIndex, newColour);
 | 
			
		||||
 | 
			
		||||
@ -208,7 +208,7 @@ void TabbedComponent::setTabBackgroundColour (const int tabIndex, Colour newColo
 | 
			
		||||
        repaint();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TabbedComponent::setCurrentTabIndex (const int newTabIndex, const bool sendChangeMessage)
 | 
			
		||||
void TabbedComponent::setCurrentTabIndex (int newTabIndex, bool sendChangeMessage)
 | 
			
		||||
{
 | 
			
		||||
    tabs->setCurrentTabIndex (newTabIndex, sendChangeMessage);
 | 
			
		||||
}
 | 
			
		||||
@ -223,14 +223,14 @@ String TabbedComponent::getCurrentTabName() const
 | 
			
		||||
    return tabs->getCurrentTabName();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TabbedComponent::setOutline (const int thickness)
 | 
			
		||||
void TabbedComponent::setOutline (int thickness)
 | 
			
		||||
{
 | 
			
		||||
    outlineThickness = thickness;
 | 
			
		||||
    resized();
 | 
			
		||||
    repaint();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TabbedComponent::setIndent (const int indentThickness)
 | 
			
		||||
void TabbedComponent::setIndent (int indentThickness)
 | 
			
		||||
{
 | 
			
		||||
    edgeIndent = indentThickness;
 | 
			
		||||
    resized();
 | 
			
		||||
@ -266,19 +266,19 @@ void TabbedComponent::resized()
 | 
			
		||||
    tabs->setBounds (TabbedComponentHelpers::getTabArea (content, outline, getOrientation(), tabDepth));
 | 
			
		||||
    content = BorderSize<int> (edgeIndent).subtractedFrom (outline.subtractedFrom (content));
 | 
			
		||||
 | 
			
		||||
    for (int i = contentComponents.size(); --i >= 0;)
 | 
			
		||||
        if (Component* c = contentComponents.getReference(i))
 | 
			
		||||
            c->setBounds (content);
 | 
			
		||||
    for (auto& c : contentComponents)
 | 
			
		||||
        if (auto comp = c.get())
 | 
			
		||||
            comp->setBounds (content);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TabbedComponent::lookAndFeelChanged()
 | 
			
		||||
{
 | 
			
		||||
    for (int i = contentComponents.size(); --i >= 0;)
 | 
			
		||||
        if (Component* c = contentComponents.getReference(i))
 | 
			
		||||
            c->lookAndFeelChanged();
 | 
			
		||||
    for (auto& c : contentComponents)
 | 
			
		||||
        if (auto comp = c.get())
 | 
			
		||||
          comp->lookAndFeelChanged();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TabbedComponent::changeCallback (const int newCurrentTabIndex, const String& newTabName)
 | 
			
		||||
void TabbedComponent::changeCallback (int newCurrentTabIndex, const String& newTabName)
 | 
			
		||||
{
 | 
			
		||||
    auto* newPanelComp = getTabContentComponent (getCurrentTabIndex());
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -49,7 +49,7 @@ public:
 | 
			
		||||
    explicit TabbedComponent (TabbedButtonBar::Orientation orientation);
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~TabbedComponent();
 | 
			
		||||
    ~TabbedComponent() override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Changes the placement of the tabs.
 | 
			
		||||
@ -162,7 +162,7 @@ public:
 | 
			
		||||
    /** Returns the current component that's filling the panel.
 | 
			
		||||
        This will return nullptr if there isn't one.
 | 
			
		||||
    */
 | 
			
		||||
    Component* getCurrentContentComponent() const noexcept          { return panelComponent; }
 | 
			
		||||
    Component* getCurrentContentComponent() const noexcept          { return panelComponent.get(); }
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Callback method to indicate the selected tab has been changed.
 | 
			
		||||
 | 
			
		||||
@ -37,10 +37,7 @@ Viewport::Viewport (const String& name)  : Component (name)
 | 
			
		||||
 | 
			
		||||
    setInterceptsMouseClicks (false, true);
 | 
			
		||||
    setWantsKeyboardFocus (true);
 | 
			
		||||
 | 
			
		||||
  #if JUCE_ANDROID || JUCE_IOS
 | 
			
		||||
    setScrollOnDragEnabled (true);
 | 
			
		||||
  #endif
 | 
			
		||||
    setScrollOnDragEnabled (Desktop::getInstance().getMainMouseSource().isTouch());
 | 
			
		||||
 | 
			
		||||
    recreateScrollbars();
 | 
			
		||||
}
 | 
			
		||||
@ -66,7 +63,7 @@ void Viewport::deleteOrRemoveContentComp()
 | 
			
		||||
        {
 | 
			
		||||
            // This sets the content comp to a null pointer before deleting the old one, in case
 | 
			
		||||
            // anything tries to use the old one while it's in mid-deletion..
 | 
			
		||||
            std::unique_ptr<Component> oldCompDeleter (contentComp);
 | 
			
		||||
            std::unique_ptr<Component> oldCompDeleter (contentComp.get());
 | 
			
		||||
            contentComp = nullptr;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
@ -124,7 +121,7 @@ Point<int> Viewport::viewportPosToCompPos (Point<int> pos) const
 | 
			
		||||
{
 | 
			
		||||
    jassert (contentComp != nullptr);
 | 
			
		||||
 | 
			
		||||
    auto contentBounds = contentHolder.getLocalArea (contentComp, contentComp->getLocalBounds());
 | 
			
		||||
    auto contentBounds = contentHolder.getLocalArea (contentComp.get(), contentComp->getLocalBounds());
 | 
			
		||||
 | 
			
		||||
    Point<int> p (jmax (jmin (0, contentHolder.getWidth()  - contentBounds.getWidth()),  jmin (0, -(pos.x))),
 | 
			
		||||
                  jmax (jmin (0, contentHolder.getHeight() - contentBounds.getHeight()), jmin (0, -(pos.y))));
 | 
			
		||||
@ -214,7 +211,7 @@ struct Viewport::DragToScrollListener   : private MouseListener,
 | 
			
		||||
        offsetY.behaviour.setMinimumVelocity (60);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~DragToScrollListener()
 | 
			
		||||
    ~DragToScrollListener() override
 | 
			
		||||
    {
 | 
			
		||||
        viewport.contentHolder.removeMouseListener (this);
 | 
			
		||||
        Desktop::getInstance().removeGlobalMouseListener (this);
 | 
			
		||||
@ -398,8 +395,9 @@ void Viewport::updateVisibleArea()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Rectangle<int> contentBounds;
 | 
			
		||||
    if (contentComp != nullptr)
 | 
			
		||||
        contentBounds = contentHolder.getLocalArea (contentComp, contentComp->getLocalBounds());
 | 
			
		||||
 | 
			
		||||
    if (auto cc = contentComp.get())
 | 
			
		||||
        contentBounds = contentHolder.getLocalArea (cc, cc->getLocalBounds());
 | 
			
		||||
 | 
			
		||||
    auto visibleOrigin = -contentBounds.getPosition();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -56,7 +56,7 @@ public:
 | 
			
		||||
    explicit Viewport (const String& componentName = String());
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~Viewport();
 | 
			
		||||
    ~Viewport() override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Sets the component that this viewport will contain and scroll around.
 | 
			
		||||
@ -81,7 +81,7 @@ public:
 | 
			
		||||
 | 
			
		||||
        @see setViewedComponent
 | 
			
		||||
    */
 | 
			
		||||
    Component* getViewedComponent() const noexcept                  { return contentComp; }
 | 
			
		||||
    Component* getViewedComponent() const noexcept                  { return contentComp.get(); }
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Changes the position of the viewed component.
 | 
			
		||||
@ -272,7 +272,12 @@ public:
 | 
			
		||||
    */
 | 
			
		||||
    bool canScrollHorizontally() const noexcept;
 | 
			
		||||
 | 
			
		||||
    /** Enables or disables drag-to-scroll functionality in the viewport. */
 | 
			
		||||
    /** Enables or disables drag-to-scroll functionality in the viewport.
 | 
			
		||||
 | 
			
		||||
        If your viewport contains a Component that you don't want to receive mouse events when the
 | 
			
		||||
        user is drag-scrolling, you can disable this with the Component::setViewportIgnoreDragFlag()
 | 
			
		||||
        method.
 | 
			
		||||
    */
 | 
			
		||||
    void setScrollOnDragEnabled (bool shouldScrollOnDrag);
 | 
			
		||||
 | 
			
		||||
    /** Returns true if drag-to-scroll functionality is enabled. */
 | 
			
		||||
@ -322,8 +327,6 @@ private:
 | 
			
		||||
    bool vScrollbarRight = true, hScrollbarBottom = true;
 | 
			
		||||
 | 
			
		||||
    struct DragToScrollListener;
 | 
			
		||||
    friend struct DragToScrollListener;
 | 
			
		||||
    friend struct ContainerDeletePolicy<DragToScrollListener>;
 | 
			
		||||
    std::unique_ptr<DragToScrollListener> dragToScrollListener;
 | 
			
		||||
 | 
			
		||||
    Point<int> viewportPosToCompPos (Point<int>) const;
 | 
			
		||||
 | 
			
		||||
@ -32,7 +32,7 @@ static Typeface::Ptr getTypefaceForFontFromLookAndFeel (const Font& font)
 | 
			
		||||
    return LookAndFeel::getDefaultLookAndFeel().getTypefaceForFont (font);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
typedef Typeface::Ptr (*GetTypefaceForFont) (const Font&);
 | 
			
		||||
using GetTypefaceForFont = Typeface::Ptr (*)(const Font&);
 | 
			
		||||
extern GetTypefaceForFont juce_getTypefaceForFont;
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
@ -147,7 +147,7 @@ void LookAndFeel::setDefaultSansSerifTypefaceName (const String& newName)
 | 
			
		||||
{
 | 
			
		||||
    if (defaultSans != newName)
 | 
			
		||||
    {
 | 
			
		||||
        defaultTypeface = {};
 | 
			
		||||
        defaultTypeface.reset();
 | 
			
		||||
        Typeface::clearTypefaceCache();
 | 
			
		||||
        defaultSans = newName;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -40,7 +40,7 @@ struct JUCE_API  ExtraLookAndFeelBaseClasses
 | 
			
		||||
    /** This abstract base class is implemented by LookAndFeel classes. */
 | 
			
		||||
    struct JUCE_API  LassoComponentMethods
 | 
			
		||||
    {
 | 
			
		||||
        virtual ~LassoComponentMethods() {}
 | 
			
		||||
        virtual ~LassoComponentMethods() = default;
 | 
			
		||||
 | 
			
		||||
        virtual void drawLasso (Graphics&, Component& lassoComp) = 0;
 | 
			
		||||
    };
 | 
			
		||||
@ -49,7 +49,7 @@ struct JUCE_API  ExtraLookAndFeelBaseClasses
 | 
			
		||||
    /** This abstract base class is implemented by LookAndFeel classes. */
 | 
			
		||||
    struct JUCE_API  KeyMappingEditorComponentMethods
 | 
			
		||||
    {
 | 
			
		||||
        virtual ~KeyMappingEditorComponentMethods() {}
 | 
			
		||||
        virtual ~KeyMappingEditorComponentMethods() = default;
 | 
			
		||||
 | 
			
		||||
        virtual void drawKeymapChangeButton (Graphics&, int width, int height, Button&, const String& keyDescription) = 0;
 | 
			
		||||
    };
 | 
			
		||||
@ -58,7 +58,7 @@ struct JUCE_API  ExtraLookAndFeelBaseClasses
 | 
			
		||||
    /** This abstract base class is implemented by LookAndFeel classes. */
 | 
			
		||||
    struct JUCE_API  AudioDeviceSelectorComponentMethods
 | 
			
		||||
    {
 | 
			
		||||
        virtual ~AudioDeviceSelectorComponentMethods() {}
 | 
			
		||||
        virtual ~AudioDeviceSelectorComponentMethods() = default;
 | 
			
		||||
 | 
			
		||||
        virtual void drawLevelMeter (Graphics&, int width, int height, float level) = 0;
 | 
			
		||||
    };
 | 
			
		||||
@ -113,7 +113,7 @@ public:
 | 
			
		||||
    LookAndFeel();
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    virtual ~LookAndFeel();
 | 
			
		||||
    ~LookAndFeel() override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Returns the current default look-and-feel for a component to use when it
 | 
			
		||||
 | 
			
		||||
@ -52,7 +52,7 @@ LookAndFeel_V1::~LookAndFeel_V1()
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
void LookAndFeel_V1::drawButtonBackground (Graphics& g, Button& button, const Colour& backgroundColour,
 | 
			
		||||
                                           bool isMouseOverButton, bool isButtonDown)
 | 
			
		||||
                                           bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown)
 | 
			
		||||
{
 | 
			
		||||
    const int width = button.getWidth();
 | 
			
		||||
    const int height = button.getHeight();
 | 
			
		||||
@ -69,9 +69,9 @@ void LookAndFeel_V1::drawButtonBackground (Graphics& g, Button& button, const Co
 | 
			
		||||
 | 
			
		||||
    Colour bc (backgroundColour.withMultipliedSaturation (0.3f));
 | 
			
		||||
 | 
			
		||||
    if (isMouseOverButton)
 | 
			
		||||
    if (shouldDrawButtonAsHighlighted)
 | 
			
		||||
    {
 | 
			
		||||
        if (isButtonDown)
 | 
			
		||||
        if (shouldDrawButtonAsDown)
 | 
			
		||||
            bc = bc.brighter();
 | 
			
		||||
        else if (bc.getBrightness() > 0.5f)
 | 
			
		||||
            bc = bc.darker (0.1f);
 | 
			
		||||
@ -82,21 +82,21 @@ void LookAndFeel_V1::drawButtonBackground (Graphics& g, Button& button, const Co
 | 
			
		||||
    g.setColour (bc);
 | 
			
		||||
    g.fillPath (p);
 | 
			
		||||
 | 
			
		||||
    g.setColour (bc.contrasting().withAlpha ((isMouseOverButton) ? 0.6f : 0.4f));
 | 
			
		||||
    g.strokePath (p, PathStrokeType ((isMouseOverButton) ? 2.0f : 1.4f));
 | 
			
		||||
    g.setColour (bc.contrasting().withAlpha ((shouldDrawButtonAsHighlighted) ? 0.6f : 0.4f));
 | 
			
		||||
    g.strokePath (p, PathStrokeType ((shouldDrawButtonAsHighlighted) ? 2.0f : 1.4f));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void LookAndFeel_V1::drawTickBox (Graphics& g, Component& /*component*/,
 | 
			
		||||
                                  float x, float y, float w, float h,
 | 
			
		||||
                                  const bool ticked,
 | 
			
		||||
                                  const bool isEnabled,
 | 
			
		||||
                                  const bool /*isMouseOverButton*/,
 | 
			
		||||
                                  const bool isButtonDown)
 | 
			
		||||
                                  const bool /*shouldDrawButtonAsHighlighted*/,
 | 
			
		||||
                                  const bool shouldDrawButtonAsDown)
 | 
			
		||||
{
 | 
			
		||||
    Path box;
 | 
			
		||||
    box.addRoundedRectangle (0.0f, 2.0f, 6.0f, 6.0f, 1.0f);
 | 
			
		||||
 | 
			
		||||
    g.setColour (isEnabled ? Colours::blue.withAlpha (isButtonDown ? 0.3f : 0.1f)
 | 
			
		||||
    g.setColour (isEnabled ? Colours::blue.withAlpha (shouldDrawButtonAsDown ? 0.3f : 0.1f)
 | 
			
		||||
                           : Colours::lightgrey.withAlpha (0.1f));
 | 
			
		||||
 | 
			
		||||
    AffineTransform trans (AffineTransform::scale (w / 9.0f, h / 9.0f).translated (x, y));
 | 
			
		||||
@ -118,7 +118,7 @@ void LookAndFeel_V1::drawTickBox (Graphics& g, Component& /*component*/,
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void LookAndFeel_V1::drawToggleButton (Graphics& g, ToggleButton& button, bool isMouseOverButton, bool isButtonDown)
 | 
			
		||||
void LookAndFeel_V1::drawToggleButton (Graphics& g, ToggleButton& button, bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown)
 | 
			
		||||
{
 | 
			
		||||
    if (button.hasKeyboardFocus (true))
 | 
			
		||||
    {
 | 
			
		||||
@ -132,8 +132,8 @@ void LookAndFeel_V1::drawToggleButton (Graphics& g, ToggleButton& button, bool i
 | 
			
		||||
                 (float) tickWidth, (float) tickWidth,
 | 
			
		||||
                 button.getToggleState(),
 | 
			
		||||
                 button.isEnabled(),
 | 
			
		||||
                 isMouseOverButton,
 | 
			
		||||
                 isButtonDown);
 | 
			
		||||
                 shouldDrawButtonAsHighlighted,
 | 
			
		||||
                 shouldDrawButtonAsDown);
 | 
			
		||||
 | 
			
		||||
    g.setColour (button.findColour (ToggleButton::textColourId));
 | 
			
		||||
    g.setFont (jmin (15.0f, button.getHeight() * 0.6f));
 | 
			
		||||
@ -182,8 +182,8 @@ void LookAndFeel_V1::drawProgressBar (Graphics& g, ProgressBar& progressBar,
 | 
			
		||||
void LookAndFeel_V1::drawScrollbarButton (Graphics& g, ScrollBar& bar,
 | 
			
		||||
                                          int width, int height, int buttonDirection,
 | 
			
		||||
                                          bool isScrollbarVertical,
 | 
			
		||||
                                          bool isMouseOverButton,
 | 
			
		||||
                                          bool isButtonDown)
 | 
			
		||||
                                          bool shouldDrawButtonAsHighlighted,
 | 
			
		||||
                                          bool shouldDrawButtonAsDown)
 | 
			
		||||
{
 | 
			
		||||
    if (isScrollbarVertical)
 | 
			
		||||
        width -= 2;
 | 
			
		||||
@ -209,9 +209,9 @@ void LookAndFeel_V1::drawScrollbarButton (Graphics& g, ScrollBar& bar,
 | 
			
		||||
                       width * 0.7f, height * 0.1f,
 | 
			
		||||
                       width * 0.7f, height * 0.9f);
 | 
			
		||||
 | 
			
		||||
    if (isButtonDown)
 | 
			
		||||
    if (shouldDrawButtonAsDown)
 | 
			
		||||
        g.setColour (Colours::white);
 | 
			
		||||
    else if (isMouseOverButton)
 | 
			
		||||
    else if (shouldDrawButtonAsHighlighted)
 | 
			
		||||
        g.setColour (Colours::white.withAlpha (0.7f));
 | 
			
		||||
    else
 | 
			
		||||
        g.setColour (bar.findColour (ScrollBar::thumbColourId).withAlpha (0.5f));
 | 
			
		||||
 | 
			
		||||
@ -38,16 +38,18 @@ class JUCE_API  LookAndFeel_V1    : public LookAndFeel_V2
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    LookAndFeel_V1();
 | 
			
		||||
    ~LookAndFeel_V1();
 | 
			
		||||
    ~LookAndFeel_V1() override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    void drawButtonBackground (Graphics&, Button&, const Colour& backgroundColour,
 | 
			
		||||
                               bool isMouseOverButton, bool isButtonDown) override;
 | 
			
		||||
                               bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown) override;
 | 
			
		||||
 | 
			
		||||
    void drawToggleButton (Graphics&, ToggleButton&, bool isMouseOverButton, bool isButtonDown) override;
 | 
			
		||||
    void drawToggleButton (Graphics&, ToggleButton&,
 | 
			
		||||
                           bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown) override;
 | 
			
		||||
 | 
			
		||||
    void drawTickBox (Graphics&, Component&, float x, float y, float w, float h,
 | 
			
		||||
                      bool ticked, bool isEnabled, bool isMouseOverButton, bool isButtonDown) override;
 | 
			
		||||
                      bool ticked, bool isEnabled,
 | 
			
		||||
                      bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown) override;
 | 
			
		||||
 | 
			
		||||
    void drawProgressBar (Graphics&, ProgressBar&, int width, int height,
 | 
			
		||||
                          double progress, const String& textToShow) override;
 | 
			
		||||
@ -55,7 +57,7 @@ public:
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    void drawScrollbarButton (Graphics&, ScrollBar&, int width, int height,
 | 
			
		||||
                              int buttonDirection, bool isScrollbarVertical,
 | 
			
		||||
                              bool isMouseOverButton, bool isButtonDown) override;
 | 
			
		||||
                              bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown) override;
 | 
			
		||||
 | 
			
		||||
    void drawScrollbar (Graphics&, ScrollBar&, int x, int y, int width, int height,
 | 
			
		||||
                        bool isScrollbarVertical, int thumbStartPosition, int thumbSize,
 | 
			
		||||
 | 
			
		||||
@ -31,14 +31,14 @@ namespace LookAndFeelHelpers
 | 
			
		||||
{
 | 
			
		||||
    static Colour createBaseColour (Colour buttonColour,
 | 
			
		||||
                                    bool hasKeyboardFocus,
 | 
			
		||||
                                    bool isMouseOverButton,
 | 
			
		||||
                                    bool isButtonDown) noexcept
 | 
			
		||||
                                    bool shouldDrawButtonAsHighlighted,
 | 
			
		||||
                                    bool shouldDrawButtonAsDown) noexcept
 | 
			
		||||
    {
 | 
			
		||||
        const float sat = hasKeyboardFocus ? 1.3f : 0.9f;
 | 
			
		||||
        const Colour baseColour (buttonColour.withMultipliedSaturation (sat));
 | 
			
		||||
 | 
			
		||||
        if (isButtonDown)      return baseColour.contrasting (0.2f);
 | 
			
		||||
        if (isMouseOverButton) return baseColour.contrasting (0.1f);
 | 
			
		||||
        if (shouldDrawButtonAsDown)        return baseColour.contrasting (0.2f);
 | 
			
		||||
        if (shouldDrawButtonAsHighlighted) return baseColour.contrasting (0.1f);
 | 
			
		||||
 | 
			
		||||
        return baseColour;
 | 
			
		||||
    }
 | 
			
		||||
@ -239,13 +239,13 @@ LookAndFeel_V2::~LookAndFeel_V2()  {}
 | 
			
		||||
void LookAndFeel_V2::drawButtonBackground (Graphics& g,
 | 
			
		||||
                                           Button& button,
 | 
			
		||||
                                           const Colour& backgroundColour,
 | 
			
		||||
                                           bool isMouseOverButton,
 | 
			
		||||
                                           bool isButtonDown)
 | 
			
		||||
                                           bool shouldDrawButtonAsHighlighted,
 | 
			
		||||
                                           bool shouldDrawButtonAsDown)
 | 
			
		||||
{
 | 
			
		||||
    const int width = button.getWidth();
 | 
			
		||||
    const int height = button.getHeight();
 | 
			
		||||
 | 
			
		||||
    const float outlineThickness = button.isEnabled() ? ((isButtonDown || isMouseOverButton) ? 1.2f : 0.7f) : 0.4f;
 | 
			
		||||
    const float outlineThickness = button.isEnabled() ? ((shouldDrawButtonAsDown || shouldDrawButtonAsHighlighted) ? 1.2f : 0.7f) : 0.4f;
 | 
			
		||||
    const float halfThickness = outlineThickness * 0.5f;
 | 
			
		||||
 | 
			
		||||
    const float indentL = button.isConnectedOnLeft()   ? 0.1f : halfThickness;
 | 
			
		||||
@ -255,7 +255,8 @@ void LookAndFeel_V2::drawButtonBackground (Graphics& g,
 | 
			
		||||
 | 
			
		||||
    const Colour baseColour (LookAndFeelHelpers::createBaseColour (backgroundColour,
 | 
			
		||||
                                                                   button.hasKeyboardFocus (true),
 | 
			
		||||
                                                                   isMouseOverButton, isButtonDown)
 | 
			
		||||
                                                                   shouldDrawButtonAsHighlighted,
 | 
			
		||||
                                                                   shouldDrawButtonAsDown)
 | 
			
		||||
                               .withMultipliedAlpha (button.isEnabled() ? 1.0f : 0.5f));
 | 
			
		||||
 | 
			
		||||
    drawGlassLozenge (g,
 | 
			
		||||
@ -280,7 +281,8 @@ int LookAndFeel_V2::getTextButtonWidthToFitText (TextButton& b, int buttonHeight
 | 
			
		||||
    return getTextButtonFont (b, buttonHeight).getStringWidth (b.getButtonText()) + buttonHeight;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void LookAndFeel_V2::drawButtonText (Graphics& g, TextButton& button, bool /*isMouseOverButton*/, bool /*isButtonDown*/)
 | 
			
		||||
void LookAndFeel_V2::drawButtonText (Graphics& g, TextButton& button,
 | 
			
		||||
                                     bool /*shouldDrawButtonAsHighlighted*/, bool /*shouldDrawButtonAsDown*/)
 | 
			
		||||
{
 | 
			
		||||
    Font font (getTextButtonFont (button, button.getHeight()));
 | 
			
		||||
    g.setFont (font);
 | 
			
		||||
@ -306,16 +308,16 @@ void LookAndFeel_V2::drawTickBox (Graphics& g, Component& component,
 | 
			
		||||
                                  float x, float y, float w, float h,
 | 
			
		||||
                                  const bool ticked,
 | 
			
		||||
                                  const bool isEnabled,
 | 
			
		||||
                                  const bool isMouseOverButton,
 | 
			
		||||
                                  const bool isButtonDown)
 | 
			
		||||
                                  const bool shouldDrawButtonAsHighlighted,
 | 
			
		||||
                                  const bool shouldDrawButtonAsDown)
 | 
			
		||||
{
 | 
			
		||||
    const float boxSize = w * 0.7f;
 | 
			
		||||
 | 
			
		||||
    drawGlassSphere (g, x, y + (h - boxSize) * 0.5f, boxSize,
 | 
			
		||||
                     LookAndFeelHelpers::createBaseColour (component.findColour (TextButton::buttonColourId)
 | 
			
		||||
                                                                    .withMultipliedAlpha (isEnabled ? 1.0f : 0.5f),
 | 
			
		||||
                                                           true, isMouseOverButton, isButtonDown),
 | 
			
		||||
                     isEnabled ? ((isButtonDown || isMouseOverButton) ? 1.1f : 0.5f) : 0.3f);
 | 
			
		||||
                                                           true, shouldDrawButtonAsHighlighted, shouldDrawButtonAsDown),
 | 
			
		||||
                     isEnabled ? ((shouldDrawButtonAsDown || shouldDrawButtonAsHighlighted) ? 1.1f : 0.5f) : 0.3f);
 | 
			
		||||
 | 
			
		||||
    if (ticked)
 | 
			
		||||
    {
 | 
			
		||||
@ -335,7 +337,7 @@ void LookAndFeel_V2::drawTickBox (Graphics& g, Component& component,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void LookAndFeel_V2::drawToggleButton (Graphics& g, ToggleButton& button,
 | 
			
		||||
                                       bool isMouseOverButton, bool isButtonDown)
 | 
			
		||||
                                       bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown)
 | 
			
		||||
{
 | 
			
		||||
    if (button.hasKeyboardFocus (true))
 | 
			
		||||
    {
 | 
			
		||||
@ -350,8 +352,8 @@ void LookAndFeel_V2::drawToggleButton (Graphics& g, ToggleButton& button,
 | 
			
		||||
                 tickWidth, tickWidth,
 | 
			
		||||
                 button.getToggleState(),
 | 
			
		||||
                 button.isEnabled(),
 | 
			
		||||
                 isMouseOverButton,
 | 
			
		||||
                 isButtonDown);
 | 
			
		||||
                 shouldDrawButtonAsHighlighted,
 | 
			
		||||
                 shouldDrawButtonAsDown);
 | 
			
		||||
 | 
			
		||||
    g.setColour (button.findColour (ToggleButton::textColourId));
 | 
			
		||||
    g.setFont (fontSize);
 | 
			
		||||
@ -377,7 +379,7 @@ void LookAndFeel_V2::changeToggleButtonWidthToFitText (ToggleButton& button)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void LookAndFeel_V2::drawDrawableButton (Graphics& g, DrawableButton& button,
 | 
			
		||||
                                         bool /*isMouseOverButton*/, bool /*isButtonDown*/)
 | 
			
		||||
                                         bool /*shouldDrawButtonAsHighlighted*/, bool /*shouldDrawButtonAsDown*/)
 | 
			
		||||
{
 | 
			
		||||
    bool toggleState = button.getToggleState();
 | 
			
		||||
 | 
			
		||||
@ -644,8 +646,8 @@ bool LookAndFeel_V2::areScrollbarButtonsVisible()
 | 
			
		||||
void LookAndFeel_V2::drawScrollbarButton (Graphics& g, ScrollBar& scrollbar,
 | 
			
		||||
                                          int width, int height, int buttonDirection,
 | 
			
		||||
                                          bool /*isScrollbarVertical*/,
 | 
			
		||||
                                          bool /*isMouseOverButton*/,
 | 
			
		||||
                                          bool isButtonDown)
 | 
			
		||||
                                          bool /*shouldDrawButtonAsHighlighted*/,
 | 
			
		||||
                                          bool shouldDrawButtonAsDown)
 | 
			
		||||
{
 | 
			
		||||
    Path p;
 | 
			
		||||
 | 
			
		||||
@ -666,7 +668,7 @@ void LookAndFeel_V2::drawScrollbarButton (Graphics& g, ScrollBar& scrollbar,
 | 
			
		||||
                       width * 0.7f, height * 0.1f,
 | 
			
		||||
                       width * 0.7f, height * 0.9f);
 | 
			
		||||
 | 
			
		||||
    if (isButtonDown)
 | 
			
		||||
    if (shouldDrawButtonAsDown)
 | 
			
		||||
        g.setColour (scrollbar.findColour (ScrollBar::thumbColourId).contrasting (0.2f));
 | 
			
		||||
    else
 | 
			
		||||
        g.setColour (scrollbar.findColour (ScrollBar::thumbColourId));
 | 
			
		||||
@ -1132,7 +1134,7 @@ CaretComponent* LookAndFeel_V2::createCaretComponent (Component* keyFocusOwner)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
void LookAndFeel_V2::drawComboBox (Graphics& g, int width, int height, const bool isButtonDown,
 | 
			
		||||
void LookAndFeel_V2::drawComboBox (Graphics& g, int width, int height, const bool isMouseButtonDown,
 | 
			
		||||
                                   int buttonX, int buttonY, int buttonW, int buttonH, ComboBox& box)
 | 
			
		||||
{
 | 
			
		||||
    g.fillAll (box.findColour (ComboBox::backgroundColourId));
 | 
			
		||||
@ -1148,11 +1150,11 @@ void LookAndFeel_V2::drawComboBox (Graphics& g, int width, int height, const boo
 | 
			
		||||
        g.drawRect (0, 0, width, height);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    auto outlineThickness = box.isEnabled() ? (isButtonDown ? 1.2f : 0.5f) : 0.3f;
 | 
			
		||||
    auto outlineThickness = box.isEnabled() ? (isMouseButtonDown ? 1.2f : 0.5f) : 0.3f;
 | 
			
		||||
 | 
			
		||||
    auto baseColour = LookAndFeelHelpers::createBaseColour (box.findColour (ComboBox::buttonColourId),
 | 
			
		||||
                                                            box.hasKeyboardFocus (true),
 | 
			
		||||
                                                            false, isButtonDown)
 | 
			
		||||
                                                            false, isMouseButtonDown)
 | 
			
		||||
                         .withMultipliedAlpha (box.isEnabled() ? 1.0f : 0.5f);
 | 
			
		||||
 | 
			
		||||
    drawGlassLozenge (g,
 | 
			
		||||
@ -1199,6 +1201,30 @@ void LookAndFeel_V2::positionComboBoxText (ComboBox& box, Label& label)
 | 
			
		||||
    label.setFont (getComboBoxFont (box));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PopupMenu::Options LookAndFeel_V2::getOptionsForComboBoxPopupMenu (ComboBox& box, Label& label)
 | 
			
		||||
{
 | 
			
		||||
    return PopupMenu::Options().withTargetComponent (&box)
 | 
			
		||||
                               .withItemThatMustBeVisible (box.getSelectedId())
 | 
			
		||||
                               .withMinimumWidth (box.getWidth())
 | 
			
		||||
                               .withMaximumNumColumns (1)
 | 
			
		||||
                               .withStandardItemHeight (label.getHeight());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void LookAndFeel_V2::drawComboBoxTextWhenNothingSelected (Graphics& g, ComboBox& box, Label& label)
 | 
			
		||||
{
 | 
			
		||||
    g.setColour (findColour (ComboBox::textColourId).withMultipliedAlpha (0.5f));
 | 
			
		||||
 | 
			
		||||
    auto font = label.getLookAndFeel().getLabelFont (label);
 | 
			
		||||
 | 
			
		||||
    g.setFont (font);
 | 
			
		||||
 | 
			
		||||
    auto textArea = getLabelBorderSize (label).subtractedFrom (label.getLocalBounds());
 | 
			
		||||
 | 
			
		||||
    g.drawFittedText (box.getTextWhenNothingSelected(), textArea, label.getJustificationType(),
 | 
			
		||||
                      jmax (1, (int) (textArea.getHeight() / font.getHeight())),
 | 
			
		||||
                      label.getMinimumHorizontalScale());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
Font LookAndFeel_V2::getLabelFont (Label& label)
 | 
			
		||||
{
 | 
			
		||||
@ -1217,7 +1243,7 @@ void LookAndFeel_V2::drawLabel (Graphics& g, Label& label)
 | 
			
		||||
        g.setColour (label.findColour (Label::textColourId).withMultipliedAlpha (alpha));
 | 
			
		||||
        g.setFont (font);
 | 
			
		||||
 | 
			
		||||
        Rectangle<int> textArea (label.getBorderSize().subtractedFrom (label.getLocalBounds()));
 | 
			
		||||
        auto textArea = getLabelBorderSize (label).subtractedFrom (label.getLocalBounds());
 | 
			
		||||
 | 
			
		||||
        g.drawFittedText (label.getText(), textArea, label.getJustificationType(),
 | 
			
		||||
                          jmax (1, (int) (textArea.getHeight() / font.getHeight())),
 | 
			
		||||
@ -1233,6 +1259,11 @@ void LookAndFeel_V2::drawLabel (Graphics& g, Label& label)
 | 
			
		||||
    g.drawRect (label.getLocalBounds());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
BorderSize<int> LookAndFeel_V2::getLabelBorderSize (Label& label)
 | 
			
		||||
{
 | 
			
		||||
    return label.getBorderSize();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
void LookAndFeel_V2::drawLinearSliderBackground (Graphics& g, int x, int y, int width, int height,
 | 
			
		||||
                                                 float /*sliderPos*/,
 | 
			
		||||
@ -1794,9 +1825,9 @@ public:
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    void paintButton (Graphics& g, bool isMouseOverButton, bool isButtonDown) override
 | 
			
		||||
    void paintButton (Graphics& g, bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown) override
 | 
			
		||||
    {
 | 
			
		||||
        float alpha = isMouseOverButton ? (isButtonDown ? 1.0f : 0.8f) : 0.55f;
 | 
			
		||||
        float alpha = shouldDrawButtonAsHighlighted ? (shouldDrawButtonAsDown ? 1.0f : 0.8f) : 0.55f;
 | 
			
		||||
 | 
			
		||||
        if (! isEnabled())
 | 
			
		||||
            alpha *= 0.5f;
 | 
			
		||||
@ -2624,7 +2655,7 @@ void LookAndFeel_V2::layoutFileBrowserComponent (FileBrowserComponent& browserCo
 | 
			
		||||
//==============================================================================
 | 
			
		||||
static Drawable* createDrawableFromSVG (const char* data)
 | 
			
		||||
{
 | 
			
		||||
    std::unique_ptr<XmlElement> xml (XmlDocument::parse (data));
 | 
			
		||||
    auto xml = parseXML (data);
 | 
			
		||||
    jassert (xml != nullptr);
 | 
			
		||||
    return Drawable::createFromSVG (*xml);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -39,25 +39,29 @@ class JUCE_API  LookAndFeel_V2  : public LookAndFeel
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    LookAndFeel_V2();
 | 
			
		||||
    ~LookAndFeel_V2();
 | 
			
		||||
    ~LookAndFeel_V2() override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    void drawButtonBackground (Graphics&, Button&, const Colour& backgroundColour,
 | 
			
		||||
                               bool isMouseOverButton, bool isButtonDown) override;
 | 
			
		||||
                               bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown) override;
 | 
			
		||||
    Font getTextButtonFont (TextButton&, int buttonHeight) override;
 | 
			
		||||
 | 
			
		||||
    void drawButtonText (Graphics&, TextButton&, bool isMouseOverButton, bool isButtonDown) override;
 | 
			
		||||
    void drawButtonText (Graphics&, TextButton&,
 | 
			
		||||
                         bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown) override;
 | 
			
		||||
    int getTextButtonWidthToFitText (TextButton&, int buttonHeight) override;
 | 
			
		||||
 | 
			
		||||
    void drawToggleButton (Graphics&, ToggleButton&, bool isMouseOverButton, bool isButtonDown) override;
 | 
			
		||||
    void drawToggleButton (Graphics&, ToggleButton&,
 | 
			
		||||
                           bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown) override;
 | 
			
		||||
 | 
			
		||||
    void changeToggleButtonWidthToFitText (ToggleButton&) override;
 | 
			
		||||
 | 
			
		||||
    void drawTickBox (Graphics&, Component&,
 | 
			
		||||
                      float x, float y, float w, float h,
 | 
			
		||||
                      bool ticked, bool isEnabled, bool isMouseOverButton, bool isButtonDown) override;
 | 
			
		||||
                      bool ticked, bool isEnabled,
 | 
			
		||||
                      bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown) override;
 | 
			
		||||
 | 
			
		||||
    void drawDrawableButton (Graphics&, DrawableButton&, bool isMouseOverButton, bool isButtonDown) override;
 | 
			
		||||
    void drawDrawableButton (Graphics&, DrawableButton&,
 | 
			
		||||
                             bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown) override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    AlertWindow* createAlertWindow (const String& title, const String& message,
 | 
			
		||||
@ -98,7 +102,7 @@ public:
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    bool areScrollbarButtonsVisible() override;
 | 
			
		||||
    void drawScrollbarButton (Graphics&, ScrollBar&, int width, int height, int buttonDirection,
 | 
			
		||||
                              bool isScrollbarVertical, bool isMouseOverButton, bool isButtonDown) override;
 | 
			
		||||
                              bool isScrollbarVertical, bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown) override;
 | 
			
		||||
 | 
			
		||||
    void drawScrollbar (Graphics&, ScrollBar&, int x, int y, int width, int height,
 | 
			
		||||
                        bool isScrollbarVertical, int thumbStartPosition, int thumbSize,
 | 
			
		||||
@ -187,16 +191,19 @@ public:
 | 
			
		||||
    int getPopupMenuBorderSize() override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    void drawComboBox (Graphics&, int width, int height, bool isButtonDown,
 | 
			
		||||
    void drawComboBox (Graphics&, int width, int height, bool isMouseButtonDown,
 | 
			
		||||
                       int buttonX, int buttonY, int buttonW, int buttonH,
 | 
			
		||||
                       ComboBox&) override;
 | 
			
		||||
    Font getComboBoxFont (ComboBox&) override;
 | 
			
		||||
    Label* createComboBoxTextBox (ComboBox&) override;
 | 
			
		||||
    void positionComboBoxText (ComboBox&, Label&) override;
 | 
			
		||||
    PopupMenu::Options getOptionsForComboBoxPopupMenu (ComboBox&, Label&) override;
 | 
			
		||||
    void drawComboBoxTextWhenNothingSelected (Graphics&, ComboBox&, Label&) override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    void drawLabel (Graphics&, Label&) override;
 | 
			
		||||
    Font getLabelFont (Label&) override;
 | 
			
		||||
    BorderSize<int> getLabelBorderSize (Label&) override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    void drawLinearSlider (Graphics&, int x, int y, int width, int height,
 | 
			
		||||
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user