Enhanced States Syntax - Functional and Design SpecificationEnhanced States Syntax - Functional and Design Specification | Glossary | Summary and Background | Usage Scenario | Detailed Description | API Description | B Features | Additional Implementation Details | Prototype Work | Compiler Work | Web Tier Compiler Impact | Flex Feature Dependencies | Backwards Compatibility | Accessibility | Performance | Globalization | Localization | Issues and Recommendations | Documentation | QA
Glossarystate - A state (or 'view-state') is a collection of changes (called overrides) to a view. The changes within a state can comprise additions or removals of components as well as changes to their properties, styles, and behavior.
Summary and BackgroundGoals
Usage ScenarioFlex 4 will target all of the legacy usage scenarios of classic Flex states functionality (stateful components, states as application "views" or "pages", effects and transitions between view states, etc.). This document outlines what is primarily a syntax change for the existing functionality. Detailed DescriptionInline States SyntaxStates will be promoted to a full language feature of MXML during the Flex 4 time frame. A more terse and flexible inline syntax will be provided for expressing all state-specific changes to a component instance. The classic syntax will be deprecated as of MXML version 4.0. First, a brief description of how the states model will change for version 4.0 components:
API DescriptionA detailed overview of the new inline syntax follows: State-Specific Component InstancesThe AddChild and RemoveChild override mechanism will be replaced by a new includeIn language attribute that can be used to decorate inline MXML component instance tags with the set of states for which the specific instance is to be realized. The new includeIn attribute accepts a comma delimited list of state names, all of which must have been previously declared within the document's states array. Optionally, excludeFrom can be used to define an explicit "black-list" of states where the instance will not apply. The excludeFrom and includeIn attributes are mutually exclusive. If both are defined on a single tag, it is considered an error and an appropriate compiler error will be issued. An example: <!-- Given the states A,B,C -->
<m:states>
<m:State name="A"/>
<m:State name="B"/>
<m:State name="C"/>
</m:states>
<!-- This button will appear in only states A and B -->
<Button label="Click Me" includeIn="A, B"/>
<!-- This button will appear in states A and B -->
<Button label="Button C" excludeFrom="C"/>
The includeIn and excludeFrom attributes will be treated as reserved language keywords by the MXML compiler. The includeIn and excludeFrom attributes can be legally specified on any MXML object within a document, with the exception of:
In addition to referencing mutually exclusive states, both attributes also support composite states (currently known as overlays). A more detailed specification of how Overlays are supported in the new state model will be incorporated into the Overlays specification (not yet drafted).
BEFORE - Classic states syntax (O'Reilly Programming Flex 2): <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"> <mx:states> <mx:State name="newCheckbox"> <mx:AddChild relativeTo="{vbox}"> <mx:CheckBox id="checkbox" label="Checkbox" /> </mx:AddChild> </mx:State> <mx:State name="newTextArea" basedOn="newCheckBox"> <mx:AddChild relativeTo="{vbox}"> <mx:TextArea id="textarea" /> </mx:AddChild> </mx:State> </mx:states> <mx:VBox id="vbox"> <mx:Button label="Click" click="currentState='newCheckbox'" /> <mx:Button label="Click" click="currentState='newTextArea'" /> </mx:VBox> </mx:Application> AFTER - Inline states syntax: <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="library:ns.adobe.com/flex/halo" xmlns:m="http://ns.adobe.com/mxml/2009" layout="absolute"> <m:states> <m:State name="default"/> <m:State name="newCheckbox"/> <m:State name="newTextArea"/> </m:states> <mx:VBox> <mx:Button label="Click" click="currentState='newCheckbox'" /> <mx:Button label="Click" click="currentState='newTextArea'" /> <mx:CheckBox id="checkbox" label="Checkbox" includeIn="newCheckbox, newTextArea"/> <mx:TextArea id="textarea" includeIn="newTextArea"/> </mx:VBox> </mx:Application> Transient component instances (instances that appear across one or more states), are declared inline with the rest of the document, essentially at their "natural" location in the DOM. The context of a state-specific instance is no longer explicitly defined by the relativeTo/position properties of AddChild. Location is instead inferred by the inline placement. Note that for a state-specific node to be realized within a state, its ancestors must also be defined within the same state as well. For example, a child is not visible in StateA if its parent is excluded from StateA. If such a scenario is detected, a compiler warning will be issued. BEFORE - Classic states syntax (O'Reilly Programming Flex 2): <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"> <mx:states> <mx:State name="newTextInput"> <mx:AddChild relativeTo="{checkbox1}" position="after"> <mx:TextInput id="textinput" /> </mx:AddChild> </mx:State> </mx:states> <mx:VBox id="vbox"> <mx:CheckBox id="checkbox1" label="One" /> <mx:CheckBox id="checkbox2" label="Two" /> <mx:Button id="button" label="Click" click="currentState='newTextInput'" /> </mx:VBox> </mx:Application> AFTER - Inline states syntax: <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="library:ns.adobe.com/flex/halo" xmlns:m="http://ns.adobe.com/mxml/2009" layout="absolute"> <m:states> <m:State name="default"/> <m:State name="newTextInput"/> </m:states> <mx:VBox> <mx:CheckBox label="One" /> <mx:TextInput includeIn="newTextInput"/> <mx:CheckBox label="Two" /> <mx:Button id="button" label="Click" click="currentState='newTextInput'" /> </mx:VBox> </mx:Application> And another example, demonstrating how the use of RemoveChild in the legacy syntax, translates to the new:
BEFORE - Classic states syntax (O'Reilly Programming Flex 2): <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"> <mx:states> <mx:State name="noCheckboxes"> <mx:RemoveChild target="{checkbox1}" /> <mx:RemoveChild target="{checkbox2}" /> </mx:State> </mx:states> <mx:VBox id="vbox"> <mx:CheckBox id="checkbox1" label="One" /> <mx:CheckBox id="checkbox2" label="Two" /> <mx:Button id="button" label="Click" click="currentState='noCheckboxes'" /> </mx:VBox> </mx:Application> AFTER - Inline states syntax: <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="library:ns.adobe.com/flex/halo" xmlns:m="http://ns.adobe.com/mxml/2009" layout="absolute"> <m:states> <m:State name="default"/> <m:State name="noCheckboxes"/> </m:states> <mx:VBox id="vbox"> <mx:CheckBox label="One" excludeFrom="noCheckboxes"/> <mx:CheckBox label="Two" includeIn="default"/> <!-- Works as above --> <mx:Button id="button" label="Click" click="currentState='noCheckboxes'" /> </mx:VBox> </mx:Application> ReparentingWhere one would generally have used a RemoveChild followed by an AddChild to reparent instances within a state (Flex 3), a new Reparent language tag will be provided that can be used as an inline insertion point for a given component instance. The Reparent tag itself provides a target attribute which specifies the component instance to reparent. The includeIn attribute used in combination with the Reparent tag specifies the context for which the reparenting is to take place. There is no formal runtime representation of the Reparent tag itself. The compiler will convert the Reparent into explicit remove and insertion overrides for the given state(s). Note that for a Reparent tag to be valid, it must refer to a document node that is not already realized within the state that the reparenting is to take place. Additionally, two or more Reparent tags must not target the same DOM node within the same state. The set of reparent operations in a given state must, when combined, result in a valid DOM (no circular references, etc.). If any of these error conditions are detected, a compiler error will be issued. Additional restrictions on the Reparent tag are as follows:
See the Media Chat example later for an example Reparent use case. State-Specific Property ValuesThe SetProperty, SetStyle, and SetEventHandler overrides will be replaced by an inline attribute notation. State-specific property values can be expressed by utilizing the 'dot' operator on any writable XML attribute to essentially provide a hint to the compiler that the attribute is to be 'scoped' to a specific state. <!-- Button's label in base state is "XXX', in state A, "YYY", and in state B, "ZZZ" --> <Button label="XXX" label.A="YYY" label.B="ZZZ" /> The unqualified property/value pair (e.g property=value) is assumed to be the default base value and the value within all states, unless specifically overridden. <!-- Default value, 'YYY' applies to all named states, except the 'A' state --> <Button label="YYY" label.A="XXX" /> The "drill-down" (dot) syntax can be utilized with most component properties, styles, or event handlers. The state-specific attribute syntax cannot however be used with built-in language attributes. The full set of language attributes are detailed in the Flex 4 MXML 2009 language specification, but they include (for example), id, states, frameRate, etc. To facilitate the ability to "clear" a property value within a given state, a new directive '@Clear" will be introduced. This essentially results in property being unset. e.g. For a style property, it would result in a clearStyle() being invoked (thus allowing the natural cascade to take effect). The @Clear value directive can be used with properties, styles, and event handlers. <!-- In state A, the color style is cleared. Any CSS selectors can now take effect. --> <Button color="0xFF0000" color.A="@Clear" /> Some additional examples of state-specific property syntax:
BEFORE - Classic states syntax (O'Reilly Programming Flex 2): <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"> <mx:states> <mx:State name="landState"> <mx:SetStyle target="{car}" name="color" value="0xFF0000" /> <mx:SetStyle target="{train}" name="color" value="0xFF0000" /> <mx:SetStyle target="{motorcycle}" name="color" value="0xFF0000" /> </mx:State> <mx:State name="airState"> <mx:SetStyle target="{helicopter}" name="color" value="0xFF0000" /> <mx:SetStyle target="{airplane}" name="color" value="0xFF0000" /> </mx:State> <mx:State name="waterState"> <mx:SetStyle target="{boat}" name="color" value="0xFF0000" /> <mx:SetStyle target="{submarine}" name="color" value="0xFF0000" /> </mx:State> </mx:states> <mx:VBox id="vbox"> <mx:HBox> <mx:Button id="land" label="Land" click="currentState='landState'" /> <mx:Button id="air" label="Air" click="currentState='airState'" /> <mx:Button id="water" label="Water" click="currentState='waterState'" /> </mx:HBox> <mx:CheckBox id="helicopter" label="Helicopter" /> <mx:CheckBox id="motorcycle" label="Motorcycle" /> <mx:CheckBox id="car" label="Car" /> <mx:CheckBox id="airplane" label="Airplane" /> <mx:CheckBox id="train" label="Train" /> <mx:CheckBox id="boat" label="Boat" /> <mx:CheckBox id="submarine" label="Submarine" /> </mx:VBox> </mx:Application> AFTER - Inline states syntax: <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="library:ns.adobe.com/flex/halo" xmlns:m="http://ns.adobe.com/mxml/2009" layout="absolute"> <m:states> <m:State name="landState"/> <m:State name="airState"/> <m:State name="waterState"/> </m:states> <mx:VBox id="vbox"> <mx:HBox> <mx:Button id="land" label="Land" click="currentState='landState'" /> <mx:Button id="air" label="Air" click="currentState='airState'" /> <mx:Button id="water" label="Water" click="currentState='waterState'" /> </mx:HBox> <mx:CheckBox label="Helicopter" color.airState="0xFF0000"/> <mx:CheckBox label="Motorcycle" color.landState="0xFF0000" /> <mx:CheckBox label="Car" color.landState="0xFF0000" /> <mx:CheckBox label="Airplane" color.airState="0xFF0000"/> <mx:CheckBox label="Train" color.landState="0xFF0000" /> <mx:CheckBox label="Boat" color.waterState="0xFF0000"/> <mx:CheckBox label="Submarine" color.waterState="0xFF0000"/> </mx:VBox> </mx:Application>
BEFORE - Classic states syntax (O'Reilly Programming Flex 2): <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"> <mx:states> <mx:State name="enabled"> <mx:SetProperty target="{textinput}" name="enabled" value="{true}" /> <mx:SetEventHandler target="{button}" name="click" handler="currentState=''" /> <mx:SetProperty target="{button}" name="label" value="Disable" /> </mx:State> </mx:states> <mx:HBox id="hbox"> <mx:Button id="button" label="Enable" click="currentState='enabled'" /> <mx:TextInput id="textinput" enabled="false" text="example text" /> </mx:HBox> </mx:Application> AFTER - Inline states syntax: <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="library:ns.adobe.com/flex/halo" xmlns:m="http://ns.adobe.com/mxml/2009" layout="absolute"> <m:states> <m:State name="disabledState"/> <m:State name="enabledState"/> </m:states> <mx:HBox> <mx:Button id="button" label="Enable" label.enabledState="Disable" click="currentState='enabled'" click.enabledState="currentState=''" /> <mx:TextInput enabled="false" enabled.enabledState="true" text="example text" /> </mx:HBox> </mx:Application> The state-specific property value syntax can also be used with object based properties...
BEFORE - Classic states syntax: <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:states> <mx:State name="glow"> <mx:SetProperty target="{b}" name="filters"> <mx:value> <mx:Array> <mx:GlowFilter /> </mx:Array> </mx:value> </mx:SetProperty> </mx:State> </mx:states> <mx:Button label="Button" id="b" click="currentState=currentState=='glow'?'':'glow'"> <mx:filters> <mx:DropShadowFilter distance="9" /> </mx:filters> </mx:Button> </mx:Application> AFTER - Inline states syntax: <mx:Application xmlns:mx="library:ns.adobe.com/flex/halo" xmlns:m="http://ns.adobe.com/mxml/2009"> <m:states> <m:State name="default"/> <m:State name="glow"/> </m:states> <mx:Button label="Button" click="currentState=currentState=='glow'?'':'glow'"> <mx:filters> <mx:DropShadowFilter distance="9" /> </mx:filters> <mx:filters.glow> <mx:GlowFilter/> </mx:filters.glow> </mx:Button> </mx:Application> <!-- Alternatively the above code could be written using state specific nodes --> <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:m="http://ns.adobe.com/mxml/2009" xmlns:mx="library:ns.adobe.com/flex/halo"> <m:states> <m:State name="default"/> <m:State name="glow"/> </m:states> <mx:Button label="Button" click="currentState=currentState=='glow'?'':'glow'"> <mx:filters> <mx:DropShadowFilter distance="9" includeIn="default" /> <mx:GlowFilter includeIn="glow"/> </mx:filters> </mx:Button> </mx:Application> When state-specific attributes are used with composite states (Overlays), along with mutually exclusive states, the order of precedence is as follows:
State GroupsIf several states within a stateful document are quite similar, and are commonly used together when setting state-specific properties, a "state group" can be created. State groups are essentially state macros that can be used directly within an includeIn or excludeFrom, or a state-specific property's scope. For example, given this case: <m:states> <m:State name="A"/> <m:State name="B"/> <m:State name="C"/> <m:State name="D"/> </m:states> ... <mx:Button label.A="SomeLabel" label.C="SomeLabel" label.D="SomeLabel"/> <mx:Button includeIn="A,C,D"/> <mx:Button label.A="SomeLabel" label.B="SomeLabel"/> <mx:Button includeIn="A,B"/> If one discoveres a pattern of treating a set of states identically in some cases, a state group representing these states can be created and referred to as appropriate. <m:states> <m:State name="A" stateGroups="G1,G2"/> <m:State name="B" stateGroups="G2"/> <m:State name="C" stateGroups="G1"/> <m:State name="D" stateGroups="G1"/> </m:states> ... <mx:Button label.G1="SomeLabel"/> <mx:Button includeIn="G1"/> <mx:Button label.G2="SomeLabel"/> <mx:Button includeIn="G2"/> The stateGroups attribute accepts a comma delimited list of valid state identifiers (whitespace ignored). Custom Creation and Destruction PoliciesitemCreationPolicy Historically if one wanted a custom creation policy (immediate vs. deferred instantiated) for a state-specific component instance they would utilize the creationPolicy attribute of the AddChild override. To provide for a similar level of control, a per-item based creation policy language attribute (itemCreationPolicy) will be introduced. Supported values for itemCreationPolicy are ItemCreationPolicy.DEFERRED, ItemCreationPolicy.IMMEDIATE. The itemCreationPolicy language attribute can be specified on any MXML object supporting the includeIn and excludeFrom attributes. An item creation policy of ItemCreationPolicy.DEFERRED is the default, the instance is created when needed. An item creation policy of ItemCreationPolicy.IMMEDIATE means that the object will be created as soon as the owning document context is initialized.
BEFORE - Classic states syntax: <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"> <mx:states> <mx:State name="newTextInput"> <mx:AddChild relativeTo="{checkbox1}" position="after" creationPolicy="all"> <mx:TextInput id="textinput" /> </mx:AddChild> </mx:State> </mx:states> <mx:VBox id="vbox"> <mx:CheckBox id="checkbox1" label="One" /> <mx:CheckBox id="checkbox2" label="Two" /> <mx:Button id="button" label="Click" click="currentState='newTextInput'" /> </mx:VBox> </mx:Application> AFTER - Inline states syntax: <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="library:ns.adobe.com/flex/halo" xmlns:m="http://ns.adobe.com/mxml/2009" layout="absolute"> <mx:states> <mx:State name="default"/> <mx:State name="newTextInput"/> </mx:states> <mx:VBox id="vbox"> <mx:CheckBox label="One" /> <mx:TextInput includeIn="newTextInput" itemCreationPolicy="immediate"/> <mx:CheckBox label="Two" /> <mx:Button id="button" label="Click" click="currentState='newTextInput'" /> </mx:VBox> </mx:Application> itemDestructionPolicy By default, after the framework initially creates a state-specific instance, the instance is cached indefinitely, even after switching to a state where the item is excluded. An optional itemDestructionPolicy language attribute is provided as a means of ensuring a state-specific instance is destroyed upon leaving a state in which it exists. Typically it is more efficient to allow items to be cached, however there are times, such as for rarely visited states, that you may wish not to take the memory hit for a cached instance. Supported values for itemDestructionPolicy are "never" and "auto". The itemDestructionPolicy language attribute can be specified on any MXML object supporting the includeIn and excludeFrom attributes. An item destruction policy of "never" is the default, all state-specific instances are realized when appropriate and cached indefinitely. An item destruction policy of "auto" means that the object will be removed from the DOM and all document and framework references to the object cleared, upon leaving a state where the instance exists. In the example below, the text input instance will be released upon switching to then from, the 'newTextInput' state:
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="library:ns.adobe.com/flex/halo" xmlns:m="http://ns.adobe.com/mxml/2009" layout="absolute"> <mx:states> <mx:State name="default"/> <mx:State name="newTextInput"/> </mx:states> <mx:VBox id="vbox"> <mx:CheckBox label="One" /> <mx:TextInput includeIn="newTextInput" itemDestructionPolicy="auto"/> <mx:CheckBox label="Two" /> <mx:Button id="button" label="Click" click="currentState='newTextInput'" /> </mx:VBox> </mx:Application> Some Additional ExamplesHere is an example that ties everything together. A real world use case (Flex Media Chat, www.flashcomguru.com)...
BEFORE - Classic states syntax: <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:states> <mx:State name="chatState"> <mx:SetProperty target="{mainPanel}" name="width" value="80%"/> <mx:SetProperty target="{mainPanel}" name="height" value="80%"/> <mx:RemoveChild target="{submit}"/> <mx:RemoveChild target="{female}"/> <mx:RemoveChild target="{hbox1}"/> <mx:RemoveChild target="{hbox2}"/> <mx:RemoveChild target="{username}"/> <mx:AddChild relativeTo="{mainPanel}" position="lastChild"> <mx:VBox width="100%" height="100%" verticalGap="8" verticalAlign="middle" horizontalAlign="left" id="vbox2"> <mx:HDividedBox width="100%" height="100%" liveDragging="true"> <Chat:ChatTextarea id="hist" editable="false" width="75%" height="100%" paddingLeft="3" focusAlpha="0" htmlText="{chat.chatHistory}"> </Chat:ChatTextarea> <mx:List id="userlist" height="100%" width="25%" itemRenderer="usersRenderer" dataProvider="{chat.dpUsers}"></mx:List> </mx:HDividedBox> <mx:HBox width="100%" verticalAlign="middle" horizontalAlign="center" id="hbox6"> <mx:HBox width="75%" verticalAlign="middle" horizontalAlign="center" id="hbox5"> <mx:ColorPicker id="picker" toolTip="Font color"/> <mx:TextInput width="100%" id="msg" paddingLeft="3" focusAlpha="0" keyUp="checkSend(event)" color="{picker.selectedColor}" /> <mx:Button label="Send" id="send" click="sendMsg()"/> </mx:HBox> <mx:HBox width="25%" verticalAlign="middle" horizontalAlign="center" id="hbox7"> </mx:HBox> </mx:HBox> </mx:VBox> </mx:AddChild> <mx:SetProperty target="{text1}" name="text" value="FlexMediaChat"/> <mx:RemoveChild target="{vbox1}"/> <mx:SetProperty target="{hbox4}" name="width" value="75%"/> <mx:SetStyle target="{mainPanel}" name="horizontalAlign" value="left"/> <mx:SetStyle target="{text1}" name="color"/> <mx:RemoveChild target="{image1}"/> <mx:AddChild relativeTo="{hbox8}" position="lastChild" target="{image1}"/> <mx:RemoveChild target="{text1}"/> <mx:AddChild relativeTo="{hbox8}" position="lastChild" target="{text1}"/> <mx:RemoveChild target="{hbox4}"/> <mx:AddChild relativeTo="{hbox9}" position="lastChild" target="{hbox4}"/> <mx:SetProperty target="{hbox9}" name="width" value="100%"/> <mx:AddChild relativeTo="{hbox4}" position="lastChild"> <mx:Spacer width="80%" height="100%"/> </mx:AddChild> </mx:State> </mx:states> <mx:Panel width="410" height="210" layout="vertical" id="mainPanel" horizontalAlign="center" headerHeight="10" verticalAlign="middle" fontSize="12" paddingTop="10" paddingLeft="10" paddingRight="10"paddingBottom="10" verticalScrollPolicy="off" horizontalScrollPolicy="off"> <mx:HBox width="97%" id="hbox9"> <mx:HBox width="97%" id="hbox4" horizontalAlign="left"> <mx:Image source="assets/internet-group-chat.png" id="image1"/> <mx:Text text="User Login" fontWeight="bold" fontSize="18" id="text1" selectable="false" color="#333333"/> </mx:HBox> <mx:HBox id="hbox8" horizontalAlign="right"> </mx:HBox> </mx:HBox> <mx:VBox height="92%" width="95%" horizontalScrollPolicy="off" id="vbox1"> <mx:Spacer width="100%" height="6"/> <mx:HBox width="100%" id="hbox1"> <mx:Text text="Username:"/> <mx:TextInput id="username" width="269" focusAlpha="0" enter="connect(event)"/> </mx:HBox> <mx:HBox width="100%" id="hbox2"> <mx:RadioButtonGroup id="gender"/> <mx:Text text="Gender:"/> <mx:Spacer width="16" height="100%"/> <mx:Image id="maleicon" source="assets/male_login.png"/> <mx:RadioButton label="male" groupName="gender" selected="true" id="male"/> <mx:Image id="femaleicon" source="assets/female_login.png"/> <mx:RadioButton label="female" groupName="gender" id="female" selected="false"/> </mx:HBox> <mx:Spacer width="100%" height="7"/> <mx:HBox width="100%" id="hbox3" horizontalAlign="right"> <mx:Image source="assets/dialog-warning.png" id="warning"/> <mx:Text color="#e60000" id="status" text="Text"/> <mx:Spacer width="100%"/> <mx:Button label="Connect" click="connect( event )" id="submit" width="110" height="34" icon="@Embed('assets/go-next.png')"/> </mx:HBox> </mx:VBox> </mx:Panel> </mx:Application> AFTER - Inline states syntax: <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="library:ns.adobe.com/flex/halo" xmlns:m="http://ns.adobe.com/mxml/2009" m:version="4"> <m:states> <m:State name="defaultState"/> <m:State name="chatState"/> </m:states> <mx:Panel width="410" width.chatState="80%" height="110" height.chatState="80%" layout="vertical" id="mainPanel" horizontalAlign="center" horizontalAlign.chatState="left" headerHeight="10" verticalAlign="middle" fontSize="12" paddingTop="10" paddingLeft="10" paddingRight="10" paddingBottom="10" verticalScrollPolicy="off" horizontalScrollPolicy="off"> <mx:HBox width="97%" width.chatState="100%"> <mx:HBox width="97%" width.chatState="80%" id="hbox4" horizontalAlign="left"> <mx:Image source="assets/internet-group-chat.png" id="image1"/> <mx:Text text="User Login" text.chatState="FlexMediaChat" fontWeight="bold" fontSize="18" id="text1" selectable="false" color="#333333" color.chatState=""/> <mx:Spacer width="80%" height="100%" includeIn="chatState"/> </mx:HBox> <mx:HBox horizontalAlign="right"> <mx:Reparent target="{image1}" includeIn="chatState"/> <mx:Reparent target="{text1}" includeIn="chatState"/> </mx:HBox> <mx:Reparent target="{hbox4}" includeIn="chatState"/> </mx:HBox> <mx:VBox height="92%" width="95%" horizontalScrollPolicy="off" includeIn="defaultState"> <mx:Spacer width="100%" height="6"/> <mx:HBox width="100%" includeIn="defaultState"> <mx:Text text="Username:"/> <mx:TextInput id="username" width="269" focusAlpha="0" enter="connect(event)" includeIn="defaultState"/> </mx:HBox> <mx:HBox width="100%" includeIn="defaultState"> <mx:RadioButtonGroup/> <mx:Text text="Gender:"/> <mx:Spacer width="16" height="100%"/> <mx:Image id="maleicon" source="assets/male_login.png"/> <mx:RadioButton label="male" groupName="gender" selected="true" id="male"/> <mx:Image source="assets/female_login.png"/> <mx:RadioButton label="female" groupName="gender" selected="false" includeIn="defaultState"/> </mx:HBox> <mx:Spacer width="100%" height="7"/> <mx:HBox width="100%" horizontalAlign="right"> <mx:Image source="assets/dialog-warning.png" id="warning"/> <mx:Text color="#e60000" id="status" text="Text"/> <mx:Spacer width="100%"/> <mx:Button label="Connect" click="connect( event )" id="submit" width="110" height="34" icon="@Embed('assets/go-next.png')" includeIn="defaultState"/> </mx:HBox> </mx:VBox> <!-- chatState content --> <mx:VBox width="100%" height="100%" verticalGap="8" verticalAlign="middle" horizontalAlign="left" includeIn="chatState"> <mx:HDividedBox width="100%" height="100%" liveDragging="true"> <Chat:ChatTextarea editable="false" width="75%" height="100%" paddingLeft="3" focusAlpha="0" htmlText="{chat.chatHistory}"> </Chat:ChatTextarea> <mx:List height="100%" width="25%" itemRenderer="usersRenderer" dataProvider="{chat.dpUsers}"></mx:List> </mx:HDividedBox> <mx:HBox width="100%" verticalAlign="middle" horizontalAlign="center"> <mx:HBox width="75%" verticalAlign="middle" horizontalAlign="center" > <mx:ColorPicker id="picker" toolTip="Font color"/> <mx:TextInput width="100%" id="msg" paddingLeft="3" focusAlpha="0" keyUp="checkSend(event)" color="{picker.selectedColor}" /> <mx:Button label="Send" id="send" click="sendMsg()"/> </mx:HBox> <mx:HBox width="25%" verticalAlign="middle" horizontalAlign="center"> </mx:HBox> </mx:HBox> </mx:VBox> </mx:Panel> </mx:Application> And lastly, a Flex 4 button skin example, noting first the classic syntax, followed by the inline syntax.
BEFORE - Classic states syntax: <?xml version="1.0" encoding="utf-8"?> <Skin xmlns:mx="http://www.adobe.com/2006/mxml"> <states> <mx:State name="up" /> <mx:State name="over"> <mx:SetProperty target="{s}" name="color" value="0x6666BB" /> <mx:SetProperty target="{e2}" name="color" value="0xF0F0F0" /> </mx:State> <mx:State name="down" basedOn="over"> <mx:SetProperty target="{e1}" name="color" value="0xBBBBDD" /> <mx:SetProperty target="{e2}" name="color" value="0xBBBBDD" /> </mx:State> <mx:State name="disabled" > <mx:SetProperty target="{s}" name="color" value="0xAAAAAA" /> <mx:SetProperty target="{e2}" name="color" value="0xF0F0F0" /> </mx:State> </states> <content> <mx:Graphic left="0" top="0" right="0" bottom="0" scaleGridLeft="6" scaleGridTop="6" scaleGridRight="44" scaleGridBottom="14"> <mx:Rect width="50" height="20" radiusX="6" radiusY="6"> <mx:fill> <mx:SolidColor id="s" color="0x666666" /> </mx:fill> </mx:Rect> <mx:Rect width="48" height="18" x="1" y="1" radiusX="5" radiusY="5"> <mx:fill> <mx:LinearGradient rotation="90"> <mx:GradientEntry id="e2" color="0xFFFFFF" alpha="0.8" /> <mx:GradientEntry id="e1" color="0xDEDEDE" alpha="0.6" /> </mx:LinearGradient> </mx:fill> </mx:Rect> </mx:Graphic> <ContentHolder horizontalCenter="0" verticalCenter="1" left="10" right="10" content="{data.content}" layout="flex.layout.HorizontalLayout" /> </content> </Skin> AFTER - Inline states syntax: <Skin xmlns:mx="library:ns.adobe.com/flex/halo" xmlns:m="http://ns.adobe.com/mxml/2009" > <m:states> <m:State name="up" /> <m:State name="over"/> <m:State name="down"/> <m:State name="disabled" /> </m:states> <content> <mx:Graphic left="0" top="0" right="0" bottom="0" scaleGridLeft="6" scaleGridTop="6" scaleGridRight="44" scaleGridBottom="14"> <mx:Rect width="50" height="20" radiusX="6" radiusY="6"> <mx:fill> <mx:SolidColor color="0x666666" color.over="0x6666BB" color.down="0x6666BB" color.disabled="0xAAAAAA"/> </mx:fill> </mx:Rect> <mx:Rect width="48" height="18" x="1" y="1" radiusX="5" radiusY="5"> <mx:fill> <mx:LinearGradient rotation="90"> <mx:GradientEntry color="0xFFFFFF" color.down="0xBBBBDD" color.over="0xF0F0F0" color.disabled="0xF0F0F0" alpha="0.8" /> <mx:GradientEntry color="0xDEDEDE" color.down="0xBBBBDD" alpha="0.6" /> </mx:LinearGradient> </mx:fill> </mx:Rect> </mx:Graphic> <ContentHolder horizontalCenter="0" verticalCenter="1" left="10" right="10" content="{data.content}" layout="flex.layout.HorizontalLayout" /> </content> </Skin> B FeaturesStateful XML/E4X Nodes - There is an ask to allow descendants of XML and XMLList tags to support the new states syntax. If the feature is green-lit at a later date, an associated mini-spec will be published. Stateful Model Nodes - There is an ask to allow descendants of MXML datamodel (mx:Model) nodes to support the new states syntax. If the feature is green-lit at a later date, an associated mini-spec will be published. Enhanced Runtime API - As a fit and finish task, it would be prudent to update the runtime states API to follow closer to the way the new syntax works. e.g. A helper would be provided that would allow a developer to setPropertyForState(object, property, state) for instance. Or specifically set the include or exclude list for a given component instance. Essentially an API divorced from the notion of the current runtime States and Overrides model. When the work is done on this feature, a mini-spec will be circulated. Additional Implementation DetailsImplementation Design and ImplicationsA Phased ApproachAs mentioned previously, the states concept as first introduced in Flex 2.x and carried forward in Flex 3.0 will be promoted to a first-class MXML language feature for Flex 4.0. This means, for instance, that state-specific objects will no longer be limited to visual children (UIComponents). In order to get to a point where our tooling products can begin utilizing the new language features, we will phase in the functionality in stages.
Phase One Compiler and Framework ChangesCompiler ChangesThe MXML sub-compiler will be enhanced with direct support for states as follows:
SDK/API Changes
Nice To Have:
Prototype WorkThe bulk of the necessary compiler changes have been prototyped and passed along to the compiler team for review. An analysis of the changes with regards to performance was also done, using our stock performance automation tests, with good results. Compiler WorkPlease refer to the preceding Implementation Design and Implications section. Web Tier Compiler ImpactNot Applicable. Flex Feature DependenciesThis feature is dependent on any state-related features such as Overlays, Effects, Transitions. Backwards CompatibilitySyntax changesThe legacy states syntax will be deprecated in favor of what is detailed here. A mechanism will be provided to utilize the classic states syntax if desired but only by opting out of the Flex 4 model altogether (e.g. via -compatibility-version or by removing any MXML 2009 (Flex 4) namespace declarations). BehaviorNot applicable Warnings/DeprecationA deprecation related warning will be issued if the use of Override children of states are used within a Flex 4 document. AccessibilityNot Applicable. PerformanceThe new syntax as interpreted by the compiler results in generated code comparable to the current Flex 3 runtime states model, so no performance regressions or injections should be introduced (e.g. the IOverride based classes are still utilized at runtime to accomplish state changes). GlobalizationNot Applicable. LocalizationCompiler FeaturesThe following state syntax related error and warning messages have been added to compiler_en.properties and require translation: StateResolutionError - Cannot resolve state '$(name)'. AmbiguousStateFilterError - The includeIn and excludeFrom keywords may not be specified concurrently. ...more will be added here as necessary. There are no help description or linker message additions at this time. Framework FeaturesNot Applicable. Issues and Recommendations
DocumentationThe new states functionality represents a significant overhaul to the way stateful documents and components are authored with MXML. An equally as significant documentation revision around the view states feature is required, detailing not only the new language keywords, but also providing comprehensive examples. QASuggested focus areas and test cases to consider (not exhaustive):
|
|
| You must be logged in to comment. |
|---|
