[NUI] Supports Clockwise and CounterClockwise focus movement.
authorjoogab.yun <joogab.yun@samsung.com>
Thu, 10 Mar 2022 05:27:14 +0000 (14:27 +0900)
committerdongsug-song <35130733+dongsug-song@users.noreply.github.com>
Tue, 29 Mar 2022 03:10:12 +0000 (12:10 +0900)
Clockwise and CounterClockwise are rotary wheel event directions.

There is also a requirement that the focus be moved with a rotary wheel as well.

So, you can set the FocusableView according to the clockwise and counterclockwise directions of the rotary wheel.

```C#
  var viewA = new View { Focusable = true };
  var ViewB = new View { Focusable = true };

  viewA.ClockwiseFocusableView = viewB;
  ViewB.CounterClockwiseFocusableView = ViewA;

```

In ViewA, if the rotary wheel is in the Clockwise direction, ViewB is focused.
When the rotary wheel in ViewB is in the CountClockwise direction, ViewA is focused.

Dependency
https://review.tizen.org/gerrit/#/c/platform/core/uifw/dali-toolkit/+/272040/
https://review.tizen.org/gerrit/#/c/platform/core/uifw/dali-csharp-binder/+/272137/

src/Tizen.NUI/src/internal/Interop/Interop.ViewProperty.cs
src/Tizen.NUI/src/public/BaseComponents/View.cs
src/Tizen.NUI/src/public/BaseComponents/ViewBindableProperty.cs
src/Tizen.NUI/src/public/BaseComponents/ViewEnum.cs
src/Tizen.NUI/src/public/BaseComponents/ViewInternal.cs
test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/CustomWheelEventSample.cs [new file with mode: 0755]

