|
3 | 3 | */
|
4 | 4 | package processing.app.tools;
|
5 | 5 |
|
| 6 | +import processing.app.PreferencesData; |
| 7 | + |
6 | 8 | import javax.swing.*;
|
7 | 9 | import javax.swing.event.ChangeEvent;
|
8 | 10 | import javax.swing.event.ChangeListener;
|
@@ -567,6 +569,43 @@ public MenuScrollTimer(final int increment, int interval) {
|
567 | 569 | public void actionPerformed(ActionEvent e) {
|
568 | 570 | firstIndex += increment * accelerator;
|
569 | 571 | 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 | + } |
570 | 609 | }
|
571 | 610 | });
|
572 | 611 | }
|
|
0 commit comments