migrating to the latest JUCE version

This commit is contained in:
2022-11-04 23:11:33 +01:00
committed by Nikolai Rodionov
parent 4257a0f8ba
commit faf8f18333
2796 changed files with 888518 additions and 784244 deletions

View File

@ -1,119 +1,119 @@
/*
==============================================================================
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 action that can be performed by an accessible UI element.
@tags{Accessibility}
*/
enum class AccessibilityActionType
{
/** Represents a "press" action.
This will be called when the user "clicks" the UI element using an
accessibility client.
*/
press,
/** Represents a "toggle" action.
This will be called when the user toggles the state of a UI element,
for example a toggle button or the selection of a list item.
*/
toggle,
/** Indicates that the UI element has received focus.
This will be called when a UI element receives focus from an accessibility
client, or keyboard focus from the application.
*/
focus,
/** Represents the user showing a contextual menu for a UI element.
This will be called for UI elements which expand and collapse to
show contextual information or menus, or show a popup.
*/
showMenu
};
/** A simple wrapper for building a collection of supported accessibility actions
and corresponding callbacks for a UI element.
Pass one of these when constructing an `AccessibilityHandler` to enable users
to interact with a UI element via the supported actions.
@tags{Accessibility}
*/
class JUCE_API AccessibilityActions
{
public:
/** Constructor.
Creates a default AccessibilityActions object with no action callbacks.
*/
AccessibilityActions() = default;
/** Adds an action.
When the user performs this action with an accessibility client
`actionCallback` will be called.
Returns a reference to itself so that several calls can be chained.
*/
AccessibilityActions& addAction (AccessibilityActionType type,
std::function<void()> actionCallback)
{
actionMap[type] = std::move (actionCallback);
return *this;
}
/** Returns true if the specified action is supported. */
bool contains (AccessibilityActionType type) const
{
return actionMap.find (type) != actionMap.end();
}
/** If an action has been registered for the provided action type, invokes the
action and returns true. Otherwise, returns false.
*/
bool invoke (AccessibilityActionType type) const
{
auto iter = actionMap.find (type);
if (iter == actionMap.end())
return false;
iter->second();
return true;
}
private:
std::map<AccessibilityActionType, std::function<void()>> actionMap;
};
} // 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 action that can be performed by an accessible UI element.
@tags{Accessibility}
*/
enum class AccessibilityActionType
{
/** Represents a "press" action.
This will be called when the user "clicks" the UI element using an
accessibility client.
*/
press,
/** Represents a "toggle" action.
This will be called when the user toggles the state of a UI element,
for example a toggle button or the selection of a list item.
*/
toggle,
/** Indicates that the UI element has received focus.
This will be called when a UI element receives focus from an accessibility
client, or keyboard focus from the application.
*/
focus,
/** Represents the user showing a contextual menu for a UI element.
This will be called for UI elements which expand and collapse to
show contextual information or menus, or show a popup.
*/
showMenu
};
/** A simple wrapper for building a collection of supported accessibility actions
and corresponding callbacks for a UI element.
Pass one of these when constructing an `AccessibilityHandler` to enable users
to interact with a UI element via the supported actions.
@tags{Accessibility}
*/
class JUCE_API AccessibilityActions
{
public:
/** Constructor.
Creates a default AccessibilityActions object with no action callbacks.
*/
AccessibilityActions() = default;
/** Adds an action.
When the user performs this action with an accessibility client
`actionCallback` will be called.
Returns a reference to itself so that several calls can be chained.
*/
AccessibilityActions& addAction (AccessibilityActionType type,
std::function<void()> actionCallback)
{
actionMap[type] = std::move (actionCallback);
return *this;
}
/** Returns true if the specified action is supported. */
bool contains (AccessibilityActionType type) const
{
return actionMap.find (type) != actionMap.end();
}
/** If an action has been registered for the provided action type, invokes the
action and returns true. Otherwise, returns false.
*/
bool invoke (AccessibilityActionType type) const
{
auto iter = actionMap.find (type);
if (iter == actionMap.end())
return false;
iter->second();
return true;
}
private:
std::map<AccessibilityActionType, std::function<void()>> actionMap;
};
} // namespace juce

View File

@ -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
{
/** A list of events that can be notified to any subscribed accessibility clients.
To post a notification, call `AccessibilityHandler::notifyAccessibilityEvent`
on the associated handler with the appropriate `AccessibilityEvent` type and
listening clients will be notified.
@tags{Accessibility}
*/
enum class AccessibilityEvent
{
/** Indicates that the UI element's value has changed.
This should be called on the handler that implements `AccessibilityValueInterface`
for the UI element that has changed.
*/
valueChanged,
/** Indicates that the title of the UI element has changed.
This should be called on the handler whose title has changed.
*/
titleChanged,
/** Indicates that the structure of the UI elements has changed in a
significant way.
This should be called on the top-level handler whose structure has changed.
*/
structureChanged,
/** Indicates that the selection of a text element has changed.
This should be called on the handler that implements `AccessibilityTextInterface`
for the text element that has changed.
*/
textSelectionChanged,
/** Indicates that the visible text of a text element has changed.
This should be called on the handler that implements `AccessibilityTextInterface`
for the text element that has changed.
*/
textChanged,
/** Indicates that the selection of rows in a list or table has changed.
This should be called on the handler that implements `AccessibilityTableInterface`
for the UI element that has changed.
*/
rowSelectionChanged
};
}
/*
==============================================================================
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
{
/** A list of events that can be notified to any subscribed accessibility clients.
To post a notification, call `AccessibilityHandler::notifyAccessibilityEvent`
on the associated handler with the appropriate `AccessibilityEvent` type and
listening clients will be notified.
@tags{Accessibility}
*/
enum class AccessibilityEvent
{
/** Indicates that the UI element's value has changed.
This should be called on the handler that implements `AccessibilityValueInterface`
for the UI element that has changed.
*/
valueChanged,
/** Indicates that the title of the UI element has changed.
This should be called on the handler whose title has changed.
*/
titleChanged,
/** Indicates that the structure of the UI elements has changed in a
significant way.
This should be called on the top-level handler whose structure has changed.
*/
structureChanged,
/** Indicates that the selection of a text element has changed.
This should be called on the handler that implements `AccessibilityTextInterface`
for the text element that has changed.
*/
textSelectionChanged,
/** Indicates that the visible text of a text element has changed.
This should be called on the handler that implements `AccessibilityTextInterface`
for the text element that has changed.
*/
textChanged,
/** Indicates that the selection of rows in a list or table has changed.
This should be called on the handler that implements `AccessibilityTableInterface`
for the UI element that has changed.
*/
rowSelectionChanged
};
}

View File

@ -1,71 +1,71 @@
/*
==============================================================================
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
{
/** The list of available roles for an AccessibilityHandler object.
When creating a custom AccessibilityHandler you should select the role that
best describes the UI element being represented.
@tags{Accessibility}
*/
enum class AccessibilityRole
{
button,
toggleButton,
radioButton,
comboBox,
image,
slider,
label,
staticText,
editableText,
menuItem,
menuBar,
popupMenu,
table,
tableHeader,
column,
row,
cell,
hyperlink,
list,
listItem,
tree,
treeItem,
progressBar,
group,
dialogWindow,
window,
scrollBar,
tooltip,
splashScreen,
ignored,
unspecified
};
}
/*
==============================================================================
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
{
/** The list of available roles for an AccessibilityHandler object.
When creating a custom AccessibilityHandler you should select the role that
best describes the UI element being represented.
@tags{Accessibility}
*/
enum class AccessibilityRole
{
button,
toggleButton,
radioButton,
comboBox,
image,
slider,
label,
staticText,
editableText,
menuItem,
menuBar,
popupMenu,
table,
tableHeader,
column,
row,
cell,
hyperlink,
list,
listItem,
tree,
treeItem,
progressBar,
group,
dialogWindow,
window,
scrollBar,
tooltip,
splashScreen,
ignored,
unspecified
};
}

View File

