[NUI] propose a way to change the value of Picker by up/down direction key
authordongsug.song <dongsug.song@samsung.com>
Wed, 23 Mar 2022 12:29:26 +0000 (21:29 +0900)
committerJaehyun Cho <jaehyun0cho@gmail.com>
Wed, 20 Apr 2022 08:38:08 +0000 (17:38 +0900)
src/Tizen.NUI.Components/Controls/DatePicker.cs
src/Tizen.NUI.Components/Controls/Picker.cs
src/Tizen.NUI.Components/Controls/TimePicker.cs

index 1505393..d1aa687 100755 (executable)
@@ -87,6 +87,7 @@ namespace Tizen.NUI.Components
         /// <since_tizen> 9 </since_tizen>
         public DatePicker()
         {
+            SetKeyboardNavigationSupport(true);
         }
 
         /// <summary>
@@ -96,6 +97,7 @@ namespace Tizen.NUI.Components
         /// <since_tizen> 9 </since_tizen>
         public DatePicker(string style) : base(style)
         {
+            SetKeyboardNavigationSupport(true);
         }
 
         /// <summary>
@@ -105,6 +107,7 @@ namespace Tizen.NUI.Components
         /// <since_tizen> 9 </since_tizen>
         public DatePicker(DatePickerStyle datePickerStyle) : base(datePickerStyle)
         {
+            SetKeyboardNavigationSupport(true);
         }
 
 
@@ -234,7 +237,8 @@ namespace Tizen.NUI.Components
         }
 
         /// <summary>
-        /// ToDo : only key navigation is enabled, but value editing is not yet added. for example, after enter key and up/down key the value need be changed.
+        /// ToDo : only key navigation is enabled, and value editing is added as an very simple operation. by toggling enter key, it switches edit mode. 
+        /// ToDo : this should be fixed and changed properly by owner. (And UX SPEC should be referenced also)
         /// </summary>
         /// <param name="currentFocusedView"></param>
         /// <param name="direction"></param>
@@ -249,10 +253,6 @@ namespace Tizen.NUI.Components
                 {
                     return monthPicker;
                 }
-                else if (direction == View.FocusDirection.Left)
-                {
-                    return null;
-                }
             }
             else if (currentFocusedView == monthPicker)
             {
@@ -267,11 +267,7 @@ namespace Tizen.NUI.Components
             }
             else if (currentFocusedView == dayPicker)
             {
-                if (direction == View.FocusDirection.Right)
-                {
-                    return null;
-                }
-                else if (direction == View.FocusDirection.Left)
+                if (direction == View.FocusDirection.Left)
                 {
                     return monthPicker;
                 }
index 1bcf1a0..05dfa5d 100755 (executable)
@@ -33,7 +33,7 @@ namespace Tizen.NUI.Components
         /// ValueChangedEventArgs default constructor.
         /// <param name="value">value of Picker.</param>
         /// </summary>
-        [EditorBrowsable(EditorBrowsableState.Never)]   
+        [EditorBrowsable(EditorBrowsableState.Never)]
         public ValueChangedEventArgs(int value)
         {
             Value = value;
@@ -45,7 +45,7 @@ namespace Tizen.NUI.Components
         /// </summary>
         /// <since_tizen> 9 </since_tizen>
         public int Value { get; }
-        
+
     }
 
     /// <summary>
@@ -59,7 +59,7 @@ namespace Tizen.NUI.Components
         private const int scrollVisibleItems = 5;
         //Dummy item count for loop feature. Max value of scrolling distance in 
         //RPI target is bigger than 20 items height. it can adjust depends on the internal logic and device env.
-        private const int dummyItemsForLoop = 20;             
+        private const int dummyItemsForLoop = 20;
         private int startScrollOffset;
         private int itemHeight;
         private int startScrollY;
@@ -81,6 +81,10 @@ namespace Tizen.NUI.Components
         private IList<TextLabel> itemList;
         private Vector2 size;
         private TextLabelStyle itemTextLabel;
+        private bool editMode = false;
+        private View recoverIndicator = null;
+        private View editModeIndicator = null;
+
 
         /// <summary>
         /// Creates a new instance of Picker.
@@ -144,6 +148,10 @@ namespace Tizen.NUI.Components
                 Utility.Dispose(upLine);
                 Remove(downLine);
                 Utility.Dispose(downLine);
+
+                recoverIndicator = null;
+                editModeIndicator.Dispose();
+                editModeIndicator = null;
             }
 
             base.Dispose(type);
