[NUI] Add FocusableChildren
authorjoogab.yun <joogab.yun@samsung.com>
Fri, 20 Aug 2021 05:33:13 +0000 (14:33 +0900)
committerdongsug-song <35130733+dongsug-song@users.noreply.github.com>
Wed, 1 Sep 2021 08:20:01 +0000 (17:20 +0900)
src/Tizen.NUI/src/internal/Interop/Interop.ActorInternal.cs
src/Tizen.NUI/src/public/BaseComponents/Style/ViewStyle.cs
src/Tizen.NUI/src/public/BaseComponents/Style/ViewStyleBindableProperty.cs
src/Tizen.NUI/src/public/BaseComponents/View.cs
src/Tizen.NUI/src/public/BaseComponents/ViewBindableProperty.cs
src/Tizen.NUI/src/public/BaseComponents/ViewInternal.cs
test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/FocusFinderSample.cs [new file with mode: 0644]

index 7d70a20..fed28c7 100755 (executable)
@@ -204,6 +204,13 @@ namespace Tizen.NUI
             [return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.U1)]
             public static extern bool IsKeyboardFocusable(global::System.Runtime.InteropServices.HandleRef jarg1);
 
+            [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Actor_SetKeyboardFocusableChildren")]
+            public static extern void SetKeyboardFocusableChildren(global::System.Runtime.InteropServices.HandleRef manager, bool focusable);
+
+            [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Actor_AreChildrenKeyBoardFocusable")]
+            [return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.U1)]
+            public static extern bool AreChildrenKeyBoardFocusable(global::System.Runtime.InteropServices.HandleRef manager);
+
             [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Actor_SetTouchFocusable")]
             public static extern void SetFocusableInTouch(global::System.Runtime.InteropServices.HandleRef jarg1, bool jarg2);
 
index b9dc121..378d7da 100755 (executable)
@@ -29,6 +29,7 @@ namespace Tizen.NUI.BaseComponents
     {
         private bool disposed = false;
         private bool? focusable;
+        private bool? focusableChildren;
         private bool? focusableInTouch;
         private bool? positionUsesPivotPoint;
         private Position parentOrigin;
@@ -108,6 +109,17 @@ namespace Tizen.NUI.BaseComponents
         }
 
         /// <summary>
+        /// Whether the children of this view can be focusable by keyboard navigation. If user sets this to false, the children of this view will not be focused.
+        /// Note : Default value is true.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public bool? FocusableChildren
+        {
+            get => (bool?)GetValue(FocusableChildrenProperty);
+            set => SetValue(FocusableChildrenProperty, value);
+        }
+
+        /// <summary>
         /// Whether this view can focus by touch.
         /// If Focusable is false, FocusableInTouch is disabled.
         /// If you want to have focus on touch, you need to set both Focusable and FocusableInTouch settings to true.
index 4b357c4..46ed3a6 100755 (executable)
@@ -49,6 +49,14 @@ namespace Tizen.NUI.BaseComponents
             defaultValueCreator: (bindable) => ((ViewStyle)bindable).focusable
         );
 
+        /// <summary> Bindable property of FocusableChildren. Please do not open it. </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static readonly BindableProperty FocusableChildrenProperty = BindableProperty.Create(nameof(FocusableChildren), typeof(bool?), typeof(ViewStyle), true,
+            propertyChanged: (bindable, oldValue, newValue) => ((ViewStyle)bindable).focusableChildren = (bool?)newValue,
+            defaultValueCreator: (bindable) => ((ViewStyle)bindable).focusableChildren
+        );
+
+
         /// <summary> Bindable property of FocusableInTouch. Please do not open it. </summary>
         [EditorBrowsable(EditorBrowsableState.Never)]
         public static readonly BindableProperty FocusableInTouchProperty = BindableProperty.Create(nameof(FocusableInTouch), typeof(bool?), typeof(ViewStyle), null,
index 66baabf..0006b64 100755 (executable)
@@ -928,6 +928,24 @@ namespace Tizen.NUI.BaseComponents
         }
 
         /// <summary>
+        /// Whether the children of this view can be focusable by keyboard navigation. If user sets this to false, the children of this actor view will not be focused.
+        /// Note : Default value is true.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public bool FocusableChildren
+        {
+            set
+            {
+                SetValue(FocusableChildrenProperty, value);
+                NotifyPropertyChanged();
+            }
+            get
+            {
+                return (bool)GetValue(FocusableChildrenProperty);
+            }
+        }
+
+        /// <summary>
         /// Whether this view can focus by touch.
         /// If Focusable is false, FocusableInTouch is disabled.
         /// If you want to have focus on touch, you need to set both Focusable and FocusableInTouch settings to true.
