Forums Développement Multimédia

Les formations Mediabox
Les formations Mediabox

Le conteneur Spark Panel

Compatible Flex 4. Cliquer pour en savoir plus sur les compatibilités.Compatible ActionScript 3. Cliquer pour en savoir plus sur les compatibilités.Par tannoy (Antony Chauviré), le 27 mai 2010

Cet article est une traduction de l'aide Adobe Flex.

Adobe a donné son accord concernant la traduction de la documentation.

Présentation

Le conteneur Panel inclut une barre de titre, un titre, une bordure, et une zone de contenu pour ses enfants. Vous utilisez fréquemment des conteneurs Panel pour séparer différents modules de votre application. Par exemple, vous pouvez définir plusieurs conteneurs Panel dans votre application où un premier Panel contiendrait un formulaire, un second contiendrait un panier d'achat et un troisième contiendrait un catalogue.

La mise en page par défaut du conteneur Panel est BasicLayout. L'image suivante montre un conteneur Panel avec une mise en page verticale:

Pour une information complète sur la référence de langage, regardez ActionScript 3.0 Reference for the Adobe Flash Platform.

Création d'un conteneur Spark Panel

Vous utilisez la balise <s:Panel> pour définir un conteneur Panel. Spécifiez une valeur à la propriété id si vous souhaitez utiliser votre contrôle ailleurs dans une balise MXML ou dans un bloc ActionScript.

L'exemple suivant définit un conteneur Panel contenant un formulaire en haut de l'application. Dans cet exemple, le conteneur Panel vous offre un mécanisme permettant d'intégrer une barre de titre, comme dans une fenêtre d'interface standard.

<?xml version="1.0" encoding="utf-8"?>
<!-- containers\spark\SparkPanelSimple.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark" > 
 
    <s:Panel id="myPanel" title="My Application" x="20" y="20">
        <mx:Form id="myForm" width="400">
 
            <mx:FormHeading label="Billing Information"/>
 
            <mx:FormItem label="First Name">
                <s:TextInput id="fname" width="100%"/>
            </mx:FormItem>
 
            <mx:FormItem label="Last Name">
                <s:TextInput id="lname" width="100%"/>
            </mx:FormItem>
 
            <mx:FormItem label="Address">
                <s:TextInput id="addr1" width="100%"/>
                <s:TextInput id="addr2" width="100%"/>
            </mx:FormItem>
 
            <mx:FormItem label="City / State" direction="vertical">
                <s:TextInput id="city"/>
                <s:TextInput id="state"/>
            </mx:FormItem>
 
            <mx:FormItem label="ZIP Code">
                <s:TextInput id="zip" width="100"/>
            </mx:FormItem>
 
            <mx:FormItem>
                <mx:HRule width="200" height="1"/>
                <s:Button label="Submit Form"/>
            </mx:FormItem>
        </mx:Form>
    </s:Panel>
</s:Application>

Le fichier SWF de l'exemple ci-dessus est affiché ci-dessous :

L"extension Adobe Flash Plugin est nécessaire pour afficher ce contenu.

Ajout d'une barre de contrôle au conteneur Spark Panel

Une barre de contrôle contient un groupe de contrôles en dehors de la zone de contenu du conteneur Spark Panel. La barre de contrôle est toujours visible en bas du conteneur Panel. Par conséquent, si le conteneur Panel utilise les barres de défilement, la barre de contrôle n'est pas défilée avec et reste fixe, au contraire du conteneur des autres enfants.

Définissez la propriété controlBarVisible sur true (valeur par défaut) pour rendre la barre de contrôle visible. Vous utilisez la propriété Panel.controlBarContent pour définir les contrôles qui apparaissent à l'intérieur de la barre de contrôle, comme le montre l'exemple suivant:

