/dev/FLDev/lib/com/bit101/components/ComboBox.as

http://github.com/OpenRTMFP/ArcusNode · ActionScript · 461 lines · 275 code · 49 blank · 137 comment · 19 complexity · 985bd41aed6613b268f3aeb8e56d4cd6 MD5 · raw file

  1. /**
  2. * ComboBox.as
  3. * Keith Peters
  4. * version 0.9.10
  5. *
  6. * A button that exposes a list of choices and displays the chosen item.
  7. *
  8. * Copyright (c) 2011 Keith Peters
  9. *
  10. * Permission is hereby granted, free of charge, to any person obtaining a copy
  11. * of this software and associated documentation files (the "Software"), to deal
  12. * in the Software without restriction, including without limitation the rights
  13. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  14. * copies of the Software, and to permit persons to whom the Software is
  15. * furnished to do so, subject to the following conditions:
  16. *
  17. * The above copyright notice and this permission notice shall be included in
  18. * all copies or substantial portions of the Software.
  19. *
  20. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  21. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  22. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  23. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  24. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  25. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  26. * THE SOFTWARE.
  27. */
  28. package com.bit101.components
  29. {
  30. import flash.display.DisplayObjectContainer;
  31. import flash.display.Stage;
  32. import flash.events.Event;
  33. import flash.events.MouseEvent;
  34. import flash.geom.Point;
  35. import flash.geom.Rectangle;
  36. [Event(name="select", type="flash.events.Event")]
  37. public class ComboBox extends Component
  38. {
  39. public static const TOP:String = "top";
  40. public static const BOTTOM:String = "bottom";
  41. protected var _defaultLabel:String = "";
  42. protected var _dropDownButton:PushButton;
  43. protected var _items:Array;
  44. protected var _labelButton:PushButton;
  45. protected var _list:List;
  46. protected var _numVisibleItems:int = 6;
  47. protected var _open:Boolean = false;
  48. protected var _openPosition:String = BOTTOM;
  49. protected var _stage:Stage;
  50. /**
  51. * Constructor
  52. * @param parent The parent DisplayObjectContainer on which to add this List.
  53. * @param xpos The x position to place this component.
  54. * @param ypos The y position to place this component.
  55. * @param defaultLabel The label to show when no item is selected.
  56. * @param items An array of items to display in the list. Either strings or objects with label property.
  57. */
  58. public function ComboBox(parent:DisplayObjectContainer=null, xpos:Number=0, ypos:Number=0, defaultLabel:String="", items:Array = null)
  59. {
  60. _defaultLabel = defaultLabel;
  61. _items = items;
  62. addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
  63. addEventListener(Event.REMOVED_FROM_STAGE, onRemovedFromStage);
  64. super(parent, xpos, ypos);
  65. }
  66. /**
  67. * Initilizes the component.
  68. */
  69. protected override function init():void
  70. {
  71. super.init();
  72. setSize(100, 20);
  73. setLabelButtonLabel();
  74. }
  75. /**
  76. * Creates and adds the child display objects of this component.
  77. */
  78. protected override function addChildren():void
  79. {
  80. super.addChildren();
  81. _list = new List(null, 0, 0, _items);
  82. _list.autoHideScrollBar = true;
  83. _list.addEventListener(Event.SELECT, onSelect);
  84. _labelButton = new PushButton(this, 0, 0, "", onDropDown);
  85. _dropDownButton = new PushButton(this, 0, 0, "+", onDropDown);
  86. }
  87. /**
  88. * Determines what to use for the main button label and sets it.
  89. */
  90. protected function setLabelButtonLabel():void
  91. {
  92. if(selectedItem == null)
  93. {
  94. _labelButton.label = _defaultLabel;
  95. }
  96. else if(selectedItem is String)
  97. {
  98. _labelButton.label = selectedItem as String;
  99. }
  100. else if(selectedItem.hasOwnProperty("label") && selectedItem.label is String)
  101. {
  102. _labelButton.label = selectedItem.label;
  103. }
  104. else
  105. {
  106. _labelButton.label = selectedItem.toString();
  107. }
  108. }
  109. /**
  110. * Removes the list from the stage.
  111. */
  112. protected function removeList():void
  113. {
  114. if(_stage.contains(_list)) _stage.removeChild(_list);
  115. _stage.removeEventListener(MouseEvent.CLICK, onStageClick);
  116. _dropDownButton.label = "+";
  117. }
  118. ///////////////////////////////////
  119. // public methods
  120. ///////////////////////////////////
  121. public override function draw():void
  122. {
  123. super.draw();
  124. _labelButton.setSize(_width - _height + 1, _height);
  125. _labelButton.draw();
  126. _dropDownButton.setSize(_height, _height);
  127. _dropDownButton.draw();
  128. _dropDownButton.x = _width - height;
  129. _list.setSize(_width, _numVisibleItems * _list.listItemHeight);
  130. }
  131. /**
  132. * Adds an item to the list.
  133. * @param item The item to add. Can be a string or an object containing a string property named label.
  134. */
  135. public function addItem(item:Object):void
  136. {
  137. _list.addItem(item);
  138. }
  139. /**
  140. * Adds an item to the list at the specified index.
  141. * @param item The item to add. Can be a string or an object containing a string property named label.
  142. * @param index The index at which to add the item.
  143. */
  144. public function addItemAt(item:Object, index:int):void
  145. {
  146. _list.addItemAt(item, index);
  147. }
  148. /**
  149. * Removes the referenced item from the list.
  150. * @param item The item to remove. If a string, must match the item containing that string. If an object, must be a reference to the exact same object.
  151. */
  152. public function removeItem(item:Object):void
  153. {
  154. _list.removeItem(item);
  155. }
  156. /**
  157. * Removes the item from the list at the specified index
  158. * @param index The index of the item to remove.
  159. */
  160. public function removeItemAt(index:int):void
  161. {
  162. _list.removeItemAt(index);
  163. }
  164. /**
  165. * Removes all items from the list.
  166. */
  167. public function removeAll():void
  168. {
  169. _list.removeAll();
  170. }
  171. ///////////////////////////////////
  172. // event handlers
  173. ///////////////////////////////////
  174. /**
  175. * Called when one of the top buttons is pressed. Either opens or closes the list.
  176. */
  177. protected function onDropDown(event:MouseEvent):void
  178. {
  179. _open = !_open;
  180. if(_open)
  181. {
  182. var point:Point = new Point();
  183. if(_openPosition == BOTTOM)
  184. {
  185. point.y = _height;
  186. }
  187. else
  188. {
  189. point.y = -_numVisibleItems * _list.listItemHeight;
  190. }
  191. point = this.localToGlobal(point);
  192. _list.move(point.x, point.y);
  193. _stage.addChild(_list);
  194. _stage.addEventListener(MouseEvent.CLICK, onStageClick);
  195. _dropDownButton.label = "-";
  196. }
  197. else
  198. {
  199. removeList();
  200. }
  201. }
  202. /**
  203. * Called when the mouse is clicked somewhere outside of the combo box when the list is open. Closes the list.
  204. */
  205. protected function onStageClick(event:MouseEvent):void
  206. {
  207. // ignore clicks within buttons or list
  208. if(event.target == _dropDownButton || event.target == _labelButton) return;
  209. if(new Rectangle(_list.x, _list.y, _list.width, _list.height).contains(event.stageX, event.stageY)) return;
  210. _open = false;
  211. removeList();
  212. }
  213. /**
  214. * Called when an item in the list is selected. Displays that item in the label button.
  215. */
  216. protected function onSelect(event:Event):void
  217. {
  218. _open = false;
  219. _dropDownButton.label = "+";
  220. if(stage != null && stage.contains(_list))
  221. {
  222. stage.removeChild(_list);
  223. }
  224. setLabelButtonLabel();
  225. dispatchEvent(event);
  226. }
  227. /**
  228. * Called when the component is added to the stage.
  229. */
  230. protected function onAddedToStage(event:Event):void
  231. {
  232. _stage = stage;
  233. }
  234. /**
  235. * Called when the component is removed from the stage.
  236. */
  237. protected function onRemovedFromStage(event:Event):void
  238. {
  239. removeList();
  240. }
  241. ///////////////////////////////////
  242. // getter/setters
  243. ///////////////////////////////////
  244. /**
  245. * Sets / gets the index of the selected list item.
  246. */
  247. public function set selectedIndex(value:int):void
  248. {
  249. _list.selectedIndex = value;
  250. setLabelButtonLabel();
  251. }
  252. public function get selectedIndex():int
  253. {
  254. return _list.selectedIndex;
  255. }
  256. /**
  257. * Sets / gets the item in the list, if it exists.
  258. */
  259. public function set selectedItem(item:Object):void
  260. {
  261. _list.selectedItem = item;
  262. setLabelButtonLabel();
  263. }
  264. public function get selectedItem():Object
  265. {
  266. return _list.selectedItem;
  267. }
  268. /**
  269. * Sets/gets the default background color of list items.
  270. */
  271. public function set defaultColor(value:uint):void
  272. {
  273. _list.defaultColor = value;
  274. }
  275. public function get defaultColor():uint
  276. {
  277. return _list.defaultColor;
  278. }
  279. /**
  280. * Sets/gets the selected background color of list items.
  281. */
  282. public function set selectedColor(value:uint):void
  283. {
  284. _list.selectedColor = value;
  285. }
  286. public function get selectedColor():uint
  287. {
  288. return _list.selectedColor;
  289. }
  290. /**
  291. * Sets/gets the rollover background color of list items.
  292. */
  293. public function set rolloverColor(value:uint):void
  294. {
  295. _list.rolloverColor = value;
  296. }
  297. public function get rolloverColor():uint
  298. {
  299. return _list.rolloverColor;
  300. }
  301. /**
  302. * Sets the height of each list item.
  303. */
  304. public function set listItemHeight(value:Number):void
  305. {
  306. _list.listItemHeight = value;
  307. invalidate();
  308. }
  309. public function get listItemHeight():Number
  310. {
  311. return _list.listItemHeight;
  312. }
  313. /**
  314. * Sets / gets the position the list will open on: top or bottom.
  315. */
  316. public function set openPosition(value:String):void
  317. {
  318. _openPosition = value;
  319. }
  320. public function get openPosition():String
  321. {
  322. return _openPosition;
  323. }
  324. /**
  325. * Sets / gets the label that will be shown if no item is selected.
  326. */
  327. public function set defaultLabel(value:String):void
  328. {
  329. _defaultLabel = value;
  330. setLabelButtonLabel();
  331. }
  332. public function get defaultLabel():String
  333. {
  334. return _defaultLabel;
  335. }
  336. /**
  337. * Sets / gets the number of visible items in the drop down list. i.e. the height of the list.
  338. */
  339. public function set numVisibleItems(value:int):void
  340. {
  341. _numVisibleItems = value;
  342. invalidate();
  343. }
  344. public function get numVisibleItems():int
  345. {
  346. return _numVisibleItems;
  347. }
  348. /**
  349. * Sets / gets the list of items to be shown.
  350. */
  351. public function set items(value:Array):void
  352. {
  353. _list.items = value;
  354. }
  355. public function get items():Array
  356. {
  357. return _list.items;
  358. }
  359. /**
  360. * Sets / gets the class used to render list items. Must extend ListItem.
  361. */
  362. public function set listItemClass(value:Class):void
  363. {
  364. _list.listItemClass = value;
  365. }
  366. public function get listItemClass():Class
  367. {
  368. return _list.listItemClass;
  369. }
  370. /**
  371. * Sets / gets the color for alternate rows if alternateRows is set to true.
  372. */
  373. public function set alternateColor(value:uint):void
  374. {
  375. _list.alternateColor = value;
  376. }
  377. public function get alternateColor():uint
  378. {
  379. return _list.alternateColor;
  380. }
  381. /**
  382. * Sets / gets whether or not every other row will be colored with the alternate color.
  383. */
  384. public function set alternateRows(value:Boolean):void
  385. {
  386. _list.alternateRows = value;
  387. }
  388. public function get alternateRows():Boolean
  389. {
  390. return _list.alternateRows;
  391. }
  392. /**
  393. * Sets / gets whether the scrollbar will auto hide when there is nothing to scroll.
  394. */
  395. public function set autoHideScrollBar(value:Boolean):void
  396. {
  397. _list.autoHideScrollBar = value;
  398. invalidate();
  399. }
  400. public function get autoHideScrollBar():Boolean
  401. {
  402. return _list.autoHideScrollBar;
  403. }
  404. /**
  405. * Gets whether or not the combo box is currently open.
  406. */
  407. public function get isOpen():Boolean
  408. {
  409. return _open;
  410. }
  411. }
  412. }