[NUI] remove StateValueCollection from Selector (#1975)
authorYeongJong Lee <cleanlyj@naver.com>
Wed, 16 Sep 2020 07:44:00 +0000 (16:44 +0900)
committerGitHub <noreply@github.com>
Wed, 16 Sep 2020 07:44:00 +0000 (16:44 +0900)
State-Value pair is now added to Selector.StateValueList without
duplicate check.

You need to use Selector.StateValueList when custom state-value pair is added
to Selector. and it is now able to add custom state and pre-defined
state in the same initializer.

Before:
```
Selector<string> textSelector = new Selector<string>()
{
    Normal = "Defalut",
    { ControlState.Pressed, "Pressed!" }, // build error
    { ControlState.Focused, "Focused!" }  // build error
};
```

After:
```
Selector<string> textSelector = new Selector<string>()
{
    Normal = "Default!",
    StateValueList =
    {
        { ControlState.Pressed, "Pressed!" },
        { ControlState.Focused, "Focused!" }
    }
};
```

Also, this patch fixes a bunch of CA2227(Collection properties should be read
only) warnings.

Co-authored-by: dongsug-song <35130733+dongsug-song@users.noreply.github.com>
src/Tizen.NUI/src/public/BaseComponents/Style/Selector.cs
src/Tizen.NUI/src/public/BaseComponents/Style/StateValueCollection.cs [deleted file]

index ebf5b1f..8b155fe 100755 (executable)
@@ -15,6 +15,7 @@
  *
  */
 using System;
+using System.Collections.Generic;
 using System.ComponentModel;
 using Tizen.NUI.Binding;
 using Tizen.NUI.Components;
@@ -27,10 +28,31 @@ namespace Tizen.NUI.BaseComponents
     /// <since_tizen> 6 </since_tizen>
     /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
     [EditorBrowsable(EditorBrowsableState.Never)]
-    public class Selector<T> : StateValueCollection<T>
+    public class Selector<T>
     {
         private readonly bool cloneable = typeof(T).IsAssignableFrom(typeof(ICloneable));
 
+        /// <summary>
+        /// The list for adding state-value pair.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public IList<StateValuePair<T>> StateValueList { get; private set; } = new List<StateValuePair<T>>();
+
+        /// <summary>
+        /// Adds the specified state and value to the <see cref="StateValueList"/>.
+        /// </summary>
+        /// <param name="state">The state.</param>
+        /// <param name="value">The value associated with state.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void Add(ControlState state, T value) => StateValueList.Add(new StateValuePair<T>(state, value));
+
+        /// <summary>
+        /// Adds the specified state and value to the <see cref="StateValueList"/>.
+        /// </summary>
+        /// <param name="stateValuePair"></param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void Add(StateValuePair<T> stateValuePair) => StateValueList.Add(stateValuePair);
+
         /// <since_tizen> 6 </since_tizen>
         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
         public static implicit operator Selector<T>(T value)
@@ -78,7 +100,7 @@ namespace Tizen.NUI.BaseComponents
         [EditorBrowsable(EditorBrowsableState.Never)]
         public T Normal
         {
-            get => Find(x => x.State == ControlState.Normal).Value;
+            get => ((List<StateValuePair<T>>)StateValueList).FindLast(x => x.State == ControlState.Normal).Value;
             set => Add(ControlState.Normal, value);
         }
         /// <summary>
@@ -89,7 +111,8 @@ namespace Tizen.NUI.BaseComponents
         [EditorBrowsable(EditorBrowsableState.Never)]
         public T Pressed
         {
-            get => Find(x => x.State == ControlState.Pressed).Value;
+
+            get => ((List<StateValuePair<T>>)StateValueList).FindLast(x => x.State == ControlState.Pressed).Value;
             set => Add(ControlState.Pressed, value);
         }
         /// <summary>
@@ -100,7 +123,7 @@ namespace Tizen.NUI.BaseComponents
         [EditorBrowsable(EditorBrowsableState.Never)]
         public T Focused
         {
-            get => Find(x => x.State == ControlState.Focused).Value;
+            get => ((List<StateValuePair<T>>)StateValueList).FindLast(x => x.State == ControlState.Focused).Value;
             set => Add(ControlState.Focused, value);
         }
         /// <summary>
@@ -111,7 +134,7 @@ namespace Tizen.NUI.BaseComponents
         [EditorBrowsable(EditorBrowsableState.Never)]
         public T Selected
         {
-            get => Find(x => x.State == ControlState.Selected).Value;
+            get => ((List<StateValuePair<T>>)StateValueList).FindLast(x => x.State == ControlState.Selected).Value;
             set => Add(ControlState.Selected, value);
         }
         /// <summary>
@@ -122,7 +145,8 @@ namespace Tizen.NUI.BaseComponents
         [EditorBrowsable(EditorBrowsableState.Never)]
         public T Disabled
         {
-            get => Find(x => x.State == ControlState.Disabled).Value;
+
+            get => ((List<StateValuePair<T>>)StateValueList).FindLast(x => x.State == ControlState.Disabled).Value;
             set => Add(ControlState.Disabled, value);
         }
         /// <summary>
@@ -133,7 +157,7 @@ namespace Tizen.NUI.BaseComponents
         [EditorBrowsable(EditorBrowsableState.Never)]
         public T DisabledFocused
         {
-            get => Find(x => x.State == ControlState.DisabledFocused).Value;
+            get => ((List<StateValuePair<T>>)StateValueList).FindLast(x => x.State == ControlState.DisabledFocused).Value;
             set => Add(ControlState.DisabledFocused, value);
         }
         /// <summary>
@@ -143,7 +167,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 => Find(x => x.State == ControlState.SelectedFocused).Value;
+            get => ((List<StateValuePair<T>>)StateValueList).FindLast(x => x.State == ControlState.SelectedFocused).Value;
             set => Add(ControlState.SelectedFocused, value);
         }
         /// <summary>
@@ -154,7 +178,8 @@ namespace Tizen.NUI.BaseComponents
         [EditorBrowsable(EditorBrowsableState.Never)]
         public T DisabledSelected
         {
-            get => Find(x => x.State == ControlState.DisabledSelected).Value;
+
+            get => ((List<StateValuePair<T>>)StateValueList).FindLast(x => x.State == ControlState.DisabledSelected).Value;
             set => Add(ControlState.DisabledSelected, value);
         }
 
@@ -166,7 +191,7 @@ namespace Tizen.NUI.BaseComponents
         [EditorBrowsable(EditorBrowsableState.Never)]
         public T Other
         {
-            get => Find(x => x.State == ControlState.Other).Value;
+            get => ((List<StateValuePair<T>>)StateValueList).FindLast(x => x.State == ControlState.Other).Value;
             set => Add(ControlState.Other, value);
         }
         /// <summary>
@@ -187,7 +212,7 @@ namespace Tizen.NUI.BaseComponents
 
             result = default;
 
-            int index = StateValueList.FindIndex(x => x.State == state);
+            int index = ((List<StateValuePair<T>>)StateValueList).FindLastIndex(x => x.State == state);
             if (index >= 0)
             {
                 result = StateValueList[index].Value;
@@ -196,7 +221,7 @@ namespace Tizen.NUI.BaseComponents
 
             if (state.IsCombined)
             {
-                index = StateValueList.FindIndex(x => state.Contains(x.State));
+                index = ((List<StateValuePair<T>>)StateValueList).FindLastIndex(x => state.Contains(x.State));
                 if (index >= 0)
                 {
                     result = StateValueList[index].Value;
@@ -204,7 +229,7 @@ namespace Tizen.NUI.BaseComponents
                 }
             }
 
-            index = StateValueList.FindIndex(x => x.State == ControlState.Other);
+            index = ((List<StateValuePair<T>>)StateValueList).FindLastIndex(x => x.State == ControlState.Other);
             if (index >= 0)
             {
                 result = StateValueList[index].Value;
@@ -214,12 +239,14 @@ namespace Tizen.NUI.BaseComponents
             return false;
         }
 
-        /// <inheritdoc/>
+        /// <summary>
+        /// Removes all elements from <see cref="StateValueList"./>
+        /// </summary>
         [EditorBrowsable(EditorBrowsableState.Never)]
-        public override void Clear()
+        public void Clear()
         {
             All = default;
-            base.Clear();
+            StateValueList.Clear();
         }
 
         /// <inheritdoc/>
@@ -256,23 +283,15 @@ namespace Tizen.NUI.BaseComponents
         [EditorBrowsable(EditorBrowsableState.Never)]
         public void Clone(Selector<T> other)
         {
-            Clear();
-
             if (cloneable)
             {
                 All = (T)((ICloneable)other.All)?.Clone();
-                foreach (var item in other.StateValueList)
-                {
-                    AddWithoutCheck(new StateValuePair<T>(item.State, (T)((ICloneable)item.Value)?.Clone()));
-                }
+                StateValueList = ((List<StateValuePair<T>>)other.StateValueList).ConvertAll(m => new StateValuePair<T>(m.State, (T)((ICloneable)m.Value)?.Clone()));
             }
             else
             {
                 All = other.All;
-                foreach (var item in other.StateValueList)
-                {
-                    AddWithoutCheck(item);
-                }
+                StateValueList = ((List<StateValuePair<T>>)other.StateValueList).ConvertAll(m => m);
             }
         }
 
@@ -407,4 +426,23 @@ namespace Tizen.NUI.BaseComponents
             }
         }
     }
