From: YeongJong Lee Date: Fri, 27 Nov 2020 05:09:53 +0000 (+0900) Subject: [NUI] Add ControlStateTypeConverter for xaml (#2185) X-Git-Tag: submit/tizen/20201208.153507~1^2~17 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=33ae18063254ba9540e2ae76298361c98d95b156;p=platform%2Fcore%2Fcsapi%2Ftizenfx.git [NUI] Add ControlStateTypeConverter for xaml (#2185) Custom ConstrolState is now available in xaml. ### Sample XamlPage.xaml ```xaml ``` MyButton.cs ```cs public class MyButton : Button { public MyButton(ButtonStyle buttonStyle) : base(buttonStyle) {} public void SetControlState(ControlState s) => ControlState = s; } ``` Main.cs ```cs protected override void OnCreate() { base.OnCreate(); Window.Instance.BackgroundColor = new Color(227 / 255f, 255 / 255f, 227 / 255f, 1.0f); Window.Instance.KeyEvent += OnKeyEvent; View root = new View(); root.WidthSpecification = LayoutParamPolicies.MatchParent; root.HeightSpecification = LayoutParamPolicies.MatchParent; root.Layout = new AbsoluteLayout(); Window.Instance.GetDefaultLayer().Add(root); XamlPage xamlPage = new XamlPage(); root.Add(xamlPage); ControlState MyState = ControlState.Create("MyState"); Button button = new Button() { Position2D = new Position2D(100, 100) }; bool flag = false; button.Clicked += (object sender, ClickedEventArgs e) => { if (!flag) { xamlPage.MyButton.SetControlState(MyState); flag = true; } else { xamlPage.MyButton.SetControlState(ControlState.Focused + MyState); flag = false; } }; root.Add(button); } ``` --- diff --git a/src/Tizen.NUI/src/public/BaseComponents/ControlState.cs b/src/Tizen.NUI/src/public/BaseComponents/ControlState.cs index 14a7de2b7..205b88d99 100755 --- a/src/Tizen.NUI/src/public/BaseComponents/ControlState.cs +++ b/src/Tizen.NUI/src/public/BaseComponents/ControlState.cs @@ -26,6 +26,7 @@ namespace Tizen.NUI.BaseComponents /// Class for describing the states of the view. /// [EditorBrowsable(EditorBrowsableState.Never)] + [Binding.TypeConverter(typeof(ControlStateTypeConverter))] public class ControlState : IEquatable { private static readonly Dictionary stateDictionary = new Dictionary(); @@ -90,12 +91,7 @@ namespace Tizen.NUI.BaseComponents [EditorBrowsable(EditorBrowsableState.Never)] public bool IsCombined => stateList.Count > 1; - /// - /// Default Contructor. Please use or instead. - /// - // Do not open this constructor. This is only for xaml support. - [EditorBrowsable(EditorBrowsableState.Never)] - public ControlState() { } + private ControlState() { } private ControlState(string name) : this() => this.name = name; @@ -112,6 +108,8 @@ namespace Tizen.NUI.BaseComponents if (string.IsNullOrWhiteSpace(name)) throw new ArgumentException("name cannot be empty string", nameof(name)); + name = name.Trim(); + if (stateDictionary.TryGetValue(name, out ControlState state)) return state; @@ -302,76 +300,26 @@ namespace Tizen.NUI.BaseComponents newState.stateList.AddRange(rest); return newState; } - } - /// - /// The Key/Value pair structure. this is mutable to support for xaml. - /// - [EditorBrowsable(EditorBrowsableState.Never)] - public struct StateValuePair : IEquatable> - { - /// - /// The constructor with the specified state and value. - /// - /// The state - /// The value associated with state. - [EditorBrowsable(EditorBrowsableState.Never)] - public StateValuePair(ControlState state, T value) + class ControlStateTypeConverter : Binding.TypeConverter { - State = state; - Value = value; - } - - /// - /// The state - /// - [EditorBrowsable(EditorBrowsableState.Never)] - public ControlState State { get; set; } - /// - /// The value associated with state. - /// - [EditorBrowsable(EditorBrowsableState.Never)] - public T Value { get; set; } - - /// - [EditorBrowsable(EditorBrowsableState.Never)] - public bool Equals(StateValuePair other) => (Value.Equals(other.Value)) && (State == other.State); + public override object ConvertFromInvariantString(string value) + { + if (value != null) + { + value = value.Trim(); - /// - [EditorBrowsable(EditorBrowsableState.Never)] - public override bool Equals(object obj) - { - if (!(obj is StateValuePair)) - return false; + ControlState convertedState = new ControlState(); + string[] parts = value.Split(','); + foreach (string part in parts) + { + convertedState += Create(part); + } + return convertedState; + } - return Equals((StateValuePair)obj); + throw new InvalidOperationException($"Cannot convert \"{value}\" into {typeof(ControlState)}"); + } } - - /// - [EditorBrowsable(EditorBrowsableState.Never)] - public override int GetHashCode() => (State.GetHashCode() * 397) ^ Value.GetHashCode(); - - - /// - /// Compares whether the two StateValuePair are different or not. - /// - /// A on the left hand side. - /// A on the right hand side. - /// true if the StateValuePair are equal; otherwise, false. - [EditorBrowsable(EditorBrowsableState.Never)] - public static bool operator ==(StateValuePair lhs, StateValuePair rhs) => lhs.Equals(rhs); - - /// - /// Compares whether the two StateValuePair are same or not. - /// - /// A on the left hand side. - /// A on the right hand side. - /// true if the StateValuePair are not equal; otherwise, false. - [EditorBrowsable(EditorBrowsableState.Never)] - public static bool operator !=(StateValuePair lhs, StateValuePair rhs) => !(lhs == rhs); - - /// - [EditorBrowsable(EditorBrowsableState.Never)] - public override string ToString() => $"[{State}, {Value}]"; } } \ No newline at end of file diff --git a/src/Tizen.NUI/src/public/BaseComponents/Style/Selector.cs b/src/Tizen.NUI/src/public/BaseComponents/Style/Selector.cs index 07baed1e0..b6f04dd27 100755 --- a/src/Tizen.NUI/src/public/BaseComponents/Style/Selector.cs +++ b/src/Tizen.NUI/src/public/BaseComponents/Style/Selector.cs @@ -34,32 +34,32 @@ namespace Tizen.NUI.BaseComponents private readonly bool cloneable = typeof(ICloneable).IsAssignableFrom(typeof(T)); /// - /// The list for adding state-value pair. + /// The list for adding . /// [EditorBrowsable(EditorBrowsableState.Never)] - public IList> StateValueList { get; set; } = new List>(); + public IList> SelectorItems { get; set; } = new List>(); /// - /// Adds the specified state and value. + /// Adds the specified state and value to the . /// /// The state. /// The value associated with state. [EditorBrowsable(EditorBrowsableState.Never)] - public void Add(ControlState state, T value) => Add(new StateValuePair(state, value)); + public void Add(ControlState state, T value) => SelectorItems.Add(new SelectorItem(state, value)); /// - /// Adds the specified state and value. + /// Adds the specified state and value to the . /// - /// + /// The selector item class that stores a state-value pair. [EditorBrowsable(EditorBrowsableState.Never)] - public void Add(StateValuePair stateValuePair) + public void Add(SelectorItem selectorItem) { // To prevent a state from having multiple values, remove existing state-value pair. - int index = ((List>)StateValueList).FindIndex(x => x.State == stateValuePair.State); + int index = ((List>)SelectorItems).FindIndex(x => x.State == selectorItem.State); if (index != -1) - StateValueList.RemoveAt(index); + SelectorItems.RemoveAt(index); - StateValueList.Add(stateValuePair); + SelectorItems.Add(selectorItem); } /// 6 @@ -108,7 +108,7 @@ namespace Tizen.NUI.BaseComponents [EditorBrowsable(EditorBrowsableState.Never)] public T Normal { - get => ((List>)StateValueList).Find(x => x.State == ControlState.Normal).Value; + get => ((List>)SelectorItems).Find(x => x.State == ControlState.Normal).Value; set => Add(ControlState.Normal, value); } /// @@ -119,8 +119,7 @@ namespace Tizen.NUI.BaseComponents [EditorBrowsable(EditorBrowsableState.Never)] public T Pressed { - - get => ((List>)StateValueList).Find(x => x.State == ControlState.Pressed).Value; + get => ((List>)SelectorItems).Find(x => x.State == ControlState.Pressed).Value; set => Add(ControlState.Pressed, value); } /// @@ -131,7 +130,7 @@ namespace Tizen.NUI.BaseComponents [EditorBrowsable(EditorBrowsableState.Never)] public T Focused { - get => ((List>)StateValueList).Find(x => x.State == ControlState.Focused).Value; + get => ((List>)SelectorItems).Find(x => x.State == ControlState.Focused).Value; set => Add(ControlState.Focused, value); } /// @@ -142,7 +141,7 @@ namespace Tizen.NUI.BaseComponents [EditorBrowsable(EditorBrowsableState.Never)] public T Selected { - get => ((List>)StateValueList).Find(x => x.State == ControlState.Selected).Value; + get => ((List>)SelectorItems).Find(x => x.State == ControlState.Selected).Value; set => Add(ControlState.Selected, value); } /// @@ -153,8 +152,7 @@ namespace Tizen.NUI.BaseComponents [EditorBrowsable(EditorBrowsableState.Never)] public T Disabled { - - get => ((List>)StateValueList).Find(x => x.State == ControlState.Disabled).Value; + get => ((List>)SelectorItems).Find(x => x.State == ControlState.Disabled).Value; set => Add(ControlState.Disabled, value); } /// @@ -165,7 +163,7 @@ namespace Tizen.NUI.BaseComponents [EditorBrowsable(EditorBrowsableState.Never)] public T DisabledFocused { - get => ((List>)StateValueList).Find(x => x.State == ControlState.DisabledFocused).Value; + get => ((List>)SelectorItems).Find(x => x.State == ControlState.DisabledFocused).Value; set => Add(ControlState.DisabledFocused, value); } /// @@ -175,7 +173,7 @@ namespace Tizen.NUI.BaseComponents /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API. public T SelectedFocused { - get => ((List>)StateValueList).Find(x => x.State == ControlState.SelectedFocused).Value; + get => ((List>)SelectorItems).Find(x => x.State == ControlState.SelectedFocused).Value; set => Add(ControlState.SelectedFocused, value); } /// @@ -186,8 +184,7 @@ namespace Tizen.NUI.BaseComponents [EditorBrowsable(EditorBrowsableState.Never)] public T DisabledSelected { - - get => ((List>)StateValueList).Find(x => x.State == ControlState.DisabledSelected).Value; + get => ((List>)SelectorItems).Find(x => x.State == ControlState.DisabledSelected).Value; set => Add(ControlState.DisabledSelected, value); } @@ -199,7 +196,7 @@ namespace Tizen.NUI.BaseComponents [EditorBrowsable(EditorBrowsableState.Never)] public T Other { - get => ((List>)StateValueList).Find(x => x.State == ControlState.Other).Value; + get => ((List>)SelectorItems).Find(x => x.State == ControlState.Other).Value; set => Add(ControlState.Other, value); } @@ -207,7 +204,7 @@ namespace Tizen.NUI.BaseComponents /// Gets the number of elements. /// [EditorBrowsable(EditorBrowsableState.Never)] - public int Count => StateValueList.Count; + public int Count => SelectorItems.Count; /// /// Get value by State. @@ -226,12 +223,15 @@ namespace Tizen.NUI.BaseComponents return true; } + if (state == null) + throw new ArgumentNullException(nameof(state)); + result = default; - int index = ((List>)StateValueList).FindIndex(x => x.State == state); + int index = ((List>)SelectorItems).FindIndex(x => x.State == state); if (index >= 0) { - result = StateValueList[index].Value; + result = SelectorItems[index].Value; return true; } @@ -241,18 +241,18 @@ namespace Tizen.NUI.BaseComponents } if (state.IsCombined) { - index = ((List>)StateValueList).FindIndex(x => state.Contains(x.State)); + index = ((List>)SelectorItems).FindIndex(x => state.Contains(x.State)); if (index >= 0) { - result = StateValueList[index].Value; + result = SelectorItems[index].Value; return true; } } - index = ((List>)StateValueList).FindIndex(x => x.State == ControlState.Other); + index = ((List>)SelectorItems).FindIndex(x => x.State == ControlState.Other); if (index >= 0) { - result = StateValueList[index].Value; + result = SelectorItems[index].Value; return true; } @@ -266,7 +266,7 @@ namespace Tizen.NUI.BaseComponents public void Clear() { All = default; - StateValueList.Clear(); + SelectorItems.Clear(); } /// @@ -275,7 +275,7 @@ namespace Tizen.NUI.BaseComponents { string result = $"[All, {All}]"; - foreach (var item in StateValueList) + foreach (var item in SelectorItems) { result += $", {item}"; } @@ -312,20 +312,19 @@ namespace Tizen.NUI.BaseComponents if (cloneable) { All = (T)((ICloneable)other.All)?.Clone(); - StateValueList = ((List>)other.StateValueList).ConvertAll(m => new StateValuePair(m.State, (T)((ICloneable)m.Value)?.Clone())); + SelectorItems = ((List>)other.SelectorItems).ConvertAll(m => new SelectorItem(m.State, (T)((ICloneable)m.Value)?.Clone())); } else { All = other.All; - StateValueList = ((List>)other.StateValueList).ConvertAll(m => m); + SelectorItems = ((List>)other.SelectorItems).ConvertAll(m => m); } } internal bool HasMultiValue() { - return StateValueList.Count > 1; + return SelectorItems.Count > 1; } - } /// @@ -467,4 +466,64 @@ namespace Tizen.NUI.BaseComponents } } } + + /// + /// The selector item class that stores a state-value pair. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public class SelectorItem + { + /// + /// The default constructor. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public SelectorItem() {} + + /// + /// The constructor with the specified state and value. + /// + /// The state + /// The value associated with state. + [EditorBrowsable(EditorBrowsableState.Never)] + public SelectorItem(ControlState state, T value) + { + State = state; + Value = value; + } + + /// + /// The state + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public ControlState State { get; set; } + + /// + /// The value associated with state. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public T Value { get; set; } + + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override string ToString() => $"[{State}, {Value}]"; + } + + /// + /// Extension class for . + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static class SelectorExtensions + { + /// + /// Adds the specified state and value to the . + /// + /// The list for adding state-value pair. + /// The state. + /// The value associated with state. + [EditorBrowsable(EditorBrowsableState.Never)] + public static void Add(this IList> list, ControlState state, T value) + { + list.Add(new SelectorItem(state, value)); + } + } }