@@ -177,7 +185,7 @@ namespace Tizen.NUI.Components
                 UpdateValueList();
             }
         }
-        
+
         /// <summary>
         /// The Current value of Picker.
         /// </summary>
@@ -239,7 +247,7 @@ namespace Tizen.NUI.Components
             {
                 if (maxValue == value) return;
                 if (currentValue > value) currentValue = value;
-                
+
                 maxValue = value;
                 needItemUpdate = true;
 
@@ -273,7 +281,7 @@ namespace Tizen.NUI.Components
             {
                 if (minValue == value) return;
                 if (currentValue < value) currentValue = value;
-                
+
                 minValue = value;
                 needItemUpdate = true;
 
@@ -361,7 +369,7 @@ namespace Tizen.NUI.Components
                 pickerScroller.ScrollAvailableArea = new Vector2(0, (itemList.Count * itemHeight) - size.Height);
             }
         }
-                
+
         private void Initialize()
         {
             HeightSpecification = LayoutParamPolicies.MatchParent;
@@ -388,7 +396,7 @@ namespace Tizen.NUI.Components
             pickerScroller.ScrollAnimationStarted += OnScrollAnimationStarted;
 
             itemList = new List<TextLabel>();
-            
+
             minValue = maxValue = currentValue = 0;
             displayedValues = null;
             //Those many flags for min, max, value method calling sequence dependency.
@@ -399,10 +407,13 @@ namespace Tizen.NUI.Components
 
             Add(pickerScroller);
             AddLine();
+
+            Focusable = true;
+            KeyEvent += OnKeyEvent;
         }
 
         private void OnValueChanged()
