2 * Copyright(c) 2021 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<FocusChangingEventArgs> focusChangingEventHandler;
40 private PreFocusChangeEventCallback focusChangingCallback;
42 private EventHandler<FocusChangedEventArgs> focusChangedEventHandler;
43 private FocusChangedEventCallback focusChangedEventCallback;
45 private EventHandler<FocusGroupChangedEventArgs> focusGroupChangedEventHandler;
46 private FocusGroupChangedEventCallback focusGroupChangedEventCallback;
48 private EventHandler<FocusedViewActivatedEventArgs> focusedViewEnterKeyEventHandler;
49 private FocusedViewEnterKeyEventCallback focusedViewEnterKeyEventCallback;
51 private EventHandler<FocusedViewActivatedEventArgs> focusedViewEnterKeyEventHandler2;
52 private FocusedViewEnterKeyEventCallback2 focusedViewEnterKeyEventCallback2;
54 internal FocusManager(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
58 internal FocusManager() : this(Interop.FocusManager.NewFocusManager(), true)
60 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
63 [UnmanagedFunctionPointer(CallingConvention.StdCall)]
64 internal delegate IntPtr PreFocusChangeEventCallback(IntPtr current, IntPtr proposed, View.FocusDirection direction);
66 [UnmanagedFunctionPointer(CallingConvention.StdCall)]
67 internal delegate void FocusChangedEventCallback(IntPtr current, IntPtr next);
69 [UnmanagedFunctionPointer(CallingConvention.StdCall)]
70 private delegate void FocusGroupChangedEventCallback(IntPtr current, bool forwardDirection);
72 [UnmanagedFunctionPointer(CallingConvention.StdCall)]
73 private delegate void FocusedViewEnterKeyEventCallback(IntPtr view);
75 [UnmanagedFunctionPointer(CallingConvention.StdCall)]
76 private delegate void FocusedViewEnterKeyEventCallback2(IntPtr view);
78 private View internalFocusIndicator = null;
79 private View nullFocusIndicator = null;
82 /// PreFocusChange will be triggered before the focus is going to be changed.<br />
83 /// The FocusManager makes the best guess for which view to focus towards the given direction, but applications might want to change that.<br />
84 /// By connecting with this event, they can check the proposed view to focus and return a different view if they wish.<br />
85 /// This event is only triggered when the navigation key is pressed and KeyboardFocusManager tries to move the focus automatically.<br />
86 /// It won't be emitted for focus movement by calling the SetCurrentFocusView directly.<br />
88 /// <since_tizen> 3 </since_tizen>
89 [Obsolete("Please do not use! This will be deprecated in API10. Please use FocusChanging instead!")]
90 // this will be deprecated, so suppress warning would be OK.
91 [System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1710:Identifiers should have correct suffix", Justification = "<Pending>")]
92 public event EventHandlerWithReturnType<object, PreFocusChangeEventArgs, View> PreFocusChange
96 if (preFocusChangeEventHandler == null)
98 preFocusChangeCallback = OnPreFocusChange;
99 using PreFocusChangeSignal signal = PreFocusChangeSignal();
100 signal?.Connect(preFocusChangeCallback);
102 preFocusChangeEventHandler += value;
106 preFocusChangeEventHandler -= value;
107 using PreFocusChangeSignal signal = PreFocusChangeSignal();
108 if (preFocusChangeEventHandler == null && signal?.Empty() == false)
110 signal?.Disconnect(preFocusChangeCallback);
116 /// FocusChanging will be triggered before the focus is going to be changed.<br />
117 /// The FocusManager makes the best guess for which view to focus towards the given direction, but applications might want to change that.<br />
118 /// By connecting with this event, they can check the proposed view to focus and assign a different view if they wish.<br />
119 /// This event is only triggered when the navigation key is pressed and FocusManager tries to move the focus automatically.<br />
120 /// It won't be emitted for focus movement by calling the SetCurrentFocusView directly.<br />
123 /// By setting FocusChangingEventArgs.Proposed with the view to be focused, the focus will be moved to the assigned view.
125 /// <since_tizen> 10 </since_tizen>
126 public event EventHandler<FocusChangingEventArgs> FocusChanging
130 if (focusChangingEventHandler == null)
132 focusChangingCallback = OnFocusChanging;
133 //this is same as old PreFocusChangeSignal, so the body will be same. (only name is changed, behavior is same)
134 using PreFocusChangeSignal signal = PreFocusChangeSignal();
135 signal?.Connect(focusChangingCallback);
137 focusChangingEventHandler += value;
141 focusChangingEventHandler -= value;
142 //this is same as old PreFocusChangeSignal, so the body will be same. (only name is changed, behavior is same)
143 using PreFocusChangeSignal signal = PreFocusChangeSignal();
144 if (focusChangingEventHandler == null && signal?.Empty() == false)
146 signal?.Disconnect(focusChangingCallback);
152 /// The FocusChanged will be triggered after the current focused view has been changed.
154 /// <since_tizen> 3 </since_tizen>
155 public event EventHandler<FocusChangedEventArgs> FocusChanged
159 if (focusChangedEventCallback == null)
161 focusChangedEventCallback = OnFocusChanged;
162 using FocusChangedSignal signal = FocusChangedSignal();
163 signal?.Connect(focusChangedEventCallback);
165 focusChangedEventHandler += value;
169 focusChangedEventHandler -= value;
171 using FocusChangedSignal signal = FocusChangedSignal();
172 if (focusChangedEventCallback == null && signal?.Empty() == false)
174 signal?.Disconnect(focusChangedEventCallback);
180 /// The FocusGroupChanged will be triggered when the focus group has been changed.<br />
181 /// 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 />
182 /// If not, the application has to set the new focus.<br />
184 /// <since_tizen> 3 </since_tizen>
185 public event EventHandler<FocusGroupChangedEventArgs> FocusGroupChanged
189 if (focusGroupChangedEventCallback == null)
191 focusGroupChangedEventCallback = OnFocusGroupChanged;
192 using FocusGroupChangedSignal signal = FocusGroupChangedSignal();
193 signal?.Connect(focusGroupChangedEventCallback);
195 focusGroupChangedEventHandler += value;
199 focusGroupChangedEventHandler -= value;
201 using FocusGroupChangedSignal signal = FocusGroupChangedSignal();
202 if (focusGroupChangedEventCallback == null && signal?.Empty() == false)
204 signal?.Disconnect(focusGroupChangedEventCallback);
210 /// The FocusedViewActivated will be triggered when the current focused view has the enter key pressed on it.
212 /// <since_tizen> 3 </since_tizen>
213 public event EventHandler<FocusedViewActivatedEventArgs> FocusedViewActivated
217 if (focusedViewEnterKeyEventCallback == null)
219 focusedViewEnterKeyEventCallback = OnFocusedViewEnterKey;
220 Interop.FocusManager.FocusedActorEnterKeySignalConnect(SwigCPtr, focusedViewEnterKeyEventCallback.ToHandleRef(this));
221 NDalicPINVOKE.ThrowExceptionIfExists();
223 focusedViewEnterKeyEventHandler += value;
227 focusedViewEnterKeyEventHandler -= value;
228 if (focusedViewEnterKeyEventHandler == null && focusedViewEnterKeyEventCallback != null)
230 Interop.FocusManager.FocusedActorEnterKeySignalDisconnect(SwigCPtr, focusedViewEnterKeyEventCallback.ToHandleRef(this));
231 NDalicPINVOKE.ThrowExceptionIfExists();
232 focusedViewEnterKeyEventCallback = null;
238 /// [Obsolete("Do not use this, that will be deprecated.")]
240 /// <since_tizen> 3 </since_tizen>
241 /// Do not use this, that will be deprecated.
242 /// Instead Use FocusedViewActivated.
243 [Obsolete("Do not use this, that will be deprecated. Use FocusManager.FocusedViewActivated instead. " +
245 "FocusManager.Instance.FocusedViewActivated = OnFocusedViewActivated; " +
246 "private void OnFocusedViewActivated(object source, FocusManager.FocusedViewActivatedEventArgs args) {...}")]
247 [EditorBrowsable(EditorBrowsableState.Never)]
248 public event EventHandler<FocusedViewActivatedEventArgs> FocusedViewEnterKeyPressed
252 if (focusedViewEnterKeyEventCallback2 == null)
254 focusedViewEnterKeyEventCallback2 = OnFocusedViewEnterKey2;
255 Interop.FocusManager.FocusedActorEnterKeySignalConnect(SwigCPtr, focusedViewEnterKeyEventCallback2.ToHandleRef(this));
256 NDalicPINVOKE.ThrowExceptionIfExists();
258 focusedViewEnterKeyEventHandler2 += value;
262 focusedViewEnterKeyEventHandler2 -= value;
264 if (focusedViewEnterKeyEventHandler2 == null && focusedViewEnterKeyEventCallback2 != null)
266 Interop.FocusManager.FocusedActorEnterKeySignalDisconnect(SwigCPtr, focusedViewEnterKeyEventCallback2.ToHandleRef(this));
267 NDalicPINVOKE.ThrowExceptionIfExists();
268 focusedViewEnterKeyEventCallback2 = null;
274 /// ICustomFocusAlgorithm is used to provide the custom keyboard focus algorithm for retrieving the next focusable view.<br />
275 /// The application can implement the interface and override the keyboard focus behavior.<br />
276 /// If the focus is changing within a layout container, then the layout container is queried first to provide the next focusable view.<br />
277 /// If this does not provide a valid view, then the Keyboard FocusManager will check focusable properties to determine the next focusable actor.<br />
278 /// If focusable properties are not set, then the keyboard FocusManager calls the GetNextFocusableView() method of this interface.<br />
280 /// <since_tizen> 3 </since_tizen>
281 public interface ICustomFocusAlgorithm
284 /// Get the next focus actor.
286 /// <param name="current">The current focus view.</param>
287 /// <param name="proposed">The proposed focus view</param>
288 /// <param name="direction">The focus move direction</param>
289 /// <returns>The next focus actor.</returns>
290 /// <since_tizen> 3 </since_tizen>
291 View GetNextFocusableView(View current, View proposed, View.FocusDirection direction);
296 /// Gets or sets the status of whether the focus movement should be looped within the same focus group.<br />
297 /// The focus movement is not looped by default.<br />
299 /// <since_tizen> 3 </since_tizen>
300 public bool FocusGroupLoop
304 SetFocusGroupLoop(value);
308 return GetFocusGroupLoop();
313 /// Gets or sets the focus indicator view.<br />
314 /// This will replace the default focus indicator view in the FocusManager and will be added to the focused view as a highlight.<br />
316 /// <since_tizen> 3 </since_tizen>
317 public View FocusIndicator
321 internalFocusIndicator = value;
322 if (internalFocusIndicator == null)
324 if (nullFocusIndicator == null)
326 nullFocusIndicator = new View();
328 SetFocusIndicatorView(nullFocusIndicator);
332 SetFocusIndicatorView(internalFocusIndicator);
337 return internalFocusIndicator;
342 /// Gets the singleton of the FocusManager object.
344 /// <since_tizen> 3 </since_tizen>
345 public static FocusManager Instance
354 /// Moves the keyboard focus to the given view.<br />
355 /// Only one view can be focused at the same time.<br />
356 /// The view must be in the stage already and keyboard focusable.<br />
358 /// <param name="view">The view to be focused.</param>
359 /// <returns>Whether the focus is successful or not.</returns>
360 /// <since_tizen> 3 </since_tizen>
361 public bool SetCurrentFocusView(View view)
365 throw new ArgumentNullException(nameof(view), "the target view should not be null");
368 bool ret = Interop.FocusManager.SetCurrentFocusActor(SwigCPtr, View.getCPtr(view));
369 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
374 /// Gets the current focused view.
376 /// <returns>A handle to the current focused view or an empty handle if no view is focused.</returns>
377 /// <since_tizen> 3 </since_tizen>
378 public View GetCurrentFocusView()
380 //to fix memory leak issue, match the handle count with native side.
381 IntPtr cPtr = Interop.FocusManager.GetCurrentFocusActor(SwigCPtr);
382 View ret = this.GetInstanceSafely<View>(cPtr);
387 /// Moves the focus to the next focusable view in the focus chain in the given direction (according to the focus traversal order).
389 /// <param name="direction">The direction of the focus movement.</param>
390 /// <returns>True if the movement was successful.</returns>
391 /// <since_tizen> 3 </since_tizen>
392 public bool MoveFocus(View.FocusDirection direction)
394 bool ret = Interop.FocusManager.MoveFocus(SwigCPtr, (int)direction);
395 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
400 /// Clears the focus from the current focused view if any, so that no view is focused in the focus chain.<br />
401 /// It will emit the FocusChanged event without the current focused view.<br />
403 /// <since_tizen> 3 </since_tizen>
404 public void ClearFocus()
406 Interop.FocusManager.ClearFocus(SwigCPtr);
407 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
411 /// Move the focus to previous focused view.
413 /// <since_tizen> 3 </since_tizen>
414 public void MoveFocusBackward()
416 Interop.FocusManager.MoveFocusBackward(SwigCPtr);
417 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
421 /// 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 />
422 /// Layout controls set themselves as focus groups by default.<br />
424 /// <param name="view">The view to be set as a focus group.</param>
425 /// <param name="isFocusGroup">Whether to set the view as a focus group or not.</param>
426 /// <since_tizen> 3 </since_tizen>
427 public void SetAsFocusGroup(View view, bool isFocusGroup)
429 Interop.FocusManager.SetAsFocusGroup(SwigCPtr, View.getCPtr(view), isFocusGroup);
430 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
434 /// Checks whether the view is set as a focus group or not.
436 /// <param name="view">The view to be checked.</param>
437 /// <returns>Whether the view is set as a focus group.</returns>
438 /// <since_tizen> 3 </since_tizen>
439 public bool IsFocusGroup(View view)
441 bool ret = Interop.FocusManager.IsFocusGroup(SwigCPtr, View.getCPtr(view));
442 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
447 /// Returns the closest ancestor of the given view that is a focus group.
449 /// <param name="view">The view to be checked for its focus group.</param>
450 /// <returns>The focus group the given view belongs to or an empty handle if the given view.</returns>
451 /// <since_tizen> 3 </since_tizen>
452 public View GetFocusGroup(View view)
454 //to fix memory leak issue, match the handle count with native side.
455 IntPtr cPtr = Interop.FocusManager.GetFocusGroup(SwigCPtr, View.getCPtr(view));
456 View ret = this.GetInstanceSafely<View>(cPtr);
461 /// Provides the implementation of a custom focus algorithm interface to allow the application to define the focus logic.<br />
463 /// <param name="arg0">The user's implementation of ICustomFocusAlgorithm.</param>
464 /// <since_tizen> 3 </since_tizen>
465 public void SetCustomAlgorithm(ICustomFocusAlgorithm arg0)
469 customAlgorithmInterfaceWrapper = new CustomAlgorithmInterfaceWrapper();
470 customAlgorithmInterfaceWrapper.SetFocusAlgorithm(arg0);
472 Interop.NDalic.SetCustomAlgorithm(SwigCPtr, CustomAlgorithmInterface.getCPtr(customAlgorithmInterfaceWrapper));
473 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
477 Interop.NDalic.SetCustomAlgorithm(SwigCPtr, new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero));
478 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
483 /// Sets to use the automatic focus moveing algorithm. <br />
484 /// It moves the focus to the view closest to the keyboard movement direction.
486 /// <param name="enable">Whether using default focus algorithm or not</param>
487 [EditorBrowsable(EditorBrowsableState.Never)]
488 public void EnableDefaultAlgorithm(bool enable)
490 Interop.FocusManager.EnableDefaultAlgorithm(SwigCPtr, enable);
491 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
495 /// Checks default focus moveing algorithm is enabled or not
497 /// <returns>Whether default focus algorithm is enabled</returns>
498 [EditorBrowsable(EditorBrowsableState.Never)]
499 public bool IsDefaultAlgorithmEnabled()
501 bool ret = Interop.FocusManager.IsDefaultAlgorithmEnabled(SwigCPtr);
502 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
507 /// Get the nearest focusable view.
509 /// <param name="rootView">The view group in which to find the next focusable view.</param>
510 /// <param name="focusedView">The current focused view.</param>
511 /// <param name="direction">The direction.</param>
512 /// <returns>The nearest focusable view, or an empty handle if none exists.</returns>
513 [EditorBrowsable(EditorBrowsableState.Never)]
514 public View GetNearestFocusableActor(View rootView, View focusedView, View.FocusDirection direction)
516 //to fix memory leak issue, match the handle count with native side.
517 IntPtr cPtr = Interop.FocusManager.GetNearestFocusableActor(View.getCPtr(rootView), View.getCPtr(focusedView), (int)direction);
518 View ret = this.GetInstanceSafely<View>(cPtr);
523 /// Sets the root view to start moving focus when DefaultAlgorithm is enabled.
524 /// This will only look for focusable Views within that View tree when looking for the next focus.
526 /// <param name="rootView">The root view in which to find the next focusable view.</param>
527 [EditorBrowsable(EditorBrowsableState.Never)]
528 public void SetFocusFinderRootView(View rootView)
530 Interop.FocusManager.SetFocusFinderRootView(SwigCPtr, View.getCPtr(rootView));
531 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
535 /// Reset the root view that starts moving focus when DefaultAlgorithm is enabled.
536 /// When reset, the window becomes root.
538 [EditorBrowsable(EditorBrowsableState.Never)]
539 public void ResetFocusFinderRootView()
541 Interop.FocusManager.ResetFocusFinderRootView(SwigCPtr);
542 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
546 /// Get a default focus indicator
549 /// The type actually <see cref="Tizen.NUI.BaseComponents.ImageView"/> of blue border squred png image, so it would be difficult to modify itself.
550 /// To change focus indicator, creating new indicator and assigning it to FocusIndicator are recommended.
553 /// FocusManager.Instance.FocusIndicator = new View()
555 /// PositionUsesPivotPoint = true,
556 /// PivotPoint = new Position(0, 0, 0),
557 /// WidthResizePolicy = ResizePolicyType.FillToParent,
558 /// HeightResizePolicy = ResizePolicyType.FillToParent,
559 /// BorderlineColor = Color.Orange,
560 /// BorderlineWidth = 4.0f,
561 /// BorderlineOffset = -1f,
562 /// BackgroundColor = new Color(0.2f, 0.2f, 0.2f, 0.2f),
566 /// <returns>instance of default focus indicator</returns>
567 [EditorBrowsable(EditorBrowsableState.Never)]
568 public View GetDefaultFocusIndicator()
570 ImageView ret = new ImageView(FrameworkInformation.ResourcePath + "keyboard_focus.9.png")
572 Name = "DefaultFocusIndicatorCreatedByNUI",
573 PositionUsesAnchorPoint = true,
574 ParentOrigin = ParentOrigin.Center,
575 PivotPoint = ParentOrigin.Center,
576 Position2D = new Position2D(0, 0),
578 ret.SetResizePolicy(ResizePolicyType.FillToParent, DimensionType.AllDimensions);
582 internal static FocusManager Get()
584 FocusManager ret = new FocusManager(Interop.FocusManager.Get(), true);
585 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
588 //tv profile never use default focus indicator, so this is not needed!
589 ret.FocusIndicator = ret.GetDefaultFocusIndicator();
594 internal void SetFocusGroupLoop(bool enabled)
596 Interop.FocusManager.SetFocusGroupLoop(SwigCPtr, enabled);
597 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
600 internal bool GetFocusGroupLoop()
602 bool ret = Interop.FocusManager.GetFocusGroupLoop(SwigCPtr);
603 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
607 internal void SetFocusIndicatorView(View indicator)
609 Interop.FocusManager.SetFocusIndicatorActor(SwigCPtr, View.getCPtr(indicator));
610 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
613 internal View GetFocusIndicatorView()
615 //to fix memory leak issue, match the handle count with native side.
616 IntPtr cPtr = Interop.FocusManager.GetFocusIndicatorActor(SwigCPtr);
617 return this.GetInstanceSafely<View>(cPtr);
620 internal PreFocusChangeSignal PreFocusChangeSignal()
622 PreFocusChangeSignal ret = new PreFocusChangeSignal(Interop.FocusManager.PreFocusChangeSignal(SwigCPtr), false);
623 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
627 internal FocusChangedSignal FocusChangedSignal()
629 FocusChangedSignal ret = new FocusChangedSignal(Interop.FocusManager.FocusChangedSignal(SwigCPtr), false);
630 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
634 internal FocusGroupChangedSignal FocusGroupChangedSignal()
636 FocusGroupChangedSignal ret = new FocusGroupChangedSignal(Interop.FocusManager.FocusGroupChangedSignal(SwigCPtr), false);
637 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
641 private IntPtr OnPreFocusChange(IntPtr current, IntPtr proposed, View.FocusDirection direction)
644 PreFocusChangeEventArgs e = new PreFocusChangeEventArgs();
646 if (current != global::System.IntPtr.Zero)
648 e.CurrentView = Registry.GetManagedBaseHandleFromNativePtr(current) as View;
650 if (proposed != global::System.IntPtr.Zero)
652 e.ProposedView = Registry.GetManagedBaseHandleFromNativePtr(proposed) as View;
654 e.Direction = direction;
656 if (preFocusChangeEventHandler != null)
658 view = preFocusChangeEventHandler(this, e);
663 return view.GetPtrfromView();
667 if (e.ProposedView != null) return proposed;
672 private IntPtr OnFocusChanging(IntPtr current, IntPtr proposed, View.FocusDirection direction)
674 View originallyProposed = null;
675 FocusChangingEventArgs e = new FocusChangingEventArgs();
677 if (current != global::System.IntPtr.Zero)
679 e.Current = Registry.GetManagedBaseHandleFromNativePtr(current) as View;
681 if (proposed != global::System.IntPtr.Zero)
683 originallyProposed = e.Proposed = Registry.GetManagedBaseHandleFromNativePtr(proposed) as View;
685 e.Direction = direction;
687 focusChangingEventHandler?.Invoke(this, e);
689 if (originallyProposed != e.Proposed)
691 //when user has changed Proposed
692 return e.Proposed.GetPtrfromView();
696 if (originallyProposed != null)
707 private void OnFocusChanged(IntPtr current, IntPtr next)
709 if (focusChangedEventHandler != null)
711 FocusChangedEventArgs e = new FocusChangedEventArgs();
713 e.Previous = e.CurrentView = Registry.GetManagedBaseHandleFromNativePtr(current) as View;
714 e.Current = e.NextView = Registry.GetManagedBaseHandleFromNativePtr(next) as View;
715 focusChangedEventHandler(this, e);
719 private void OnFocusGroupChanged(IntPtr current, bool forwardDirection)
721 if (focusGroupChangedEventHandler != null)
723 FocusGroupChangedEventArgs e = new FocusGroupChangedEventArgs();
725 e.CurrentView = Registry.GetManagedBaseHandleFromNativePtr(current) as View;
726 e.ForwardDirection = forwardDirection;
727 focusGroupChangedEventHandler(this, e);
731 private void OnFocusedViewEnterKey(IntPtr view)
733 if (focusedViewEnterKeyEventHandler != null)
735 FocusedViewActivatedEventArgs e = new FocusedViewActivatedEventArgs();
736 e.View = Registry.GetManagedBaseHandleFromNativePtr(view) as View;
737 focusedViewEnterKeyEventHandler(this, e);
742 /// Do not use this, that will be deprecated.
744 /// Do not use this, that will be deprecated.
745 /// Instead Use OnFocusedViewEnterKey.
746 [Obsolete("Do not use this, that will be deprecated. Use FocusManager.OnFocusedViewEnterKey instead.")]
747 [EditorBrowsable(EditorBrowsableState.Never)]
748 private void OnFocusedViewEnterKey2(IntPtr view)
750 if (focusedViewEnterKeyEventHandler != null)
752 FocusedViewActivatedEventArgs e = new FocusedViewActivatedEventArgs();
753 e.View = Registry.GetManagedBaseHandleFromNativePtr(view) as View;
754 focusedViewEnterKeyEventHandler(this, e);
759 /// Event arguments that passed via the PreFocusChange signal.
761 /// <since_tizen> 3 </since_tizen>
762 [Obsolete("Please do not use! This will be deprecated in API10. Please use FocusChangingEventArgs instead!")]
763 [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1034:Nested types should not be visible", Justification = "<Pending>")]
764 // this will be deprecated, so suppress warning would be OK.
765 public class PreFocusChangeEventArgs : EventArgs
767 private View current;
768 private View proposed;
769 private View.FocusDirection direction;
772 /// The current focus view.
774 /// <since_tizen> 3 </since_tizen>
775 public View CurrentView
788 /// The proposed view.
790 /// <since_tizen> 3 </since_tizen>
791 public View ProposedView
804 /// The focus move direction.
806 /// <since_tizen> 3 </since_tizen>
807 public View.FocusDirection Direction
821 /// Event arguments that passed via the FocusChanged signal.
823 /// <since_tizen> 3 </since_tizen>
824 public class FocusChangedEventArgs : EventArgs
826 private View currentView;
827 private View nextView;
828 private View previous;
829 private View current;
832 /// The current focus view.
834 /// <since_tizen> 3 </since_tizen>
835 [Obsolete("Please do not use! This will be deprecated! Please use Previous instead!")]
836 public View CurrentView
848 /// The next focus view.
850 /// <since_tizen> 3 </since_tizen>
851 [Obsolete("Please do not use! This will be deprecated! Please use Current instead!")]
864 /// The previously focused view.
866 /// <since_tizen> 10 </since_tizen>
879 /// The current focused view after focus changed.
881 /// <since_tizen> 10 </since_tizen>
896 /// Event arguments that passed via the FocusGroupChanged signal.
898 /// <since_tizen> 3 </since_tizen>
899 public class FocusGroupChangedEventArgs : EventArgs
901 private View current;
902 private bool forwardDirection;
905 /// The current focus view.
907 /// <since_tizen> 3 </since_tizen>
908 public View CurrentView
921 /// The forward direction.
923 /// <since_tizen> 3 </since_tizen>
924 public bool ForwardDirection
928 return forwardDirection;
932 forwardDirection = value;
938 /// Event arguments that passed via the FocusedViewEnterKey signal.
940 /// <since_tizen> 3 </since_tizen>
941 public class FocusedViewActivatedEventArgs : EventArgs
948 /// <since_tizen> 3 </since_tizen>
963 /// Do not use this, that will be deprecated.
965 /// <since_tizen> 3 </since_tizen>
966 /// Do not use this, that will be deprecated.
967 /// Instead Use FocusedViewActivatedEventArgs.
968 [Obsolete("Do not use this, that will be deprecated. Use FocusedViewActivatedEventArgs instead. " +
970 "FocusManager.Instance.FocusedViewActivated = OnFocusedViewActivated; " +
971 "private void OnFocusedViewActivated(object source, FocusManager.FocusedViewActivatedEventArgs arg)" +
973 [EditorBrowsable(EditorBrowsableState.Never)]
974 [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible")]
975 public class FocusedViewEnterKeyEventArgs : EventArgs
982 /// <since_tizen> 3 </since_tizen>
996 private class CustomAlgorithmInterfaceWrapper : CustomAlgorithmInterface
998 private FocusManager.ICustomFocusAlgorithm customFocusAlgorithm;
1000 public CustomAlgorithmInterfaceWrapper()
1004 public void SetFocusAlgorithm(FocusManager.ICustomFocusAlgorithm customFocusAlgorithm)
1006 this.customFocusAlgorithm = customFocusAlgorithm;
1009 public override View GetNextFocusableView(View current, View proposed, View.FocusDirection direction, string deviceName)
1011 if (customFocusAlgorithm == null)
1013 Tizen.Log.Error("NUI", $"[ERROR] User defined ICustomFocusAlgorithm interface class becomes unreachable. Null will be proposed for next focusing!");
1016 if (customFocusAlgorithm is ICustomAwareDeviceFocusAlgorithm deviceAwared)
1018 return deviceAwared.GetNextFocusableView(current, proposed, direction, deviceName);
1022 return customFocusAlgorithm.GetNextFocusableView(current, proposed, direction);