加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

Flex Spark Panel 扩展成 TitleBarPanel

发布时间:2020-12-15 05:12:08 所属栏目:百科 来源:网络整理
导读:Summary: ?由于Spark组件重新架构了,导致mx组件里的好多功能不能使用了。比如Panel: mx的Panel有titleBar,可以添加一些组件在titleBar里; 但在 spark的Panel上实现titleBar 要另辟其径了。 ? 在网上search了半天,没有符合要求的。 ?只好去官方文档仔细

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 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">
	<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","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.5
			if (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 method
		override protected function partAdded(partName:String,instance:Object):void
		{
			//call super method
			super.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 stub
				Alert.show("Min Button on click.");
			}
			
			protected function maxBtn_clickHandler(event:MouseEvent):void
			{
				// TODO Auto-generated method stub
				Alert.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.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读