Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a screen reader mode option and implement on character creation screens #72344

Merged
merged 15 commits into from
Mar 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
6b2bf35
Add a SCREEN_READER_MODE option
ZeroInternalReflection Mar 8, 2024
abe1249
Implement SCREEN_READER_MODE on character creation - points
ZeroInternalReflection Mar 8, 2024
cfcb83a
Implement SCREEN_READER_MODE on character creation - scenarios
ZeroInternalReflection Mar 9, 2024
0736ed6
Implement SCREEN_READER_MODE on character creation - professions
ZeroInternalReflection Mar 9, 2024
8e5b26c
Implement SCREEN_READER_MODE on character creation - backgrounds
ZeroInternalReflection Mar 9, 2024
f7a33e2
Implement SCREEN_READER_MODE on character creation - stats
ZeroInternalReflection Mar 9, 2024
e2690c0
Implement SCREEN_READER_MODE on character creation - traits
ZeroInternalReflection Mar 11, 2024
3068767
Implement SCREEN_READER_MODE on character creation - skills
ZeroInternalReflection Mar 11, 2024
70aeb7b
Add SCREEN_READER_MODE documentation to USER_INTERFACE
ZeroInternalReflection Mar 11, 2024
9aa6593
Rework player_difficulty summary for screen_reader_mode
ZeroInternalReflection Mar 12, 2024
27e7744
Remove redundant spaces from player_difficulty to_string
ZeroInternalReflection Mar 13, 2024
4b97aef
Remove redundant string initialization from set_traits
ZeroInternalReflection Mar 13, 2024
e8032ee
Remove redundant string initialization in set_profession
ZeroInternalReflection Mar 13, 2024
07abc06
Remove redundant string initialization from set_hobbies
ZeroInternalReflection Mar 13, 2024
3c8c481
Remove redundant string initialization from set_scenario
ZeroInternalReflection Mar 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
165 changes: 155 additions & 10 deletions doc/USER_INTERFACE_AND_ACCESSIBILITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,42 @@ text to show correctly.

## Compatibility with screen readers

There are people who use screen readers to play Cataclysm DDA. In order for screen
readers to announce the most important information in a UI, the terminal cursor has
to be placed at the correct location. This information may be text such as selected
item names in a list, etc, and the cursor has to be placed exactly at the beginning
of the text for screen readers to announce it. (Note: from my test with an Ubuntu
VM, if the cursor is placed after the end of the text, the cursor might be wrapped
to the next line and cause the screen reader to announce the text incorrectly. It
also seems to be easier for people to control the screen reader to read from the
beginning of the text where the cursor is placed.)
There are people who use screen readers to play Cataclysm DDA. There are several
things to keep in mind when checking the user interface for compatibility with
screen readers. These include:

1. Screen reader mode:
An option ("SCREEN_READER_MODE") has been added where the user can indicate that
they are using a screen reader. If a change to the UI to optimize for screen
readers would be undesirable for other users, consider checking against
"SCREEN_READER_MODE", and including the change when true.

2. Text color:
Text color is not announced by screen readers. If key information is only
communicated to the player through text color, that information will not be
available to players using screen readers. For example, a simple
uilist where some options have been disabled:

----------------------------------------------------------------------------
|Execute which action? |
|--------------------------------------------------------------------------|
|<color_c_green>1</color> <color_c_light_gray>Cut up an item</color> |
|<color_c_green>f</color> <color_c_light_gray>Start a fire quickly</color> |
|<color_c_dark_gray>h Use holster</color> |
----------------------------------------------------------------------------

A screen reader user will only know that "Use holster" is unavailable when they
attempt to use it. When presenting information, consider hiding inaccessible
options and adding text to confirm information conveyed by text color. As an
example, the display of food spoilage status:

<color_c_light_blue>Acorns (fresh)</color>
<color_c_yellow>Acorns (old)</color>

3. Cursor placement
In general, screen readers will start reading where the program has set the terminal
cursor. Thus, the cursor should be set to the beginning of the most important
section of the UI.

