From 333983947e89ee2c6373e8bcacd731304608843e Mon Sep 17 00:00:00 2001 From: ed Date: Thu, 20 May 2021 17:48:41 +0100 Subject: [PATCH] Accessibility: Removed widget_handlers --- .../juce_ButtonAccessibilityHandler.h | 96 ---------------- .../juce_ComboBoxAccessibilityHandler.h | 66 ----------- .../juce_LabelAccessibilityHandler.h | 62 ---------- .../juce_SliderAccessibilityHandler.h | 100 ---------------- .../juce_TableListBoxAccessibilityHandler.h | 83 -------------- .../juce_TextEditorAccessibilityHandler.h | 108 ------------------ .../juce_TreeViewAccessibilityHandler.h | 79 ------------- .../juce_gui_basics/buttons/juce_Button.cpp | 63 ++++++++++ modules/juce_gui_basics/juce_gui_basics.h | 7 -- .../juce_gui_basics/layout/juce_ScrollBar.cpp | 24 ++-- .../juce_gui_basics/widgets/juce_ComboBox.cpp | 33 ++++++ .../juce_gui_basics/widgets/juce_Label.cpp | 29 +++++ .../widgets/juce_ProgressBar.cpp | 8 +- .../juce_gui_basics/widgets/juce_Slider.cpp | 43 ++++++- .../widgets/juce_TableListBox.cpp | 41 ++++++- .../widgets/juce_TextEditor.cpp | 75 ++++++++++++ .../juce_gui_basics/widgets/juce_TreeView.cpp | 27 ++++- 17 files changed, 321 insertions(+), 623 deletions(-) delete mode 100644 modules/juce_gui_basics/accessibility/widget_handlers/juce_ButtonAccessibilityHandler.h delete mode 100644 modules/juce_gui_basics/accessibility/widget_handlers/juce_ComboBoxAccessibilityHandler.h delete mode 100644 modules/juce_gui_basics/accessibility/widget_handlers/juce_LabelAccessibilityHandler.h delete mode 100644 modules/juce_gui_basics/accessibility/widget_handlers/juce_SliderAccessibilityHandler.h delete mode 100644 modules/juce_gui_basics/accessibility/widget_handlers/juce_TableListBoxAccessibilityHandler.h delete mode 100644 modules/juce_gui_basics/accessibility/widget_handlers/juce_TextEditorAccessibilityHandler.h delete mode 100644 modules/juce_gui_basics/accessibility/widget_handlers/juce_TreeViewAccessibilityHandler.h diff --git a/modules/juce_gui_basics/accessibility/widget_handlers/juce_ButtonAccessibilityHandler.h b/modules/juce_gui_basics/accessibility/widget_handlers/juce_ButtonAccessibilityHandler.h deleted file mode 100644 index db7e025213..0000000000 --- a/modules/juce_gui_basics/accessibility/widget_handlers/juce_ButtonAccessibilityHandler.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - ============================================================================== - - 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 -{ - -/** Basic accessible interface for a Button that can be clicked or toggled. - - @tags{Accessibility} -*/ -class JUCE_API ButtonAccessibilityHandler : public AccessibilityHandler -{ -public: - explicit ButtonAccessibilityHandler (Button& buttonToWrap) - : AccessibilityHandler (buttonToWrap, - getButtonRole (buttonToWrap), - getAccessibilityActions (buttonToWrap)), - button (buttonToWrap) - { - } - - AccessibleState getCurrentState() const override - { - auto state = AccessibilityHandler::getCurrentState(); - - if (button.getClickingTogglesState()) - { - state = state.withCheckable(); - - if (button.getToggleState()) - state = state.withChecked(); - } - - return state; - } - - String getTitle() const override - { - auto title = AccessibilityHandler::getTitle(); - - if (title.isEmpty()) - return button.getButtonText(); - - return title; - } - -private: - static AccessibilityRole getButtonRole (const Button& b) - { - if (b.getRadioGroupId() != 0) return AccessibilityRole::radioButton; - if (b.getClickingTogglesState()) return AccessibilityRole::toggleButton; - - return AccessibilityRole::button; - } - - static AccessibilityActions getAccessibilityActions (Button& button) - { - auto actions = AccessibilityActions().addAction (AccessibilityActionType::press, - [&button] { button.triggerClick(); }); - - if (button.getClickingTogglesState()) - actions = actions.addAction (AccessibilityActionType::toggle, - [&button] { button.setToggleState (! button.getToggleState(), sendNotification); }); - - return actions; - } - - Button& button; - - //============================================================================== - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ButtonAccessibilityHandler) -}; - -} // namespace juce diff --git a/modules/juce_gui_basics/accessibility/widget_handlers/juce_ComboBoxAccessibilityHandler.h b/modules/juce_gui_basics/accessibility/widget_handlers/juce_ComboBoxAccessibilityHandler.h deleted file mode 100644 index fda95013ba..0000000000 --- a/modules/juce_gui_basics/accessibility/widget_handlers/juce_ComboBoxAccessibilityHandler.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - ============================================================================== - - 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 -{ - -/** Basic accessible interface for a ComboBox that can show a menu. - - @tags{Accessibility} -*/ -class JUCE_API ComboBoxAccessibilityHandler : public AccessibilityHandler -{ -public: - explicit ComboBoxAccessibilityHandler (ComboBox& comboBoxToWrap) - : AccessibilityHandler (comboBoxToWrap, - AccessibilityRole::comboBox, - getAccessibilityActions (comboBoxToWrap)), - comboBox (comboBoxToWrap) - { - } - - AccessibleState getCurrentState() const override - { - auto state = AccessibilityHandler::getCurrentState().withExpandable(); - - return comboBox.isPopupActive() ? state.withExpanded() : state.withCollapsed(); - } - - String getTitle() const override { return comboBox.getText(); } - -private: - static AccessibilityActions getAccessibilityActions (ComboBox& comboBox) - { - return AccessibilityActions().addAction (AccessibilityActionType::press, [&comboBox] { comboBox.showPopup(); }) - .addAction (AccessibilityActionType::showMenu, [&comboBox] { comboBox.showPopup(); }); - } - - ComboBox& comboBox; - - //============================================================================== - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ComboBoxAccessibilityHandler) -}; - -} // namespace juce diff --git a/modules/juce_gui_basics/accessibility/widget_handlers/juce_LabelAccessibilityHandler.h b/modules/juce_gui_basics/accessibility/widget_handlers/juce_LabelAccessibilityHandler.h deleted file mode 100644 index 2d4d6b1aa9..0000000000 --- a/modules/juce_gui_basics/accessibility/widget_handlers/juce_LabelAccessibilityHandler.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - ============================================================================== - - 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 -{ - -/** Basic accessible interface for a Label that can also show a TextEditor - when clicked. - - @tags{Accessibility} -*/ -class JUCE_API LabelAccessibilityHandler : public AccessibilityHandler -{ -public: - explicit LabelAccessibilityHandler (Label& labelToWrap) - : AccessibilityHandler (labelToWrap, - AccessibilityRole::staticText, - getAccessibilityActions (labelToWrap)), - label (labelToWrap) - { - } - - String getTitle() const override { return label.getText(); } - -private: - static AccessibilityActions getAccessibilityActions (Label& label) - { - if (label.isEditable()) - return AccessibilityActions().addAction (AccessibilityActionType::press, [&label] { label.showEditor(); }); - - return {}; - } - - Label& label; - - //============================================================================== - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LabelAccessibilityHandler) -}; - -} // namespace juce diff --git a/modules/juce_gui_basics/accessibility/widget_handlers/juce_SliderAccessibilityHandler.h b/modules/juce_gui_basics/accessibility/widget_handlers/juce_SliderAccessibilityHandler.h deleted file mode 100644 index 3ee1535f37..0000000000 --- a/modules/juce_gui_basics/accessibility/widget_handlers/juce_SliderAccessibilityHandler.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - ============================================================================== - - 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 -{ - -/** Basic accessible interface for a Slider. - - @tags{Accessibility} -*/ -class JUCE_API SliderAccessibilityHandler : public AccessibilityHandler -{ -public: - explicit SliderAccessibilityHandler (Slider& sliderToWrap) - : AccessibilityHandler (sliderToWrap, - AccessibilityRole::slider, - {}, - { std::make_unique (sliderToWrap) }) - { - } - -private: - class SliderValueInterface : public AccessibilityValueInterface - { - public: - explicit SliderValueInterface (Slider& sliderToWrap) - : slider (sliderToWrap) - { - } - - bool isReadOnly() const override { return false; } - - double getCurrentValue() const override - { - return slider.isTwoValue() ? slider.getMaxValue() : slider.getValue(); - } - - void setValue (double newValue) override - { - if (slider.isTwoValue()) - slider.setMaxValue (newValue, sendNotification); - else - slider.setValue (newValue, sendNotification); - } - - String getCurrentValueAsString() const override - { - return slider.getTextFromValue (getCurrentValue()); - } - - void setValueAsString (const String& newValue) override - { - setValue (slider.getValueFromText (newValue)); - } - - AccessibleValueRange getRange() const override - { - return { { slider.getMinimum(), slider.getMaximum() }, - getStepSize() }; - } - - private: - double getStepSize() const - { - auto interval = slider.getInterval(); - - return interval != 0.0 ? interval - : slider.proportionOfLengthToValue (0.01); - } - - Slider& slider; - }; - - //============================================================================== - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SliderAccessibilityHandler) -}; - -} // namespace juce diff --git a/modules/juce_gui_basics/accessibility/widget_handlers/juce_TableListBoxAccessibilityHandler.h b/modules/juce_gui_basics/accessibility/widget_handlers/juce_TableListBoxAccessibilityHandler.h deleted file mode 100644 index 955a6bd96e..0000000000 --- a/modules/juce_gui_basics/accessibility/widget_handlers/juce_TableListBoxAccessibilityHandler.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - ============================================================================== - - 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 -{ - -/** Basic accessible interface for a TableListBox. - - @tags{Accessibility} -*/ -class JUCE_API TableListBoxAccessibilityHandler : public AccessibilityHandler -{ -public: - explicit TableListBoxAccessibilityHandler (TableListBox& tableListBoxToWrap) - : AccessibilityHandler (tableListBoxToWrap, - AccessibilityRole::list, - {}, - { std::make_unique (tableListBoxToWrap) }) - { - } - -private: - class TableListBoxTableInterface : public AccessibilityTableInterface - { - public: - explicit TableListBoxTableInterface (TableListBox& tableListBoxToWrap) - : tableListBox (tableListBoxToWrap) - { - } - - int getNumRows() const override - { - if (auto* model = tableListBox.getModel()) - return model->getNumRows(); - - return 0; - } - - int getNumColumns() const override - { - return tableListBox.getHeader().getNumColumns (false); - } - - const AccessibilityHandler* getCellHandler (int row, int column) const override - { - if (isPositiveAndBelow (row, getNumRows()) && isPositiveAndBelow (column, getNumColumns())) - if (auto* cellComponent = tableListBox.getCellComponent (tableListBox.getHeader().getColumnIdOfIndex (column, false), row)) - return cellComponent->getAccessibilityHandler(); - - return nullptr; - } - - private: - TableListBox& tableListBox; - }; - - //============================================================================== - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TableListBoxAccessibilityHandler) -}; - -} // namespace juce diff --git a/modules/juce_gui_basics/accessibility/widget_handlers/juce_TextEditorAccessibilityHandler.h b/modules/juce_gui_basics/accessibility/widget_handlers/juce_TextEditorAccessibilityHandler.h deleted file mode 100644 index 83ea7b2858..0000000000 --- a/modules/juce_gui_basics/accessibility/widget_handlers/juce_TextEditorAccessibilityHandler.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - ============================================================================== - - 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 -{ - -/** Basic accessible interface for a TextEditor. - - @tags{Accessibility} -*/ -class JUCE_API TextEditorAccessibilityHandler : public AccessibilityHandler -{ -public: - explicit TextEditorAccessibilityHandler (TextEditor& textEditorToWrap) - : AccessibilityHandler (textEditorToWrap, - textEditorToWrap.isReadOnly() ? AccessibilityRole::staticText : AccessibilityRole::editableText, - {}, - { textEditorToWrap.isReadOnly() ? nullptr : std::make_unique (textEditorToWrap) }), - textEditor (textEditorToWrap) - { - } - - String getTitle() const override - { - return textEditor.isReadOnly() ? textEditor.getText() : textEditor.getTitle(); - } - -private: - class TextEditorTextInterface : public AccessibilityTextInterface - { - public: - explicit TextEditorTextInterface (TextEditor& editor) - : textEditor (editor) - { - } - - bool isDisplayingProtectedText() const override { return textEditor.getPasswordCharacter() != 0; } - - int getTotalNumCharacters() const override { return textEditor.getText().length(); } - Range getSelection() const override { return textEditor.getHighlightedRegion(); } - void setSelection (Range r) override { textEditor.setHighlightedRegion (r); } - - String getText (Range r) const override - { - if (isDisplayingProtectedText()) - return String::repeatedString (String::charToString (textEditor.getPasswordCharacter()), - getTotalNumCharacters()); - - return textEditor.getTextInRange (r); - } - - void setText (const String& newText) override - { - textEditor.setText (newText); - } - - int getTextInsertionOffset() const override { return textEditor.getCaretPosition(); } - - RectangleList getTextBounds (Range textRange) const override - { - auto localRects = textEditor.getTextBounds (textRange); - RectangleList globalRects; - - std::for_each (localRects.begin(), localRects.end(), - [&] (const Rectangle& r) { globalRects.add (textEditor.localAreaToGlobal (r)); }); - - return globalRects; - } - - int getOffsetAtPoint (Point point) const override - { - auto localPoint = textEditor.getLocalPoint (nullptr, point); - return textEditor.getTextIndexAt (localPoint.x, localPoint.y); - } - - private: - TextEditor& textEditor; - }; - - TextEditor& textEditor; - - //============================================================================== - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TextEditorAccessibilityHandler) -}; - -} // namespace juce diff --git a/modules/juce_gui_basics/accessibility/widget_handlers/juce_TreeViewAccessibilityHandler.h b/modules/juce_gui_basics/accessibility/widget_handlers/juce_TreeViewAccessibilityHandler.h deleted file mode 100644 index 6f828e0569..0000000000 --- a/modules/juce_gui_basics/accessibility/widget_handlers/juce_TreeViewAccessibilityHandler.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - ============================================================================== - - 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 -{ - -/** Basic accessible interface for a TreeView. - - @tags{Accessibility} -*/ -class JUCE_API TreeViewAccessibilityHandler : public AccessibilityHandler -{ -public: - explicit TreeViewAccessibilityHandler (TreeView& treeViewToWrap) - : AccessibilityHandler (treeViewToWrap, - AccessibilityRole::tree, - {}, - { std::make_unique (treeViewToWrap) }) - { - } - -private: - class TreeViewTableInterface : public AccessibilityTableInterface - { - public: - explicit TreeViewTableInterface (TreeView& treeViewToWrap) - : treeView (treeViewToWrap) - { - } - - int getNumRows() const override - { - return treeView.getNumRowsInTree(); - } - - int getNumColumns() const override - { - return 1; - } - - const AccessibilityHandler* getCellHandler (int row, int) const override - { - if (auto* itemComp = treeView.getItemComponent (treeView.getItemOnRow (row))) - return itemComp->getAccessibilityHandler(); - - return nullptr; - } - - private: - TreeView& treeView; - }; - - //============================================================================== - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TreeViewAccessibilityHandler) -}; - -} // namespace juce diff --git a/modules/juce_gui_basics/buttons/juce_Button.cpp b/modules/juce_gui_basics/buttons/juce_Button.cpp index 9978d96723..5623e7d33e 100644 --- a/modules/juce_gui_basics/buttons/juce_Button.cpp +++ b/modules/juce_gui_basics/buttons/juce_Button.cpp @@ -700,6 +700,69 @@ void Button::repeatTimerCallback() } //============================================================================== +class ButtonAccessibilityHandler : public AccessibilityHandler +{ +public: + explicit ButtonAccessibilityHandler (Button& buttonToWrap) + : AccessibilityHandler (buttonToWrap, + getButtonRole (buttonToWrap), + getAccessibilityActions (buttonToWrap)), + button (buttonToWrap) + { + } + + AccessibleState getCurrentState() const override + { + auto state = AccessibilityHandler::getCurrentState(); + + if (button.getClickingTogglesState()) + { + state = state.withCheckable(); + + if (button.getToggleState()) + state = state.withChecked(); + } + + return state; + } + + String getTitle() const override + { + auto title = AccessibilityHandler::getTitle(); + + if (title.isEmpty()) + return button.getButtonText(); + + return title; + } + +private: + static AccessibilityRole getButtonRole (const Button& b) + { + if (b.getRadioGroupId() != 0) return AccessibilityRole::radioButton; + if (b.getClickingTogglesState()) return AccessibilityRole::toggleButton; + + return AccessibilityRole::button; + } + + static AccessibilityActions getAccessibilityActions (Button& button) + { + auto actions = AccessibilityActions().addAction (AccessibilityActionType::press, + [&button] { button.triggerClick(); }); + + if (button.getClickingTogglesState()) + actions = actions.addAction (AccessibilityActionType::toggle, + [&button] { button.setToggleState (! button.getToggleState(), sendNotification); }); + + return actions; + } + + Button& button; + + //============================================================================== + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ButtonAccessibilityHandler) +}; + std::unique_ptr Button::createAccessibilityHandler() { return std::make_unique (*this); diff --git a/modules/juce_gui_basics/juce_gui_basics.h b/modules/juce_gui_basics/juce_gui_basics.h index 4589f6fc0e..082ad6cc52 100644 --- a/modules/juce_gui_basics/juce_gui_basics.h +++ b/modules/juce_gui_basics/juce_gui_basics.h @@ -306,13 +306,6 @@ namespace juce #include "accessibility/enums/juce_AccessibilityRole.h" #include "accessibility/juce_AccessibilityState.h" #include "accessibility/juce_AccessibilityHandler.h" -#include "accessibility/widget_handlers/juce_ButtonAccessibilityHandler.h" -#include "accessibility/widget_handlers/juce_ComboBoxAccessibilityHandler.h" -#include "accessibility/widget_handlers/juce_LabelAccessibilityHandler.h" -#include "accessibility/widget_handlers/juce_SliderAccessibilityHandler.h" -#include "accessibility/widget_handlers/juce_TableListBoxAccessibilityHandler.h" -#include "accessibility/widget_handlers/juce_TextEditorAccessibilityHandler.h" -#include "accessibility/widget_handlers/juce_TreeViewAccessibilityHandler.h" #if JUCE_LINUX || JUCE_BSD #if JUCE_GUI_BASICS_INCLUDE_XHEADERS diff --git a/modules/juce_gui_basics/layout/juce_ScrollBar.cpp b/modules/juce_gui_basics/layout/juce_ScrollBar.cpp index d540d0497d..f856ce3198 100644 --- a/modules/juce_gui_basics/layout/juce_ScrollBar.cpp +++ b/modules/juce_gui_basics/layout/juce_ScrollBar.cpp @@ -443,25 +443,15 @@ bool ScrollBar::getVisibility() const noexcept //============================================================================== std::unique_ptr ScrollBar::createAccessibilityHandler() { - class ScrollBarValueInterface : public AccessibilityRangedNumericValueInterface + class ValueInterface : public AccessibilityRangedNumericValueInterface { public: - explicit ScrollBarValueInterface (ScrollBar& scrollBarToWrap) - : scrollBar (scrollBarToWrap) - { - } + explicit ValueInterface (ScrollBar& scrollBarToWrap) : scrollBar (scrollBarToWrap) {} - bool isReadOnly() const override { return false; } + bool isReadOnly() const override { return false; } - double getCurrentValue() const override - { - return scrollBar.getCurrentRangeStart(); - } - - void setValue (double newValue) override - { - scrollBar.setCurrentRangeStart (newValue); - } + double getCurrentValue() const override { return scrollBar.getCurrentRangeStart(); } + void setValue (double newValue) override { scrollBar.setCurrentRangeStart (newValue); } AccessibleValueRange getRange() const override { @@ -474,12 +464,14 @@ std::unique_ptr ScrollBar::createAccessibilityHandler() private: ScrollBar& scrollBar; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ValueInterface) }; return std::make_unique (*this, AccessibilityRole::scrollBar, AccessibilityActions{}, - AccessibilityHandler::Interfaces { std::make_unique (*this) }); + AccessibilityHandler::Interfaces { std::make_unique (*this) }); } } // namespace juce diff --git a/modules/juce_gui_basics/widgets/juce_ComboBox.cpp b/modules/juce_gui_basics/widgets/juce_ComboBox.cpp index fe04769c97..26718ad128 100644 --- a/modules/juce_gui_basics/widgets/juce_ComboBox.cpp +++ b/modules/juce_gui_basics/widgets/juce_ComboBox.cpp @@ -643,6 +643,39 @@ void ComboBox::setSelectedId (const int newItemId, const bool dontSendChange) void ComboBox::setText (const String& newText, const bool dontSendChange) { setText (newText, dontSendChange ? dontSendNotification : sendNotification); } //============================================================================== +class ComboBoxAccessibilityHandler : public AccessibilityHandler +{ +public: + explicit ComboBoxAccessibilityHandler (ComboBox& comboBoxToWrap) + : AccessibilityHandler (comboBoxToWrap, + AccessibilityRole::comboBox, + getAccessibilityActions (comboBoxToWrap)), + comboBox (comboBoxToWrap) + { + } + + AccessibleState getCurrentState() const override + { + auto state = AccessibilityHandler::getCurrentState().withExpandable(); + + return comboBox.isPopupActive() ? state.withExpanded() : state.withCollapsed(); + } + + String getTitle() const override { return comboBox.getText(); } + +private: + static AccessibilityActions getAccessibilityActions (ComboBox& comboBox) + { + return AccessibilityActions().addAction (AccessibilityActionType::press, [&comboBox] { comboBox.showPopup(); }) + .addAction (AccessibilityActionType::showMenu, [&comboBox] { comboBox.showPopup(); }); + } + + ComboBox& comboBox; + + //============================================================================== + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ComboBoxAccessibilityHandler) +}; + std::unique_ptr ComboBox::createAccessibilityHandler() { return std::make_unique (*this); diff --git a/modules/juce_gui_basics/widgets/juce_Label.cpp b/modules/juce_gui_basics/widgets/juce_Label.cpp index 22da77137a..6d18923a2d 100644 --- a/modules/juce_gui_basics/widgets/juce_Label.cpp +++ b/modules/juce_gui_basics/widgets/juce_Label.cpp @@ -515,6 +515,35 @@ void Label::textEditorFocusLost (TextEditor& ed) textEditorTextChanged (ed); } +//============================================================================== +class LabelAccessibilityHandler : public AccessibilityHandler +{ +public: + explicit LabelAccessibilityHandler (Label& labelToWrap) + : AccessibilityHandler (labelToWrap, + AccessibilityRole::staticText, + getAccessibilityActions (labelToWrap)), + label (labelToWrap) + { + } + + String getTitle() const override { return label.getText(); } + +private: + static AccessibilityActions getAccessibilityActions (Label& label) + { + if (label.isEditable()) + return AccessibilityActions().addAction (AccessibilityActionType::press, [&label] { label.showEditor(); }); + + return {}; + } + + Label& label; + + //============================================================================== + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LabelAccessibilityHandler) +}; + std::unique_ptr Label::createAccessibilityHandler() { return std::make_unique (*this); diff --git a/modules/juce_gui_basics/widgets/juce_ProgressBar.cpp b/modules/juce_gui_basics/widgets/juce_ProgressBar.cpp index 085535072e..7e84947c33 100644 --- a/modules/juce_gui_basics/widgets/juce_ProgressBar.cpp +++ b/modules/juce_gui_basics/widgets/juce_ProgressBar.cpp @@ -120,10 +120,10 @@ void ProgressBar::timerCallback() //============================================================================== std::unique_ptr ProgressBar::createAccessibilityHandler() { - class ProgressBarValueInterface : public AccessibilityRangedNumericValueInterface + class ValueInterface : public AccessibilityRangedNumericValueInterface { public: - explicit ProgressBarValueInterface (ProgressBar& progressBarToWrap) + explicit ValueInterface (ProgressBar& progressBarToWrap) : progressBar (progressBarToWrap) { } @@ -135,12 +135,14 @@ std::unique_ptr ProgressBar::createAccessibilityHandler() private: ProgressBar& progressBar; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ValueInterface) }; return std::make_unique (*this, AccessibilityRole::progressBar, AccessibilityActions{}, - AccessibilityHandler::Interfaces { std::make_unique (*this) }); + AccessibilityHandler::Interfaces { std::make_unique (*this) }); } } // namespace juce diff --git a/modules/juce_gui_basics/widgets/juce_Slider.cpp b/modules/juce_gui_basics/widgets/juce_Slider.cpp index 6f82d49f48..100e46afd5 100644 --- a/modules/juce_gui_basics/widgets/juce_Slider.cpp +++ b/modules/juce_gui_basics/widgets/juce_Slider.cpp @@ -1680,7 +1680,48 @@ void Slider::mouseWheelMove (const MouseEvent& e, const MouseWheelDetails& wheel std::unique_ptr Slider::createAccessibilityHandler() { - return std::make_unique (*this); + class ValueInterface : public AccessibilityValueInterface + { + public: + explicit ValueInterface (Slider& sliderToWrap) + : slider (sliderToWrap), + valueToControl (slider.isTwoValue() ? slider.getMaxValueObject() : slider.getValueObject()) + { + } + + bool isReadOnly() const override { return false; } + + double getCurrentValue() const override { return valueToControl.getValue(); } + void setValue (double newValue) override { valueToControl = newValue; } + + String getCurrentValueAsString() const override { return slider.getTextFromValue (getCurrentValue()); } + void setValueAsString (const String& newValue) override { setValue (slider.getValueFromText (newValue)); } + + AccessibleValueRange getRange() const override + { + return { { slider.getMinimum(), slider.getMaximum() }, + getStepSize() }; + } + + private: + double getStepSize() const + { + auto interval = slider.getInterval(); + + return interval != 0.0 ? interval + : slider.proportionOfLengthToValue (0.01); + } + + Slider& slider; + Value valueToControl; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ValueInterface) + }; + + return std::make_unique (*this, + AccessibilityRole::slider, + AccessibilityActions{}, + AccessibilityHandler::Interfaces { std::make_unique (*this) }); } } // namespace juce diff --git a/modules/juce_gui_basics/widgets/juce_TableListBox.cpp b/modules/juce_gui_basics/widgets/juce_TableListBox.cpp index c54539fc8b..aed0f60ed2 100644 --- a/modules/juce_gui_basics/widgets/juce_TableListBox.cpp +++ b/modules/juce_gui_basics/widgets/juce_TableListBox.cpp @@ -544,7 +544,46 @@ void TableListBox::updateColumnComponents() const std::unique_ptr TableListBox::createAccessibilityHandler() { - return std::make_unique (*this); + class TableInterface : public AccessibilityTableInterface + { + public: + explicit TableInterface (TableListBox& tableListBoxToWrap) + : tableListBox (tableListBoxToWrap) + { + } + + int getNumRows() const override + { + if (auto* tableModel = tableListBox.getModel()) + return tableModel->getNumRows(); + + return 0; + } + + int getNumColumns() const override + { + return tableListBox.getHeader().getNumColumns (false); + } + + const AccessibilityHandler* getCellHandler (int row, int column) const override + { + if (isPositiveAndBelow (row, getNumRows()) && isPositiveAndBelow (column, getNumColumns())) + if (auto* cellComponent = tableListBox.getCellComponent (tableListBox.getHeader().getColumnIdOfIndex (column, false), row)) + return cellComponent->getAccessibilityHandler(); + + return nullptr; + } + + private: + TableListBox& tableListBox; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TableInterface) + }; + + return std::make_unique (*this, + AccessibilityRole::list, + AccessibilityActions{}, + AccessibilityHandler::Interfaces { std::make_unique (*this) }); } //============================================================================== diff --git a/modules/juce_gui_basics/widgets/juce_TextEditor.cpp b/modules/juce_gui_basics/widgets/juce_TextEditor.cpp index aa98efd6e8..c36fced547 100644 --- a/modules/juce_gui_basics/widgets/juce_TextEditor.cpp +++ b/modules/juce_gui_basics/widgets/juce_TextEditor.cpp @@ -2687,6 +2687,81 @@ void TextEditor::coalesceSimilarSections() } //============================================================================== +class TextEditorAccessibilityHandler : public AccessibilityHandler +{ +public: + explicit TextEditorAccessibilityHandler (TextEditor& textEditorToWrap) + : AccessibilityHandler (textEditorToWrap, + textEditorToWrap.isReadOnly() ? AccessibilityRole::staticText : AccessibilityRole::editableText, + {}, + { textEditorToWrap.isReadOnly() ? nullptr : std::make_unique (textEditorToWrap) }), + textEditor (textEditorToWrap) + { + } + + String getTitle() const override + { + return textEditor.isReadOnly() ? textEditor.getText() : textEditor.getTitle(); + } + +private: + class TextEditorTextInterface : public AccessibilityTextInterface + { + public: + explicit TextEditorTextInterface (TextEditor& editor) + : textEditor (editor) + { + } + + bool isDisplayingProtectedText() const override { return textEditor.getPasswordCharacter() != 0; } + + int getTotalNumCharacters() const override { return textEditor.getText().length(); } + Range getSelection() const override { return textEditor.getHighlightedRegion(); } + void setSelection (Range r) override { textEditor.setHighlightedRegion (r); } + + String getText (Range r) const override + { + if (isDisplayingProtectedText()) + return String::repeatedString (String::charToString (textEditor.getPasswordCharacter()), + getTotalNumCharacters()); + + return textEditor.getTextInRange (r); + } + + void setText (const String& newText) override + { + textEditor.setText (newText); + } + + int getTextInsertionOffset() const override { return textEditor.getCaretPosition(); } + + RectangleList getTextBounds (Range textRange) const override + { + auto localRects = textEditor.getTextBounds (textRange); + RectangleList globalRects; + + std::for_each (localRects.begin(), localRects.end(), + [&] (const Rectangle& r) { globalRects.add (textEditor.localAreaToGlobal (r)); }); + + return globalRects; + } + + int getOffsetAtPoint (Point point) const override + { + auto localPoint = textEditor.getLocalPoint (nullptr, point); + return textEditor.getTextIndexAt (localPoint.x, localPoint.y); + } + + private: + TextEditor& textEditor; + }; + + TextEditor& textEditor; + + //============================================================================== + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TextEditorAccessibilityHandler) +}; + std::unique_ptr TextEditor::createAccessibilityHandler() { return std::make_unique (*this); diff --git a/modules/juce_gui_basics/widgets/juce_TreeView.cpp b/modules/juce_gui_basics/widgets/juce_TreeView.cpp index 7b0b07423a..9caa2957c9 100644 --- a/modules/juce_gui_basics/widgets/juce_TreeView.cpp +++ b/modules/juce_gui_basics/widgets/juce_TreeView.cpp @@ -1328,7 +1328,32 @@ void TreeView::itemDropped (const SourceDetails& dragSourceDetails) //============================================================================== std::unique_ptr TreeView::createAccessibilityHandler() { - return std::make_unique (*this); + class TableInterface : public AccessibilityTableInterface + { + public: + explicit TableInterface (TreeView& treeViewToWrap) : treeView (treeViewToWrap) {} + + int getNumRows() const override { return treeView.getNumRowsInTree(); } + int getNumColumns() const override { return 1; } + + const AccessibilityHandler* getCellHandler (int row, int) const override + { + if (auto* itemComp = treeView.getItemComponent (treeView.getItemOnRow (row))) + return itemComp->getAccessibilityHandler(); + + return nullptr; + } + + private: + TreeView& treeView; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TableInterface) + }; + + return std::make_unique (*this, + AccessibilityRole::tree, + AccessibilityActions{}, + AccessibilityHandler::Interfaces { std::make_unique (*this) }); } //==============================================================================