From: joogab.yun Date: Fri, 4 Mar 2022 09:28:29 +0000 (+0900) Subject: [NUI] Add a new Tizen.NUI.ICustomAwareDeviceFocusAlgorithm. X-Git-Tag: submit/tizen/20220329.054434~1^2~7 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2c4dae8e2e5d3a6bb84f217def164bc0f2b1ff45;p=platform%2Fcore%2Fcsapi%2Ftizenfx.git [NUI] Add a new Tizen.NUI.ICustomAwareDeviceFocusAlgorithm. This interface takes an additional deviceName argument to GetNextFocusableView(). The deviceName is the name of the device where the key event occurred. A new deviceName added to GetNextFocusableView() should not affect the current app. Current apps are using the FocusManager.ICustomFocusAlgorithm interface. So I created a new Tizen.NUI.ICustomAwareDeviceFocusAlgorithm interface. for example) Currently ``` c# class CustomInterface : FocusManager.ICustomFocusAlgorithm { public View GetNextFocusableView(View current, View proposed, View.FocusDirection direction) { return proposed; } } ``` If you wnat to do GetNextFocusableView() with deviceName, you can inherit ICustomAwareDeviceFocusAlgorithm. ``` c# class CustomInterface : Tizen.NUI.ICustomAwareDeviceFocusAlgorithm { // This method is called when a direction key is pressed. public View GetNextFocusableView(View current, View proposed, View.FocusDirection direction, string deviceName) { return proposed; } // This method is never called. public View GetNextFocusableView(View current, View proposed, View.FocusDirection direction) { return proposed; } } ``` dependency https://review.tizen.org/gerrit/#/c/platform/core/uifw/dali-toolkit/+/271983/ https://review.tizen.org/gerrit/#/c/platform/core/uifw/dali-csharp-binder/+/271984/ --- diff --git a/src/Tizen.NUI/src/internal/Common/CustomAlgorithmInterface.cs b/src/Tizen.NUI/src/internal/Common/CustomAlgorithmInterface.cs index 23ff57a44..3f6dc242e 100755 --- a/src/Tizen.NUI/src/internal/Common/CustomAlgorithmInterface.cs +++ b/src/Tizen.NUI/src/internal/Common/CustomAlgorithmInterface.cs @@ -31,9 +31,9 @@ namespace Tizen.NUI Interop.CustomAlgorithmInterface.DeleteCustomAlgorithmInterface(swigCPtr); } - public virtual View GetNextFocusableView(View current, View proposed, View.FocusDirection direction) + public virtual View GetNextFocusableView(View current, View proposed, View.FocusDirection direction, string deviceName = "") { - View ret = new View(Interop.CustomAlgorithmInterface.GetNextFocusableActor(SwigCPtr, View.getCPtr(current), View.getCPtr(proposed), (int)direction), true); + View ret = new View(Interop.CustomAlgorithmInterface.GetNextFocusableActor(SwigCPtr, View.getCPtr(current), View.getCPtr(proposed), (int)direction, deviceName), true); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); return ret; } @@ -58,7 +58,7 @@ namespace Tizen.NUI return hasDerivedMethod && (methodInfo != null); } - private global::System.IntPtr SwigDirectorGetNextFocusableView(global::System.IntPtr current, global::System.IntPtr proposed, int direction) + private global::System.IntPtr SwigDirectorGetNextFocusableView(global::System.IntPtr current, global::System.IntPtr proposed, int direction, string deviceName) { if (current == global::System.IntPtr.Zero && proposed == global::System.IntPtr.Zero) { @@ -70,19 +70,19 @@ namespace Tizen.NUI View currentView = Registry.GetManagedBaseHandleFromNativePtr(current) as View; View proposedView = Registry.GetManagedBaseHandleFromNativePtr(proposed) as View; - return View.getCPtr(GetNextFocusableView(currentView, proposedView, (View.FocusDirection)direction)).Handle; + return View.getCPtr(GetNextFocusableView(currentView, proposedView, (View.FocusDirection)direction, deviceName)).Handle; } catch (global::System.Exception ex) { Tizen.Log.Error("NUI", "Registry Error: " + ex); + throw; } - return global::System.IntPtr.Zero; } - internal delegate global::System.IntPtr SwigDelegateCustomAlgorithmInterface_0(global::System.IntPtr current, global::System.IntPtr proposed, int direction); + internal delegate global::System.IntPtr SwigDelegateCustomAlgorithmInterface_0(global::System.IntPtr current, global::System.IntPtr proposed, int direction, string deviceName); private SwigDelegateCustomAlgorithmInterface_0 swigDelegate0; - private static global::System.Type[] swigMethodTypes0 = new global::System.Type[] { typeof(View), typeof(View), typeof(View.FocusDirection) }; + private static global::System.Type[] swigMethodTypes0 = new global::System.Type[] { typeof(View), typeof(View), typeof(View.FocusDirection), typeof(string) }; } } diff --git a/src/Tizen.NUI/src/internal/Interop/Interop.CustomAlgorithmInterface.cs b/src/Tizen.NUI/src/internal/Interop/Interop.CustomAlgorithmInterface.cs index 9319dd2d8..88bb27c43 100755 --- a/src/Tizen.NUI/src/internal/Interop/Interop.CustomAlgorithmInterface.cs +++ b/src/Tizen.NUI/src/internal/Interop/Interop.CustomAlgorithmInterface.cs @@ -25,7 +25,7 @@ namespace Tizen.NUI public static extern void DeleteCustomAlgorithmInterface(global::System.Runtime.InteropServices.HandleRef jarg1); [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_CustomAlgorithmInterface_GetNextFocusableActor")] - public static extern global::System.IntPtr GetNextFocusableActor(global::System.Runtime.InteropServices.HandleRef jarg1, global::System.Runtime.InteropServices.HandleRef jarg2, global::System.Runtime.InteropServices.HandleRef jarg3, int jarg4); + public static extern global::System.IntPtr GetNextFocusableActor(global::System.Runtime.InteropServices.HandleRef jarg1, global::System.Runtime.InteropServices.HandleRef jarg2, global::System.Runtime.InteropServices.HandleRef jarg3, int jarg4, string deviceName); [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_new_CustomAlgorithmInterface")] public static extern global::System.IntPtr NewCustomAlgorithmInterface(); diff --git a/src/Tizen.NUI/src/public/Input/FocusManager.cs b/src/Tizen.NUI/src/public/Input/FocusManager.cs index cc27082a6..7706b567e 100755 --- a/src/Tizen.NUI/src/public/Input/FocusManager.cs +++ b/src/Tizen.NUI/src/public/Input/FocusManager.cs @@ -237,6 +237,7 @@ namespace Tizen.NUI View GetNextFocusableView(View current, View proposed, View.FocusDirection direction); } + /// /// Gets or sets the status of whether the focus movement should be looped within the same focus group.
/// The focus movement is not looped by default.
@@ -811,14 +812,21 @@ namespace Tizen.NUI this.customFocusAlgorithm = customFocusAlgorithm; } - public override View GetNextFocusableView(View current, View proposed, View.FocusDirection direction) + public override View GetNextFocusableView(View current, View proposed, View.FocusDirection direction, string deviceName) { if (customFocusAlgorithm == null) { Tizen.Log.Error("NUI", $"[ERROR] User defined ICustomFocusAlgorithm interface class becomes unreachable. Null will be proposed for next focusing!"); return null; } - return customFocusAlgorithm.GetNextFocusableView(current, proposed, direction); + if (customFocusAlgorithm is ICustomAwareDeviceFocusAlgorithm deviceAwared) + { + return deviceAwared.GetNextFocusableView(current, proposed, direction, deviceName); + } + else + { + return customFocusAlgorithm.GetNextFocusableView(current, proposed, direction); + } } } } diff --git a/src/Tizen.NUI/src/public/Input/ICustomAwareDeviceFocusAlgorithm.cs b/src/Tizen.NUI/src/public/Input/ICustomAwareDeviceFocusAlgorithm.cs new file mode 100755 index 000000000..6503a4dfb --- /dev/null +++ b/src/Tizen.NUI/src/public/Input/ICustomAwareDeviceFocusAlgorithm.cs @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2022 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 Tizen.NUI.BaseComponents; +using System.ComponentModel; + +namespace Tizen.NUI +{ + /// + /// ICustomAwareDeviceFocusAlgorithm inherits from + /// ICustomAwareDeviceFocusAlgorithm is used to provide the custom keyboard focus algorithm for retrieving the next focusable view.
+ /// The application can implement the interface and override the keyboard focus behavior.
+ /// If the focus is changing within a layout container, then the layout container is queried first to provide the next focusable view.
+ /// If this does not provide a valid view, then the Keyboard FocusManager will check focusable properties to determine the next focusable actor.
+ /// If focusable properties are not set, then the keyboard FocusManager calls the GetNextFocusableView() method of this interface.
+ /// This interface calls GetNextFocusableView() with deviceName.
+ ///
+ [EditorBrowsable(EditorBrowsableState.Never)] + public interface ICustomAwareDeviceFocusAlgorithm : FocusManager.ICustomFocusAlgorithm + { + /// + /// Get the next focus actor. + /// + /// The current focus view. + /// The proposed focus view + /// The focus move direction + /// The name of device the key event originated from + /// The next focus actor. + [EditorBrowsable(EditorBrowsableState.Never)] + View GetNextFocusableView(View current, View proposed, View.FocusDirection direction, string deviceName); + } +} diff --git a/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/GetNextFocusSample.cs b/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/GetNextFocusSample.cs new file mode 100644 index 000000000..e59873bf6 --- /dev/null +++ b/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/GetNextFocusSample.cs @@ -0,0 +1,84 @@ +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 GetNextFocusSample : IExample + { + + int ItemWidth = 100; + int ItemHeight = 100; + int ItemSpacing = 10; + + public View TargetView = new View(); + + class CustomInterface : ICustomAwareDeviceFocusAlgorithm + { + // This method is called when a direction key is pressed. + public View GetNextFocusableView(View current, View proposed, View.FocusDirection direction, string deviceName) + { + Tizen.Log.Error("NUI", $" GetNextFocusableView deviceName {deviceName}\n"); + return proposed; + } + + // This method is never called. + public View GetNextFocusableView(View current, View proposed, View.FocusDirection direction) + { + Tizen.Log.Error("NUI", $" GetNextFocusableView \n"); + return proposed; + } + } + + public void Activate() + { + Window window = NUIApplication.GetDefaultWindow(); + + CustomInterface custom = new CustomInterface(); + FocusManager.Instance.SetCustomAlgorithm(custom); + + var absLayout = new View + { + Layout = new AbsoluteLayout(), + WidthResizePolicy = ResizePolicyType.FillToParent, + HeightResizePolicy = ResizePolicyType.FillToParent, + Focusable = true, + FocusableInTouch = true, + }; + window.Add(absLayout); + + 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)); + absLayout.Add(btn); + } + } + } + + 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() + { + } + } +}