All pastes #422745 Raw Edit

Stuff

public text v1 · immutable
·published 2007-04-03 17:38 UTC
rendered paste body
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();
		}
	}
}