[NUI] add ControlState class to support combined and custom state (#1762)
### Custom State
You can define your own control states. first, declare ControlState variable
and initialize using `ControlState.Create`.
```
public class MyButton : Button {
...
ControlState MyState = ControlState.Create("MyState");
...
}
```
And assign to `View.ControlState`.
```
void OnStateChanged(...) {
ControlState = MyState;
}
```
If you want to assign the value of custom state to `Selector`, use
`Add(ControlState state, object value)`.
```
Selector<string> textSelector = new Selector<string>();
textSelector.Add(ControlState.Pressed, "Pressed!");
textSelector.Add(MyState, "MyText");
```
or
```
Selector<string> textSelector = new Selector<string>()
{
{ ControlState.Pressed, "Pressed!" },
{ MyState, "MyText" }
};
```
### Combined State
To implement your own combined control states, you can use the `+` or `+=`
operators.
For example, `MyCombinedStateX` are all the same.
```
ControlState MyCombinedStateA =
ControlState.Create(ControlState.Pressed, ControlState.Focused);
ControlState MyCombinedStateB = ControlState.Pressed + ControlState.Focused;
```
Note that `Normal` and `All` state cannot be combined with other states.
`Normal` state is ignored. however, `All` state will ignore other states.
```
ControlState.Create(ControlState.Pressed, ControlState.Focused, ControlState.Normal) ==
ControlState.Create(ControlState.Pressed, ControlState.Focused)
ControlState.Create(ControlState.All, ControlState.Pressed, ControlState.Focused) ==
ControlState.Create(ControlState.All)
```
### ControlState in Xaml
It will support new initialization syntax.
Legacy:
```
<c:TextLabelStyle.Text>
<c:Selector x:TypeArguments="x:String" Normal="button" Pressed="pressed!!"/>
</c:TextLabelStyle.Text>
```
New:
```
<c:TextLabelStyle.Text>
<c:StateValuePair x:TypeArguments="x:String" State="Normal" Value="button"/>
<c:StateValuePair x:TypeArguments="x:String" State="Pressed" Value="pressed!!" />
<c:StateValuePair x:TypeArguments="x:String" State="MyState" Value="my state!" />
<c:StateValuePair x:TypeArguments="x:String" State="MyState,Normal,Focused" Value="my combined state!" />
</c:TextLabelStyle.Text>
```
However, it won't work because there is no converter of `ControlState`.
The next step would be to implement `ControlState` converter.
14 files changed: