1//////////////////////////////////////////////////////////////////////////////// 2// 3// ADOBE SYSTEMS INCORPORATED 4// Copyright 2003-2007 Adobe Systems Incorporated 5// All Rights Reserved. 6// 7// NOTICE: Adobe permits you to use, modify, and distribute this file 8// in accordance with the terms of the license agreement accompanying it. 9// 10//////////////////////////////////////////////////////////////////////////////// 11 12package mx.accessibility 13{ 14 15import flash.accessibility.Accessibility; 16import flash.events.Event; 17import mx.controls.Menu; 18import mx.core.UIComponent; 19import mx.core.mx_internal; 20import mx.events.MenuEvent; 21 22use namespace mx_internal; 23 24/** 25 * MenuAccImpl is a subclass of AccessibilityImplementation 26 * which implements accessibility for the Menu class. 27 */ 28public class MenuAccImpl extends ListBaseAccImpl 29{ 30 include "../core/Version.as"; 31 32 //-------------------------------------------------------------------------- 33 // 34 // Class constants 35 // 36 //-------------------------------------------------------------------------- 37 38 /** 39 * @private 40 */ 41 private static const ROLE_SYSTEM_MENUITEM:uint = 0x0C; 42 43 /** 44 * @private 45 */ 46 private static const STATE_SYSTEM_CHECKED:uint = 0x00000010; 47 48 /** 49 * @private 50 */ 51 private static const STATE_SYSTEM_FOCUSED:uint = 0x00000004; 52 53 /** 54 * @private 55 */ 56 private static const STATE_SYSTEM_HASPOPUP:uint = 0x40000000; 57 58 /** 59 * @private 60 */ 61 private static const STATE_SYSTEM_HOTTRACKED:uint = 0x00000080; 62 63 /** 64 * @private 65 */ 66 private static const STATE_SYSTEM_UNAVAILABLE:uint = 0x00000001; 67 68 /** 69 * @private 70 */ 71 private static const EVENT_OBJECT_FOCUS:uint = 0x8005; 72 73 /** 74 * @private 75 */ 76 private static const EVENT_OBJECT_SELECTION:uint = 0x8006; 77 78 /** 79 * @private 80 */ 81 private static const EVENT_SYSTEM_MENUPOPUPSTART:uint = 0x00000006; 82 83 /** 84 * @private 85 */ 86 private static const EVENT_SYSTEM_MENUPOPUPEND:uint = 0x00000007; 87 88 //-------------------------------------------------------------------------- 89 // 90 // Class methods 91 // 92 //-------------------------------------------------------------------------- 93 94 /** 95 * Enables accessibility in the Menu class. 96 * 97 * <p>This method is called by application startup code 98 * that is autogenerated by the MXML compiler. 99 * Afterwards, when instances of Menu are initialized, 100 * their <code>accessibilityImplementation</code> property 101 * will be set to an instance of this class.</p> 102 */ 103 public static function enableAccessibility():void 104 { 105 Menu.createAccessibilityImplementation = 106 createAccessibilityImplementation; 107 } 108 109 /** 110 * @private 111 * Creates a Menu's AccessibilityImplementation object. 112 * This method is called from UIComponent's 113 * initializeAccessibility() method. 114 */ 115 mx_internal static function createAccessibilityImplementation( 116 component:UIComponent):void 117 { 118 component.accessibilityImplementation = 119 new MenuAccImpl(component); 120 } 121 122 //-------------------------------------------------------------------------- 123 // 124 // Constructor 125 // 126 //-------------------------------------------------------------------------- 127 128 /** 129 * Constructor. 130 * 131 * @param master The UIComponent instance that this AccImpl instance 132 * is making accessible. 133 */ 134 public function MenuAccImpl(master:UIComponent) 135 { 136 super(master); 137 138 role = 0x0B; // ROLE_SYSTEM_MENUPOPUP 139 } 140 141 //-------------------------------------------------------------------------- 142 // 143 // Overridden properties: AccImpl 144 // 145 //-------------------------------------------------------------------------- 146 147 //---------------------------------- 148 // eventsToHandle 149 //---------------------------------- 150 151 /** 152 * @private 153 * Array of events that we should listen for from the master component. 154 */ 155 override protected function get eventsToHandle():Array 156 { 157 return super.eventsToHandle.concat( 158 [ "itemRollOver", "menuShow", "menuHide" ]); 159 } 160 161 //-------------------------------------------------------------------------- 162 // 163 // Overridden methods: AccessibilityImplementation 164 // 165 //-------------------------------------------------------------------------- 166 167 /** 168 * @private 169 * Gets the role for the component. 170 * 171 * @param childID children of the component 172 */ 173 override public function get_accRole(childID:uint):uint 174 { 175 return childID == 0 ? role : ROLE_SYSTEM_MENUITEM; 176 } 177 178 /** 179 * @private 180 * IAccessible method for returning the state of the Menu. 181 * States are predefined for all the components in MSAA. 182 * Values are assigned to each state. 183 * Depending upon the menuItem being Selected, Selectable, 184 * Invisible, Offscreen, a value is returned. 185 * 186 * @param childID uint 187 * 188 * @return State uint 189 */ 190 override public function get_accState(childID:uint):uint 191 { 192 var accState:uint = getState(childID); 193 194 if (childID > 0 && childID < 100000) 195 { 196 var item:Object = Menu(master).dataProvider[childID - 1]; 197 198 if (!Menu(master).dataDescriptor.isEnabled(item)) 199 { 200 accState |= STATE_SYSTEM_UNAVAILABLE; 201 return accState; 202 } 203 204 //if (Menu(master).dataDescriptor.isFocused(item)) 205 accState |= STATE_SYSTEM_HOTTRACKED | STATE_SYSTEM_FOCUSED; 206 207 if (Menu(master).dataDescriptor.isToggled(item)) 208 accState |= STATE_SYSTEM_CHECKED; 209 210 if (Menu(master).dataDescriptor.isBranch(item)) 211 accState |= STATE_SYSTEM_HASPOPUP; 212 } 213 return accState; 214 } 215 216 /** 217 * @private 218 * IAccessible method for returning the Default Action. 219 * 220 * @param childID uint 221 * 222 * @return focused childID. 223 */ 224 override public function get_accDefaultAction(childID:uint):String 225 { 226 if (childID == 0) 227 return null; 228 229 var item:Object = Menu(master).dataProvider[childID - 1]; 230 231 return Menu(master).dataDescriptor.isBranch(item) ? "Open" : "Execute"; 232 } 233 234 //-------------------------------------------------------------------------- 235 // 236 // Overridden methods: AccImpl 237 // 238 //-------------------------------------------------------------------------- 239 240 /** 241 * @private 242 * method for returning the name of the MenuItem 243 * which is spoken out by the screen reader 244 * The MenuItem should return the label as the name 245 * and Menu should return the name specified in the Accessibility Panel. 246 * 247 * @param childID uint 248 * 249 * @return Name String 250 */ 251 override protected function getName(childID:uint):String 252 { 253 if (childID == 0) 254 return ""; 255 256 var menu:Menu = Menu(master); 257 258 var item:Object = menu.dataProvider[childID - 1]; 259 260 return menu.itemToLabel(item); 261 } 262 263 //-------------------------------------------------------------------------- 264 // 265 // Overridden event handlers: AccImpl 266 // 267 //-------------------------------------------------------------------------- 268 269 /** 270 * @private 271 * Override the generic event handler. 272 * All AccImpl must implement this 273 * to listen for events from its master component. 274 */ 275 override protected function eventHandler(event:Event):void 276 { 277 // Let AccImpl class handle the events 278 // that all accessible UIComponents understand. 279 $eventHandler(event); 280 281 var index:int = 0; 282 var childID:uint; 283 284 switch (event.type) 285 { 286 case MenuEvent.ITEM_ROLL_OVER: 287 { 288 index = MenuEvent(event).index; 289 if (index >= 0) 290 { 291 childID = index + 1; 292 293 Accessibility.sendEvent(MenuEvent(event).menu, childID, 294 EVENT_OBJECT_FOCUS); 295 296 Accessibility.sendEvent(MenuEvent(event).menu, childID, 297 EVENT_OBJECT_SELECTION); 298 } 299 break; 300 } 301 302 case MenuEvent.ITEM_CLICK: 303 { 304 index = MenuEvent(event).menu.selectedIndex; 305 if (index >= 0) 306 { 307 childID = index + 1; 308 309 Accessibility.sendEvent(MenuEvent(event).menu, childID, 310 EVENT_OBJECT_FOCUS); 311 312 Accessibility.sendEvent(MenuEvent(event).menu, childID, 313 EVENT_OBJECT_SELECTION); 314 } 315 break; 316 } 317 318 case MenuEvent.MENU_SHOW: 319 { 320 Accessibility.sendEvent(MenuEvent(event).menu, 0, 321 EVENT_SYSTEM_MENUPOPUPSTART); 322 break; 323 } 324 325 case MenuEvent.MENU_HIDE: 326 { 327 Accessibility.sendEvent(MenuEvent(event).menu, 0, 328 EVENT_SYSTEM_MENUPOPUPEND); 329 break; 330 } 331 } 332 } 333} 334 335} 336