migrating to the latest JUCE version
This commit is contained in:
		@@ -1,64 +1,64 @@
 | 
			
		||||
/*
 | 
			
		||||
  ==============================================================================
 | 
			
		||||
 | 
			
		||||
   This file is part of the JUCE library.
 | 
			
		||||
   Copyright (c) 2020 - Raw Material Software Limited
 | 
			
		||||
 | 
			
		||||
   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 6 End-User License
 | 
			
		||||
   Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
 | 
			
		||||
 | 
			
		||||
   End User License Agreement: www.juce.com/juce-6-licence
 | 
			
		||||
   Privacy Policy: www.juce.com/juce-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
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
CaretComponent::CaretComponent (Component* const keyFocusOwner)
 | 
			
		||||
    : owner (keyFocusOwner)
 | 
			
		||||
{
 | 
			
		||||
    setPaintingIsUnclipped (true);
 | 
			
		||||
    setInterceptsMouseClicks (false, false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CaretComponent::~CaretComponent()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CaretComponent::paint (Graphics& g)
 | 
			
		||||
{
 | 
			
		||||
    g.setColour (findColour (caretColourId, true));
 | 
			
		||||
    g.fillRect (getLocalBounds());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CaretComponent::timerCallback()
 | 
			
		||||
{
 | 
			
		||||
    setVisible (shouldBeShown() && ! isVisible());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CaretComponent::setCaretPosition (const Rectangle<int>& characterArea)
 | 
			
		||||
{
 | 
			
		||||
    startTimer (380);
 | 
			
		||||
    setVisible (shouldBeShown());
 | 
			
		||||
    setBounds (characterArea.withWidth (2));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool CaretComponent::shouldBeShown() const
 | 
			
		||||
{
 | 
			
		||||
    return owner == nullptr || (owner->hasKeyboardFocus (false)
 | 
			
		||||
                                 && ! owner->isCurrentlyBlockedByAnotherModalComponent());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace juce
 | 
			
		||||
/*
 | 
			
		||||
  ==============================================================================
 | 
			
		||||
 | 
			
		||||
   This file is part of the JUCE library.
 | 
			
		||||
   Copyright (c) 2022 - Raw Material Software Limited
 | 
			
		||||
 | 
			
		||||
   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 7 End-User License
 | 
			
		||||
   Agreement and JUCE Privacy Policy.
 | 
			
		||||
 | 
			
		||||
   End User License Agreement: www.juce.com/juce-7-licence
 | 
			
		||||
   Privacy Policy: www.juce.com/juce-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
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
CaretComponent::CaretComponent (Component* const keyFocusOwner)
 | 
			
		||||
    : owner (keyFocusOwner)
 | 
			
		||||
{
 | 
			
		||||
    setPaintingIsUnclipped (true);
 | 
			
		||||
    setInterceptsMouseClicks (false, false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CaretComponent::~CaretComponent()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CaretComponent::paint (Graphics& g)
 | 
			
		||||
{
 | 
			
		||||
    g.setColour (findColour (caretColourId, true));
 | 
			
		||||
    g.fillRect (getLocalBounds());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CaretComponent::timerCallback()
 | 
			
		||||
{
 | 
			
		||||
    setVisible (shouldBeShown() && ! isVisible());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CaretComponent::setCaretPosition (const Rectangle<int>& characterArea)
 | 
			
		||||
{
 | 
			
		||||
    startTimer (380);
 | 
			
		||||
    setVisible (shouldBeShown());
 | 
			
		||||
    setBounds (characterArea.withWidth (2));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool CaretComponent::shouldBeShown() const
 | 
			
		||||
{
 | 
			
		||||
    return owner == nullptr || (owner->hasKeyboardFocus (false)
 | 
			
		||||
                                 && ! owner->isCurrentlyBlockedByAnotherModalComponent());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace juce
 | 
			
		||||
 
 | 
			
		||||
@@ -1,81 +1,81 @@
 | 
			
		||||
/*
 | 
			
		||||
  ==============================================================================
 | 
			
		||||
 | 
			
		||||
   This file is part of the JUCE library.
 | 
			
		||||
   Copyright (c) 2020 - Raw Material Software Limited
 | 
			
		||||
 | 
			
		||||
   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 6 End-User License
 | 
			
		||||
   Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
 | 
			
		||||
 | 
			
		||||
   End User License Agreement: www.juce.com/juce-6-licence
 | 
			
		||||
   Privacy Policy: www.juce.com/juce-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
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
/**
 | 
			
		||||
 | 
			
		||||
    @tags{GUI}
 | 
			
		||||
*/
 | 
			
		||||
