Menu

Spark BorderContainer

SourceForge Editorial Staff

Spark BorderContainer - Functional and Design Specification


Glossary


Summary and Background


The BorderContainer class provides a container class that can be styled with a border and a background fill or image. It has many of the same styles as HaloBorder and is used in a similar way to the Halo container classes such as Box and Canvas. Examples of styles that are supported are borderWeight, borderColor, backgroundColor, backgroundImage, cornerRadius and dropShadowVisible. The class also supports directly setting a fill or stroke instance.

Usage Scenarios


Gina, an application developer is prototyping her web application. She wants to quickly define visual regions of her application. Using the BorderContainer class, she creates three regions, each with a border and their own background color. She then fills in the containers with the various components of her application.

Without the BorderContainer class, she would have had to create three skin classes and assign those to three separate SkinnableContainer instances.

Gina wants a gradient background for one of her regions. She assigns a LinearGradient to the backgroundFill property of that BorderContainer.

Detailed Description


Design

The BorderContainer consists of a component class and a skin class called BorderSkin. BorderContainer declares the available styles and the backgroundFill and borderStroke properties. It serves as a proxy for the styles and properties in BorderSkin. BorderSkin draws the border and background using these styles and properties. The BorderContainer class is not meant to be skinned by a different skin class. All of the style drawing logic is held in the BorderSkin class.

Supported Styles

  • backgroundAlpha
  • backgroundColor
  • backgroundImage
  • backgroundImageResizeMode
  • borderAlpha
  • borderColor
  • borderStyle (solid, inset)
  • borderVisible
  • borderWeight
  • cornerRadius
  • dropShadowVisible

Unsupported styles from Halo Container

  • backgroundAttachment (fixed, scroll)
  • backgroundDisabledColor
  • borderSides (left, top, bottom, right)
  • borderThickness(Left/Right/Top/Bottom)
  • cornerRadius(TL/TR/BL/BR)
  • dropShadowAlpha
  • dropShadowAngle
  • dropShadowColor
  • dropShadowDistance

Properties

The backgroundFill property is an IFill that can be used to customize the background of the BorderContainer. If the backgroundFill property is set, then the backgroundAlpha, backgroundColor, backgroundImage and backgroundImageResizeMode styles are ignored.

The borderStroke property is an IStroke that can be used to customize the border of the BorderContainer. If the borderStroke property is set, then the borderAlpha, borderColor, borderStyle, borderVisible and borderWeight styles are ignored.

API Description


BorderContainer.as

