# Spark SkinnableContainer - Functional and Design Specification
----
## Summary and Background
----
**graphic element** - A graphical element like a Rectangle, Path, or Bitmap. This element is not a subclass of DisplayObject; however, it does need a DisplayObject to render on to.
**visual element** - A visual element (a.k.a. - "element"). This can be a halo component, a gumbo component, or a **graphic element**. Visual elements implement `IVisualElement`.
**data item** (a.k.a. - "item") - Basically anything is considered a data item. Mostly it refers to a non-visual item like a String, Number, XMLNode, etc. A visual element can also be a data item--it just depends on how it's treated.
**}SkinnableContainer** \- A skinnable component with chrome that holds and lays out visual elements. It also serves as a base class for other skinnable visual containers. For example, [Panel](Panel) is a subclass of SkinnableContainer that has a border, header, and footer.
**}SkinnableDataContainer** \- A skinnable component with chrome that holds and lays out data items and supports virtualization. It also serves as a base class for other skinnable data containers. For example, List is a subclass of SkinnableDataContainer that adds support for selection, mouse handling, and key handling.
## Usage Scenario
----
The first example shows using SkinnableContainer as a container to show visual elements. The second example extends SkinnableContainer to create a Panel.
### Example 1: Displaying visual children in SkinnableContainer
<s:skinnablecontainer skinclass="mySkin">
<s:layout><s:verticallayout horizontalalign="center"></s:verticallayout></s:layout>
<s:rect>
....
</s:rect>
<s:button ...="">
<s:button ...="">
</s:button></s:button></s:skinnablecontainer>
### Example 2: Panel Component
public class Panel extends SkinnableContainer {
// The content and layout properties are inherited from SkinnableContainer.
// Panel doesn't add much other functionality beyond what's in SkinnableContainer
// Skin parts. The Panel class has one new parts: titleField. This is where
// the header's title goes
SkinPart(required="true")
/**
* The skin part that defines the appearance of the
* title text in the container.
*/
public var titleField:TextGraphicElement;
/**
* Title or caption displayed in the title bar.
*/
public var title:String;
// This function is called when the skin part is loaded and assigned.
override protected function partAdded(partName:String, instance:*):void
{
// Assign the content to the header and footer. The main content
// assignment is done in the superclass (SkinnableContainer)
super.partAdded(partName, instance);
if (instance == titleField)
{
titleField.text = title;
}
}
}
## Detailed Description
----
### SkinnableContainer
The SkinnableContainer class is basically a [Spark Group](Spark%20Group) with skinnable chrome. More precisely, it is an SkinnableComponent with a skin file that contains a contentGroup. It has one SkinPart named `contentGroup`, and it proxies the content and layout functionality of the `contentGroup` skin part. See the API Description section for details. Because of this, SkinnableContainer has non-content children and is skinnable, while Group can only contain content children.
## API Description
----
### SkinnableContainer
Most of the SkinnableContainer APIs are proxies to the `contentGroup` skin part. Details on these APIs can be found in the [Spark Group](Spark%20Group). SkinnableContainer also supports deferred instantiation--Group does not.
package mx.components
{
/**
* Dispatched after the content for this component has been created. With deferred
* instantiation, the content for a component may be created long after the
* component is created.
*
* @eventType mx.events.FlexEvent.CONTENT_CREATION_COMPLETE
*/
Event(name="contentCreationComplete", type="mx.events.FlexEvent")
/**
* Dispatched when a visual element is added to the content holder.
*
event.element
is the visual element that was added.
*
* @eventType mx.events.ElementExistenceEvent.ELEMENT_ADD
*/
Event(name="elementAdd", type="mx.events.ElementExistenceEvent")
/**
* Dispatched when a visual element is removed to the content holder.
*
event.element
is the visual element that's being removed.
*
* @eventType mx.events.ElementExistenceEvent.ELEMENT_REMOVE
*/
Event(name="elementRemove", type="mx.events.ElementExistenceEvent")
DefaultProperty("mxmlContentFactory")
class SkinnableContainer extends SkinnableContainerBase
{
// NOTE: SkinnableContainerBase extends SkinnableComponent
// SkinnableContainerBase handles enabling/disabling of children and also an
// IViewport implementation needed for scrolling
//--------------------------------------------------------------------------
//
// Skin Parts
//
//--------------------------------------------------------------------------
/**
* The Group that displays the content of this component. The content
* and layout properties of the
* component are assigned to this skin part.
*/
SkinPart
public var contentGroup:Group;
//--------------------------------------------------------------------------
//
// Group property and method proxies
//
// The remainder of the FxContainer APIs are direct proxies to the
// contentGroup SkinPart.
//
// Details for these APIs can be found in the Group class.
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
//
// Properties
//
//--------------------------------------------------------------------------
public function get layout():LayoutBase;
public function set layout(value:LayoutBase):void;
//--------------------------------------------------------------------------
//
// ViewPort/Scrolling ... just proxies to contentGroup
//
//--------------------------------------------------------------------------
public function get clipAndEnableScrolling():Boolean;
public function set clipAndEnableScrolling(value:Boolean):void;
//--------------------------------------------------------------------------
//
// Deferred Instantiation (see Deferred Spec for more details)
//
//--------------------------------------------------------------------------
public function set mxmlContentFactory(value:IDeferredInstance):void;
public function get creationPolicy():String;
public function set creationPolicy(value:String):void;
public function createDeferredContent():void
//--------------------------------------------------------------------------
//
// Content management
//
// These are proxies to the properties and methods on the contentGroup
// skin part, provided for convenience. They are equivalent to accessing
// the contentGroup part directly. For example, addElement(element); and
// contentGroup.addElement(element); do the same thing.
//--------------------------------------------------------------------------
public function get numElements():int;
public function getElementAt(index:int):IVisualElement
public function addElement(element:IVisualElement):IVisualElement;
public function addElementAt(element:IVisualElement, index:int):IVisualElement;
public function removeElement(element:IVisualElement):IVisualElement;
public function removeElementAt(index:int):IVisualElement;
public function getElementIndex(element:IVisualElement):int;
public function setElementIndex(element:IVisualElement, index:int):void;
public function swapElements(element1 :IVisualElement, element2 :IVisualElement):void;
public function swapElemenstAt(index1:int, index2:int):void;
}
}
## Prototype Work
----
An implementation of SkinnableContainer has been checked in. A prototype of
Panel has been written.
## Compiler Work
----
None.
## Web Tier Compiler Impact
----
None.
## Flex Feature Dependencies
----
[Group Spec](Group%20Spec) - SkinnableContainer has a very tight connection with the Group class, and we must keep the API's in sync.
SkinnableContainer is a usable container class and also a base class for several components. As these components are developed, some core functionality may be pushed back down into SkinnableContainer.
## Backwards Compatibility
----
### Syntax changes
None. These are new classes.
### Behavior
None. These are new classes.
### Warnings/Deprecation
None.
## Accessibility
----
N/A
## Performance
----
These classes are bound by the performance of the Group class.
## Globalization
----
Not Applicable.
## Localization
----
### Compiler Features
None.
### Framework Features
None.
## Issues and Recommendations
----
## QA
----
These are base classes, so testing should be API-focused.
[[ include ref='flexsdk_rightnav' ]]
[[ include ref='site:open_commentlogin' ]]