This became a long email. TLDR section at the end.

I went back and checked on the "inherits" property and it turns out it is
"basedOn". I don't remember seeing any documentation on this but it appears
to work:

    <s:states>
        <s:State name="state1"/>
        <s:State name="state2"/>
        <s:State name="state3" basedOn="state2" />
    </s:states>

    <s:HGroup top="30">
        <s:Button label="state 1" click="currentState='state1'" />
        <s:Button label="state 2" click="currentState='state2'"/>
        <s:Button label="state 3 based on state 2"
click="currentState='state3'"/>
    </s:HGroup>

    <s:BorderContainer width="300" height="300" verticalCenter="0"
horizontalCenter="0"

             >
        <s:Button id="myButton"
                  label.state1="Width is 100"
                  label.state2="Width is 200"
                  label.state3="Based on state 2 and color is red"
                  width.state1="100"
                  width.state2="200"
                  color.state3="red"
                  />
    </s:BorderContainer>

The third state inherits all the properties of the second state and adds
it's own.

Does this help solve anything we've discussed so far?

>From what I can tell it does but still has some problems. For example, what
if you have a state that takes styles from more than one defined state, ie
showing both the default and focused states at the same time like in your
Button example. This would be the "up-default-focused" state. The upDefault
and upFocused are both based on the "up" state. The basedOn poroperty only
lets you inherit from one.

One way to make it work is to base the combined state on the original up,
over down states and redefine the default and focused styles again (if the
state overrides a style). Or if it doesn't override a style then you would
need to add include those components in the includeIn tag like so,

    <s:states>
        <s:State name="up"/>
        <s:State name="over"/>
        <s:State name="down"/>

        <s:State name="upDefault" basedOn="up"/>
        <s:State name="overDefault" basedOn="over"/>
        <s:State name="downDefault" basedOn="down"/>

        <s:State name="upFocused" basedOn="up"/>
        <s:State name="overFocused" basedOn="over"/>
        <s:State name="downFocused" basedOn="down"/>

        <s:State name="upDefaultFocused" basedOn="up"/>
        <s:State name="overDefaultFocused" basedOn="over"/>
        <s:State name="downDefaultFocused" basedOn="down"/>
    </s:states>

    <s:HGroup top="30">
        <s:Button label="up" click="currentState='up'" />
        <s:Button label="over" click="currentState='down'"/>
        <s:Button label="down" click="currentState='over'"/>

        <s:Button label="up default" click="currentState='upDefault'" />
        <s:Button label="over default" click="currentState='overDefault'"/>
        <s:Button label="down default" click="currentState='downDefault'"/>

        <s:Button label="up focused" click="currentState='upFocused'" />
        <s:Button label="over focused" click="currentState='overFocused'"/>
        <s:Button label="down focused" click="currentState='downFocused'"/>

        <s:Button label="up focused"
click="currentState='upDefaultFocused'" />
        <s:Button label="over focused"
click="currentState='overDefaultFocused'"/>
        <s:Button label="down focused"
click="currentState='downDefaultFocused'"/>
    </s:HGroup>

    <s:BorderContainer width="400" height="300" verticalCenter="0"
horizontalCenter="0">

        <s:layout>
            <s:HorizontalLayout />
        </s:layout>

        <s:Button id="myButton"
                  label.up="Up"
                  label.down="Down"
                  label.over="Over"
                  />

        <!-- DEFAULT -->
        <s:Label
includeIn="upDefault,overDefault,downDefault,upDefaultFocused,overDefaultFocused,downDefaultFocused"
                 color="red"
                 fontWeight="bold"
                 text.up="Default (up)"
                 text.over="Default (over)"
                 text.down="Default (down)"
                 text.upDefaultFocused="Default and Focused (up)"
                 text.overDefaultFocused="Default and Focused (over)"
                 text.downDefaultFocused="Default and Focused (down)"
                 />

        <!-- FOCUSED -->
        <s:Label
includeIn="upFocused,overFocused,downFocused,upDefaultFocused,downDefaultFocused,overDefaultFocused"
                 color="blue"
                 fontWeight="bold"
                 text.up="Focused (up)"
                 text.over="Focused (over)"
                 text.down="Focused (down)"
                 text.upDefaultFocused="Default and Focused (up)"
                 text.overDefaultFocused="Default and Focused (over)"
                 text.downDefaultFocused="Default and Focused (down)"
                 />

    </s:BorderContainer>


The text.upDefaultFocused, text.overDefaultFocused, etc inline attributes
are optional in this case.

If you combined the above example with state groups you would get the
following:

    <!--<s:states>
        <s:State name="up"/>
        <s:State name="over"/>
        <s:State name="down"/>

        <s:State name="upDefault" basedOn="up" stateGroups="default"/>
        <s:State name="overDefault" basedOn="over" stateGroups="default"/>
        <s:State name="downDefault" basedOn="down" stateGroups="default"/>

        <s:State name="upFocused" basedOn="up" stateGroups="focused"/>
        <s:State name="overFocused" basedOn="over" stateGroups="focused"/>
        <s:State name="downFocused" basedOn="down" stateGroups="focused"/>

        <s:State name="upDefaultFocused" basedOn="up"
stateGroups="defaultFocused"/>
        <s:State name="overDefaultFocused" basedOn="over"
stateGroups="defaultFocused"/>
        <s:State name="downDefaultFocused" basedOn="down"
stateGroups="defaultFocused"/>
    </s:states>

    <s:HGroup top="30">
        <s:Button label="up" click="currentState='up'" />
        <s:Button label="over" click="currentState='down'"/>
        <s:Button label="down" click="currentState='over'"/>

        <s:Button label="up default" click="currentState='upDefault'" />
        <s:Button label="over default" click="currentState='overDefault'"/>
        <s:Button label="down default" click="currentState='downDefault'"/>

        <s:Button label="up focused" click="currentState='upFocused'" />
        <s:Button label="over focused" click="currentState='overFocused'"/>
        <s:Button label="down focused" click="currentState='downFocused'"/>

        <s:Button label="up focused"
