package
{
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.geom.Rectangle;
import mx.controls.Alert;
import mx.core.Container;
import mx.core.IVisualElement;
import mx.core.UIComponent;
import mx.effects.Parallel;
import mx.events.EffectEvent;
import spark.components.Button;
import spark.components.Group;
import spark.components.Panel;
import spark.effects.Move;
import spark.effects.Resize;
import spark.effects.easing.Elastic;
import spark.effects.easing.IEaser;
//dispatched when max button is click
[Event(type="MySuperPanelEvent", name="max")]
//dispatched when titleBar is click
[Event(type="MySuperPanelEvent", name="min")]
//dispatched when restore button is click
[Event(type="MySuperPanelEvent", name="restore")]
/**
*
* @author jixin_huang
*/
public class MySuperPanel extends Panel
{
[SkinPart(required="false")]
/**
* 最大化按钮
* @default
*/
public var maxBtn:Button;
[SkinPart(required="false")]
/**
*
* @default
*/
public var restoreBtn:Button;
[SkinPart(required="false")]
/**
* 标题栏
* @default
*/
public var topGroup:Group;
/**
*
* @default
*/
protected var parallel:Parallel;
/**
*
* @default
*/
protected var resize:Resize;
/**
*
* @default
*/
protected var _move:Move;
/**
*
* @default
*/
protected var restoreRect:Rectangle;
[Bindable]
/**
* 最大化边距
* @default
*/
private var _maxGap:Number=5;
/**
*
* @default
*/
protected var flag:Boolean=false;
/**
*
* @default
*/
protected var isMinimized:Boolean=false;
/**
*
* @default
*/
protected var isMaximized:Boolean=false;
/**
*
*/
public function MySuperPanel()
{
//TODO: implement function
super();
//set defaults
setStyle("skinClass", MySuperPanelSkin);
parallel=new Parallel();
resize=new Resize();
_move=new Move();
parallel.addChild(resize);
parallel.addChild(_move);
}
/**
*
* @return
*/
public function get maxGap():Number
{
return _maxGap;
}
/**
*
* @param value
*/
public function set maxGap(value:Number):void
{
_maxGap=value;
}
/**
* 复原
* @param event
*/
protected function restoreBtnClickHandler(event:MouseEvent):void
{
resize.widthTo=restoreRect.width;
resize.heightTo=restoreRect.height;
_move.xTo=restoreRect.x;
_move.yTo=restoreRect.y;
parallel.play();
maxBtn.visible=maxBtn.enabled=true;
restoreBtn.visible=restoreBtn.enabled=false;
dispatchEvent(new MySuperPanelEvent("max"));
isMaximized=false;
topGroup.addEventListener(MouseEvent.MOUSE_DOWN, topGroupMouseDownHandler);
}
/**
* 最大化
* @param event
*/
protected function maxBtnClickHandler(event:MouseEvent):void
{
if (!restoreRect)
{
restoreRect=new Rectangle(x, y, this.width, this.height);
}
parallel.target=this;
parallel.duration=500;
resize.widthTo=this.parent.width - 2 * maxGap;
resize.heightTo=this.parent.height - 2 * maxGap;
_move.xTo=this.parent.x + maxGap;
_move.yTo=this.parent.y + maxGap;
parallel.play();
maxBtn.visible=maxBtn.enabled=false;
restoreBtn.visible=restoreBtn.enabled=true;
Group(this.parent).setElementIndex(this, Group(this.parent).numChildren - 1);
dispatchEvent(new MySuperPanelEvent("max"));
isMaximized=true;
isMinimized=false;
topGroup.removeEventListener(MouseEvent.MOUSE_DOWN, topGroupMouseDownHandler);
}
/**
*
* @param event
*/
protected function topGroupMouseDownHandler(event:MouseEvent):void
{
topGroup.addEventListener(MouseEvent.MOUSE_UP, topGroupMouseUpHandler);
topGroup.addEventListener(MouseEvent.MOUSE_MOVE, topGroupMouseMoveHandler);
}
/**
*
* @param event
*/
protected function topGroupMouseUpHandler(event:MouseEvent):void
{
topGroup.removeEventListener(MouseEvent.MOUSE_MOVE, topGroupMouseMoveHandler);
this.stopDrag();
if (this.y <= 0)
{
this.y=-this.height + 4;
this.addEventListener(MouseEvent.ROLL_OVER, rollOverHandler);
this.addEventListener(MouseEvent.ROLL_OUT, rollOutHandler);
}
else
{
this.removeEventListener(MouseEvent.ROLL_OVER, rollOverHandler);
this.removeEventListener(MouseEvent.ROLL_OUT, rollOutHandler);
/*if (!restoreRect)
{
restoreRect=new Rectangle(this.x, this.y, this.width, this.height);
}
else
{
restoreRect.x=this.x;
restoreRect.y=this.y;
}*/
}
}
/**
*
* @param event
*/
protected function topGroupMouseMoveHandler(event:MouseEvent):void
{
this.startDrag();
}
/**
*
* @param event
*/
protected function rollOverHandler(event:MouseEvent):void
{
this.y=-2;
}
/**
*
* @param event
*/
protected function rollOutHandler(event:MouseEvent):void
{
this.y=-this.height + 4;
}
/**
*
* @param event
*/
protected function topGroupDoubleClickHandler(event:MouseEvent):void
{
trace(topGroup.height + "");
if (isMinimized)
{
if (restoreRect)
{
this.height=restoreRect.height;
}
isMinimized=false;
}
else if (isMaximized)
{
this.height=restoreRect.height;
this.width=restoreRect.width;
this.x=restoreRect.x;
this.y=restoreRect.y;
isMaximized=false;
maxBtn.visible=maxBtn.enabled=true;
restoreBtn.visible=restoreBtn.enabled=false;
topGroup.addEventListener(MouseEvent.MOUSE_DOWN, topGroupMouseDownHandler);
}
else
{
if (!restoreRect)
{
restoreRect=new Rectangle(this.x, this.y, this.width, this.height);
}
this.height=topGroup.height;
isMinimized=true; //set minimized state;
}
}
/**
* override functions
*/
override protected function partAdded(partName:String, instance:Object):void
{
super.partAdded(partName, instance);
if (instance == topGroup)
{
topGroup.doubleClickEnabled=true;
topGroup.addEventListener(MouseEvent.DOUBLE_CLICK, topGroupDoubleClickHandler);
topGroup.addEventListener(MouseEvent.MOUSE_DOWN, topGroupMouseDownHandler);
}
if (instance == maxBtn)
{
maxBtn.addEventListener(MouseEvent.CLICK, maxBtnClickHandler);
}
if (instance == restoreBtn)
{
restoreBtn.addEventListener(MouseEvent.CLICK, restoreBtnClickHandler);
}
}
/**
*
* @param partName
* @param instance
*/
override protected function partRemoved(partName:String, instance:Object):void
{
super.partRemoved(partName, instance);
if (instance == topGroup)
{
topGroup.doubleClickEnabled=false;
topGroup.removeEventListener(MouseEvent.DOUBLE_CLICK, topGroupDoubleClickHandler);
}
if (instance == maxBtn)
{
maxBtn.removeEventListener(MouseEvent.CLICK, maxBtnClickHandler);
}
{
maxBtn.removeEventListener(MouseEvent.CLICK, restoreBtnClickHandler);
}
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<!--
ADOBE SYSTEMS INCORPORATED
Copyright 2008 Adobe Systems Incorporated
All Rights Reserved.
NOTICE: Adobe permits you to use, modify, and distribute this file
in accordance with the terms of the license agreement accompanying it.
-->
<!--- The default skin class for a Spark Panel container.
@see spark.components.Panel
@langversion 3.0
@playerversion Flash 10
@playerversion AIR 1.5
@productversion Flex 4
-->
<s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:fb="http://ns.adobe.com/flashbuilder/2009"
blendMode="normal"
mouseEnabled="false"
minWidth="131"
minHeight="127"
alpha.disabled="0.5"
alpha.disabledWithControlBar="0.5"
xmlns:mx="library://ns.adobe.com/flex/mx">
<fx:Metadata>[HostComponent("MySuperPanel")]</fx:Metadata>
<fx:Script fb:purpose="styling">
/* Define the skin elements that should not be colorized.
For panel, border and title background are skinned, but the content area and title text are not. */
static private const exclusions:Array=["background", "titleDisplay", "contentGroup", "controlBarGroup"];
/**
* @private
*/
override public function get colorizeExclusions():Array
{
return exclusions;
}
/**
* @private
*/
override protected function initializationComplete():void
{
useChromeColor=true;
super.initializationComplete();
}
/**
* @private
*/
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
if (getStyle("borderVisible") == true)
{
border.visible=true;
background.left=background.top=background.right=background.bottom=1;
contents.left=contents.top=contents.right=contents.bottom=1;
}
else
{
border.visible=false;
background.left=background.top=background.right=background.bottom=0;
contents.left=contents.top=contents.right=contents.bottom=0;
}
dropShadow.visible=getStyle("dropShadowVisible");
var cr:Number=getStyle("cornerRadius");
var withControls:Boolean=(currentState == "disabledWithControlBar" || currentState == "normalWithControlBar");
if (cornerRadius != cr)
{
cornerRadius=cr;
dropShadow.tlRadius=cornerRadius;
dropShadow.trRadius=cornerRadius;
dropShadow.blRadius=cornerRadius;
dropShadow.brRadius=cornerRadius;
setPartCornerRadii(topMaskRect, withControls);
setPartCornerRadii(border, withControls);
setPartCornerRadii(background, withControls);
}
if (bottomMaskRect)
setPartCornerRadii(bottomMaskRect, withControls);
borderStroke.color=getStyle("borderColor");
borderStroke.alpha=getStyle("borderAlpha");
backgroundFill.color=getStyle("backgroundColor");
backgroundFill.alpha=getStyle("backgroundAlpha");
super.updateDisplayList(unscaledWidth, unscaledHeight);
}
/**
* @private
*/
private function setPartCornerRadii(target:Rect, includeBottom:Boolean):void
{
target.topLeftRadiusX=cornerRadius;
target.topRightRadiusX=cornerRadius;
target.bottomLeftRadiusX=cornerRadius;
target.bottomRightRadiusX=cornerRadius;
}
private var cornerRadius:Number;
</fx:Script>
<s:states>
<s:State name="normal"/>
<s:State name="disabled"/>
<s:State name="normalWithControlBar"
stateGroups="withControls"/>
<s:State name="disabledWithControlBar"
stateGroups="withControls"/>
</s:states>
<!-- drop shadow can't be hittable so it stays sibling of other graphics -->
<!--- @private -->
<s:RectangularDropShadow id="dropShadow"
blurX="20"
blurY="20"
alpha="0.32"
distance="11"
angle="90"
color="#000000"
left="0"
top="0"
right="0"
bottom="0"/>
<!-- drop shadow can't be hittable so all other graphics go in this group -->
<s:Group left="0"
right="0"
top="0"
bottom="0">
<!-- top group mask -->
<!--- @private -->
<s:Group left="1"
top="1"
right="1"
bottom="1"
id="topGroupMask">
<!--- @private -->
<s:Rect id="topMaskRect"
left="0"
top="0"
right="0"
bottom="0">
<s:fill>
<s:SolidColor color="0xdae8eb"/>
</s:fill>
</s:Rect>
</s:Group>
<!-- bottom group mask -->
<!--- @private -->
<s:Group left="1"
top="1"
right="1"
bottom="1"
id="bottomGroupMask"
includeIn="normalWithControlBar, disabledWithControlBar">
<!--- @private -->
<s:Rect id="bottomMaskRect"
left="0"
top="0"
right="0"
bottom="0">
<s:fill>
<s:SolidColor alpha="0"/>
</s:fill>
</s:Rect>
</s:Group>
<!-- layer 1: border -->
<!--- @private -->
<s:Rect id="border"
left="0"
right="0"
top="0"
bottom="0">
<s:stroke>
<!--- @private -->
<s:SolidColorStroke id="borderStroke"
weight="1"/>
</s:stroke>
</s:Rect>
<!-- layer 2: background fill -->
<!--- Defines the appearance of the PanelSkin class's background. -->
<s:Rect id="background"
left="1"
top="1"
right="1"
bottom="1">
<s:fill>
<!--- @private
Defines the PanelSkin class's background fill. The default color is 0xFFFFFF. -->
<s:SolidColor id="backgroundFill"
color="#000000"/>
</s:fill>
</s:Rect>
<!-- layer 3: contents -->
<!--- Contains the vertical stack of titlebar content and controlbar. -->
<s:Group left="1"
right="1"
top="1"
bottom="1"
id="contents">
<s:layout>
<s:VerticalLayout gap="0"
horizontalAlign="justify"/>
</s:layout>
<!--- @private -->
<s:Group id="topGroup"
mask="{topGroupMask}">
<!-- layer 0: title bar fill -->
<!--- @private -->
<s:Rect id="tbFill"
left="0"
right="0"
top="0"
bottom="1">
<s:fill>
<s:LinearGradient rotation="90">
<s:GradientEntry color="0xE2E2E2"/>
<s:GradientEntry color="0xD9D9D9"/>
</s:LinearGradient>
</s:fill>
</s:Rect>
<!-- layer 1: title bar highlight -->
<!--- @private -->
<s:Rect id="tbHilite"
left="0"
right="0"
top="0"
bottom="0">
<s:stroke>
<s:LinearGradientStroke rotation="90"
weight="1">
<s:GradientEntry color="0xEAEAEA"/>
<s:GradientEntry color="0xD9D9D9"/>
</s:LinearGradientStroke>
</s:stroke>
</s:Rect>
<!-- layer 2: title bar divider -->
<!--- @private -->
<s:Rect id="tbDiv"
left="0"
right="0"
height="1"
bottom="0">
<s:fill>
<s:SolidColor color="0xC0C0C0"/>
</s:fill>
</s:Rect>
<!-- layer 3: text -->
<!--- @copy spark.components.Panel#titleDisplay -->
<s:Label id="titleDisplay"
maxDisplayedLines="1"
left="9"
right="3"
top="1"
bottom="0"
minHeight="30"
verticalAlign="middle"
fontWeight="bold">
</s:Label>
<s:Button id="maxBtn"
skinClass="MaxBtnSkin"
verticalCenter="0"
right="4"/>
<s:Button id="restoreBtn"
visible="false"
enabled="false"
skinClass="RestoreBtnSkin"
verticalCenter="0"
right="4"/>
</s:Group>
<!--
Note: setting the minimum size to 0 here so that changes to the host component's
size will not be thwarted by this skin part's minimum size. This is a compromise,
more about it here: http://bugs.adobe.com/jira/browse/SDK-21143
-->
<!--- @copy spark.components.SkinnableContainer#contentGroup -->
<s:Group id="contentGroup"
width="100%"
height="100%"
minWidth="0"
minHeight="0">
</s:Group>
<!--- @private -->
<s:Group id="bottomGroup"
minWidth="0"
minHeight="0"
includeIn="normalWithControlBar, disabledWithControlBar">
<s:Group left="0"
right="0"
top="0"
bottom="0"
mask="{bottomGroupMask}">
<!-- layer 0: control bar divider line -->
<s:Rect left="0"
right="0"
top="0"
height="1"
alpha="0.22">
<s:fill>
<s:SolidColor color="0x000000"/>
</s:fill>
</s:Rect>
<!-- layer 1: control bar highlight -->
<s:Rect left="0"
right="0"
top="1"
bottom="0">
<s:stroke>
<s:LinearGradientStroke rotation="90"
weight="1">
<s:GradientEntry color="0xE5E5E5"/>
<s:GradientEntry color="0xD8D8D8"/>
</s:LinearGradientStroke>
</s:stroke>
</s:Rect>
<s:Rect left="1"
right="1"
top="2"
bottom="1">
<s:fill>
<s:LinearGradient rotation="90">
<s:GradientEntry color="0xDADADA"/>
<s:GradientEntry color="0xC5C5C5"/>
</s:LinearGradient>
</s:fill>
</s:Rect>
</s:Group>
<!-- layer 3: control bar -->
<!--- @copy spark.components.Panel#controlBarGroup -->
<s:Group id="controlBarGroup"
left="0"
right="0"
top="1"
bottom="1"
minWidth="0"
minHeight="0">
<s:layout>
<s:HorizontalLayout paddingLeft="10"
paddingRight="10"
paddingTop="7"
paddingBottom="7"
gap="10"/>
</s:layout>
</s:Group>
</s:Group>
</s:Group>
</s:Group>
</s:SparkSkin>
<?xml version="1.0" encoding="utf-8"?>
<s:Skin xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:fx="http://ns.adobe.com/mxml/2009">
<fx:Metadata>[HostComponent("spark.components.Button")]</fx:Metadata>
<s:states>
<s:State name="up"/>
<s:State name="over"/>
<s:State name="down"/>
<s:State name="disabled"/>
</s:states>
<s:Path data="M 18.5 16.5 C 18.5 17.605 17.605 18.5 16.5 18.5 L 2.5 18.5 C 1.396 18.5 0.5 17.605 0.5 16.5 L 0.5 2.5 C 0.5 1.396 1.396 0.5 2.5 0.5 L 16.5 0.5 C 17.605 0.5 18.5 1.396 18.5 2.5 L 18.5 16.5 Z"
winding="nonZero"
x="0"
y="0">
<s:stroke.over>
<s:SolidColorStroke caps="none"
joints="miter"
miterLimit="4"
weight="1"/>
</s:stroke.over>
<s:stroke.down>
<s:SolidColorStroke caps="none"
joints="miter"
miterLimit="4"
weight="1"/>
</s:stroke.down>
<s:stroke.disabled>
<s:SolidColorStroke caps="none"
joints="miter"
miterLimit="4"
weight="1"/>
</s:stroke.disabled>
<s:fill>
<s:SolidColor color="0xffffff"
alpha="0"
alpha.over="0.5"/>
</s:fill>
</s:Path>
<s:Rect height="8"
width="10"
x="4"
y="6">
<s:stroke>
<s:SolidColorStroke color="0x012012"
caps="none"
joints="{JointStyle.ROUND}"
miterLimit="4"
weight="1.5"/>
</s:stroke>
</s:Rect>
</s:Skin>
<s:Skin xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:fx="http://ns.adobe.com/mxml/2009">
<fx:Metadata>[HostComponent("spark.components.Button")]</fx:Metadata>
<s:states>
<s:State name="up"/>
<s:State name="over"/>
<s:State name="down"/>
<s:State name="disabled"/>
</s:states>
<s:Path data="M 18.5 16.5 C 18.5 17.605 17.605 18.5 16.5 18.5 L 2.5 18.5 C 1.396 18.5 0.5 17.605 0.5 16.5 L 0.5 2.5 C 0.5 1.396 1.396 0.5 2.5 0.5 L 16.5 0.5 C 17.605 0.5 18.5 1.396 18.5 2.5 L 18.5 16.5 Z"
winding="nonZero"
x="0"
y="0">
<s:stroke.over>
<s:SolidColorStroke caps="none"
joints="miter"
miterLimit="4"
weight="1"/>
</s:stroke.over>
<s:stroke.down>
<s:SolidColorStroke caps="none"
joints="miter"
miterLimit="4"
weight="1"/>
</s:stroke.down>
<s:stroke.disabled>
<s:SolidColorStroke caps="none"
joints="miter"
miterLimit="4"
weight="1"/>
</s:stroke.disabled>
<s:fill>
<s:SolidColor color="0xffffff"
alpha="0"
alpha.over="0.5"/>
</s:fill>
</s:Path>
<s:Rect height="8"
width="8"
x="3"
y="8">
<s:stroke>
<s:SolidColorStroke caps="none"
joints="miter"
miterLimit="4"
weight="2"/>
</s:stroke>
</s:Rect>
<s:Rect height="8"
width="8"
x="8"
y="3">
<s:stroke>
<s:SolidColorStroke caps="none"
joints="miter"
miterLimit="4"
weight="2"/>
</s:stroke>
</s:Rect>
</s:Skin>
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
minWidth="955"
minHeight="600"
xmlns:local="*">
<fx:Style>
@namespace s "library://ns.adobe.com/flex/spark";
@namespace mx "library://ns.adobe.com/flex/mx";
@namespace local "*";
s|Application{
background-color:#000000;
}
</fx:Style>
<fx:Declarations>
<!-- 将非可视元素(例如服务、值对象)放在此处 -->
</fx:Declarations>
<!--<local:FxWindow x="55"
y="195"
width="330"
height="250">
</local:FxWindow>-->
<local:MySuperPanel title="超级面板"
x="296"
y="55"
width="219"
height="467"
cornerRadius="4"
maxGap="20">
<local:filters>
<s:GlowFilter color="0xaebfed"
blurX="20"
blurY="20"/>
</local:filters>
</local:MySuperPanel>
</s:Application>