flex-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Cosma Colanicchia <cosma...@gmail.com>
Subject Re: Multidimensional States
Date Mon, 03 Jun 2013 07:45:13 GMT
Just trying to throw a quick thinking at it, in particular about the MXML
declaration mess - to avoid cartesian multiplication of states, couldn't we
just normalize them? I mean, grouping them in mutually exclusive groups,
which is the typical scenario:

<s:states>
  <s:ExclusiveStateGruop>
      <s:State name="up"/>
      <s:State name="down"/>
      <s:State name="over"/>
  </s:ExclusiveStateGruop>
  <s:ExclusiveStateGruop>
      <s:State name="nonFocused"/>
      <s:State name="focused"/>
  </s:ExclusiveStateGruop>
  <s:ExclusiveStateGruop>
      <s:State name="nonDefault"/>
      <s:State name="default"/>
  </s:ExclusiveStateGruop>
</s:states>

This is different from the current freely assignable state groups, in that
they define the mixing rules of the various base states - thus we
implicitly expressed all the possible (and valid) combinations of the
various base state (in this case, 3*2*2 = 12 possible valid states),
instead of manually declaring a lot of states with long and unreadable
names (like "overAndFocusedAndDefault").


The API should let specify multiple current states, as long as two mutually
exclusive state are not specified, for example with a sintax like this:

myComp.currentState = "up-focused-nonDefault" // VALID
myComp.currentState = "up-down-nonDefault" // INVALID

(to avoid confusion with current syntax, I think we should pick another
separator different from "," to express these "state trails") We may also
agree that the first state declared of each exclusive group is the default
value of its group, so that we can write:

myComp.currentState = "up" // same as "up-nonFocused-nonDefault"


Then, current state groups and MXML syntax would kick in, it should just
recognize the state trails:

<s:Rect includeIn="focused" alpha="0.5" alpha.default="0.7">
...
<s:Rect includeIn="focused-nonDefault">


Or, we could also supports additional MXML like:

<s:Rect alpha.up="0" alpha.over="0.5" alpha.over-focused="1.0"> ...

In which more specific value assignment should win over more generic ones
(something like that is already implemented, when you write alpha="0"
alpha.over="1").


Finally, from a compatibility point of view, a component using an
"old-style" states set could be just translated to a single mutually
exclusive state group (in fact, it is one) - the compiler should just
prevent mixing the two approaches.



2013/6/3 Alex Harui <aharui@adobe.com>