index 9f83f05..080fd68 100755 (executable)
@@ -63,6 +63,12 @@ namespace Tizen.NUI
             [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_View_Property_DOWN_FOCUSABLE_ACTOR_ID_get")]
             public static extern int DownFocusableActorIdGet();
 
+            [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_View_Property_CLOCKWISE_FOCUSABLE_ACTOR_ID_get")]
+            public static extern int ClockwiseFocusableActorIdGet();
+
+            [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_View_Property_COUNTER_CLOCKWISE_FOCUSABLE_ACTOR_ID_get")]
+            public static extern int CounterClockwiseFocusableActorIdGet();
+
             [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_View_Property_UPDATE_SIZE_HINT_get")]
             public static extern int UpdateSizeHintGet();
 
index d14a94c..1d7a348 100755 (executable)
@@ -954,6 +954,46 @@ namespace Tizen.NUI.BaseComponents
         }
 
         /// <summary>
+        /// The clockwise focusable view by rotary wheel.<br />
+        /// This will return null if not set.<br />
+        /// This will also return null if the specified clockwise focusable view is not on a window.<br />
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public View ClockwiseFocusableView
+        {
+            // As native side will be only storing IDs so need a logic to convert View to ID and vice-versa.
+            get
+            {
+                return (View)GetValue(ClockwiseFocusableViewProperty);
+            }
+            set
+            {
+                SetValue(ClockwiseFocusableViewProperty, value);
+                NotifyPropertyChanged();
+            }
+        }
+
+        /// <summary>
+        /// The counter clockwise focusable view by rotary wheel.<br />
+        /// This will return null if not set.<br />
+        /// This will also return null if the specified counter clockwise focusable view is not on a window.<br />
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public View CounterClockwiseFocusableView
+        {
+            // As native side will be only storing IDs so need a logic to convert View to ID and vice-versa.
+            get
+            {
+                return (View)GetValue(CounterClockwiseFocusableViewProperty);
+            }
+            set
+            {
+                SetValue(CounterClockwiseFocusableViewProperty, value);
+                NotifyPropertyChanged();
+            }
+        }
+
+        /// <summary>
         /// Whether the view should be focusable by keyboard navigation.
         /// </summary>
         /// <since_tizen> 3 </since_tizen>
index 1e01871..40f15c2 100755 (executable)
@@ -608,6 +608,40 @@ namespace Tizen.NUI.BaseComponents
         });
 
         /// <summary>
+        /// ClockwiseFocusableViewProperty
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static readonly BindableProperty ClockwiseFocusableViewProperty = BindableProperty.Create(nameof(View.ClockwiseFocusableView), typeof(View), typeof(View), null, propertyChanged: (bindable, oldValue, newValue) =>
+        {
+            var view = (View)bindable;
+            if (newValue != null && (newValue is View)) { view.ClockwiseFocusableViewId = (int)(newValue as View)?.GetId(); }
+            else { view.ClockwiseFocusableViewId = -1; }
+        },
+        defaultValueCreator: (bindable) =>
+        {
+            var view = (View)bindable;
+            if (view.ClockwiseFocusableViewId >= 0) { return view.ConvertIdToView((uint)view.ClockwiseFocusableViewId); }
+            return null;
+        });
+
+        /// <summary>
+        /// CounterClockwiseFocusableViewProperty
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static readonly BindableProperty CounterClockwiseFocusableViewProperty = BindableProperty.Create(nameof(View.CounterClockwiseFocusableView), typeof(View), typeof(View), null, propertyChanged: (bindable, oldValue, newValue) =>
+        {
+            var view = (View)bindable;
+            if (newValue != null && (newValue is View)) { view.CounterClockwiseFocusableViewId = (int)(newValue as View)?.GetId(); }
+            else { view.CounterClockwiseFocusableViewId = -1; }
+        },
+        defaultValueCreator: (bindable) =>
+        {
+            var view = (View)bindable;
+            if (view.CounterClockwiseFocusableViewId >= 0) { return view.ConvertIdToView((uint)view.CounterClockwiseFocusableViewId); }
+            return null;
+        });
+
+        /// <summary>
         /// FocusableProperty
         /// </summary>
         [EditorBrowsable(EditorBrowsableState.Never)]
index 9d1bd12..d2236bc 100755 (executable)
@@ -151,6 +151,16 @@ namespace Tizen.NUI.BaseComponents
             /// </summary>
             [EditorBrowsable(EditorBrowsableState.Never)]
             Backward,
+            /// <summary>
+            /// Move focus towards the Clockwise direction by rotary wheel.
+            /// </summary>
+            [EditorBrowsable(EditorBrowsableState.Never)]
+            Clockwise,
+            /// <summary>
+            /// Move focus towards the CounterClockwise direction by rotary wheel.
+            /// </summary>
+            [EditorBrowsable(EditorBrowsableState.Never)]
+            CounterClockwise,
         }
 
         /// <summary>
@@ -177,6 +187,8 @@ namespace Tizen.NUI.BaseComponents
             internal static readonly int RightFocusableViewId = Interop.ViewProperty.RightFocusableActorIdGet();
             internal static readonly int UpFocusableViewId = Interop.ViewProperty.UpFocusableActorIdGet();
             internal static readonly int DownFocusableViewId = Interop.ViewProperty.DownFocusableActorIdGet();
+            internal static readonly int ClockwiseFocusableViewId = Interop.ViewProperty.ClockwiseFocusableActorIdGet();
+            internal static readonly int CounterClockwiseFocusableViewId = Interop.ViewProperty.CounterClockwiseFocusableActorIdGet();
             internal static readonly int StyleName = Interop.ViewProperty.StyleNameGet();
             internal static readonly int KeyInputFocus = Interop.ViewProperty.KeyInputFocusGet();
             internal static readonly int BACKGROUND = Interop.ViewProperty.BackgroundGet();
index 9a16d10..c05e499 100755 (executable)
@@ -430,6 +430,42 @@ namespace Tizen.NUI.BaseComponents
             }
         }
 
