PageRenderTime 60ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

/ActionScript Project/MusicPlayer for RealLife/src/flas/controls/List.as

http://abellee87.googlecode.com/
ActionScript | 790 lines | 335 code | 57 blank | 398 comment | 83 complexity | 3fa813c423cddf56d9b8f1a690e6de9a MD5 | raw file
  1. // Copyright 2007. Adobe Systems Incorporated. All Rights Reserved.
  2. package fl.controls {
  3. import fl.data.DataProvider;
  4. import fl.controls.listClasses.CellRenderer;
  5. import fl.controls.listClasses.ICellRenderer;
  6. import fl.controls.listClasses.ListData;
  7. import fl.controls.ScrollPolicy;
  8. import fl.controls.SelectableList;
  9. import fl.core.InvalidationType;
  10. import fl.core.UIComponent;
  11. import fl.events.DataChangeType;
  12. import fl.events.DataChangeEvent;
  13. import fl.events.ListEvent;
  14. import fl.events.ScrollEvent;
  15. import fl.managers.IFocusManagerComponent;
  16. import flash.display.DisplayObject;
  17. import flash.display.Sprite;
  18. import flash.events.Event;
  19. import flash.events.KeyboardEvent;
  20. import flash.events.MouseEvent;
  21. import flash.ui.Keyboard;
  22. import flash.utils.Dictionary;
  23. import flash.geom.Rectangle;
  24. /**
  25. * The List component displays list-based information and is ideally suited
  26. * for the display of arrays of information.
  27. *
  28. * <p>The List component consists of items, rows, and a data provider, which are
  29. * described as follows:</p>
  30. * <ul>
  31. * <li>Item: An ActionScript object that usually contains a descriptive <code>label</code>
  32. * property and a <code>data</code> property that stores the data associated with that item. </li>
  33. * <li>Row: A component that is used to display the item. </li>
  34. * <li>Data provider: A component that models the items that the List component displays.</li>
  35. * </ul>
  36. *
  37. * <p>By default, the List component uses the CellRenderer class to supply the rows in
  38. * which list items are displayed. You can create these rows programmatically; this
  39. * is usually done by subclassing the CellRenderer class. The CellRenderer class
  40. * implements the ICellRenderer interface, which provides the set of properties and
  41. * methods that the List component uses to manipulate its rows and to send data and state information
  42. * to each row for display. This includes information about data sizing and selection.</p>
  43. *
  44. * <p>The List component provides methods that act on its data provider--for example, the
  45. * <code>addItem()</code> and <code>removeItem()</code> methods. You can use these and
  46. * other methods to manipulate the data of any array that exists in the same frame as
  47. * a List component and then broadcast the changes to multiple views. If a List component
  48. * is not provided with an external data provider, these methods automatically create an
  49. * instance of a data provider and expose it through the <code>List.dataProvider</code>
  50. * property. The List component renders each row by using a Sprite that implements the
  51. * ICellRenderer interface. To specify this renderer, use the <code>List.cellRenderer</code>
  52. * property. You can also build an Array instance or get one from a server and use it as a
  53. * data model for multiple lists, combo boxes, data grids, and so on. </p>
  54. *
  55. * @includeExample examples/ListExample.as
  56. *
  57. * @langversion 3.0
  58. * @playerversion Flash 9.0.28.0
  59. *
  60. * @playerversion AIR 1.0
  61. * @productversion Flash CS3
  62. */
  63. public class List extends SelectableList implements IFocusManagerComponent{
  64. /**
  65. * @private
  66. *
  67. * @langversion 3.0
  68. * @playerversion Flash 9.0.28.0
  69. */
  70. protected var _rowHeight:Number = 20;
  71. /**
  72. * @private
  73. *
  74. * @langversion 3.0
  75. * @playerversion Flash 9.0.28.0
  76. */
  77. protected var _cellRenderer:Object;
  78. /**
  79. * @private
  80. *
  81. * @langversion 3.0
  82. * @playerversion Flash 9.0.28.0
  83. */
  84. protected var _labelField:String="label";
  85. /**
  86. * @private
  87. *
  88. * @langversion 3.0
  89. * @playerversion Flash 9.0.28.0
  90. */
  91. protected var _labelFunction:Function;
  92. /**
  93. * @private
  94. *
  95. * @langversion 3.0
  96. * @playerversion Flash 9.0.28.0
  97. */
  98. protected var _iconField:String = "icon";
  99. /**
  100. * @private
  101. *
  102. * @langversion 3.0
  103. * @playerversion Flash 9.0.28.0
  104. */
  105. protected var _iconFunction:Function;
  106. /**
  107. * @private
  108. *
  109. * @langversion 3.0
  110. * @playerversion Flash 9.0.28.0
  111. */
  112. private static var defaultStyles:Object = {
  113. focusRectSkin:null,
  114. focusRectPadding:null
  115. };
  116. /**
  117. * @copy fl.core.UIComponent#getStyleDefinition()
  118. *
  119. * @includeExample ../core/examples/UIComponent.getStyleDefinition.1.as -noswf
  120. *
  121. * @see fl.core.UIComponent#getStyle()
  122. * @see fl.core.UIComponent#setStyle()
  123. * @see fl.managers.StyleManager
  124. *
  125. * @langversion 3.0
  126. * @playerversion Flash 9.0.28.0
  127. *
  128. * @playerversion AIR 1.0
  129. * @productversion Flash CS3
  130. */
  131. public static function getStyleDefinition():Object {
  132. return mergeStyles(defaultStyles, SelectableList.getStyleDefinition());
  133. }
  134. /**
  135. * @private
  136. * Method for creating the Accessibility class.
  137. * This method is called from UIComponent.
  138. *
  139. * @langversion 3.0
  140. * @playerversion Flash 9.0.28.0
  141. */
  142. public static var createAccessibilityImplementation:Function;
  143. /**
  144. * Creates a new List component instance.
  145. *
  146. * @langversion 3.0
  147. * @playerversion Flash 9.0.28.0
  148. *
  149. * @playerversion AIR 1.0
  150. * @productversion Flash CS3
  151. */
  152. public function List() {
  153. super();
  154. }
  155. /**
  156. * Gets or sets the name of the field in the <code>dataProvider</code> object
  157. * to be displayed as the label for the TextInput field and drop-down list.
  158. *
  159. * <p>By default, the component displays the <code>label</code> property
  160. * of each <code>dataProvider</code> item. If the <code>dataProvider</code>
  161. * items do not contain a <code>label</code> property, you can set the
  162. * <code>labelField</code> property to use a different property.</p>
  163. *
  164. * <p><strong>Note:</strong> The <code>labelField</code> property is not used
  165. * if the <code>labelFunction</code> property is set to a callback function.</p>
  166. *
  167. * @default "label"
  168. *
  169. * @see #labelFunction
  170. *
  171. * @includeExample examples/List.labelField.1.as -noswf
  172. *
  173. * @langversion 3.0
  174. * @playerversion Flash 9.0.28.0
  175. *
  176. * @playerversion AIR 1.0
  177. * @productversion Flash CS3
  178. */
  179. public function get labelField():String {
  180. return _labelField;
  181. }
  182. /**
  183. * @private
  184. *
  185. * @langversion 3.0
  186. * @playerversion Flash 9.0.28.0
  187. */
  188. public function set labelField(value:String):void {
  189. if (value == _labelField) { return; }
  190. _labelField = value;
  191. invalidate(InvalidationType.DATA);
  192. }
  193. /**
  194. * Gets or sets the function to be used to obtain the label for the item.
  195. *
  196. * <p>By default, the component displays the <code>label</code> property
  197. * for a <code>dataProvider</code> item. But some data sets may not have
  198. * a <code>label</code> field or may not have a field whose value
  199. * can be used as a label without modification. For example, a given data
  200. * set might store full names but maintain them in <code>lastName</code> and
  201. * <code>firstName</code> fields. In such a case, this property could be
  202. * used to set a callback function that concatenates the values of the
  203. * <code>lastName</code> and <code>firstName</code> fields into a full
  204. * name string to be displayed.</p>
  205. *
  206. * <p><strong>Note:</strong> The <code>labelField</code> property is not used
  207. * if the <code>labelFunction</code> property is set to a callback function.</p>
  208. *
  209. * @default null
  210. *
  211. * @includeExample examples/List.labelFunction.1.as -noswf
  212. *
  213. * @langversion 3.0
  214. * @playerversion Flash 9.0.28.0
  215. *
  216. * @playerversion AIR 1.0
  217. * @productversion Flash CS3
  218. */
  219. public function get labelFunction():Function {
  220. return _labelFunction;
  221. }
  222. /**
  223. * @private
  224. *
  225. * @langversion 3.0
  226. * @playerversion Flash 9.0.28.0
  227. */
  228. public function set labelFunction(value:Function):void {
  229. if (_labelFunction == value) { return; }
  230. _labelFunction = value;
  231. invalidate(InvalidationType.DATA);
  232. }
  233. /**
  234. * Gets or sets the item field that provides the icon for the item.
  235. *
  236. * <p><strong>Note:</strong> The <code>iconField</code> is not used
  237. * if the <code>iconFunction</code> property is set to a callback function.</p>
  238. *
  239. * @default "icon"
  240. *
  241. * @includeExample examples/List.iconField.1.as -noswf
  242. *
  243. * @langversion 3.0
  244. * @playerversion Flash 9.0.28.0
  245. *
  246. * @playerversion AIR 1.0
  247. * @productversion Flash CS3
  248. */
  249. public function get iconField():String {
  250. return _iconField;
  251. }
  252. /**
  253. * @private
  254. *
  255. * @langversion 3.0
  256. * @playerversion Flash 9.0.28.0
  257. */
  258. public function set iconField(value:String):void {
  259. if (value == _iconField) { return; }
  260. _iconField = value;
  261. invalidate(InvalidationType.DATA);
  262. }
  263. /**
  264. * Gets or sets the function to be used to obtain the icon for the item.
  265. *
  266. * <p><strong>Note:</strong> The <code>iconField</code> is not used
  267. * if the <code>iconFunction</code> property is set to a callback function.</p>
  268. *
  269. * @default null
  270. *
  271. * @includeExample examples/List.iconFunction.1.as -noswf
  272. *
  273. * @langversion 3.0
  274. * @playerversion Flash 9.0.28.0
  275. *
  276. * @playerversion AIR 1.0
  277. * @productversion Flash CS3
  278. */
  279. public function get iconFunction():Function {
  280. return _iconFunction;
  281. }
  282. /**
  283. * @private
  284. *
  285. * @langversion 3.0
  286. * @playerversion Flash 9.0.28.0
  287. */
  288. public function set iconFunction(value:Function):void {
  289. if (_iconFunction == value) { return; }
  290. _iconFunction = value;
  291. invalidate(InvalidationType.DATA);
  292. }
  293. /**
  294. * Gets or sets the number of rows that are at least partially visible in the
  295. * list.
  296. *
  297. * @includeExample examples/SelectableList.rowCount.1.as -noswf
  298. * @includeExample examples/List.rowCount.2.as -noswf
  299. *
  300. * @langversion 3.0
  301. * @playerversion Flash 9.0.28.0
  302. *
  303. * @playerversion AIR 1.0
  304. * @productversion Flash CS3
  305. */
  306. override public function get rowCount():uint {
  307. //This is low right now (ie. doesn't count two half items as a whole):
  308. return Math.ceil(calculateAvailableHeight()/rowHeight);
  309. }
  310. /**
  311. * @private
  312. *
  313. * @langversion 3.0
  314. * @playerversion Flash 9.0.28.0
  315. */
  316. public function set rowCount(value:uint):void {
  317. var pad:Number = Number(getStyleValue("contentPadding"));
  318. var scrollBarHeight:Number = (_horizontalScrollPolicy == ScrollPolicy.ON || (_horizontalScrollPolicy == ScrollPolicy.AUTO && _maxHorizontalScrollPosition > 0)) ? 15 : 0;
  319. height = rowHeight*value+2*pad+scrollBarHeight;
  320. }
  321. /**
  322. * Gets or sets the height of each row in the list, in pixels.
  323. *
  324. * @default 20
  325. *
  326. * @langversion 3.0
  327. * @playerversion Flash 9.0.28.0
  328. *
  329. * @playerversion AIR 1.0
  330. * @productversion Flash CS3
  331. */
  332. public function get rowHeight():Number {
  333. return _rowHeight;
  334. }
  335. /**
  336. * @private
  337. *
  338. * @langversion 3.0
  339. * @playerversion Flash 9.0.28.0
  340. */
  341. public function set rowHeight(value:Number):void {
  342. _rowHeight = value;
  343. invalidate(InvalidationType.SIZE);
  344. }
  345. /**
  346. * @copy fl.controls.SelectableList#scrollToIndex()
  347. *
  348. * @langversion 3.0
  349. * @playerversion Flash 9.0.28.0
  350. *
  351. * @playerversion AIR 1.0
  352. * @productversion Flash CS3
  353. */
  354. override public function scrollToIndex(newCaretIndex:int):void {
  355. drawNow();
  356. var lastVisibleItemIndex:uint = Math.floor((_verticalScrollPosition + availableHeight) / rowHeight) - 1;
  357. var firstVisibleItemIndex:uint = Math.ceil(_verticalScrollPosition / rowHeight);
  358. if(newCaretIndex < firstVisibleItemIndex) {
  359. verticalScrollPosition = newCaretIndex * rowHeight;
  360. } else if(newCaretIndex > lastVisibleItemIndex) {
  361. verticalScrollPosition = (newCaretIndex + 1) * rowHeight - availableHeight;
  362. }
  363. }
  364. /**
  365. * @private (protected)
  366. *
  367. * @langversion 3.0
  368. * @playerversion Flash 9.0.28.0
  369. */
  370. override protected function configUI():void {
  371. useFixedHorizontalScrolling = true;
  372. _horizontalScrollPolicy = ScrollPolicy.AUTO;
  373. _verticalScrollPolicy = ScrollPolicy.AUTO;
  374. super.configUI();
  375. }
  376. /**
  377. * @private (protected)
  378. *
  379. * @langversion 3.0
  380. * @playerversion Flash 9.0.28.0
  381. */
  382. protected function calculateAvailableHeight():Number {
  383. var pad:Number = Number(getStyleValue("contentPadding"));
  384. return height-pad*2-((_horizontalScrollPolicy == ScrollPolicy.ON || (_horizontalScrollPolicy == ScrollPolicy.AUTO && _maxHorizontalScrollPosition > 0)) ? 15 : 0);
  385. }
  386. /**
  387. * @private (protected)
  388. *
  389. * @langversion 3.0
  390. * @playerversion Flash 9.0.28.0
  391. */
  392. override protected function setHorizontalScrollPosition(value:Number,fireEvent:Boolean=false):void {
  393. list.x = -value;
  394. super.setHorizontalScrollPosition(value, true);
  395. }
  396. /**
  397. * @private (protected)
  398. *
  399. * @langversion 3.0
  400. * @playerversion Flash 9.0.28.0
  401. */
  402. override protected function setVerticalScrollPosition(scroll:Number,fireEvent:Boolean=false):void {
  403. // This causes problems. It seems like the render event can get "blocked" if it's called from within a callLater
  404. invalidate(InvalidationType.SCROLL);
  405. super.setVerticalScrollPosition(scroll, true);
  406. }
  407. /**
  408. * @private (protected)
  409. *
  410. * @langversion 3.0
  411. * @playerversion Flash 9.0.28.0
  412. */
  413. override protected function draw():void {
  414. var contentHeightChanged:Boolean = (contentHeight != rowHeight*length);
  415. contentHeight = rowHeight*length;
  416. if (isInvalid(InvalidationType.STYLES)) {
  417. setStyles();
  418. drawBackground();
  419. // drawLayout is expensive, so only do it if padding has changed:
  420. if (contentPadding != getStyleValue("contentPadding")) {
  421. invalidate(InvalidationType.SIZE,false);
  422. }
  423. // redrawing all the cell renderers is even more expensive, so we really only want to do it if necessary:
  424. if (_cellRenderer != getStyleValue("cellRenderer")) {
  425. // remove all the existing renderers:
  426. _invalidateList();
  427. _cellRenderer = getStyleValue("cellRenderer");
  428. }
  429. }
  430. if (isInvalid(InvalidationType.SIZE, InvalidationType.STATE) || contentHeightChanged) {
  431. drawLayout();
  432. }
  433. if (isInvalid(InvalidationType.RENDERER_STYLES)) {
  434. updateRendererStyles();
  435. }
  436. if (isInvalid(InvalidationType.STYLES,InvalidationType.SIZE,InvalidationType.DATA,InvalidationType.SCROLL,InvalidationType.SELECTED)) {
  437. drawList();
  438. }
  439. // Call drawNow on nested components to get around problems with nested render events:
  440. updateChildren();
  441. // Not calling super.draw, because we're handling everything here. Instead we'll just call validate();
  442. validate();
  443. }
  444. /**
  445. * @private (protected)
  446. *
  447. * @langversion 3.0
  448. * @playerversion Flash 9.0.28.0
  449. */
  450. override protected function drawList():void {
  451. // List is very environmentally friendly, it reuses existing
  452. // renderers for old data, and recycles old renderers for new data.
  453. // set horizontal scroll:
  454. listHolder.x = listHolder.y = contentPadding;
  455. var rect:Rectangle = listHolder.scrollRect;
  456. rect.x = _horizontalScrollPosition;
  457. // set pixel scroll:
  458. rect.y = Math.floor(_verticalScrollPosition)%rowHeight;
  459. listHolder.scrollRect = rect;
  460. listHolder.cacheAsBitmap = useBitmapScrolling;
  461. // figure out what we have to render:
  462. var startIndex:uint = Math.floor(_verticalScrollPosition/rowHeight);
  463. var endIndex:uint = Math.min(length,startIndex + rowCount+1);
  464. // these vars get reused in different loops:
  465. var i:uint;
  466. var item:Object;
  467. var renderer:ICellRenderer;
  468. // create a dictionary for looking up the new "displayed" items:
  469. var itemHash:Dictionary = renderedItems = new Dictionary(true);
  470. for (i=startIndex; i<endIndex; i++) {
  471. itemHash[_dataProvider.getItemAt(i)] = true;
  472. }
  473. // find cell renderers that are still active, and make those that aren't active available:
  474. var itemToRendererHash:Dictionary = new Dictionary(true);
  475. while (activeCellRenderers.length > 0) {
  476. renderer = activeCellRenderers.pop() as ICellRenderer;
  477. item = renderer.data;
  478. if (itemHash[item] == null || invalidItems[item] == true) {
  479. availableCellRenderers.push(renderer);
  480. } else {
  481. itemToRendererHash[item] = renderer;
  482. // prevent problems with duplicate objects:
  483. invalidItems[item] = true;
  484. }
  485. list.removeChild(renderer as DisplayObject);
  486. }
  487. invalidItems = new Dictionary(true);
  488. // draw cell renderers:
  489. for (i=startIndex; i<endIndex; i++) {
  490. var reused:Boolean = false;
  491. item = _dataProvider.getItemAt(i);
  492. if (itemToRendererHash[item] != null) {
  493. // existing renderer for this item we can reuse:
  494. reused = true;
  495. renderer = itemToRendererHash[item];
  496. delete(itemToRendererHash[item]);
  497. } else if (availableCellRenderers.length > 0) {
  498. // recycle an old renderer:
  499. renderer = availableCellRenderers.pop() as ICellRenderer;
  500. } else {
  501. // out of renderers, create a new one:
  502. renderer = getDisplayObjectInstance(getStyleValue("cellRenderer")) as ICellRenderer;
  503. var rendererSprite:Sprite = renderer as Sprite;
  504. if (rendererSprite != null) {
  505. rendererSprite.addEventListener(MouseEvent.CLICK,handleCellRendererClick,false,0,true);
  506. rendererSprite.addEventListener(MouseEvent.ROLL_OVER,handleCellRendererMouseEvent,false,0,true);
  507. rendererSprite.addEventListener(MouseEvent.ROLL_OUT,handleCellRendererMouseEvent,false,0,true);
  508. rendererSprite.addEventListener(Event.CHANGE,handleCellRendererChange,false,0,true);
  509. rendererSprite.doubleClickEnabled = true;
  510. rendererSprite.addEventListener(MouseEvent.DOUBLE_CLICK,handleCellRendererDoubleClick,false,0,true);
  511. if (rendererSprite.hasOwnProperty("setStyle")) {
  512. for (var n:String in rendererStyles) {
  513. rendererSprite["setStyle"](n, rendererStyles[n])
  514. }
  515. }
  516. }
  517. }
  518. list.addChild(renderer as Sprite);
  519. activeCellRenderers.push(renderer);
  520. renderer.y = rowHeight*(i-startIndex);
  521. renderer.setSize(availableWidth+_maxHorizontalScrollPosition,rowHeight);
  522. var label:String = itemToLabel(item);
  523. var icon:Object = null;
  524. if (_iconFunction != null) {
  525. icon = _iconFunction(item);
  526. } else if (_iconField != null) {
  527. icon = item[_iconField];
  528. }
  529. if (!reused) {
  530. renderer.data = item;
  531. }
  532. renderer.listData = new ListData(label,icon,this,i,i,0);
  533. renderer.selected = (_selectedIndices.indexOf(i) != -1);
  534. // force an immediate draw (because render event will not be called on the renderer):
  535. if (renderer is UIComponent) {
  536. (renderer as UIComponent).drawNow();
  537. }
  538. }
  539. }
  540. /**
  541. * @private (protected)
  542. *
  543. * @langversion 3.0
  544. * @playerversion Flash 9.0.28.0
  545. */
  546. override protected function keyDownHandler(event:KeyboardEvent):void {
  547. if (!selectable) { return; }
  548. switch (event.keyCode) {
  549. case Keyboard.UP:
  550. case Keyboard.DOWN:
  551. case Keyboard.END:
  552. case Keyboard.HOME:
  553. case Keyboard.PAGE_UP:
  554. case Keyboard.PAGE_DOWN:
  555. moveSelectionVertically(event.keyCode, event.shiftKey && _allowMultipleSelection, event.ctrlKey && _allowMultipleSelection);
  556. break;
  557. case Keyboard.LEFT:
  558. case Keyboard.RIGHT:
  559. moveSelectionHorizontally(event.keyCode, event.shiftKey && _allowMultipleSelection, event.ctrlKey && _allowMultipleSelection);
  560. break;
  561. case Keyboard.SPACE:
  562. if(caretIndex == -1) {
  563. caretIndex = 0;
  564. }
  565. doKeySelection(caretIndex, event.shiftKey, event.ctrlKey);
  566. scrollToSelected();
  567. break;
  568. default:
  569. var nextIndex:int = getNextIndexAtLetter(String.fromCharCode(event.keyCode), selectedIndex);
  570. if (nextIndex > -1) {
  571. selectedIndex = nextIndex;
  572. scrollToSelected();
  573. }
  574. break;
  575. }
  576. event.stopPropagation();
  577. }
  578. /**
  579. * @private (protected)
  580. * Moves the selection in a horizontal direction in response
  581. * to the user selecting items using the left-arrow or right-arrow
  582. * keys and modifiers such as the Shift and Ctrl keys.
  583. *
  584. * <p>Not implemented in List because the default list
  585. * is single column and therefore doesn't scroll horizontally.</p>
  586. *
  587. * @param code The key that was pressed (e.g. Keyboard.LEFT)
  588. *
  589. * @param shiftKey <code>true</code> if the shift key was held down when
  590. * the keyboard key was pressed.
  591. *
  592. * @param ctrlKey <code>true</code> if the ctrl key was held down when
  593. * the keyboard key was pressed.
  594. *
  595. * @langversion 3.0
  596. * @playerversion Flash 9.0.28.0
  597. */
  598. override protected function moveSelectionHorizontally(code:uint, shiftKey:Boolean, ctrlKey:Boolean):void {}
  599. /**
  600. * @private (protected)
  601. * Moves the selection in a vertical direction in response
  602. * to the user selecting items using the up-arrow or down-arrow
  603. * Keys and modifiers such as the Shift and Ctrl keys.
  604. *
  605. * @param code The key that was pressed (e.g. Keyboard.DOWN)
  606. *
  607. * @param shiftKey <code>true</code> if the shift key was held down when
  608. * the keyboard key was pressed.
  609. *
  610. * @param ctrlKey <code>true</code> if the ctrl key was held down when
  611. * the keyboard key was pressed.
  612. *
  613. * @langversion 3.0
  614. * @playerversion Flash 9.0.28.0
  615. */
  616. override protected function moveSelectionVertically(code:uint, shiftKey:Boolean, ctrlKey:Boolean):void {
  617. var pageSize:int = Math.max(Math.floor(calculateAvailableHeight() / rowHeight), 1);
  618. var newCaretIndex:int = -1;
  619. var dir:int = 0;
  620. switch(code) {
  621. case Keyboard.UP:
  622. if (caretIndex > 0) {
  623. newCaretIndex = caretIndex - 1;
  624. }
  625. break;
  626. case Keyboard.DOWN:
  627. if (caretIndex < length - 1) {
  628. newCaretIndex = caretIndex + 1;
  629. }
  630. break;
  631. case Keyboard.PAGE_UP:
  632. if (caretIndex > 0) {
  633. newCaretIndex = Math.max(caretIndex - pageSize, 0);
  634. }
  635. break;
  636. case Keyboard.PAGE_DOWN:
  637. if (caretIndex < length - 1) {
  638. newCaretIndex = Math.min(caretIndex + pageSize, length - 1);
  639. }
  640. break;
  641. case Keyboard.HOME:
  642. if (caretIndex > 0) {
  643. newCaretIndex = 0;
  644. }
  645. break;
  646. case Keyboard.END:
  647. if (caretIndex < length - 1) {
  648. newCaretIndex = length - 1;
  649. }
  650. break;
  651. }
  652. if(newCaretIndex >= 0) {
  653. doKeySelection(newCaretIndex, shiftKey, ctrlKey);
  654. scrollToSelected();
  655. }
  656. }
  657. /**
  658. * @private (protected)
  659. *
  660. * @langversion 3.0
  661. * @playerversion Flash 9.0.28.0
  662. */
  663. protected function doKeySelection(newCaretIndex:int, shiftKey:Boolean, ctrlKey:Boolean):void {
  664. var selChanged:Boolean = false;
  665. if(shiftKey) {
  666. var i:int;
  667. var selIndices:Array = [];
  668. var startIndex:int = lastCaretIndex;
  669. var endIndex:int = newCaretIndex;
  670. if(startIndex == -1) {
  671. startIndex = caretIndex != -1 ? caretIndex : newCaretIndex;
  672. }
  673. if(startIndex > endIndex) {
  674. endIndex = startIndex;
  675. startIndex = newCaretIndex;
  676. }
  677. for(i = startIndex; i <= endIndex; i++) {
  678. selIndices.push(i);
  679. }
  680. selectedIndices = selIndices;
  681. caretIndex = newCaretIndex;
  682. selChanged = true;
  683. } else {
  684. selectedIndex = newCaretIndex;
  685. caretIndex = lastCaretIndex = newCaretIndex;
  686. selChanged = true;
  687. }
  688. if(selChanged) {
  689. dispatchEvent(new Event(Event.CHANGE));
  690. }
  691. invalidate(InvalidationType.DATA);
  692. }
  693. /**
  694. * Retrieves the string that the renderer displays for the given data object
  695. * based on the <code>labelField</code> and <code>labelFunction</code> properties.
  696. *
  697. * <p><strong>Note:</strong> The <code>labelField</code> is not used
  698. * if the <code>labelFunction</code> property is set to a callback function.</p>
  699. *
  700. * @param item The object to be rendered.
  701. *
  702. * @return The string to be displayed based on the data.
  703. *
  704. * @internal <code>var label:String = myList.itemToLabel(data);</code>
  705. *
  706. * @includeExample examples/List.itemToLabel.1.as -noswf
  707. *
  708. * @langversion 3.0
  709. * @playerversion Flash 9.0.28.0
  710. *
  711. * @playerversion AIR 1.0
  712. * @productversion Flash CS3
  713. */
  714. override public function itemToLabel(item:Object):String {
  715. if (_labelFunction != null) {
  716. return String(_labelFunction(item));
  717. } else {
  718. return (item[_labelField]!=null) ? String(item[_labelField]) : "";
  719. }
  720. }
  721. /**
  722. * @private (protected)
  723. *
  724. * @langversion 3.0
  725. * @playerversion Flash 9.0.28.0
  726. */
  727. override protected function initializeAccessibility():void {
  728. if (List.createAccessibilityImplementation != null) {
  729. List.createAccessibilityImplementation(this);
  730. }
  731. }
  732. }
  733. }