Skip to content

Commit

Permalink
8284542: [Accessibility] [Win] Missing attribute for toggle state of …
Browse files Browse the repository at this point in the history
…CheckBox in CheckBoxTreeItem

Reviewed-by: kcr, kizune, angorya
  • Loading branch information
arapte committed May 17, 2023
1 parent 6aeaff3 commit bdadcb2
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 7 deletions.
Expand Up @@ -25,6 +25,10 @@

package javafx.scene.control.cell;

import javafx.scene.AccessibleAttribute;
import javafx.scene.AccessibleAttribute.ToggleState;
import javafx.scene.AccessibleRole;

import javafx.scene.control.CheckBoxTreeItem;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ObjectProperty;
Expand Down Expand Up @@ -344,6 +348,7 @@ private CheckBoxTreeCell(

// by default the graphic is null until the cell stops being empty
setGraphic(null);
setAccessibleRole(AccessibleRole.CHECK_BOX_TREE_ITEM);
}


Expand Down Expand Up @@ -479,4 +484,19 @@ public final Callback<TreeItem<T>, ObservableValue<Boolean>> getSelectedStateCal
// This was done to resolve RT-33603, but will impact the ability for
// TreeItem.graphic to change dynamically.
}

/** {@inheritDoc} */
@Override public Object queryAccessibleAttribute(AccessibleAttribute attribute, Object... parameters) {
switch (attribute) {
case TOGGLE_STATE:
if (checkBox.isIndeterminate()) {
return ToggleState.INDETERMINATE;
} else if (checkBox.isSelected()) {
return ToggleState.CHECKED;
} else {
return ToggleState.UNCHECKED;
}
default: return super.queryAccessibleAttribute(attribute, parameters);
}
}
}
Expand Up @@ -361,7 +361,13 @@ private static enum MacRole {
},
null
),
NSAccessibilityRowRole(new AccessibleRole[] {AccessibleRole.LIST_ITEM, AccessibleRole.TABLE_ROW, AccessibleRole.TREE_ITEM, AccessibleRole.TREE_TABLE_ROW},
NSAccessibilityRowRole(new AccessibleRole[] {
AccessibleRole.LIST_ITEM,
AccessibleRole.TABLE_ROW,
AccessibleRole.TREE_ITEM,
AccessibleRole.CHECK_BOX_TREE_ITEM,
AccessibleRole.TREE_TABLE_ROW
},
new MacAttribute[] {
MacAttribute.NSAccessibilitySubroleAttribute,
MacAttribute.NSAccessibilityIndexAttribute,
Expand Down Expand Up @@ -483,7 +489,11 @@ static MacRole getRole(AccessibleRole targetRole) {
private static enum MacSubrole {
NSAccessibilityTableRowSubrole(AccessibleRole.LIST_ITEM, AccessibleRole.TABLE_ROW),
NSAccessibilitySecureTextFieldSubrole(AccessibleRole.PASSWORD_FIELD),
NSAccessibilityOutlineRowSubrole(new AccessibleRole[] { AccessibleRole.TREE_ITEM, AccessibleRole.TREE_TABLE_ROW },
NSAccessibilityOutlineRowSubrole(new AccessibleRole[] {
AccessibleRole.TREE_ITEM,
AccessibleRole.CHECK_BOX_TREE_ITEM,
AccessibleRole.TREE_TABLE_ROW
},
new MacAttribute[] {
MacAttribute.NSAccessibilityDisclosedByRowAttribute,
MacAttribute.NSAccessibilityDisclosedRowsAttribute,
Expand Down Expand Up @@ -748,8 +758,9 @@ public void sendNotification(AccessibleAttribute notification) {
}

AccessibleRole role = (AccessibleRole) getAttribute(ROLE);
if (role == AccessibleRole.TREE_ITEM || role == AccessibleRole.TREE_TABLE_ROW) {
AccessibleRole containerRole = role == AccessibleRole.TREE_ITEM ? AccessibleRole.TREE_VIEW : AccessibleRole.TREE_TABLE_VIEW;
if (role == AccessibleRole.TREE_ITEM || role == AccessibleRole.CHECK_BOX_TREE_ITEM || role == AccessibleRole.TREE_TABLE_ROW) {
AccessibleRole containerRole = (role == AccessibleRole.TREE_ITEM || role == AccessibleRole.CHECK_BOX_TREE_ITEM) ?
AccessibleRole.TREE_VIEW : AccessibleRole.TREE_TABLE_VIEW;
MacAccessible container = (MacAccessible)getContainerAccessible(containerRole);
if (container != null) {
NSAccessibilityPostNotification(container.getNativeAccessible(), MacNotification.NSAccessibilityRowCountChangedNotification.ptr);
Expand Down
Expand Up @@ -299,14 +299,16 @@ public void sendNotification(AccessibleAttribute notification) {
break;
}
case INDETERMINATE: {
if (getAttribute(ROLE) == AccessibleRole.CHECK_BOX) {
Object role = getAttribute(ROLE);
if (role == AccessibleRole.CHECK_BOX || role == AccessibleRole.CHECK_BOX_TREE_ITEM) {
notifyToggleState();
}
break;
}
case SELECTED: {
Object role = getAttribute(ROLE);
if (role == AccessibleRole.CHECK_BOX || role == AccessibleRole.TOGGLE_BUTTON) {
if (role == AccessibleRole.CHECK_BOX || role == AccessibleRole.TOGGLE_BUTTON
|| role == AccessibleRole.CHECK_BOX_TREE_ITEM) {
notifyToggleState();
break;
}
Expand Down Expand Up @@ -431,6 +433,7 @@ private Accessible getContainer() {
case LIST_ITEM: return getContainerAccessible(AccessibleRole.LIST_VIEW);
case TAB_ITEM: return getContainerAccessible(AccessibleRole.TAB_PANE);
case PAGE_ITEM: return getContainerAccessible(AccessibleRole.PAGINATION);
case CHECK_BOX_TREE_ITEM:
case TREE_ITEM: return getContainerAccessible(AccessibleRole.TREE_VIEW);
case TREE_TABLE_ROW:
case TREE_TABLE_CELL: return getContainerAccessible(AccessibleRole.TREE_TABLE_VIEW);
Expand Down Expand Up @@ -477,6 +480,7 @@ private int getControlType() {
case COMBO_BOX: return UIA_ComboBoxControlTypeId;
case HYPERLINK: return UIA_HyperlinkControlTypeId;
case TREE_VIEW: return UIA_TreeControlTypeId;
case CHECK_BOX_TREE_ITEM:
case TREE_ITEM: return UIA_TreeItemControlTypeId;
case PROGRESS_INDICATOR: return UIA_ProgressBarControlTypeId;
case TOOL_BAR: return UIA_ToolBarControlTypeId;
Expand Down Expand Up @@ -530,6 +534,7 @@ private void changeSelection(boolean add, boolean clear) {
}
break;
}
case CHECK_BOX_TREE_ITEM:
case TREE_ITEM: {
Integer index = (Integer)getAttribute(INDEX);
if (index != null) {
Expand Down Expand Up @@ -628,6 +633,12 @@ private long GetPatternProvider(int patternId) {
impl = patternId == UIA_SelectionPatternId ||
patternId == UIA_ScrollPatternId;
break;
case CHECK_BOX_TREE_ITEM:
impl = patternId == UIA_SelectionItemPatternId ||
patternId == UIA_ExpandCollapsePatternId ||
patternId == UIA_ScrollItemPatternId ||
patternId == UIA_TogglePatternId;
break;
case TREE_ITEM:
impl = patternId == UIA_SelectionItemPatternId ||
patternId == UIA_ExpandCollapsePatternId ||
Expand Down Expand Up @@ -913,6 +924,15 @@ private WinVariant GetPropertyValue(int propertyId) {
variant.bstrVal = "JavaFXProvider";
break;
}
case UIA_ToggleToggleStatePropertyId: {
AccessibleRole role = (AccessibleRole) getAttribute(ROLE);
if (role == AccessibleRole.CHECK_BOX_TREE_ITEM) {
variant = new WinVariant();
variant.vt = WinVariant.VT_I4;
variant.lVal = get_ToggleState();
}
break;
}
default:
}
return variant;
Expand Down Expand Up @@ -1008,7 +1028,8 @@ private long Navigate(int direction) {
if (isDisposed()) return 0;
AccessibleRole role = (AccessibleRole)getAttribute(ROLE);
/* special case for the tree item hierarchy, as expected by Windows */
boolean treeCell = role == AccessibleRole.TREE_ITEM;
boolean treeCell = (role == AccessibleRole.TREE_ITEM
|| role == AccessibleRole.CHECK_BOX_TREE_ITEM);
Node node = null;
switch (direction) {
case NavigateDirection_Parent: {
Expand Down Expand Up @@ -1369,6 +1390,7 @@ private void Select() {
executeAction(AccessibleAction.FIRE);
break;
case LIST_ITEM:
case CHECK_BOX_TREE_ITEM:
case TREE_ITEM:
case TABLE_CELL:
case TREE_TABLE_CELL:
Expand Down Expand Up @@ -1562,6 +1584,16 @@ private void Toggle() {

private int get_ToggleState() {
if (isDisposed()) return 0;
if (getAttribute(ROLE) == AccessibleRole.CHECK_BOX_TREE_ITEM) {
ToggleState toggleState = (ToggleState)getAttribute(TOGGLE_STATE);
if (toggleState == ToggleState.INDETERMINATE) {
return ToggleState_Indeterminate;
} else if (toggleState == ToggleState.CHECKED) {
return ToggleState_On;
} else {
return ToggleState_Off;
}
}
if (Boolean.TRUE.equals(getAttribute(INDETERMINATE))) {
return ToggleState_Indeterminate;
}
Expand Down Expand Up @@ -1888,6 +1920,7 @@ private void ScrollIntoView() {
}
break;
}
case CHECK_BOX_TREE_ITEM:
case TREE_ITEM: {
Integer index = (Integer)getAttribute(INDEX);
if (index != null) {
Expand Down
Expand Up @@ -337,6 +337,27 @@ public enum AccessibleAttribute {
*/
INDETERMINATE(Boolean.class),

/**
* Returns {@link ToggleState toggle state} of CheckBox of CheckBoxTreeItem.
* <ul>
* <li>Used by: CheckBoxTreeItem</li>
* <li>Needs notify: yes </li>
* <li>Return Type: {@link ToggleState}
* <ul>
* <li>{@link ToggleState#UNCHECKED ToggleState.UNCHECKED}: control is not selected</li>
* <li>{@link ToggleState#CHECKED ToggleState.CHECKED}: control is selected</li>
* <li>{@link ToggleState#INDETERMINATE ToggleState.INDETERMINATE}:
* selection state of control cannot be determined</li>
* </ul>
* </li>
* <li>Parameters: </li>
* </ul>
*
* @see ToggleState
* @since 21
*/
TOGGLE_STATE(ToggleState.class),

/**
* Returns the item at the given index.
* <ul>
Expand Down Expand Up @@ -800,4 +821,26 @@ public enum AccessibleAttribute {
public Class<?> getReturnType() {
return returnClass;
}

/**
* This enum describes the values for {@link AccessibleAttribute#TOGGLE_STATE TOGGLE_STATE} attribute.
*
* @since 21
*/
public enum ToggleState {
/**
* Indicates that the toggle control is not selected.
*/
UNCHECKED,

/**
* Indicates that the toggle control is selected.
*/
CHECKED,

/**
* Indicates that the toggle state of the control cannot be determined.
*/
INDETERMINATE
}
}
Expand Up @@ -739,6 +739,33 @@ public enum AccessibleRole {
*/
TREE_ITEM,

/**
* Check Box Tree Item role.
* <p>
* Attributes:
* <ul>
* <li> {@link AccessibleAttribute#TEXT} </li>
* <li> {@link AccessibleAttribute#INDEX} </li>
* <li> {@link AccessibleAttribute#SELECTED} </li>
* <li> {@link AccessibleAttribute#EXPANDED} </li>
* <li> {@link AccessibleAttribute#LEAF} </li>
* <li> {@link AccessibleAttribute#DISCLOSURE_LEVEL} </li>
* <li> {@link AccessibleAttribute#TREE_ITEM_COUNT} </li>
* <li> {@link AccessibleAttribute#TREE_ITEM_AT_INDEX} </li>
* <li> {@link AccessibleAttribute#TREE_ITEM_PARENT} </li>
* <li> {@link AccessibleAttribute#TOGGLE_STATE} </li>
* </ul>
* Actions:
* <ul>
* <li> {@link AccessibleAction#EXPAND} </li>
* <li> {@link AccessibleAction#COLLAPSE} </li>
* <li> {@link AccessibleAction#REQUEST_FOCUS} </li>
* </ul>
*
* @since 21
*/
CHECK_BOX_TREE_ITEM,

/**
* Tree Table Cell role.
* <p>
Expand Down

1 comment on commit bdadcb2

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.