index 8daa13e..e533477 100755 (executable)
@@ -574,6 +574,21 @@ namespace Tizen.NUI.BaseComponents
         });
 
         /// <summary>
+        /// FocusableChildrenProperty
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static readonly BindableProperty FocusableChildrenProperty = BindableProperty.Create(nameof(FocusableChildren), typeof(bool), typeof(View), true, propertyChanged: (bindable, oldValue, newValue) =>
+        {
+            var view = (View)bindable;
+            if (newValue != null) { view.SetKeyboardFocusableChildren((bool)newValue); }
+        },
+        defaultValueCreator: (bindable) =>
+        {
+            var view = (View)bindable;
+            return view.AreChildrenKeyBoardFocusable();
+        });
+
+        /// <summary>
         /// FocusableInTouchProperty
         /// </summary>
         [EditorBrowsable(EditorBrowsableState.Never)]
index 4be54a0..dcc758f 100755 (executable)
@@ -926,6 +926,21 @@ namespace Tizen.NUI.BaseComponents
             return ret;
         }
 
+        internal void SetKeyboardFocusableChildren(bool focusable)
+        {
+            Interop.ActorInternal.SetKeyboardFocusableChildren(SwigCPtr, focusable);
+            if (NDalicPINVOKE.SWIGPendingException.Pending)
+                throw NDalicPINVOKE.SWIGPendingException.Retrieve();
+        }
+
+        internal bool AreChildrenKeyBoardFocusable()
+        {
+            bool ret = Interop.ActorInternal.AreChildrenKeyBoardFocusable(SwigCPtr);
+            if (NDalicPINVOKE.SWIGPendingException.Pending)
+                throw NDalicPINVOKE.SWIGPendingException.Retrieve();
+            return ret;
+        }
+
         internal void SetFocusableInTouch(bool enabled)
         {
             Interop.ActorInternal.SetFocusableInTouch(SwigCPtr, enabled);
diff --git a/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/FocusFinderSample.cs b/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/FocusFinderSample.cs
new file mode 100644 (file)
index 0000000..813cbf1
--- /dev/null
@@ -0,0 +1,233 @@
+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 FocusFinderSample : IExample
+    {
+
+        int ItemWidth = 100;
+        int ItemHeight = 100;
+        int ItemSpacing = 10;
+
+        public View TargetView = new View();
+        TextLabel _textLabel;
+
+
+        public void Activate()
+        {
+            Window window = NUIApplication.GetDefaultWindow();
+
+            FocusManager.Instance.EnableDefaultAlgorithm(true);
+
+            var absLayout = new View
+            {
+                Layout = new AbsoluteLayout(),
+                WidthResizePolicy = ResizePolicyType.FillToParent,
+                HeightResizePolicy = ResizePolicyType.FillToParent,
+                // FocusableChildren = false,
+            };
+            window.Add(absLayout);
+
+            List<View> buttons = new List<View>();
+
+            for (int row = 0; row < 5; row++)
+            {
+                for (int cols = 0; cols < 5; cols++)
+                {
+                    var btn = MakeFocusableButton($"{row * 5 + cols}");
+                    btn.Position = new Position(ItemWidth + cols * (ItemWidth + ItemSpacing), ItemHeight + 300 + row * (ItemHeight + ItemSpacing));
+                    buttons.Add(btn);
+                    absLayout.Add(btn);
+                }
+            }
+
+            var changeLayout = new Button
+            {
+                Focusable = true,
+                FocusableInTouch = true,
+                Text = "Change Position",
+                SizeWidth = 300,
+                SizeHeight = 100,
+            };
+
+            changeLayout.Position = new Position(10, 10);
+
+            absLayout.Add(changeLayout);
+            changeLayout.Clicked += (s, e) =>
+            {
+                buttons.Reverse();
+
+                for (int row = 0; row < 5; row++)
+                {
+                    for (int cols = 0; cols < 5; cols++)
+                    {
+
+                        var btn = buttons[row * 5 + cols];
+                        btn.Position = new Position(ItemWidth + cols * (ItemWidth + ItemSpacing), ItemHeight + 300 + row * (ItemHeight + ItemSpacing));
+                    }
+                }
+            };
+
+            var hideButton = new Button
+            {
+                Focusable = true,
+                FocusableInTouch = true,
+                Text = "Hide button",
+                SizeWidth = 400,
+                SizeHeight = 100,
+            };
+
+            hideButton.Position = new Position(340, 10);
+            hideButton.Clicked += (s, e) =>
+            {
+
+                for (int i = 0; i < buttons.Count; i++)
+                {
+                    if (i % 2 == 0)
+                    {
+                        if (buttons[i].Visibility)
+                        {
+                            buttons[i].Hide();
+                        }
+                        else
+                        {
+                            buttons[i].Show();
+                        }
+                    }
+                }
+            };
+            absLayout.Add(hideButton);
+
+
+            var overlap = new Button
+            {
+                Focusable = true,
+                FocusableInTouch = true,
+                Text = "Overlap view",
+                SizeWidth = 300,
+                SizeHeight = 100,
+            };
+            overlap.Position = new Position(10, 120);
+            absLayout.Add(overlap);
+
+            View overlappedView = null;
+            overlap.Clicked += (s, e) =>
+            {
+                if (overlappedView != null)
+                {
+                    overlappedView.Unparent();
+                    overlappedView.Dispose();
+                    overlappedView = null;
+                    return;
+                }
+
+                overlappedView = new View
+                {
+                    Focusable = true,
+                    FocusableInTouch = true,
+                    Layout = new AbsoluteLayout(),
+                    SizeWidth = 400,
+                    SizeHeight = 400,
+                    BackgroundColor = new Color(1f, 0.5f, 0.5f, 0.5f)
+                };
+                overlappedView.Position = new Position(ItemWidth, ItemHeight + 300);
+                absLayout.Add(overlappedView);
+
+                var innerButton = MakeFocusableButton("InnerButton");
+                innerButton.SizeWidth = 350;
+                innerButton.SizeHeight = 350;
+                overlappedView.Add(innerButton);
+                innerButton.Position = new Position(10, 10);
+            };
+
+            _textLabel = new TextLabel
+            {
+                Text = "Focused : ",
+                SizeWidth = 500,
+                SizeHeight = 200,
+            };
+            _textLabel.Position = new Position(340, 220);
+            absLayout.Add(_textLabel);
+
+
+
+
+
+
+            var absLayout2 = new View
+            {
+                Layout = new AbsoluteLayout(),
+                WidthResizePolicy = ResizePolicyType.FillToParent,
+                HeightResizePolicy = ResizePolicyType.FillToParent,
+            };
+            window.Add(absLayout2);
+
+            var btn1 = MakeFocusableButton("#");
+            btn1.Position = new Position(ItemWidth, ItemHeight + 170);
+            ((Button)btn1).TextColor = Color.Red;
+            absLayout2.Add(btn1);
+
+            var btn2 = MakeFocusableButton("%");
+            btn2.Position = new Position(ItemWidth + 1 * (ItemWidth + ItemSpacing), ItemHeight + 170);
+            ((Button)btn2).TextColor = Color.Red;
+            absLayout2.Add(btn2);
+
+            var btn3 = MakeFocusableButton("*");
+            btn3.Position = new Position(ItemWidth + 2 * (ItemWidth + ItemSpacing), ItemHeight + 170);
+            ((Button)btn3).TextColor = Color.Red;
+            absLayout2.Add(btn3);
+
+            var btn4 = MakeFocusableButton("+");
+            btn4.Position = new Position(ItemWidth + 3 * (ItemWidth + ItemSpacing), ItemHeight + 170);
+            ((Button)btn4).TextColor = Color.Red;
+            absLayout2.Add(btn4);
+
+            var btn5 = MakeFocusableButton("-");
+            btn5.Position = new Position(ItemWidth + 4 * (ItemWidth + ItemSpacing), ItemHeight + 170);
+            ((Button)btn5).TextColor = Color.Red;
+            absLayout2.Add(btn5);
+
+
+            var focusableChildrenView = new Button
+            {
+                Focusable = true,
+                FocusableInTouch = true,
+                Text = "FocusableChildren",
+                SizeWidth = 400,
+                SizeHeight = 100,
+            };
+            focusableChildrenView.Position = new Position(340, 120);
+            absLayout.Add(focusableChildrenView);
+
+            focusableChildrenView.Clicked += (s, e) =>
+            {
+                absLayout2.FocusableChildren = false;
+            };
+        }
+
+        View MakeFocusableButton(string title)
+        {
+            var btn = new Button
+            {
+                Focusable = true,
+                FocusableInTouch = true,
+                Text = title,
+                SizeWidth = ItemWidth,
+                SizeHeight = ItemHeight,
+            };
+
+            btn.FocusGained += (s, e) => btn.Text = $"[{title}]";
+            btn.FocusLost += (s, e) => btn.Text = $"{title}";
+            btn.FocusGained += (s, e) => _textLabel.Text = $"Focused : {title}";
+            return btn;
+        }
+
+        public void Deactivate()
+        {
+        }
+    }
+}