+        private int ClockwiseFocusableViewId
+        {
+            get
+            {
+                int returnValue = -1;
+                PropertyValue clockwiseFocusableViewId = GetProperty(View.Property.ClockwiseFocusableViewId);
+                clockwiseFocusableViewId?.Get(out returnValue);
+                clockwiseFocusableViewId?.Dispose();
+                return returnValue;
+            }
+            set
+            {
+                PropertyValue setValue = new Tizen.NUI.PropertyValue(value);
+                SetProperty(View.Property.ClockwiseFocusableViewId, setValue);
+                setValue.Dispose();
+            }
+        }
+
+        private int CounterClockwiseFocusableViewId
+        {
+            get
+            {
+                int returnValue = -1;
+                PropertyValue counterClockwiseFocusableViewId = GetProperty(View.Property.CounterClockwiseFocusableViewId);
+                counterClockwiseFocusableViewId?.Get(out returnValue);
+                counterClockwiseFocusableViewId?.Dispose();
+                return returnValue;
+            }
+            set
+            {
+                PropertyValue setValue = new Tizen.NUI.PropertyValue(value);
+                SetProperty(View.Property.CounterClockwiseFocusableViewId, setValue);
+                setValue.Dispose();
+            }
+        }
+
         internal string GetName()
         {
             string ret = Interop.Actor.GetName(SwigCPtr);
diff --git a/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/CustomWheelEventSample.cs b/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/CustomWheelEventSample.cs
new file mode 100755 (executable)
index 0000000..c43263a
--- /dev/null
@@ -0,0 +1,82 @@
+using Tizen.NUI;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Components;
+using Tizen.NUI.Events;
+using System.Collections.Generic;
+
+namespace Tizen.NUI.Samples
+{
+    public class CustomWheelEventSample : IExample
+    {
+
+        int ItemWidth = 100;
+        int ItemHeight = 100;
+        int ItemSpacing = 10;
+
+        public View TargetView = new View();
+
+        public void Activate()
+        {
+            Window window = NUIApplication.GetDefaultWindow();
+            var absLayout = new View
+            {
+                Layout = new AbsoluteLayout(),
+                WidthResizePolicy = ResizePolicyType.FillToParent,
+                HeightResizePolicy = ResizePolicyType.FillToParent,
+                Focusable = true,
+                FocusableInTouch = true,
+            };
+            window.Add(absLayout);
+
+            var btn1 = MakeFocusableButton("1");
+            btn1.Position = new Position(ItemWidth + 1 * (ItemWidth + ItemSpacing), ItemHeight);
+            absLayout.Add(btn1);
+
+            var btn2 = MakeFocusableButton("2");
+            btn2.Position = new Position(ItemWidth + 2 * (ItemWidth + ItemSpacing), ItemHeight);
+            absLayout.Add(btn2);
+
+            var btn3 = MakeFocusableButton("3");
+            btn3.Position = new Position(ItemWidth + 3 * (ItemWidth + ItemSpacing), ItemHeight);
+            absLayout.Add(btn3);
+
+            var btn4 = MakeFocusableButton("4");
+            btn4.Position = new Position(ItemWidth + 4 * (ItemWidth + ItemSpacing), ItemHeight);
+            absLayout.Add(btn4);
+
+
+            btn1.ClockwiseFocusableView = btn2;
+            btn2.ClockwiseFocusableView = btn3;
+            btn3.ClockwiseFocusableView = btn4;
+            btn4.ClockwiseFocusableView = btn1;
+
+            btn1.CounterClockwiseFocusableView = btn4;
+            btn2.CounterClockwiseFocusableView = btn1;
+            btn3.CounterClockwiseFocusableView = btn2;
+            btn4.CounterClockwiseFocusableView = btn3;
+
+            FocusManager.Instance.SetCurrentFocusView(btn1);
+        }
+
+        View MakeFocusableButton(string title)
+        {
+            var btn = new Button
+            {
+                Focusable = true,
+                FocusableInTouch = true,
+                Text = title,
+                SizeWidth = ItemWidth,
+                SizeHeight = ItemHeight,
+                BackgroundColor = Color.Blue,
+            };
+
+            btn.FocusGained += (s, e) => btn.Text = $"[{title}]";
+            btn.FocusLost += (s, e) => btn.Text = $"{title}";
+            return btn;
+        }
+
+        public void Deactivate()
+        {
+        }
+    }
+}