The recommended way to place the cursor is to use `ui_adaptor`. This ensures the
desired cursor position is preserved when subsequent output code changes the
Expand All @@ -62,4 +89,122 @@ For debugging purposes, you can set the `DEBUG_CURSES_CURSOR` compile flag to
always show the cursor in the terminal (currently only works with the curses
build).

For more information and examples, please see the documentation in `ui_manager.h`.
4. Window layout
While setting the terminal cursor position is sufficient to set things up for
screen readers in many cases, there are caveats to this. Screen readers will also
attempt to detect text changes. If that text change is after the terminal cursor,
the screen reader may skip over text. As an example (terminal position noted
by X):

XEye color: amber

changing into

XEye color: blue

The screen reader will only read the word "blue", even though the cursor is
set to start reading at "Eye".

Another complication is if the screen reader detects text changes above the
terminal cursor. As an example:

Lifestyle: underpowered
XStrength: 8

changing into

Lifestyle: weak
XStrength: 9

The screen reader will start reading at "weak".

Behaviour like this means that screen readers struggle with certain common UI
layouts. Examples of how to implement SCREEN_READER_MODE in various UI layouts
can be found in src/newcharacter.cpp.

Note: In all following examples, the terminal cursor is marked "X".

4a. List with additional information at the top or bottom:

-----------------------------------------------------
|Choose type of butchery: |
|---------------------------------------------------|
XB Quick butchery 6 minutes |
|b Full butchery 39 minutes |
|---------------------------------------------------|
|This technique is used when you are in a hurry, but|
|still want to harvest something from the corpse. |
-----------------------------------------------------
Figure 4ai - List with details at the bottom, current configuration

If the cursor is set at "Quick butchery", then the screen reader will read all of the
other options before getting to the description of what "Quick butchery" entails. The
preferred layout in SCREEN_READER_MODE is the following:

-----------------------------------------------------
|Choose type of butchery: |
|---------------------------------------------------|
| |
| |
|---------------------------------------------------|
XB Quick butchery 6 minutes |
|This technique is used when you are in a hurry, but|
-----------------------------------------------------
Figure 4aii - List with details at the bottom, recommended "SCREEN_READER_MODE"

That is:
1. Add the currently-selected list entry to the detail pane at the bottom, and
2. Disable display of the list of options.
The screen reader user can then scroll through the list of available options, only
hearing about the details of the currently-selected option.

Hiding the list of options is necessary even when the cursor is set to point X.
In addition to following the terminal cursor, screen readers will try to detect when
text changes, and can be misled by scrolling text. As an example:

-----------------------------------------------------
|Choose type of butchery: |
|---------------------------------------------------|
Yb Full butchery 39 minutes |
|f Field dress corpse 5 minutes |
|---------------------------------------------------|
XThis technique is used to properly butcher a corpse|
|and requires a rope & a tree or a butchering rack, |
-----------------------------------------------------
Figure 4aiii - List with details at the bottom with scrolling issues

When the list scrolls, the text at the top changes, and the screen reader will
'helpfully' start reading at point Y rather than the current cursor position X.

4b. List with additional information at the side:

_______________________________
|List | Details relating to|
XItem 1 | item 1. Lorem |
|Item 2 | ipsum |
|Item 3 | |
|Item 4 | |
|Item 5 | |
-------------------------------
Figure 4bi - List with details at the side, current configuration

In this common layout, the screen reader is unable to differentiate between the two
panes, and ends up reading the list interwoven with the details of the currently-selected
item. This is true whether the terminal cursor is set to the current item or to the top
left of the details pane.

The recommended layout in SCREEN_READER_MODE is the following:

_______________________________
| | XItem 1 |
| | Details relating to|
| | item 1. Lorem |
| | ipsum |
| | |
| | |
-------------------------------
Figure 4bii - List with details at the side, recommended "SCREEN_READER_MODE"

That is:
1. Add the currently-selected list entry to the detail pane at the side, and
2. Disable display of the list of options.
Loading
Loading