package FlashChat { import flash.events.Event; import flash.events.MouseEvent; import flash.geom.Point; import mx.containers.TitleWindow; import mx.controls.Button; import mx.core.EdgeMetrics; import mx.core.FlexVersion; import mx.core.mx_internal; import mx.events.ResizeEvent; import mx.managers.CursorManager; import mx.managers.CursorManagerPriority; import mx.managers.ISystemManager; import mx.states.State; import mx.styles.StyleProxy; import utilityClasses.DiagonalResizeCursor; import utilityClasses.HorizontalResizeCursor; import utilityClasses.RotatedDiagonalResizeCursor; import utilityClasses.VerticalResizeCursor; use namespace mx_internal; /** * Dispatched when the user selects the maximize button. */ [Event(name="minimize", type="flash.events.Event")] /** * The minimize button default skin. * * @default null */ [Style(name="minimizeButtonSkin", type="Class", inherit="no", states="up, over, down, disabled")] /** * The minimize button disabled skin. * * @default MinimizeButtonDisabled */ [Style(name="minimizeButtonDisabledSkin", type="Class", inherit="no")] /** * The minimize button down skin. * * @default MinimizeButtonDown */ [Style(name="minimizeButtonDownSkin", type="Class", inherit="no")] /** * The minimize button over skin. * * @default MinimizeButtonOver */ [Style(name="minimizeButtonOverSkin", type="Class", inherit="no")] /** * The minimize button up skin. * * @default MinimizeButtonUp */ [Style(name="minimizeButtonUpSkin", type="Class", inherit="no")] public class ResizableTitleWindow extends TitleWindow { static private var EDGE_NONE : Number = 0; static private var EDGE_BOTTOM : Number = 1; static private var EDGE_RIGHT : Number = 2; static private var EDGE_LEFT : Number = 3; static private var EDGE_TOP : Number = 4; static private var EDGE_CORNER : Number = 5; static private var EDGE_LEFT_BOTTOM : Number = 6; static private var EDGE_LEFT_TOP : Number = 7; static private var EDGE_RIGHT_TOP : Number = 8; //Added for flashChat private var originalSize : Object = null; /** * @private */ //-------------------------------------------------------------------------- // Various States of the window //-------------------------------------------------------------------------- /** * @private */ private var stateNormal:State; /** * @private */ private var stateMin:State; private var minimizeButton:Button; private var _useDefaultMinimizeAction:Boolean = true; public function get useDefaultMinimizeAction():Boolean { return _useDefaultMinimizeAction; } public function set useDefaultMinimizeAction(value:Boolean):void { _useDefaultMinimizeAction = value; } private var _minimizable:Boolean = false; public function get minimizable():Boolean { return _minimizable; } public function set minimizable(value:Boolean):void { _minimizable = value; invalidateDisplayList(); } private var _closeable:Boolean = true; public function get closeable():Boolean { return _closeable; } public function set closeable(value:Boolean):void { _closeable = value; invalidateDisplayList(); } protected function get minimizeButtonStyleFilters():Object { return _minimizeButtonStyleFilters; } private static var _minimizeButtonStyleFilters:Object = { "minimizeButtonUpSkin" : "minimizeButtonUpSkin", "minimizeButtonOverSkin" : "minimizeButtonOverSkin", "minimizeButtonDownSkin" : "minimizeButtonDownSkin", "minimizeButtonDisabledSkin" : "minimizeButtonDisabledSkin", "minimizeButtonSkin" : "minimizeButtonSkin", "repeatDelay" : "repeatDelay", "repeatInterval" : "repeatInterval" }; override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void{ super.updateDisplayList(unscaledWidth,unscaledHeight); } override protected function createChildren():void{ super.createChildren(); storeOrigDimensions(); stateNormal = new State(); stateNormal.name = "normal"; stateMin = new State(); stateMin.name = "minimized"; states.push(stateMin); states.push(stateNormal); if (titleBar) { titleBar.height = getHeaderHeight(); showCloseButton = closeable; if (!minimizeButton && minimizable) { minimizeButton = new Button(); minimizeButton.styleName = new StyleProxy(this, minimizeButtonStyleFilters); minimizeButton.upSkinName = "minimizeButtonUpSkin"; minimizeButton.overSkinName = "minimizeButtonOverSkin"; minimizeButton.downSkinName = "minimizeButtonDownSkin"; minimizeButton.disabledSkinName = "minimizeButtonDisabledSkin"; minimizeButton.skinName = "minimizeButtonSkin"; minimizeButton.explicitWidth = 16; minimizeButton.explicitHeight = 16; minimizeButton.visible = true; minimizeButton.enabled = true;//enabled && parent is IUIComponent; minimizeButton.focusEnabled = false; minimizeButton.addEventListener(MouseEvent.CLICK, titleBar_mouseClickHandler); // Add the minimize button on top of the title/status. titleBar.addChild(minimizeButton); minimizeButton.owner = this; } } } /** * @private */ private function titleBar_mouseClickHandler(event:MouseEvent):void { if(this.parent!=null && event is MouseEvent) { if(event.type == MouseEvent.CLICK) { //State Automata between minimized/maximized/normal states if(event.target == minimizeButton) { if(currentState == "minimized") { setState(stateNormal.name); } else { setState(stateMin.name); } } event.preventDefault(); } } } public function setState(stateName: String): void { setCurrentState(stateName); switch (stateName) { case 'minimized': if (useDefaultMinimizeAction) { originalSize = {w: width, h: height}; height = getHeaderHeight(); } break; case 'normal': if (originalSize && useDefaultMinimizeAction) { height = originalSize.h; width = originalSize.w; } break; default: break; } dispatchEvent(new Event(stateName)); } override protected function layoutChrome(unscaledWidth:Number, unscaledHeight:Number):void { super.layoutChrome(unscaledWidth,unscaledHeight); var w: Number, h: Number; var headerHeight:Number = getHeaderHeight(); var maxButtonHeight: Number = 0; maxButtonHeight = Math.max(maxButtonHeight, closeButton.getExplicitOrMeasuredHeight()); var vm:EdgeMetrics = FlexVersion.compatibilityVersion < FlexVersion.VERSION_3_0 ? borderMetrics : EdgeMetrics.EMPTY; var gap:uint = vm.right; var x:uint=0; var y:uint = Math.round(( headerHeight - maxButtonHeight ) / 2 ); x = unscaledWidth - vm.right; gap = 5; if(closeable) { w = closeButton.getExplicitOrMeasuredWidth(); h = closeButton.getExplicitOrMeasuredHeight(); closeButton.setActualSize(w, h); x = closeButton.x; closeButton.move(x,y); } if(minimizable) { w = minimizeButton.getExplicitOrMeasuredWidth(); h = minimizeButton.getExplicitOrMeasuredHeight(); minimizeButton.setActualSize(w, h); x -= (w+gap); minimizeButton.move( x, y ); } } /*----------------------------------------*/ /** * @private * CursorSymbol used to display Vertical Resize Cursor */ private var vCursorSymbol:Class = VerticalResizeCursor; /** * @private * CursorSymbol used to display Horizontal Resize Cursor */ private var hCursorSymbol:Class = HorizontalResizeCursor; /** * @private * CursorSymbol used to display Diagonal Resize Cursor */ private var dCursorSymbol:Class = DiagonalResizeCursor; /** * @private * CursorSymbol used to display Rotated Diagonal Resize Cursor */ private var rdCursorSymbol:Class = RotatedDiagonalResizeCursor; /** * @private */ private var cursorId:Number=0; /** * @private */ private var isHandleDragging : Boolean = false; /** * @private */ private var lastEdge:Number=0; /** * @private */ private var handleEdge : Number = EDGE_NONE; /** * @private */ private var origPosition:Point; /** * @private */ private var origDimensions:Point; /** * @private */ private var origPerDimensions:Point; public function ResizableTitleWindow():void { super(); setStyle("resizeAffordance",6); addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler,true); addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler,false); addEventListener(MouseEvent.MOUSE_MOVE, systemManager_mouseMoveHandler); addEventListener(MouseEvent.CLICK, bringToFront,false); addEventListener(MouseEvent.ROLL_OUT, systemManager_mouseMoveHandler); minWidth = Math.max(minWidth, 30); minHeight = Math.max(minHeight, 100); } private function bringToFront(e:MouseEvent):void { } /** * @private */ private function mouseDownHandler(event:MouseEvent):void { systemManager.addEventListener( MouseEvent.MOUSE_MOVE, systemManager_mouseMoveHandler, true); systemManager.addEventListener( MouseEvent.MOUSE_UP, systemManager_mouseUpHandler, true); systemManager_mouseDownHandler(event); } /** * @private */ private function systemManager_mouseDownHandler(event:MouseEvent):void { if(handleEdge != EDGE_NONE) { isHandleDragging = true; event.stopPropagation(); } } /** * @private */ private function systemManager_mouseMoveHandler(event:MouseEvent):void { if(this.parent!=null) { if(isHandleDragging) resize(event); else setResizeCursor(event); } } /** * @private */ private function systemManager_mouseUpHandler(event:MouseEvent):void { systemManager.removeEventListener(MouseEvent.MOUSE_MOVE, systemManager_mouseMoveHandler, true); systemManager.removeEventListener(MouseEvent.MOUSE_UP, systemManager_mouseUpHandler, true); systemManager.removeEventListener(MouseEvent.MOUSE_DOWN, systemManager_mouseDownHandler, true); isHandleDragging = false; } /** * @private */ private function isCursorOnEdge(event:MouseEvent):void { if ('minimized' == currentState) { handleEdge = EDGE_NONE; return; } var point:Point, eventPoint:Point; var x1:Number, x2:Number, y1:Number, y2:Number; var tolerance:Number = getStyle("resizeAffordance") as Number; point = new Point(x,y); point = this.parent.localToGlobal(point); eventPoint = new Point(event.stageX, event.stageY); //Distance from right edge x1 = eventPoint.x - this.width - point.x; //Distance from left edge x2 = eventPoint.x-point.x; //Distance from bottom edge y1 = eventPoint.y - this.height-point.y; //Distance from top edge y2 = eventPoint.y - point.y; if (event.type == "rollOut") { handleEdge = EDGE_NONE; } else { handleEdge = EDGE_NONE; if(handleEdge == EDGE_NONE) { if(Math.abs(x1) < tolerance && Math.abs(y1) < tolerance) handleEdge = EDGE_CORNER; else if(Math.abs(x1) < tolerance && Math.abs(y2) < tolerance) handleEdge = EDGE_RIGHT_TOP; else if(Math.abs(x2) < tolerance && Math.abs(y2) < tolerance) handleEdge = EDGE_LEFT_TOP; else if(Math.abs(x2) < tolerance && Math.abs(y1) < tolerance) handleEdge = EDGE_LEFT_BOTTOM; else if(Math.abs(y1) < tolerance) handleEdge = EDGE_BOTTOM; else if(Math.abs(x1) < tolerance) handleEdge = EDGE_RIGHT; else if(Math.abs(x2) < tolerance) handleEdge = EDGE_LEFT; else if(Math.abs(y2) < tolerance) handleEdge = EDGE_TOP; } } } /** * @private */ private function resize(event:MouseEvent):void { var newWidth:Number, newHeight:Number; var point:Point = new Point(x,y); point = this.parent.localToGlobal(point); var eventPoint:Point = new Point(event.stageX, event.stageY); if (handleEdge == EDGE_BOTTOM) setSize(point.x,point.y,width, eventPoint.y-point.y); else if(handleEdge == EDGE_RIGHT) setSize(point.x,point.y,eventPoint.x-point.x, height); else if(handleEdge == EDGE_LEFT) setSize(eventPoint.x,point.y, point.x-eventPoint.x+width, height); else if(handleEdge == EDGE_TOP) setSize(point.x,eventPoint.y, width, point.y-eventPoint.y+height); else if(handleEdge == EDGE_CORNER) setSize(point.x,point.y,eventPoint.x-point.x, eventPoint.y-point.y); else if(handleEdge == EDGE_LEFT_TOP) setSize(eventPoint.x, eventPoint.y, point.x-eventPoint.x+width, point.y-eventPoint.y+height); else if(handleEdge == EDGE_LEFT_BOTTOM) setSize(eventPoint.x, point.y, point.x-eventPoint.x+width, eventPoint.y - point.y); else if(handleEdge == EDGE_RIGHT_TOP) setSize(point.x, eventPoint.y, eventPoint.x - point.x, point.y-eventPoint.y+height); } /** * @private */ private function setSize(newX:Number,newY:Number,newWidth:Number, newHeight:Number):void { if (newWidth < minWidth) { newWidth = minWidth; } if (newHeight < minHeight) { newHeight = minHeight; } var point:Point = new Point(newX, newY); point = this.parent.globalToLocal(point); x = point.x; y = point.y; width = newWidth; height = newHeight; storeOrigDimensions(); } /** * @private */ private function storeOrigDimensions():void { origPosition = new Point(); origDimensions = new Point(); origPerDimensions = new Point(); //In case this is a Pop up, special care is needed if (parent is ISystemManager) { origPosition.x = parent.x; origPosition.y = parent.y; origPosition = this.localToGlobal(origPosition); } else { origPosition.x = x; origPosition.y = y; } if(percentWidth) origPerDimensions.x = percentWidth; else origDimensions.x = getExplicitOrMeasuredWidth() ; if(percentHeight) origPerDimensions.y = percentHeight; else origDimensions.y = getExplicitOrMeasuredHeight(); } /** * @private */ private function setResizeCursor(event:MouseEvent):void { isCursorOnEdge(event); if (handleEdge != EDGE_NONE) { if(cursorId==0 || lastEdge != handleEdge) { if(lastEdge != handleEdge) { CursorManager.removeCursor(cursorId); cursorId=0; } if(handleEdge == EDGE_CORNER || handleEdge == EDGE_LEFT_TOP) cursorId=CursorManager.setCursor(dCursorSymbol, CursorManagerPriority.HIGH); else if(handleEdge == EDGE_LEFT_BOTTOM || handleEdge == EDGE_RIGHT_TOP) cursorId=CursorManager.setCursor(rdCursorSymbol, CursorManagerPriority.HIGH); else if(handleEdge == EDGE_RIGHT || handleEdge == EDGE_LEFT) cursorId=CursorManager.setCursor(hCursorSymbol, CursorManagerPriority.HIGH); else if(handleEdge == EDGE_BOTTOM || handleEdge == EDGE_TOP) cursorId=CursorManager.setCursor(vCursorSymbol, CursorManagerPriority.HIGH); lastEdge = handleEdge; } } else { if(cursorId!=0) { CursorManager.removeCursor(cursorId); cursorId=0; lastEdge = EDGE_NONE; } } } } }