2 * Copyright(c) 2019 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 using System.Runtime.InteropServices;
20 using Tizen.NUI.BaseComponents;
21 using System.ComponentModel;
26 /// Provides the functionality of handling keyboard navigation and maintaining the two-dimensional keyboard focus chain.<br />
27 /// It provides functionality of setting the focus and moving the focus in four directions( i.e., left, right, up, and down).<br />
28 /// It also draws a highlight for the focused view and sends an event when the focus is changed.<br />
30 /// <since_tizen> 3 </since_tizen>
31 public class FocusManager : BaseHandle
33 private static readonly FocusManager instance = FocusManager.Get();
34 private CustomAlgorithmInterfaceWrapper _customAlgorithmInterfaceWrapper;
36 private EventHandlerWithReturnType<object, PreFocusChangeEventArgs, View> _preFocusChangeEventHandler;
37 private PreFocusChangeEventCallback _preFocusChangeCallback;
39 private EventHandler<FocusChangedEventArgs> _focusChangedEventHandler;
40 private FocusChangedEventCallback _focusChangedEventCallback;
42 private EventHandler<FocusGroupChangedEventArgs> _focusGroupChangedEventHandler;
43 private FocusGroupChangedEventCallback _focusGroupChangedEventCallback;
45 private EventHandler<FocusedViewActivatedEventArgs> _focusedViewEnterKeyEventHandler;
46 private FocusedViewEnterKeyEventCallback _focusedViewEnterKeyEventCallback;
48 private EventHandler<FocusedViewActivatedEventArgs> _focusedViewEnterKeyEventHandler2;
49 private FocusedViewEnterKeyEventCallback2 _focusedViewEnterKeyEventCallback2;
51 internal FocusManager(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.FocusManager.FocusManager_SWIGUpcast(cPtr), cMemoryOwn)
55 internal FocusManager() : this(Interop.FocusManager.new_FocusManager(), true)
57 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
60 [UnmanagedFunctionPointer(CallingConvention.StdCall)]
61 internal delegate IntPtr PreFocusChangeEventCallback(IntPtr current, IntPtr proposed, View.FocusDirection direction);
63 [UnmanagedFunctionPointer(CallingConvention.StdCall)]
64 internal delegate void FocusChangedEventCallback(IntPtr current, IntPtr next);
66 [UnmanagedFunctionPointer(CallingConvention.StdCall)]
67 private delegate void FocusGroupChangedEventCallback(IntPtr current, bool forwardDirection);
69 [UnmanagedFunctionPointer(CallingConvention.StdCall)]
70 private delegate void FocusedViewEnterKeyEventCallback(IntPtr view);
72 [UnmanagedFunctionPointer(CallingConvention.StdCall)]
73 private delegate void FocusedViewEnterKeyEventCallback2(IntPtr view);
76 /// PreFocusChange will be triggered before the focus is going to be changed.<br />
77 /// The FocusManager makes the best guess for which view to focus towards the given direction, but applications might want to change that.<br />
78 /// By connecting with this event, they can check the proposed view to focus and return a different view if they wish.<br />
79 /// This event is only triggered when the navigation key is pressed and KeyboardFocusManager tries to move the focus automatically.<br />
80 /// It won't be emitted for focus movement by calling the SetCurrentFocusView directly.<br />
82 /// <since_tizen> 3 </since_tizen>
83 public event EventHandlerWithReturnType<object, PreFocusChangeEventArgs, View> PreFocusChange
87 if (_preFocusChangeEventHandler == null)
89 _preFocusChangeCallback = OnPreFocusChange;
90 PreFocusChangeSignal().Connect(_preFocusChangeCallback);
92 _preFocusChangeEventHandler += value;
96 _preFocusChangeEventHandler -= value;
97 if (_preFocusChangeEventHandler == null && PreFocusChangeSignal().Empty() == false)
99 PreFocusChangeSignal().Disconnect(_preFocusChangeCallback);
105 /// The FocusGroupChanged will be triggered after the current focused view has been changed.
107 /// <since_tizen> 3 </since_tizen>
108 public event EventHandler<FocusChangedEventArgs> FocusChanged
112 if (_focusChangedEventCallback == null)
114 _focusChangedEventCallback = OnFocusChanged;
115 FocusChangedSignal().Connect(_focusChangedEventCallback);
117 _focusChangedEventHandler += value;
121 _focusChangedEventHandler -= value;
123 if (_focusChangedEventCallback == null && FocusChangedSignal().Empty() == false)
125 FocusChangedSignal().Disconnect(_focusChangedEventCallback);
131 /// The FocusGroupChanged will be triggered when the focus group has been changed.<br />
132 /// If the current focus group has a parent layout control, the FocusManager will make the best guess for the next focus group to move the focus to in the given direction (forward or backward).<br />
133 /// If not, the application has to set the new focus.<br />
135 /// <since_tizen> 3 </since_tizen>
136 public event EventHandler<FocusGroupChangedEventArgs> FocusGroupChanged
140 if (_focusGroupChangedEventCallback == null)
142 _focusGroupChangedEventCallback = OnFocusGroupChanged;
143 FocusGroupChangedSignal().Connect(_focusGroupChangedEventCallback);
145 _focusGroupChangedEventHandler += value;
149 _focusGroupChangedEventHandler -= value;
151 if (_focusGroupChangedEventCallback == null && FocusGroupChangedSignal().Empty() == false)
153 FocusGroupChangedSignal().Disconnect(_focusGroupChangedEventCallback);
159 /// The FocusedViewActivated will be triggered when the current focused view has the enter key pressed on it.
161 /// <since_tizen> 3 </since_tizen>
162 public event EventHandler<FocusedViewActivatedEventArgs> FocusedViewActivated
166 if (_focusedViewEnterKeyEventCallback == null)
168 _focusedViewEnterKeyEventCallback = OnFocusedViewEnterKey;
169 FocusedViewEnterKeySignal().Connect(_focusedViewEnterKeyEventCallback);
171 _focusedViewEnterKeyEventHandler += value;
175 _focusedViewEnterKeyEventHandler -= value;
177 if (_focusedViewEnterKeyEventCallback != null && FocusedViewEnterKeySignal().Empty() == false)
179 FocusedViewEnterKeySignal().Disconnect(_focusedViewEnterKeyEventCallback);
185 /// [Obsolete("Please do not use! this will be deprecated")]
187 /// <since_tizen> 3 </since_tizen>
188 /// Please do not use! this will be deprecated!
189 /// Instead please use FocusedViewActivated.
190 [Obsolete("Please do not use! This will be deprecated! Please use FocusManager.FocusedViewActivated instead! " +
192 "FocusManager.Instance.FocusedViewActivated = OnFocusedViewActivated; " +
193 "private void OnFocusedViewActivated(object source, FocusManager.FocusedViewActivatedEventArgs args) {...}")]
194 [EditorBrowsable(EditorBrowsableState.Never)]
195 public event EventHandler<FocusedViewActivatedEventArgs> FocusedViewEnterKeyPressed
199 if (_focusedViewEnterKeyEventCallback2 == null)
201 _focusedViewEnterKeyEventCallback2 = OnFocusedViewEnterKey2;
202 FocusedViewEnterKeySignal().Connect(_focusedViewEnterKeyEventCallback2);
204 _focusedViewEnterKeyEventHandler2 += value;
208 _focusedViewEnterKeyEventHandler2 -= value;
210 if (_focusedViewEnterKeyEventCallback2 != null && FocusedViewEnterKeySignal().Empty() == false)
212 FocusedViewEnterKeySignal().Disconnect(_focusedViewEnterKeyEventCallback2);
218 /// ICustomFocusAlgorithm is used to provide the custom keyboard focus algorithm for retrieving the next focusable view.<br />
219 /// The application can implement the interface and override the keyboard focus behavior.<br />
220 /// If the focus is changing within a layout container, then the layout container is queried first to provide the next focusable view.<br />
221 /// If this does not provide a valid view, then the Keyboard FocusManager will check focusable properties to determine the next focusable actor.<br />
222 /// If focusable properties are not set, then the keyboard FocusManager calls the GetNextFocusableView() method of this interface.<br />
224 /// <since_tizen> 3 </since_tizen>
225 public interface ICustomFocusAlgorithm
228 /// Get the next focus actor.
230 /// <param name="current">The current focus view.</param>
231 /// <param name="proposed">The proposed focus view</param>
232 /// <param name="direction">The focus move direction</param>
233 /// <returns>The next focus actor.</returns>
234 /// <since_tizen> 3 </since_tizen>
235 View GetNextFocusableView(View current, View proposed, View.FocusDirection direction);
239 /// Gets or sets the status of whether the focus movement should be looped within the same focus group.<br />
240 /// The focus movement is not looped by default.<br />
242 /// <since_tizen> 3 </since_tizen>
243 public bool FocusGroupLoop
247 SetFocusGroupLoop(value);
251 return GetFocusGroupLoop();
256 /// Gets or sets the focus indicator view.<br />
257 /// This will replace the default focus indicator view in the FocusManager and will be added to the focused view as a highlight.<br />
259 /// <since_tizen> 3 </since_tizen>
260 public View FocusIndicator
264 SetFocusIndicatorView(value);
268 return GetFocusIndicatorView();
273 /// Gets the singleton of the FocusManager object.
275 /// <since_tizen> 3 </since_tizen>
276 public static FocusManager Instance
285 /// Moves the keyboard focus to the given view.<br />
286 /// Only one view can be focused at the same time.<br />
287 /// The view must be in the stage already and keyboard focusable.<br />
289 /// <param name="view">The view to be focused.</param>
290 /// <returns>Whether the focus is successful or not.</returns>
291 /// <since_tizen> 3 </since_tizen>
292 public bool SetCurrentFocusView(View view)
296 throw new ArgumentNullException("the target view should not be null");
299 bool ret = Interop.FocusManager.FocusManager_SetCurrentFocusActor(swigCPtr, View.getCPtr(view));
300 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
305 /// Gets the current focused view.
307 /// <returns>A handle to the current focused view or an empty handle if no view is focused.</returns>
308 /// <since_tizen> 3 </since_tizen>
309 public View GetCurrentFocusView()
311 //to fix memory leak issue, match the handle count with native side.
312 IntPtr cPtr = Interop.FocusManager.FocusManager_GetCurrentFocusActor(swigCPtr);
313 View ret = this.GetInstanceSafely<View>(cPtr);
318 /// Moves the focus to the next focusable view in the focus chain in the given direction (according to the focus traversal order).
320 /// <param name="direction">The direction of the focus movement.</param>
321 /// <returns>True if the movement was successful.</returns>
322 /// <since_tizen> 3 </since_tizen>
323 public bool MoveFocus(View.FocusDirection direction)
325 bool ret = Interop.FocusManager.FocusManager_MoveFocus(swigCPtr, (int)direction);
326 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
331 /// Clears the focus from the current focused view if any, so that no view is focused in the focus chain.<br />
332 /// It will emit the FocusChanged event without the current focused view.<br />
334 /// <since_tizen> 3 </since_tizen>
335 public void ClearFocus()
337 Interop.FocusManager.FocusManager_ClearFocus(swigCPtr);
338 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
342 /// Move the focus to previous focused view.
344 /// <since_tizen> 3 </since_tizen>
345 public void MoveFocusBackward()
347 Interop.FocusManager.FocusManager_MoveFocusBackward(swigCPtr);
348 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
352 /// Sets whether the view is a focus group that can limit the scope of the focus movement to its child views in the focus chain.<br />
353 /// Layout controls set themselves as focus groups by default.<br />
355 /// <param name="view">The view to be set as a focus group.</param>
356 /// <param name="isFocusGroup">Whether to set the view as a focus group or not.</param>
357 /// <since_tizen> 3 </since_tizen>
358 public void SetAsFocusGroup(View view, bool isFocusGroup)
360 Interop.FocusManager.FocusManager_SetAsFocusGroup(swigCPtr, View.getCPtr(view), isFocusGroup);
361 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
365 /// Checks whether the view is set as a focus group or not.
367 /// <param name="view">The view to be checked.</param>
368 /// <returns>Whether the view is set as a focus group.</returns>
369 /// <since_tizen> 3 </since_tizen>
370 public bool IsFocusGroup(View view)
372 bool ret = Interop.FocusManager.FocusManager_IsFocusGroup(swigCPtr, View.getCPtr(view));
373 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
378 /// Returns the closest ancestor of the given view that is a focus group.
380 /// <param name="view">The view to be checked for its focus group.</param>
381 /// <returns>The focus group the given view belongs to or an empty handle if the given view.</returns>
382 /// <since_tizen> 3 </since_tizen>
383 public View GetFocusGroup(View view)
385 //to fix memory leak issue, match the handle count with native side.
386 IntPtr cPtr = Interop.FocusManager.FocusManager_GetFocusGroup(swigCPtr, View.getCPtr(view));
387 View ret = this.GetInstanceSafely<View>(cPtr);
392 /// Provides the implementation of a custom focus algorithm interface to allow the application to define the focus logic.<br />
394 /// <param name="arg0">The user's implementation of ICustomFocusAlgorithm.</param>
395 /// <since_tizen> 3 </since_tizen>
396 public void SetCustomAlgorithm(ICustomFocusAlgorithm arg0)
400 _customAlgorithmInterfaceWrapper = new CustomAlgorithmInterfaceWrapper();
401 _customAlgorithmInterfaceWrapper.SetFocusAlgorithm(arg0);
403 Interop.NDalic.SetCustomAlgorithm(swigCPtr, CustomAlgorithmInterface.getCPtr(_customAlgorithmInterfaceWrapper));
404 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
408 Interop.NDalic.SetCustomAlgorithm(swigCPtr, new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero));
409 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
414 /// Sets to use the automatic focus moveing algorithm. <br />
415 /// It moves the focus to the view closest to the keyboard movement direction.
417 /// <param name="enable">Whether using default focus algorithm or not</param>
418 [EditorBrowsable(EditorBrowsableState.Never)]
419 public void EnableDefaultAlgorithm(bool enable)
421 Interop.FocusManager.EnableDefaultAlgorithm(SwigCPtr, enable);
422 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
426 /// Checks default focus moveing algorithm is enabled or not
428 /// <returns>Whether default focus algorithm is enabled</returns>
429 [EditorBrowsable(EditorBrowsableState.Never)]
430 public bool IsDefaultAlgorithmEnabled()
432 bool ret = Interop.FocusManager.IsDefaultAlgorithmEnabled(SwigCPtr);
433 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
437 internal static FocusManager Get()
439 FocusManager ret = new FocusManager(Interop.FocusManager.FocusManager_Get(), true);
440 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
444 internal void SetFocusGroupLoop(bool enabled)
446 Interop.FocusManager.FocusManager_SetFocusGroupLoop(swigCPtr, enabled);
447 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
450 internal bool GetFocusGroupLoop()
452 bool ret = Interop.FocusManager.FocusManager_GetFocusGroupLoop(swigCPtr);
453 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
457 internal void SetFocusIndicatorView(View indicator)
459 Interop.FocusManager.FocusManager_SetFocusIndicatorActor(swigCPtr, View.getCPtr(indicator));
460 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
463 internal View GetFocusIndicatorView()
465 //to fix memory leak issue, match the handle count with native side.
466 IntPtr cPtr = Interop.FocusManager.FocusManager_GetFocusIndicatorActor(swigCPtr);
467 View ret = this.GetInstanceSafely<View>(cPtr);
471 internal PreFocusChangeSignal PreFocusChangeSignal()
473 PreFocusChangeSignal ret = new PreFocusChangeSignal(Interop.FocusManager.FocusManager_PreFocusChangeSignal(swigCPtr), false);
474 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
478 internal FocusChangedSignal FocusChangedSignal()
480 FocusChangedSignal ret = new FocusChangedSignal(Interop.FocusManager.FocusManager_FocusChangedSignal(swigCPtr), false);
481 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
485 internal FocusGroupChangedSignal FocusGroupChangedSignal()
487 FocusGroupChangedSignal ret = new FocusGroupChangedSignal(Interop.FocusManager.FocusManager_FocusGroupChangedSignal(swigCPtr), false);
488 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
492 internal ViewSignal FocusedViewEnterKeySignal()
494 ViewSignal ret = new ViewSignal(Interop.FocusManager.FocusManager_FocusedActorEnterKeySignal(swigCPtr), false);
495 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
499 private IntPtr OnPreFocusChange(IntPtr current, IntPtr proposed, View.FocusDirection direction)
502 PreFocusChangeEventArgs e = new PreFocusChangeEventArgs();
504 if (current != global::System.IntPtr.Zero)
506 e.CurrentView = Registry.GetManagedBaseHandleFromNativePtr(current) as View;
508 if (proposed != global::System.IntPtr.Zero)
510 e.ProposedView = Registry.GetManagedBaseHandleFromNativePtr(proposed) as View;
512 e.Direction = direction;
514 if (_preFocusChangeEventHandler != null)
516 view = _preFocusChangeEventHandler(this, e);
521 return view.GetPtrfromView();
525 if (e.ProposedView) return proposed;
530 private void OnFocusChanged(IntPtr current, IntPtr next)
532 FocusChangedEventArgs e = new FocusChangedEventArgs();
534 e.CurrentView = Registry.GetManagedBaseHandleFromNativePtr(current) as View;
535 e.NextView = Registry.GetManagedBaseHandleFromNativePtr(next) as View;
537 if (_focusChangedEventHandler != null)
539 _focusChangedEventHandler(this, e);
543 private void OnFocusGroupChanged(IntPtr current, bool forwardDirection)
545 FocusGroupChangedEventArgs e = new FocusGroupChangedEventArgs();
547 e.CurrentView = Registry.GetManagedBaseHandleFromNativePtr(current) as View;
548 e.ForwardDirection = forwardDirection;
550 if (_focusGroupChangedEventHandler != null)
552 _focusGroupChangedEventHandler(this, e);
556 private void OnFocusedViewEnterKey(IntPtr view)
558 FocusedViewActivatedEventArgs e = new FocusedViewActivatedEventArgs();
560 e.View = Registry.GetManagedBaseHandleFromNativePtr(view) as View;
562 if (_focusedViewEnterKeyEventHandler != null)
564 _focusedViewEnterKeyEventHandler(this, e);
569 /// Please do not use! this will be deprecated!
571 /// Please do not use! this will be deprecated!
572 /// Instead please use OnFocusedViewEnterKey.
573 [Obsolete("Please do not use! This will be deprecated! Please use FocusManager.OnFocusedViewEnterKey instead!")]
574 [EditorBrowsable(EditorBrowsableState.Never)]
575 private void OnFocusedViewEnterKey2(IntPtr view)
577 FocusedViewActivatedEventArgs e = new FocusedViewActivatedEventArgs();
579 e.View = Registry.GetManagedBaseHandleFromNativePtr(view) as View;
581 if (_focusedViewEnterKeyEventHandler != null)
583 _focusedViewEnterKeyEventHandler(this, e);
588 /// Event arguments that passed via the PreFocusChange signal.
590 /// <since_tizen> 3 </since_tizen>
591 public class PreFocusChangeEventArgs : EventArgs
593 private View _current;
594 private View _proposed;
595 private View.FocusDirection _direction;
598 /// The current focus view.
600 /// <since_tizen> 3 </since_tizen>
601 public View CurrentView
614 /// The proposed view.
616 /// <since_tizen> 3 </since_tizen>
617 public View ProposedView
630 /// The focus move direction.
632 /// <since_tizen> 3 </since_tizen>
633 public View.FocusDirection Direction
647 /// Event arguments that passed via the FocusChanged signal.
649 /// <since_tizen> 3 </since_tizen>
650 public class FocusChangedEventArgs : EventArgs
652 private View _current;
656 /// The current focus view.
658 /// <since_tizen> 3 </since_tizen>
659 public View CurrentView
671 /// The next focus view.
673 /// <since_tizen> 3 </since_tizen>
688 /// Event arguments that passed via the FocusGroupChanged signal.
690 /// <since_tizen> 3 </since_tizen>
691 public class FocusGroupChangedEventArgs : EventArgs
693 private View _current;
694 private bool _forwardDirection;
697 /// The current focus view.
699 /// <since_tizen> 3 </since_tizen>
700 public View CurrentView
713 /// The forward direction.
715 /// <since_tizen> 3 </since_tizen>
716 public bool ForwardDirection
720 return _forwardDirection;
724 _forwardDirection = value;
730 /// Event arguments that passed via the FocusedViewEnterKey signal.
732 /// <since_tizen> 3 </since_tizen>
733 public class FocusedViewActivatedEventArgs : EventArgs
740 /// <since_tizen> 3 </since_tizen>
755 /// Please do not use! this will be deprecated
757 /// <since_tizen> 3 </since_tizen>
758 /// Please do not use! this will be deprecated.
759 /// Instead please use FocusedViewActivatedEventArgs.
760 [Obsolete("Please do not use! This will be deprecated! Please use FocusedViewActivatedEventArgs instead! " +
762 "FocusManager.Instance.FocusedViewActivated = OnFocusedViewActivated; " +
763 "private void OnFocusedViewActivated(object source, FocusManager.FocusedViewActivatedEventArgs arg)" +
765 [EditorBrowsable(EditorBrowsableState.Never)]
766 public class FocusedViewEnterKeyEventArgs : EventArgs
773 /// <since_tizen> 3 </since_tizen>
787 private class CustomAlgorithmInterfaceWrapper : CustomAlgorithmInterface
789 private FocusManager.ICustomFocusAlgorithm _customFocusAlgorithm;
791 public CustomAlgorithmInterfaceWrapper()
795 public void SetFocusAlgorithm(FocusManager.ICustomFocusAlgorithm customFocusAlgorithm)
797 _customFocusAlgorithm = customFocusAlgorithm;
800 public override View GetNextFocusableView(View current, View proposed, View.FocusDirection direction)
802 if(_customFocusAlgorithm == null)
804 Tizen.Log.Error("NUI", $"[ERROR] User defined ICustomFocusAlgorithm interface class becomes unreachable. Null will be proposed for next focusing!");
807 return _customFocusAlgorithm.GetNextFocusableView(current, proposed, direction);