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

Accessibility: Make the FocusTraverser navigate onto disabled components

With this change disabled components become discoverable by screen
readers, similarly to how OS native user interface components behave by
default.

The KeyboardFocusTraverser will still skip disabled components so this
does not affect keyboard navigation without screen readers.
This commit is contained in:
attila 2025-07-04 15:38:18 +02:00 committed by Attila Szarvas
parent 02e826dddb
commit 8433428036
5 changed files with 104 additions and 21 deletions

View file

@ -45,10 +45,10 @@ struct FocusHelpers
return order > 0 ? order : std::numeric_limits<int>::max();
}
template <typename FocusContainerFn>
static void findAllComponents (const Component* parent,
std::vector<Component*>& components,
FocusContainerFn isFocusContainer)
bool (Component::* isFocusContainer)() const,
FocusTraverser::SkipDisabledComponents skipDisabledComponents)
{
if (parent == nullptr || parent->getNumChildComponents() == 0)
return;
@ -56,8 +56,12 @@ struct FocusHelpers
std::vector<Component*> localComponents;
for (auto* c : parent->getChildren())
if (c->isVisible() && c->isEnabled())
{
constexpr auto no = FocusTraverser::SkipDisabledComponents::no;
if (c->isVisible() && (c->isEnabled() || skipDisabledComponents == no))
localComponents.push_back (c);
}
const auto compareComponents = [&] (const Component* a, const Component* b)
{
@ -81,23 +85,23 @@ struct FocusHelpers
components.push_back (c);
if (! (c->*isFocusContainer)())
findAllComponents (c, components, isFocusContainer);
findAllComponents (c, components, isFocusContainer, skipDisabledComponents);
}
}
enum class NavigationDirection { forwards, backwards };
template <typename FocusContainerFn>
static Component* navigateFocus (const Component* current,
const Component* focusContainer,
NavigationDirection direction,
FocusContainerFn isFocusContainer)
bool (Component::* isFocusContainer)() const,
FocusTraverser::SkipDisabledComponents skipDisabledComponents)
{
if (focusContainer == nullptr)
return nullptr;
std::vector<Component*> components;
findAllComponents (focusContainer, components, isFocusContainer);
findAllComponents (focusContainer, components, isFocusContainer, skipDisabledComponents);
const auto iter = std::find (components.cbegin(), components.cend(), current);