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.MenuBar; 18import mx.core.UIComponent; 19import mx.core.mx_internal; 20import mx.events.MenuEvent; 21 22use namespace mx_internal; 23 24/** 25 * MenuBarAccImpl is a subclass of AccessibilityImplementation 26 * which implements accessibility for the MenuBar class. 27 */ 28public class MenuBarAccImpl extends AccImpl 29{ 30 include "../core/Version.as"; 31 32 //-------------------------------------------------------------------------- 33 // 34 // 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_FOCUSABLE:uint = 0x00100000; 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_SELECTABLE:uint = 0x00200000; 67 68 /** 69 * @private 70 */ 71 private static const STATE_SYSTEM_UNAVAILABLE:uint = 0x00000001; 72 73 /** 74 * @private 75 */ 76 private static const EVENT_OBJECT_FOCUS:uint = 0x8005; 77 78 /** 79 * @private 80 */ 81 private static const EVENT_SYSTEM_MENUEND:uint = 0x00000005; 82 83 /** 84 * @private 85 */ 86 private static const EVENT_SYSTEM_MENUSTART:uint = 0x00000004; 87 88 /** 89 * @private 90 */ 91 private static const EVENT_OBJECT_SELECTION:uint = 0x8006; 92 93 //-------------------------------------------------------------------------- 94 // 95 // Class methods 96 // 97 //-------------------------------------------------------------------------- 98 99 /** 100 * Enables accessibility in the MenuBar class. 101 * 102 * <p>This method is called by application startup code 103 * that is autogenerated by the MXML compiler. 104 * Afterwards, when instances of MenuBar are initialized, 105 * their <code>accessibilityImplementation</code> property 106 * will be set to an instance of this class.</p> 107 */ 108 public static function enableAccessibility():void 109 { 110 MenuBar.createAccessibilityImplementation = 111 createAccessibilityImplementation; 112 } 113 114 /** 115 * @private 116 * Creates a MenuBar's AccessibilityImplementation object. 117 * This method is called from UIComponent's 118 * initializeAccessibility() method. 119 */ 120 mx_internal static function createAccessibilityImplementation( 121 component:UIComponent):void 122 { 123 component.accessibilityImplementation = 124 new MenuBarAccImpl(component); 125 } 126 127 //-------------------------------------------------------------------------- 128 // 129 // Constructor 130 // 131 //-------------------------------------------------------------------------- 132 133 /** 134 * Constructor. 135 * 136 * @param master The UIComponent instance that this AccImpl instance 137 * is making accessible. 138 */ 139 public function MenuBarAccImpl(master:UIComponent) 140 { 141 super(master); 142 143 role = 0x02; // ROLE_SYSTEM_MENUBAR 144 } 145 146 //-------------------------------------------------------------------------- 147 // 148 // Overridden properties: AccImpl 149 // 150 //-------------------------------------------------------------------------- 151 152 //---------------------------------- 153 // eventsToHandle 154 //---------------------------------- 155 156 /** 157 * @private 158 * Array of events that we should listen for from the master component. 159 */ 160 override protected function get eventsToHandle():Array 161 { 162 return super.eventsToHandle.concat( 163 [ "menuShow", "menuHide", "focusIn", "focusOut" ]); 164 } 165 166 //-------------------------------------------------------------------------- 167 // 168 // Overridden methods: AccessibilityImplementation 169 // 170 //-------------------------------------------------------------------------- 171 172 /** 173 * Gets the role for the component. 174 * 175 * @param childID uint 176 */ 177 override public function get_accRole(childID:uint):uint 178 { 179 return childID == 0 ? role : ROLE_SYSTEM_MENUITEM; 180 } 181 182 /** 183 * @private 184 * IAccessible method for returning the state of the MenuItem. 185 * States are predefined for all the components in MSAA. 186 * Values are assigned to each state. 187 * Depending upon the listItem being Selected, Selectable, 188 * Invisible, Offscreen, a value is returned. 189 * 190 * @param childID uint 191 * 192 * @return State uint 193 */ 194 override public function get_accState(childID:uint):uint 195 { 196 var accState:uint = getState(childID); 197 198 if (childID > 0) 199 { 200 var menuBar:MenuBar = MenuBar(master); 201 202 var index:int = childID - 1; 203 204 if (!menuBar.menuBarItems[index] || !menuBar.menuBarItems[index].enabled) 205 { 206 accState |= STATE_SYSTEM_UNAVAILABLE; 207 } 208 else 209 { 210 accState |= STATE_SYSTEM_SELECTABLE | STATE_SYSTEM_FOCUSABLE; 211 212 // if (menuBar.getMenuAt(index)) 213 accState |= STATE_SYSTEM_HASPOPUP; 214 215 if (index == menuBar.selectedIndex) 216 accState |= STATE_SYSTEM_HOTTRACKED | STATE_SYSTEM_FOCUSED; 217 } 218 } 219 return accState; 220 } 221 222 /** 223 * @private 224 * IAccessible method for returning the Default Action. 225 * 226 * @param childID uint 227 * 228 * @return name of default action. 229 */ 230 override public function get_accDefaultAction(childID:uint):String 231 { 232 if (childID == 0) 233 return null; 234 235 return childID - 1 == MenuBar(master).selectedIndex ? "Close" : "Open"; 236 } 237 238 /** 239 * @private 240 * IAccessible method for executing the Default Action. 241 * 242 * @param childID uint 243 */ 244 override public function accDoDefaultAction(childID:uint):void 245 { 246 if (childID > 0) 247 { 248 var index:int = childID - 1; 249 //MenuBar(master).selectedIndex = index; 250 //MenuBar(master).showMenu(index); 251 } 252 } 253 254 /** 255 * @private 256 * Method to return an array of childIDs. 257 * 258 * @return Array 259 */ 260 override public function getChildIDArray():Array 261 { 262 var n:int = MenuBar(master).menuBarItems ? 263 MenuBar(master).menuBarItems.length : 264 0; 265 266 return createChildIDArray(n); 267 } 268 269 /** 270 * @private 271 * IAccessible method for returning the bounding box of the MenuBarItem. 272 * 273 * @param childID uint 274 * 275 * @return Location Object 276 */ 277 override public function accLocation(childID:uint):* 278 { 279 //should check that this is returning the needed component 280 return MenuBar(master).menuBarItems[childID - 1]; 281 //return MenuBar(master).getMenuBarItemAt(childID - 1); 282 } 283 284 /** 285 * @private 286 * IAccessible method for returning the childFocus of the List. 287 * 288 * @param childID uint 289 * 290 * @return focused childID. 291 */ 292 override public function get_accFocus():uint 293 { 294 var index:int = MenuBar(master).selectedIndex; 295 296 return index >= 0 ? index + 1 : 0; 297 } 298 299 //-------------------------------------------------------------------------- 300 // 301 // Overridden methods: AccImpl 302 // 303 //-------------------------------------------------------------------------- 304 305 /** 306 * @private 307 * IAccessible method for returning the name of the MenuBar 308 * which is spoken out by the screen reader. 309 * The MenuItem should return the label as the name 310 * and MenuBar should return the name specified in the Accessibility Panel. 311 * 312 * @param childID uint 313 * 314 * @return Name String 315 */ 316 override protected function getName(childID:uint):String 317 { 318 if (childID == 0) 319 return ""; 320 321 var menuBar:MenuBar = MenuBar(master); 322 323 var index:int = childID - 1; 324 325 if (menuBar.menuBarItems && menuBar.menuBarItems.length > index) 326 { 327 if (menuBar.menuBarItems[index] && menuBar.menuBarItems[index].data) 328 return menuBar.itemToLabel(menuBar.menuBarItems[index].data); 329 } 330 331 return ""; 332 } 333 334 //-------------------------------------------------------------------------- 335 // 336 // Overridden event handlers: AccImpl 337 // 338 //-------------------------------------------------------------------------- 339 340 /** 341 * @private 342 * Override the generic event handler. 343 * All AccImpl must implement this 344 * to listen for events from its master component. 345 */ 346 override protected function eventHandler(event:Event):void 347 { 348 // Let AccImpl class handle the events 349 // that all accessible UIComponents understand. 350 $eventHandler(event); 351 352 switch (event.type) 353 { 354 case "menuShow": 355 { 356 var index:int = MenuBar(master).selectedIndex; 357 358 // since all the menu events are also received by Menubar. 359 if (index >= 0 && !MenuEvent(event).menu.parentMenu) 360 { 361 var childID:uint = index + 1; 362 363 Accessibility.sendEvent(master, childID, 364 EVENT_OBJECT_FOCUS); 365 366 Accessibility.sendEvent(master, childID, 367 EVENT_OBJECT_SELECTION); 368 } 369 370 break; 371 } 372 373 case "menuHide": 374 { 375 if (!MenuEvent(event).menu.parentMenu) 376 Accessibility.sendEvent(master, 0, EVENT_SYSTEM_MENUEND); 377 break; 378 } 379 380 case "focusIn": 381 { 382 Accessibility.sendEvent(master, 0, EVENT_SYSTEM_MENUSTART); 383 break; 384 } 385 386 case "focusOut": 387 { 388 if (MenuBar(master).selectedIndex == -1) 389 Accessibility.sendEvent(master, 0, EVENT_SYSTEM_MENUEND); 390 break; 391 } 392 } 393 } 394} 395 396} 397