PageRenderTime 51ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/src/org/openPyro/core/UIContainer.as

http://github.com/arpit/openpyro
ActionScript | 1034 lines | 714 code | 119 blank | 201 comment | 139 complexity | 7b205e8a53ed2881e55f12a74bcb6024 MD5 | raw file
  1. package org.openPyro.core{
  2. import flash.display.DisplayObject;
  3. import flash.display.Sprite;
  4. import flash.events.Event;
  5. import flash.events.MouseEvent;
  6. import flash.filters.DropShadowFilter;
  7. import flash.geom.Rectangle;
  8. import org.openPyro.controls.ScrollBar;
  9. import org.openPyro.controls.events.ScrollEvent;
  10. import org.openPyro.controls.scrollBarClasses.ScrollPolicy;
  11. import org.openPyro.controls.skins.IScrollBarSkin;
  12. import org.openPyro.controls.skins.IScrollableContainerSkin;
  13. import org.openPyro.effects.Effect;
  14. import org.openPyro.events.PyroEvent;
  15. import org.openPyro.layout.AbsoluteLayout;
  16. import org.openPyro.layout.IContainerMeasurementHelper;
  17. import org.openPyro.layout.ILayout;
  18. import org.openPyro.utils.MouseUtil;
  19. /**
  20. * Event dispatched when content resizing causes the scrollbars to
  21. * change (either appear or disappear)
  22. */
  23. [Event(name="_scrollBarsChanged", type="org.openPyro.events.PyroEvent")]
  24. /**
  25. * UIContainers extend UIControls and introduce
  26. * the concept of scrolling and layouts. If the
  27. * bounds of the children of a UIContainer, they
  28. * get clipped by the mask layer on top.
  29. *
  30. * todo: Create UIContainer.clipContent = false/true function
  31. *
  32. * @see #layout
  33. */
  34. public class UIContainer extends UIControl{
  35. public var dropShadowSprite:Sprite;
  36. public var contentPane:UIControl;
  37. public var focusRectHolder:Sprite;
  38. protected var _horizontalScrollPolicy:String = ScrollPolicy.AUTO;
  39. protected var _verticalScrollPolicy:String = ScrollPolicy.AUTO;
  40. public function UIContainer(){
  41. super();
  42. contentPane = new UIControl();
  43. contentPane.name = "contentPane_"+this.name;
  44. focusRectHolder = new Sprite();
  45. focusRectHolder.mouseEnabled = false;
  46. this.tabChildren = true
  47. }
  48. /**
  49. * @inheritDoc
  50. */
  51. override public function initialize():void
  52. {
  53. /*
  54. Since the first time the container is
  55. validated, it may cause scrollbars to
  56. be added immediately, the contentPane
  57. is added before any of that so that
  58. scrollbars are not placed under it
  59. */
  60. $addChild(contentPane);
  61. $addChild(focusRectHolder);
  62. this.addEventListener(MouseEvent.MOUSE_WHEEL, handleMouseWheel);
  63. super.initialize();
  64. contentPane.percentUnusedWidth = 100;
  65. contentPane.percentUnusedHeight = 100;
  66. contentPane.doOnAdded()
  67. this.addEventListener(MouseEvent.ROLL_OVER, handleMouseOver)
  68. this.addEventListener(MouseEvent.ROLL_OUT, handleMouseOut)
  69. }
  70. public static var mouseOverDisabled:Boolean = false;
  71. /**
  72. * This flag is used to check at any time if the content is being scrolled verically.
  73. * Its useful when, for example, scrollpolicy is set to visible on hover but the act
  74. * of rolling off the content fades the scrollbar only if the content is not being
  75. * scrolled.
  76. */
  77. protected var _scrollingVertically:Boolean = false;
  78. protected function handleMouseOver(event:MouseEvent):void{
  79. if(UIContainer.mouseOverDisabled){
  80. event.stopImmediatePropagation();
  81. event.preventDefault();
  82. return;
  83. }
  84. if(this._horizontalScrollPolicy == ScrollPolicy.VISIBLE_ON_HOVER){
  85. if(_horizontalScrollBar && needsHorizontalScrollBar){
  86. /*
  87. * TODO: needs a check for the if _scrollingHorizontally
  88. */
  89. Effect.on(_horizontalScrollBar).cancelCurrent().fadeIn(1);
  90. }
  91. }
  92. if(this._verticalScrollPolicy == ScrollPolicy.VISIBLE_ON_HOVER){
  93. if(_verticalScrollBar && !_scrollingVertically && needsVerticalScrollBar){
  94. Effect.on(_verticalScrollBar).cancelCurrent().fadeIn(1);
  95. }
  96. }
  97. }
  98. protected function handleMouseOut(event:MouseEvent):void{
  99. if(this._horizontalScrollPolicy == ScrollPolicy.VISIBLE_ON_HOVER){
  100. if(_horizontalScrollBar){
  101. Effect.on(_horizontalScrollBar).cancelCurrent().fadeOut(1);
  102. }
  103. }
  104. if(this._verticalScrollPolicy == ScrollPolicy.VISIBLE_ON_HOVER){
  105. if(_verticalScrollBar && !_scrollingVertically){
  106. Effect.on(_verticalScrollBar).cancelCurrent().fadeOut(1);
  107. }
  108. }
  109. }
  110. /**
  111. * @private
  112. */
  113. public function set horizontalScrollPolicy(policy:String):void{
  114. _horizontalScrollPolicy = policy;
  115. }
  116. /**
  117. * Sets the behavior of the scrollbar for a UIContainer.
  118. * Note that if you set the scrollpolicy to FADE_ON_HOVER,
  119. * its advisable to set the backgroundPainter so that
  120. * the calculation of rollout/rollover does not get buggy as
  121. * the mouse rolls over the children of the UIContainer
  122. */
  123. public function get horizontalScrollPolicy():String{
  124. return _horizontalScrollPolicy;
  125. }
  126. /**
  127. * @private
  128. */
  129. public function set verticalScrollPolicy(policy:String):void{
  130. _verticalScrollPolicy = policy;
  131. }
  132. /**
  133. * Sets the behavior of the scrollbar for a UIContainer.
  134. * Note that if you set the scrollpolicy to FADE_ON_HOVER,
  135. * its advisable to set the backgroundPainter so that
  136. * the calculation of rollout/rollover does not get buggy as
  137. * the mouse rolls over the children of the UIContainer
  138. */
  139. public function get verticalScrollPolicy():String{
  140. return _verticalScrollPolicy;
  141. }
  142. override public function addChild(child:DisplayObject):DisplayObject
  143. {
  144. return addChildAt(child, this.contentPane.numChildren);
  145. }
  146. override public function addChildAt(child:DisplayObject, index:int):DisplayObject
  147. {
  148. var ch:DisplayObject = contentPane.addChildAt(child, index);
  149. if(child is MeasurableControl)
  150. {
  151. var control:MeasurableControl = child as MeasurableControl;
  152. control.parentContainer = this;
  153. control.addEventListener(PyroEvent.SIZE_INVALIDATED, invalidateSize);
  154. control.addEventListener(PyroEvent.SIZE_CHANGED, queueValidateDisplayList);
  155. control.doOnAdded()
  156. }
  157. displayListInvalidated = true;
  158. forceInvalidateDisplayList=true;
  159. invalidateSize();
  160. return ch;
  161. }
  162. override public function getChildByName(name:String):DisplayObject{
  163. return contentPane.getChildByName(name);
  164. }
  165. override public function removeChild(child:DisplayObject):DisplayObject{
  166. var childToRemove:DisplayObject = contentPane.removeChild(child);
  167. this.invalidateSize();
  168. this.invalidateDisplayList();
  169. return childToRemove;
  170. }
  171. public function removeAllChildren():void{
  172. while(this.contentPane.numChildren>0){
  173. contentPane.removeChildAt(0);
  174. }
  175. }
  176. override protected function doChildBasedValidation():void
  177. {
  178. var child:DisplayObject;
  179. if(isNaN(this._explicitWidth) && isNaN(this._percentWidth) && isNaN(_percentUnusedWidth))
  180. {
  181. super.measuredWidth = _layout.getMaxWidth(this.layoutChildren) + _padding.left + _padding.right;
  182. }
  183. if(isNaN(this._explicitHeight) && isNaN(this._percentHeight) && isNaN(_percentUnusedHeight))
  184. {
  185. super.measuredHeight = _layout.getMaxHeight(this.layoutChildren) + _padding.top + _padding.bottom;
  186. }
  187. }
  188. private var _explicitlyAllocatedWidth:Number = 0;
  189. private var _explicitlyAllocatedHeight:Number = 0;
  190. /**
  191. * This property are modified by IContainerMeasurementHelpers.
  192. * which most container layouts implement.
  193. *
  194. * @see org.openPyro.layout.IContainerMeasurementHelper
  195. */
  196. public function set explicitlyAllocatedWidth(w:Number):void
  197. {
  198. _explicitlyAllocatedWidth = w;
  199. }
  200. /**
  201. * @private
  202. */
  203. public function get explicitlyAllocatedWidth():Number
  204. {
  205. return _explicitlyAllocatedWidth ;
  206. }
  207. /**
  208. * This property are modified by IContainerMeasurementHelpers.
  209. * which most container layouts implement.
  210. *
  211. * @see org.openPyro.layout.IContainerMeasurementHelper
  212. */
  213. public function set explicitlyAllocatedHeight(h:Number):void
  214. {
  215. _explicitlyAllocatedHeight = h;
  216. }
  217. /**
  218. * @private
  219. */
  220. public function get explicitlyAllocatedHeight():Number
  221. {
  222. return _explicitlyAllocatedHeight;
  223. }
  224. /**
  225. * @inheritDoc
  226. *
  227. * If validateSize is called on UIContainers, the container does
  228. * a check at the end to see if the children layout requires a
  229. * scroll and if the scrollbar needs to be created. If so, it
  230. * creates the scrollbars and calls validateSize again.
  231. */
  232. override public function validateSize():void
  233. {
  234. calculateContentDimensions();
  235. _explicitlyAllocatedWidth = _padding.left+_padding.right
  236. _explicitlyAllocatedHeight = _padding.top+_padding.bottom;
  237. var layoutChildrenArray:Array = layoutChildren;
  238. _layout.initX = this.padding.left;
  239. _layout.initY = this.padding.top;
  240. if(_layout is IContainerMeasurementHelper)
  241. {
  242. IContainerMeasurementHelper(_layout).calculateSizes(layoutChildrenArray, this)
  243. }
  244. super.validateSize();
  245. /*
  246. Check if scrollbar is visible.
  247. Note: We only check the ScrollPolicy.VISIBLE_ON_HOVER parameter since other scrollPolicys are
  248. validated by the existance of the scrollbar itself.
  249. */
  250. if(this._verticalScrollBar && _verticalScrollBar.visible)
  251. {
  252. if(_verticalScrollPolicy != ScrollPolicy.VISIBLE_ON_HOVER){
  253. this.explicitlyAllocatedWidth-=_verticalScrollBar.width;
  254. }
  255. _verticalScrollBar.setScrollProperty(this.scrollHeight, this._contentHeight);
  256. }
  257. if(this._horizontalScrollBar && _horizontalScrollBar.visible)
  258. {
  259. if(_horizontalScrollPolicy != ScrollPolicy.VISIBLE_ON_HOVER){
  260. this.explicitlyAllocatedHeight-=_horizontalScrollBar.height
  261. }
  262. _horizontalScrollBar.setScrollProperty(this.scrollWidth, contentWidth);
  263. }
  264. if(_verticalScrollBar)
  265. {
  266. if(_horizontalScrollBar && _horizontalScrollBar.visible){
  267. _verticalScrollBar.height = this.height - _horizontalScrollBar.height//setActualSize(_verticalScrollBar.width,this.height - _horizontalScrollBar.height);
  268. }
  269. else{
  270. _verticalScrollBar.height = this.height
  271. }
  272. _verticalScrollBar.validateSize();
  273. _verticalScrollBar.validateDisplayList();
  274. }
  275. if(_horizontalScrollBar)
  276. {
  277. if(_verticalScrollBar && _verticalScrollBar.visible)
  278. {
  279. _horizontalScrollBar.width = this.width-_verticalScrollBar.width;
  280. }
  281. else{
  282. _horizontalScrollBar.width = this.width;
  283. }
  284. _horizontalScrollBar.validateSize();
  285. _horizontalScrollBar.validateDisplayList();
  286. }
  287. checkRevalidation();
  288. dispatchEvent(new PyroEvent(PyroEvent.SIZE_VALIDATED));
  289. }
  290. /**
  291. * Calculates the contentWidth and contentHeight properties
  292. */
  293. public function calculateContentDimensions():void{
  294. _contentHeight = this._layout.getMaxHeight(this.layoutChildren);
  295. _contentWidth = this._layout.getMaxWidth(this.layoutChildren);
  296. }
  297. protected var _layout:ILayout = new AbsoluteLayout()
  298. protected var layoutInvalidated:Boolean = true;
  299. /**
  300. * Containers can be assigned different layouts
  301. * which control the positioning of the
  302. * different controls.
  303. *
  304. * @see org.openPyro.layout
  305. */
  306. public function get layout():ILayout
  307. {
  308. return _layout;
  309. }
  310. /**
  311. * @private
  312. */
  313. public function set layout(l:ILayout):void
  314. {
  315. if(_layout == l) return;
  316. layoutInvalidated = true;
  317. _layout = l;
  318. _layout.container = this;
  319. if(!initialized) return;
  320. this.invalidateSize()
  321. }
  322. /**
  323. * Returns an Array of displayObjects whose positions
  324. * are controlled by the <code>ILayout</code> object.
  325. * These do not include, for example, the scrollbars.
  326. *
  327. * @see org.openPyro.layout
  328. */
  329. public function get layoutChildren():Array
  330. {
  331. var children:Array = new Array();
  332. if(!contentPane) return children;
  333. for(var i:uint=0; i<this.contentPane.numChildren; i++)
  334. {
  335. var child:MeasurableControl = contentPane.getChildAt(i) as MeasurableControl
  336. if(!child || !child.includeInLayout) continue;
  337. children.push(child);
  338. }
  339. return children;
  340. }
  341. /////////// END LAYOUT ///////////
  342. /**
  343. * @inheritDoc
  344. */
  345. override public function widthForMeasurement():Number
  346. {
  347. var containerWidth:Number = this.width - this._explicitlyAllocatedWidth
  348. if(this._verticalScrollBar && _verticalScrollBar.visible==true && _verticalScrollPolicy != ScrollPolicy.VISIBLE_ON_HOVER)
  349. {
  350. containerWidth-=_verticalScrollBar.width;
  351. }
  352. return containerWidth;
  353. }
  354. /**
  355. * @inheritDoc
  356. */
  357. override public function heightForMeasurement():Number
  358. {
  359. var containerHeight:Number = this.height-this._explicitlyAllocatedHeight;
  360. if(this._horizontalScrollBar && _horizontalScrollBar.visible==true && _horizontalScrollPolicy != ScrollPolicy.VISIBLE_ON_HOVER)
  361. {
  362. containerHeight-=_horizontalScrollBar.height;
  363. }
  364. return containerHeight;
  365. }
  366. /**
  367. * scrollWidth is the max width a horizontal
  368. * scrollbar needs to scroll
  369. */
  370. public function get scrollWidth():Number
  371. {
  372. var containerWidth:Number = this.width-padding.left-padding.right
  373. if(this._verticalScrollBar && _verticalScrollBar.visible==true)
  374. {
  375. containerWidth-=_verticalScrollBar.width;
  376. }
  377. return containerWidth;
  378. }
  379. /**
  380. * scrollHeight is the max height a vertical
  381. * scrollbar needs to scroll
  382. */
  383. public function get scrollHeight():Number
  384. {
  385. var containerHeight:Number = this.height-padding.top-padding.bottom;
  386. if(this._horizontalScrollBar && _horizontalScrollBar.visible==true)
  387. {
  388. containerHeight-=_horizontalScrollBar.height;
  389. }
  390. return containerHeight;
  391. }
  392. protected var _verticalScrollBar:ScrollBar;
  393. protected var _horizontalScrollBar:ScrollBar;
  394. /**
  395. * Returns The instance of the created verticalScrollBar
  396. * or null if it was never created or is not visible. Note
  397. * that this function does cannot be used to detect if the
  398. * scrollbar was created or not, since scrollbars once
  399. * created are never distroyed, even if a subsequent change
  400. * in the container's layout does not require the scrollbar
  401. * anymore.
  402. */
  403. public function get verticalScrollBar():ScrollBar
  404. {
  405. if(_verticalScrollBar && _verticalScrollBar.visible)
  406. {
  407. return _verticalScrollBar
  408. }
  409. else
  410. {
  411. return null;
  412. }
  413. }
  414. /**
  415. * Returns The instance of the created horizontal
  416. * or null if it was never created or is not visible. Note
  417. * that this function does cannot be used to detect if the
  418. * scrollbar was created or not, since scrollbars once
  419. * created are never distroyed, even if a subsequent change
  420. * in the container's layout does not require the scrollbar
  421. * anymore.
  422. */
  423. public function get horizontalScrollBar():ScrollBar
  424. {
  425. if(_horizontalScrollBar && _horizontalScrollBar.visible)
  426. {
  427. return _horizontalScrollBar
  428. }
  429. else
  430. {
  431. return null;
  432. }
  433. }
  434. protected var _scrollBarsChanged:Boolean = false;
  435. protected function set scrollBarsChanged(val:Boolean):void{
  436. _scrollBarsChanged = val;
  437. forceInvalidateDisplayList=true;
  438. }
  439. protected function get scrollBarsChanged():Boolean{
  440. return _scrollBarsChanged;
  441. }
  442. protected function checkRevalidation():void
  443. {
  444. if(_horizontalScrollPolicy != ScrollPolicy.OFF){
  445. checkNeedsHScrollBar();
  446. }
  447. if(_verticalScrollPolicy != ScrollPolicy.OFF)
  448. {
  449. checkNeedsVScrollBar();
  450. }
  451. if(needsHorizontalScrollBar &&
  452. this._skin &&
  453. this._skin is IScrollableContainerSkin &&
  454. IScrollableContainerSkin(_skin).horizontalScrollBarSkin)
  455. {
  456. if(!_horizontalScrollBar)
  457. {
  458. createHScrollBar();
  459. }
  460. if(_horizontalScrollBar.visible==false)
  461. {
  462. _horizontalScrollBar.visible = true;
  463. scrollBarsChanged = true;
  464. }
  465. }
  466. if(!needsHorizontalScrollBar && _horizontalScrollBar && _horizontalScrollBar.visible==true)
  467. {
  468. _horizontalScrollBar.value = 0;
  469. _horizontalScrollBar.visible = false;
  470. scrollBarsChanged = true;
  471. }
  472. if(needsVerticalScrollBar &&
  473. this._skin &&
  474. this._skin is IScrollableContainerSkin &&
  475. IScrollableContainerSkin(_skin).verticalScrollBarSkin)
  476. {
  477. if(!_verticalScrollBar)
  478. {
  479. createVScrollBar();
  480. }
  481. if(_verticalScrollBar.visible == false)
  482. {
  483. _verticalScrollBar.visible = true;
  484. scrollBarsChanged=true;
  485. }
  486. }
  487. if(!needsVerticalScrollBar && _verticalScrollBar && _verticalScrollBar.visible == true)
  488. {
  489. _verticalScrollBar.value = 0;
  490. _verticalScrollBar.visible = false;
  491. scrollBarsChanged = true;
  492. }
  493. if(_scrollBarsChanged)
  494. {
  495. _scrollBarsChanged = false;
  496. dispatchEvent(new PyroEvent(PyroEvent.SCROLLBARS_CHANGED));
  497. validateSize();
  498. }
  499. }
  500. protected var _contentHeight:Number = 0;
  501. protected var _contentWidth:Number = 0;
  502. public function get contentHeight():Number{
  503. return _contentHeight;
  504. }
  505. public function get contentWidth():Number{
  506. return _contentWidth;
  507. }
  508. protected var needsVerticalScrollBar:Boolean = false;
  509. protected var needsHorizontalScrollBar:Boolean = false;
  510. protected function checkNeedsVScrollBar():void
  511. {
  512. calculateContentDimensions();
  513. if(_contentHeight > this.height){
  514. needsVerticalScrollBar = true
  515. }
  516. else{
  517. needsVerticalScrollBar = false;
  518. }
  519. }
  520. protected function checkNeedsHScrollBar():void
  521. {
  522. calculateContentDimensions();
  523. //_contentWidth = this._layout.getMaxWidth(this.layoutChildren);
  524. if(_contentWidth > this.width){
  525. needsHorizontalScrollBar = true
  526. }
  527. else{
  528. needsHorizontalScrollBar = false;
  529. }
  530. }
  531. protected function createVScrollBar():void
  532. {
  533. _verticalScrollBar = new ScrollBar(Direction.VERTICAL);
  534. _verticalScrollBar.maximum = 1;
  535. _verticalScrollBar.minimum = 0;
  536. _verticalScrollBar.incrementalScrollDelta = _verticalScrollIncrement;
  537. _verticalScrollBar.name = "vscrollbar_"+this.name;
  538. var verticalScrollBarSkin:IScrollBarSkin = IScrollableContainerSkin(_skin).verticalScrollBarSkin;
  539. if(isNaN(verticalScrollBarSkin.scrollbarWidth)){
  540. _verticalScrollBar.width = 15;
  541. }
  542. else{
  543. _verticalScrollBar.width = verticalScrollBarSkin.scrollbarWidth;
  544. }
  545. _verticalScrollBar.addEventListener(Event.ADDED_TO_STAGE, function():void{
  546. _verticalScrollBar.addEventListener(MouseEvent.MOUSE_DOWN, function(event:MouseEvent):void{
  547. mouseOverDisabled = true;
  548. _scrollingVertically = true;
  549. })
  550. _verticalScrollBar.stage.addEventListener(MouseEvent.MOUSE_UP, function(event:MouseEvent):void{
  551. mouseOverDisabled = false;
  552. _scrollingVertically = false;
  553. })
  554. });
  555. _verticalScrollBar.addEventListener(PyroEvent.SIZE_VALIDATED, onVerticalScrollBarSizeValidated);
  556. _verticalScrollBar.addEventListener(PyroEvent.CREATION_COMPLETE, onVScrollBarCreationComplete);
  557. _verticalScrollBar.skin = verticalScrollBarSkin;
  558. _verticalScrollBar.addEventListener(ScrollEvent.SCROLL, onVerticalScroll)
  559. _verticalScrollBar.doOnAdded()
  560. _verticalScrollBar.visible = false;
  561. $addChild(_verticalScrollBar);
  562. _verticalScrollBar.addEventListener(MouseEvent.MOUSE_UP, function(event:MouseEvent):void{
  563. mouseOverDisabled = false;
  564. });
  565. if(this._verticalScrollPolicy == ScrollPolicy.VISIBLE_ON_HOVER){
  566. if(!MouseUtil.isMouseOver(this)){
  567. _verticalScrollBar.alpha = 0;
  568. }
  569. }
  570. }
  571. /**
  572. * @private
  573. */
  574. public function set verticalScrollBar(scrollBar:ScrollBar):void
  575. {
  576. _verticalScrollBar = scrollBar;
  577. _verticalScrollBar.height = this.getExplicitOrMeasuredHeight();
  578. $addChild(scrollBar);
  579. scrollBar.doOnAdded();
  580. _verticalScrollBar.addEventListener(ScrollEvent.SCROLL, onVerticalScroll)
  581. }
  582. protected function hideVScrollBar():void
  583. {
  584. if(_verticalScrollBar)
  585. {
  586. _verticalScrollBar.visible=false;
  587. }
  588. }
  589. protected function createHScrollBar():void
  590. {
  591. _horizontalScrollBar = new ScrollBar(Direction.HORIZONTAL);
  592. _horizontalScrollBar.maximum = 1
  593. _horizontalScrollBar.minimum = 0
  594. _horizontalScrollBar.incrementalScrollDelta = _horizontalScrollIncrement
  595. _horizontalScrollBar.name = "hscrollbar_"+this.name;
  596. var horizontalScrollBarSkin:IScrollBarSkin = IScrollableContainerSkin(_skin).verticalScrollBarSkin;
  597. if(isNaN(horizontalScrollBarSkin.scrollbarHeight)){
  598. _horizontalScrollBar.height = 15;
  599. }
  600. else{
  601. _horizontalScrollBar.height = horizontalScrollBarSkin.scrollbarHeight;
  602. }
  603. _horizontalScrollBar.addEventListener(Event.ADDED_TO_STAGE, function(event:Event):void{
  604. _horizontalScrollBar.addEventListener(MouseEvent.MOUSE_DOWN, function(event:MouseEvent):void{
  605. mouseOverDisabled = true;
  606. });
  607. _horizontalScrollBar.stage.addEventListener(MouseEvent.MOUSE_UP, function(event:MouseEvent):void{
  608. mouseOverDisabled = false;
  609. });
  610. });
  611. _horizontalScrollBar.addEventListener(PyroEvent.SIZE_VALIDATED, onHorizontalScrollBarSizeValidated)
  612. _horizontalScrollBar.addEventListener(ScrollEvent.SCROLL, onHorizontalScroll);
  613. _horizontalScrollBar.parentContainer = this;
  614. _horizontalScrollBar.doOnAdded()
  615. _horizontalScrollBar.skin = horizontalScrollBarSkin;
  616. _horizontalScrollBar.visible = false;
  617. $addChild(_horizontalScrollBar);
  618. if(this._horizontalScrollPolicy == ScrollPolicy.VISIBLE_ON_HOVER){
  619. if(!MouseUtil.isMouseOver(this)){
  620. _horizontalScrollBar.alpha = 0;
  621. }
  622. }
  623. }
  624. protected function onHorizontalScrollBarSizeValidated(event:PyroEvent):void
  625. {
  626. _horizontalScrollBar.removeEventListener(PyroEvent.SIZE_VALIDATED, onHorizontalScrollBarSizeValidated)
  627. _horizontalScrollBar.setScrollProperty(this.scrollWidth, contentWidth);
  628. }
  629. protected function onVerticalScrollBarSizeValidated(event:PyroEvent):void
  630. {
  631. _verticalScrollBar.removeEventListener(PyroEvent.SIZE_VALIDATED, onVerticalScrollBarSizeValidated)
  632. _verticalScrollBar.setScrollProperty(this.scrollWidth, contentWidth);
  633. }
  634. protected function hideHScrollBar():void
  635. {
  636. if(_horizontalScrollBar)
  637. {
  638. _horizontalScrollBar.visible=false;
  639. }
  640. }
  641. /*protected function setVerticalScrollBar():void{
  642. if(_verticalScrollBar.parent != this)
  643. {
  644. addChild(_verticalScrollBar);
  645. }
  646. _verticalScrollBar.height = this.height;
  647. }*/
  648. protected function handleMouseWheel(event:MouseEvent):void{
  649. if(this.verticalScrollBar){
  650. var scrollDelta:Number = verticalScrollBar.value - event.delta*.02;
  651. scrollDelta = Math.min(scrollDelta, 1)
  652. scrollDelta = Math.max(0, scrollDelta);
  653. verticalScrollBar.value = scrollDelta;
  654. }
  655. }
  656. public function set horizontalScrollPosition(value:Number):void{
  657. if(!_horizontalScrollBar) return
  658. if(value > 1){
  659. throw new Error("UIContainer scrollpositions range from 0 to 1")
  660. }
  661. this._horizontalScrollBar.value = value;
  662. }
  663. public function get horizontalScrollPosition():Number{
  664. if(_horizontalScrollBar){
  665. return _horizontalScrollBar.value;
  666. }
  667. return 0;
  668. }
  669. private var _horizontalScrollIncrement:Number = 25;
  670. public function set horizontalScrollIncrement(n:Number):void{
  671. _horizontalScrollIncrement = n;
  672. if(_horizontalScrollBar){
  673. _horizontalScrollBar.incrementalScrollDelta = n;
  674. }
  675. }
  676. public function get horizontalScrollIncrement():Number{
  677. return _horizontalScrollIncrement
  678. }
  679. private var _verticalScrollIncrement:Number = 25;
  680. public function set verticalScrollIncrement(n:Number):void{
  681. _verticalScrollIncrement = n;
  682. if(_verticalScrollBar){
  683. _verticalScrollBar.incrementalScrollDelta = n;
  684. }
  685. }
  686. public function get verticalScrollIncrement():Number{
  687. return _verticalScrollIncrement
  688. }
  689. /**
  690. * Sets the scrollposition of the vertical scrollbar
  691. * The valid values are between 0 and 1
  692. */
  693. public function set verticalScrollPosition(value:Number):void{
  694. if(!_verticalScrollBar) return;
  695. if(value > 1){
  696. throw new Error("UIContainer scrollpositions range from 0 to 1")
  697. }
  698. if(_verticalScrollBar){
  699. this._verticalScrollBar.value = value;
  700. }
  701. }
  702. public function get verticalScrollPosition():Number{
  703. if(_verticalScrollBar){
  704. return _verticalScrollBar.value;
  705. }
  706. return 0;
  707. }
  708. protected var scrollY:Number = 0;
  709. protected var scrollX:Number = 0;
  710. /**
  711. * Event listener for when the vertical scrollbar is
  712. * used.
  713. */
  714. protected function onVerticalScroll(event:ScrollEvent):void
  715. {
  716. var scrollAbleHeight:Number = this._contentHeight - this.height;
  717. if(_horizontalScrollBar)
  718. {
  719. scrollAbleHeight+=_horizontalScrollBar.height;
  720. }
  721. setContentMask();
  722. dispatchEvent(event);
  723. }
  724. /**
  725. * Event listener for when the horizontal scrollbar is
  726. * used.
  727. */
  728. protected function onHorizontalScroll(event:ScrollEvent):void
  729. {
  730. var scrollAbleWidth:Number = this.contentWidth - this.width;
  731. if(_verticalScrollBar)
  732. {
  733. scrollAbleWidth+=_verticalScrollBar.width;
  734. }
  735. scrollX = event.value*scrollAbleWidth
  736. setContentMask();
  737. dispatchEvent(event);
  738. }
  739. /**
  740. * The autoPositionViewport property determines whether the scrollRect
  741. * is applied immediately on updateDisplaylist or not. Certain controls
  742. * like Lists want to control the viewport positioning more explicitly.
  743. * For example, when an item is removed from the List or Tree, the default
  744. * setting of the autoPositionViewport will try to adjust the scroll to
  745. * the same percent value as before causing the list items to "jump". So
  746. * Lists turn this property to false and explicitly tell the viewport to
  747. * position only when its scrolled and not when items are added or removed
  748. *
  749. */
  750. protected var _autoPositionViewport:Boolean = true;
  751. public function get autoPositionViewport():Boolean{
  752. return _autoPositionViewport;
  753. }
  754. public function set autoPositionViewport(val:Boolean):void{
  755. _autoPositionViewport = val;
  756. }
  757. /**
  758. * Unlike UIControls, UIContainers do not apply a skin directly on
  759. * themselves but interpret the skin file and apply them to the
  760. * different children. So updateDisplayList here does not call
  761. * super.updateDisplayList()
  762. *
  763. * @inheritDoc
  764. */
  765. override public function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
  766. {
  767. if(layoutInvalidated)
  768. {
  769. doLayoutChildren()
  770. }
  771. if(_verticalScrollBar && _verticalScrollBar.visible==true)
  772. {
  773. _verticalScrollBar.x = this.width - _verticalScrollBar.width-1;
  774. }
  775. if(_horizontalScrollBar && _horizontalScrollBar.visible==true)
  776. {
  777. _horizontalScrollBar.y = this.height - _horizontalScrollBar.height-1;
  778. }
  779. super.updateDisplayList(unscaledWidth, unscaledHeight);
  780. if(dropShadowSprite){
  781. dropShadowSprite.width = width;
  782. dropShadowSprite.height = height;
  783. }
  784. if(_clipContent && autoPositionViewport){
  785. this.setContentMask()
  786. }
  787. }
  788. protected var _clipContent:Boolean = true;
  789. public function set clipContent(b:Boolean):void
  790. {
  791. if(!b) this.scrollRect = null;
  792. _clipContent = b;
  793. }
  794. public function get clipContent():Boolean
  795. {
  796. return _clipContent;
  797. }
  798. /**
  799. * Lays out the layoutChildren based <code>ILayout</code>
  800. * object.
  801. *
  802. * @see #layoutChildren
  803. */
  804. override public function doLayoutChildren():void
  805. {
  806. _layout.layout(this.layoutChildren);
  807. layoutInvalidated = false;
  808. }
  809. /**
  810. * Event listener for the vertical scrollbar's
  811. * creation and validation event.
  812. */
  813. protected function onVScrollBarCreationComplete(event:PyroEvent):void
  814. {
  815. if(_horizontalScrollBar){
  816. _horizontalScrollBar.y = _verticalScrollBar.height;
  817. if(_clipContent){
  818. //this.scrollRect = new Rectangle(0,0, this.width, this.height);
  819. this.setContentMask()
  820. }
  821. }
  822. }
  823. /**
  824. * Event listener for the horizontal scrollbar's
  825. * creation and validation event.
  826. */
  827. protected function onHScrollBarUpdateComplete(event:PyroEvent):void
  828. {
  829. if(_verticalScrollBar){
  830. _verticalScrollBar.x = _horizontalScrollBar.width;
  831. if(_clipContent){
  832. //this.scrollRect = new Rectangle(0,0, this.width, this.height);
  833. this.setContentMask()
  834. }
  835. }
  836. }
  837. protected var _viewportWidth:Number;
  838. protected var _viewportHeight:Number;
  839. public function calculateViewport():void{
  840. _viewportWidth = width
  841. _viewportHeight = height;
  842. if(_verticalScrollBar && _verticalScrollBar.visible==true && _verticalScrollPolicy != ScrollPolicy.VISIBLE_ON_HOVER){
  843. _viewportWidth-=_verticalScrollBar.width
  844. }
  845. if(_horizontalScrollBar && _horizontalScrollBar.visible==true && _horizontalScrollPolicy != ScrollPolicy.VISIBLE_ON_HOVER){
  846. _viewportHeight-=_horizontalScrollBar.height
  847. }
  848. }
  849. public function setContentMask():void{
  850. calculateViewport();
  851. if(_verticalScrollBar){
  852. scrollY = Math.max(0,_verticalScrollBar.value*(_contentHeight-_viewportHeight));
  853. }
  854. if(_horizontalScrollBar){
  855. scrollX = _horizontalScrollBar.value*(_contentWidth-_viewportWidth);
  856. }
  857. var rect:Rectangle = new Rectangle(scrollX,scrollY,_viewportWidth,_viewportHeight);
  858. setScrollRect(rect);
  859. }
  860. public function scrollContentPaneY(value:Number):void{
  861. calculateViewport();
  862. scrollY = value;
  863. var rect:Rectangle = new Rectangle(scrollX,scrollY,_viewportWidth,_viewportHeight);
  864. setScrollRect(rect);
  865. }
  866. public function scrollContentPaneX(value:Number):void{
  867. scrollX = value;
  868. setContentMask();
  869. }
  870. public var debugScrollRect:Boolean = false
  871. public function setScrollRect(rect:Rectangle):void{
  872. if(isNaN(rect.x)){
  873. rect.x = 0;
  874. }
  875. if(isNaN(rect.y)){
  876. rect.y = 0;
  877. }
  878. if(!debugScrollRect){
  879. this.contentPane.scrollRect = rect;
  880. }
  881. else{
  882. this.focusRectHolder.graphics.clear();
  883. this.focusRectHolder.graphics.beginFill(0xff0000,.4);
  884. try{
  885. this.focusRectHolder.graphics.drawRect(rect.left, rect.top, rect.width, rect.height);
  886. }catch(e:Error){
  887. trace("[UIContainer] Error drawing on graphics in setScrollRect");
  888. }
  889. }
  890. }
  891. /**
  892. * Creates/removes a Sprite on which the drop shadow can be applied to. This is done
  893. * since setting the dropShadow on the control itself may cause the control's
  894. * bitmap to be generated and cached by the Flash Player before the control is
  895. * fully created.
  896. */
  897. public function set dropShadowEnabled(val:Boolean):void{
  898. if(val){
  899. if(!dropShadowSprite){
  900. dropShadowSprite = new Sprite();
  901. }
  902. dropShadowSprite.graphics.beginFill(0xffffff);
  903. dropShadowSprite.graphics.drawRect(0,0,100,100);
  904. $addChildAt(dropShadowSprite,0);
  905. dropShadowSprite.width = width;
  906. dropShadowSprite.height = height;
  907. dropShadowSprite.filters = [new DropShadowFilter(4,90,0,.4)];
  908. }
  909. else{
  910. dropShadowSprite.parent.removeChild(dropShadowSprite);
  911. dropShadowSprite = null;
  912. }
  913. }
  914. }
  915. }