class JUCE_API  CaretComponent   : public Component,
 | 
			
		||||
                                   private Timer
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Creates the caret component.
 | 
			
		||||
        The keyFocusOwner is an optional component which the caret will check, making
 | 
			
		||||
        itself visible only when the keyFocusOwner has keyboard focus.
 | 
			
		||||
    */
 | 
			
		||||
    CaretComponent (Component* keyFocusOwner);
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~CaretComponent() override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Sets the caret's position to place it next to the given character.
 | 
			
		||||
        The area is the rectangle containing the entire character that the caret is
 | 
			
		||||
        positioned on, so by default a vertical-line caret may choose to just show itself
 | 
			
		||||
        at the left of this area. You can override this method to customise its size.
 | 
			
		||||
        This method will also force the caret to reset its timer and become visible (if
 | 
			
		||||
        appropriate), so that as it moves, you can see where it is.
 | 
			
		||||
    */
 | 
			
		||||
    virtual void setCaretPosition (const Rectangle<int>& characterArea);
 | 
			
		||||
 | 
			
		||||
    /** A set of colour IDs to use to change the colour of various aspects of the caret.
 | 
			
		||||
        These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
 | 
			
		||||
        methods.
 | 
			
		||||
        @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
 | 
			
		||||
    */
 | 
			
		||||
    enum ColourIds
 | 
			
		||||
    {
 | 
			
		||||
        caretColourId    = 0x1000204, /**< The colour with which to draw the caret. */
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** @internal */
 | 
			
		||||
    void paint (Graphics&) override;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    Component* owner;
 | 
			
		||||
 | 
			
		||||
    bool shouldBeShown() const;
 | 
			
		||||
    void timerCallback() override;
 | 
			
		||||
 | 
			
		||||
    JUCE_DECLARE_NON_COPYABLE (CaretComponent)
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace juce
 | 
			
		||||
/*
 | 
			
		||||
  ==============================================================================
 | 
			
		||||
 | 
			
		||||
   This file is part of the JUCE library.
 | 
			
		||||
   Copyright (c) 2022 - Raw Material Software Limited
 | 
			
		||||
 | 
			
		||||
   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 7 End-User License
 | 
			
		||||
   Agreement and JUCE Privacy Policy.
 | 
			
		||||
 | 
			
		||||
   End User License Agreement: www.juce.com/juce-7-licence
 | 
			
		||||
   Privacy Policy: www.juce.com/juce-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
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
/**
 | 
			
		||||
 | 
			
		||||
    @tags{GUI}
 | 
			
		||||
*/
 | 
			
		||||
class JUCE_API  CaretComponent   : public Component,
 | 
			
		||||
                                   private Timer
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Creates the caret component.
 | 
			
		||||
        The keyFocusOwner is an optional component which the caret will check, making
 | 
			
		||||
        itself visible only when the keyFocusOwner has keyboard focus.
 | 
			
		||||
    */
 | 
			
		||||
    CaretComponent (Component* keyFocusOwner);
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~CaretComponent() override;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Sets the caret's position to place it next to the given character.
 | 
			
		||||
        The area is the rectangle containing the entire character that the caret is
 | 
			
		||||
        positioned on, so by default a vertical-line caret may choose to just show itself
 | 
			
		||||
        at the left of this area. You can override this method to customise its size.
 | 
			
		||||
        This method will also force the caret to reset its timer and become visible (if
 | 
			
		||||
        appropriate), so that as it moves, you can see where it is.
 | 
			
		||||
    */
 | 
			
		||||
    virtual void setCaretPosition (const Rectangle<int>& characterArea);
 | 
			
		||||
 | 
			
		||||
    /** A set of colour IDs to use to change the colour of various aspects of the caret.
 | 
			
		||||
        These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
 | 
			
		||||
        methods.
 | 
			
		||||
        @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
 | 
			
		||||
    */
 | 
			
		||||
    enum ColourIds
 | 
			
		||||
    {
 | 
			
		||||
        caretColourId    = 0x1000204, /**< The colour with which to draw the caret. */
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** @internal */
 | 
			
		||||
    void paint (Graphics&) override;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    Component* owner;
 | 
			
		||||
 | 
			
		||||
    bool shouldBeShown() const;
 | 
			
		||||
    void timerCallback() override;
 | 
			
		||||
 | 
			
		||||
    JUCE_DECLARE_NON_COPYABLE (CaretComponent)
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace juce
 | 
			
		||||
 
 | 
			
		||||
@@ -1,34 +1,34 @@
 | 
			
		||||
/*
 | 
			
		||||
  ==============================================================================
 | 
			
		||||
 | 
			
		||||
   This file is part of the JUCE library.
 | 
			
		||||
   Copyright (c) 2020 - Raw Material Software Limited
 | 
			
		||||
 | 
			
		||||
   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 6 End-User License
 | 
			
		||||
   Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
 | 
			
		||||
 | 
			
		||||
   End User License Agreement: www.juce.com/juce-6-licence
 | 
			
		||||
   Privacy Policy: www.juce.com/juce-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
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
bool KeyListener::keyStateChanged (const bool, Component*)
 | 
			
		||||
{
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace juce
 | 
			
		||||
/*
 | 
			
		||||
  ==============================================================================
 | 
			
		||||
 | 
			
		||||
   This file is part of the JUCE library.
 | 
			
		||||
   Copyright (c) 2022 - Raw Material Software Limited
 | 
			
		||||
 | 
			
		||||
   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 7 End-User License
 | 
			
		||||
   Agreement and JUCE Privacy Policy.
 | 
			
		||||
 | 
			
		||||
   End User License Agreement: www.juce.com/juce-7-licence
 | 
			
		||||
   Privacy Policy: www.juce.com/juce-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
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
bool KeyListener::keyStateChanged (const bool, Component*)
 | 
			
		||||
{
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace juce
 | 
			
		||||
 
 | 
			
		||||
@@ -1,77 +1,77 @@
 | 
			
		||||
/*
 | 
			
		||||
  ==============================================================================
 | 
			
		||||
 | 
			
		||||
   This file is part of the JUCE library.
 | 
			
		||||
   Copyright (c) 2020 - Raw Material Software Limited
 | 
			
		||||
 | 
			
		||||
   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 6 End-User License
 | 
			
		||||
   Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
 | 
			
		||||
 | 
			
		||||
   End User License Agreement: www.juce.com/juce-6-licence
 | 
			
		||||
   Privacy Policy: www.juce.com/juce-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
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
/**
 | 
			
		||||
    Receives callbacks when keys are pressed.
 | 
			
		||||
 | 
			
		||||
    You can add a key listener to a component to be informed when that component
 | 
			
		||||
    gets key events. See the Component::addListener method for more details.
 | 
			
		||||
 | 
			
		||||
    @see KeyPress, Component::addKeyListener, KeyPressMappingSet
 | 
			
		||||
 | 
			
		||||
    @tags{GUI}
 | 
			
		||||
*/
 | 
			
		||||
class JUCE_API  KeyListener
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    virtual ~KeyListener() = default;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Called to indicate that a key has been pressed.
 | 
			
		||||
 | 
			
		||||
        If your implementation returns true, then the key event is considered to have
 | 
			
		||||
        been consumed, and will not be passed on to any other components. If it returns
 | 
			
		||||
        false, then the key will be passed to other components that might want to use it.
 | 
			
		||||
 | 
			
		||||
        @param key                      the keystroke, including modifier keys
 | 
			
		||||
        @param originatingComponent     the component that received the key event
 | 
			
		||||
        @see keyStateChanged, Component::keyPressed
 | 
			
		||||
    */
 | 
			
		||||
    virtual bool keyPressed (const KeyPress& key,
 | 
			
		||||
                             Component* originatingComponent) = 0;
 | 
			
		||||
 | 
			
		||||
    /** Called when any key is pressed or released.
 | 
			
		||||
 | 
			
		||||
        When this is called, classes that might be interested in
 | 
			
		||||
        the state of one or more keys can use KeyPress::isKeyCurrentlyDown() to
 | 
			
		||||
        check whether their key has changed.
 | 
			
		||||
 | 
			
		||||
        If your implementation returns true, then the key event is considered to have
 | 
			
		||||
        been consumed, and will not be passed on to any other components. If it returns
 | 
			
		||||
        false, then the key will be passed to other components that might want to use it.
 | 
			
		||||
 | 
			
		||||
        @param originatingComponent     the component that received the key event
 | 
			
		||||
        @param isKeyDown                true if a key is being pressed, false if one is being released
 | 
			
		||||
        @see KeyPress, Component::keyStateChanged
 | 
			
		||||
    */
 | 
			
		||||
    virtual bool keyStateChanged (bool isKeyDown, Component* originatingComponent);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace juce
 | 
			
		||||
/*
 | 
			
		||||
  ==============================================================================
 | 
			
		||||
 | 
			
		||||
   This file is part of the JUCE library.
 | 
			
		||||
   Copyright (c) 2022 - Raw Material Software Limited
 | 
			
		||||
 | 
			
		||||
   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 7 End-User License
 | 
			
		||||
   Agreement and JUCE Privacy Policy.
 | 
			
		||||
 | 
			
		||||
   End User License Agreement: www.juce.com/juce-7-licence
 | 
			
		||||
   Privacy Policy: www.juce.com/juce-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
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
/**
 | 
			
		||||
    Receives callbacks when keys are pressed.
 | 
			
		||||
 | 
			
		||||
    You can add a key listener to a component to be informed when that component
 | 
			
		||||
    gets key events. See the Component::addListener method for more details.
 | 
			
		||||
 | 
			
		||||
    @see KeyPress, Component::addKeyListener, KeyPressMappingSet
 | 
			
		||||
 | 
			
		||||
    @tags{GUI}
 | 
			
		||||
*/
 | 
			
		||||
class JUCE_API  KeyListener
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    virtual ~KeyListener() = default;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Called to indicate that a key has been pressed.
 | 
			
		||||
 | 
			
		||||
        If your implementation returns true, then the key event is considered to have
 | 
			
		||||
        been consumed, and will not be passed on to any other components. If it returns
 | 
			
		||||
        false, then the key will be passed to other components that might want to use it.
 | 
			
		||||
 | 
			
		||||
        @param key                      the keystroke, including modifier keys
 | 
			
		||||
        @param originatingComponent     the component that received the key event
 | 
			
		||||
        @see keyStateChanged, Component::keyPressed
 | 
			
		||||
    */
 | 
			
		||||
    virtual bool keyPressed (const KeyPress& key,
 | 
			
		||||
                             Component* originatingComponent) = 0;
 | 
			
		||||
 | 
			
		||||
    /** Called when any key is pressed or released.
 | 
			
		||||
 | 
			
		||||
        When this is called, classes that might be interested in
 | 
			
		||||
        the state of one or more keys can use KeyPress::isKeyCurrentlyDown() to
 | 
			
		||||
        check whether their key has changed.
 | 
			
		||||
 | 
			
		||||
        If your implementation returns true, then the key event is considered to have
 | 
			
		||||
        been consumed, and will not be passed on to any other components. If it returns
 | 
			
		||||
        false, then the key will be passed to other components that might want to use it.
 | 
			
		||||
 | 
			
		||||
        @param originatingComponent     the component that received the key event
 | 
			
		||||
        @param isKeyDown                true if a key is being pressed, false if one is being released
 | 
			
		||||
        @see KeyPress, Component::keyStateChanged
 | 
			
		||||
    */
 | 
			
		||||
    virtual bool keyStateChanged (bool isKeyDown, Component* originatingComponent);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace juce
 | 
			
		||||
 
 | 
			
		||||
@@ -1,289 +1,289 @@
 | 
			
		||||
/*
 | 
			
		||||
  ==============================================================================
 | 
			
		||||
 | 
			
		||||
   This file is part of the JUCE library.
 | 
			
		||||
   Copyright (c) 2020 - Raw Material Software Limited
 | 
			
		||||
 | 
			
		||||
   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 6 End-User License
 | 
			
		||||
   Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
 | 
			
		||||
 | 
			
		||||
   End User License Agreement: www.juce.com/juce-6-licence
 | 
			
		||||
   Privacy Policy: www.juce.com/juce-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
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
KeyPress::KeyPress (int code, ModifierKeys m, juce_wchar textChar) noexcept
 | 
			
		||||
    : keyCode (code), mods (m), textCharacter (textChar)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
KeyPress::KeyPress (const int code) noexcept  : keyCode (code)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool KeyPress::operator== (int otherKeyCode) const noexcept
 | 
			
		||||
{
 | 
			
		||||
    return keyCode == otherKeyCode && ! mods.isAnyModifierKeyDown();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool KeyPress::operator== (const KeyPress& other) const noexcept
 | 
			
		||||
{
 | 
			
		||||
    return mods.getRawFlags() == other.mods.getRawFlags()
 | 
			
		||||
            && (textCharacter == other.textCharacter
 | 
			
		||||
                 || textCharacter == 0
 | 
			
		||||
                 || other.textCharacter == 0)
 | 
			
		||||
            && (keyCode == other.keyCode
 | 
			
		||||
                 || (keyCode < 256
 | 
			
		||||
                      && other.keyCode < 256
 | 
			
		||||
                      && CharacterFunctions::toLowerCase ((juce_wchar) keyCode)
 | 
			
		||||
                           == CharacterFunctions::toLowerCase ((juce_wchar) other.keyCode)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool KeyPress::operator!= (const KeyPress& other) const noexcept    { return ! operator== (other); }
 | 
			
		||||
bool KeyPress::operator!= (int otherKeyCode) const noexcept         { return ! operator== (otherKeyCode); }
 | 
			
		||||
 | 
			
		||||
bool KeyPress::isCurrentlyDown() const
 | 
			
		||||
{
 | 
			
		||||
    return isKeyCurrentlyDown (keyCode)
 | 
			
		||||
            && (ModifierKeys::currentModifiers.getRawFlags() & ModifierKeys::allKeyboardModifiers)
 | 
			
		||||
                  == (mods.getRawFlags() & ModifierKeys::allKeyboardModifiers);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
namespace KeyPressHelpers
 | 
			
		||||
{
 | 
			
		||||
    struct KeyNameAndCode
 | 
			
		||||
    {
 | 
			
		||||
        const char* name;
 | 
			
		||||
        int code;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    const KeyNameAndCode translations[] =
 | 
			
		||||
    {
 | 
			
		||||
        { "spacebar",       KeyPress::spaceKey },
 | 
			
		||||
        { "return",         KeyPress::returnKey },
 | 
			
		||||
        { "escape",         KeyPress::escapeKey },
 | 
			
		||||
        { "backspace",      KeyPress::backspaceKey },
 | 
			
		||||
        { "cursor left",    KeyPress::leftKey },
 | 
			
		||||
        { "cursor right",   KeyPress::rightKey },
 | 
			
		||||
        { "cursor up",      KeyPress::upKey },
 | 
			
		||||
        { "cursor down",    KeyPress::downKey },
 | 
			
		||||
        { "page up",        KeyPress::pageUpKey },
 | 
			
		||||
        { "page down",      KeyPress::pageDownKey },
 | 
			
		||||
        { "home",           KeyPress::homeKey },
 | 
			
		||||
        { "end",            KeyPress::endKey },
 | 
			
		||||
        { "delete",         KeyPress::deleteKey },
 | 
			
		||||
        { "insert",         KeyPress::insertKey },
 | 
			
		||||
        { "tab",            KeyPress::tabKey },
 | 
			
		||||
        { "play",           KeyPress::playKey },
 | 
			
		||||
        { "stop",           KeyPress::stopKey },
 | 
			
		||||
        { "fast forward",   KeyPress::fastForwardKey },
 | 
			
		||||
        { "rewind",         KeyPress::rewindKey }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    struct ModifierDescription
 | 
			
		||||
    {
 | 
			
		||||
        const char* name;
 | 
			
		||||
        int flag;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    static const ModifierDescription modifierNames[] =
 | 
			
		||||
    {
 | 
			
		||||
        { "ctrl",      ModifierKeys::ctrlModifier },
 | 
			
		||||
        { "control",   ModifierKeys::ctrlModifier },
 | 
			
		||||
        { "ctl",       ModifierKeys::ctrlModifier },
 | 
			
		||||
        { "shift",     ModifierKeys::shiftModifier },
 | 
			
		||||
        { "shft",      ModifierKeys::shiftModifier },
 | 
			
		||||
        { "alt",       ModifierKeys::altModifier },
 | 
			
		||||
        { "option",    ModifierKeys::altModifier },
 | 
			
		||||
        { "command",   ModifierKeys::commandModifier },
 | 
			
		||||
        { "cmd",       ModifierKeys::commandModifier }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    static const char* numberPadPrefix() noexcept      { return "numpad "; }
 | 
			
		||||
 | 
			
		||||
    static int getNumpadKeyCode (const String& desc)
 | 
			
		||||
    {
 | 
			
		||||
        if (desc.containsIgnoreCase (numberPadPrefix()))
 | 
			
		||||
        {
 | 
			
		||||
            auto lastChar = desc.trimEnd().getLastCharacter();
 | 
			
		||||
 | 
			
		||||
            switch (lastChar)
 | 
			
		||||
            {
 | 
			
		||||
                case '0': case '1': case '2': case '3': case '4':
 | 
			
		||||
                case '5': case '6': case '7': case '8': case '9':
 | 
			
		||||
                    return (int) (KeyPress::numberPad0 + (int) lastChar - '0');
 | 
			
		||||
 | 
			
		||||
                case '+':   return KeyPress::numberPadAdd;
 | 
			
		||||
                case '-':   return KeyPress::numberPadSubtract;
 | 
			
		||||
                case '*':   return KeyPress::numberPadMultiply;
 | 
			
		||||
                case '/':   return KeyPress::numberPadDivide;
 | 
			
		||||
                case '.':   return KeyPress::numberPadDecimalPoint;
 | 
			
		||||
                case '=':   return KeyPress::numberPadEquals;
 | 
			
		||||
 | 
			
		||||
                default:    break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (desc.endsWith ("separator"))  return KeyPress::numberPadSeparator;
 | 
			
		||||
            if (desc.endsWith ("delete"))     return KeyPress::numberPadDelete;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
   #if JUCE_MAC || JUCE_IOS
 | 
			
		||||
    struct OSXSymbolReplacement
 | 
			
		||||
    {
 | 
			
		||||
        const char* text;
 | 
			
		||||
        juce_wchar symbol;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    const OSXSymbolReplacement osxSymbols[] =
 | 
			
		||||
    {
 | 
			
		||||
        { "shift + ",     0x21e7 },
 | 
			
		||||
        { "command + ",   0x2318 },
 | 
			
		||||
        { "option + ",    0x2325 },
 | 
			
		||||
        { "ctrl + ",      0x2303 },
 | 
			
		||||
        { "return",       0x21b5 },
 | 
			
		||||
        { "cursor left",  0x2190 },
 | 
			
		||||
        { "cursor right", 0x2192 },
 | 
			
		||||
        { "cursor up",    0x2191 },
 | 
			
		||||
        { "cursor down",  0x2193 },
 | 
			
		||||
        { "backspace",    0x232b },
 | 
			
		||||
        { "delete",       0x2326 },
 | 
			
		||||
        { "spacebar",     0x2423 }
 | 
			
		||||
    };
 | 
			
		||||
   #endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
KeyPress KeyPress::createFromDescription (const String& desc)
 | 
			
		||||
{
 | 
			
		||||
    int modifiers = 0;
 | 
			
		||||
 | 
			
		||||
    for (int i = 0; i < numElementsInArray (KeyPressHelpers::modifierNames); ++i)
 | 
			
		||||
        if (desc.containsWholeWordIgnoreCase (KeyPressHelpers::modifierNames[i].name))
 | 
			
		||||
            modifiers |= KeyPressHelpers::modifierNames[i].flag;
 | 
			
		||||
 | 
			
		||||
    int key = 0;
 | 
			
		||||
 | 
			
		||||
    for (int i = 0; i < numElementsInArray (KeyPressHelpers::translations); ++i)
 | 
			
		||||
    {
 | 
			
		||||
        if (desc.containsWholeWordIgnoreCase (String (KeyPressHelpers::translations[i].name)))
 | 
			
		||||
        {
 | 
			
		||||
            key = KeyPressHelpers::translations[i].code;
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (key == 0)
 | 
			
		||||
        key = KeyPressHelpers::getNumpadKeyCode (desc);
 | 
			
		||||
 | 
			
		||||
    if (key == 0)
 | 
			
		||||
    {
 | 
			
		||||
        // see if it's a function key..
 | 
			
		||||
        if (! desc.containsChar ('#')) // avoid mistaking hex-codes like "#f1"
 | 
			
		||||
        {
 | 
			
		||||
            for (int i = 1; i <= 35; ++i)
 | 
			
		||||
            {
 | 
			
		||||
                if (desc.containsWholeWordIgnoreCase ("f" + String (i)))
 | 
			
		||||
                {
 | 
			
		||||
                    if (i <= 16)        key = F1Key + i - 1;
 | 
			
		||||
                    else if (i <= 24)   key = F17Key + i - 17;
 | 
			
		||||
                    else if (i <= 35)   key = F25Key + i - 25;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (key == 0)
 | 
			
		||||
        {
 | 
			
		||||
            // give up and use the hex code..
 | 
			
		||||
            auto hexCode = desc.fromFirstOccurrenceOf ("#", false, false)
 | 
			
		||||
                               .retainCharacters ("0123456789abcdefABCDEF")
 | 
			
		||||
                               .getHexValue32();
 | 
			
		||||
 | 
			
		||||
            if (hexCode > 0)
 | 
			
		||||
                key = hexCode;
 | 
			
		||||
            else
 | 
			
		||||
                key = (int) CharacterFunctions::toUpperCase (desc.getLastCharacter());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return KeyPress (key, ModifierKeys (modifiers), 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
String KeyPress::getTextDescription() const
 | 
			
		||||
{
 | 
			
		||||
    String desc;
 | 
			
		||||
 | 
			
		||||
    if (keyCode > 0)
 | 
			
		||||
    {
 | 
			
		||||
        // some keyboard layouts use a shift-key to get the slash, but in those cases, we
 | 
			
		||||
        // want to store it as being a slash, not shift+whatever.
 | 
			
		||||
        if (textCharacter == '/' && keyCode != numberPadDivide)
 | 
			
		||||
            return "/";
 | 
			
		||||
 | 
			
		||||
        if (mods.isCtrlDown())      desc << "ctrl + ";
 | 
			
		||||
        if (mods.isShiftDown())     desc << "shift + ";
 | 
			
		||||
 | 
			
		||||
       #if JUCE_MAC || JUCE_IOS
 | 
			
		||||
        if (mods.isAltDown())       desc << "option + ";
 | 
			
		||||
        if (mods.isCommandDown())   desc << "command + ";
 | 
			
		||||
       #else
 | 
			
		||||
        if (mods.isAltDown())       desc << "alt + ";
 | 
			
		||||
       #endif
 | 
			
		||||
 | 
			
		||||
        for (int i = 0; i < numElementsInArray (KeyPressHelpers::translations); ++i)
 | 
			
		||||
            if (keyCode == KeyPressHelpers::translations[i].code)
 | 
			
		||||
                return desc + KeyPressHelpers::translations[i].name;
 | 
			
		||||
 | 
			
		||||
        // not all F keys have consecutive key codes on all platforms
 | 
			
		||||
        if      (keyCode >= F1Key  && keyCode <= F16Key)                  desc << 'F' << (1 + keyCode - F1Key);
 | 
			
		||||
        else if (keyCode >= F17Key && keyCode <= F24Key)                  desc << 'F' << (17 + keyCode - F17Key);
 | 
			
		||||
        else if (keyCode >= F25Key && keyCode <= F35Key)                  desc << 'F' << (25 + keyCode - F25Key);
 | 
			
		||||
        else if (keyCode >= numberPad0 && keyCode <= numberPad9)    desc << KeyPressHelpers::numberPadPrefix() << (keyCode - numberPad0);
 | 
			
		||||
        else if (keyCode >= 33 && keyCode < 176)        desc += CharacterFunctions::toUpperCase ((juce_wchar) keyCode);
 | 
			
		||||
        else if (keyCode == numberPadAdd)               desc << KeyPressHelpers::numberPadPrefix() << '+';
 | 
			
		||||
        else if (keyCode == numberPadSubtract)          desc << KeyPressHelpers::numberPadPrefix() << '-';
 | 
			
		||||
        else if (keyCode == numberPadMultiply)          desc << KeyPressHelpers::numberPadPrefix() << '*';
 | 
			
		||||
        else if (keyCode == numberPadDivide)            desc << KeyPressHelpers::numberPadPrefix() << '/';
 | 
			
		||||
        else if (keyCode == numberPadSeparator)         desc << KeyPressHelpers::numberPadPrefix() << "separator";
 | 
			
		||||
        else if (keyCode == numberPadDecimalPoint)      desc << KeyPressHelpers::numberPadPrefix() << '.';
 | 
			
		||||
        else if (keyCode == numberPadEquals)            desc << KeyPressHelpers::numberPadPrefix() << '=';
 | 
			
		||||
        else if (keyCode == numberPadDelete)            desc << KeyPressHelpers::numberPadPrefix() << "delete";
 | 
			
		||||
        else                                            desc << '#' << String::toHexString (keyCode);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return desc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
String KeyPress::getTextDescriptionWithIcons() const
 | 
			
		||||
{
 | 
			
		||||
   #if JUCE_MAC || JUCE_IOS
 | 
			
		||||
    auto s = getTextDescription();
 | 
			
		||||
 | 
			
		||||
    for (int i = 0; i < numElementsInArray (KeyPressHelpers::osxSymbols); ++i)
 | 
			
		||||
        s = s.replace (KeyPressHelpers::osxSymbols[i].text,
 | 
			
		||||
                       String::charToString (KeyPressHelpers::osxSymbols[i].symbol));
 | 
			
		||||
 | 
			
		||||
    return s;
 | 
			
		||||
   #else
 | 
			
		||||
    return getTextDescription();
 | 
			
		||||
   #endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace juce
 | 
			
		||||
/*
 | 
			
		||||
  ==============================================================================
 | 
			
		||||
 | 
			
		||||
   This file is part of the JUCE library.
 | 
			
		||||
   Copyright (c) 2022 - Raw Material Software Limited
 | 
			
		||||
 | 
			
		||||
   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 7 End-User License
 | 
			
		||||
   Agreement and JUCE Privacy Policy.
 | 
			
		||||
 | 
			
		||||
   End User License Agreement: www.juce.com/juce-7-licence
 | 
			
		||||
   Privacy Policy: www.juce.com/juce-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
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
KeyPress::KeyPress (int code, ModifierKeys m, juce_wchar textChar) noexcept
 | 
			
		||||
    : keyCode (code), mods (m), textCharacter (textChar)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
KeyPress::KeyPress (const int code) noexcept  : keyCode (code)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool KeyPress::operator== (int otherKeyCode) const noexcept
 | 
			
		||||
{
 | 
			
		||||
    return keyCode == otherKeyCode && ! mods.isAnyModifierKeyDown();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool KeyPress::operator== (const KeyPress& other) const noexcept
 | 
			
		||||
{
 | 
			
		||||
    return mods.getRawFlags() == other.mods.getRawFlags()
 | 
			
		||||
            && (textCharacter == other.textCharacter
 | 
			
		||||
                 || textCharacter == 0
 | 
			
		||||
                 || other.textCharacter == 0)
 | 
			
		||||
            && (keyCode == other.keyCode
 | 
			
		||||
                 || (keyCode < 256
 | 
			
		||||
                      && other.keyCode < 256
 | 
			
		||||
                      && CharacterFunctions::toLowerCase ((juce_wchar) keyCode)
 | 
			
		||||
                           == CharacterFunctions::toLowerCase ((juce_wchar) other.keyCode)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool KeyPress::operator!= (const KeyPress& other) const noexcept    { return ! operator== (other); }
 | 
			
		||||
bool KeyPress::operator!= (int otherKeyCode) const noexcept         { return ! operator== (otherKeyCode); }
 | 
			
		||||
 | 
			
		||||
bool KeyPress::isCurrentlyDown() const
 | 
			
		||||
{
 | 
			
		||||
    return isKeyCurrentlyDown (keyCode)
 | 
			
		||||
            && (ModifierKeys::currentModifiers.getRawFlags() & ModifierKeys::allKeyboardModifiers)
 | 
			
		||||
                  == (mods.getRawFlags() & ModifierKeys::allKeyboardModifiers);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
namespace KeyPressHelpers
 | 
			
		||||
{
 | 
			
		||||
    struct KeyNameAndCode
 | 
			
		||||
    {
 | 
			
		||||
        const char* name;
 | 
			
		||||
        int code;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    const KeyNameAndCode translations[] =
 | 
			
		||||
    {
 | 
			
		||||
        { "spacebar",       KeyPress::spaceKey },
 | 
			
		||||
        { "return",         KeyPress::returnKey },
 | 
			
		||||
        { "escape",         KeyPress::escapeKey },
 | 
			
		||||
        { "backspace",      KeyPress::backspaceKey },
 | 
			
		||||
        { "cursor left",    KeyPress::leftKey },
 | 
			
		||||
        { "cursor right",   KeyPress::rightKey },
 | 
			
		||||
        { "cursor up",      KeyPress::upKey },
 | 
			
		||||
        { "cursor down",    KeyPress::downKey },
 | 
			
		||||
        { "page up",        KeyPress::pageUpKey },
 | 
			
		||||
        { "page down",      KeyPress::pageDownKey },
 | 
			
		||||
        { "home",           KeyPress::homeKey },
 | 
			
		||||
        { "end",            KeyPress::endKey },
 | 
			
		||||
        { "delete",         KeyPress::deleteKey },
 | 
			
		||||
        { "insert",         KeyPress::insertKey },
 | 
			
		||||
        { "tab",            KeyPress::tabKey },
 | 
			
		||||
        { "play",           KeyPress::playKey },
 | 
			
		||||
        { "stop",           KeyPress::stopKey },
 | 
			
		||||
        { "fast forward",   KeyPress::fastForwardKey },
 | 
			
		||||
        { "rewind",         KeyPress::rewindKey }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    struct ModifierDescription
 | 
			
		||||
    {
 | 
			
		||||
        const char* name;
 | 
			
		||||
        int flag;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    static const ModifierDescription modifierNames[] =
 | 
			
		||||
    {
 | 
			
		||||
        { "ctrl",      ModifierKeys::ctrlModifier },
 | 
			
		||||
        { "control",   ModifierKeys::ctrlModifier },
 | 
			
		||||
        { "ctl",       ModifierKeys::ctrlModifier },
 | 
			
		||||
        { "shift",     ModifierKeys::shiftModifier },
 | 
			
		||||
        { "shft",      ModifierKeys::shiftModifier },
 | 
			
		||||
        { "alt",       ModifierKeys::altModifier },
 | 
			
		||||
        { "option",    ModifierKeys::altModifier },
 | 
			
		||||
        { "command",   ModifierKeys::commandModifier },
 | 
			
		||||
        { "cmd",       ModifierKeys::commandModifier }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    static const char* numberPadPrefix() noexcept      { return "numpad "; }
 | 
			
		||||
 | 
			
		||||
    static int getNumpadKeyCode (const String& desc)
 | 
			
		||||
    {
 | 
			
		||||
        if (desc.containsIgnoreCase (numberPadPrefix()))
 | 
			
		||||
        {
 | 
			
		||||
            auto lastChar = desc.trimEnd().getLastCharacter();
 | 
			
		||||
 | 
			
		||||
            switch (lastChar)
 | 
			
		||||
            {
 | 
			
		||||
                case '0': case '1': case '2': case '3': case '4':
 | 
			
		||||
                case '5': case '6': case '7': case '8': case '9':
 | 
			
		||||
                    return (int) (KeyPress::numberPad0 + (int) lastChar - '0');
 | 
			
		||||
 | 
			
		||||
                case '+':   return KeyPress::numberPadAdd;
 | 
			
		||||
                case '-':   return KeyPress::numberPadSubtract;
 | 
			
		||||
                case '*':   return KeyPress::numberPadMultiply;
 | 
			
		||||
                case '/':   return KeyPress::numberPadDivide;
 | 
			
		||||
                case '.':   return KeyPress::numberPadDecimalPoint;
 | 
			
		||||
                case '=':   return KeyPress::numberPadEquals;
 | 
			
		||||
 | 
			
		||||
                default:    break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (desc.endsWith ("separator"))  return KeyPress::numberPadSeparator;
 | 
			
		||||
            if (desc.endsWith ("delete"))     return KeyPress::numberPadDelete;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
   #if JUCE_MAC || JUCE_IOS
 | 
			
		||||
    struct OSXSymbolReplacement
 | 
			
		||||
    {
 | 
			
		||||
        const char* text;
 | 
			
		||||
        juce_wchar symbol;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    const OSXSymbolReplacement osxSymbols[] =
 | 
			
		||||
    {
 | 
			
		||||
        { "shift + ",     0x21e7 },
 | 
			
		||||
        { "command + ",   0x2318 },
 | 
			
		||||
        { "option + ",    0x2325 },
 | 
			
		||||
        { "ctrl + ",      0x2303 },
 | 
			
		||||
        { "return",       0x21b5 },
 | 
			
		||||
        { "cursor left",  0x2190 },
 | 
			
		||||
        { "cursor right", 0x2192 },
 | 
			
		||||
        { "cursor up",    0x2191 },
 | 
			
		||||
        { "cursor down",  0x2193 },
 | 
			
		||||
        { "backspace",    0x232b },
 | 
			
		||||
        { "delete",       0x2326 },
 | 
			
		||||
        { "spacebar",     0x2423 }
 | 
			
		||||
    };
 | 
			
		||||
   #endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
KeyPress KeyPress::createFromDescription (const String& desc)
 | 
			
		||||
{
 | 
			
		||||
    int modifiers = 0;
 | 
			
		||||
 | 
			
		||||
    for (int i = 0; i < numElementsInArray (KeyPressHelpers::modifierNames); ++i)
 | 
			
		||||
        if (desc.containsWholeWordIgnoreCase (KeyPressHelpers::modifierNames[i].name))
 | 
			
		||||
            modifiers |= KeyPressHelpers::modifierNames[i].flag;
 | 
			
		||||
 | 
			
		||||
    int key = 0;
 | 
			
		||||
 | 
			
		||||
    for (int i = 0; i < numElementsInArray (KeyPressHelpers::translations); ++i)
 | 
			
		||||
    {
 | 
			
		||||
        if (desc.containsWholeWordIgnoreCase (String (KeyPressHelpers::translations[i].name)))
 | 
			
		||||
        {
 | 
			
		||||
            key = KeyPressHelpers::translations[i].code;
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (key == 0)
 | 
			
		||||
        key = KeyPressHelpers::getNumpadKeyCode (desc);
 | 
			
		||||
 | 
			
		||||
    if (key == 0)
 | 
			
		||||
    {
 | 
			
		||||
        // see if it's a function key..
 | 
			
		||||
        if (! desc.containsChar ('#')) // avoid mistaking hex-codes like "#f1"
 | 
			
		||||
        {
 | 
			
		||||
            for (int i = 1; i <= 35; ++i)
 | 
			
		||||
            {
 | 
			
		||||
                if (desc.containsWholeWordIgnoreCase ("f" + String (i)))
 | 
			
		||||
                {
 | 
			
		||||
                    if (i <= 16)        key = F1Key + i - 1;
 | 
			
		||||
                    else if (i <= 24)   key = F17Key + i - 17;
 | 
			
		||||
                    else if (i <= 35)   key = F25Key + i - 25;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (key == 0)
 | 
			
		||||
        {
 | 
			
		||||
            // give up and use the hex code..
 | 
			
		||||
            auto hexCode = desc.fromFirstOccurrenceOf ("#", false, false)
 | 
			
		||||
                               .retainCharacters ("0123456789abcdefABCDEF")
 | 
			
		||||
                               .getHexValue32();
 | 
			
		||||
 | 
			
		||||
            if (hexCode > 0)
 | 
			
		||||
                key = hexCode;
 | 
			
		||||
            else
 | 
			
		||||
                key = (int) CharacterFunctions::toUpperCase (desc.getLastCharacter());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return KeyPress (key, ModifierKeys (modifiers), 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
String KeyPress::getTextDescription() const
 | 
			
		||||
{
 | 
			
		||||
    String desc;
 | 
			
		||||
 | 
			
		||||
    if (keyCode > 0)
 | 
			
		||||
    {
 | 
			
		||||
        // some keyboard layouts use a shift-key to get the slash, but in those cases, we
 | 
			
		||||
        // want to store it as being a slash, not shift+whatever.
 | 
			
		||||
        if (textCharacter == '/' && keyCode != numberPadDivide)
 | 
			
		||||
            return "/";
 | 
			
		||||
 | 
			
		||||
        if (mods.isCtrlDown())      desc << "ctrl + ";
 | 
			
		||||
        if (mods.isShiftDown())     desc << "shift + ";
 | 
			
		||||
 | 
			
		||||
       #if JUCE_MAC || JUCE_IOS
 | 
			
		||||
        if (mods.isAltDown())       desc << "option + ";
 | 
			
		||||
        if (mods.isCommandDown())   desc << "command + ";
 | 
			
		||||
       #else
 | 
			
		||||
        if (mods.isAltDown())       desc << "alt + ";
 | 
			
		||||
       #endif
 | 
			
		||||
 | 
			
		||||
        for (int i = 0; i < numElementsInArray (KeyPressHelpers::translations); ++i)
 | 
			
		||||
            if (keyCode == KeyPressHelpers::translations[i].code)
 | 
			
		||||
                return desc + KeyPressHelpers::translations[i].name;
 | 
			
		||||
 | 
			
		||||
        // not all F keys have consecutive key codes on all platforms
 | 
			
		||||
        if      (keyCode >= F1Key  && keyCode <= F16Key)                  desc << 'F' << (1 + keyCode - F1Key);
 | 
			
		||||
        else if (keyCode >= F17Key && keyCode <= F24Key)                  desc << 'F' << (17 + keyCode - F17Key);
 | 
			
		||||
        else if (keyCode >= F25Key && keyCode <= F35Key)                  desc << 'F' << (25 + keyCode - F25Key);
 | 
			
		||||
        else if (keyCode >= numberPad0 && keyCode <= numberPad9)    desc << KeyPressHelpers::numberPadPrefix() << (keyCode - numberPad0);
 | 
			
		||||
        else if (keyCode >= 33 && keyCode < 176)        desc += CharacterFunctions::toUpperCase ((juce_wchar) keyCode);
 | 
			
		||||
        else if (keyCode == numberPadAdd)               desc << KeyPressHelpers::numberPadPrefix() << '+';
 | 
			
		||||
        else if (keyCode == numberPadSubtract)          desc << KeyPressHelpers::numberPadPrefix() << '-';
 | 
			
		||||
        else if (keyCode == numberPadMultiply)          desc << KeyPressHelpers::numberPadPrefix() << '*';
 | 
			
		||||
        else if (keyCode == numberPadDivide)            desc << KeyPressHelpers::numberPadPrefix() << '/';
 | 
			
		||||
        else if (keyCode == numberPadSeparator)         desc << KeyPressHelpers::numberPadPrefix() << "separator";
 | 
			
		||||
        else if (keyCode == numberPadDecimalPoint)      desc << KeyPressHelpers::numberPadPrefix() << '.';
 | 
			
		||||
        else if (keyCode == numberPadEquals)            desc << KeyPressHelpers::numberPadPrefix() << '=';
 | 
			
		||||
        else if (keyCode == numberPadDelete)            desc << KeyPressHelpers::numberPadPrefix() << "delete";
 | 
			
		||||
        else                                            desc << '#' << String::toHexString (keyCode);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return desc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
String KeyPress::getTextDescriptionWithIcons() const
 | 
			
		||||
{
 | 
			
		||||
   #if JUCE_MAC || JUCE_IOS
 | 
			
		||||
    auto s = getTextDescription();
 | 
			
		||||
 | 
			
		||||
    for (int i = 0; i < numElementsInArray (KeyPressHelpers::osxSymbols); ++i)
 | 
			
		||||
        s = s.replace (KeyPressHelpers::osxSymbols[i].text,
 | 
			
		||||
                       String::charToString (KeyPressHelpers::osxSymbols[i].symbol));
 | 
			
		||||
 | 
			
		||||
    return s;
 | 
			
		||||
   #else
 | 
			
		||||
    return getTextDescription();
 | 
			
		||||
   #endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace juce
 | 
			
		||||
 
 | 
			
		||||
@@ -1,277 +1,277 @@
 | 
			
		||||
/*
 | 
			
		||||
  ==============================================================================
 | 
			
		||||
 | 
			
		||||
   This file is part of the JUCE library.
 | 
			
		||||
   Copyright (c) 2020 - Raw Material Software Limited
 | 
			
		||||
 | 
			
		||||
   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 6 End-User License
 | 
			
		||||
   Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
 | 
			
		||||
 | 
			
		||||
   End User License Agreement: www.juce.com/juce-6-licence
 | 
			
		||||
   Privacy Policy: www.juce.com/juce-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
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
/**
 | 
			
		||||
    Represents a key press, including any modifier keys that are needed.
 | 
			
		||||
 | 
			
		||||
    E.g. a KeyPress might represent CTRL+C, SHIFT+ALT+H, Spacebar, Escape, etc.
 | 
			
		||||
 | 
			
		||||
    @see Component, KeyListener, KeyPressMappingSet, Button::addShortcut
 | 
			
		||||
 | 
			
		||||
    @tags{GUI}
 | 
			
		||||
*/
 | 
			
		||||
class JUCE_API  KeyPress
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Creates an (invalid) KeyPress.
 | 
			
		||||
 | 
			
		||||
        @see isValid
 | 
			
		||||
    */
 | 
			
		||||
    KeyPress() = default;
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~KeyPress() = default;
 | 
			
		||||
 | 
			
		||||
    /** Creates a KeyPress for a key and some modifiers.
 | 
			
		||||
 | 
			
		||||
        e.g.
 | 
			
		||||
        CTRL+C would be: KeyPress ('c', ModifierKeys::ctrlModifier, 0)
 | 
			
		||||
        SHIFT+Escape would be: KeyPress (KeyPress::escapeKey, ModifierKeys::shiftModifier, 0)
 | 
			
		||||
 | 
			
		||||
        @param keyCode      a code that represents the key - this value must be
 | 
			
		||||
                            one of special constants listed in this class, or an
 | 
			
		||||
                            8-bit character code such as a letter (case is ignored),
 | 
			
		||||
                            digit or a simple key like "," or ".". Note that this
 | 
			
		||||
                            isn't the same as the textCharacter parameter, so for example
 | 
			
		||||
                            a keyCode of 'a' and a shift-key modifier should have a
 | 
			
		||||
                            textCharacter value of 'A'.
 | 
			
		||||
        @param modifiers    the modifiers to associate with the keystroke
 | 
			
		||||
        @param textCharacter    the character that would be printed if someone typed
 | 
			
		||||
                            this keypress into a text editor. This value may be
 | 
			
		||||
                            null if the keypress is a non-printing character
 | 
			
		||||
        @see getKeyCode, isKeyCode, getModifiers
 | 
			
		||||
    */
 | 
			
		||||
    KeyPress (int keyCode,
 | 
			
		||||
              ModifierKeys modifiers,
 | 
			
		||||
              juce_wchar textCharacter) noexcept;
 | 
			
		||||
 | 
			
		||||
    /** Creates a keypress with a keyCode but no modifiers or text character. */
 | 
			
		||||
    explicit KeyPress (int keyCode) noexcept;
 | 
			
		||||
 | 
			
		||||
    /** Creates a copy of another KeyPress. */
 | 
			
		||||
    KeyPress (const KeyPress&) = default;
 | 
			
		||||
 | 
			
		||||
    /** Copies this KeyPress from another one. */
 | 
			
		||||
    KeyPress& operator= (const KeyPress&) = default;
 | 
			
		||||
 | 
			
		||||
    /** Compares two KeyPress objects. */
 | 
			
		||||
    bool operator== (const KeyPress& other) const noexcept;
 | 
			
		||||
 | 
			
		||||
    /** Compares two KeyPress objects. */
 | 
			
		||||
    bool operator!= (const KeyPress& other) const noexcept;
 | 
			
		||||
 | 
			
		||||
    /** Returns true if this keypress is for the given keycode without any modifiers. */
 | 
			
		||||
    bool operator== (int keyCode) const noexcept;
 | 
			
		||||
 | 
			
		||||
    /** Returns true if this keypress is not for the given keycode without any modifiers. */
 | 
			
		||||
    bool operator!= (int keyCode) const noexcept;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Returns true if this is a valid KeyPress.
 | 
			
		||||
 | 
			
		||||
        A null keypress can be created by the default constructor, in case it's
 | 
			
		||||
        needed.
 | 
			
		||||
    */
 | 
			
		||||
    bool isValid() const noexcept                               { return keyCode != 0; }
 | 
			
		||||
 | 
			
		||||
    /** Returns the key code itself.
 | 
			
		||||
 | 
			
		||||
        This will either be one of the special constants defined in this class,
 | 
			
		||||
        or an 8-bit character code.
 | 
			
		||||
    */
 | 
			
		||||
    int getKeyCode() const noexcept                             { return keyCode; }
 | 
			
		||||
 | 
			
		||||
    /** Returns the key modifiers.
 | 
			
		||||
 | 
			
		||||
        @see ModifierKeys
 | 
			
		||||
    */
 | 
			
		||||
    ModifierKeys getModifiers() const noexcept                  { return mods; }
 | 
			
		||||
 | 
			
		||||
    /** Returns the character that is associated with this keypress.
 | 
			
		||||
 | 
			
		||||
        This is the character that you'd expect to see printed if you press this
 | 
			
		||||
        keypress in a text editor or similar component.
 | 
			
		||||
    */
 | 
			
		||||
    juce_wchar getTextCharacter() const noexcept                { return textCharacter; }
 | 
			
		||||
 | 
			
		||||
    /** Checks whether the KeyPress's key is the same as the one provided, without checking
 | 
			
		||||
        the modifiers.
 | 
			
		||||
 | 
			
		||||
        The values for key codes can either be one of the special constants defined in
 | 
			
		||||
        this class, or an 8-bit character code.
 | 
			
		||||
 | 
			
		||||
        @see getKeyCode
 | 
			
		||||
    */
 | 
			
		||||
    bool isKeyCode (int keyCodeToCompare) const noexcept        { return keyCode == keyCodeToCompare; }
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Converts a textual key description to a KeyPress.
 | 
			
		||||
 | 
			
		||||
        This attempts to decode a textual version of a keypress, e.g. "ctrl + c" or "spacebar".
 | 
			
		||||
 | 
			
		||||
        This isn't designed to cope with any kind of input, but should be given the
 | 
			
		||||
        strings that are created by the getTextDescription() method.
 | 
			
		||||
 | 
			
		||||
        If the string can't be parsed, the object returned will be invalid.
 | 
			
		||||
 | 
			
		||||
        @see getTextDescription
 | 
			
		||||
    */
 | 
			
		||||
    static KeyPress createFromDescription (const String& textVersion);
 | 
			
		||||
 | 
			
		||||
    /** Creates a textual description of the key combination.
 | 
			
		||||
 | 
			
		||||
        e.g. "ctrl + c" or "delete".
 | 
			
		||||
 | 
			
		||||
        To store a keypress in a file, use this method, along with createFromDescription()
 | 
			
		||||
        to retrieve it later.
 | 
			
		||||
    */
 | 
			
		||||
    String getTextDescription() const;
 | 
			
		||||
 | 
			
		||||
    /** Creates a textual description of the key combination, using unicode icon symbols if possible.
 | 
			
		||||
 | 
			
		||||
        On OSX, this uses the Apple symbols for command, option, shift, etc, instead of the textual
 | 
			
		||||
        modifier key descriptions that are returned by getTextDescription()
 | 
			
		||||
    */
 | 
			
		||||
    String getTextDescriptionWithIcons() const;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Checks whether the user is currently holding down the keys that make up this
 | 
			
		||||
        KeyPress.
 | 
			
		||||
 | 
			
		||||
        Note that this will return false if any extra modifier keys are
 | 
			
		||||
        down - e.g. if the keypress is CTRL+X and the user is actually holding CTRL+ALT+x
 | 
			
		||||
        then it will be false.
 | 
			
		||||
    */
 | 
			
		||||
    bool isCurrentlyDown() const;
 | 
			
		||||
 | 
			
		||||
    /** Checks whether a particular key is held down, irrespective of modifiers.
 | 
			
		||||
 | 
			
		||||
        The values for key codes can either be one of the special constants defined in
 | 
			
		||||
        this class, or an 8-bit character code.
 | 
			
		||||
    */
 | 
			
		||||
    static bool isKeyCurrentlyDown (int keyCode);
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    // Key codes
 | 
			
		||||
    //
 | 
			
		||||
    // Note that the actual values of these are platform-specific and may change
 | 
			
		||||
    // without warning, so don't store them anywhere as constants. For persisting/retrieving
 | 
			
		||||
    // KeyPress objects, use getTextDescription() and createFromDescription() instead.
 | 
			
		||||
    //
 | 
			
		||||
 | 
			
		||||
    static const int spaceKey;      /**< key-code for the space bar */
 | 
			
		||||
    static const int escapeKey;     /**< key-code for the escape key */
 | 
			
		||||
    static const int returnKey;     /**< key-code for the return key*/
 | 
			
		||||
    static const int tabKey;        /**< key-code for the tab key*/
 | 
			
		||||
 | 
			
		||||
    static const int deleteKey;     /**< key-code for the delete key (not backspace) */
 | 
			
		||||
    static const int backspaceKey;  /**< key-code for the backspace key */
 | 
			
		||||
    static const int insertKey;     /**< key-code for the insert key */
 | 
			
		||||
 | 
			
		||||
    static const int upKey;         /**< key-code for the cursor-up key */
 | 
			
		||||
    static const int downKey;       /**< key-code for the cursor-down key */
 | 
			
		||||
    static const int leftKey;       /**< key-code for the cursor-left key */
 | 
			
		||||
    static const int rightKey;      /**< key-code for the cursor-right key */
 | 
			
		||||
    static const int pageUpKey;     /**< key-code for the page-up key */
 | 
			
		||||
    static const int pageDownKey;   /**< key-code for the page-down key */
 | 
			
		||||
    static const int homeKey;       /**< key-code for the home key */
 | 
			
		||||
    static const int endKey;        /**< key-code for the end key */
 | 
			
		||||
 | 
			
		||||
    static const int F1Key;         /**< key-code for the F1 key */
 | 
			
		||||
    static const int F2Key;         /**< key-code for the F2 key */
 | 
			
		||||
    static const int F3Key;         /**< key-code for the F3 key */
 | 
			
		||||
    static const int F4Key;         /**< key-code for the F4 key */
 | 
			
		||||
    static const int F5Key;         /**< key-code for the F5 key */
 | 
			
		||||
    static const int F6Key;         /**< key-code for the F6 key */
 | 
			
		||||
    static const int F7Key;         /**< key-code for the F7 key */
 | 
			
		||||
    static const int F8Key;         /**< key-code for the F8 key */
 | 
			
		||||
    static const int F9Key;         /**< key-code for the F9 key */
 | 
			
		||||
    static const int F10Key;        /**< key-code for the F10 key */
 | 
			
		||||
    static const int F11Key;        /**< key-code for the F11 key */
 | 
			
		||||
    static const int F12Key;        /**< key-code for the F12 key */
 | 
			
		||||
    static const int F13Key;        /**< key-code for the F13 key */
 | 
			
		||||
    static const int F14Key;        /**< key-code for the F14 key */
 | 
			
		||||
    static const int F15Key;        /**< key-code for the F15 key */
 | 
			
		||||
    static const int F16Key;        /**< key-code for the F16 key */
 | 
			
		||||
    static const int F17Key;        /**< key-code for the F17 key */
 | 
			
		||||
    static const int F18Key;        /**< key-code for the F18 key */
 | 
			
		||||
    static const int F19Key;        /**< key-code for the F19 key */
 | 
			
		||||
    static const int F20Key;        /**< key-code for the F20 key */
 | 
			
		||||
    static const int F21Key;        /**< key-code for the F21 key */
 | 
			
		||||
    static const int F22Key;        /**< key-code for the F22 key */
 | 
			
		||||
    static const int F23Key;        /**< key-code for the F23 key */
 | 
			
		||||
    static const int F24Key;        /**< key-code for the F24 key */
 | 
			
		||||
    static const int F25Key;        /**< key-code for the F25 key */
 | 
			
		||||
    static const int F26Key;        /**< key-code for the F26 key */
 | 
			
		||||
    static const int F27Key;        /**< key-code for the F27 key */
 | 
			
		||||
    static const int F28Key;        /**< key-code for the F28 key */
 | 
			
		||||
    static const int F29Key;        /**< key-code for the F29 key */
 | 
			
		||||
    static const int F30Key;        /**< key-code for the F30 key */
 | 
			
		||||
    static const int F31Key;        /**< key-code for the F31 key */
 | 
			
		||||
    static const int F32Key;        /**< key-code for the F32 key */
 | 
			
		||||
    static const int F33Key;        /**< key-code for the F33 key */
 | 
			
		||||
    static const int F34Key;        /**< key-code for the F34 key */
 | 
			
		||||
    static const int F35Key;        /**< key-code for the F35 key */
 | 
			
		||||
 | 
			
		||||
    static const int numberPad0;     /**< key-code for the 0 on the numeric keypad. */
 | 
			
		||||
    static const int numberPad1;     /**< key-code for the 1 on the numeric keypad. */
 | 
			
		||||
    static const int numberPad2;     /**< key-code for the 2 on the numeric keypad. */
 | 
			
		||||
    static const int numberPad3;     /**< key-code for the 3 on the numeric keypad. */
 | 
			
		||||
    static const int numberPad4;     /**< key-code for the 4 on the numeric keypad. */
 | 
			
		||||
    static const int numberPad5;     /**< key-code for the 5 on the numeric keypad. */
 | 
			
		||||
    static const int numberPad6;     /**< key-code for the 6 on the numeric keypad. */
 | 
			
		||||
    static const int numberPad7;     /**< key-code for the 7 on the numeric keypad. */
 | 
			
		||||
    static const int numberPad8;     /**< key-code for the 8 on the numeric keypad. */
 | 
			
		||||
    static const int numberPad9;     /**< key-code for the 9 on the numeric keypad. */
 | 
			
		||||
 | 
			
		||||
    static const int numberPadAdd;            /**< key-code for the add sign on the numeric keypad. */
 | 
			
		||||
    static const int numberPadSubtract;       /**< key-code for the subtract sign on the numeric keypad. */
 | 
			
		||||
    static const int numberPadMultiply;       /**< key-code for the multiply sign on the numeric keypad. */
 | 
			
		||||
    static const int numberPadDivide;         /**< key-code for the divide sign on the numeric keypad. */
 | 
			
		||||
    static const int numberPadSeparator;      /**< key-code for the comma on the numeric keypad. */
 | 
			
		||||
    static const int numberPadDecimalPoint;   /**< key-code for the decimal point sign on the numeric keypad. */
 | 
			
		||||
    static const int numberPadEquals;         /**< key-code for the equals key on the numeric keypad. */
 | 
			
		||||
    static const int numberPadDelete;         /**< key-code for the delete key on the numeric keypad. */
 | 
			
		||||
 | 
			
		||||
    static const int playKey;        /**< key-code for a multimedia 'play' key, (not all keyboards will have one) */
 | 
			
		||||
    static const int stopKey;        /**< key-code for a multimedia 'stop' key, (not all keyboards will have one) */
 | 
			
		||||
    static const int fastForwardKey; /**< key-code for a multimedia 'fast-forward' key, (not all keyboards will have one) */
 | 
			
		||||
    static const int rewindKey;      /**< key-code for a multimedia 'rewind' key, (not all keyboards will have one) */
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    int keyCode = 0;
 | 
			
		||||
    ModifierKeys mods;
 | 
			
		||||
    juce_wchar textCharacter = 0;
 | 
			
		||||
 | 
			
		||||
    JUCE_LEAK_DETECTOR (KeyPress)
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace juce
 | 
			
		||||
/*
 | 
			
		||||
  ==============================================================================
 | 
			
		||||
 | 
			
		||||
   This file is part of the JUCE library.
 | 
			
		||||
   Copyright (c) 2022 - Raw Material Software Limited
 | 
			
		||||
 | 
			
		||||
   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 7 End-User License
 | 
			
		||||
   Agreement and JUCE Privacy Policy.
 | 
			
		||||
 | 
			
		||||
   End User License Agreement: www.juce.com/juce-7-licence
 | 
			
		||||
   Privacy Policy: www.juce.com/juce-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
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
/**
 | 
			
		||||
    Represents a key press, including any modifier keys that are needed.
 | 
			
		||||
 | 
			
		||||
    E.g. a KeyPress might represent CTRL+C, SHIFT+ALT+H, Spacebar, Escape, etc.
 | 
			
		||||
 | 
			
		||||
    @see Component, KeyListener, KeyPressMappingSet, Button::addShortcut
 | 
			
		||||
 | 
			
		||||
    @tags{GUI}
 | 
			
		||||
*/
 | 
			
		||||
class JUCE_API  KeyPress
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Creates an (invalid) KeyPress.
 | 
			
		||||
 | 
			
		||||
        @see isValid
 | 
			
		||||
    */
 | 
			
		||||
    KeyPress() = default;
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~KeyPress() = default;
 | 
			
		||||
 | 
			
		||||
    /** Creates a KeyPress for a key and some modifiers.
 | 
			
		||||
 | 
			
		||||
        e.g.
 | 
			
		||||
        CTRL+C would be: KeyPress ('c', ModifierKeys::ctrlModifier, 0)
 | 
			
		||||
        SHIFT+Escape would be: KeyPress (KeyPress::escapeKey, ModifierKeys::shiftModifier, 0)
 | 
			
		||||
 | 
			
		||||
        @param keyCode      a code that represents the key - this value must be
 | 
			
		||||
                            one of special constants listed in this class, or an
 | 
			
		||||
                            8-bit character code such as a letter (case is ignored),
 | 
			
		||||
                            digit or a simple key like "," or ".". Note that this
 | 
			
		||||
                            isn't the same as the textCharacter parameter, so for example
 | 
			
		||||
                            a keyCode of 'a' and a shift-key modifier should have a
 | 
			
		||||
                            textCharacter value of 'A'.
 | 
			
		||||
        @param modifiers    the modifiers to associate with the keystroke
 | 
			
		||||
        @param textCharacter    the character that would be printed if someone typed
 | 
			
		||||
                            this keypress into a text editor. This value may be
 | 
			
		||||
                            null if the keypress is a non-printing character
 | 
			
		||||
        @see getKeyCode, isKeyCode, getModifiers
 | 
			
		||||
    */
 | 
			
		||||
    KeyPress (int keyCode,
 | 
			
		||||
              ModifierKeys modifiers,
 | 
			
		||||
              juce_wchar textCharacter) noexcept;
 | 
			
		||||
 | 
			
		||||
    /** Creates a keypress with a keyCode but no modifiers or text character. */
 | 
			
		||||
    explicit KeyPress (int keyCode) noexcept;
 | 
			
		||||
 | 
			
		||||
    /** Creates a copy of another KeyPress. */
 | 
			
		||||
    KeyPress (const KeyPress&) = default;
 | 
			
		||||
 | 
			
		||||
    /** Copies this KeyPress from another one. */
 | 
			
		||||
    KeyPress& operator= (const KeyPress&) = default;
 | 
			
		||||
 | 
			
		||||
    /** Compares two KeyPress objects. */
 | 
			
		||||
    bool operator== (const KeyPress& other) const noexcept;
 | 
			
		||||
 | 
			
		||||
    /** Compares two KeyPress objects. */
 | 
			
		||||
    bool operator!= (const KeyPress& other) const noexcept;
 | 
			
		||||
 | 
			
		||||
    /** Returns true if this keypress is for the given keycode without any modifiers. */
 | 
			
		||||
    bool operator== (int keyCode) const noexcept;
 | 
			
		||||
 | 
			
		||||
    /** Returns true if this keypress is not for the given keycode without any modifiers. */
 | 
			
		||||
    bool operator!= (int keyCode) const noexcept;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Returns true if this is a valid KeyPress.
 | 
			
		||||
 | 
			
		||||
        A null keypress can be created by the default constructor, in case it's
 | 
			
		||||
        needed.
 | 
			
		||||
    */
 | 
			
		||||
    bool isValid() const noexcept                               { return keyCode != 0; }
 | 
			
		||||
 | 
			
		||||
    /** Returns the key code itself.
 | 
			
		||||
 | 
			
		||||
        This will either be one of the special constants defined in this class,
 | 
			
		||||
        or an 8-bit character code.
 | 
			
		||||
    */
 | 
			
		||||
    int getKeyCode() const noexcept                             { return keyCode; }
 | 
			
		||||
 | 
			
		||||
    /** Returns the key modifiers.
 | 
			
		||||
 | 
			
		||||
        @see ModifierKeys
 | 
			
		||||
    */
 | 
			
		||||
    ModifierKeys getModifiers() const noexcept                  { return mods; }
 | 
			
		||||
 | 
			
		||||
    /** Returns the character that is associated with this keypress.
 | 
			
		||||
 | 
			
		||||
        This is the character that you'd expect to see printed if you press this
 | 
			
		||||
        keypress in a text editor or similar component.
 | 
			
		||||
    */
 | 
			
		||||
    juce_wchar getTextCharacter() const noexcept                { return textCharacter; }
 | 
			
		||||
 | 
			
		||||
    /** Checks whether the KeyPress's key is the same as the one provided, without checking
 | 
			
		||||
        the modifiers.
 | 
			
		||||
 | 
			
		||||
        The values for key codes can either be one of the special constants defined in
 | 
			
		||||
        this class, or an 8-bit character code.
 | 
			
		||||
 | 
			
		||||
        @see getKeyCode
 | 
			
		||||
    */
 | 
			
		||||
    bool isKeyCode (int keyCodeToCompare) const noexcept        { return keyCode == keyCodeToCompare; }
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Converts a textual key description to a KeyPress.
 | 
			
		||||
 | 
			
		||||
        This attempts to decode a textual version of a keypress, e.g. "ctrl + c" or "spacebar".
 | 
			
		||||
 | 
			
		||||
        This isn't designed to cope with any kind of input, but should be given the
 | 
			
		||||
        strings that are created by the getTextDescription() method.
 | 
			
		||||
 | 
			
		||||
        If the string can't be parsed, the object returned will be invalid.
 | 
			
		||||
 | 
			
		||||
        @see getTextDescription
 | 
			
		||||
    */
 | 
			
		||||
    static KeyPress createFromDescription (const String& textVersion);
 | 
			
		||||
 | 
			
		||||
    /** Creates a textual description of the key combination.
 | 
			
		||||
 | 
			
		||||
        e.g. "ctrl + c" or "delete".
 | 
			
		||||
 | 
			
		||||
        To store a keypress in a file, use this method, along with createFromDescription()
 | 
			
		||||
        to retrieve it later.
 | 
			
		||||
    */
 | 
			
		||||
    String getTextDescription() const;
 | 
			
		||||
 | 
			
		||||
    /** Creates a textual description of the key combination, using unicode icon symbols if possible.
 | 
			
		||||
 | 
			
		||||
        On OSX, this uses the Apple symbols for command, option, shift, etc, instead of the textual
 | 
			
		||||
        modifier key descriptions that are returned by getTextDescription()
 | 
			
		||||
    */
 | 
			
		||||
    String getTextDescriptionWithIcons() const;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Checks whether the user is currently holding down the keys that make up this
 | 
			
		||||
        KeyPress.
 | 
			
		||||
 | 
			
		||||
        Note that this will return false if any extra modifier keys are
 | 
			
		||||
        down - e.g. if the keypress is CTRL+X and the user is actually holding CTRL+ALT+x
 | 
			
		||||
        then it will be false.
 | 
			
		||||
    */
 | 
			
		||||
    bool isCurrentlyDown() const;
 | 
			
		||||
 | 
			
		||||
    /** Checks whether a particular key is held down, irrespective of modifiers.
 | 
			
		||||
 | 
			
		||||
        The values for key codes can either be one of the special constants defined in
 | 
			
		||||
        this class, or an 8-bit character code.
 | 
			
		||||
    */
 | 
			
		||||
    static bool isKeyCurrentlyDown (int keyCode);
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    // Key codes
 | 
			
		||||
    //
 | 
			
		||||
    // Note that the actual values of these are platform-specific and may change
 | 
			
		||||
    // without warning, so don't store them anywhere as constants. For persisting/retrieving
 | 
			
		||||
    // KeyPress objects, use getTextDescription() and createFromDescription() instead.
 | 
			
		||||
    //
 | 
			
		||||
 | 
			
		||||
    static const int spaceKey;      /**< key-code for the space bar */
 | 
			
		||||
    static const int escapeKey;     /**< key-code for the escape key */
 | 
			
		||||
    static const int returnKey;     /**< key-code for the return key*/
 | 
			
		||||
    static const int tabKey;        /**< key-code for the tab key*/
 | 
			
		||||
 | 
			
		||||
    static const int deleteKey;     /**< key-code for the delete key (not backspace) */
 | 
			
		||||
    static const int backspaceKey;  /**< key-code for the backspace key */
 | 
			
		||||
    static const int insertKey;     /**< key-code for the insert key */
 | 
			
		||||
 | 
			
		||||
    static const int upKey;         /**< key-code for the cursor-up key */
 | 
			
		||||
    static const int downKey;       /**< key-code for the cursor-down key */
 | 
			
		||||
    static const int leftKey;       /**< key-code for the cursor-left key */
 | 
			
		||||
    static const int rightKey;      /**< key-code for the cursor-right key */
 | 
			
		||||
    static const int pageUpKey;     /**< key-code for the page-up key */
 | 
			
		||||
    static const int pageDownKey;   /**< key-code for the page-down key */
 | 
			
		||||
    static const int homeKey;       /**< key-code for the home key */
 | 
			
		||||
    static const int endKey;        /**< key-code for the end key */
 | 
			
		||||
 | 
			
		||||
    static const int F1Key;         /**< key-code for the F1 key */
 | 
			
		||||
    static const int F2Key;         /**< key-code for the F2 key */
 | 
			
		||||
    static const int F3Key;         /**< key-code for the F3 key */
 | 
			
		||||
    static const int F4Key;         /**< key-code for the F4 key */
 | 
			
		||||
    static const int F5Key;         /**< key-code for the F5 key */
 | 
			
		||||
    static const int F6Key;         /**< key-code for the F6 key */
 | 
			
		||||
    static const int F7Key;         /**< key-code for the F7 key */
 | 
			
		||||
    static const int F8Key;         /**< key-code for the F8 key */
 | 
			
		||||
    static const int F9Key;         /**< key-code for the F9 key */
 | 
			
		||||
    static const int F10Key;        /**< key-code for the F10 key */
 | 
			
		||||
    static const int F11Key;        /**< key-code for the F11 key */
 | 
			
		||||
    static const int F12Key;        /**< key-code for the F12 key */
 | 
			
		||||
    static const int F13Key;        /**< key-code for the F13 key */
 | 
			
		||||
    static const int F14Key;        /**< key-code for the F14 key */
 | 
			
		||||
    static const int F15Key;        /**< key-code for the F15 key */
 | 
			
		||||
    static const int F16Key;        /**< key-code for the F16 key */
 | 
			
		||||
    static const int F17Key;        /**< key-code for the F17 key */
 | 
			
		||||
    static const int F18Key;        /**< key-code for the F18 key */
 | 
			
		||||
    static const int F19Key;        /**< key-code for the F19 key */
 | 
			
		||||
    static const int F20Key;        /**< key-code for the F20 key */
 | 
			
		||||
    static const int F21Key;        /**< key-code for the F21 key */
 | 
			
		||||
    static const int F22Key;        /**< key-code for the F22 key */
 | 
			
		||||
    static const int F23Key;        /**< key-code for the F23 key */
 | 
			
		||||
    static const int F24Key;        /**< key-code for the F24 key */
 | 
			
		||||
    static const int F25Key;        /**< key-code for the F25 key */
 | 
			
		||||
    static const int F26Key;        /**< key-code for the F26 key */
 | 
			
		||||
    static const int F27Key;        /**< key-code for the F27 key */
 | 
			
		||||
    static const int F28Key;        /**< key-code for the F28 key */
 | 
			
		||||
    static const int F29Key;        /**< key-code for the F29 key */
 | 
			
		||||
    static const int F30Key;        /**< key-code for the F30 key */
 | 
			
		||||
    static const int F31Key;        /**< key-code for the F31 key */
 | 
			
		||||
    static const int F32Key;        /**< key-code for the F32 key */
 | 
			
		||||
    static const int F33Key;        /**< key-code for the F33 key */
 | 
			
		||||
    static const int F34Key;        /**< key-code for the F34 key */
 | 
			
		||||
    static const int F35Key;        /**< key-code for the F35 key */
 | 
			
		||||
 | 
			
		||||
    static const int numberPad0;     /**< key-code for the 0 on the numeric keypad. */
 | 
			
		||||
    static const int numberPad1;     /**< key-code for the 1 on the numeric keypad. */
 | 
			
		||||
    static const int numberPad2;     /**< key-code for the 2 on the numeric keypad. */
 | 
			
		||||
    static const int numberPad3;     /**< key-code for the 3 on the numeric keypad. */
 | 
			
		||||
    static const int numberPad4;     /**< key-code for the 4 on the numeric keypad. */
 | 
			
		||||
    static const int numberPad5;     /**< key-code for the 5 on the numeric keypad. */
 | 
			
		||||
    static const int numberPad6;     /**< key-code for the 6 on the numeric keypad. */
 | 
			
		||||
    static const int numberPad7;     /**< key-code for the 7 on the numeric keypad. */
 | 
			
		||||
    static const int numberPad8;     /**< key-code for the 8 on the numeric keypad. */
 | 
			
		||||
    static const int numberPad9;     /**< key-code for the 9 on the numeric keypad. */
 | 
			
		||||
 | 
			
		||||
    static const int numberPadAdd;            /**< key-code for the add sign on the numeric keypad. */
 | 
			
		||||
    static const int numberPadSubtract;       /**< key-code for the subtract sign on the numeric keypad. */
 | 
			
		||||
    static const int numberPadMultiply;       /**< key-code for the multiply sign on the numeric keypad. */
 | 
			
		||||
    static const int numberPadDivide;         /**< key-code for the divide sign on the numeric keypad. */
 | 
			
		||||
    static const int numberPadSeparator;      /**< key-code for the comma on the numeric keypad. */
 | 
			
		||||
    static const int numberPadDecimalPoint;   /**< key-code for the decimal point sign on the numeric keypad. */
 | 
			
		||||
    static const int numberPadEquals;         /**< key-code for the equals key on the numeric keypad. */
 | 
			
		||||
    static const int numberPadDelete;         /**< key-code for the delete key on the numeric keypad. */
 | 
			
		||||
 | 
			
		||||
    static const int playKey;        /**< key-code for a multimedia 'play' key, (not all keyboards will have one) */
 | 
			
		||||
    static const int stopKey;        /**< key-code for a multimedia 'stop' key, (not all keyboards will have one) */
 | 
			
		||||
    static const int fastForwardKey; /**< key-code for a multimedia 'fast-forward' key, (not all keyboards will have one) */
 | 
			
		||||
    static const int rewindKey;      /**< key-code for a multimedia 'rewind' key, (not all keyboards will have one) */
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    int keyCode = 0;
 | 
			
		||||
    ModifierKeys mods;
 | 
			
		||||
    juce_wchar textCharacter = 0;
 | 
			
		||||
 | 
			
		||||
    JUCE_LEAK_DETECTOR (KeyPress)
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace juce
 | 
			
		||||
 
 | 
			
		||||
@@ -1,274 +1,274 @@
 | 
			
		||||
/*
 | 
			
		||||
  ==============================================================================
 | 
			
		||||
 | 
			
		||||
   This file is part of the JUCE library.
 | 
			
		||||
   Copyright (c) 2020 - Raw Material Software Limited
 | 
			
		||||
 | 
			
		||||
   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 6 End-User License
 | 
			
		||||
   Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
 | 
			
		||||
 | 
			
		||||
   End User License Agreement: www.juce.com/juce-6-licence
 | 
			
		||||
   Privacy Policy: www.juce.com/juce-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
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
namespace KeyboardFocusTraverserHelpers
 | 
			
		||||
{
 | 
			
		||||
    static bool isKeyboardFocusable (const Component* comp, const Component* container)
 | 
			
		||||
    {
 | 
			
		||||
        return comp->getWantsKeyboardFocus() && container->isParentOf (comp);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static Component* traverse (Component* current, Component* container,
 | 
			
		||||
                                FocusHelpers::NavigationDirection direction)
 | 
			
		||||
    {
 | 
			
		||||
        if (auto* comp = FocusHelpers::navigateFocus (current, container, direction,
 | 
			
		||||
                                                      &Component::isKeyboardFocusContainer))
 | 
			
		||||
        {
 | 
			
		||||
            if (isKeyboardFocusable (comp, container))
 | 
			
		||||
                return comp;
 | 
			
		||||
 | 
			
		||||
            return traverse (comp, container, direction);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Component* KeyboardFocusTraverser::getNextComponent (Component* current)
 | 
			
		||||
{
 | 
			
		||||
    return KeyboardFocusTraverserHelpers::traverse (current, current->findKeyboardFocusContainer(),
 | 
			
		||||
                                                    FocusHelpers::NavigationDirection::forwards);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Component* KeyboardFocusTraverser::getPreviousComponent (Component* current)
 | 
			
		||||
{
 | 
			
		||||
    return KeyboardFocusTraverserHelpers::traverse (current, current->findKeyboardFocusContainer(),
 | 
			
		||||
                                                    FocusHelpers::NavigationDirection::backwards);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Component* KeyboardFocusTraverser::getDefaultComponent (Component* parentComponent)
 | 
			
		||||
{
 | 
			
		||||
    for (auto* comp : getAllComponents (parentComponent))
 | 
			
		||||
        if (KeyboardFocusTraverserHelpers::isKeyboardFocusable (comp, parentComponent))
 | 
			
		||||
            return comp;
 | 
			
		||||
 | 
			
		||||
    return nullptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::vector<Component*> KeyboardFocusTraverser::getAllComponents (Component* parentComponent)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<Component*> components;
 | 
			
		||||
    FocusHelpers::findAllComponents (parentComponent,
 | 
			
		||||
                                     components,
 | 
			
		||||
                                     &Component::isKeyboardFocusContainer);
 | 
			
		||||
 | 
			
		||||
    auto removePredicate = [parentComponent] (const Component* comp)
 | 
			
		||||
    {
 | 
			
		||||
        return ! KeyboardFocusTraverserHelpers::isKeyboardFocusable (comp, parentComponent);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    components.erase (std::remove_if (std::begin (components), std::end (components), std::move (removePredicate)),
 | 
			
		||||
                      std::end (components));
 | 
			
		||||
 | 
			
		||||
    return components;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
//==============================================================================
 | 
			
		||||
#if JUCE_UNIT_TESTS
 | 
			
		||||
 | 
			
		||||
struct KeyboardFocusTraverserTests  : public UnitTest
 | 
			
		||||
{
 | 
			
		||||
    KeyboardFocusTraverserTests()
 | 
			
		||||
        : UnitTest ("KeyboardFocusTraverser", UnitTestCategories::gui)
 | 
			
		||||
    {}
 | 
			
		||||
 | 
			
		||||
    void runTest() override
 | 
			
		||||
    {
 | 
			
		||||
        ScopedJuceInitialiser_GUI libraryInitialiser;
 | 
			
		||||
        const MessageManagerLock mml;
 | 
			
		||||
 | 
			
		||||
        beginTest ("No child wants keyboard focus");
 | 
			
		||||
        {
 | 
			
		||||
            TestComponent parent;
 | 
			
		||||
 | 
			
		||||
            expect (traverser.getDefaultComponent (&parent) == nullptr);
 | 
			
		||||
            expect (traverser.getAllComponents (&parent).empty());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        beginTest ("Single child wants keyboard focus");
 | 
			
		||||
        {
 | 
			
		||||
            TestComponent parent;
 | 
			
		||||
 | 
			
		||||
            parent.children[5].setWantsKeyboardFocus (true);
 | 
			
		||||
 | 
			
		||||
            auto* defaultComponent = traverser.getDefaultComponent (&parent);
 | 
			
		||||
 | 
			
		||||
            expect (defaultComponent == &parent.children[5]);
 | 
			
		||||
            expect (defaultComponent->getWantsKeyboardFocus());
 | 
			
		||||
 | 
			
		||||
            expect (traverser.getNextComponent (defaultComponent) == nullptr);
 | 
			
		||||
            expect (traverser.getPreviousComponent (defaultComponent) == nullptr);
 | 
			
		||||
            expect (traverser.getAllComponents (&parent).size() == 1);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        beginTest ("Multiple children want keyboard focus");
 | 
			
		||||
        {
 | 
			
		||||
            TestComponent parent;
 | 
			
		||||
 | 
			
		||||
            Component* focusChildren[]
 | 
			
		||||
            {
 | 
			
		||||
                &parent.children[1],
 | 
			
		||||
                &parent.children[9],
 | 
			
		||||
                &parent.children[3],
 | 
			
		||||
                &parent.children[5],
 | 
			
		||||
                &parent.children[8],
 | 
			
		||||
                &parent.children[0]
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            for (auto* focusChild : focusChildren)
 | 
			
		||||
                focusChild->setWantsKeyboardFocus (true);
 | 
			
		||||
 | 
			
		||||
            auto allComponents = traverser.getAllComponents (&parent);
 | 
			
		||||
 | 
			
		||||
            for (auto* focusChild : focusChildren)
 | 
			
		||||
                expect (std::find (allComponents.cbegin(), allComponents.cend(), focusChild) != allComponents.cend());
 | 
			
		||||
 | 
			
		||||
            auto* componentToTest = traverser.getDefaultComponent (&parent);
 | 
			
		||||
 | 
			
		||||
            for (;;)
 | 
			
		||||
            {
 | 
			
		||||
                expect (componentToTest->getWantsKeyboardFocus());
 | 
			
		||||
                expect (std::find (std::begin (focusChildren), std::end (focusChildren), componentToTest) != std::end (focusChildren));
 | 
			
		||||
 | 
			
		||||
                componentToTest = traverser.getNextComponent (componentToTest);
 | 
			
		||||
 | 
			
		||||
                if (componentToTest == nullptr)
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            int focusOrder = 1;
 | 
			
		||||
            for (auto* focusChild : focusChildren)
 | 
			
		||||
                focusChild->setExplicitFocusOrder (focusOrder++);
 | 
			
		||||
 | 
			
		||||
            componentToTest = traverser.getDefaultComponent (&parent);
 | 
			
		||||
 | 
			
		||||
            for (auto* focusChild : focusChildren)
 | 
			
		||||
            {
 | 
			
		||||
                expect (componentToTest == focusChild);
 | 
			
		||||
                expect (componentToTest->getWantsKeyboardFocus());
 | 
			
		||||
 | 
			
		||||
                componentToTest = traverser.getNextComponent (componentToTest);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        beginTest ("Single nested child wants keyboard focus");
 | 
			
		||||
        {
 | 
			
		||||
            TestComponent parent;
 | 
			
		||||
            Component grandparent;
 | 
			
		||||
 | 
			
		||||
            grandparent.addAndMakeVisible (parent);
 | 
			
		||||
 | 
			
		||||
            auto& focusChild = parent.children[5];
 | 
			
		||||
 | 
			
		||||
            focusChild.setWantsKeyboardFocus (true);
 | 
			
		||||
 | 
			
		||||
            expect (traverser.getDefaultComponent (&grandparent) == &focusChild);
 | 
			
		||||
            expect (traverser.getDefaultComponent (&parent) == &focusChild);
 | 
			
		||||
            expect (traverser.getNextComponent (&focusChild) == nullptr);
 | 
			
		||||
            expect (traverser.getPreviousComponent (&focusChild) == nullptr);
 | 
			
		||||
            expect (traverser.getAllComponents (&parent).size() == 1);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        beginTest ("Multiple nested children want keyboard focus");
 | 
			
		||||
        {
 | 
			
		||||
            TestComponent parent;
 | 
			
		||||
            Component grandparent;
 | 
			
		||||
 | 
			
		||||
            grandparent.addAndMakeVisible (parent);
 | 
			
		||||
 | 
			
		||||
            Component* focusChildren[]
 | 
			
		||||
            {
 | 
			
		||||
                &parent.children[1],
 | 
			
		||||
                &parent.children[4],
 | 
			
		||||
                &parent.children[5]
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            for (auto* focusChild : focusChildren)
 | 
			
		||||
                focusChild->setWantsKeyboardFocus (true);
 | 
			
		||||
 | 
			
		||||
            auto allComponents = traverser.getAllComponents (&parent);
 | 
			
		||||
 | 
			
		||||
            expect (std::equal (allComponents.cbegin(), allComponents.cend(), focusChildren,
 | 
			
		||||
                                [] (const Component* c1, const Component* c2) { return c1 == c2; }));
 | 
			
		||||
 | 
			
		||||
            const auto front = *focusChildren;
 | 
			
		||||
            const auto back  = *std::prev (std::end (focusChildren));
 | 
			
		||||
 | 
			
		||||
            expect (traverser.getDefaultComponent (&grandparent) == front);
 | 
			
		||||
            expect (traverser.getDefaultComponent (&parent) == front);
 | 
			
		||||
            expect (traverser.getNextComponent (front) == *std::next (std::begin (focusChildren)));
 | 
			
		||||
            expect (traverser.getPreviousComponent (back) == *std::prev (std::end (focusChildren), 2));
 | 
			
		||||
 | 
			
		||||
            std::array<Component, 3> otherParents;
 | 
			
		||||
 | 
			
		||||
            for (auto& p : otherParents)
 | 
			
		||||
            {
 | 
			
		||||
                grandparent.addAndMakeVisible (p);
 | 
			
		||||
                p.setWantsKeyboardFocus (true);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            expect (traverser.getDefaultComponent (&grandparent) == front);
 | 
			
		||||
            expect (traverser.getDefaultComponent (&parent) == front);
 | 
			
		||||
            expect (traverser.getNextComponent (back) == &otherParents.front());
 | 
			
		||||
            expect (traverser.getNextComponent (&otherParents.back()) == nullptr);
 | 
			
		||||
            expect (traverser.getAllComponents (&grandparent).size() == numElementsInArray (focusChildren) + otherParents.size());
 | 
			
		||||
            expect (traverser.getAllComponents (&parent).size() == (size_t) numElementsInArray (focusChildren));
 | 
			
		||||
 | 
			
		||||
            for (auto* focusChild : focusChildren)
 | 
			
		||||
                focusChild->setWantsKeyboardFocus (false);
 | 
			
		||||
 | 
			
		||||
            expect (traverser.getDefaultComponent (&grandparent) == &otherParents.front());
 | 
			
		||||
            expect (traverser.getDefaultComponent (&parent) == nullptr);
 | 
			
		||||
            expect (traverser.getAllComponents (&grandparent).size() == otherParents.size());
 | 
			
		||||
            expect (traverser.getAllComponents (&parent).empty());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    struct TestComponent  : public Component
 | 
			
		||||
    {
 | 
			
		||||
        TestComponent()
 | 
			
		||||
        {
 | 
			
		||||
            for (auto& child : children)
 | 
			
		||||
                addAndMakeVisible (child);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        std::array<Component, 10> children;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    KeyboardFocusTraverser traverser;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static KeyboardFocusTraverserTests keyboardFocusTraverserTests;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
} // namespace juce
 | 
			
		||||
/*
 | 
			
		||||
  ==============================================================================
 | 
			
		||||
 | 
			
		||||
   This file is part of the JUCE library.
 | 
			
		||||
   Copyright (c) 2022 - Raw Material Software Limited
 | 
			
		||||
 | 
			
		||||
   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 7 End-User License
 | 
			
		||||
   Agreement and JUCE Privacy Policy.
 | 
			
		||||
 | 
			
		||||
   End User License Agreement: www.juce.com/juce-7-licence
 | 
			
		||||
   Privacy Policy: www.juce.com/juce-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
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
namespace KeyboardFocusTraverserHelpers
 | 
			
		||||
{
 | 
			
		||||
    static bool isKeyboardFocusable (const Component* comp, const Component* container)
 | 
			
		||||
    {
 | 
			
		||||
        return comp->getWantsKeyboardFocus() && container->isParentOf (comp);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static Component* traverse (Component* current, Component* container,
 | 
			
		||||
                                FocusHelpers::NavigationDirection direction)
 | 
			
		||||
    {
 | 
			
		||||
        if (auto* comp = FocusHelpers::navigateFocus (current, container, direction,
 | 
			
		||||
                                                      &Component::isKeyboardFocusContainer))
 | 
			
		||||
        {
 | 
			
		||||
            if (isKeyboardFocusable (comp, container))
 | 
			
		||||
                return comp;
 | 
			
		||||
 | 
			
		||||
            return traverse (comp, container, direction);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Component* KeyboardFocusTraverser::getNextComponent (Component* current)
 | 
			
		||||
{
 | 
			
		||||
    return KeyboardFocusTraverserHelpers::traverse (current, current->findKeyboardFocusContainer(),
 | 
			
		||||
                                                    FocusHelpers::NavigationDirection::forwards);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Component* KeyboardFocusTraverser::getPreviousComponent (Component* current)
 | 
			
		||||
{
 | 
			
		||||
    return KeyboardFocusTraverserHelpers::traverse (current, current->findKeyboardFocusContainer(),
 | 
			
		||||
                                                    FocusHelpers::NavigationDirection::backwards);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Component* KeyboardFocusTraverser::getDefaultComponent (Component* parentComponent)
 | 
			
		||||
{
 | 
			
		||||
    for (auto* comp : getAllComponents (parentComponent))
 | 
			
		||||
        if (KeyboardFocusTraverserHelpers::isKeyboardFocusable (comp, parentComponent))
 | 
			
		||||
            return comp;
 | 
			
		||||
 | 
			
		||||
    return nullptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::vector<Component*> KeyboardFocusTraverser::getAllComponents (Component* parentComponent)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<Component*> components;
 | 
			
		||||
    FocusHelpers::findAllComponents (parentComponent,
 | 
			
		||||
                                     components,
 | 
			
		||||
                                     &Component::isKeyboardFocusContainer);
 | 
			
		||||
 | 
			
		||||
    auto removePredicate = [parentComponent] (const Component* comp)
 | 
			
		||||
    {
 | 
			
		||||
        return ! KeyboardFocusTraverserHelpers::isKeyboardFocusable (comp, parentComponent);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    components.erase (std::remove_if (std::begin (components), std::end (components), std::move (removePredicate)),
 | 
			
		||||
                      std::end (components));
 | 
			
		||||
 | 
			
		||||
    return components;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
//==============================================================================
 | 
			
		||||
#if JUCE_UNIT_TESTS
 | 
			
		||||
 | 
			
		||||
struct KeyboardFocusTraverserTests  : public UnitTest
 | 
			
		||||
{
 | 
			
		||||
    KeyboardFocusTraverserTests()
 | 
			
		||||
        : UnitTest ("KeyboardFocusTraverser", UnitTestCategories::gui)
 | 
			
		||||
    {}
 | 
			
		||||
 | 
			
		||||
    void runTest() override
 | 
			
		||||
    {
 | 
			
		||||
        ScopedJuceInitialiser_GUI libraryInitialiser;
 | 
			
		||||
        const MessageManagerLock mml;
 | 
			
		||||
 | 
			
		||||
        beginTest ("No child wants keyboard focus");
 | 
			
		||||
        {
 | 
			
		||||
            TestComponent parent;
 | 
			
		||||
 | 
			
		||||
            expect (traverser.getDefaultComponent (&parent) == nullptr);
 | 
			
		||||
            expect (traverser.getAllComponents (&parent).empty());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        beginTest ("Single child wants keyboard focus");
 | 
			
		||||
        {
 | 
			
		||||
            TestComponent parent;
 | 
			
		||||
 | 
			
		||||
            parent.children[5].setWantsKeyboardFocus (true);
 | 
			
		||||
 | 
			
		||||
            auto* defaultComponent = traverser.getDefaultComponent (&parent);
 | 
			
		||||
 | 
			
		||||
            expect (defaultComponent == &parent.children[5]);
 | 
			
		||||
            expect (defaultComponent->getWantsKeyboardFocus());
 | 
			
		||||
 | 
			
		||||
            expect (traverser.getNextComponent (defaultComponent) == nullptr);
 | 
			
		||||
            expect (traverser.getPreviousComponent (defaultComponent) == nullptr);
 | 
			
		||||
            expect (traverser.getAllComponents (&parent).size() == 1);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        beginTest ("Multiple children want keyboard focus");
 | 
			
		||||
        {
 | 
			
		||||
            TestComponent parent;
 | 
			
		||||
 | 
			
		||||
            Component* focusChildren[]
 | 
			
		||||
            {
 | 
			
		||||
                &parent.children[1],
 | 
			
		||||
                &parent.children[9],
 | 
			
		||||
                &parent.children[3],
 | 
			
		||||
                &parent.children[5],
 | 
			
		||||
                &parent.children[8],
 | 
			
		||||
                &parent.children[0]
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            for (auto* focusChild : focusChildren)
 | 
			
		||||
                focusChild->setWantsKeyboardFocus (true);
 | 
			
		||||
 | 
			
		||||
            auto allComponents = traverser.getAllComponents (&parent);
 | 
			
		||||
 | 
			
		||||
            for (auto* focusChild : focusChildren)
 | 
			
		||||
                expect (std::find (allComponents.cbegin(), allComponents.cend(), focusChild) != allComponents.cend());
 | 
			
		||||
 | 
			
		||||
            auto* componentToTest = traverser.getDefaultComponent (&parent);
 | 
			
		||||
 | 
			
		||||
            for (;;)
 | 
			
		||||
            {
 | 
			
		||||
                expect (componentToTest->getWantsKeyboardFocus());
 | 
			
		||||
                expect (std::find (std::begin (focusChildren), std::end (focusChildren), componentToTest) != std::end (focusChildren));
 | 
			
		||||
 | 
			
		||||
                componentToTest = traverser.getNextComponent (componentToTest);
 | 
			
		||||
 | 
			
		||||
                if (componentToTest == nullptr)
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            int focusOrder = 1;
 | 
			
		||||
            for (auto* focusChild : focusChildren)
 | 
			
		||||
                focusChild->setExplicitFocusOrder (focusOrder++);
 | 
			
		||||
 | 
			
		||||
            componentToTest = traverser.getDefaultComponent (&parent);
 | 
			
		||||
 | 
			
		||||
            for (auto* focusChild : focusChildren)
 | 
			
		||||
            {
 | 
			
		||||
                expect (componentToTest == focusChild);
 | 
			
		||||
                expect (componentToTest->getWantsKeyboardFocus());
 | 
			
		||||
 | 
			
		||||
                componentToTest = traverser.getNextComponent (componentToTest);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        beginTest ("Single nested child wants keyboard focus");
 | 
			
		||||
        {
 | 
			
		||||
            TestComponent parent;
 | 
			
		||||
            Component grandparent;
 | 
			
		||||
 | 
			
		||||
            grandparent.addAndMakeVisible (parent);
 | 
			
		||||
 | 
			
		||||
            auto& focusChild = parent.children[5];
 | 
			
		||||
 | 
			
		||||
            focusChild.setWantsKeyboardFocus (true);
 | 
			
		||||
 | 
			
		||||
            expect (traverser.getDefaultComponent (&grandparent) == &focusChild);
 | 
			
		||||
            expect (traverser.getDefaultComponent (&parent) == &focusChild);
 | 
			
		||||
            expect (traverser.getNextComponent (&focusChild) == nullptr);
 | 
			
		||||
            expect (traverser.getPreviousComponent (&focusChild) == nullptr);
 | 
			
		||||
            expect (traverser.getAllComponents (&parent).size() == 1);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        beginTest ("Multiple nested children want keyboard focus");
 | 
			
		||||
        {
 | 
			
		||||
            TestComponent parent;
 | 
			
		||||
            Component grandparent;
 | 
			
		||||
 | 
			
		||||
            grandparent.addAndMakeVisible (parent);
 | 
			
		||||
 | 
			
		||||
            Component* focusChildren[]
 | 
			
		||||
            {
 | 
			
		||||
                &parent.children[1],
 | 
			
		||||
                &parent.children[4],
 | 
			
		||||
                &parent.children[5]
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            for (auto* focusChild : focusChildren)
 | 
			
		||||
                focusChild->setWantsKeyboardFocus (true);
 | 
			
		||||
 | 
			
		||||
            auto allComponents = traverser.getAllComponents (&parent);
 | 
			
		||||
 | 
			
		||||
            expect (std::equal (allComponents.cbegin(), allComponents.cend(), focusChildren,
 | 
			
		||||
                                [] (const Component* c1, const Component* c2) { return c1 == c2; }));
 | 
			
		||||
 | 
			
		||||
            const auto front = *focusChildren;
 | 
			
		||||
            const auto back  = *std::prev (std::end (focusChildren));
 | 
			
		||||
 | 
			
		||||
            expect (traverser.getDefaultComponent (&grandparent) == front);
 | 
			
		||||
            expect (traverser.getDefaultComponent (&parent) == front);
 | 
			
		||||
            expect (traverser.getNextComponent (front) == *std::next (std::begin (focusChildren)));
 | 
			
		||||
            expect (traverser.getPreviousComponent (back) == *std::prev (std::end (focusChildren), 2));
 | 
			
		||||
 | 
			
		||||
            std::array<Component, 3> otherParents;
 | 
			
		||||
 | 
			
		||||
            for (auto& p : otherParents)
 | 
			
		||||
            {
 | 
			
		||||
                grandparent.addAndMakeVisible (p);
 | 
			
		||||
                p.setWantsKeyboardFocus (true);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            expect (traverser.getDefaultComponent (&grandparent) == front);
 | 
			
		||||
            expect (traverser.getDefaultComponent (&parent) == front);
 | 
			
		||||
            expect (traverser.getNextComponent (back) == &otherParents.front());
 | 
			
		||||
            expect (traverser.getNextComponent (&otherParents.back()) == nullptr);
 | 
			
		||||
            expect (traverser.getAllComponents (&grandparent).size() == numElementsInArray (focusChildren) + otherParents.size());
 | 
			
		||||
            expect (traverser.getAllComponents (&parent).size() == (size_t) numElementsInArray (focusChildren));
 | 
			
		||||
 | 
			
		||||
            for (auto* focusChild : focusChildren)
 | 
			
		||||
                focusChild->setWantsKeyboardFocus (false);
 | 
			
		||||
 | 
			
		||||
            expect (traverser.getDefaultComponent (&grandparent) == &otherParents.front());
 | 
			
		||||
            expect (traverser.getDefaultComponent (&parent) == nullptr);
 | 
			
		||||
            expect (traverser.getAllComponents (&grandparent).size() == otherParents.size());
 | 
			
		||||
            expect (traverser.getAllComponents (&parent).empty());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    struct TestComponent  : public Component
 | 
			
		||||
    {
 | 
			
		||||
        TestComponent()
 | 
			
		||||
        {
 | 
			
		||||
            for (auto& child : children)
 | 
			
		||||
                addAndMakeVisible (child);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        std::array<Component, 10> children;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    KeyboardFocusTraverser traverser;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static KeyboardFocusTraverserTests keyboardFocusTraverserTests;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
} // namespace juce
 | 
			
		||||
 
 | 
			
		||||
@@ -1,87 +1,87 @@
 | 
			
		||||
/*
 | 
			
		||||
  ==============================================================================
 | 
			
		||||
 | 
			
		||||
   This file is part of the JUCE library.
 | 
			
		||||
   Copyright (c) 2020 - Raw Material Software Limited
 | 
			
		||||
 | 
			
		||||
   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 6 End-User License
 | 
			
		||||
   Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
 | 
			
		||||
 | 
			
		||||
   End User License Agreement: www.juce.com/juce-6-licence
 | 
			
		||||
   Privacy Policy: www.juce.com/juce-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
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
/**
 | 
			
		||||
    Controls the order in which keyboard focus moves between components.
 | 
			
		||||
 | 
			
		||||
    The default behaviour of this class uses a FocusTraverser object internally to
 | 
			
		||||
    determine the default/next/previous component until it finds one which wants
 | 
			
		||||
    keyboard focus, as set by the Component::setWantsKeyboardFocus() method.
 | 
			
		||||
 | 
			
		||||
    If you need keyboard focus traversal in a more customised way, you can create
 | 
			
		||||
    a subclass of ComponentTraverser that uses your own algorithm, and use
 | 
			
		||||
    Component::createKeyboardFocusTraverser() to create it.
 | 
			
		||||
 | 
			
		||||
    @see FocusTraverser, ComponentTraverser, Component::createKeyboardFocusTraverser
 | 
			
		||||
 | 
			
		||||
    @tags{GUI}
 | 
			
		||||
*/
 | 
			
		||||
class JUCE_API  KeyboardFocusTraverser  : public ComponentTraverser
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~KeyboardFocusTraverser() override = default;
 | 
			
		||||
 | 
			
		||||
    /** Returns the component that should receive keyboard focus by default within the
 | 
			
		||||
        given parent component.
 | 
			
		||||
 | 
			
		||||
        The default implementation will return the foremost focusable component (as
 | 
			
		||||
        determined by FocusTraverser) that also wants keyboard focus, or nullptr if
 | 
			
		||||
        there is no suitable component.
 | 
			
		||||
    */
 | 
			
		||||
    Component* getDefaultComponent (Component* parentComponent) override;
 | 
			
		||||
 | 
			
		||||
    /** Returns the component that should be given keyboard focus after the specified
 | 
			
		||||
        one when moving "forwards".
 | 
			
		||||
 | 
			
		||||
        The default implementation will return the next focusable component (as
 | 
			
		||||
        determined by FocusTraverser) that also wants keyboard focus, or nullptr if
 | 
			
		||||
        there is no suitable component.
 | 
			
		||||
    */
 | 
			
		||||
    Component* getNextComponent (Component* current) override;
 | 
			
		||||
 | 
			
		||||
    /** Returns the component that should be given keyboard focus after the specified
 | 
			
		||||
        one when moving "backwards".
 | 
			
		||||
 | 
			
		||||
        The default implementation will return the previous focusable component (as
 | 
			
		||||
        determined by FocusTraverser) that also wants keyboard focus, or nullptr if
 | 
			
		||||
        there is no suitable component.
 | 
			
		||||
    */
 | 
			
		||||
    Component* getPreviousComponent (Component* current) override;
 | 
			
		||||
 | 
			
		||||
    /** Returns all of the components that can receive keyboard focus within the given
 | 
			
		||||
        parent component in traversal order.
 | 
			
		||||
 | 
			
		||||
        The default implementation will return all focusable child components (as
 | 
			
		||||
        determined by FocusTraverser) that also wants keyboard focus.
 | 
			
		||||
    */
 | 
			
		||||
    std::vector<Component*> getAllComponents (Component* parentComponent) override;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace juce
 | 
			
		||||
/*
 | 
			
		||||
  ==============================================================================
 | 
			
		||||
 | 
			
		||||
   This file is part of the JUCE library.
 | 
			
		||||
   Copyright (c) 2022 - Raw Material Software Limited
 | 
			
		||||
 | 
			
		||||
   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 7 End-User License
 | 
			
		||||
   Agreement and JUCE Privacy Policy.
 | 
			
		||||
 | 
			
		||||
   End User License Agreement: www.juce.com/juce-7-licence
 | 
			
		||||
   Privacy Policy: www.juce.com/juce-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
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
/**
 | 
			
		||||
    Controls the order in which keyboard focus moves between components.
 | 
			
		||||
 | 
			
		||||
    The default behaviour of this class uses a FocusTraverser object internally to
 | 
			
		||||
    determine the default/next/previous component until it finds one which wants
 | 
			
		||||
    keyboard focus, as set by the Component::setWantsKeyboardFocus() method.
 | 
			
		||||
 | 
			
		||||
    If you need keyboard focus traversal in a more customised way, you can create
 | 
			
		||||
    a subclass of ComponentTraverser that uses your own algorithm, and use
 | 
			
		||||
    Component::createKeyboardFocusTraverser() to create it.
 | 
			
		||||
 | 
			
		||||
    @see FocusTraverser, ComponentTraverser, Component::createKeyboardFocusTraverser
 | 
			
		||||
 | 
			
		||||
    @tags{GUI}
 | 
			
		||||
*/
 | 
			
		||||
class JUCE_API  KeyboardFocusTraverser  : public ComponentTraverser
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    ~KeyboardFocusTraverser() override = default;
 | 
			
		||||
 | 
			
		||||
    /** Returns the component that should receive keyboard focus by default within the
 | 
			
		||||
        given parent component.
 | 
			
		||||
 | 
			
		||||
        The default implementation will return the foremost focusable component (as
 | 
			
		||||
        determined by FocusTraverser) that also wants keyboard focus, or nullptr if
 | 
			
		||||
        there is no suitable component.
 | 
			
		||||
    */
 | 
			
		||||
    Component* getDefaultComponent (Component* parentComponent) override;
 | 
			
		||||
 | 
			
		||||
    /** Returns the component that should be given keyboard focus after the specified
 | 
			
		||||
        one when moving "forwards".
 | 
			
		||||
 | 
			
		||||
        The default implementation will return the next focusable component (as
 | 
			
		||||
        determined by FocusTraverser) that also wants keyboard focus, or nullptr if
 | 
			
		||||
        there is no suitable component.
 | 
			
		||||
    */
 | 
			
		||||
    Component* getNextComponent (Component* current) override;
 | 
			
		||||
 | 
			
		||||
    /** Returns the component that should be given keyboard focus after the specified
 | 
			
		||||
        one when moving "backwards".
 | 
			
		||||
 | 
			
		||||
        The default implementation will return the previous focusable component (as
 | 
			
		||||
        determined by FocusTraverser) that also wants keyboard focus, or nullptr if
 | 
			
		||||
        there is no suitable component.
 | 
			
		||||
    */
 | 
			
		||||
    Component* getPreviousComponent (Component* current) override;
 | 
			
		||||
 | 
			
		||||
    /** Returns all of the components that can receive keyboard focus within the given
 | 
			
		||||
        parent component in traversal order.
 | 
			
		||||
 | 
			
		||||
        The default implementation will return all focusable child components (as
 | 
			
		||||
        determined by FocusTraverser) that also wants keyboard focus.
 | 
			
		||||
    */
 | 
			
		||||
    std::vector<Component*> getAllComponents (Component* parentComponent) override;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace juce
 | 
			
		||||
 
 | 
			
		||||
@@ -1,49 +1,49 @@
 | 
			
		||||
/*
 | 
			
		||||
  ==============================================================================
 | 
			
		||||
 | 
			
		||||
   This file is part of the JUCE library.
 | 
			
		||||
   Copyright (c) 2020 - Raw Material Software Limited
 | 
			
		||||
 | 
			
		||||
   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 6 End-User License
 | 
			
		||||
   Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
 | 
			
		||||
 | 
			
		||||
   End User License Agreement: www.juce.com/juce-6-licence
 | 
			
		||||
   Privacy Policy: www.juce.com/juce-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
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
ModifierKeys ModifierKeys::currentModifiers;
 | 
			
		||||
 | 
			
		||||
ModifierKeys::ModifierKeys (int rawFlags) noexcept               : flags (rawFlags)    {}
 | 
			
		||||
 | 
			
		||||
int ModifierKeys::getNumMouseButtonsDown() const noexcept
 | 
			
		||||
{
 | 
			
		||||
    int num = 0;
 | 
			
		||||
 | 
			
		||||
    if (isLeftButtonDown())     ++num;
 | 
			
		||||
    if (isRightButtonDown())    ++num;
 | 
			
		||||
    if (isMiddleButtonDown())   ++num;
 | 
			
		||||
 | 
			
		||||
    return num;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ModifierKeys ModifierKeys::getCurrentModifiersRealtime() noexcept
 | 
			
		||||
{
 | 
			
		||||
    return ComponentPeer::getCurrentModifiersRealtime();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace juce
 | 
			
		||||
/*
 | 
			
		||||
  ==============================================================================
 | 
			
		||||
 | 
			
		||||
   This file is part of the JUCE library.
 | 
			
		||||
   Copyright (c) 2022 - Raw Material Software Limited
 | 
			
		||||
 | 
			
		||||
   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 7 End-User License
 | 
			
		||||
   Agreement and JUCE Privacy Policy.
 | 
			
		||||
 | 
			
		||||
   End User License Agreement: www.juce.com/juce-7-licence
 | 
			
		||||
   Privacy Policy: www.juce.com/juce-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
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
ModifierKeys ModifierKeys::currentModifiers;
 | 
			
		||||
 | 
			
		||||
ModifierKeys::ModifierKeys (int rawFlags) noexcept               : flags (rawFlags)    {}
 | 
			
		||||
 | 
			
		||||
int ModifierKeys::getNumMouseButtonsDown() const noexcept
 | 
			
		||||
{
 | 
			
		||||
    int num = 0;
 | 
			
		||||
 | 
			
		||||
    if (isLeftButtonDown())     ++num;
 | 
			
		||||
    if (isRightButtonDown())    ++num;
 | 
			
		||||
    if (isMiddleButtonDown())   ++num;
 | 
			
		||||
 | 
			
		||||
    return num;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ModifierKeys ModifierKeys::getCurrentModifiersRealtime() noexcept
 | 
			
		||||
{
 | 
			
		||||
    return ComponentPeer::getCurrentModifiersRealtime();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace juce
 | 
			
		||||
 
 | 
			
		||||
@@ -1,211 +1,211 @@
 | 
			
		||||
/*
 | 
			
		||||
  ==============================================================================
 | 
			
		||||
 | 
			
		||||
   This file is part of the JUCE library.
 | 
			
		||||
   Copyright (c) 2020 - Raw Material Software Limited
 | 
			
		||||
 | 
			
		||||
   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 6 End-User License
 | 
			
		||||
   Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
 | 
			
		||||
 | 
			
		||||
   End User License Agreement: www.juce.com/juce-6-licence
 | 
			
		||||
   Privacy Policy: www.juce.com/juce-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
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
/**
 | 
			
		||||
    Represents the state of the mouse buttons and modifier keys.
 | 
			
		||||
 | 
			
		||||
    This is used both by mouse events and by KeyPress objects to describe
 | 
			
		||||
    the state of keys such as shift, control, alt, etc.
 | 
			
		||||
 | 
			
		||||
    @see KeyPress, MouseEvent::mods
 | 
			
		||||
 | 
			
		||||
    @tags{GUI}
 | 
			
		||||
*/
 | 
			
		||||
class JUCE_API  ModifierKeys
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Creates a ModifierKeys object with no flags set. */
 | 
			
		||||
    ModifierKeys() = default;
 | 
			
		||||
 | 
			
		||||
    /** Creates a ModifierKeys object from a raw set of flags.
 | 
			
		||||
 | 
			
		||||
        @param flags to represent the keys that are down
 | 
			
		||||
        @see    shiftModifier, ctrlModifier, altModifier, leftButtonModifier,
 | 
			
		||||
                rightButtonModifier, commandModifier, popupMenuClickModifier
 | 
			
		||||
    */
 | 
			
		||||
    ModifierKeys (int flags) noexcept;
 | 
			
		||||
 | 
			
		||||
    /** Creates a copy of another object. */
 | 
			
		||||
    ModifierKeys (const ModifierKeys&) = default;
 | 
			
		||||
 | 
			
		||||
    /** Copies this object from another one. */
 | 
			
		||||
    ModifierKeys& operator= (const ModifierKeys&) = default;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Checks whether the 'command' key flag is set (or 'ctrl' on Windows/Linux).
 | 
			
		||||
 | 
			
		||||
        This is a platform-agnostic way of checking for the operating system's
 | 
			
		||||
        preferred command-key modifier - so on the Mac it tests for the cmd key, on
 | 
			
		||||
        Windows/Linux, it's actually checking for the CTRL key.
 | 
			
		||||
    */
 | 
			
		||||
    inline bool isCommandDown() const noexcept          { return testFlags (commandModifier); }
 | 
			
		||||
 | 
			
		||||
    /** Checks whether the user is trying to launch a pop-up menu.
 | 
			
		||||
 | 
			
		||||
        This checks for platform-specific modifiers that might indicate that the user
 | 
			
		||||
        is following the operating system's normal method of showing a pop-up menu.
 | 
			
		||||
 | 
			
		||||
        So on Windows/Linux, this method is really testing for a right-click.
 | 
			
		||||
        On the Mac, it tests for either the CTRL key being down, or a right-click.
 | 
			
		||||
    */
 | 
			
		||||
    inline bool isPopupMenu() const noexcept            { return testFlags (popupMenuClickModifier); }
 | 
			
		||||
 | 
			
		||||
    /** Checks whether the flag is set for the left mouse-button. */
 | 
			
		||||
    inline bool isLeftButtonDown() const noexcept       { return testFlags (leftButtonModifier); }
 | 
			
		||||
 | 
			
		||||
    /** Checks whether the flag is set for the right mouse-button.
 | 
			
		||||
 | 
			
		||||
        Note that for detecting popup-menu clicks, you should be using isPopupMenu() instead, as
 | 
			
		||||
        this is platform-independent (and makes your code more explanatory too).
 | 
			
		||||
    */
 | 
			
		||||
    inline bool isRightButtonDown() const noexcept      { return testFlags (rightButtonModifier); }
 | 
			
		||||
 | 
			
		||||
    inline bool isMiddleButtonDown() const noexcept     { return testFlags (middleButtonModifier); }
 | 
			
		||||
 | 
			
		||||
    /** Tests for any of the mouse-button flags. */
 | 
			
		||||
    inline bool isAnyMouseButtonDown() const noexcept   { return testFlags (allMouseButtonModifiers); }
 | 
			
		||||
 | 
			
		||||
    /** Tests for any of the modifier key flags. */
 | 
			
		||||
    inline bool isAnyModifierKeyDown() const noexcept   { return testFlags ((shiftModifier | ctrlModifier | altModifier | commandModifier)); }
 | 
			
		||||
 | 
			
		||||
    /** Checks whether the shift key's flag is set. */
 | 
			
		||||
    inline bool isShiftDown() const noexcept            { return testFlags (shiftModifier); }
 | 
			
		||||
 | 
			
		||||
    /** Checks whether the CTRL key's flag is set.
 | 
			
		||||
 | 
			
		||||
        Remember that it's better to use the platform-agnostic routines to test for command-key and
 | 
			
		||||
        popup-menu modifiers.
 | 
			
		||||
 | 
			
		||||
        @see isCommandDown, isPopupMenu
 | 
			
		||||
    */
 | 
			
		||||
    inline bool isCtrlDown() const noexcept             { return testFlags (ctrlModifier); }
 | 
			
		||||
 | 
			
		||||
    /** Checks whether the ALT key's flag is set. */
 | 
			
		||||
    inline bool isAltDown() const noexcept              { return testFlags (altModifier); }
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Flags that represent the different keys. */
 | 
			
		||||
    enum Flags
 | 
			
		||||
    {
 | 
			
		||||
        /** Indicates no modifier keys. */
 | 
			
		||||
        noModifiers                             = 0,
 | 
			
		||||
 | 
			
		||||
        /** Shift key flag. */
 | 
			
		||||
        shiftModifier                           = 1,
 | 
			
		||||
 | 
			
		||||
        /** CTRL key flag. */
 | 
			
		||||
        ctrlModifier                            = 2,
 | 
			
		||||
 | 
			
		||||
        /** ALT key flag. */
 | 
			
		||||
        altModifier                             = 4,
 | 
			
		||||
 | 
			
		||||
        /** Left mouse button flag. */
 | 
			
		||||
        leftButtonModifier                      = 16,
 | 
			
		||||
 | 
			
		||||
        /** Right mouse button flag. */
 | 
			
		||||
        rightButtonModifier                     = 32,
 | 
			
		||||
 | 
			
		||||
        /** Middle mouse button flag. */
 | 
			
		||||
        middleButtonModifier                    = 64,
 | 
			
		||||
 | 
			
		||||
       #if JUCE_MAC || JUCE_IOS
 | 
			
		||||
        /** Command key flag - on windows this is the same as the CTRL key flag. */
 | 
			
		||||
        commandModifier                         = 8,
 | 
			
		||||
 | 
			
		||||
        /** Popup menu flag - on windows this is the same as rightButtonModifier, on the
 | 
			
		||||
            Mac it's the same as (rightButtonModifier | ctrlModifier). */
 | 
			
		||||
        popupMenuClickModifier                  = rightButtonModifier | ctrlModifier,
 | 
			
		||||
       #else
 | 
			
		||||
        /** Command key flag - on windows this is the same as the CTRL key flag. */
 | 
			
		||||
        commandModifier                         = ctrlModifier,
 | 
			
		||||
 | 
			
		||||
        /** Popup menu flag - on windows this is the same as rightButtonModifier, on the
 | 
			
		||||
            Mac it's the same as (rightButtonModifier | ctrlModifier). */
 | 
			
		||||
        popupMenuClickModifier                  = rightButtonModifier,
 | 
			
		||||
       #endif
 | 
			
		||||
 | 
			
		||||
        /** Represents a combination of all the shift, alt, ctrl and command key modifiers. */
 | 
			
		||||
        allKeyboardModifiers                    = shiftModifier | ctrlModifier | altModifier | commandModifier,
 | 
			
		||||
 | 
			
		||||
        /** Represents a combination of all the mouse buttons at once. */
 | 
			
		||||
        allMouseButtonModifiers                 = leftButtonModifier | rightButtonModifier | middleButtonModifier,
 | 
			
		||||
 | 
			
		||||
        /** Represents a combination of all the alt, ctrl and command key modifiers. */
 | 
			
		||||
        ctrlAltCommandModifiers                 = ctrlModifier | altModifier | commandModifier
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Returns a copy of only the mouse-button flags */
 | 
			
		||||
    ModifierKeys withOnlyMouseButtons() const noexcept                  { return ModifierKeys (flags & allMouseButtonModifiers); }
 | 
			
		||||
 | 
			
		||||
    /** Returns a copy of only the non-mouse flags */
 | 
			
		||||
    ModifierKeys withoutMouseButtons() const noexcept                   { return ModifierKeys (flags & ~allMouseButtonModifiers); }
 | 
			
		||||
 | 
			
		||||
    bool operator== (const ModifierKeys other) const noexcept           { return flags == other.flags; }
 | 
			
		||||
    bool operator!= (const ModifierKeys other) const noexcept           { return flags != other.flags; }
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Returns the raw flags for direct testing. */
 | 
			
		||||
    inline int getRawFlags() const noexcept                             { return flags; }
 | 
			
		||||
 | 
			
		||||
    ModifierKeys withoutFlags (int rawFlagsToClear) const noexcept      { return ModifierKeys (flags & ~rawFlagsToClear); }
 | 
			
		||||
    ModifierKeys withFlags (int rawFlagsToSet) const noexcept           { return ModifierKeys (flags | rawFlagsToSet); }
 | 
			
		||||
 | 
			
		||||
    /** Tests a combination of flags and returns true if any of them are set. */
 | 
			
		||||
    bool testFlags (int flagsToTest) const noexcept                     { return (flags & flagsToTest) != 0; }
 | 
			
		||||
 | 
			
		||||
    /** Returns the total number of mouse buttons that are down. */
 | 
			
		||||
    int getNumMouseButtonsDown() const noexcept;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** This object represents the last-known state of the keyboard and mouse buttons. */
 | 
			
		||||
    static ModifierKeys currentModifiers;
 | 
			
		||||
 | 
			
		||||
    /** Creates a ModifierKeys object to represent the last-known state of the
 | 
			
		||||
        keyboard and mouse buttons.
 | 
			
		||||
 | 
			
		||||
        This method is here for backwards compatibility and there's no need to call it anymore,
 | 
			
		||||
        you should use the public currentModifiers member directly.
 | 
			
		||||
     */
 | 
			
		||||
    static ModifierKeys getCurrentModifiers() noexcept                  { return currentModifiers; }
 | 
			
		||||
 | 
			
		||||
    /** Creates a ModifierKeys object to represent the current state of the
 | 
			
		||||
        keyboard and mouse buttons.
 | 
			
		||||
 | 
			
		||||
        This method is here for backwards compatibility and you should call ComponentPeer::getCurrentModifiersRealtime()
 | 
			
		||||
        instead (which is what this method now does).
 | 
			
		||||
    */
 | 
			
		||||
    static ModifierKeys getCurrentModifiersRealtime() noexcept;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    int flags = 0;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace juce
 | 
			
		||||
/*
 | 
			
		||||
  ==============================================================================
 | 
			
		||||
 | 
			
		||||
   This file is part of the JUCE library.
 | 
			
		||||
   Copyright (c) 2022 - Raw Material Software Limited
 | 
			
		||||
 | 
			
		||||
   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 7 End-User License
 | 
			
		||||
   Agreement and JUCE Privacy Policy.
 | 
			
		||||
 | 
			
		||||
   End User License Agreement: www.juce.com/juce-7-licence
 | 
			
		||||
   Privacy Policy: www.juce.com/juce-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
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
/**
 | 
			
		||||
    Represents the state of the mouse buttons and modifier keys.
 | 
			
		||||
 | 
			
		||||
    This is used both by mouse events and by KeyPress objects to describe
 | 
			
		||||
    the state of keys such as shift, control, alt, etc.
 | 
			
		||||
 | 
			
		||||
    @see KeyPress, MouseEvent::mods
 | 
			
		||||
 | 
			
		||||
    @tags{GUI}
 | 
			
		||||
*/
 | 
			
		||||
class JUCE_API  ModifierKeys
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Creates a ModifierKeys object with no flags set. */
 | 
			
		||||
    ModifierKeys() = default;
 | 
			
		||||
 | 
			
		||||
    /** Creates a ModifierKeys object from a raw set of flags.
 | 
			
		||||
 | 
			
		||||
        @param flags to represent the keys that are down
 | 
			
		||||
        @see    shiftModifier, ctrlModifier, altModifier, leftButtonModifier,
 | 
			
		||||
                rightButtonModifier, commandModifier, popupMenuClickModifier
 | 
			
		||||
    */
 | 
			
		||||
    ModifierKeys (int flags) noexcept;
 | 
			
		||||
 | 
			
		||||
    /** Creates a copy of another object. */
 | 
			
		||||
    ModifierKeys (const ModifierKeys&) = default;
 | 
			
		||||
 | 
			
		||||
    /** Copies this object from another one. */
 | 
			
		||||
    ModifierKeys& operator= (const ModifierKeys&) = default;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Checks whether the 'command' key flag is set (or 'ctrl' on Windows/Linux).
 | 
			
		||||
 | 
			
		||||
        This is a platform-agnostic way of checking for the operating system's
 | 
			
		||||
        preferred command-key modifier - so on the Mac it tests for the cmd key, on
 | 
			
		||||
        Windows/Linux, it's actually checking for the CTRL key.
 | 
			
		||||
    */
 | 
			
		||||
    inline bool isCommandDown() const noexcept          { return testFlags (commandModifier); }
 | 
			
		||||
 | 
			
		||||
    /** Checks whether the user is trying to launch a pop-up menu.
 | 
			
		||||
 | 
			
		||||
        This checks for platform-specific modifiers that might indicate that the user
 | 
			
		||||
        is following the operating system's normal method of showing a pop-up menu.
 | 
			
		||||
 | 
			
		||||
        So on Windows/Linux, this method is really testing for a right-click.
 | 
			
		||||
        On the Mac, it tests for either the CTRL key being down, or a right-click.
 | 
			
		||||
    */
 | 
			
		||||
    inline bool isPopupMenu() const noexcept            { return testFlags (popupMenuClickModifier); }
 | 
			
		||||
 | 
			
		||||
    /** Checks whether the flag is set for the left mouse-button. */
 | 
			
		||||
    inline bool isLeftButtonDown() const noexcept       { return testFlags (leftButtonModifier); }
 | 
			
		||||
 | 
			
		||||
    /** Checks whether the flag is set for the right mouse-button.
 | 
			
		||||
 | 
			
		||||
        Note that for detecting popup-menu clicks, you should be using isPopupMenu() instead, as
 | 
			
		||||
        this is platform-independent (and makes your code more explanatory too).
 | 
			
		||||
    */
 | 
			
		||||
    inline bool isRightButtonDown() const noexcept      { return testFlags (rightButtonModifier); }
 | 
			
		||||
 | 
			
		||||
    inline bool isMiddleButtonDown() const noexcept     { return testFlags (middleButtonModifier); }
 | 
			
		||||
 | 
			
		||||
    /** Tests for any of the mouse-button flags. */
 | 
			
		||||
    inline bool isAnyMouseButtonDown() const noexcept   { return testFlags (allMouseButtonModifiers); }
 | 
			
		||||
 | 
			
		||||
    /** Tests for any of the modifier key flags. */
 | 
			
		||||
    inline bool isAnyModifierKeyDown() const noexcept   { return testFlags ((shiftModifier | ctrlModifier | altModifier | commandModifier)); }
 | 
			
		||||
 | 
			
		||||
    /** Checks whether the shift key's flag is set. */
 | 
			
		||||
    inline bool isShiftDown() const noexcept            { return testFlags (shiftModifier); }
 | 
			
		||||
 | 
			
		||||
    /** Checks whether the CTRL key's flag is set.
 | 
			
		||||
 | 
			
		||||
        Remember that it's better to use the platform-agnostic routines to test for command-key and
 | 
			
		||||
        popup-menu modifiers.
 | 
			
		||||
 | 
			
		||||
        @see isCommandDown, isPopupMenu
 | 
			
		||||
    */
 | 
			
		||||
    inline bool isCtrlDown() const noexcept             { return testFlags (ctrlModifier); }
 | 
			
		||||
 | 
			
		||||
    /** Checks whether the ALT key's flag is set. */
 | 
			
		||||
    inline bool isAltDown() const noexcept              { return testFlags (altModifier); }
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Flags that represent the different keys. */
 | 
			
		||||
    enum Flags
 | 
			
		||||
    {
 | 
			
		||||
        /** Indicates no modifier keys. */
 | 
			
		||||
        noModifiers                             = 0,
 | 
			
		||||
 | 
			
		||||
        /** Shift key flag. */
 | 
			
		||||
        shiftModifier                           = 1,
 | 
			
		||||
 | 
			
		||||
        /** CTRL key flag. */
 | 
			
		||||
        ctrlModifier                            = 2,
 | 
			
		||||
 | 
			
		||||
        /** ALT key flag. */
 | 
			
		||||
        altModifier                             = 4,
 | 
			
		||||
 | 
			
		||||
        /** Left mouse button flag. */
 | 
			
		||||
        leftButtonModifier                      = 16,
 | 
			
		||||
 | 
			
		||||
        /** Right mouse button flag. */
 | 
			
		||||
        rightButtonModifier                     = 32,
 | 
			
		||||
 | 
			
		||||
        /** Middle mouse button flag. */
 | 
			
		||||
        middleButtonModifier                    = 64,
 | 
			
		||||
 | 
			
		||||
       #if JUCE_MAC || JUCE_IOS
 | 
			
		||||
        /** Command key flag - on windows this is the same as the CTRL key flag. */
 | 
			
		||||
        commandModifier                         = 8,
 | 
			
		||||
 | 
			
		||||
        /** Popup menu flag - on windows this is the same as rightButtonModifier, on the
 | 
			
		||||
            Mac it's the same as (rightButtonModifier | ctrlModifier). */
 | 
			
		||||
        popupMenuClickModifier                  = rightButtonModifier | ctrlModifier,
 | 
			
		||||
       #else
 | 
			
		||||
        /** Command key flag - on windows this is the same as the CTRL key flag. */
 | 
			
		||||
        commandModifier                         = ctrlModifier,
 | 
			
		||||
 | 
			
		||||
        /** Popup menu flag - on windows this is the same as rightButtonModifier, on the
 | 
			
		||||
            Mac it's the same as (rightButtonModifier | ctrlModifier). */
 | 
			
		||||
        popupMenuClickModifier                  = rightButtonModifier,
 | 
			
		||||
       #endif
 | 
			
		||||
 | 
			
		||||
        /** Represents a combination of all the shift, alt, ctrl and command key modifiers. */
 | 
			
		||||
        allKeyboardModifiers                    = shiftModifier | ctrlModifier | altModifier | commandModifier,
 | 
			
		||||
 | 
			
		||||
        /** Represents a combination of all the mouse buttons at once. */
 | 
			
		||||
        allMouseButtonModifiers                 = leftButtonModifier | rightButtonModifier | middleButtonModifier,
 | 
			
		||||
 | 
			
		||||
        /** Represents a combination of all the alt, ctrl and command key modifiers. */
 | 
			
		||||
        ctrlAltCommandModifiers                 = ctrlModifier | altModifier | commandModifier
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Returns a copy of only the mouse-button flags */
 | 
			
		||||
    JUCE_NODISCARD ModifierKeys withOnlyMouseButtons() const noexcept                  { return ModifierKeys (flags & allMouseButtonModifiers); }
 | 
			
		||||
 | 
			
		||||
    /** Returns a copy of only the non-mouse flags */
 | 
			
		||||
    JUCE_NODISCARD ModifierKeys withoutMouseButtons() const noexcept                   { return ModifierKeys (flags & ~allMouseButtonModifiers); }
 | 
			
		||||
 | 
			
		||||
    bool operator== (const ModifierKeys other) const noexcept                          { return flags == other.flags; }
 | 
			
		||||
    bool operator!= (const ModifierKeys other) const noexcept                          { return flags != other.flags; }
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** Returns the raw flags for direct testing. */
 | 
			
		||||
    inline int getRawFlags() const noexcept                                            { return flags; }
 | 
			
		||||
 | 
			
		||||
    JUCE_NODISCARD ModifierKeys withoutFlags (int rawFlagsToClear) const noexcept      { return ModifierKeys (flags & ~rawFlagsToClear); }
 | 
			
		||||
    JUCE_NODISCARD ModifierKeys withFlags (int rawFlagsToSet) const noexcept           { return ModifierKeys (flags | rawFlagsToSet); }
 | 
			
		||||
 | 
			
		||||
    /** Tests a combination of flags and returns true if any of them are set. */
 | 
			
		||||
    bool testFlags (int flagsToTest) const noexcept                                    { return (flags & flagsToTest) != 0; }
 | 
			
		||||
 | 
			
		||||
    /** Returns the total number of mouse buttons that are down. */
 | 
			
		||||
    int getNumMouseButtonsDown() const noexcept;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** This object represents the last-known state of the keyboard and mouse buttons. */
 | 
			
		||||
    static ModifierKeys currentModifiers;
 | 
			
		||||
 | 
			
		||||
    /** Creates a ModifierKeys object to represent the last-known state of the
 | 
			
		||||
        keyboard and mouse buttons.
 | 
			
		||||
 | 
			
		||||
        This method is here for backwards compatibility and there's no need to call it anymore,
 | 
			
		||||
        you should use the public currentModifiers member directly.
 | 
			
		||||
     */
 | 
			
		||||
    static ModifierKeys getCurrentModifiers() noexcept                                 { return currentModifiers; }
 | 
			
		||||
 | 
			
		||||
    /** Creates a ModifierKeys object to represent the current state of the
 | 
			
		||||
        keyboard and mouse buttons.
 | 
			
		||||
 | 
			
		||||
        This method is here for backwards compatibility and you should call ComponentPeer::getCurrentModifiersRealtime()
 | 
			
		||||
        instead (which is what this method now does).
 | 
			
		||||
    */
 | 
			
		||||
    static ModifierKeys getCurrentModifiersRealtime() noexcept;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    int flags = 0;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace juce
 | 
			
		||||
 
 | 
			
		||||
@@ -1,49 +1,49 @@
 | 
			
		||||
/*
 | 
			
		||||
  ==============================================================================
 | 
			
		||||
 | 
			
		||||
   This file is part of the JUCE library.
 | 
			
		||||
   Copyright (c) 2020 - Raw Material Software Limited
 | 
			
		||||
 | 
			
		||||
   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 6 End-User License
 | 
			
		||||
   Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
 | 
			
		||||
 | 
			
		||||
   End User License Agreement: www.juce.com/juce-6-licence
 | 
			
		||||
   Privacy Policy: www.juce.com/juce-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
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
/**
 | 
			
		||||
    Handles reading/writing to the system's clipboard.
 | 
			
		||||
 | 
			
		||||
    @tags{GUI}
 | 
			
		||||
*/
 | 
			
		||||
class JUCE_API  SystemClipboard
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    /** Copies a string of text onto the clipboard */
 | 
			
		||||
    static void copyTextToClipboard (const String& text);
 | 
			
		||||
 | 
			
		||||
    /** Gets the current clipboard's contents.
 | 
			
		||||
 | 
			
		||||
        Obviously this might have come from another app, so could contain
 | 
			
		||||
        anything..
 | 
			
		||||
    */
 | 
			
		||||
    static String getTextFromClipboard();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace juce
 | 
			
		||||
/*
 | 
			
		||||
  ==============================================================================
 | 
			
		||||
 | 
			
		||||
   This file is part of the JUCE library.
 | 
			
		||||
   Copyright (c) 2022 - Raw Material Software Limited
 | 
			
		||||
 | 
			
		||||
   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 7 End-User License
 | 
			
		||||
   Agreement and JUCE Privacy Policy.
 | 
			
		||||
 | 
			
		||||
   End User License Agreement: www.juce.com/juce-7-licence
 | 
			
		||||
   Privacy Policy: www.juce.com/juce-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
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
/**
 | 
			
		||||
    Handles reading/writing to the system's clipboard.
 | 
			
		||||
 | 
			
		||||
    @tags{GUI}
 | 
			
		||||
*/
 | 
			
		||||
class JUCE_API  SystemClipboard
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    /** Copies a string of text onto the clipboard */
 | 
			
		||||
    static void copyTextToClipboard (const String& text);
 | 
			
		||||
 | 
			
		||||
    /** Gets the current clipboard's contents.
 | 
			
		||||
 | 
			
		||||
        Obviously this might have come from another app, so could contain
 | 
			
		||||
        anything..
 | 
			
		||||
    */
 | 
			
		||||
    static String getTextFromClipboard();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace juce
 | 
			
		||||
 
 | 
			
		||||
@@ -1,123 +1,123 @@
 | 
			
		||||
/*
 | 
			
		||||
  ==============================================================================
 | 
			
		||||
 | 
			
		||||
   This file is part of the JUCE library.
 | 
			
		||||
   Copyright (c) 2020 - Raw Material Software Limited
 | 
			
		||||
 | 
			
		||||
   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 6 End-User License
 | 
			
		||||
   Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
 | 
			
		||||
 | 
			
		||||
   End User License Agreement: www.juce.com/juce-6-licence
 | 
			
		||||
   Privacy Policy: www.juce.com/juce-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
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
/** This class is used to invoke a range of text-editor navigation methods on
 | 
			
		||||
    an object, based upon a keypress event.
 | 
			
		||||
 | 
			
		||||
    It's currently used internally by the TextEditor and CodeEditorComponent.
 | 
			
		||||
 | 
			
		||||
    @tags{GUI}
 | 
			
		||||
*/
 | 
			
		||||
template <class CallbackClass>
 | 
			
		||||
struct TextEditorKeyMapper
 | 
			
		||||
{
 | 
			
		||||
    /** Checks the keypress and invokes one of a range of navigation functions that
 | 
			
		||||
        the target class must implement, based on the key event.
 | 
			
		||||
    */
 | 
			
		||||
    static bool invokeKeyFunction (CallbackClass& target, const KeyPress& key)
 | 
			
		||||
    {
 | 
			
		||||
        auto mods = key.getModifiers();
 | 
			
		||||
 | 
			
		||||
        const bool isShiftDown   = mods.isShiftDown();
 | 
			
		||||
        const bool ctrlOrAltDown = mods.isCtrlDown() || mods.isAltDown();
 | 
			
		||||
 | 
			
		||||
        int numCtrlAltCommandKeys = 0;
 | 
			
		||||
        if (mods.isCtrlDown())    ++numCtrlAltCommandKeys;
 | 
			
		||||
        if (mods.isAltDown())     ++numCtrlAltCommandKeys;
 | 
			
		||||
 | 
			
		||||
        if (key == KeyPress (KeyPress::downKey, ModifierKeys::ctrlModifier, 0) && target.scrollUp())   return true;
 | 
			
		||||
        if (key == KeyPress (KeyPress::upKey,   ModifierKeys::ctrlModifier, 0) && target.scrollDown()) return true;
 | 
			
		||||
 | 
			
		||||
       #if JUCE_MAC
 | 
			
		||||
        if (mods.isCommandDown() && ! ctrlOrAltDown)
 | 
			
		||||
        {
 | 
			
		||||
            if (key.isKeyCode (KeyPress::upKey))        return target.moveCaretToTop (isShiftDown);
 | 
			
		||||
            if (key.isKeyCode (KeyPress::downKey))      return target.moveCaretToEnd (isShiftDown);
 | 
			
		||||
            if (key.isKeyCode (KeyPress::leftKey))      return target.moveCaretToStartOfLine (isShiftDown);
 | 
			
		||||
            if (key.isKeyCode (KeyPress::rightKey))     return target.moveCaretToEndOfLine   (isShiftDown);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (mods.isCommandDown())
 | 
			
		||||
            ++numCtrlAltCommandKeys;
 | 
			
		||||
       #endif
 | 
			
		||||
 | 
			
		||||
        if (numCtrlAltCommandKeys < 2)
 | 
			
		||||
        {
 | 
			
		||||
            if (key.isKeyCode (KeyPress::leftKey))  return target.moveCaretLeft  (ctrlOrAltDown, isShiftDown);
 | 
			
		||||
            if (key.isKeyCode (KeyPress::rightKey)) return target.moveCaretRight (ctrlOrAltDown, isShiftDown);
 | 
			
		||||
 | 
			
		||||
            if (key.isKeyCode (KeyPress::homeKey))  return ctrlOrAltDown ? target.moveCaretToTop         (isShiftDown)
 | 
			
		||||
                                                                         : target.moveCaretToStartOfLine (isShiftDown);
 | 
			
		||||
            if (key.isKeyCode (KeyPress::endKey))   return ctrlOrAltDown ? target.moveCaretToEnd         (isShiftDown)
 | 
			
		||||
                                                                         : target.moveCaretToEndOfLine   (isShiftDown);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (numCtrlAltCommandKeys == 0)
 | 
			
		||||
        {
 | 
			
		||||
            if (key.isKeyCode (KeyPress::upKey))        return target.moveCaretUp   (isShiftDown);
 | 
			
		||||
            if (key.isKeyCode (KeyPress::downKey))      return target.moveCaretDown (isShiftDown);
 | 
			
		||||
 | 
			
		||||
            if (key.isKeyCode (KeyPress::pageUpKey))    return target.pageUp   (isShiftDown);
 | 
			
		||||
            if (key.isKeyCode (KeyPress::pageDownKey))  return target.pageDown (isShiftDown);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (key == KeyPress ('c', ModifierKeys::commandModifier, 0)
 | 
			
		||||
              || key == KeyPress (KeyPress::insertKey, ModifierKeys::ctrlModifier, 0))
 | 
			
		||||
            return target.copyToClipboard();
 | 
			
		||||
 | 
			
		||||
        if (key == KeyPress ('x', ModifierKeys::commandModifier, 0)
 | 
			
		||||
              || key == KeyPress (KeyPress::deleteKey, ModifierKeys::shiftModifier, 0))
 | 
			
		||||
            return target.cutToClipboard();
 | 
			
		||||
 | 
			
		||||
        if (key == KeyPress ('v', ModifierKeys::commandModifier, 0)
 | 
			
		||||
              || key == KeyPress (KeyPress::insertKey, ModifierKeys::shiftModifier, 0))
 | 
			
		||||
            return target.pasteFromClipboard();
 | 
			
		||||
 | 
			
		||||
        // NB: checking for delete must happen after the earlier check for shift + delete
 | 
			
		||||
        if (numCtrlAltCommandKeys < 2)
 | 
			
		||||
        {
 | 
			
		||||
            if (key.isKeyCode (KeyPress::backspaceKey)) return target.deleteBackwards (ctrlOrAltDown);
 | 
			
		||||
            if (key.isKeyCode (KeyPress::deleteKey))    return target.deleteForwards  (ctrlOrAltDown);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (key == KeyPress ('a', ModifierKeys::commandModifier, 0))
 | 
			
		||||
            return target.selectAll();
 | 
			
		||||
 | 
			
		||||
        if (key == KeyPress ('z', ModifierKeys::commandModifier, 0))
 | 
			
		||||
            return target.undo();
 | 
			
		||||
 | 
			
		||||
        if (key == KeyPress ('y', ModifierKeys::commandModifier, 0)
 | 
			
		||||
             || key == KeyPress ('z', ModifierKeys::commandModifier | ModifierKeys::shiftModifier, 0))
 | 
			
		||||
            return target.redo();
 | 
			
		||||
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace juce
 | 
			
		||||
/*
 | 
			
		||||
  ==============================================================================
 | 
			
		||||
 | 
			
		||||
   This file is part of the JUCE library.
 | 
			
		||||
   Copyright (c) 2022 - Raw Material Software Limited
 | 
			
		||||
 | 
			
		||||
   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 7 End-User License
 | 
			
		||||
   Agreement and JUCE Privacy Policy.
 | 
			
		||||
 | 
			
		||||
   End User License Agreement: www.juce.com/juce-7-licence
 | 
			
		||||
   Privacy Policy: www.juce.com/juce-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
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
/** This class is used to invoke a range of text-editor navigation methods on
 | 
			
		||||
    an object, based upon a keypress event.
 | 
			
		||||
 | 
			
		||||
    It's currently used internally by the TextEditor and CodeEditorComponent.
 | 
			
		||||
 | 
			
		||||
    @tags{GUI}
 | 
			
		||||
*/
 | 
			
		||||
template <class CallbackClass>
 | 
			
		||||
struct TextEditorKeyMapper
 | 
			
		||||
{
 | 
			
		||||
    /** Checks the keypress and invokes one of a range of navigation functions that
 | 
			
		||||
        the target class must implement, based on the key event.
 | 
			
		||||
    */
 | 
			
		||||
    static bool invokeKeyFunction (CallbackClass& target, const KeyPress& key)
 | 
			
		||||
    {
 | 
			
		||||
        auto mods = key.getModifiers();
 | 
			
		||||
 | 
			
		||||
        const bool isShiftDown   = mods.isShiftDown();
 | 
			
		||||
        const bool ctrlOrAltDown = mods.isCtrlDown() || mods.isAltDown();
 | 
			
		||||
 | 
			
		||||
        int numCtrlAltCommandKeys = 0;
 | 
			
		||||
        if (mods.isCtrlDown())    ++numCtrlAltCommandKeys;
 | 
			
		||||
        if (mods.isAltDown())     ++numCtrlAltCommandKeys;
 | 
			
		||||
 | 
			
		||||
        if (key == KeyPress (KeyPress::downKey, ModifierKeys::ctrlModifier, 0) && target.scrollUp())   return true;
 | 
			
		||||
        if (key == KeyPress (KeyPress::upKey,   ModifierKeys::ctrlModifier, 0) && target.scrollDown()) return true;
 | 
			
		||||
 | 
			
		||||
       #if JUCE_MAC
 | 
			
		||||
        if (mods.isCommandDown() && ! ctrlOrAltDown)
 | 
			
		||||
        {
 | 
			
		||||
            if (key.isKeyCode (KeyPress::upKey))        return target.moveCaretToTop (isShiftDown);
 | 
			
		||||
            if (key.isKeyCode (KeyPress::downKey))      return target.moveCaretToEnd (isShiftDown);
 | 
			
		||||
            if (key.isKeyCode (KeyPress::leftKey))      return target.moveCaretToStartOfLine (isShiftDown);
 | 
			
		||||
            if (key.isKeyCode (KeyPress::rightKey))     return target.moveCaretToEndOfLine   (isShiftDown);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (mods.isCommandDown())
 | 
			
		||||
            ++numCtrlAltCommandKeys;
 | 
			
		||||
       #endif
 | 
			
		||||
 | 
			
		||||
        if (numCtrlAltCommandKeys < 2)
 | 
			
		||||
        {
 | 
			
		||||
            if (key.isKeyCode (KeyPress::leftKey))  return target.moveCaretLeft  (ctrlOrAltDown, isShiftDown);
 | 
			
		||||
            if (key.isKeyCode (KeyPress::rightKey)) return target.moveCaretRight (ctrlOrAltDown, isShiftDown);
 | 
			
		||||
 | 
			
		||||
            if (key.isKeyCode (KeyPress::homeKey))  return ctrlOrAltDown ? target.moveCaretToTop         (isShiftDown)
 | 
			
		||||
                                                                         : target.moveCaretToStartOfLine (isShiftDown);
 | 
			
		||||
            if (key.isKeyCode (KeyPress::endKey))   return ctrlOrAltDown ? target.moveCaretToEnd         (isShiftDown)
 | 
			
		||||
                                                                         : target.moveCaretToEndOfLine   (isShiftDown);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (numCtrlAltCommandKeys == 0)
 | 
			
		||||
        {
 | 
			
		||||
            if (key.isKeyCode (KeyPress::upKey))        return target.moveCaretUp   (isShiftDown);
 | 
			
		||||
            if (key.isKeyCode (KeyPress::downKey))      return target.moveCaretDown (isShiftDown);
 | 
			
		||||
 | 
			
		||||
            if (key.isKeyCode (KeyPress::pageUpKey))    return target.pageUp   (isShiftDown);
 | 
			
		||||
            if (key.isKeyCode (KeyPress::pageDownKey))  return target.pageDown (isShiftDown);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (key == KeyPress ('c', ModifierKeys::commandModifier, 0)
 | 
			
		||||
              || key == KeyPress (KeyPress::insertKey, ModifierKeys::ctrlModifier, 0))
 | 
			
		||||
            return target.copyToClipboard();
 | 
			
		||||
 | 
			
		||||
        if (key == KeyPress ('x', ModifierKeys::commandModifier, 0)
 | 
			
		||||
              || key == KeyPress (KeyPress::deleteKey, ModifierKeys::shiftModifier, 0))
 | 
			
		||||
            return target.cutToClipboard();
 | 
			
		||||
 | 
			
		||||
        if (key == KeyPress ('v', ModifierKeys::commandModifier, 0)
 | 
			
		||||
              || key == KeyPress (KeyPress::insertKey, ModifierKeys::shiftModifier, 0))
 | 
			
		||||
            return target.pasteFromClipboard();
 | 
			
		||||
 | 
			
		||||
        // NB: checking for delete must happen after the earlier check for shift + delete
 | 
			
		||||
        if (numCtrlAltCommandKeys < 2)
 | 
			
		||||
        {
 | 
			
		||||
            if (key.isKeyCode (KeyPress::backspaceKey)) return target.deleteBackwards (ctrlOrAltDown);
 | 
			
		||||
            if (key.isKeyCode (KeyPress::deleteKey))    return target.deleteForwards  (ctrlOrAltDown);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (key == KeyPress ('a', ModifierKeys::commandModifier, 0))
 | 
			
		||||
            return target.selectAll();
 | 
			
		||||
 | 
			
		||||
        if (key == KeyPress ('z', ModifierKeys::commandModifier, 0))
 | 
			
		||||
            return target.undo();
 | 
			
		||||
 | 
			
		||||
        if (key == KeyPress ('y', ModifierKeys::commandModifier, 0)
 | 
			
		||||
             || key == KeyPress ('z', ModifierKeys::commandModifier | ModifierKeys::shiftModifier, 0))
 | 
			
		||||
            return target.redo();
 | 
			
		||||
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace juce
 | 
			
		||||
 
 | 
			
		||||
@@ -1,96 +1,120 @@
 | 
			
		||||
/*
 | 
			
		||||
  ==============================================================================
 | 
			
		||||
 | 
			
		||||
   This file is part of the JUCE library.
 | 
			
		||||
   Copyright (c) 2020 - Raw Material Software Limited
 | 
			
		||||
 | 
			
		||||
   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 6 End-User License
 | 
			
		||||
   Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
 | 
			
		||||
 | 
			
		||||
   End User License Agreement: www.juce.com/juce-6-licence
 | 
			
		||||
   Privacy Policy: www.juce.com/juce-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
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
/**
 | 
			
		||||
    An abstract base class which can be implemented by components that function as
 | 
			
		||||
    text editors.
 | 
			
		||||
 | 
			
		||||
    This class allows different types of text editor component to provide a uniform
 | 
			
		||||
    interface, which can be used by things like OS-specific input methods, on-screen
 | 
			
		||||
    keyboards, etc.
 | 
			
		||||
 | 
			
		||||
    @tags{GUI}
 | 
			
		||||
*/
 | 
			
		||||
class JUCE_API  TextInputTarget
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** */
 | 
			
		||||
    TextInputTarget() = default;
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    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.
 | 
			
		||||
    */
 | 
			
		||||
    virtual bool isTextInputActive() const = 0;
 | 
			
		||||
 | 
			
		||||
    /** Returns the extents of the selected text region, or an empty range if
 | 
			
		||||
        nothing is selected,
 | 
			
		||||
    */
 | 
			
		||||
    virtual Range<int> getHighlightedRegion() const = 0;
 | 
			
		||||
 | 
			
		||||
    /** Sets the currently-selected text region. */
 | 
			
		||||
    virtual void setHighlightedRegion (const Range<int>& newRange) = 0;
 | 
			
		||||
 | 
			
		||||
    /** Sets a number of temporarily underlined sections.
 | 
			
		||||
        This is needed by MS Windows input method UI.
 | 
			
		||||
    */
 | 
			
		||||
    virtual void setTemporaryUnderlining (const Array<Range<int>>& underlinedRegions) = 0;
 | 
			
		||||
 | 
			
		||||
    /** Returns a specified sub-section of the text. */
 | 
			
		||||
    virtual String getTextInRange (const Range<int>& range) const = 0;
 | 
			
		||||
 | 
			
		||||
    /** Inserts some text, overwriting the selected text region, if there is one. */
 | 
			
		||||
    virtual void insertTextAtCaret (const String& textToInsert) = 0;
 | 
			
		||||
 | 
			
		||||
    /** Returns the position of the caret, relative to the component's origin. */
 | 
			
		||||
    virtual Rectangle<int> getCaretRectangle() = 0;
 | 
			
		||||
 | 
			
		||||
    /** A set of possible on-screen keyboard types, for use in the
 | 
			
		||||
        getKeyboardType() method.
 | 
			
		||||
    */
 | 
			
		||||
    enum VirtualKeyboardType
 | 
			
		||||
    {
 | 
			
		||||
        textKeyboard = 0,
 | 
			
		||||
        numericKeyboard,
 | 
			
		||||
        decimalKeyboard,
 | 
			
		||||
        urlKeyboard,
 | 
			
		||||
        emailAddressKeyboard,
 | 
			
		||||
        phoneNumberKeyboard
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /** Returns the target's preference for the type of keyboard that would be most appropriate.
 | 
			
		||||
        This may be ignored, depending on the capabilities of the OS.
 | 
			
		||||
    */
 | 
			
		||||
    virtual VirtualKeyboardType getKeyboardType()       { return textKeyboard; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace juce
 | 
			
		||||
/*
 | 
			
		||||
  ==============================================================================
 | 
			
		||||
 | 
			
		||||
   This file is part of the JUCE library.
 | 
			
		||||
   Copyright (c) 2022 - Raw Material Software Limited
 | 
			
		||||
 | 
			
		||||
   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 7 End-User License
 | 
			
		||||
   Agreement and JUCE Privacy Policy.
 | 
			
		||||
 | 
			
		||||
   End User License Agreement: www.juce.com/juce-7-licence
 | 
			
		||||
   Privacy Policy: www.juce.com/juce-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
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
/**
 | 
			
		||||
    An abstract base class which can be implemented by components that function as
 | 
			
		||||
    text editors.
 | 
			
		||||
 | 
			
		||||
    This class allows different types of text editor component to provide a uniform
 | 
			
		||||
    interface, which can be used by things like OS-specific input methods, on-screen
 | 
			
		||||
    keyboards, etc.
 | 
			
		||||
 | 
			
		||||
    @tags{GUI}
 | 
			
		||||
*/
 | 
			
		||||
class JUCE_API  TextInputTarget
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    /** */
 | 
			
		||||
    TextInputTarget() = default;
 | 
			
		||||
 | 
			
		||||
    /** Destructor. */
 | 
			
		||||
    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.
 | 
			
		||||
    */
 | 
			
		||||
    virtual bool isTextInputActive() const = 0;
 | 
			
		||||
 | 
			
		||||
    /** Returns the extents of the selected text region, or an empty range if
 | 
			
		||||
        nothing is selected,
 | 
			
		||||
    */
 | 
			
		||||
    virtual Range<int> getHighlightedRegion() const = 0;
 | 
			
		||||
 | 
			
		||||
    /** Sets the currently-selected text region. */
 | 
			
		||||
    virtual void setHighlightedRegion (const Range<int>& newRange) = 0;
 | 
			
		||||
 | 
			
		||||
    /** Sets a number of temporarily underlined sections.
 | 
			
		||||
        This is needed by MS Windows input method UI.
 | 
			
		||||
    */
 | 
			
		||||
    virtual void setTemporaryUnderlining (const Array<Range<int>>& underlinedRegions) = 0;
 | 
			
		||||
 | 
			
		||||
    /** Returns a specified sub-section of the text. */
 | 
			
		||||
    virtual String getTextInRange (const Range<int>& range) const = 0;
 | 
			
		||||
 | 
			
		||||
    /** Inserts some text, overwriting the selected text region, if there is one. */
 | 
			
		||||
    virtual void insertTextAtCaret (const String& textToInsert) = 0;
 | 
			
		||||
 | 
			
		||||
    /** Returns the current index of the caret. */
 | 
			
		||||
    virtual int getCaretPosition() const = 0;
 | 
			
		||||
 | 
			
		||||
    /** Returns the position of the caret, relative to the component's origin. */
 | 
			
		||||
    Rectangle<int> getCaretRectangle() const        { return getCaretRectangleForCharIndex (getCaretPosition()); }
 | 
			
		||||
 | 
			
		||||
    /** Returns the bounding box of the character at the given index. */
 | 
			
		||||
    virtual Rectangle<int> getCaretRectangleForCharIndex (int characterIndex) const = 0;
 | 
			
		||||
 | 
			
		||||
    /** Returns the total number of codepoints in the string. */
 | 
			
		||||
    virtual int getTotalNumChars() const = 0;
 | 
			
		||||
 | 
			
		||||
    /** Returns the index closest to the given point.
 | 
			
		||||
 | 
			
		||||
        This is the location where the cursor might be placed after clicking at the given
 | 
			
		||||
        point in a text field.
 | 
			
		||||
    */
 | 
			
		||||
    virtual int getCharIndexForPoint (Point<int> point) const = 0;
 | 
			
		||||
 | 
			
		||||
    /** Returns the bounding box for a range of text in the editor. As the range may span
 | 
			
		||||
        multiple lines, this method returns a RectangleList.
 | 
			
		||||
 | 
			
		||||
        The bounds are relative to the component's top-left and may extend beyond the bounds
 | 
			
		||||
        of the component if the text is long and word wrapping is disabled.
 | 
			
		||||
    */
 | 
			
		||||
    virtual RectangleList<int> getTextBounds (Range<int> textRange) const = 0;
 | 
			
		||||
 | 
			
		||||
    /** A set of possible on-screen keyboard types, for use in the
 | 
			
		||||
        getKeyboardType() method.
 | 
			
		||||
    */
 | 
			
		||||
    enum VirtualKeyboardType
 | 
			
		||||
    {
 | 
			
		||||
        textKeyboard = 0,
 | 
			
		||||
        numericKeyboard,
 | 
			
		||||
        decimalKeyboard,
 | 
			
		||||
        urlKeyboard,
 | 
			
		||||
        emailAddressKeyboard,
 | 
			
		||||
        phoneNumberKeyboard
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /** Returns the target's preference for the type of keyboard that would be most appropriate.
 | 
			
		||||
        This may be ignored, depending on the capabilities of the OS.
 | 
			
		||||
    */
 | 
			
		||||
    virtual VirtualKeyboardType getKeyboardType()       { return textKeyboard; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace juce
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user