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();
}
}
}