Skip to content

Commit 930ec16

Browse files
authored
Merge pull request #9168 from joew46167/scrollMenu
Tools Boards menu scroll updates for accessibility
2 parents b9c3f00 + 2a53cba commit 930ec16

File tree

1 file changed

+39
-0
lines changed

1 file changed

+39
-0
lines changed

app/src/processing/app/tools/MenuScroller.java

+39
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
*/
44
package processing.app.tools;
55

6+
import processing.app.PreferencesData;
7+
68
import javax.swing.*;
79
import javax.swing.event.ChangeEvent;
810
import javax.swing.event.ChangeListener;
@@ -567,6 +569,43 @@ public MenuScrollTimer(final int increment, int interval) {
567569
public void actionPerformed(ActionEvent e) {
568570
firstIndex += increment * accelerator;
569571
refreshMenu();
572+
if (PreferencesData.getBoolean("ide.accessible")) {
573+
// If the user has chosen to use accessibility features, it means that they are using a screen reader
574+
// to assist them in development of their project. This scroller is very unfriendly toward screen readers
575+
// because it does not tell the user that it is scrolling through the board options, and it does not read
576+
// the name of the boards as they scroll by. It is possible that the desired board will never become
577+
// accessible.
578+
// Because this scroller is quite nice for the sighted user, the idea here is to continue to use the
579+
// scroller, but to fool it into scrolling one item at a time for accessible features users so that the
580+
// screen readers work well, too.
581+
// It's not the prettiest of code, but it works.
582+
String itemClassName;
583+
int keyEvent;
584+
585+
// The blind user likely used an arrow key to get to the scroller. Determine which arrow key
586+
// so we can send an event for the opposite arrow key. This fools the scroller into scrolling
587+
// a single item. Get the class name of the new item while we're here
588+
if (increment > 0) {
589+
itemClassName = menuItems[firstIndex + scrollCount - 1].getClass().getName();
590+
keyEvent = KeyEvent.VK_UP;
591+
}
592+
else {
593+
itemClassName = menuItems[firstIndex].getClass().getName();
594+
keyEvent = KeyEvent.VK_DOWN;
595+
}
596+
597+
// Use the class name to check if the next item is a separator. If it is, just let it scroll on like
598+
// normal, otherwise move the cursor back with the opposite key event to the new item so that item is read
599+
// by a screen reader and the user can use their arrow keys to navigate the list one item at a time
600+
if (!itemClassName.equals(JSeparator.class.getName()) ) {
601+
KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
602+
Component comp = manager.getFocusOwner();
603+
KeyEvent event = new KeyEvent(comp,
604+
KeyEvent.KEY_PRESSED, System.currentTimeMillis(), 0,
605+
keyEvent, KeyEvent.CHAR_UNDEFINED);
606+
comp.dispatchEvent(event);
607+
}
608+
}
570609
}
571610
});
572611
}

0 commit comments

Comments
 (0)