Flex Spark Panel 扩展成 TitleBarPanel

来源:互联网 发布:淘宝内部优惠券图片 编辑:程序博客网 时间:2024/06/18 14:47

Summary:  由于Spark组件重新架构了,导致mx组件里的好多功能不能使用了。比如Panel: mx的Panel有titleBar,可以添加一些组件在titleBar里; 但在 spark的Panel上实现titleBar 要另辟其径了。   在网上search了半天,没有符合要求的。  只好去官方文档仔细阅读一下 spark组件的来龙去脉。 终于明白了,spark 框架的良苦用心。Requirement: 要求spark 的Panel 可以在使用时,任意地添加组件在title上,比如:Close Button, Refresh Button, Max Button等。Solution: 使用自定义的SparkSkin,扩展spark.components.Panel 控件, 添加 titleBarContent 属性。1. TitleBarPanelSkin 的代码如下:
<?xml version="1.0" encoding="utf-8"?><!--ADOBE SYSTEMS INCORPORATEDCopyright 2008 Adobe Systems IncorporatedAll Rights Reserved.NOTICE: Adobe permits you to use, modify, and distribute this filein 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"><fx:Metadata>[HostComponent("com.lombardrisk.common.components.panel.TitleBarPanel")]</fx:Metadata>        <fx:Script fb:purpose="styling">        <![CDATA[import mx.core.FlexVersion;/* Define the skin elements that should not be colorized.         For panel, border and title background are skinned, but the content area, background, border, and title text are not. */        static private const exclusions:Array = ["background", "titleDisplay", "contentGroup", "controlBarGroup", "border"];/* exclusions before Flex 4.5 for backwards-compatibility purposes */static private const exclusions_4_0:Array = ["background", "titleDisplay", "contentGroup", "controlBarGroup"];/** * @private */override public function get colorizeExclusions():Array {// Since border is styleable via borderColor, no need to allow chromeColor to affect// the border.  This is wrapped in a compatibility flag since this change was added  // in Flex 4.5if (FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_5){return exclusions_4_0;}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 = withControls ? cornerRadius : 0;                dropShadow.brRadius = withControls ? cornerRadius : 0;                                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 = includeBottom ? cornerRadius : 0;            target.bottomRightRadiusX = includeBottom ? cornerRadius : 0;        }                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 alpha="0"/>                </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="#FFFFFF"/>            </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" textAlign="start" fontWeight="bold">                </s:Label><s:HGroup id="titleBar"  right="2" top="3" />            </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>                                        <!-- layer 2: control bar fill -->                    <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>

2. TitelBarPanel 的 代码如下:

package com.topsli.common.components.panel{import mx.core.IVisualElement;import spark.components.Group;import spark.components.HGroup;import spark.components.Panel;public class TitleBarPanel extends Panel{[SkinPart(required="true")]public var titleBar:HGroup;public function TitleBarPanel(){super();}private var _titleBarContent:Array;[ArrayElementType("mx.core.IVisualElement")]public function get titleBarContent():Array{return _titleBarContent;}public function set titleBarContent(value:Array):void{_titleBarContent = value;}//add event listeners by overriding partAdded methodoverride protected function partAdded(partName:String, instance:Object):void{//call super methodsuper.partAdded(partName,instance);if(instance == titleBar){for each(var obj:Object in titleBarContent){titleBar.addElement(obj as IVisualElement);}}}}}



3. 使用TitleBarPanel时的 Example 如下:
<?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/halo"     minWidth="1024" minHeight="768"    xmlns:panel="com.topsli.common.components.*"><fx:Script><![CDATA[import mx.controls.Alert;protected function minBtn_clickHandler(event:MouseEvent):void{// TODO Auto-generated method stubAlert.show("Min Button on click.");}protected function maxBtn_clickHandler(event:MouseEvent):void{// TODO Auto-generated method stubAlert.show("Max Button on click.");}]]></fx:Script><panel:TitleBarPanel id="titlePanel" title="TitleBar Panel"    skinClass="com.topsli.common.components.TitleBarPanelSkin"   horizontalCenter="0"  bottom="20" width="300" height="400"><panel:titleBarContent><s:Button  label="Min" click="minBtn_clickHandler(event)" /><s:Button  label="Max" click="maxBtn_clickHandler(event)"/></panel:titleBarContent><s:Button x="50" y="100" id="myBtn1" label="Click Here" /></panel:TitleBarPanel></s:Application>

使用起来比较方便,只需要在titleBarContent里添加组件就可以了。 Spark组件的让我们扩展起来更为方便,有时间多了解一下spark组件的framework.

原创粉丝点击