I have a skin with 3 states. I may have more states in the future. But it's a tool bar with normal state, and then an expanded view where only one expanded view should be visible at a time.
When I had two states I could easily transition between the two using the transition code below. But now that I have three states the secondary state is not closed. If I'm in a secondary state I want to close out of it first.
Here is my code from the skin class:
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<fx:Script>
<![CDATA[
protected function imageViewButton_clickHandler(event:MouseEvent):void
{
if (currentState==NORMAL_VIEW) {
currentState = IMAGE_VIEW;
}
else {
currentState = NORMAL_VIEW;
}
}
protected function linkViewButton_clickHandler(event:MouseEvent):void
{
if (currentState==NORMAL_VIEW) {
currentState = LINK_VIEW;
}
else {
currentState = NORMAL_VIEW;
}
}
public static var NORMAL_VIEW:String = "normal";
public static var LINK_VIEW:String = "linkView";
public static var IMAGE_VIEW:String = "imageView";
]]>
</fx:Script>
<s:transitions>
<s:Transition fromState="normal" toState="*">
<s:Sequence duration="250">
<s:Resize target="{this}"/>
<s:AddAction target="{linkViewButton}"/>
<s:Fade target="{linkViewButton}"/>
</s:Sequence>
</s:Transition>
<s:Transition fromState="linkView" toState="*">
<s:Sequence duration="250">
<s:Fade target="{linkViewButton}"/>
<s:Resize target="{this}"/>
</s:Sequence>
</s:Transition>
<s:Transition fromState="imageView" toState="*">
<s:Sequence duration="250">
<s:Fade target="{imageViewButton}"/>
<s:Resize target="{this}"/>
</s:Sequence>
</s:Transition>
</s:transitions>
<s:states>
<s:State name="normal"/>
<s:State name="linkView"/>
<s:State name="imageView"/>
</s:states>
<s:VGroup width="100%">
<s:HGroup width="100%" >
<s:Button label="Button 1" />
<s:Line height="100%">
<s:stroke>
<s:SolidColorStroke color="#B3C2B8"/>
</s:stroke>
</s:Line>
<s:ToggleButton id="gotoLinkView" label="Link Details" click="linkViewButton_clickHandler(event)"/>
<s:Line height="100%">
<s:stroke>
<s:SolidColorStroke color="#B3C2B8"/>
</s:stroke>
</s:Line>
<s:ToggleButton id="gotoImageView" label="Image Details" click="imageViewButton_clickHandler(event)"/>
<s:Line height="100%">
<s:stroke>
<s:SolidColorStroke color="#B3C2B8"/>
</s:stroke>
</s:Line>
</s:HGroup>
<s:Button id="linkViewButton" label="Link View"
includeIn="linkView"
itemCreationPolicy="immediate" width="100%"/>
<s:Button id="imageViewButton" label="Image View"
includeIn="imageView"
itemCreationPolicy="immediate"
width="100%"/>
</s:VGroup>
</s:WindowedApplication>
Here is the full example of transitioning between multiple states where there could be open states and where you want to preserve the transition animations or reverse them out of the open state before transitioning into another open state. Thanks to @Vesper for his catch on the logic error.
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
applicationComplete="windowedapplication1_applicationCompleteHandler(event)"
stateChangeComplete="windowedapplication1_stateChangeCompleteHandler(event)">
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
public static var NORMAL_VIEW:String = "normal";
public static var LINK_VIEW:String = "linkView";
public static var IMAGE_VIEW:String = "imageView";
public var deferredState:String;
public var deferredToggle:Object;
protected function linkViewButton_clickHandler(event:MouseEvent):void
{
if (currentState!=LINK_VIEW) {
if (currentState != NORMAL_VIEW) {
deferredState = LINK_VIEW;
currentState = NORMAL_VIEW;
deferredToggle = event.currentTarget;
deselectToggles(deferredToggle);
return;
}
currentState = LINK_VIEW;
}
else {
currentState = NORMAL_VIEW;
}
}
protected function imageViewButton_clickHandler(event:MouseEvent):void
{
if (currentState!=IMAGE_VIEW) {
if (currentState != NORMAL_VIEW) {
deferredState = IMAGE_VIEW;
currentState = NORMAL_VIEW;
deferredToggle = event.currentTarget;
deselectToggles(deferredToggle);
return;
}
currentState = IMAGE_VIEW;
}
else {
currentState = NORMAL_VIEW;
}
}
protected function windowedapplication1_stateChangeCompleteHandler(event:FlexEvent):void
{
//trace("State change complete");
if (currentState==NORMAL_VIEW) {
//trace("Normal state");
}
if (deferredState!=null) {
currentState = deferredState;
deferredState = null;
deferredToggle = null;
}
}
public function deselectToggles(selectedToggle:Object=null):void {
var toggle:ToggleButton;
for (var i:int = 0; i < toggles.length; i++)
{
toggle = toggles[i] as ToggleButton;
if (toggle!=selectedToggle) {
toggle.selected = false;
}
}
}
protected function windowedapplication1_applicationCompleteHandler(event:FlexEvent):void
{
toggles.push(gotoLinkView, gotoImageView);
}
public var toggles:Array = [];
]]>
</fx:Script>
<s:transitions>
<s:Transition fromState="normal" toState="linkView" interruptionBehavior="stop" autoReverse="true">
<s:Sequence duration="250"
effectStart="trace('normal to link view')"
>
<s:Resize target="{borderContainer}"/>
<s:AddAction target="{linkViewButton}"/>
<s:Fade target="{linkViewButton}"/>
</s:Sequence>
</s:Transition>
<s:Transition fromState="normal" toState="imageView" interruptionBehavior="stop" autoReverse="true">
<s:Sequence duration="250"
effectStart="trace('normal to image view')"
>
<s:Resize target="{borderContainer}"/>
<s:AddAction target="{imageViewButton}"/>
<s:Fade target="{imageViewButton}"/>
</s:Sequence>
</s:Transition>
</s:transitions>
<s:states>
<s:State name="normal"/>
<s:State name="linkView"/>
<s:State name="imageView"/>
</s:states>
<s:BorderContainer width="100%" id="borderContainer">
<s:layout>
<s:VerticalLayout/>
</s:layout>
<s:HGroup width="100%" >
<s:Button label="Button 1" />
<s:Line height="100%">
<s:stroke>
<s:SolidColorStroke color="#B3C2B8"/>
</s:stroke>
</s:Line>
<s:ToggleButton id="gotoLinkView" label="Link Details" click="linkViewButton_clickHandler(event)"/>
<s:Line height="100%">
<s:stroke>
<s:SolidColorStroke color="#B3C2B8"/>
</s:stroke>
</s:Line>
<s:ToggleButton id="gotoImageView" label="Image Details" click="imageViewButton_clickHandler(event)"/>
<s:Line height="100%">
<s:stroke>
<s:SolidColorStroke color="#B3C2B8"/>
</s:stroke>
</s:Line>
</s:HGroup>
<s:Button id="linkViewButton"
label="Link View"
height="100"
includeIn="linkView"
itemCreationPolicy="immediate" width="100%"/>
<s:Button id="imageViewButton"
height="100"
label="Image View"
includeIn="imageView"
itemCreationPolicy="immediate"
width="100%"/>
</s:BorderContainer>
</s:WindowedApplication>