click="currentState='upDefaultFocused'" />
        <s:Button label="over focused"
click="currentState='overDefaultFocused'"/>
        <s:Button label="down focused"
click="currentState='downDefaultFocused'"/>
    </s:HGroup>

    <s:BorderContainer width="300" height="300" verticalCenter="0"
horizontalCenter="0">

        <s:layout>
            <s:HorizontalLayout />
        </s:layout>

        <s:Button id="myButton"
                  label.up="Up"
                  label.down="Down"
                  label.over="Over"
                  />

        <s:Label includeIn="default,defaultFocused"
                 color="red"
                 fontWeight="bold"
                 text.up="Default (up)"
                 text.over="Default (over)"
                 text.down="Default (down)"
                 />

        <s:Label includeIn="focused,defaultFocused"
                 color="blue"
                 fontWeight="bold"
                 text.up="Focused (up)"
                 text.over="Focused (over)"
                 text.down="Focused (down)"/>

    </s:BorderContainer>


This reminds me of the old debate on inheritance vs composition. We can use
the basedOn to solve some issues but not others.

In CSS you can add in different styles and the last one declared wins. So
in HTML CSS you would do this with class="upButton emphasized" when
emphasized. In Flex CSS you would use currentState = "up" and
style+="default". Which is going on behind the scenes on the Spark Button
when you set the emphasized property to true:

if (_emphasized)
                super.styleName = style + " emphasized";
            else
                super.styleName = style.split(" emphasized").join("");


Alex, what would currentState look like as a organizing property? What does
conditional expressions look like?

And what are you doing here with isFocused,

  <s:Rect id="focusBorder" includeIn="{isFocused}"
            left="{emphasized ? -1 : -2}" />

I didn't know you could use bindings in an includeIn or is that a typo?

I like these:

currentState.mouse = "up";

currentState = "up-focused-nonDefault";

They look like something that can be done. In this case, maybe separate
with spaces to promote a more CSS type of syntax? This might be simplest to
support since it could apply properties in a last declared wins situation.

It might also be easier to solve if CSS in Flex supported defining
properties such as size and position?

Another concrete example to think about is the toggle button. It doubles
the amount of states as Button just with toggled vs normal.

>>I'd really like to know what the Flex team was
>>talking about when they mentioned this.
>It wasn't the "Flex team", it was just me.

I was referring to a few years ago as well. I heard Deepa ask devs if they
were interested in it at a usergroup meeting held in the Townsend offices.
I said yes, but I had no idea what she meant. It sounded important. :P

After working on mobile apps for a few years, each with different
requirements, what I'm doing now is creating multiple applications and in
some cases I can reuse some of the layout and UI components.

My projects look like this:


MobileProject (3 or more applications)
 MyAndroidApplication
    applicationDPI="320"
    <style source="androidstyles.css"/>
    <Group id=containerGroup width=100% height=100% />

 MyIPhoneApplication
    <style source="iphonestyles.css"/>
    <Group id=containerGroup width=100% height=100% />

 MyIPadApplication
    <style source="ipadstyles.css"/>
    <Group id=containerGroup width=100% height=100%/>

The container group component looks like this:


    <s:states>
        <s:State name="home"/>
        <s:State name="library"/>
        <s:State name="instructions"/>
        <s:State name="settings"/>
    </s:states>

    <views:Home         id="home"         includeIn="home"
width="100%" height="100%" ownerComponent="{this}"/>
    <views:Library         id="library"     includeIn="library"
width="100%" height="100%" ownerComponent="{this}"/>
    <views:Instructions id="instructions" includeIn="instructions"
width="100%" height="100%" ownerComponent="{this}" />
    <views:Settings     id="settings"     includeIn="settings"
width="100%" height="100%" ownerComponent="{this}" />


And the components and layout in them look like this

    <s:states>
        <s:State name="landscape" />
        <s:State name="portrait" />
    </s:states>

     <s:Scroller id="adjustmentsScroller"
                    height="60%"
                    height.landscape="100%"
                    width="100%"
                    width.landscape="50%"
                    horizontalScrollPolicy="off"
                    verticalScrollPolicy="on"
                    visible="{bitmapData!=null}"
                    includeInLayout="{bitmapData!=null}"
                    >


I have another use case. After watching this,
http://www.youtube.com/watch?v=kXTP8XqrSwE I was thinking about how to do
the same thing in Flex. To sum up the video it was about updating the
layout based on available size.

Right now with mobile development we have a solution for fixed size in
either portrait and landscape states and set the applicationDPI. We also
solve this with constraints and percentage based values.

Can we or should we support responsive design can with states?

Unfortunately, I'm not really providing any solutions so much as providing
more information and more of the challenges. I might also be working on
States in the near future.

TLDR - Think about how to support responsive design, should we add support
to define properties in CSS, should / could currentState support multiple
states, explain conditionals and examples of State basedOn property are
provided.


On Mon, Jun 3, 2013 at 10:29 AM, Alex Harui <aha...@adobe.com> wrote:

> Good input.
>
> If I understand your scenario (and maybe you or someone can post a small
> but real-world scenario), it supports my thinking that, instead of more
> ways to use State, that the currentState property should just be thought
> of as another organizing property, and the conditional setting of values
> should be somehow determined by any property on a component, not just
> currentState.  Then if you had an orientation property or maybe
> "isLandscape" then you would create conditional expressions to determine
> what to do.
>
> -Alex
>

Reply via email to