package spark.components
{    
    /**
     *  Alpha level of the color defined by the <code>backgroundColor</code>
     *  property, or the image file defined by the <code>backgroundImage</code>
     *  style.
     *  Valid values range from 0.0 to 1.0. 
     *  
     *  @default 1.0
     */
    <a href="Style%28name%3D%26quot%3BbackgroundAlpha%26quot%3B%2C%20type%3D%26quot%3BNumber%26quot%3B%2C%20inherit%3D%26quot%3Bno%26quot%3B%29">Style(name="backgroundAlpha", type="Number", inherit="no")</a>

    /**
     *  Background color of the container.
     *  
     *  The default value is <code>undefined</code>, which means it is not set.
     *  If both this style and the <code>backgroundImage</code> style
     *  are <code>undefined</code>, the component has a transparent background.
     */
    <a href="Style%28name%3D%26quot%3BbackgroundColor%26quot%3B%2C%20type%3D%26quot%3Buint%26quot%3B%2C%20format%3D%26quot%3BColor%26quot%3B%2C%20inherit%3D%26quot%3Bno%26quot%3B%29">Style(name="backgroundColor", type="uint", format="Color", inherit="no")</a>

    /**
     *  Background image of a container. The image must be specified using the
     *  Embed directive. The embedded image can be an absolute or relative
     *  URL or class.  You can either have both a <code>backgroundColor</code> and a
     *  <code>backgroundImage</code> set at the same time. The background image is displayed
     *  on top of the background color.
     *  The default value is <code>undefined</code>, meaning "not set".
     *  If this style and the <code>backgroundColor</code> style are undefined,
     *  the component has a transparent background.
     */
    <a href="Style%28name%3D%26quot%3BbackgroundImage%26quot%3B%2C%20type%3D%26quot%3BObject%26quot%3B%2C%20format%3D%26quot%3BFile%26quot%3B%2C%20inherit%3D%26quot%3Bno%26quot%3B%29">Style(name="backgroundImage", type="Object", format="File", inherit="no")</a>

    /**
     *  The resizeMode determines how the background image fills in the dimensions. If you set the value
     *  of this property in a tag, use the string (such as "repeat"). If you set the value of 
     *  this property in ActionScript, use the constant (such as <code>BitmapResizeMode.NOSCALE</code>).
     * 
     *  When set to <code>BitmapResizeMode.NOSCALE</code> ("noScale"), the image
     *  ends at the edge of the region.
     * 
     *  When set to <code>BitmapResizeMode.REPEAT</code> ("repeat"), the image 
     *  repeats to fill the region.
     *
     *  When set to <code>BitmapResizeMode.SCALE</code> ("scale"), the image
     *  stretches to fill the region.
     * 
     *  @default <code>BitmapResizeMode.SCALE</code>
     */
    <a href="Style%28name%3D%26quot%3BbackgroundImageResizeMode%26quot%3B%2C%20type%3D%26quot%3BString%26quot%3B%2C%20enumeration%3D%26quot%3Bscale%2C%20noScale%2C%20repeat%26quot%3B%2C%20inherit%3D%26quot%3Bno%26quot%3B%29">Style(name="backgroundImageResizeMode", type="String", enumeration="scale, noScale, repeat", inherit="no")</a>

    /**
     *  Alpha level of the color defined by the <code>borderColor</code> style.
     *  
     *  Valid values range from 0.0 to 1.0. 
     *  
     *  @default 1.0
     */
    <a href="Style%28name%3D%26quot%3BborderAlpha%26quot%3B%2C%20type%3D%26quot%3BNumber%26quot%3B%2C%20inherit%3D%26quot%3Bno%26quot%3B%29">Style(name="borderAlpha", type="Number", inherit="no")</a>

    /**
     *  Color of the border.
     *  The default value depends on the component class;
     *  if not overridden for the class, the default value is <code>0xB7BABC</code>.
     */
    <a href="Style%28name%3D%26quot%3BborderColor%26quot%3B%2C%20type%3D%26quot%3Buint%26quot%3B%2C%20format%3D%26quot%3BColor%26quot%3B%2C%20inherit%3D%26quot%3Bno%26quot%3B%29">Style(name="borderColor", type="uint", format="Color", inherit="no")</a>

    /**
     *  Bounding box style.
     *  The possible values are <code>"solid"</code> and <code>"inset"</code>.
     * 
     *  @default solid
     */
    <a href="Style%28name%3D%26quot%3BborderStyle%26quot%3B%2C%20type%3D%26quot%3BString%26quot%3B%2C%20enumeration%3D%26quot%3Binset%2Csolid%26quot%3B%2C%20inherit%3D%26quot%3Bno%26quot%3B%29">Style(name="borderStyle", type="String", enumeration="inset,solid", inherit="no")</a>

    /**
     *  Determines if the border is visible or not. If true, then no border will be visible,
     *  except a border set via the borderStroke property. 
     *   
     *  @default true
     */
    <a href="Style%28name%3D%26quot%3BborderVisible%26quot%3B%2C%20type%3D%26quot%3BBoolean%26quot%3B%2C%20inherit%3D%26quot%3Bno%26quot%3B%29">Style(name="borderVisible", type="Boolean", inherit="no")</a>

    /**
     *  The stroke weight for the border. 
     *
     *  @default 1
     */
    <a href="Style%28name%3D%26quot%3BborderWeight%26quot%3B%2C%20type%3D%26quot%3BNumber%26quot%3B%2C%20format%3D%26quot%3BLength%26quot%3B%2C%20inherit%3D%26quot%3Bno%26quot%3B%29">Style(name="borderWeight", type="Number", format="Length", inherit="no")</a>

    /**
     *  Radius of the curved corners of the border
     *  if not overriden for the class, the default value is 0.
     */
    <a href="Style%28name%3D%26quot%3BcornerRadius%26quot%3B%2C%20type%3D%26quot%3BNumber%26quot%3B%2C%20format%3D%26quot%3BLength%26quot%3B%2C%20inherit%3D%26quot%3Bno%26quot%3B%29">Style(name="cornerRadius", type="Number", format="Length", inherit="no")</a>

    /**
     *  Boolean property that specifies whether the container has a visible
     *  drop shadow.
     *  
     *  @default false
     */
    <a href="Style%28name%3D%26quot%3BdropShadowVisible%26quot%3B%2C%20type%3D%26quot%3BBoolean%26quot%3B%2C%20inherit%3D%26quot%3Bno%26quot%3B%29">Style(name="dropShadowVisible", type="Boolean", inherit="no")</a>

    /**
     *  The BorderContainer class is a convenience class that provides a set of common styles that control
     *  the appearance of the border and background of a container.
     */ 
    public class BorderContainer extends SkinnableContainer
    {
        /**
         *  Constructor
         */ 
        public function BorderContainer();

        /**
         *  The backgroundFill is used to draw the background of the BorderContainer. 
         *  Setting this property will override the backgroundAlpha, 
         *  backgroundColor, backgroundImage and backgroundImageResizeMode styles.
         * 
         *  @default null
         */ 
        public function get backgroundFill():IFill;        
        public function set backgroundFill(value:IFill):void;

        /**
         *  The borderStroke draws the border of the BorderContainer. Setting this property will override 
         *  the borderAlpha, borderColor, borderStyle, borderVisible and borderWeight styles.  
         * 
         *  @default null
         */ 
        public function get borderStroke():IStroke;        
        public function set borderStroke(value:IStroke):void; 
    }
}

B Features


None

Examples and Usage


