package com.jwopitz.containers { import flash.events.MouseEvent; import mx.containers.Panel; import mx.controls.Button; import mx.core.EventPriority; import mx.core.UIComponent; import mx.events.FlexEvent; [Event (name="gripClick", type="flash.events.MouseEvent")] [Event (name="gripMouseDown", type="flash.events.MouseEvent")] [Event (name="gripMouseMove", type="flash.events.MouseEvent")] [Event (name="gripMouseOver", type="flash.events.MouseEvent")] [Event (name="gripMouseOut", type="flash.events.MouseEvent")] [Event (name="gripMouseUp", type="flash.events.MouseEvent")] [Event (name="gripRollOut", type="flash.events.MouseEvent")] [Event (name="gripRollOver", type="flash.events.MouseEvent")] [Bindable] public class Pod extends Panel { public static const GRIP_CLICK:String = "gripClick"; public static const GRIP_MOUSE_DOWN:String = "gripMouseDown"; public static const GRIP_MOUSE_MOVE:String = "gripMouseMove"; public static const GRIP_MOUSE_OVER:String = "gripMouseOver"; public static const GRIP_MOUSE_OUT:String = "gripMouseOut"; public static const GRIP_MOUSE_UP:String = "gripMouseUp"; public static const GRIP_ROLL_OUT:String = "gripRollOut"; public static const GRIP_ROLL_OVER:String = "gripRollOver"; protected var _creationQueue:Array = []; protected var _titleBarAssets:Array = []; public var defaultTitleBarComponentClass:Class = Button; override protected function createChildren ():void { super.createChildren(); titleBar.mouseChildren = false; assignTitleBarListeners(); } override protected function layoutChrome (unscaledWidth:Number, unscaledHeight:Number):void { super.layoutChrome(unscaledWidth, unscaledHeight); repositionButtons(); } protected function assignTitleBarListeners ():void { titleBar.addEventListener(FlexEvent.CREATION_COMPLETE, titleBar_onCreationComplete, false, EventPriority.DEFAULT_HANDLER); titleBar.addEventListener(MouseEvent.CLICK, titleBar_onClick, false, EventPriority.DEFAULT_HANDLER); titleBar.addEventListener(MouseEvent.MOUSE_DOWN, titleBar_onMouseDown, false, EventPriority.DEFAULT_HANDLER); titleBar.addEventListener(MouseEvent.MOUSE_MOVE, titleBar_onMouseMove, false, EventPriority.DEFAULT_HANDLER); titleBar.addEventListener(MouseEvent.MOUSE_OUT, titleBar_onMouseOut, false, EventPriority.DEFAULT_HANDLER); titleBar.addEventListener(MouseEvent.MOUSE_OVER, titleBar_onMouseOver, false, EventPriority.DEFAULT_HANDLER); titleBar.addEventListener(MouseEvent.MOUSE_UP, titleBar_onMouseUp, false, EventPriority.DEFAULT_HANDLER); titleBar.addEventListener(MouseEvent.ROLL_OUT, titleBar_onRollOut, false, EventPriority.DEFAULT_HANDLER); titleBar.addEventListener(MouseEvent.ROLL_OVER, titleBar_onRollOver, false, EventPriority.DEFAULT_HANDLER); } protected function repositionButtons ():void { var uic:UIComponent; var tx:Number = 0; //target x value var px:Number = 0; //previous x value var ty:Number = 0; //target y value var i:int = 0; var l:int = _titleBarAssets.length; if (l == 0) return; for (i; i < l; i++){ uic = _titleBarAssets[i] as UIComponent; uic.setActualSize(uic.getExplicitOrMeasuredWidth(), uic.getExplicitOrMeasuredHeight()); if (i == 0){ tx = unscaledWidth - borderMetrics.right - uic.getExplicitOrMeasuredWidth() - 10; } else { tx = px - uic.getExplicitOrMeasuredWidth() - 5; } ty = (getHeaderHeight() - uic.getExplicitOrMeasuredHeight()) / 2; if (uic.x != tx || uic.y != ty) uic.move(tx, ty); px = tx; } } public function addTitleBarComponent (value:UIComponent = null):UIComponent { if (!value) value = new defaultTitleBarComponentClass(); value.addEventListener(MouseEvent.CLICK, titleBarComponent_defaultMouseEventHandler, false, EventPriority.DEFAULT_HANDLER); value.addEventListener(MouseEvent.MOUSE_DOWN, titleBarComponent_defaultMouseEventHandler, false, EventPriority.DEFAULT_HANDLER); value.addEventListener(MouseEvent.MOUSE_OUT, titleBarComponent_defaultMouseEventHandler, false, EventPriority.DEFAULT_HANDLER); value.addEventListener(MouseEvent.MOUSE_OVER, titleBarComponent_defaultMouseEventHandler, false, EventPriority.DEFAULT_HANDLER); value.addEventListener(MouseEvent.MOUSE_UP, titleBarComponent_defaultMouseEventHandler, false, EventPriority.DEFAULT_HANDLER); value.buttonMode = true; value.owner = this; _titleBarAssets.push(value); if (!titleBar){ _creationQueue.push(value); } else { titleBar.addChild(value); } return value; } /** * Clones a target mouse event but allows for the type to be set prior to cloning. * This method should be used only for capturing events fired from the titleBar area which * do not originate from any of its children. */ protected function createTitleBarMouseEvent (type:String, targetEvt:MouseEvent):MouseEvent { var evt:MouseEvent = new MouseEvent(type, targetEvt.bubbles, targetEvt.cancelable, targetEvt.localX, targetEvt.localY, targetEvt.relatedObject, targetEvt.ctrlKey, targetEvt.altKey, targetEvt.shiftKey, targetEvt.buttonDown, targetEvt.delta); return evt; } // // title bar button evt handlers //-----------------------------------------------------------// /** * TitleBar by default is setup to handle events as possible drag initiators while in popup modes. * In order to override that default behavior, the evt must stop propogation and be handled in a different manner so as not to * trigger a possible drag action. */ protected function titleBarComponent_defaultMouseEventHandler (evt:MouseEvent):void { evt.stopPropagation(); } // // title bar evt handlers //-----------------------------------------------------------// /** * Depending on the instantiation of this component, the titleBar may not be created yet when calling addTitleBarComponent(). * In order to avoid null pointer references, if a titleBarComponent is being added and the titleBar = null, the added child * is placed in the creation queue. TitleBar then references this queue and adds the components listed. */ protected function titleBar_onCreationComplete (evt:FlexEvent):void { var titleBarChild:UIComponent; var i:int = 0; var l:int = _creationQueue.length; for (i; i < l; i++){ titleBarChild = _creationQueue[i] as UIComponent; titleBar.addChild(titleBarChild); } _creationQueue = []; } protected function titleBar_onClick (evt:MouseEvent):void { dispatchEvent(createTitleBarMouseEvent(Pod.GRIP_CLICK, evt)); } /** * TitleBar has a predefined handler that acts on click events when a Pod is in popup mode. * titleBar_onMouseDown is used in order to receive and broadcast click events when in non-popup mode. */ protected function titleBar_onMouseDown (evt:MouseEvent):void { if (!isPopUp){ dispatchEvent(createTitleBarMouseEvent(Pod.GRIP_MOUSE_DOWN, evt)); } } protected function titleBar_onMouseMove (evt:MouseEvent):void { dispatchEvent(createTitleBarMouseEvent(Pod.GRIP_MOUSE_MOVE, evt)); } protected function titleBar_onMouseOut (evt:MouseEvent):void { dispatchEvent(createTitleBarMouseEvent(Pod.GRIP_MOUSE_OUT, evt)); } protected function titleBar_onMouseOver (evt:MouseEvent):void { dispatchEvent(createTitleBarMouseEvent(Pod.GRIP_MOUSE_OVER, evt)); } protected function titleBar_onMouseUp (evt:MouseEvent):void { dispatchEvent(createTitleBarMouseEvent(Pod.GRIP_MOUSE_UP, evt)); } protected function titleBar_onRollOut (evt:MouseEvent):void { dispatchEvent(createTitleBarMouseEvent(Pod.GRIP_ROLL_OUT, evt)); } protected function titleBar_onRollOver (evt:MouseEvent):void { dispatchEvent(createTitleBarMouseEvent(Pod.GRIP_ROLL_OVER, evt)); } public function get headerHeight ():Number { return getHeaderHeight(); } } }