<?xml version="1.0" encoding="utf-8"?>
<!-- containers\spark\SparkPanelCB.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark"
    width="750">
    <s:layout>
        <s:VerticalLayout/>
    </s:layout>
 
    <fx:Script>
        <![CDATA[
            import mx.controls.Alert;
        ]]>
    </fx:Script>
 
    <fx:Declarations>
        <fx:XMLList id="menuXML">
            <fx:menuitem label="File">
                <fx:menuitem label="New" data="New"/>
                <fx:menuitem label="Open" data="Open"/>
                <fx:menuitem label="Save" data="Save"/>
                <fx:menuitem label="Exit" data="Exit"/>
            </fx:menuitem>
            <fx:menuitem label="Edit">
                <fx:menuitem label="Cut" data="Cut"/>
                <fx:menuitem label="Copy" data="Copy"/>
                <fx:menuitem label="Paste" data="Paste"/>
            </fx:menuitem>
            <fx:menuitem label="View"/>
        </fx:XMLList>
 
        <fx:Array id="cmbDP">
            <fx:String>Item 1</fx:String>
            <fx:String>Item 2</fx:String>
            <fx:String>Item 3</fx:String>
        </fx:Array>
    </fx:Declarations>
 
    <s:Panel title="Spark Panel">
        <s:layout>
            <s:VerticalLayout/>
        </s:layout>
        <s:controlBarContent>
            <mx:MenuBar height="100%" 
                dataProvider="{menuXML}" 
                labelField="@label" 
                showRoot="true"/>
            <mx:HBox paddingBottom="5" 
                 paddingTop="5">
                <mx:ComboBox dataProvider="{cmbDP}"/>
                <mx:Spacer width="100%"/>
                <mx:TextInput id="myTI" text=""/>
                <mx:Button id="srch1" 
                    label="Search" 
                    click="Alert.show('Searching');"/>
            </mx:HBox>
        </s:controlBarContent>        
 
        <s:Button label="Button"/>
        <s:TextArea width="300" height="200"/>        
    </s:Panel>    
</s:Application>

Le fichier SWF de l'exemple ci-dessus est affiché ci-dessous :

L"extension Adobe Flash Plugin est nécessaire pour afficher ce contenu.

Par défaut, les contrôles de la barre de contrôle sont positionnés par une mise en page de type HorizontalLayout. Utilisez la propriété Panel.controlBarLayout pour spécifier une mise en page différente, comme le montre le code suivant:

<s:controlBarLayout> 
    <s:HorizontalLayout paddingLeft="12" gap="5"/> 
</s:controlBarLayout>

La position et l'apparence de la barre de contrôle du conteneur Panel sont déterminées par la classe spark.skins.spark.PanelSkin, la classe de skin du conteneur Panel. Par défaut, la classe PanelSkin positionne la barre de contrôle en bas de la zone de contenu du conteneur Panel et lui donne un arrière-plan gris. Vous pouvez créer une skin personnalisée pour changer l'apparence par défaut de la barre de contrôle.

Création d'une skin personnalisée

Pour créer une skin personnalisée, nous allons créer une classe qui étendra la classe spark.skins.SparkSkin. Nous allons copier le code de la classe spark.skins.spark.PanelSkin afin de partir de la version de par défaut pour créer notre skin.

Voici le code initial correspondant au contenu de la skin par défaut.

<?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>
        <![CDATA[ 
        /** 
         * @copy spark.skins.spark.ApplicationSkin#hostComponent
         */
        [HostComponent("spark.components.Panel")]
        ]]>
    </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 = 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: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>

Nous allons modifier la présentation de notre panel afin que la barre de contrôle soit positionnée sous la barre de titre.

Les éléments principaux du conteneur Panel (barre de titre, barre de contrôle et zone de contenu) sont affichés dans un conteneur Group dont la propriété id a pour valeur contents.

        <!-- layer 3: contents -->
        <!--- Contains the vertical stack of titlebar content and controlbar. -->
        <s:Group left="1" right="1" top="1" bottom="1" id="contents">

Ce conteneur possède une propriété layout de type VerticalLayout qui positionne ses enfants les uns sous les autres. Nous allons donc déplacer le conteneur Group, dont la 'propriété id a pour valeur bottomGroup, au dessus du conteneur Group dont la propriété id a pour valeur contentGroup.

<!--- @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>
 
<!--
    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>

Nous allons ensuite modifier le dégradé utilisé pour l'arrière-plan de la barre de contrôle comme le montre l'exemple suivant:

<!-- layer 2: control bar fill -->
<s:Rect left="1" right="1" top="2" bottom="1">
	<s:fill>
		<s:LinearGradient rotation="90">
			<s:GradientEntry color="0x66666" />
			<s:GradientEntry color="0x999999" />
		</s:LinearGradient>
	</s:fill>
</s:Rect>

Nous définirons ensuite la propriété skinClass de notre Panel pour utiliser notre skin personnalisée.

<s:Panel title="Spark Panel" skinClass="CustomPanelSkin">

Le fichier SWF de l'exemple ci-dessus est affiché ci-dessous :

L"extension Adobe Flash Plugin est nécessaire pour afficher ce contenu.