<?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">

    <fx:Style>        
        .borderStyle
        {
            backgroundColor : #ddffdd;
            backgroundAlpha : .7;
        }
    </fx:Style>

    <s:layout>
        <s:VerticalLayout paddingLeft="10" paddingTop="10" gap="10"/>
    </s:layout>

    <s:BorderContainer width="200" height="200" cornerRadius="8" borderColor="0x336699" borderWeight="4">
        <s:Button label="Inline BorderContainer Styles" horizontalCenter="0" verticalCenter="0"/>
    </s:BorderContainer>

    <s:BorderContainer width="200" height="200" styleName="borderStyle">
        <s:Button label="StyleSheet Background Styles" horizontalCenter="0" verticalCenter="0"/>
    </s:BorderContainer>

    <s:BorderContainer width="200" height="200">
        <s:backgroundFill>
            <s:LinearGradient>
                <fx:Array>
                    <s:GradientEntry color="0xff0000"/>
                    <s:GradientEntry color="0x00ff00"/>
                </fx:Array>
            </s:LinearGradient>
        </s:backgroundFill>
        <s:Button label="LinearGradient Fill" horizontalCenter="0" verticalCenter="0"/>
    </s:BorderContainer>

</s:Application>

Additional Implementation Details


None

Prototype Work


Glenn has already created a working prototype

Compiler Work


No

Web Tier Compiler Impact


None

Flex Feature Dependencies


None

Backwards Compatibility


N/A

Accessibility


None

Performance


There are no performance issues specific to this feature.

Globalization


None

Localization


Compiler Features

None

Framework Features

None

Issues and Recommendations


Open Issues

Resolved Issues

Should we support tiling and positioning the backgroundImage?

Right now we have backgroundSize which controls the scale of the image. Halo has backgroundSize which controls the percentage size of the image in relationship to the container's size.

BitmapFill has resizeMode (noScale, scale, repeat). It also has x/y transform properties to position the image.

There is overlap between BitmapFill.resizeMode and the backgroundSize style. Also, BitmapFill.resizeMode is not fully fleshed out and is subject to change.

The solution is to add backgroundImageResizeMode which has three possible values (scale, noScale, and repeat). If a developer wants to further customize this, then they can use a BitmapFill for the backgroundFill property. Then they can control the scale, repeating and position.

Should we reuse existing Spark styles (contentBackgroundColor)

No. Since contentBackgroundColor is an inheriting style, child components of the BorderContainer that support contentBackgroundColor will have the same background color as the BorderContainer. Use backgroundColor instead.

Should BorderContainer support undefined borderColor / backgroundColor? Should BorderContainer default to a set borderColor and backgroundColor?

Some Halo containers have a backgroundColor defined and borderColor is a global style.

Consider renaming BorderContainer (but not to Container)

The current proposal is to name it Border. BorderContainer is a long tag to type out. Border is a well understood concept. Other ideas we are considering are Box, Frame, StylableContainer, and BorderBox. One downside of calling it Border is that there already is a Halo class called Border which serves as a base class for all of the border skins.

We have two sets of terminology for the same things. Stroke/Fill versus Border/Background. Border/Background are terms from Halo's container and are familiar to existing Flex developers. Stroke/Fill are terms used in the graphic primitives and are the existing Flash drawing API terms.

Border is more descriptive than stroke. We will be adding border properties to Spark Panel and other components. backgroundColor is already used as a Spark style. So instead of changing background/border terms to use fill/stroke, we are going to change the fill/stroke properties to incorporate background/border. The proposed solution is to continue use the border/contentBackground terminology. This means changing all of the backgroundX styles to contentBackgroundX, changing fill to contentBackgroundFill and stroke to borderStroke.

Should we support borderStyle. Should the borderStyles use the Spark look? The Spark inset has a dropShadow on the top side. Or should we have inset look like Halo? Do we even need this style?

Supporting solid, inset and none.

Should we support all of the dropShadow styles or just dropShadowVisible?

If the developer wants their own dropShadow, then they can create their own skin. Would the dropShadow styles be used?

Should we support subclassing BorderContainer and BorderSkin? This would involve changing the skin from a programmatic one to a declarative/programmatic hybrid.

It is not critical to support subclassing BorderContainer and BorderSkin. If a developer wants more custom chrome, they can create their own skin. BorderContainer's purpose is to make it easy to implement the easy, common cases. The difficulty in supporting subclassing is that there is a conflict between laying out the content area programmatically and declaratively.

Should Panel and Form use BorderContainer's styles and logic?

No, Panel and Form will have their own subsets of supported styles. It would be tricky to get this functionality into the PanelSkin and FormSkin.

Should we create a BorderElement primitive (which contains the style drawing logic) used by BorderContainer and any other component?

No, it will be tricky to integrate into the skins.

Should there be scrolling support?

No, scrolling is not a requirement. To support scrolling, the developer can wrap the content area with a Scroller. This still won't solve a scrolling background. To do that, put your own BitmapImage into the Scroller.

Should we inset the content when cornerRadius set?

No, Halo doesn't do this. The developer should use the layout padding to inset their content. If we start insetting the content based on cornerRadius, then it makes it harder for the developer to specify the padding.

Should we add borderAlpha?

Yes.

Documentation


No special requirements

QA


None



Related

Wiki: Flex 4

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.