-        { 
+        {
             ValueChangedEventArgs eventArgs =
                 new ValueChangedEventArgs(displayedValuesUpdate ? Int32.Parse(itemList[currentValue].Name) : Int32.Parse(itemList[currentValue].Text));
             ValueChanged?.Invoke(this, eventArgs);
@@ -420,7 +431,7 @@ namespace Tizen.NUI.Components
         private void OnScroll(object sender, ScrollEventArgs e)
         {
             if (!loopEnabled || onAnimation || onAlignAnimation) return;
-            
+
             PageAdjust(e.Position.Y);
         }
 
@@ -441,7 +452,8 @@ namespace Tizen.NUI.Components
             lastScrollPosion = (int)(-e.Position.Y + offset);
 
             onAnimation = false;
-            if (onAlignAnimation) {
+            if (onAlignAnimation)
+            {
                 onAlignAnimation = false;
                 if (loopEnabled == true)
                 {
@@ -457,11 +469,13 @@ namespace Tizen.NUI.Components
             }
 
             //Item center align with animation, otherwise changed event emit.
-            if (offset != 0) {
+            if (offset != 0)
+            {
                 onAlignAnimation = true;
                 pickerScroller.ScrollTo(-e.Position.Y + offset, true);
             }
-            else {
+            else
+            {
                 if (currentValue != ((int)(-e.Position.Y / itemHeight) + 2))
                 {
                     currentValue = ((int)(-e.Position.Y / itemHeight) + 2);
@@ -483,10 +497,13 @@ namespace Tizen.NUI.Components
         private String GetItemText(bool loopEnabled, int idx)
         {
             if (!loopEnabled) return " ";
-            else {
-                if (displayedValuesUpdate) {
+            else
+            {
+                if (displayedValuesUpdate)
+                {
                     idx = idx - MinValue;
-                    if (idx <= displayedValues.Count) {
+                    if (idx <= displayedValues.Count)
+                    {
                         return displayedValues[idx];
                     }
                     return " ";
@@ -535,7 +552,8 @@ namespace Tizen.NUI.Components
 
             //FIXME: This is wrong.
             //       But scroller can't update item property after added please fix me.
-            if (itemList.Count > 0) {
+            if (itemList.Count > 0)
+            {
                 itemList.Clear();
                 pickerScroller.RemoveAllChildren();
             }
@@ -547,9 +565,9 @@ namespace Tizen.NUI.Components
                 //So need below calc.
                 int dummyStartIdx = 0;
                 if (maxValue - minValue >= dummyItemsForLoop)
-                  dummyStartIdx = maxValue - dummyItemsForLoop + 1;
+                    dummyStartIdx = maxValue - dummyItemsForLoop + 1;
                 else
-                  dummyStartIdx = maxValue - (dummyItemsForLoop % (maxValue - minValue + 1)) + 1;
+                    dummyStartIdx = maxValue - (dummyItemsForLoop % (maxValue - minValue + 1)) + 1;
 
                 //Start add items in scroller. first dummys for scroll anim.
                 for (int i = 0; i < dummyItemsForLoop; i++)
@@ -595,6 +613,75 @@ namespace Tizen.NUI.Components
             needItemUpdate = false;
         }
 
+        private bool OnKeyEvent(object o, View.KeyEventArgs e)
+        {
+            if (e.Key.State == Key.StateType.Down)
+            {
+                if (e.Key.KeyPressedName == "Return")
+                {
+                    if (editMode)
+                    {
+                        //Todo: sometimes this gets wrong. the currentValue is not correct. need to be fixed.
+                        if (currentValue != ((int)(-pickerScroller.Position.Y / itemHeight) + 2))
+                        {
+                            currentValue = ((int)(-pickerScroller.Position.Y / itemHeight) + 2);
+                            OnValueChanged();
+                        }
+
+                        //set editMode false (toggle the mode)
+                        editMode = false;
+                        FocusManager.Instance.FocusIndicator = recoverIndicator;
+                        return true;
+                    }
+                    else
+                    {
+                        //set editMode true (toggle the mode)
+                        editMode = true;
+                        if (editModeIndicator == null)
+                        {
+                            editModeIndicator = new View()
+                            {
+                                PositionUsesPivotPoint = true,
+                                PivotPoint = new Position(0, 0, 0),
+                                WidthResizePolicy = ResizePolicyType.FillToParent,
+                                HeightResizePolicy = ResizePolicyType.FillToParent,
+                                BorderlineColor = Color.Red,
+                                BorderlineWidth = 6.0f,
+                                BorderlineOffset = -1f,
+                                BackgroundColor = new Color(0.2f, 0.2f, 0.2f, 0.4f),
+                            };
+                        }
+                        recoverIndicator = FocusManager.Instance.FocusIndicator;
+                        FocusManager.Instance.FocusIndicator = editModeIndicator;
+                        return true;
+                    }
+                }
+                else if (e.Key.KeyPressedName == "Up")
+                {
+                    if (editMode)
+                    {
+                        InternalCurrentValue += 1;
+                        return true;
+                    }
+                }
+                else if (e.Key.KeyPressedName == "Down")
+                {
+                    if (editMode)
+                    {
+                        InternalCurrentValue -= 1;
+                        return true;
+                    }
+                }
+
+                if (editMode)
+                {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+
         internal class PickerScroller : ScrollableBase
         {
             private int itemHeight;
index a71e031..83794ac 100755 (executable)
@@ -338,7 +338,8 @@ namespace Tizen.NUI.Components
         }
 
         /// <summary>
-        /// ToDo : only key navigation is enabled, but value editing is not yet added. for example, after enter key and up/down key the value need be changed.
+        /// ToDo : only key navigation is enabled, and value editing is added as an very simple operation. by toggling enter key, it switches edit mode. 
+        /// ToDo : this should be fixed and changed properly by owner. (And UX SPEC should be referenced also)
         /// </summary>
         /// <param name="currentFocusedView"></param>
         /// <param name="direction"></param>
@@ -353,10 +354,7 @@ namespace Tizen.NUI.Components
                 {
                     return minutePicker;
                 }
-                else if (direction == View.FocusDirection.Left)
-                {
-                    return null;
-                }
+
             }
             else if (currentFocusedView == minutePicker)
             {
@@ -371,11 +369,7 @@ namespace Tizen.NUI.Components
             }
             else if (currentFocusedView == ampmPicker)
             {
-                if (direction == View.FocusDirection.Right)
-                {
-                    return null;
-                }
-                else if (direction == View.FocusDirection.Left)
+                if (direction == View.FocusDirection.Left)
                 {
                     return minutePicker;
                 }
@@ -383,7 +377,6 @@ namespace Tizen.NUI.Components
             return null;
         }
 
-
         [SuppressMessage("Microsoft.Reliability",
                          "CA2000:DisposeObjectsBeforeLosingScope",
                          Justification = "The CellPadding will be dispose when the time picker disposed")]