@ -1,61 +1,52 @@
/*
==============================================================================
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 interface which represents a UI element that supports a cell interface.
This typically represents a single cell inside of a UI element which implements an
AccessibilityTableInterface.
@tags{Accessibility}
*/
class JUCE_API AccessibilityCellInterface
{
public:
/** Destructor. */
virtual ~AccessibilityCellInterface() = default;
/** Returns the column index of the cell in the table. */
virtual int getColumnIndex() const = 0;
/** Returns the number of columns occupied by the cell in the table. */
virtual int getColumnSpan() const = 0;
/** Returns the row index of the cell in the table. */
virtual int getRowIndex() const = 0;
/** Returns the number of rows occupied by the cell in the table. */
virtual int getRowSpan() const = 0;
/** Returns the indentation level for the cell. */
virtual int getDisclosureLevel() const = 0;
/** Returns the AccessibilityHandler of the table which contains the cell. */
virtual const AccessibilityHandler* getTableHandler() const = 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
{
/** An abstract interface which represents a UI element that supports a cell interface.
This typically represents a single cell inside of a UI element which implements an
AccessibilityTableInterface.
@tags{Accessibility}
*/
class JUCE_API AccessibilityCellInterface
{
public:
/** Destructor. */
virtual ~AccessibilityCellInterface() = default;
/** Returns the indentation level for the cell. */
virtual int getDisclosureLevel() const = 0;
/** Returns the AccessibilityHandler of the table which contains the cell. */
virtual const AccessibilityHandler* getTableHandler() const = 0;
/** Returns a list of the accessibility elements that are disclosed by this element, if any. */
virtual std::vector<const AccessibilityHandler*> getDisclosedRows() const { return {}; }
};
} // namespace juce

View File

@ -1,54 +1,96 @@
/*
==============================================================================
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 interface which represents a UI element that supports a table interface.
Examples of UI elements which typically support a table interface are lists, tables,
and trees.
@tags{Accessibility}
*/
class JUCE_API AccessibilityTableInterface
{
public:
/** Destructor. */
virtual ~AccessibilityTableInterface() = default;
/** Returns the total number of rows in the table. */
virtual int getNumRows() const = 0;
/** Returns the total number of columns in the table. */
virtual int getNumColumns() const = 0;
/** Returns the AccessibilityHandler for one of the cells in the table, or
nullptr if there is no cell at the specified position.
*/
virtual const AccessibilityHandler* getCellHandler (int row, int column) const = 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
{
/** An abstract interface which represents a UI element that supports a table interface.
Examples of UI elements which typically support a table interface are lists, tables,
and trees.
@tags{Accessibility}
*/
class JUCE_API AccessibilityTableInterface
{
public:
/** Destructor. */
virtual ~AccessibilityTableInterface() = default;
/** Returns the total number of rows in the table. */
virtual int getNumRows() const = 0;
/** Returns the total number of columns in the table. */
virtual int getNumColumns() const = 0;
/** Returns the AccessibilityHandler for one of the cells in the table, or
nullptr if there is no cell at the specified position.
*/
virtual const AccessibilityHandler* getCellHandler (int row, int column) const = 0;
/** Returns the AccessibilityHandler for a row in the table, or nullptr if there is
no row at this index.
The row component should have a child component for each column in the table.
*/
virtual const AccessibilityHandler* getRowHandler (int row) const = 0;
/** Returns the AccessibilityHandler for the header, or nullptr if there is
no header.
If you supply a header, it must have exactly the same number of children
as there are columns in the table.
*/
virtual const AccessibilityHandler* getHeaderHandler() const = 0;
struct Span { int begin, num; };
/** Given the handler of one of the cells in the table, returns the rows covered
by that cell, or null if the cell does not exist in the table.
This function replaces the getRowIndex and getRowSpan
functions from AccessibilityCellInterface. Most of the time, it's easier for the
table itself to keep track of cell locations, than to delegate to the individual
cells.
*/
virtual Optional<Span> getRowSpan (const AccessibilityHandler&) const = 0;
/** Given the handler of one of the cells in the table, returns the columns covered
by that cell, or null if the cell does not exist in the table.
This function replaces the getColumnIndex and getColumnSpan
functions from AccessibilityCellInterface. Most of the time, it's easier for the
table itself to keep track of cell locations, than to delegate to the individual
cells.
*/
virtual Optional<Span> getColumnSpan (const AccessibilityHandler&) const = 0;
/** Attempts to scroll the table (if necessary) so that the cell with the given handler
is visible.
*/
virtual void showCell (const AccessibilityHandler&) const = 0;
};
} // namespace juce

View File

@ -1,81 +1,84 @@
/*
==============================================================================
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 interface which represents a UI element that supports a text interface.
A UI element can use this interface to provide extended textual information which
cannot be conveyed using just the title, description, and help text properties of
AccessibilityHandler. This is typically for text that an accessibility client might
want to read line-by-line, or provide text selection and input for.
@tags{Accessibility}
*/
class JUCE_API AccessibilityTextInterface
{
public:
/** Destructor. */
virtual ~AccessibilityTextInterface() = default;
/** Returns true if the text being displayed is protected and should not be
exposed to the user, for example a password entry field.
*/
virtual bool isDisplayingProtectedText() const = 0;
/** Returns true if the text being displayed is read-only or false if editable. */
virtual bool isReadOnly() const = 0;
/** Returns the total number of characters in the text element. */
virtual int getTotalNumCharacters() const = 0;
/** Returns the range of characters that are currently selected, or an empty
range if nothing is selected.
*/
virtual Range<int> getSelection() const = 0;
/** Selects a section of the text. */
virtual void setSelection (Range<int> newRange) = 0;
/** Gets the current text insertion position, if supported. */
virtual int getTextInsertionOffset() const = 0;
/** Returns a section of text. */
virtual String getText (Range<int> range) const = 0;
/** Replaces the text with a new string. */
virtual void setText (const String& newText) = 0;
/** Returns the bounding box in screen coordinates for a range of text.
As the range may span multiple lines, this method returns a RectangleList.
*/
virtual RectangleList<int> getTextBounds (Range<int> textRange) const = 0;
/** Returns the index of the character at a given position in screen coordinates. */
virtual int getOffsetAtPoint (Point<int> point) const = 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
{
/** An abstract interface which represents a UI element that supports a text interface.
A UI element can use this interface to provide extended textual information which
cannot be conveyed using just the title, description, and help text properties of
AccessibilityHandler. This is typically for text that an accessibility client might
want to read line-by-line, or provide text selection and input for.
@tags{Accessibility}
*/
class JUCE_API AccessibilityTextInterface
{
public:
/** Destructor. */
virtual ~AccessibilityTextInterface() = default;
/** Returns true if the text being displayed is protected and should not be
exposed to the user, for example a password entry field.
*/
virtual bool isDisplayingProtectedText() const = 0;
/** Returns true if the text being displayed is read-only or false if editable. */
virtual bool isReadOnly() const = 0;
/** Returns the total number of characters in the text element. */
virtual int getTotalNumCharacters() const = 0;
/** Returns the range of characters that are currently selected, or an empty
range if nothing is selected.
*/
virtual Range<int> getSelection() const = 0;
/** Selects a section of the text. */
virtual void setSelection (Range<int> newRange) = 0;
/** Gets the current text insertion position, if supported. */
virtual int getTextInsertionOffset() const = 0;
/** Returns a section of text. */
virtual String getText (Range<int> range) const = 0;
/** Returns the full text. */
String getAllText() const { return getText ({ 0, getTotalNumCharacters() }); }
/** Replaces the text with a new string. */
virtual void setText (const String& newText) = 0;
/** Returns the bounding box in screen coordinates for a range of text.
As the range may span multiple lines, this method returns a RectangleList.
*/
virtual RectangleList<int> getTextBounds (Range<int> textRange) const = 0;
/** Returns the index of the character at a given position in screen coordinates. */
virtual int getOffsetAtPoint (Point<int> point) const = 0;
};
} // namespace juce

View File

@ -1,222 +1,222 @@
/*
==============================================================================
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 interface representing the value of an accessibility element.
Values should be used when information needs to be conveyed which cannot
be represented by the accessibility element's label alone. For example, a
gain slider with the label "Gain" needs to also provide a value for its
position whereas a "Save" button does not.
This class allows for full control over the value text/numeric conversion,
ranged, and read-only properties but in most cases you'll want to use one
of the derived classes below which handle some of this for you.
@see AccessibilityTextValueInterface, AccessibilityNumericValueInterface,
AccessibilityRangedNumericValueInterface
@tags{Accessibility}
*/
class JUCE_API AccessibilityValueInterface
{
public:
/** Destructor. */
virtual ~AccessibilityValueInterface() = default;
/** Returns true if the value is read-only and cannot be modified by an
accessibility client.
@see setValue, setValueAsString
*/
virtual bool isReadOnly() const = 0;
/** Returns the current value as a double. */
virtual double getCurrentValue() const = 0;
/** Returns the current value as a String. */
virtual String getCurrentValueAsString() const = 0;
/** Sets the current value to a new double value. */
virtual void setValue (double newValue) = 0;
/** Sets the current value to a new String value. */
virtual void setValueAsString (const String& newValue) = 0;
/** Represents the range of this value, if supported.
Return one of these from the `getRange()` method, providing a minimum,
maximum, and interval value for the range to indicate that this is a
ranged value.
The default state is an "invalid" range, indicating that the accessibility
element does not support ranged values.
@see AccessibilityRangedNumericValueInterface
@tags{Accessibility}
*/
class JUCE_API AccessibleValueRange
{
public:
/** Constructor.
Creates a default, "invalid" range that can be returned from
`AccessibilityValueInterface::getRange()` to indicate that the value
interface does not support ranged values.
*/
AccessibleValueRange() = default;
/** The minimum and maximum values for this range, inclusive. */
struct JUCE_API MinAndMax { double min, max; };
/** Constructor.
Creates a valid AccessibleValueRange with the provided minimum, maximum,
and interval values.
*/
AccessibleValueRange (MinAndMax valueRange, double interval)
: valid (true),
range (valueRange),
stepSize (interval)
{
jassert (range.min < range.max);
}
/** Returns true if this represents a valid range. */
bool isValid() const noexcept { return valid; }
/** Returns the minimum value for this range. */
double getMinimumValue() const noexcept { return range.min; }
/** Returns the maxiumum value for this range. */
double getMaximumValue() const noexcept { return range.max; }
/** Returns the interval for this range. */
double getInterval() const noexcept { return stepSize; }
private:
bool valid = false;
MinAndMax range {};
double stepSize = 0.0;
};
/** If this is a ranged value, this should return a valid AccessibleValueRange
object representing the supported numerical range.
*/
virtual AccessibleValueRange getRange() const = 0;
};
//==============================================================================
/** A value interface that represents a text value.
@tags{Accessibility}
*/
class JUCE_API AccessibilityTextValueInterface : public AccessibilityValueInterface
{
public:
/** Returns true if the value is read-only and cannot be modified by an
accessibility client.
@see setValueAsString
*/
bool isReadOnly() const override = 0;
/** Returns the current value. */
String getCurrentValueAsString() const override = 0;
/** Sets the current value to a new value. */
void setValueAsString (const String& newValue) override = 0;
/** @internal */
double getCurrentValue() const final { return getCurrentValueAsString().getDoubleValue(); }
/** @internal */
void setValue (double newValue) final { setValueAsString (String (newValue)); }
/** @internal */
AccessibleValueRange getRange() const final { return {}; }
};
//==============================================================================
/** A value interface that represents a non-ranged numeric value.
@tags{Accessibility}
*/
class JUCE_API AccessibilityNumericValueInterface : public AccessibilityValueInterface
{
public:
/** Returns true if the value is read-only and cannot be modified by an
accessibility client.
@see setValue
*/
bool isReadOnly() const override = 0;
/** Returns the current value. */
double getCurrentValue() const override = 0;
/** Sets the current value to a new value. */
void setValue (double newValue) override = 0;
/** @internal */
String getCurrentValueAsString() const final { return String (getCurrentValue()); }
/** @internal */
void setValueAsString (const String& newValue) final { setValue (newValue.getDoubleValue()); }
/** @internal */
AccessibleValueRange getRange() const final { return {}; }
};
//==============================================================================
/** A value interface that represents a ranged numeric value.
@tags{Accessibility}
*/
class JUCE_API AccessibilityRangedNumericValueInterface : public AccessibilityValueInterface
{
public:
/** Returns true if the value is read-only and cannot be modified by an
accessibility client.
@see setValueAsString
*/
bool isReadOnly() const override = 0;
/** Returns the current value. */
double getCurrentValue() const override = 0;
/** Sets the current value to a new value. */
void setValue (double newValue) override = 0;
/** Returns the range. */
AccessibleValueRange getRange() const override = 0;
/** @internal */
String getCurrentValueAsString() const final { return String (getCurrentValue()); }
/** @internal */
void setValueAsString (const String& newValue) final { setValue (newValue.getDoubleValue()); }
};
} // 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 interface representing the value of an accessibility element.
Values should be used when information needs to be conveyed which cannot
be represented by the accessibility element's label alone. For example, a
gain slider with the label "Gain" needs to also provide a value for its
position whereas a "Save" button does not.
This class allows for full control over the value text/numeric conversion,
ranged, and read-only properties but in most cases you'll want to use one
of the derived classes below which handle some of this for you.
@see AccessibilityTextValueInterface, AccessibilityNumericValueInterface,
AccessibilityRangedNumericValueInterface
@tags{Accessibility}
*/
class JUCE_API AccessibilityValueInterface
{
public:
/** Destructor. */
virtual ~AccessibilityValueInterface() = default;
/** Returns true if the value is read-only and cannot be modified by an
accessibility client.
@see setValue, setValueAsString
*/
virtual bool isReadOnly() const = 0;
/** Returns the current value as a double. */
virtual double getCurrentValue() const = 0;
/** Returns the current value as a String. */
virtual String getCurrentValueAsString() const = 0;
/** Sets the current value to a new double value. */
virtual void setValue (double newValue) = 0;
/** Sets the current value to a new String value. */
virtual void setValueAsString (const String& newValue) = 0;
/** Represents the range of this value, if supported.
Return one of these from the `getRange()` method, providing a minimum,
maximum, and interval value for the range to indicate that this is a
ranged value.
The default state is an "invalid" range, indicating that the accessibility
element does not support ranged values.
@see AccessibilityRangedNumericValueInterface
@tags{Accessibility}
*/
class JUCE_API AccessibleValueRange
{
public:
/** Constructor.
Creates a default, "invalid" range that can be returned from
`AccessibilityValueInterface::getRange()` to indicate that the value
interface does not support ranged values.
*/
AccessibleValueRange() = default;
/** The minimum and maximum values for this range, inclusive. */
struct JUCE_API MinAndMax { double min, max; };
/** Constructor.
Creates a valid AccessibleValueRange with the provided minimum, maximum,
and interval values.
*/
AccessibleValueRange (MinAndMax valueRange, double interval)
: valid (true),
range (valueRange),
stepSize (interval)
{
jassert (range.min < range.max);
}
/** Returns true if this represents a valid range. */
bool isValid() const noexcept { return valid; }
/** Returns the minimum value for this range. */
double getMinimumValue() const noexcept { return range.min; }
/** Returns the maximum value for this range. */
double getMaximumValue() const noexcept { return range.max; }
/** Returns the interval for this range. */
double getInterval() const noexcept { return stepSize; }
private:
bool valid = false;
MinAndMax range {};
double stepSize = 0.0;
};
/** If this is a ranged value, this should return a valid AccessibleValueRange
object representing the supported numerical range.
*/
virtual AccessibleValueRange getRange() const = 0;
};
//==============================================================================
/** A value interface that represents a text value.
@tags{Accessibility}
*/
class JUCE_API AccessibilityTextValueInterface : public AccessibilityValueInterface
{
public:
/** Returns true if the value is read-only and cannot be modified by an
accessibility client.
@see setValueAsString
*/
bool isReadOnly() const override = 0;
/** Returns the current value. */
String getCurrentValueAsString() const override = 0;
/** Sets the current value to a new value. */
void setValueAsString (const String& newValue) override = 0;
/** @internal */
double getCurrentValue() const final { return getCurrentValueAsString().getDoubleValue(); }
/** @internal */
void setValue (double newValue) final { setValueAsString (String (newValue)); }
/** @internal */
AccessibleValueRange getRange() const final { return {}; }
};
//==============================================================================
/** A value interface that represents a non-ranged numeric value.
@tags{Accessibility}
*/
class JUCE_API AccessibilityNumericValueInterface : public AccessibilityValueInterface
{
public:
/** Returns true if the value is read-only and cannot be modified by an
accessibility client.
@see setValue
*/
bool isReadOnly() const override = 0;
/** Returns the current value. */
double getCurrentValue() const override = 0;
/** Sets the current value to a new value. */
void setValue (double newValue) override = 0;
/** @internal */
String getCurrentValueAsString() const final { return String (getCurrentValue()); }
/** @internal */
void setValueAsString (const String& newValue) final { setValue (newValue.getDoubleValue()); }
/** @internal */
AccessibleValueRange getRange() const final { return {}; }
};
//==============================================================================
/** A value interface that represents a ranged numeric value.
@tags{Accessibility}
*/
class JUCE_API AccessibilityRangedNumericValueInterface : public AccessibilityValueInterface
{
public:
/** Returns true if the value is read-only and cannot be modified by an
accessibility client.
@see setValueAsString
*/
bool isReadOnly() const override = 0;
/** Returns the current value. */
double getCurrentValue() const override = 0;
/** Sets the current value to a new value. */
void setValue (double newValue) override = 0;
/** Returns the range. */
AccessibleValueRange getRange() const override = 0;
/** @internal */
String getCurrentValueAsString() const final { return String (getCurrentValue()); }
/** @internal */
void setValueAsString (const String& newValue) final { setValue (newValue.getDoubleValue()); }
};
} // namespace juce

View File

@ -1,340 +1,339 @@
/*
==============================================================================
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
{
AccessibilityHandler* AccessibilityHandler::currentlyFocusedHandler = nullptr;
enum class InternalAccessibilityEvent
{
elementCreated,
elementDestroyed,
elementMovedOrResized,
focusChanged,
windowOpened,
windowClosed
};
void notifyAccessibilityEventInternal (const AccessibilityHandler&, InternalAccessibilityEvent);
inline String getAccessibleApplicationOrPluginName()
{
#if defined (JucePlugin_Name)
return JucePlugin_Name;
#else
if (auto* app = JUCEApplicationBase::getInstance())
return app->getApplicationName();
return "JUCE Application";
#endif
}
AccessibilityHandler::AccessibilityHandler (Component& comp,
AccessibilityRole accessibilityRole,
AccessibilityActions accessibilityActions,
Interfaces interfacesIn)
: component (comp),
typeIndex (typeid (component)),
role (accessibilityRole),
actions (std::move (accessibilityActions)),
interfaces (std::move (interfacesIn)),
nativeImpl (createNativeImpl (*this))
{
notifyAccessibilityEventInternal (*this, InternalAccessibilityEvent::elementCreated);
}
AccessibilityHandler::~AccessibilityHandler()
{
giveAwayFocus();
notifyAccessibilityEventInternal (*this, InternalAccessibilityEvent::elementDestroyed);
}
//==============================================================================
AccessibleState AccessibilityHandler::getCurrentState() const
{
if (component.isCurrentlyBlockedByAnotherModalComponent()
&& Component::getCurrentlyModalComponent()->isVisible())
return {};
auto state = AccessibleState().withFocusable();
return hasFocus (false) ? state.withFocused() : state;
}
bool AccessibilityHandler::isIgnored() const
{
return role == AccessibilityRole::ignored || getCurrentState().isIgnored();
}
static bool isComponentVisibleWithinWindow (const Component& comp)
{
if (auto* peer = comp.getPeer())
return ! peer->getAreaCoveredBy (comp).getIntersection (peer->getComponent().getLocalBounds()).isEmpty();
return false;
}
static bool isComponentVisibleWithinParent (Component* comp)
{
if (auto* parent = comp->getParentComponent())
{
if (comp->getBoundsInParent().getIntersection (parent->getLocalBounds()).isEmpty())
return false;
return isComponentVisibleWithinParent (parent);
}
return true;
}
bool AccessibilityHandler::isVisibleWithinParent() const
{
return getCurrentState().isAccessibleOffscreen()
|| (isComponentVisibleWithinParent (&component) && isComponentVisibleWithinWindow (component));
}
//==============================================================================
const AccessibilityActions& AccessibilityHandler::getActions() const noexcept
{
return actions;
}
AccessibilityValueInterface* AccessibilityHandler::getValueInterface() const
{
return interfaces.value.get();
}
AccessibilityTableInterface* AccessibilityHandler::getTableInterface() const
{
return interfaces.table.get();
}
AccessibilityCellInterface* AccessibilityHandler::getCellInterface() const
{
return interfaces.cell.get();
}
AccessibilityTextInterface* AccessibilityHandler::getTextInterface() const
{
return interfaces.text.get();
}
//==============================================================================
static AccessibilityHandler* findEnclosingHandler (Component* comp)
{
if (comp != nullptr)
{
if (auto* handler = comp->getAccessibilityHandler())
return handler;
return findEnclosingHandler (comp->getParentComponent());
}
return nullptr;
}
static AccessibilityHandler* getUnignoredAncestor (AccessibilityHandler* handler)
{
while (handler != nullptr
&& (handler->isIgnored() || ! handler->isVisibleWithinParent())
&& handler->getParent() != nullptr)
{
handler = handler->getParent();
}
return handler;
}
static AccessibilityHandler* findFirstUnignoredChild (const std::vector<AccessibilityHandler*>& handlers)
{
if (! handlers.empty())
{
const auto iter = std::find_if (handlers.cbegin(), handlers.cend(),
[] (const AccessibilityHandler* handler) { return ! handler->isIgnored() && handler->isVisibleWithinParent(); });
if (iter != handlers.cend())
return *iter;
for (auto* handler : handlers)
if (auto* unignored = findFirstUnignoredChild (handler->getChildren()))
return unignored;
}
return nullptr;
}
static AccessibilityHandler* getFirstUnignoredDescendant (AccessibilityHandler* handler)
{
if (handler != nullptr && (handler->isIgnored() || ! handler->isVisibleWithinParent()))
return findFirstUnignoredChild (handler->getChildren());
return handler;
}
AccessibilityHandler* AccessibilityHandler::getParent() const
{
if (auto* focusContainer = component.findFocusContainer())
return getUnignoredAncestor (findEnclosingHandler (focusContainer));
return nullptr;
}
std::vector<AccessibilityHandler*> AccessibilityHandler::getChildren() const
{
if (! component.isFocusContainer() && component.getParentComponent() != nullptr)
return {};
const auto addChildComponentHandler = [this] (Component* focusableComponent,
std::vector<AccessibilityHandler*>& childHandlers)
{
if (focusableComponent == nullptr)
return;
if (auto* handler = findEnclosingHandler (focusableComponent))
{
if (! handler->getCurrentState().isFocusable() || ! isParentOf (handler))
return;
if (auto* unignored = getFirstUnignoredDescendant (handler))
if (std::find (childHandlers.cbegin(), childHandlers.cend(), unignored) == childHandlers.cend())
childHandlers.push_back (unignored);
}
};
std::vector<AccessibilityHandler*> children;
if (auto traverser = component.createFocusTraverser())
{
addChildComponentHandler (traverser->getDefaultComponent (&component), children);
for (auto* focusableChild : traverser->getAllComponents (&component))
addChildComponentHandler (focusableChild, children);
}
return children;
}
bool AccessibilityHandler::isParentOf (const AccessibilityHandler* possibleChild) const noexcept
{
while (possibleChild != nullptr)
{
possibleChild = possibleChild->getParent();
if (possibleChild == this)
return true;
}
return false;
}
AccessibilityHandler* AccessibilityHandler::getChildAt (Point<int> screenPoint)
{
if (auto* comp = Desktop::getInstance().findComponentAt (screenPoint))
{
if (auto* handler = getUnignoredAncestor (findEnclosingHandler (comp)))
if (isParentOf (handler))
return handler;
}
return nullptr;
}
AccessibilityHandler* AccessibilityHandler::getChildFocus()
{
return hasFocus (true) ? getUnignoredAncestor (currentlyFocusedHandler)
: nullptr;
}
bool AccessibilityHandler::hasFocus (bool trueIfChildFocused) const
{
return currentlyFocusedHandler != nullptr
&& (currentlyFocusedHandler == this
|| (trueIfChildFocused && isParentOf (currentlyFocusedHandler)));
}
void AccessibilityHandler::grabFocus()
{
if (! hasFocus (false))
grabFocusInternal (true);
}
void AccessibilityHandler::giveAwayFocus() const
{
if (hasFocus (true))
giveAwayFocusInternal();
}
void AccessibilityHandler::grabFocusInternal (bool canTryParent)
{
if (getCurrentState().isFocusable() && ! isIgnored())
{
takeFocus();
return;
}
if (isParentOf (currentlyFocusedHandler))
return;
if (auto traverser = component.createFocusTraverser())
{
if (auto* defaultComp = traverser->getDefaultComponent (&component))
{
if (auto* handler = getUnignoredAncestor (findEnclosingHandler (defaultComp)))
{
if (isParentOf (handler))
{
handler->grabFocusInternal (false);
return;
}
}
}
}
if (canTryParent)
if (auto* parent = getParent())
parent->grabFocusInternal (true);
}
void AccessibilityHandler::giveAwayFocusInternal() const
{
currentlyFocusedHandler = nullptr;
notifyAccessibilityEventInternal (*this, InternalAccessibilityEvent::focusChanged);
}
void AccessibilityHandler::takeFocus()
{
currentlyFocusedHandler = this;
notifyAccessibilityEventInternal (*this, InternalAccessibilityEvent::focusChanged);
if ((component.isShowing() || component.isOnDesktop())
&& component.getWantsKeyboardFocus()
&& ! component.hasKeyboardFocus (true))
{
component.grabKeyboardFocus();
}
}
} // 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
{
AccessibilityHandler* AccessibilityHandler::currentlyFocusedHandler = nullptr;
enum class InternalAccessibilityEvent
{
elementCreated,
elementDestroyed,
elementMovedOrResized,
focusChanged,
windowOpened,
windowClosed
};
void notifyAccessibilityEventInternal (const AccessibilityHandler&, InternalAccessibilityEvent);
inline String getAccessibleApplicationOrPluginName()
{
#if defined (JucePlugin_Name)
return JucePlugin_Name;
#else
if (auto* app = JUCEApplicationBase::getInstance())
return app->getApplicationName();
return "JUCE Application";
#endif
}
AccessibilityHandler::AccessibilityHandler (Component& comp,
AccessibilityRole accessibilityRole,
AccessibilityActions accessibilityActions,
Interfaces interfacesIn)
: component (comp),
typeIndex (typeid (component)),
role (accessibilityRole),
actions (std::move (accessibilityActions)),
interfaces (std::move (interfacesIn)),
nativeImpl (createNativeImpl (*this))
{
}
AccessibilityHandler::~AccessibilityHandler()
{
giveAwayFocus();
notifyAccessibilityEventInternal (*this, InternalAccessibilityEvent::elementDestroyed);
}
//==============================================================================
AccessibleState AccessibilityHandler::getCurrentState() const
{
if (component.isCurrentlyBlockedByAnotherModalComponent()
&& Component::getCurrentlyModalComponent()->isVisible())
return {};
auto state = AccessibleState().withFocusable();
return hasFocus (false) ? state.withFocused() : state;
}
bool AccessibilityHandler::isIgnored() const
{
return role == AccessibilityRole::ignored || getCurrentState().isIgnored();
}
static bool isComponentVisibleWithinWindow (const Component& comp)
{
if (auto* peer = comp.getPeer())
return ! peer->getAreaCoveredBy (comp).getIntersection (peer->getComponent().getLocalBounds()).isEmpty();
return false;
}
static bool isComponentVisibleWithinParent (Component* comp)
{
if (auto* parent = comp->getParentComponent())
{
if (comp->getBoundsInParent().getIntersection (parent->getLocalBounds()).isEmpty())
return false;
return isComponentVisibleWithinParent (parent);
}
return true;
}
bool AccessibilityHandler::isVisibleWithinParent() const
{
return getCurrentState().isAccessibleOffscreen()
|| (isComponentVisibleWithinParent (&component) && isComponentVisibleWithinWindow (component));
}
//==============================================================================
const AccessibilityActions& AccessibilityHandler::getActions() const noexcept
{
return actions;
}
AccessibilityValueInterface* AccessibilityHandler::getValueInterface() const
{
return interfaces.value.get();
}
AccessibilityTableInterface* AccessibilityHandler::getTableInterface() const
{
return interfaces.table.get();
}
AccessibilityCellInterface* AccessibilityHandler::getCellInterface() const
{
return interfaces.cell.get();
}
AccessibilityTextInterface* AccessibilityHandler::getTextInterface() const
{
return interfaces.text.get();
}
//==============================================================================
static AccessibilityHandler* findEnclosingHandler (Component* comp)
{
if (comp != nullptr)
{
if (auto* handler = comp->getAccessibilityHandler())
return handler;
return findEnclosingHandler (comp->getParentComponent());
}
return nullptr;
}
static AccessibilityHandler* getUnignoredAncestor (AccessibilityHandler* handler)
{
while (handler != nullptr
&& (handler->isIgnored() || ! handler->isVisibleWithinParent())
&& handler->getParent() != nullptr)
{
handler = handler->getParent();
}
return handler;
}
static AccessibilityHandler* findFirstUnignoredChild (const std::vector<AccessibilityHandler*>& handlers)
{
if (! handlers.empty())
{
const auto iter = std::find_if (handlers.cbegin(), handlers.cend(),
[] (const AccessibilityHandler* handler) { return ! handler->isIgnored() && handler->isVisibleWithinParent(); });
if (iter != handlers.cend())
return *iter;
for (auto* handler : handlers)
if (auto* unignored = findFirstUnignoredChild (handler->getChildren()))
return unignored;
}
return nullptr;
}
static AccessibilityHandler* getFirstUnignoredDescendant (AccessibilityHandler* handler)
{
if (handler != nullptr && (handler->isIgnored() || ! handler->isVisibleWithinParent()))
return findFirstUnignoredChild (handler->getChildren());
return handler;
}
AccessibilityHandler* AccessibilityHandler::getParent() const
{
if (auto* focusContainer = component.findFocusContainer())
return getUnignoredAncestor (findEnclosingHandler (focusContainer));
return nullptr;
}
std::vector<AccessibilityHandler*> AccessibilityHandler::getChildren() const
{
if (! component.isFocusContainer() && component.getParentComponent() != nullptr)
return {};
const auto addChildComponentHandler = [this] (Component* focusableComponent,
std::vector<AccessibilityHandler*>& childHandlers)
{
if (focusableComponent == nullptr)
return;
if (auto* handler = findEnclosingHandler (focusableComponent))
{
if (! handler->getCurrentState().isFocusable() || ! isParentOf (handler))
return;
if (auto* unignored = getFirstUnignoredDescendant (handler))
if (std::find (childHandlers.cbegin(), childHandlers.cend(), unignored) == childHandlers.cend())
childHandlers.push_back (unignored);
}
};
std::vector<AccessibilityHandler*> children;
if (auto traverser = component.createFocusTraverser())
{
addChildComponentHandler (traverser->getDefaultComponent (&component), children);
for (auto* focusableChild : traverser->getAllComponents (&component))
addChildComponentHandler (focusableChild, children);
}
return children;
}
bool AccessibilityHandler::isParentOf (const AccessibilityHandler* possibleChild) const noexcept
{
while (possibleChild != nullptr)
{
possibleChild = possibleChild->getParent();
if (possibleChild == this)
return true;
}
return false;
}
AccessibilityHandler* AccessibilityHandler::getChildAt (Point<int> screenPoint)
{
if (auto* comp = Desktop::getInstance().findComponentAt (screenPoint))
{
if (auto* handler = getUnignoredAncestor (findEnclosingHandler (comp)))
if (isParentOf (handler))
return handler;
}
return nullptr;
}
AccessibilityHandler* AccessibilityHandler::getChildFocus()
{
return hasFocus (true) ? getUnignoredAncestor (currentlyFocusedHandler)
: nullptr;
}
bool AccessibilityHandler::hasFocus (bool trueIfChildFocused) const
{
return currentlyFocusedHandler != nullptr
&& (currentlyFocusedHandler == this
|| (trueIfChildFocused && isParentOf (currentlyFocusedHandler)));
}
void AccessibilityHandler::grabFocus()
{
if (! hasFocus (false))
grabFocusInternal (true);
}
void AccessibilityHandler::giveAwayFocus() const
{
if (hasFocus (true))
giveAwayFocusInternal();
}
void AccessibilityHandler::grabFocusInternal (bool canTryParent)
{
if (getCurrentState().isFocusable() && ! isIgnored())
{
takeFocus();
return;
}
if (isParentOf (currentlyFocusedHandler))
return;
if (auto traverser = component.createFocusTraverser())
{
if (auto* defaultComp = traverser->getDefaultComponent (&component))
{
if (auto* handler = getUnignoredAncestor (findEnclosingHandler (defaultComp)))
{
if (isParentOf (handler))
{
handler->grabFocusInternal (false);
return;
}
}
}
}
if (canTryParent)
if (auto* parent = getParent())
parent->grabFocusInternal (true);
}
void AccessibilityHandler::giveAwayFocusInternal() const
{
currentlyFocusedHandler = nullptr;
notifyAccessibilityEventInternal (*this, InternalAccessibilityEvent::focusChanged);
}
void AccessibilityHandler::takeFocus()
{
currentlyFocusedHandler = this;
notifyAccessibilityEventInternal (*this, InternalAccessibilityEvent::focusChanged);
if ((component.isShowing() || component.isOnDesktop())
&& component.getWantsKeyboardFocus()
&& ! component.hasKeyboardFocus (true))
{
component.grabKeyboardFocus();
}
}
} // namespace juce

View File

@ -1,325 +1,325 @@
/*
==============================================================================
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
{
class AccessibilityNativeHandle;
/** Base class for accessible Components.
This class wraps a Component and provides methods that allow an accessibility client,
such as VoiceOver on macOS, or Narrator on Windows, to control it.
It handles hierarchical navigation, properties, state, and various interfaces.
@tags{Accessibility}
*/
class JUCE_API AccessibilityHandler
{
public:
/** Utility struct which holds one or more accessibility interfaces.
The main purpose of this class is to provide convenience constructors from each
of the four types of accessibility interface.
*/
struct JUCE_API Interfaces
{
Interfaces() = default;
Interfaces (std::unique_ptr<AccessibilityValueInterface> ptr) : value (std::move (ptr)) {}
Interfaces (std::unique_ptr<AccessibilityTextInterface> ptr) : text (std::move (ptr)) {}
Interfaces (std::unique_ptr<AccessibilityTableInterface> ptr) : table (std::move (ptr)) {}
Interfaces (std::unique_ptr<AccessibilityCellInterface> ptr) : cell (std::move (ptr)) {}
Interfaces (std::unique_ptr<AccessibilityValueInterface> valueIn,
std::unique_ptr<AccessibilityTextInterface> textIn,
std::unique_ptr<AccessibilityTableInterface> tableIn,
std::unique_ptr<AccessibilityCellInterface> cellIn)
: value (std::move (valueIn)),
text (std::move (textIn)),
table (std::move (tableIn)),
cell (std::move (cellIn))
{
}
std::unique_ptr<AccessibilityValueInterface> value;
std::unique_ptr<AccessibilityTextInterface> text;
std::unique_ptr<AccessibilityTableInterface> table;
std::unique_ptr<AccessibilityCellInterface> cell;
};
/** Constructor.
This will create a AccessibilityHandler which wraps the provided Component and makes
it visible to accessibility clients. You must also specify a role for the UI element
from the `AccessibilityRole` list which best describes it.
To enable users to interact with the UI element you should provide the set of supported
actions and their associated callbacks via the `accessibilityActions` parameter.
For UI elements that support more complex interaction the value, text, table, and cell
interfaces should be implemented as required and passed as the final argument of this
constructor. See the documentation of these classes for more information about the
types of control they represent and which methods need to be implemented.
*/
AccessibilityHandler (Component& componentToWrap,
AccessibilityRole accessibilityRole,
AccessibilityActions actions = {},
Interfaces interfaces = {});
/** Destructor. */
virtual ~AccessibilityHandler();
//==============================================================================
/** Returns the Component that this handler represents. */
const Component& getComponent() const noexcept { return component; }
/** Returns the Component that this handler represents. */
Component& getComponent() noexcept { return component; }
//==============================================================================
/** The type of UI element that this accessibility handler represents.
@see AccessibilityRole
*/
AccessibilityRole getRole() const noexcept { return role; }
/** The title of the UI element.
This will be read out by the system and should be concise, preferably matching
the visible title of the UI element (if any). For example, this might be the
text of a button or a simple label.
The default implementation will call `Component::getTitle()`, but you can override
this to return a different string if required.
If neither a name nor a description is provided then the UI element may be
ignored by accessibility clients.
This must be a localised string.
*/
virtual String getTitle() const { return component.getTitle(); }
/** A short description of the UI element.
This may be read out by the system. It should not include the type of the UI
element and should ideally be a single word, for example "Open" for a button
that opens a window.
The default implementation will call `Component::getDescription()`, but you
can override this to return a different string if required.
If neither a name nor a description is provided then the UI element may be
ignored by accessibility clients.
This must be a localised string.
*/
virtual String getDescription() const { return component.getDescription(); }
/** Some help text for the UI element (if required).
This may be read out by the system. This string functions in a similar way to
a tooltip, for example "Click to open window." for a button which opens a window.
The default implementation will call `Component::getHelpText()`, but you can
override this to return a different string if required.
This must be a localised string.
*/
virtual String getHelp() const { return component.getHelpText(); }
/** Returns the current state of the UI element.
The default implementation of this method will set the focusable flag and, if
this UI element is currently focused, will also set the focused flag.
*/
virtual AccessibleState getCurrentState() const;
/** Returns true if this UI element should be ignored by accessibility clients. */
bool isIgnored() const;
/** Returns true if this UI element is visible within its parent.
This will always return true for UI elements with the AccessibleState::accessibleOffscreen
flag set.
*/
bool isVisibleWithinParent() const;
//==============================================================================
/** Returns the set of actions that the UI element supports and the associated
callbacks.
*/
const AccessibilityActions& getActions() const noexcept;
/** Returns the value interface for this UI element, or nullptr if it is not supported.
@see AccessibilityValueInterface
*/
AccessibilityValueInterface* getValueInterface() const;
/** Returns the table interface for this UI element, or nullptr if it is not supported.
@see AccessibilityTableInterface
*/
AccessibilityTableInterface* getTableInterface() const;
/** Returns the cell interface for this UI element, or nullptr if it is not supported.
@see AccessibilityCellInterface
*/
AccessibilityCellInterface* getCellInterface() const;
/** Returns the text interface for this UI element, or nullptr if it is not supported.
@see AccessibilityTextInterface
*/
AccessibilityTextInterface* getTextInterface() const;
//==============================================================================
/** Returns the first unignored parent of this UI element in the accessibility hierarchy,
or nullptr if this is a root element without a parent.
*/
AccessibilityHandler* getParent() const;
/** Returns the unignored children of this UI element in the accessibility hierarchy. */
std::vector<AccessibilityHandler*> getChildren() const;
/** Checks whether a given UI element is a child of this one in the accessibility
hierarchy.
*/
bool isParentOf (const AccessibilityHandler* possibleChild) const noexcept;
/** Returns the deepest child of this UI element in the accessibility hierarchy that
contains the given screen point, or nullptr if there is no child at this point.
*/
AccessibilityHandler* getChildAt (Point<int> screenPoint);
/** Returns the deepest UI element which currently has focus.
This can be a child of this UI element or, if no child is focused,
this element itself.
Note that this can be different to the value of the Component with keyboard
focus returned by Component::getCurrentlyFocusedComponent().
@see hasFocus
*/
AccessibilityHandler* getChildFocus();
/** Returns true if this UI element has the focus.
@param trueIfChildFocused if this is true, this method will also return true
if any child of this UI element in the accessibility
hierarchy has focus
*/
bool hasFocus (bool trueIfChildFocused) const;
/** Tries to give focus to this UI element.
If the UI element is focusable and not ignored this will update the currently focused
element, try to give keyboard focus to the Component it represents, and notify any
listening accessibility clients that the current focus has changed.
@see hasFocus, giveAwayFocus
*/
void grabFocus();
/** If this UI element or any of its children in the accessibility hierarchy currently
have focus, this will defocus it.
This will also give away the keyboard focus from the Component it represents, and
notify any listening accessibility clients that the current focus has changed.
@see hasFocus, grabFocus
*/
void giveAwayFocus() const;
//==============================================================================
/** Used to send a notification to any observing accessibility clients that something
has changed in the UI element.
@see AccessibilityEvent
*/
void notifyAccessibilityEvent (AccessibilityEvent event) const;
/** A priority level that can help an accessibility client determine how to handle
an announcement request.
Exactly what this controls is platform-specific, but generally a low priority
announcement will be read when the screen reader is free, whereas a high priority
announcement will interrupt the current speech.
*/
enum class AnnouncementPriority
{
low,
medium,
high
};
/** Posts an announcement to be made to the user.
@param announcementString a localised string containing the announcement to be read out
@param priority the appropriate priority level for the announcement
*/
static void postAnnouncement (const String& announcementString, AnnouncementPriority priority);
//==============================================================================
/** @internal */
AccessibilityNativeHandle* getNativeImplementation() const;
/** @internal */
std::type_index getTypeIndex() const { return typeIndex; }
private:
//==============================================================================
friend class AccessibilityNativeHandle;
//==============================================================================
void grabFocusInternal (bool);
void giveAwayFocusInternal() const;
void takeFocus();
static AccessibilityHandler* currentlyFocusedHandler;
//==============================================================================
Component& component;
std::type_index typeIndex;
const AccessibilityRole role;
AccessibilityActions actions;
Interfaces interfaces;
//==============================================================================
class AccessibilityNativeImpl;
std::unique_ptr<AccessibilityNativeImpl> nativeImpl;
static std::unique_ptr<AccessibilityNativeImpl> createNativeImpl (AccessibilityHandler&);
//==============================================================================
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AccessibilityHandler)
};
} // 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
{
class AccessibilityNativeHandle;
/** Base class for accessible Components.
This class wraps a Component and provides methods that allow an accessibility client,
such as VoiceOver on macOS, or Narrator on Windows, to control it.
It handles hierarchical navigation, properties, state, and various interfaces.
@tags{Accessibility}
*/
class JUCE_API AccessibilityHandler
{
public:
/** Utility struct which holds one or more accessibility interfaces.
The main purpose of this class is to provide convenience constructors from each
of the four types of accessibility interface.
*/
struct JUCE_API Interfaces
{
Interfaces() = default;
Interfaces (std::unique_ptr<AccessibilityValueInterface> ptr) : value (std::move (ptr)) {}
Interfaces (std::unique_ptr<AccessibilityTextInterface> ptr) : text (std::move (ptr)) {}
Interfaces (std::unique_ptr<AccessibilityTableInterface> ptr) : table (std::move (ptr)) {}
Interfaces (std::unique_ptr<AccessibilityCellInterface> ptr) : cell (std::move (ptr)) {}
Interfaces (std::unique_ptr<AccessibilityValueInterface> valueIn,
std::unique_ptr<AccessibilityTextInterface> textIn,
std::unique_ptr<AccessibilityTableInterface> tableIn,
std::unique_ptr<AccessibilityCellInterface> cellIn)
: value (std::move (valueIn)),
text (std::move (textIn)),
table (std::move (tableIn)),
cell (std::move (cellIn))
{
}
std::unique_ptr<AccessibilityValueInterface> value;
std::unique_ptr<AccessibilityTextInterface> text;
std::unique_ptr<AccessibilityTableInterface> table;
std::unique_ptr<AccessibilityCellInterface> cell;
};
/** Constructor.
This will create a AccessibilityHandler which wraps the provided Component and makes
it visible to accessibility clients. You must also specify a role for the UI element
from the `AccessibilityRole` list which best describes it.
To enable users to interact with the UI element you should provide the set of supported
actions and their associated callbacks via the `accessibilityActions` parameter.
For UI elements that support more complex interaction the value, text, table, and cell
interfaces should be implemented as required and passed as the final argument of this
constructor. See the documentation of these classes for more information about the
types of control they represent and which methods need to be implemented.
*/
AccessibilityHandler (Component& componentToWrap,
AccessibilityRole accessibilityRole,
AccessibilityActions actions = {},
Interfaces interfaces = {});
/** Destructor. */
virtual ~AccessibilityHandler();
//==============================================================================
/** Returns the Component that this handler represents. */
const Component& getComponent() const noexcept { return component; }
/** Returns the Component that this handler represents. */
Component& getComponent() noexcept { return component; }
//==============================================================================
/** The type of UI element that this accessibility handler represents.
@see AccessibilityRole
*/
AccessibilityRole getRole() const noexcept { return role; }
/** The title of the UI element.
This will be read out by the system and should be concise, preferably matching
the visible title of the UI element (if any). For example, this might be the
text of a button or a simple label.
The default implementation will call `Component::getTitle()`, but you can override
this to return a different string if required.
If neither a name nor a description is provided then the UI element may be
ignored by accessibility clients.
This must be a localised string.
*/
virtual String getTitle() const { return component.getTitle(); }
/** A short description of the UI element.
This may be read out by the system. It should not include the type of the UI
element and should ideally be a single word, for example "Open" for a button
that opens a window.
The default implementation will call `Component::getDescription()`, but you
can override this to return a different string if required.
If neither a name nor a description is provided then the UI element may be
ignored by accessibility clients.
This must be a localised string.
*/
virtual String getDescription() const { return component.getDescription(); }
/** Some help text for the UI element (if required).
This may be read out by the system. This string functions in a similar way to
a tooltip, for example "Click to open window." for a button which opens a window.
The default implementation will call `Component::getHelpText()`, but you can
override this to return a different string if required.
This must be a localised string.
*/
virtual String getHelp() const { return component.getHelpText(); }
/** Returns the current state of the UI element.
The default implementation of this method will set the focusable flag and, if
this UI element is currently focused, will also set the focused flag.
*/
virtual AccessibleState getCurrentState() const;
/** Returns true if this UI element should be ignored by accessibility clients. */
bool isIgnored() const;
/** Returns true if this UI element is visible within its parent.
This will always return true for UI elements with the AccessibleState::accessibleOffscreen
flag set.
*/
bool isVisibleWithinParent() const;
//==============================================================================
/** Returns the set of actions that the UI element supports and the associated
callbacks.
*/
const AccessibilityActions& getActions() const noexcept;
/** Returns the value interface for this UI element, or nullptr if it is not supported.
@see AccessibilityValueInterface
*/
AccessibilityValueInterface* getValueInterface() const;
/** Returns the table interface for this UI element, or nullptr if it is not supported.
@see AccessibilityTableInterface
*/
AccessibilityTableInterface* getTableInterface() const;
/** Returns the cell interface for this UI element, or nullptr if it is not supported.
@see AccessibilityCellInterface
*/
AccessibilityCellInterface* getCellInterface() const;
/** Returns the text interface for this UI element, or nullptr if it is not supported.
@see AccessibilityTextInterface
*/
AccessibilityTextInterface* getTextInterface() const;
//==============================================================================
/** Returns the first unignored parent of this UI element in the accessibility hierarchy,
or nullptr if this is a root element without a parent.
*/
AccessibilityHandler* getParent() const;
/** Returns the unignored children of this UI element in the accessibility hierarchy. */
std::vector<AccessibilityHandler*> getChildren() const;
/** Checks whether a given UI element is a child of this one in the accessibility
hierarchy.
*/
bool isParentOf (const AccessibilityHandler* possibleChild) const noexcept;
/** Returns the deepest child of this UI element in the accessibility hierarchy that
contains the given screen point, or nullptr if there is no child at this point.
*/
AccessibilityHandler* getChildAt (Point<int> screenPoint);
/** Returns the deepest UI element which currently has focus.
This can be a child of this UI element or, if no child is focused,
this element itself.
Note that this can be different to the value of the Component with keyboard
focus returned by Component::getCurrentlyFocusedComponent().
@see hasFocus
*/
AccessibilityHandler* getChildFocus();
/** Returns true if this UI element has the focus.
@param trueIfChildFocused if this is true, this method will also return true
if any child of this UI element in the accessibility
hierarchy has focus
*/
bool hasFocus (bool trueIfChildFocused) const;
/** Tries to give focus to this UI element.
If the UI element is focusable and not ignored this will update the currently focused
element, try to give keyboard focus to the Component it represents, and notify any
listening accessibility clients that the current focus has changed.
@see hasFocus, giveAwayFocus
*/
void grabFocus();
/** If this UI element or any of its children in the accessibility hierarchy currently
have focus, this will defocus it.
This will also give away the keyboard focus from the Component it represents, and
notify any listening accessibility clients that the current focus has changed.
@see hasFocus, grabFocus
*/
void giveAwayFocus() const;
//==============================================================================
/** Used to send a notification to any observing accessibility clients that something
has changed in the UI element.
@see AccessibilityEvent
*/
void notifyAccessibilityEvent (AccessibilityEvent event) const;
/** A priority level that can help an accessibility client determine how to handle
an announcement request.
Exactly what this controls is platform-specific, but generally a low priority
announcement will be read when the screen reader is free, whereas a high priority
announcement will interrupt the current speech.
*/
enum class AnnouncementPriority
{
low,
medium,
high
};
/** Posts an announcement to be made to the user.
@param announcementString a localised string containing the announcement to be read out
@param priority the appropriate priority level for the announcement
*/
static void postAnnouncement (const String& announcementString, AnnouncementPriority priority);
//==============================================================================
/** @internal */
AccessibilityNativeHandle* getNativeImplementation() const;
/** @internal */
std::type_index getTypeIndex() const { return typeIndex; }
private:
//==============================================================================
friend class AccessibilityNativeHandle;
//==============================================================================
void grabFocusInternal (bool);
void giveAwayFocusInternal() const;
void takeFocus();
static AccessibilityHandler* currentlyFocusedHandler;
//==============================================================================
Component& component;
std::type_index typeIndex;
const AccessibilityRole role;
AccessibilityActions actions;
Interfaces interfaces;
//==============================================================================
class AccessibilityNativeImpl;
std::unique_ptr<AccessibilityNativeImpl> nativeImpl;
static std::unique_ptr<AccessibilityNativeImpl> createNativeImpl (AccessibilityHandler&);
//==============================================================================
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AccessibilityHandler)
};
} // namespace juce

