Darrell Loverin (Dev)
Robert Vollmar (QA)

Functional and Design Specification


Glossary


N/A

Summary and Background


The advantage of using skins for the top level application is that you can change the look of your applications by substituting a new skin via CSS. This ability allows you to customize top-level applications beyond normal CSS attributes (border, padding, margins, background color) without the need to modify the application mxml itself.

FxApplication allows a developer to put top-level graphic elements and layout elements directly into the mxml file without the need to wrap them in a Group element.

Usage Scenarios


Jane is writing a new Gumbo application. Jane uses an FxApplication element as the root of the mxml file instead of Application and specifies the 2009 namespace. Jane can add Gumbo content without a problem but some halo content (faceless components such as RadioButtonGroup) needs to go in the declarations section or a runtime exception will result.

Detailed Description


This section discusses proposed changes to the Application and FxApplication API. It also discusses solutions to a couple of coding issues that have surfaced due the fact we will have two top level application classes.

Application API not brought forward to FxApplication

    • Properties
      • application: the plan is to deprecate Application.application
      • controlBar
      • historyManagementEnabled
      • resetHistory
    • Methods
      • addToCreationQueue()
    • Styles
      • No styles are brought forward
    • Events
      • N/A

API in FxApplication not in Application

    • Properties
      • backgroundColor
      • colorCorrection - convenience method to set stage.colorCorrection.
    • Methods
      • N/A
    • Styles
      • None
    • Events
      • N/A

Deprecate Application.application

With the addition of FxApplication there are now two root application classes. Code that calls Application.application needs to be changed to FlexGlobals.topLevelApplication. The advantage of this change is using FlexGlobals.topLevelApplication does not link the the Application class. If only FxApplication is being used, linking in Application increases the size of the application.

API Description


The FxApplication API is the same as Application except where noted in detailed description. The base class of FxApplication is FxContainer whereas the base class of Application is LayoutContainer.