+
+    /// <summary>
+    /// Extension class for <see cref="Selector{T}"/>.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public static class SelectorExtensions
+    {
+        /// <summary>
+        /// Adds the specified state and value to the <see cref="Selector{T}.StateValueList"/>.
+        /// </summary>
+        /// <param name="list">The list for adding state-value pair.</param>
+        /// <param name="state">The state.</param>
+        /// <param name="value">The value associated with state.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static void Add<T>(this IList<StateValuePair<T>> list, ControlState state, T value)
+        {
+            list.Add(new StateValuePair<T>(state, value));
+        }
+    }
 }
diff --git a/src/Tizen.NUI/src/public/BaseComponents/Style/StateValueCollection.cs b/src/Tizen.NUI/src/public/BaseComponents/Style/StateValueCollection.cs
deleted file mode 100644 (file)
index eb9376a..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright(c) 2020 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.ComponentModel;
-
-namespace Tizen.NUI.BaseComponents
-{
-    /// <summary>
-    /// The StateValueCollection class, which is related by <see cref="ControlState"/>, it is abstract class for <see cref="Selector{T}"/>.
-    /// </summary>
-    [EditorBrowsable(EditorBrowsableState.Never)]
-    public abstract class StateValueCollection<T> : ICollection<StateValuePair<T>>
-    {
-
-        [EditorBrowsable(EditorBrowsableState.Never)]
-        internal List<StateValuePair<T>> StateValueList { get; } = new List<StateValuePair<T>>();
-
-        /// <inheritdoc/>
-        [EditorBrowsable(EditorBrowsableState.Never)]
-        public int Count => StateValueList.Count;
-
-        /// <inheritdoc/>
-        [EditorBrowsable(EditorBrowsableState.Never)]
-        public bool IsReadOnly => ((ICollection<StateValuePair<T>>)StateValueList).IsReadOnly;
-
-        /// <summary>
-        /// Add a <see cref="StateValuePair{T}"/> with state and value.
-        /// </summary>
-        /// <param name="state">The state.</param>
-        /// <param name="value">The value associated with state.</param>
-        [EditorBrowsable(EditorBrowsableState.Never)]
-        public void Add(ControlState state, T value) => Add(new StateValuePair<T>(state, value));
-
-        /// <inheritdoc/>
-        [EditorBrowsable(EditorBrowsableState.Never)]
-        public void Add(StateValuePair<T> item)
-        {
-            // To prevent a state from having multiple values, remove existing state-value pair.
-            int index = StateValueList.FindIndex(x => x.State == item.State);
-            if (index != -1)
-                StateValueList.RemoveAt(index);
-
-            StateValueList.Add(item);
-        }
-
-        /// <inheritdoc/>
-        [EditorBrowsable(EditorBrowsableState.Never)]
-        public virtual void Clear() => StateValueList.Clear();
-
-        /// <inheritdoc/>
-        [EditorBrowsable(EditorBrowsableState.Never)]
-        public bool Contains(StateValuePair<T> item) => StateValueList.Contains(item);
-
-        /// <inheritdoc/>
-        [EditorBrowsable(EditorBrowsableState.Never)]
-        public void CopyTo(StateValuePair<T>[] array, int arrayIndex) => StateValueList.CopyTo(array, arrayIndex);
-
-        /// <inheritdoc/>
-        [EditorBrowsable(EditorBrowsableState.Never)]
-        public bool Remove(StateValuePair<T> item) => StateValueList.Remove(item);
-
-        /// <inheritdoc/>
-        [EditorBrowsable(EditorBrowsableState.Never)]
-        public IEnumerator<StateValuePair<T>> GetEnumerator() => StateValueList.GetEnumerator();
-
-        IEnumerator IEnumerable.GetEnumerator() => StateValueList.GetEnumerator();
-
-        /// <summary>
-        /// Searches for a StateValuePair that matches the conditions defined by the specified
-        /// predicate, and returns the first occurrence within the entire <see cref="StateValueList"/>
-        /// </summary>
-        /// <param name="match">The <see cref="Predicate{T}"/> delegate that defines the conditions of the element to search for.</param>
-        /// <returns>The first element that matches the conditions defined by the specified predicate,
-        /// if found; otherwise, the default value for type <see cref="StateValuePair{T}"/>.</returns>
-        public StateValuePair<T> Find(Predicate<StateValuePair<T>> match) => StateValueList.Find(match);
-
-        /// <summary>
-        /// Add a <see cref="StateValuePair{T}"/> without duplication check.
-        /// </summary>
-        /// <param name="item">The StateValuePair item to add.</param>
-        [EditorBrowsable(EditorBrowsableState.Never)]
-        internal void AddWithoutCheck(StateValuePair<T> item) => StateValueList.Add(item);
-    }
-}
\ No newline at end of file