View File

@ -1,227 +1,227 @@
/*
==============================================================================
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 an accessible UI element.
An instance of this class is returned by `AccessibilityHandler::getCurrentState()`
to convey its current state to an accessibility client.
@see AccessibilityHandler
@tags{Accessibility}
*/
class JUCE_API AccessibleState
{
public:
/** Constructor.
Represents a "default" state with no flags set. To set a flag, use one of the
`withX()` methods - these can be chained together to set multiple flags.
*/
AccessibleState() = default;
//==============================================================================
/** Sets the checkable flag and returns the new state.
@see isCheckable
*/
AccessibleState withCheckable() const noexcept { return withFlag (Flags::checkable); }
/** Sets the checked flag and returns the new state.
@see isChecked
*/
AccessibleState withChecked() const noexcept { return withFlag (Flags::checked); }
/** Sets the collapsed flag and returns the new state.
@see isCollapsed
*/
AccessibleState withCollapsed() const noexcept { return withFlag (Flags::collapsed); }
/** Sets the expandable flag and returns the new state.
@see isExpandable
*/
AccessibleState withExpandable() const noexcept { return withFlag (Flags::expandable); }
/** Sets the expanded flag and returns the new state.
@see isExpanded
*/
AccessibleState withExpanded() const noexcept { return withFlag (Flags::expanded); }
/** Sets the focusable flag and returns the new state.
@see isFocusable
*/
AccessibleState withFocusable() const noexcept { return withFlag (Flags::focusable); }
/** Sets the focused flag and returns the new state.
@see isFocused
*/
AccessibleState withFocused() const noexcept { return withFlag (Flags::focused); }
/** Sets the ignored flag and returns the new state.
@see isIgnored
*/
AccessibleState withIgnored() const noexcept { return withFlag (Flags::ignored); }
/** Sets the selectable flag and returns the new state.
@see isSelectable
*/
AccessibleState withSelectable() const noexcept { return withFlag (Flags::selectable); }
/** Sets the multiSelectable flag and returns the new state.
@see isMultiSelectable
*/
AccessibleState withMultiSelectable() const noexcept { return withFlag (Flags::multiSelectable); }
/** Sets the selected flag and returns the new state.
@see isSelected
*/
AccessibleState withSelected() const noexcept { return withFlag (Flags::selected); }
/** Sets the accessible offscreen flag and returns the new state.
@see isSelected
*/
AccessibleState withAccessibleOffscreen() const noexcept { return withFlag (Flags::accessibleOffscreen); }
//==============================================================================
/** Returns true if the UI element is checkable.
@see withCheckable
*/
bool isCheckable() const noexcept { return isFlagSet (Flags::checkable); }
/** Returns true if the UI element is checked.
@see withChecked
*/
bool isChecked() const noexcept { return isFlagSet (Flags::checked); }
/** Returns true if the UI element is collapsed.
@see withCollapsed
*/
bool isCollapsed() const noexcept { return isFlagSet (Flags::collapsed); }
/** Returns true if the UI element is expandable.
@see withExpandable
*/
bool isExpandable() const noexcept { return isFlagSet (Flags::expandable); }
/** Returns true if the UI element is expanded.
@see withExpanded
*/
bool isExpanded() const noexcept { return isFlagSet (Flags::expanded); }
/** Returns true if the UI element is focusable.
@see withFocusable
*/
bool isFocusable() const noexcept { return isFlagSet (Flags::focusable); }
/** Returns true if the UI element is focused.
@see withFocused
*/
bool isFocused() const noexcept { return isFlagSet (Flags::focused); }
/** Returns true if the UI element is ignored.
@see withIgnored
*/
bool isIgnored() const noexcept { return isFlagSet (Flags::ignored); }
/** Returns true if the UI element supports multiple item selection.
@see withMultiSelectable
*/
bool isMultiSelectable() const noexcept { return isFlagSet (Flags::multiSelectable); }
/** Returns true if the UI element is selectable.
@see withSelectable
*/
bool isSelectable() const noexcept { return isFlagSet (Flags::selectable); }
/** Returns true if the UI element is selected.
@see withSelected
*/
bool isSelected() const noexcept { return isFlagSet (Flags::selected); }
/** Returns true if the UI element is accessible offscreen.
@see withSelected
*/
bool isAccessibleOffscreen() const noexcept { return isFlagSet (Flags::accessibleOffscreen); }
private:
enum Flags
{
checkable = (1 << 0),
checked = (1 << 1),
collapsed = (1 << 2),
expandable = (1 << 3),
expanded = (1 << 4),
focusable = (1 << 5),
focused = (1 << 6),
ignored = (1 << 7),
multiSelectable = (1 << 8),
selectable = (1 << 9),
selected = (1 << 10),
accessibleOffscreen = (1 << 11)
};
AccessibleState withFlag (int flag) const noexcept
{
auto copy = *this;
copy.flags |= flag;
return copy;
}
bool isFlagSet (int flag) const noexcept
{
return (flags & flag) != 0;
}
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 an accessible UI element.
An instance of this class is returned by `AccessibilityHandler::getCurrentState()`
to convey its current state to an accessibility client.
@see AccessibilityHandler
@tags{Accessibility}
*/
class JUCE_API AccessibleState
{
public:
/** Constructor.
Represents a "default" state with no flags set. To set a flag, use one of the
`withX()` methods - these can be chained together to set multiple flags.
*/
AccessibleState() = default;
//==============================================================================
/** Sets the checkable flag and returns the new state.
@see isCheckable
*/
JUCE_NODISCARD AccessibleState withCheckable() const noexcept { return withFlag (Flags::checkable); }
/** Sets the checked flag and returns the new state.
@see isChecked
*/
JUCE_NODISCARD AccessibleState withChecked() const noexcept { return withFlag (Flags::checked); }
/** Sets the collapsed flag and returns the new state.
@see isCollapsed
*/
JUCE_NODISCARD AccessibleState withCollapsed() const noexcept { return withFlag (Flags::collapsed); }
/** Sets the expandable flag and returns the new state.
@see isExpandable
*/
JUCE_NODISCARD AccessibleState withExpandable() const noexcept { return withFlag (Flags::expandable); }
/** Sets the expanded flag and returns the new state.
@see isExpanded
*/
JUCE_NODISCARD AccessibleState withExpanded() const noexcept { return withFlag (Flags::expanded); }
/** Sets the focusable flag and returns the new state.
@see isFocusable
*/
JUCE_NODISCARD AccessibleState withFocusable() const noexcept { return withFlag (Flags::focusable); }
/** Sets the focused flag and returns the new state.
@see isFocused
*/
JUCE_NODISCARD AccessibleState withFocused() const noexcept { return withFlag (Flags::focused); }
/** Sets the ignored flag and returns the new state.
@see isIgnored
*/
JUCE_NODISCARD AccessibleState withIgnored() const noexcept { return withFlag (Flags::ignored); }
/** Sets the selectable flag and returns the new state.
@see isSelectable
*/
JUCE_NODISCARD AccessibleState withSelectable() const noexcept { return withFlag (Flags::selectable); }
/** Sets the multiSelectable flag and returns the new state.
@see isMultiSelectable
*/
JUCE_NODISCARD AccessibleState withMultiSelectable() const noexcept { return withFlag (Flags::multiSelectable); }
/** Sets the selected flag and returns the new state.
@see isSelected
*/
JUCE_NODISCARD AccessibleState withSelected() const noexcept { return withFlag (Flags::selected); }
/** Sets the accessible offscreen flag and returns the new state.
@see isSelected
*/
JUCE_NODISCARD AccessibleState withAccessibleOffscreen() const noexcept { return withFlag (Flags::accessibleOffscreen); }
//==============================================================================
/** Returns true if the UI element is checkable.
@see withCheckable
*/
bool isCheckable() const noexcept { return isFlagSet (Flags::checkable); }
/** Returns true if the UI element is checked.
@see withChecked
*/
bool isChecked() const noexcept { return isFlagSet (Flags::checked); }
/** Returns true if the UI element is collapsed.
@see withCollapsed
*/
bool isCollapsed() const noexcept { return isFlagSet (Flags::collapsed); }
/** Returns true if the UI element is expandable.
@see withExpandable
*/
bool isExpandable() const noexcept { return isFlagSet (Flags::expandable); }
/** Returns true if the UI element is expanded.
@see withExpanded
*/
bool isExpanded() const noexcept { return isFlagSet (Flags::expanded); }
/** Returns true if the UI element is focusable.
@see withFocusable
*/
bool isFocusable() const noexcept { return isFlagSet (Flags::focusable); }
/** Returns true if the UI element is focused.
@see withFocused
*/
bool isFocused() const noexcept { return isFlagSet (Flags::focused); }
/** Returns true if the UI element is ignored.
@see withIgnored
*/
bool isIgnored() const noexcept { return isFlagSet (Flags::ignored); }
/** Returns true if the UI element supports multiple item selection.
@see withMultiSelectable
*/
bool isMultiSelectable() const noexcept { return isFlagSet (Flags::multiSelectable); }
/** Returns true if the UI element is selectable.
@see withSelectable
*/
bool isSelectable() const noexcept { return isFlagSet (Flags::selectable); }
/** Returns true if the UI element is selected.
@see withSelected
*/
bool isSelected() const noexcept { return isFlagSet (Flags::selected); }
/** Returns true if the UI element is accessible offscreen.
@see withSelected
*/
bool isAccessibleOffscreen() const noexcept { return isFlagSet (Flags::accessibleOffscreen); }
private:
enum Flags
{
checkable = (1 << 0),
checked = (1 << 1),
collapsed = (1 << 2),
expandable = (1 << 3),
expanded = (1 << 4),
focusable = (1 << 5),
focused = (1 << 6),
ignored = (1 << 7),
multiSelectable = (1 << 8),
selectable = (1 << 9),
selected = (1 << 10),
accessibleOffscreen = (1 << 11)
};
JUCE_NODISCARD AccessibleState withFlag (int flag) const noexcept
{
auto copy = *this;
copy.flags |= flag;
return copy;
}
bool isFlagSet (int flag) const noexcept
{
return (flags & flag) != 0;
}
int flags = 0;
};
} // namespace juce