PageRenderTime 84ms CodeModel.GetById 8ms RepoModel.GetById 0ms app.codeStats 0ms

/lg/flex/elements/Element.as

https://github.com/nitrog7/LiquidGear
ActionScript | 1133 lines | 631 code | 144 blank | 358 comment | 90 complexity | 20313981450feb6615aef63673afc86b MD5 | raw file
  1. /**
  2. * Element Class by Giraldo Rosales.
  3. * Visit www.liquidgear.net for documentation and updates.
  4. *
  5. *
  6. * Copyright (c) 2010 Nitrogen Labs, Inc. All rights reserved.
  7. *
  8. * Permission is hereby granted, free of charge, to any person
  9. * obtaining a copy of this software and associated documentation
  10. * files (the "Software"), to deal in the Software without
  11. * restriction, including without limitation the rights to use,
  12. * copy, modify, merge, publish, distribute, sublicense, and/or sell
  13. * copies of the Software, and to permit persons to whom the
  14. * Software is furnished to do so, subject to the following
  15. * conditions:
  16. *
  17. * The above copyright notice and this permission notice shall be
  18. * included in all copies or substantial portions of the Software.
  19. *
  20. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  21. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  22. * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  23. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  24. * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  25. * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  26. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  27. * OTHER DEALINGS IN THE SOFTWARE.
  28. **/
  29. package lg.flex.elements {
  30. //Flash Classes
  31. import flash.display.DisplayObject;
  32. import flash.display.DisplayObjectContainer;
  33. import flash.display.Sprite;
  34. import flash.events.Event;
  35. import flash.events.FocusEvent;
  36. import flash.events.IOErrorEvent;
  37. import flash.events.KeyboardEvent;
  38. import flash.events.MouseEvent;
  39. import flash.events.ProgressEvent;
  40. import flash.events.TimerEvent;
  41. import flash.geom.Point;
  42. import flash.system.Capabilities;
  43. import flash.utils.Timer;
  44. import lg.flash.events.ElementEvent;
  45. import mx.core.IVisualElement;
  46. import spark.core.SpriteVisualElement;
  47. /**
  48. * Dispatched when the element has been initialized.
  49. * @eventType mx.events.ElementEvent.INIT
  50. */
  51. [Event(name="element_init", type="lg.flash.events.ElementEvent")]
  52. /**
  53. * Dispatched when the element has gained focus.
  54. * @eventType mx.events.ElementEvent.FOCUS
  55. */
  56. [Event(name="element_focus", type="lg.flash.events.ElementEvent")]
  57. /**
  58. * Dispatched when the element has lost focus.
  59. * @eventType mx.events.ElementEvent.UNFOCUS
  60. */
  61. [Event(name="element_unfocus", type="lg.flash.events.ElementEvent")]
  62. /**
  63. * Dispatched when the element has changed.
  64. * @eventType mx.events.ElementEvent.CHANGE
  65. */
  66. [Event(name="element_change", type="lg.flash.events.ElementEvent")]
  67. /**
  68. * Dispatched when the element has been clicked.
  69. * @eventType mx.events.ElementEvent.CLICK
  70. */
  71. [Event(name="element_click", type="lg.flash.events.ElementEvent")]
  72. /**
  73. * Dispatched when the element has been double clicked.
  74. * @eventType mx.events.ElementEvent.DBLCLICK
  75. */
  76. [Event(name="element_dblclick", type="lg.flash.events.ElementEvent")]
  77. /**
  78. * Dispatched when a key has been pressed down.
  79. * @eventType mx.events.ElementEvent.KEYDOWN
  80. */
  81. [Event(name="element_keydown", type="lg.flash.events.ElementEvent")]
  82. /**
  83. * Dispatched when the a key has been released.
  84. * @eventType mx.events.ElementEvent.KEYUP
  85. */
  86. [Event(name="element_keyup", type="lg.flash.events.ElementEvent")]
  87. /**
  88. * Dispatched when the element has been added to the parent.
  89. * @eventType mx.events.ElementEvent.ADD
  90. */
  91. [Event(name="element_add", type="lg.flash.events.ElementEvent")]
  92. /**
  93. * Dispatched when the element has been fully loaded.
  94. * @eventType mx.events.ElementEvent.LOADED
  95. */
  96. [Event(name="element_loaded", type="lg.flash.events.ElementEvent")]
  97. /**
  98. * Dispatched when the mouse has been pressed down.
  99. * @eventType mx.events.ElementEvent.MOUSEDOWN
  100. */
  101. [Event(name="element_mousedown", type="lg.flash.events.ElementEvent")]
  102. /**
  103. * Dispatched while the mouse is moving over the element.
  104. * @eventType mx.events.ElementEvent.MOUSEMOVE
  105. */
  106. [Event(name="element_mousemove", type="lg.flash.events.ElementEvent")]
  107. /**
  108. * Dispatched when the mouse moves out of the element.
  109. * @eventType mx.events.ElementEvent.MOUSEOUT
  110. */
  111. [Event(name="element_mouseout", type="lg.flash.events.ElementEvent")]
  112. /**
  113. * Dispatched when the mouse moves over the element.
  114. * @eventType mx.events.ElementEvent.MOUSEOVER
  115. */
  116. [Event(name="element_mouseover", type="lg.flash.events.ElementEvent")]
  117. /**
  118. * Dispatched when the mouse is released over the element.
  119. * @eventType mx.events.ElementEvent.MOUSEUP
  120. */
  121. [Event(name="element_mouseup", type="lg.flash.events.ElementEvent")]
  122. /**
  123. * Dispatched when the element is resized.
  124. * @eventType mx.events.ElementEvent.RESIZE
  125. */
  126. [Event(name="element_resize", type="lg.flash.events.ElementEvent")]
  127. /**
  128. * Dispatched when the element has been uploaded.
  129. * @eventType mx.events.ElementEvent.UNLOAD
  130. */
  131. [Event(name="element_unload", type="lg.flash.events.ElementEvent")]
  132. /**
  133. * Dispatched when an error occurs.
  134. * @eventType mx.events.ElementEvent.ERROR
  135. */
  136. [Event(name="element_error", type="lg.flash.events.ElementEvent")]
  137. /**
  138. * Dispatched when a security or permissions error occurs.
  139. * @eventType mx.events.ElementEvent.SECURITYERROR
  140. */
  141. [Event(name="element_security_error", type="lg.flash.events.ElementEvent")]
  142. /**
  143. * Dispatched when a security or permissions error occurs.
  144. * @eventType mx.events.ElementEvent.IOERROR
  145. */
  146. [Event(name="element_io_error", type="lg.flash.events.ElementEvent")]
  147. /**
  148. * Dispatched while an element is loading.
  149. * @eventType mx.events.ElementEvent.PROGRESS
  150. */
  151. [Event(name="element_progress", type="lg.flash.events.ElementEvent")]
  152. /**
  153. * <p>The Element class is the foundation of LiquidGear. It contains the
  154. * basic events and attributes used. Most attributes are similar to that of
  155. * an HTML element.</p>
  156. * <p>If the object you are using is visible (such as an images, text, shapes,
  157. * or SWF objects), you should use the VisualElement class which is an
  158. * extension of the Element class. Element is best used for sounds
  159. * and other simple items without visual effects.</p>
  160. *
  161. **/
  162. public class Element extends SpriteVisualElement {
  163. /** Title. **/
  164. public var title:String = '';
  165. //public var lang:String = '';
  166. //public var dir:String = '';
  167. //public var className:String = '';
  168. //public var draggable:Boolean = false;
  169. //public var contentEditable:String = '';
  170. /** Base path for use with any external content. Will be used as a prefix
  171. * for any external files loaded into an element. **/
  172. public var basePath:String = '';
  173. /** Allows you to associate arbitrary data with the element. **/
  174. public var data:Object = {};
  175. /** Contains the child elements in an array. **/
  176. public var children:Vector.<DisplayObject> = new Vector.<DisplayObject>();
  177. /** Contains the child elements in an object with the id as the key. **/
  178. public var elements:Object = {};
  179. /** Indicates whether element has been toggled. **/
  180. public var toggled:Boolean = false;
  181. /** Indicates whether element will bubble events. **/
  182. public var bubble:Boolean = false;
  183. /** Indicates whether element will be automatically added to a page. **/
  184. public var addToPage:Boolean = true;
  185. /** Debugger. Use console.on() to turn on the debugger, console.off() to turn it off.
  186. * Once on, you can use trace commands to the <a href="http://demonsterdebugger.com/">De Monster Debugger</a> client with
  187. * the commands, console.log(), console.warn(), and console.error(). **/
  188. public static var debug:Boolean = false;
  189. /** @private **/
  190. private var toggleFunctions:Vector.<Function> = new Vector.<Function>(2, true);
  191. /** @private **/
  192. private var _listeners:Vector.<Object> = new Vector.<Object>();
  193. /** @private **/
  194. private var _lmLoaded:Vector.<String> = new Vector.<String>();
  195. /** @private **/
  196. private var _lmTotal:Vector.<String> = new Vector.<String>();
  197. /** Constructs a new Element object **/
  198. public function Element() {
  199. mouseEnabled = false;
  200. mouseChildren = false;
  201. data.id = name;
  202. data._isLoaded = false;
  203. data.stretch = true;
  204. switch(Capabilities.playerType) {
  205. case 'External':
  206. case 'StandAlone':
  207. data._development = true;
  208. break;
  209. default :
  210. data._development = false;
  211. break;
  212. }
  213. }
  214. /** @private **/
  215. protected function setAttributes(obj:Object, ignore:Array=null):void {
  216. if(!obj) {
  217. return;
  218. }
  219. if(obj.id) {
  220. id = obj.id;
  221. }
  222. for(var s:String in obj) {
  223. data[s] = obj[s];
  224. if(ignore) {
  225. if(ignore.indexOf(s) >= 0) {
  226. continue;
  227. }
  228. }
  229. if(s in this) {
  230. if(obj[s] == 'true') {
  231. obj[s] = true;
  232. }
  233. if(obj[s] == 'false') {
  234. obj[s] = false;
  235. }
  236. this[s] = obj[s];
  237. }
  238. }
  239. }
  240. /** Is set to true when an element is loaded **/
  241. public function get isLoaded():Boolean {
  242. return data._isLoaded;
  243. }
  244. /** Is running in the debug mode. True if run in the Flash Player, false if run in the browser. **/
  245. public function get isDevelopment():Boolean {
  246. return data._development;
  247. }
  248. /** Sets the attributes on the element if either an object with key/value
  249. * sets are included or a key as the first parameter and a value as the
  250. * second parameter. Will return the value of an attribute if only a string
  251. * is sent for the first parameter.
  252. *
  253. * @param params Can be a string or an object with key/value sets.
  254. * @return If a string is used without a second parameter, the method will
  255. * return the value specified in the element. Otherwise a string with a second
  256. * parameter value or an object with key/value pairs will set the specified
  257. * attributes and return the element.
  258. * @param value The value to set the attribute specified in the first
  259. * parameter. **/
  260. public function css(params:*=null, value:String=null):* {
  261. if(params is String) {
  262. if(value) {
  263. this[params] = value;
  264. return this;
  265. } else {
  266. return data[params];
  267. }
  268. }
  269. else if(params is Object) {
  270. for(var s:String in params) {
  271. this[s] = params[s];
  272. }
  273. return this;
  274. } else {
  275. return null;
  276. }
  277. }
  278. /** Adds a child object to the element as well as to the elements property.
  279. *
  280. * @param element A DisplayObject to add as a child element. **/
  281. public override function addChild(element:DisplayObject):DisplayObject {
  282. if(!element) {
  283. return null;
  284. }
  285. var elName:String = element.name;
  286. elements[elName] = element;
  287. var childLen:int = children.length;
  288. children[childLen] = element;
  289. super.addChild(element);
  290. return element;
  291. }
  292. /** Similar to addChild excepts keeps track of elements loaded. When all child elements added with
  293. * addExternal are loaded, the element dispatches an ElementEvent.LOADED event.
  294. *
  295. * @param element An external Element to add. Will fire an Element.LOADED call when all elements are loaded. **/
  296. public function addExternal(element:Element):Element {
  297. if(!element) {
  298. return null;
  299. }
  300. var elName:String = element.name;
  301. elements[elName] = element;
  302. element.loaded(onLoadElement);
  303. var childLen:int = children.length;
  304. children[childLen] = element;
  305. var loadedLen:int = _lmTotal.length;
  306. _lmTotal[loadedLen] = element.id;
  307. super.addChild(element);
  308. return element;
  309. }
  310. /** References the Parent. Can add the parent if element has not yet been added. **/
  311. /*
  312. public function set parent(container:sprite):void {
  313. data.parent = container;
  314. }
  315. public override function get parent():DisplayObjectContainer {
  316. var container:DisplayObjectContainer;
  317. if(super.parent) {
  318. return super.parent;
  319. } else {
  320. return data.parent;
  321. }
  322. }
  323. */
  324. /** @private **/
  325. private function onLoadElement(e:ElementEvent):void {
  326. if(bubble || e.eventPhase == 2) {
  327. var element:Element = e.target as Element;
  328. element.unbind('element_loaded', onLoadElement);
  329. var loadedLen:int = _lmLoaded.length;
  330. _lmLoaded[loadedLen] = element.id;
  331. var percent:int = (_lmLoaded.length > 0) ? (_lmLoaded.length / _lmTotal.length) * 100 : 0;
  332. if(percent >= 100) {
  333. data._isLoaded = true;
  334. trigger('element_loaded');
  335. }
  336. }
  337. }
  338. /** Removes a child object from the element.
  339. *
  340. * @param element A DisplayObject to add as a child element. **/
  341. public override function removeChild(element:DisplayObject):DisplayObject {
  342. if(element) {
  343. var elName:String = element.name;
  344. var childLen:int = children.length;
  345. for(var g:int=0; g<childLen; g++) {
  346. if(children[g] == elements[elName]) {
  347. children.splice(g, 1);
  348. break;
  349. }
  350. }
  351. elements[elName] = null;
  352. //if(element is Element) {
  353. // var lgElement:Element = element as Element;
  354. // lgElement.kill();
  355. //}
  356. super.removeChild(element);
  357. }
  358. return element;
  359. }
  360. /** Shortcut for a weak reference addEventListener call. Binds the type
  361. * of event with the function. Also adds the listener to the event
  362. * manager. If the double click event is used, it will automatically
  363. * set the doubleClickEnabled property to true.
  364. *
  365. * @param type The type of event to bind.
  366. * @param fn The function to call once the event is triggered. **/
  367. public function bind(type:String, fn:Function, capture:Boolean=false):Element {
  368. addEventListener(type, fn, capture);
  369. return this;
  370. }
  371. /** Shortcut to dispatch an event. If any variables are to be sent with
  372. * the event, you can pass them within an Object in the second parameter.
  373. * This way you can pull the data from the listener function. You can also
  374. * use the params attribute on the event to grab any of the element
  375. * variables stored in the data attribute.
  376. *
  377. * @param type Type of event to dispatch.
  378. * @param args Additional data to send with the event.
  379. * @param event Event data. **/
  380. public function trigger(type:String, args:Object=null, event:Object=null):Element {
  381. var e:ElementEvent = new ElementEvent(type);
  382. e.params = data;
  383. e.data = args;
  384. e.event = event;
  385. if(bubble || e.eventPhase == 2) {
  386. dispatchEvent(e);
  387. }
  388. //Clean
  389. e = null;
  390. return this;
  391. }
  392. /**@private **/
  393. override public function dispatchEvent(e:Event):Boolean {
  394. if (bubble || (hasEventListener(e.type) || e.bubbles)) {
  395. return super.dispatchEvent(e);
  396. }
  397. return true;
  398. }
  399. /** Shortcut for the removeEventListener method. The advantage of unbind
  400. * is the use of the event manager. You can remove all listeners of one
  401. * type with a single call by not specifying a listener.
  402. *
  403. * @param type Type of event to remove.
  404. * @param fn The function in the listener event to remove.**/
  405. public function unbind(type:String, fn:Function=null):Element {
  406. //var listenArray:Array = _listeners[type];
  407. var lisLen:int = _listeners.length;
  408. if(!lisLen) {
  409. return this;
  410. }
  411. if(fn != null) {
  412. //remove a specific listener
  413. removeEventListener(type, fn);
  414. } else {
  415. //else remove all listeners for that type
  416. var lisObj:Object;
  417. for(var g:int=0; g<lisLen; g++) {
  418. lisObj = _listeners[g];
  419. removeEventListener(lisObj.type, lisObj.fn);
  420. }
  421. }
  422. return this;
  423. }
  424. //public function live(type:String, fn:Function):Element {
  425. // return this;
  426. //}
  427. //public function die(type:String, fn:Function):Element {
  428. // return this;
  429. //}
  430. /** Adds two listeners to the element. The first is a mouseover event and
  431. * the second is a mouseout event.
  432. *
  433. * @param over The function to call when the mouse is over the element.
  434. * @param out The function call when the mouse has moved out of the
  435. * element.**/
  436. public function hover(over:Function, out:Function):Element {
  437. mouseover(over);
  438. mouseout(out);
  439. return this;
  440. }
  441. /** Adds two alternating events to the element. Toggle between the events
  442. * with every other click. Use <code>unbind('click')</code> to remove the
  443. * toggle event.
  444. *
  445. * @param fn Click function.
  446. * @param fn2 Click function.**/
  447. public function toggle(fn:Function=null, fn2:Function=null):Element {
  448. toggleFunctions = new Vector.<Function>(2, true);
  449. toggleFunctions[0] = fn;
  450. toggleFunctions[1] = fn2;
  451. click(onToggleOn);
  452. return this;
  453. }
  454. /** @private **/
  455. private function onToggleOn(e:ElementEvent):void {
  456. unbind('element_click', onToggleOn);
  457. unbind('element_click', onToggleOff);
  458. click(onToggleOff);
  459. var fn:Function = toggleFunctions[0];
  460. toggled = true;
  461. fn(e);
  462. }
  463. /** @private **/
  464. private function onToggleOff(e:ElementEvent):void {
  465. unbind('element_click', onToggleOn);
  466. unbind('element_click', onToggleOff);
  467. click(onToggleOn);
  468. var fn:Function = toggleFunctions[1];
  469. toggled = false;
  470. fn(e);
  471. }
  472. /** Triggers the textField blur event. If a function is specified, the blur
  473. * listener is, instead, added.
  474. *
  475. * @param fn Function to call when triggered.**/
  476. public function unfocus(fn:Function=null):Element {
  477. if(fn != null) {
  478. bind('element_unfocus', fn);
  479. } else {
  480. trigger('element_unfocus');
  481. }
  482. return this;
  483. }
  484. /** Triggers the change event. If a function is specified, the change
  485. * listener is, instead, added.
  486. *
  487. * @param fn Function to call when triggered.**/
  488. public function change(fn:Function=null):Element {
  489. if(fn != null) {
  490. bind('element_change', fn);
  491. } else {
  492. trigger('element_change');
  493. }
  494. return this;
  495. }
  496. /** Triggers the click event. If a function is specified, the click
  497. * listener is, instead, added.
  498. *
  499. * @param fn Function to call when triggered.**/
  500. public function click(fn:Function=null):Element {
  501. if(fn != null) {
  502. bind('element_click', fn);
  503. } else {
  504. trigger('element_click');
  505. }
  506. return this;
  507. }
  508. /** Triggers the double click event. If a function is specified, the double
  509. * click listener is, instead, added.
  510. *
  511. * @param fn Function to call when triggered.**/
  512. public function dblclick(fn:Function=null):Element {
  513. if(fn != null) {
  514. bind('element_dblclick', fn);
  515. } else {
  516. trigger('element_dblclick');
  517. }
  518. return this;
  519. }
  520. /** Triggers the error event. If a function is specified, the error
  521. * listener is, instead, added.
  522. *
  523. * @param fn Function to call when triggered.**/
  524. public function error(fn:Function=null):Element {
  525. if(fn != null) {
  526. bind('element_error', fn);
  527. } else {
  528. trigger('element_error');
  529. }
  530. return this;
  531. }
  532. /** Triggers the textField focus event. If a function is specified, the focus
  533. * listener is, instead, added.
  534. *
  535. * @param fn Function to call when triggered.**/
  536. public function focus(fn:Function=null):Element {
  537. if(fn != null) {
  538. bind('element_focus', fn);
  539. } else {
  540. trigger('element_focus');
  541. }
  542. return this;
  543. }
  544. /** Triggers the keydown event. If a function is specified, the keydown
  545. * listener is, instead, added.
  546. *
  547. * @param fn Function to call when triggered.**/
  548. public function keydown(fn:Function=null):Element {
  549. if(fn != null) {
  550. bind('element_keydown', fn);
  551. } else {
  552. trigger('element_keydown');
  553. }
  554. return this;
  555. }
  556. /** Triggers the keypress event. If a function is specified, the keypress
  557. * listener is, instead, added.
  558. *
  559. * @param fn Function to call when triggered.**/
  560. public function keypress(fn:Function=null):Element {
  561. if(fn != null) {
  562. bind('element_keypress', fn);
  563. } else {
  564. trigger('element_keypress');
  565. }
  566. return this;
  567. }
  568. /** Triggers the keyup event. If a function is specified, the keyup
  569. * listener is, instead, added.
  570. *
  571. * @param fn Function to call when triggered.**/
  572. public function keyup(fn:Function=null):Element {
  573. if(fn != null) {
  574. bind('element_keyup', fn);
  575. } else {
  576. trigger('element_keyup');
  577. }
  578. return this;
  579. }
  580. /** Binds a function to the loaded event.
  581. *
  582. * @param fn Function to call when triggered.**/
  583. public function loaded(fn:Function):Element {
  584. bind('element_loaded', fn);
  585. return this;
  586. }
  587. /** Binds a function to the progress event.
  588. *
  589. * @param fn Function to call when triggered.**/
  590. public function progress(fn:Function):Element {
  591. bind('element_progress', fn);
  592. return this;
  593. }
  594. /** Binds a function to the init event.
  595. *
  596. * @param fn Function to call when triggered.**/
  597. public function init(fn:Function):Element {
  598. bind('element_init', fn);
  599. return this;
  600. }
  601. /** Binds a function to the complete event.
  602. *
  603. * @param fn Function to call when triggered.**/
  604. public function complete(fn:Function):Element {
  605. bind('element_complete', fn);
  606. return this;
  607. }
  608. /** Binds a function to the finish event.
  609. *
  610. * @param fn Function to call when triggered.**/
  611. public function finish(fn:Function):Element {
  612. bind('element_finish', fn);
  613. return this;
  614. }
  615. /** Binds a function to the mousedown event.
  616. *
  617. * @param fn Function to call when triggered.**/
  618. public function mousedown(fn:Function):Element {
  619. bind('element_mousedown', fn);
  620. return this;
  621. }
  622. /** Binds a function to the mousemove event.
  623. *
  624. * @param fn Function to call when triggered.**/
  625. public function mousemove(fn:Function):Element {
  626. bind('element_mousemove', fn);
  627. return this;
  628. }
  629. /** Binds a function to the mouseout event.
  630. *
  631. * @param fn Function to call when triggered.**/
  632. public function mouseout(fn:Function):Element {
  633. bind('element_mouseout', fn);
  634. return this;
  635. }
  636. /** Binds a function to the mouseover event.
  637. *
  638. * @param fn Function to call when triggered.**/
  639. public function mouseover(fn:Function):Element {
  640. bind('element_mouseover', fn);
  641. return this;
  642. }
  643. /** Binds a function to the mouseup event.
  644. *
  645. * @param fn Function to call when triggered.**/
  646. public function mouseup(fn:Function):Element {
  647. bind('element_mouseup', fn);
  648. return this;
  649. }
  650. /** Binds a function to the resize event.
  651. *
  652. * @param fn Function to call when triggered.**/
  653. public function resize(fn:Function):Element {
  654. bind('element_resize', fn);
  655. return this;
  656. }
  657. /** Binds a function to the scroll event.
  658. *
  659. * @param fn Function to call when triggered.**/
  660. public function scroll(fn:Function):Element {
  661. if(fn != null) {
  662. bind('element_scroll', fn);
  663. } else {
  664. trigger('element_scroll');
  665. }
  666. return this;
  667. }
  668. /** Binds a function to the select event.
  669. *
  670. * @param fn Function to call when triggered.**/
  671. public function select(fn:Function=null):Element {
  672. if(fn != null) {
  673. bind('element_select', fn);
  674. } else {
  675. trigger('element_select');
  676. }
  677. return this;
  678. }
  679. /** Binds a function to the submit event.
  680. *
  681. * @param fn Function to call when triggered.**/
  682. public function submit(fn:Function=null):Element {
  683. if(fn != null) {
  684. bind('element_submit', fn);
  685. } else {
  686. trigger('element_submit');
  687. }
  688. return this;
  689. }
  690. /** Binds a function to the unload event.
  691. *
  692. * @param fn Function to call when triggered.**/
  693. public function unload(fn:Function):Element {
  694. bind('element_unload', fn);
  695. return this;
  696. }
  697. /* Convert AS3 Events */
  698. /** @private **/
  699. private function onInit(e:Event):void {
  700. trigger('element_init', null, e);
  701. }
  702. /** @private **/
  703. private function onComplete(e:Event):void {
  704. trigger('element_complete', null, e);
  705. }
  706. /** @private **/
  707. private function onBlur(e:FocusEvent):void {
  708. trigger('element_unfocus', null, e);
  709. }
  710. /** @private **/
  711. private function onChange(e:Event):void {
  712. trigger('element_change', null, e);
  713. }
  714. /** @private **/
  715. protected function onClick(e:MouseEvent):void {
  716. trigger('element_click', null, e);
  717. }
  718. /** @private **/
  719. protected function onDoubleClick(e:MouseEvent):void {
  720. trigger('element_dblclick', null, e);
  721. }
  722. /** @private **/
  723. private function onFocus(e:FocusEvent):void {
  724. trigger('element_focus', null, e);
  725. }
  726. /** @private **/
  727. private function onEnter(e:Event):void {
  728. trigger('element_enter', null, e);
  729. }
  730. /** @private **/
  731. private function onKeyDown(e:KeyboardEvent):void {
  732. trigger('element_keydown', null, e);
  733. }
  734. /** @private **/
  735. private function onKeyUp(e:KeyboardEvent):void {
  736. trigger('element_keyup', null, e);
  737. }
  738. /** @private **/
  739. private function onAdd(e:Event):void {
  740. trigger('element_add', null, e);
  741. }
  742. /** @private **/
  743. private function onMouseDown(e:MouseEvent):void {
  744. trigger('element_mousedown', null, e);
  745. }
  746. /** @private **/
  747. private function onMouseMove(e:MouseEvent):void {
  748. trigger('element_mousemove', null, e);
  749. }
  750. /** @private **/
  751. protected function onMouseOut(e:MouseEvent):void {
  752. trigger('element_mouseout', null, e);
  753. }
  754. /** @private **/
  755. protected function onMouseOver(e:MouseEvent):void {
  756. trigger('element_mouseover', null, e);
  757. }
  758. /** @private **/
  759. private function onMouseUp(e:MouseEvent):void {
  760. trigger('element_mouseup', null, e);
  761. }
  762. /** @private **/
  763. private function onUnload(e:Event):void {
  764. trigger('element_unload', null, e);
  765. }
  766. /** @private **/
  767. private function onError(e:IOErrorEvent):void {
  768. trace('IO Error: For element, ' + id, e.text);
  769. trigger('element_error', null, e);
  770. }
  771. /** @private **/
  772. protected function onProgress(e:ProgressEvent):void {
  773. trigger('element_progress', null, e);
  774. }
  775. /** Sets the element up to be a container to other visible items. The
  776. * element becomes a ghost, yet all child elements are still interactive with the mouse. **/
  777. public function holder():void {
  778. buttonMode = false;
  779. mouseEnabled = false;
  780. mouseChildren = true;
  781. useHandCursor = false;
  782. stretch = false;
  783. }
  784. public function set stretch(value:Boolean):void {
  785. data.stretch = value;
  786. }
  787. public function get stretch():Boolean {
  788. return data.stretch;
  789. }
  790. /** Indicates whether the element has been setup. **/
  791. public function set isSetup(value:Boolean):void {
  792. data.isSetup = value;
  793. if(value) {
  794. update();
  795. }
  796. }
  797. public function get isSetup():Boolean {
  798. if(data != null) {
  799. return data.isSetup;
  800. } else {
  801. return false;
  802. }
  803. }
  804. /** Update the elements properties. **/
  805. public function update(obj:Object=null):void {
  806. }
  807. public override function addEventListener(type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false):void {
  808. //Add listener
  809. super.addEventListener(type, listener, false, 0, true);
  810. if(useCapture) {
  811. return;
  812. }
  813. //Add listener to event manager
  814. var lisLen:int = _listeners.length;
  815. _listeners[lisLen] = {type:type, fn:listener};
  816. //Add alias if exists
  817. switch(type) {
  818. case 'element_init':
  819. super.addEventListener('init', onInit, false, 0, true);
  820. break;
  821. case 'element_complete':
  822. super.addEventListener('complete', onComplete, false, 0, true);
  823. break;
  824. case 'element_enter':
  825. super.addEventListener('enterFrame', onEnter, false, 0, true);
  826. break;
  827. case 'element_focus':
  828. super.addEventListener('focusIn', onFocus, false, 0, true);
  829. break;
  830. case 'element_unfocus':
  831. super.addEventListener('focusOut', onBlur, false, 0, true);
  832. break;
  833. case 'element_change':
  834. super.addEventListener('change', onChange, false, 0, true);
  835. break;
  836. case 'element_keydown':
  837. super.addEventListener('keyDown', onKeyDown, false, 0, true);
  838. break;
  839. case 'element_keyup':
  840. super.addEventListener('keyUp', onKeyUp, false, 0, true);
  841. break;
  842. case 'element_add':
  843. super.addEventListener('addedToStage', onAdd, false, 0, true);
  844. break;
  845. case 'element_unload':
  846. super.addEventListener('removeFromStage', onUnload, false, 0, true);
  847. break;
  848. case 'element_click':
  849. super.addEventListener('click', onClick, false, 0, true);
  850. break;
  851. case 'element_mouseover':
  852. super.addEventListener('mouseOver', onMouseOver, false, 0, true);
  853. break;
  854. case 'element_mousedown':
  855. super.addEventListener('mouseDown', onMouseDown, false, 0, true);
  856. break;
  857. case 'element_mousemove':
  858. super.addEventListener('mouseMove', onMouseMove, false, 0, true);
  859. break;
  860. case 'element_mouseout':
  861. super.addEventListener('mouseOut', onMouseOut, false, 0, true);
  862. break;
  863. case 'element_mouseup':
  864. super.addEventListener('mouseUp', onMouseUp, false, 0, true);
  865. break;
  866. case 'element_dblclick':
  867. super.addEventListener('doubleClick', onDoubleClick, false, 0, true);
  868. doubleClickEnabled = true;
  869. break;
  870. }
  871. }
  872. public override function removeEventListener(type:String, listener:Function, useCapture:Boolean=false):void {
  873. //Remove listener
  874. super.removeEventListener(type, listener, useCapture);
  875. //Remove listener from manager
  876. var lisLen:int = _listeners.length;
  877. if(!lisLen) {
  878. return;
  879. }
  880. var lisCnt:int = 0;
  881. var lisIdx:int = -1;
  882. var lisObj:Object;
  883. for(var g:int=0; g<lisLen; g++) {
  884. lisObj = _listeners[g];
  885. if(lisObj.type == type) {
  886. lisCnt++;
  887. if(lisObj.fn == listener) {
  888. lisIdx = g;
  889. }
  890. }
  891. }
  892. if(lisIdx >=0) {
  893. _listeners.splice(lisIdx, 1);
  894. }
  895. //Only remove alias if all references to the event are removed
  896. if(lisCnt > 1) {
  897. return;
  898. }
  899. //Remove alias
  900. switch(type) {
  901. case 'element_init':
  902. super.removeEventListener('init', onInit);
  903. break;
  904. case 'element_complete':
  905. super.removeEventListener('complete', onComplete);
  906. break;
  907. case 'element_enter':
  908. super.removeEventListener('enterFrame', onEnter);
  909. break;
  910. case 'element_focus':
  911. super.removeEventListener('focusIn', onFocus);
  912. break;
  913. case 'element_unfocus':
  914. removeEventListener('focusOut', onBlur);
  915. break;
  916. case 'element_change':
  917. super.removeEventListener('change', onChange);
  918. break;
  919. case 'element_keydown':
  920. super.removeEventListener('keyDown', onKeyDown);
  921. break;
  922. case 'element_keyup':
  923. super.removeEventListener('keyUp', onKeyUp);
  924. break;
  925. case 'element_add':
  926. super.removeEventListener('addedToStage', onAdd);
  927. break;
  928. case 'element_unload':
  929. super.removeEventListener('removeFromStage', onUnload);
  930. break;
  931. case 'element_click':
  932. super.removeEventListener('click', onClick);
  933. break;
  934. case 'element_mouseover':
  935. super.removeEventListener('mouseOver', onMouseOver);
  936. break;
  937. case 'element_mousedown':
  938. super.removeEventListener('mouseDown', onMouseDown);
  939. break;
  940. case 'element_mousemove':
  941. super.removeEventListener('mouseMove', onMouseMove);
  942. break;
  943. case 'element_mouseout':
  944. super.removeEventListener('mouseOut', onMouseOut);
  945. break;
  946. case 'element_mouseup':
  947. removeEventListener('mouseUp', onMouseUp);
  948. break;
  949. case 'element_dblclick':
  950. super.removeEventListener('doubleClick', onDoubleClick);
  951. doubleClickEnabled = false;
  952. break;
  953. }
  954. }
  955. /** Clear all events from an element **/
  956. public function clearEvents():void {
  957. var lisLen:int = _listeners.length;
  958. var lisObj:Object;
  959. for(var g:int; g<lisLen; g++) {
  960. lisObj = _listeners[g];
  961. if(hasEventListener(lisObj.type)) {
  962. removeEventListener(lisObj.type, lisObj.fn);
  963. }
  964. }
  965. _listeners = new Vector.<Object>();
  966. }
  967. /** Kill the object and clean from memory. **/
  968. public function kill():void {
  969. //Remove Listeners
  970. clearEvents();
  971. //Remove Children
  972. var childLen:int = children.length;
  973. for(var h:int=childLen; h>0; h--) {
  974. removeChild(elements[h-1]);
  975. }
  976. //Nullify values
  977. id = null;
  978. title = null;
  979. //lang = null;
  980. //dir = null;
  981. //className = null;
  982. basePath = null;
  983. data = null;
  984. _listeners = null;
  985. //contentEditable = null;
  986. }
  987. }
  988. }