1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00

Accessibility: Removed widget_handlers

This commit is contained in:
ed 2021-05-20 17:48:41 +01:00
parent 88313c26b6
commit 333983947e
17 changed files with 321 additions and 623 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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<SliderValueInterface> (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

View file

@ -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<TableListBoxTableInterface> (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

View file

@ -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<TextEditorTextInterface> (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<int> getSelection() const override { return textEditor.getHighlightedRegion(); }
void setSelection (Range<int> r) override { textEditor.setHighlightedRegion (r); }
String getText (Range<int> 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<int> getTextBounds (Range<int> textRange) const override
{
auto localRects = textEditor.getTextBounds (textRange);
RectangleList<int> globalRects;
std::for_each (localRects.begin(), localRects.end(),
[&] (const Rectangle<int>& r) { globalRects.add (textEditor.localAreaToGlobal (r)); });
return globalRects;
}
int getOffsetAtPoint (Point<int> 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

View file

@ -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<TreeViewTableInterface> (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

View file

@ -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<AccessibilityHandler> Button::createAccessibilityHandler()
{
return std::make_unique<ButtonAccessibilityHandler> (*this);

View file

@ -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

View file

@ -443,25 +443,15 @@ bool ScrollBar::getVisibility() const noexcept
//==============================================================================
std::unique_ptr<AccessibilityHandler> 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<AccessibilityHandler> ScrollBar::createAccessibilityHandler()
private:
ScrollBar& scrollBar;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ValueInterface)
};
return std::make_unique<AccessibilityHandler> (*this,
AccessibilityRole::scrollBar,
AccessibilityActions{},
AccessibilityHandler::Interfaces { std::make_unique<ScrollBarValueInterface> (*this) });
AccessibilityHandler::Interfaces { std::make_unique<ValueInterface> (*this) });
}
} // namespace juce

View file

@ -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<AccessibilityHandler> ComboBox::createAccessibilityHandler()
{
return std::make_unique<ComboBoxAccessibilityHandler> (*this);

View file

@ -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<AccessibilityHandler> Label::createAccessibilityHandler()
{
return std::make_unique<LabelAccessibilityHandler> (*this);

View file

@ -120,10 +120,10 @@ void ProgressBar::timerCallback()
//==============================================================================
std::unique_ptr<AccessibilityHandler> 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<AccessibilityHandler> ProgressBar::createAccessibilityHandler()
private:
ProgressBar& progressBar;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ValueInterface)
};
return std::make_unique<AccessibilityHandler> (*this,
AccessibilityRole::progressBar,
AccessibilityActions{},
AccessibilityHandler::Interfaces { std::make_unique<ProgressBarValueInterface> (*this) });
AccessibilityHandler::Interfaces { std::make_unique<ValueInterface> (*this) });
}
} // namespace juce

View file

@ -1680,7 +1680,48 @@ void Slider::mouseWheelMove (const MouseEvent& e, const MouseWheelDetails& wheel
std::unique_ptr<AccessibilityHandler> Slider::createAccessibilityHandler()
{
return std::make_unique<SliderAccessibilityHandler> (*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<AccessibilityHandler> (*this,
AccessibilityRole::slider,
AccessibilityActions{},
AccessibilityHandler::Interfaces { std::make_unique<ValueInterface> (*this) });
}
} // namespace juce

View file

@ -544,7 +544,46 @@ void TableListBox::updateColumnComponents() const
std::unique_ptr<AccessibilityHandler> TableListBox::createAccessibilityHandler()
{
return std::make_unique<TableListBoxAccessibilityHandler> (*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<AccessibilityHandler> (*this,
AccessibilityRole::list,
AccessibilityActions{},
AccessibilityHandler::Interfaces { std::make_unique<TableInterface> (*this) });
}
//==============================================================================

View file

@ -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<TextEditorTextInterface> (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<int> getSelection() const override { return textEditor.getHighlightedRegion(); }
void setSelection (Range<int> r) override { textEditor.setHighlightedRegion (r); }
String getText (Range<int> 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<int> getTextBounds (Range<int> textRange) const override
{
auto localRects = textEditor.getTextBounds (textRange);
RectangleList<int> globalRects;
std::for_each (localRects.begin(), localRects.end(),
[&] (const Rectangle<int>& r) { globalRects.add (textEditor.localAreaToGlobal (r)); });
return globalRects;
}
int getOffsetAtPoint (Point<int> 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<AccessibilityHandler> TextEditor::createAccessibilityHandler()
{
return std::make_unique<TextEditorAccessibilityHandler> (*this);

View file

@ -1328,7 +1328,32 @@ void TreeView::itemDropped (const SourceDetails& dragSourceDetails)
//==============================================================================
std::unique_ptr<AccessibilityHandler> TreeView::createAccessibilityHandler()
{
return std::make_unique<TreeViewAccessibilityHandler> (*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<AccessibilityHandler> (*this,
AccessibilityRole::tree,
AccessibilityActions{},
AccessibilityHandler::Interfaces { std::make_unique<TableInterface> (*this) });
}
//==============================================================================