package mx.core
{

public class FxApplication extends FxContainer

{

//----------------------------------
//  backgroundColor
//----------------------------------
    
[Bindable("backgroundColorUpdated")]

/**
 *  Background color of a component. 
 *  This property specifies the background color, both while the application
 *  loads, and while it is running.  
 */
public function get backgroundColor():uint;
public function set backgroundColor(value:uint):void;

//----------------------------------
// colorCorrection
//----------------------------------

[Inspectable(enumeration="default,off,on", defaultValue="default" )]
    
/**
 *  The value of the stage's <code>colorCorrection</code> property. If this application
 *  does not have access to the stage's <code>colorCorrection</code> property, 
 *  the value of the <code>colorCorrection</code> property will be reported as 
 *  null. Also, the <code>colorCorrection</code> property cannot be set if the
 *  application does not have access to the stage's <code>colorCorrection</code> property.
 *
 *  @default ColorCorrection.DEFAULT
 */
public function get colorCorrection():String;
public function set colorCorrection(value:String):void;


...

}
package mx.core
{

public class Application extends LayoutContainer

{
[Deprecated(replacement="FlexGlobals.topLevelApplication", since="4.0")]
public static function get application():Object

...

}

B Features


Examples and Usage


An FxApplication with both Gumbo and Halo components

<?xml version="1.0" encoding="utf-8"?>
<FxApplication xmlns="http://ns.adobe.com/mxml/2009"
             backgroundColor="white"
             width="800" height="600">
    <layout>
        <VerticalLayout />
    </layout>
    <Ellipse width="10" height="10" y="3">
        <fill>
            <RadialGradient>
                <GradientEntry color="0xAAAAAA" />
                <GradientEntry color="0x336699" />
            </RadialGradient>
        </fill>
    </Ellipse>
    <Button label="halo button" />
    <FxButton label="gumbo button" />
</FxApplication>

An FxApplication with a custom skin

The most flexible way to specify a custom skin for an application is to specify a CSS file using a Style tag. The skin can be changed later by modifying the CSS file without the need to modify the application source.

<?xml version="1.0" encoding="utf-8"?>
<FxApplication xmlns="http://ns.adobe.com/mxml/2009"
             width="800" height="600" >
...
<Style source="MyFlex4.css" />
...
</FxApplication>

The CSS file

The CSS file specifies the custom skin to use for the application.

MyFlex4
{
    skinClass: ClassReference("MyApplicationSkin");
    backgroundColor: #FFFFFF;
}

The Custom Skin

To make a custom skin, FxApplicationSkin.mxml was copied from FxApplicationSkin.mxml and a BitmapGraphic was added to the end of the skin. The BitmapGraphic is positioned in the bottom, right corner of the application.

<Skin xmlns="http://ns.adobe.com/mxml/2009">

    <Metadata>
    	[HostComponent("mx.components.FxApplication")]
    </Metadata> 
    
    <states>
    	<State name="normal" />
    	<State name="disabled" />
    </states>
    
	<!-- fill -->
    <Rect id="backgroundRect" left="0" right="0" top="0" bottom="0">
        <fill>
            <SolidColor color="{fxComponent.backgroundColor}" />
        </fill>
    </Rect>
        
    <Group id="contentGroup" left="0" right="0" top="0" bottom="0" />

    <BitmapGraphic source="@Embed('Nokia_6630.png')"
                   right="5" bottom="5" alpha="0.2"
                    />

</Skin>

Additional Implementation Details


None.

Prototype Work


FxApplication has been in the Gumbo for some time. Only incremental changes are being proposed.

Compiler Work


The compiler generates some style code for top-level applications. In Flex3 the style code was generated the the source file was a top-level application and subclasses the "LayoutContainer" class. The compiler will look to make the test for a Gumbo container more generic then testing for "FxApplication. The compiler team thinks the intent of the original tests are to test for a Flex Framework Application as opposed to a non-Framework Application. So instead of testing for "FxApplication" the compiler will test Gumbo applications to see if they implement ISimpleStyleClient.

Web Tier Compiler Impact


N/A

Flex Feature Dependencies


Dependent on how Styles should work in a Gumbo application.

Backwards Compatibility


Syntax changes

Done in Design Details section.

Behavior

N/A

Warnings/Deprecation

Deprecation Application.application.

Issues and Recommendations


None.


You must be logged in to comment.

I doubt this is a focus for you guys, but unloading and reloading Flex Applications into non-flex apps (just flash), and loading Flex apps into different application domains are two issues I'd love to be resolved. We develop in Flex, but have clients who want to load our software just from Flash.

Check out the Marshall plan. It's the SDK feature to support cross-versioning and support across multiple ApplicationDomains.

Why is there now a whole new method of styling and new classes? What benefits will this pose for programmers that now have had to convert to an entirely new language and syntax each time you jump to the next version number? (action-script 1, 2, 3 and now 4 are all different)?

At least with previous versions of Flex Building SDK, mxml language remained largely unchanged except for the namespace references (1999, 2002, 2004, 2005, and currently 2006). The only suggestion I had for this was storing the namespace URL in a separate file inside the project so that all the files of a given project would not need to be changed to reflect the new namespace location.

Now, however, with 2009 you not only changed the url, but the syntax as well!

So the real question is: how will companies be able to justify the substantial expense of paying for so many programming hours to have all their 3.0 code ported to the new 4.0? .... and 5.0, 6.0, etc?

While I understand the existance of Application.application and now FlexGlobals.topLevelApplication, I do have two questions that'd be wonderful to learn the answers to:

1. Why is the application typed as an Object and not an interface?
I understand why you wouldn't want to type the property to a specific implementation as that implementation may well change, but that's what interfaces are for! Define a minimal interface which all applications must implement and you'd solve both the problem of bytecode size as well as the problem of having a too loosely typed property.

2. Why is this reference not injected to the display objects?
Wouldn't this be a much cleaner approach? If nothing else, one could more easily test code that needs such a reference by simple mocking, provided that the property is settable and that an interface like the one described in the question above does indeed exist.

The whole FlexGlobals thing seems like a clear violation of OOP principles, possibly leading to brittle codebases. For instance, the code base will change when you decide to yet again change the name/location of this API? Or the implementation for that matter. Typing it as an Object means that loads of programmers cast this property in order to receive syntax highlighting. As soon as the implementation changes the cast will fail and codebases will break. The argument of increased bytecode size is moot if people cast the application (now topLevelApplication) property, even if that issue had been the foremost one.

Please Adobe, as the developers of the SDK and all of its API's, you have a responsibility to maintain a good, clean and consistent coding standard. Lead by example, so to speak.

1. We type the property as Object so that folks can access the properties that are hanging off of it without casting. Generally if folks want to do a quick shortcut, like get access to a config that hangs off the application, we'd like to let them do that instead of getting continuous errors.

2. I'm not sure what you mean about the reference being injected into the display objects. The Application remains a SkinnableComponent which means it will be in the display list. This is just about providing quick access to it.

I don't think the FlexGlobals is really a violation of OO principles. Sometimes you want to provide access to things that folks wouldn't normally have access to. For example, how do you quickly pass config information through to an object that isn't on the display list? There are plenty of other cases here too. You don't have to use these properties if you don't want, UIComponent still has is parentApplication property which will work. But we need to consider ease of development for simple cases in addition to zealotry of OO principles.