[NUI] Fix TabButton not to invoke duplicate SelectedChanged (#2775)
authorJaehyun Cho <29364140+jaehyun0cho@users.noreply.github.com>
Tue, 23 Mar 2021 12:48:05 +0000 (21:48 +0900)
committerdongsug-song <35130733+dongsug-song@users.noreply.github.com>
Tue, 30 Mar 2021 06:51:02 +0000 (15:51 +0900)
TabButton does not change its state to unselected if button or key is
unpressed while its state is selected.

Previously, TabButton invoked duplicate SelectedChanged if button or key
is unpressed while its state is selected.

Now, TabButton does not invoke duplicate SelectedChanged if button or
key is unpressed while its state is selected.

Co-authored-by: Jaehyun Cho <jae_hyun.cho@samsung.com>
src/Tizen.NUI.Components/Controls/TabBar.cs
src/Tizen.NUI.Components/Controls/TabButton.cs
src/Tizen.NUI.Components/Controls/TabButtonGroup.cs

index 284fcae..8f6fa4c 100755 (executable)
@@ -130,7 +130,6 @@ namespace Tizen.NUI.Components
             if (SelectedIndex == -1)
             {
                 tabButton.IsSelected = true;
-                tabButton.SetTabButtonState(ControlState.Pressed);
                 SelectedIndex = 0;
 
                 if (TabButtonSelected != null)
@@ -184,7 +183,6 @@ namespace Tizen.NUI.Components
             if ((SelectedIndex != -1) && (selectedTabButton != tabButtons[SelectedIndex]))
             {
                 tabButtons[SelectedIndex].IsSelected = true;
-                tabButtons[SelectedIndex].SetTabButtonState(ControlState.Pressed);
             }
 
             //TODO: To support non-unified tab button size.
index 77f0476..77ab394 100755 (executable)
@@ -15,6 +15,7 @@
  *
  */
 using System.ComponentModel;
+using System.Diagnostics.CodeAnalysis;
 using Tizen.NUI.BaseComponents;
 
 namespace Tizen.NUI.Components
@@ -25,6 +26,8 @@ namespace Tizen.NUI.Components
     [EditorBrowsable(EditorBrowsableState.Never)]
     public class TabButton : SelectButton
     {
+        private bool selectedAgain = false;
+
         /// <summary>
         /// Creates a new instance of TabButton.
         /// </summary>
@@ -34,28 +37,88 @@ namespace Tizen.NUI.Components
             GridLayout.SetHorizontalStretch(this, GridLayout.StretchFlags.ExpandAndFill);
         }
 
-        /// <summary>
-        /// Sets the control state of a TabButton.
-        /// TabButton needs to support this API since 'View.ControlState' is protected
-        /// and cannot be reached by TabButtonGroup.
-        /// </summary>
+        /// <inheritdoc/>
         [EditorBrowsable(EditorBrowsableState.Never)]
-        internal void SetTabButtonState(ControlState controlState)
+        public override bool OnKey(Key key)
         {
-            base.ControlState = controlState;
+            if ((IsEnabled == false) || (key == null))
+            {
+                return false;
+            }
+
+            if (key.State == Key.StateType.Up)
+            {
+                if (key.KeyPressedName == "Return")
+                {
+                    if (IsSelected == true)
+                    {
+                        selectedAgain = true;
+                    }
+                }
+            }
+
+            bool ret = base.OnKey(key);
+
+            if (selectedAgain == true)
+            {
+                IsSelected = true;
+                selectedAgain = false;
+            }
+
+            return ret;
         }
 
-        /// <summary>
-        /// Sets Button.IsSelected to true after selecting TabButton since it is
-        /// set to false when re-selected according to Button's logic.
-        /// </summary>
+        /// <inheritdoc/>
         [EditorBrowsable(EditorBrowsableState.Never)]
-        protected override void OnSelectedChanged()
+        protected override bool HandleControlStateOnTouch(Touch touch)
         {
-            ControlState = ControlState.Pressed;
-            if (!IsSelected)
+            if ((IsEnabled == false) || (touch == null))
+            {
+                return false;
+            }
+
+            PointStateType state = touch.GetState(0);
+            switch (state)
+            {
+                case PointStateType.Up:
+                    if (IsSelected == true)
+                    {
+                        selectedAgain = true;
+                    }
+                    break;
+                default:
+                    break;
+            }
+
+            bool ret = base.HandleControlStateOnTouch(touch);
+
+            if (selectedAgain == true)
             {
                 IsSelected = true;
+                selectedAgain = false;
+            }
+
+            return ret;
+        }
+
+        /// <inheritdoc/>
+        [SuppressMessage("Microsoft.Design",
+                         "CA1062: Validate arguments of public methods",
+                         MessageId = "controlStateChangedInfo",
+                         Justification = "OnControlStateChanged is called when controlState is changed so controlStateChangedInfo cannot be null.")]
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected override void OnControlStateChanged(ControlStateChangedEventArgs controlStateChangedInfo)
+        {
+            if (controlStateChangedInfo.PreviousState.Contains(ControlState.Selected) != controlStateChangedInfo.CurrentState.Contains(ControlState.Selected))
+            {
+                // TabButton does not invoke SelectedChanged if button or key is
+                // unpressed while its state is selected.
+                if (selectedAgain == true)
+                {
+                    return;
+                }
+
+                base.OnControlStateChanged(controlStateChangedInfo);
             }
         }
     }
index f724c34..c2c8a3e 100755 (executable)
@@ -28,6 +28,15 @@ namespace Tizen.NUI.Components
     public class TabButtonGroup : SelectGroup
     {
         /// <summary>
+        /// Constructs TabButtonGroup
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public TabButtonGroup() : base()
+        {
+            EnableMultiSelection = false;
+        }
+
+        /// <summary>
         /// Adds a tab button to the end of TabButtonGroup.
         /// </summary>
         /// <param name="tabButton">A tab button to be added to the group.</param>
@@ -58,37 +67,5 @@ namespace Tizen.NUI.Components
 
             base.RemoveSelection(tabButton);
         }
-
-        /// <summary>
-        /// Sets the state of the rest of tab buttons in TabButtonGroup as normal
-        /// when a selection is made by a user.
-        /// </summary>
-        /// <param name="selection">The handler of the SelectButton selected by a user.</param>
-        /// <exception cref="ArgumentNullException">Thrown when the argument selection is null.</exception>
-        /// <exception cref="ArgumentException">Thrown when the argument selection does not exist in TabButtonGroup.</exception>
-        [EditorBrowsable(EditorBrowsableState.Never)]
-        protected override void SelectionHandler(SelectButton selection)
-        {
-            TabButton selectedTab = selection as TabButton;
-
-            if (selectedTab == null)
-            {
-                throw new ArgumentNullException(nameof(selection), "selection should not be null.");
-            }
-
-            if (ItemGroup.Contains(selectedTab) == false)
-            {
-                throw new ArgumentException("selection does not exist in TabButtonGroup.", nameof(selection));
-            }
-
-            foreach (TabButton tabButton in ItemGroup)
-            {
-                if ((tabButton != null) && (tabButton != selectedTab) && (selectedTab.IsEnabled == true))
-                {
-                    tabButton.IsSelected = false;
-                    tabButton.SetTabButtonState(ControlState.Normal);
-                }
-            }
-        }
     }
 }