> Hi Max,
>
> Thanks for detailing it out.
>
> In the relatively few minutes I've spent thinking about the problem, I
> pondered whether the answer is to expand on how s:State is used, or simply
> allow you to have conditional attributes based on things other than
> States.  IMO, along with this set of States is code you have to write to
> set currentState appropriately, and in many cases, it seems like you're
> just going to wire it to some other property.  For this Button example, we
> don't really have a "isFocused" property, but we certainly could add one,
> and the "Default" states are all tied to what is currently called the
> 'emphasized' property.  So why not some syntax that just lets you set a
> property based on some other property?  For sure there can be collisions,
> or maybe it won't handle complex situations, but it seems like when I look
> at the AS that we write when we give up on States, they are generally
> simple expressions.  So, while property.state implies the value of that
> property when currentState is that State, maybe some other delimiter
> besides '.' can be used to dictate the value of a property when some other
> property is true or false or some simple expression.  I'm going to use "("
> in this example, which may not be legal XML, but should give you an idea)
>
> Then the states are simply:
>
>     <s:states>
>       <s:State name="up"/>
>       <s:State name="down"/>
>       <s:State name="over"/>
>     </s:states>
>
> And some widgets in the skin look like:
>
>
>     <s:Rect id="focusBorder" includeIn(isFocused)=""
>             left(emphasized)=-2 left=-1 />
>     <s:Rect id="background" color.up="..." color.down="..."
>             color(currentState=="up"&&emphasized)
>
> Now, when I look at that, I wonder: why not just use binding?
>
>     <s:Rect id="focusBorder" includeIn="{isFocused}"
>             left="{emphasized ? -1 : -2}" />
>     <s:Rect id="background" color.up="..." color.down="..."
>             color="{(currentState=="up"&&emphasized) ? "red" : "blue"}"
>
> Yes, I know we told you not to use binding in skins for performance
> reasons, but I am hoping to find ways to make databinding much faster in
> FlexJS.
>
>
>
> And one final thought:  In FlexJS, we may end up saying that you shouldn't
> specify these visual aspects in the "skin".  Instead, you might want to
> use more CSS, and then we could implement attribute selectors on the AS
> side since that CSS is going to work on the JS side.
>
> Then you just have:
>
>     <s:Rect id="focusBorder" className="buttonFocusBorder"
>     <s:Rect id="background" className="buttonBackground"
>
>
> And CSS like:
>
> .buttonFocusBorder#focusBorder[emphasized] {
>   left: -2;
> }
> .buttonFocusBorder#focusBorder {
>   left: -1;
> }
>
> .buttonBackground#background[emphasize] {
>   color: "blue";
> }
>
> .buttonBackground#background {
>   color: "red";
> }
>
> I'm not sure we can extend the set of attributes or not, but we can also
> specify multiple class selector names, so we might be able to handle
> custom properties that way.
>
>
> -Alex
>
> On 6/2/13 10:45 AM, "Maxime Cowez" <maxime.cowez@gmail.com> wrote:
>
> >I'd like to make this more concrete. Let's take Alex' Button example and
> >compare the 'stateGroups' way to the 'multidimensional states' way.
> >Here's what that Button's States might look like with 'stateGroups'.
> >
> >    <s:states>
> >        <s:State name="up" stateGroups="upStates,normal"/>
> >        <s:State name="down" stateGroups="downStates,normal"/>
> >        <s:State name="over" stateGroups="overStates,normal"/>
> >        <s:State name="upAndDefault" stateGroups="upStates,default"/>
> >        <s:State name="downAndDefault" stateGroups="downStates,default"/>
> >        <s:State name="overAndDefault" stateGroups="overStates,default"/>
> >        <s:State name="upAndFocused" stateGroups="upStates,focused"/>
> >        <s:State name="downAndFocused" stateGroups="downStates,focused"/>
> >        <s:State name="overAndFocused" stateGroups="overStates,focused"/>
> >        <s:State name="upAndDefaultAndFocused"
> >stateGroups="upStates,default,focused"/>
> >        <s:State name="downAndDefaultAndFocused"
> >stateGroups="downStates,default,focused"/>
> >        <s:State name="overAndDefaultAndFocused"
> >stateGroups="overStates,default,focused"/>
> >    </s:states>
> >
> >The states declaration looks heavy and is rather hard to decipher: -1
> >
> >The actual component would look something like:
> >
> >    <s:Rect id="focusBorder" includeIn="focused"/>
> >    <s:Rect id="background" color.upStates="..." color.downStates="..."
> >color.overStates="..."/>
> >
> >Easy to read, easy to use: +1 (I know Rect doesn't have a color attribute,
> >but you get what I mean).
> >But I haven't been entirely fair: what if I want a different background
> >color scheme for the default states? I can't do:
> >
> >    <s:Rect id="background" color.upStates="..." color.downStates="..."
> >color.overStates="..."
> >                            color.upAndDefault="..."
> >color.downAndDefault="..." color.overAndDefault="..."/>
> >
> >That will throw a compiler exception (because 'upAndDefault' is part of
> >'upStates' group and thus I have a duplicate color declaration). I can fix
> >this, but it would require even more stateGroups, e.g. normalUpStates,
> >defaultUpstates, normalDownStates, etc.: -1
> >Or I could declare a color for every single base state, but that would be
> >extremely verbose and have duplicate declarations of the same color.
> >
> >Conclusion: anything can be done, but it can become overly complex.
> >
> >
> >Here's what the same Button's States would look like with
> >'multidimensional
> >states':
> >
> >    <s:states>
> >        <s:State name="up"/>
> >        <s:State name="down"/>
> >        <s:State name="over"/>
> >        <s:State name="focused"/>
> >        <s:State name="default"/>
> >    </s:states>
> >
> >Well that's extremely terse and clear: +2
> >
> >The actual component would look something like:
> >
> >    <s:Rect id="focusBorder" includeIn="focused"/>
> >    <s:Rect id="background" color.up="..." color.down="..."
> >color.over="..."/>
> >
> >I'm assuming a pressed default button that has focus would have its
> >`currenState` set to ["default", "focused", "down"].
> >That's still better than the 'stateGroups' way: +1
> >
> >But let's see what happens with the dual color scheme. Well it can't be
> >done: -100
> >Unless we come up with something like this:
> >
> >    <s:Rect id="background" color.up="..." color.down="..."
> >color.over="..."
> >                            color.up.default="..."
> >color.down.default="..."
> >color.over.default="..."/>
> >
> >The more precise the state selector, the more precedence it takes. Doesn't
> >look half bad. If it can be done technically, that is.
> >A possible downside is that you can create situations where the developer
> >doesn't provide a 'required' state. For instance with this Button example,
> >if neither 'up', 'down' or 'over' are present in the 'currentState', the
> >'background' would have no color. This can be remedied, but takes careful
> >coding.
> >
> >Conclusion: with a new syntax this approach sure looks cleaner.
> >
> >I've been writing this as I was thinking about the subject, so I hope you
> >can make heads and tails of it ;)
> >
> >Max
> >
> >
> >On Sun, Jun 2, 2013 at 1:54 PM, Arnoud Bos
> ><arnoud@artim-interactive.nl>wrote:
> >
> >>
> >> Hi,
> >>
> >> I figure you can use some input from the community for this. I
> >>personally
> >> never use stategroups as i find them a bit confusing.
> >> So I tend to structure my components the way that it's not needed and
> >>use
> >> the normal straightforward states.
> >>
> >> IMHO states are one of the key features of Flex, stateGroups we can live
> >> without.
> >>
> >> just my 2 cents,
> >>
> >> Arnoud
> >>
> >> On 02-06-2013, at 08:49, Alex Harui <aharui@adobe.com> wrote:
> >>
> >> >> I've been coming across more and more cases where it would be great
> >>to
> >> >> have
> >> >> support for multidimensional states. What this looks like and how
> >>it's
> >> >> used
> >> >> I'm not sure. Maybe we can discuss ideas.
> >> > Yes, let's discuss.  I'm actually finishing up getting simple states
> >>to
> >> > work in FlexJS. I haven't started work on StateGroup because I wasn't
> >> sure
> >> > how often they are used and whether they are considered the "right"
> >> > solution by folks.
> >> >
> >>
> >> Met vriendelijke groet,
> >>
> >> Arnoud Bos
> >> Artim interactive
> >>
> >> E  arnoud@artim-interactive.nl
> >> W  www.artim-interactive.nl
> >> T  +31 6 246 40 216
> >> A  Elisabeth Wolffstraat 77-3
> >>    1053TT Amsterdam
> >>
> >>
> >>
> >>
> >>
> >>
>
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message