[NUI] fix memory leak problem
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / public / FocusManager.cs
1 /*
2  * Copyright(c) 2017 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18 using System;
19 using System.Runtime.InteropServices;
20 using Tizen.NUI.BaseComponents;
21 using System.ComponentModel;
22
23 namespace Tizen.NUI
24 {
25     /// <summary>
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 />
29     /// </summary>
30     /// <since_tizen> 3 </since_tizen>
31     public class FocusManager : BaseHandle
32     {
33         private global::System.Runtime.InteropServices.HandleRef swigCPtr;
34         private CustomAlgorithmInterfaceWrapper _customAlgorithmInterfaceWrapper;
35
36         internal FocusManager(global::System.IntPtr cPtr, bool cMemoryOwn) : base(NDalicManualPINVOKE.FocusManager_SWIGUpcast(cPtr), cMemoryOwn)
37         {
38             swigCPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr);
39         }
40
41         internal static global::System.Runtime.InteropServices.HandleRef getCPtr(FocusManager obj)
42         {
43             return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr;
44         }
45
46         ///<summary>
47         /// Event arguments that passed via the PreFocusChange signal.
48         /// </summary>
49         /// <since_tizen> 3 </since_tizen>
50         public class PreFocusChangeEventArgs : EventArgs
51         {
52             private View _current;
53             private View _proposed;
54             private View.FocusDirection _direction;
55
56             /// <summary>
57             /// The current focus view.
58             /// </summary>
59             /// <since_tizen> 3 </since_tizen>
60             public View CurrentView
61             {
62                 get
63                 {
64                     return _current;
65                 }
66                 set
67                 {
68                     _current = value;
69                 }
70             }
71
72             /// <summary>
73             /// The  proposed view.
74             /// </summary>
75             /// <since_tizen> 3 </since_tizen>
76             public View ProposedView
77             {
78                 get
79                 {
80                     return _proposed;
81                 }
82                 set
83                 {
84                     _proposed = value;
85                 }
86             }
87
88             /// <summary>
89             /// The focus move direction.
90             /// </summary>
91             /// <since_tizen> 3 </since_tizen>
92             public View.FocusDirection Direction
93             {
94                 get
95                 {
96                     return _direction;
97                 }
98                 set
99                 {
100                     _direction = value;
101                 }
102             }
103         }
104
105         private EventHandlerWithReturnType<object, PreFocusChangeEventArgs, View> _preFocusChangeEventHandler;
106         [UnmanagedFunctionPointer(CallingConvention.StdCall)]
107         internal delegate IntPtr PreFocusChangeEventCallback(IntPtr current, IntPtr proposed, View.FocusDirection direction);
108         private PreFocusChangeEventCallback _preFocusChangeCallback;
109
110         /// <summary>
111         /// PreFocusChange will be triggered before the focus is going to be changed.<br />
112         /// The FocusManager makes the best guess for which view to focus towards the given direction, but applications might want to change that.<br />
113         /// By connecting with this event, they can check the proposed view to focus and return a different view if they wish.<br />
114         /// This event is only triggered when the navigation key is pressed and KeyboardFocusManager tries to move the focus automatically.<br />
115         /// It won't be emitted for focus movement by calling the SetCurrentFocusView directly.<br />
116         /// </summary>
117         /// <since_tizen> 3 </since_tizen>
118         public event EventHandlerWithReturnType<object, PreFocusChangeEventArgs, View> PreFocusChange
119         {
120             add
121             {
122                 if (_preFocusChangeEventHandler == null)
123                 {
124                     _preFocusChangeCallback = OnPreFocusChange;
125                     PreFocusChangeSignal().Connect(_preFocusChangeCallback);
126                 }
127                 _preFocusChangeEventHandler += value;
128             }
129             remove
130             {
131                 _preFocusChangeEventHandler -= value;
132                 if (_preFocusChangeEventHandler == null && PreFocusChangeSignal().Empty() == false)
133                 {
134                     PreFocusChangeSignal().Disconnect(_preFocusChangeCallback);
135                 }
136             }
137         }
138
139         private IntPtr OnPreFocusChange(IntPtr current, IntPtr proposed, View.FocusDirection direction)
140         {
141             View view = null;
142             PreFocusChangeEventArgs e = new PreFocusChangeEventArgs();
143
144             if (current != global::System.IntPtr.Zero)
145             {
146                 e.CurrentView = Registry.GetManagedBaseHandleFromNativePtr(current) as View;
147             }
148             if (proposed != global::System.IntPtr.Zero)
149             {
150                 e.ProposedView = Registry.GetManagedBaseHandleFromNativePtr(proposed) as View;
151             }
152             e.Direction = direction;
153
154             if (_preFocusChangeEventHandler != null)
155             {
156                 view = _preFocusChangeEventHandler(this, e);
157             }
158
159             if (view)
160             {
161                 return view.GetPtrfromView();
162             }
163             else
164             {
165                 //if (e.ProposedView) return proposed;
166                 //else return current;
167                 return current; //xb.teng
168             }
169         }
170
171         ///<summary>
172         /// Event arguments that passed via the FocusChanged signal.
173         /// </summary>
174         /// <since_tizen> 3 </since_tizen>
175         public class FocusChangedEventArgs : EventArgs
176         {
177             private View _current;
178             private View _next;
179
180             /// <summary>
181             /// The current focus view.
182             /// </summary>
183             /// <since_tizen> 3 </since_tizen>
184             public View CurrentView
185             {
186                 get
187                 {
188                     return _current;
189                 }
190                 set
191                 {
192                     _current = value;
193                 }
194             }
195             /// <summary>
196             /// The next focus view.
197             /// </summary>
198             /// <since_tizen> 3 </since_tizen>
199             public View NextView
200             {
201                 get
202                 {
203                     return _next;
204                 }
205                 set
206                 {
207                     _next = value;
208                 }
209             }
210         }
211
212         private EventHandler<FocusChangedEventArgs> _focusChangedEventHandler;
213         [UnmanagedFunctionPointer(CallingConvention.StdCall)]
214         internal delegate void FocusChangedEventCallback(IntPtr current, IntPtr next);
215         private FocusChangedEventCallback _focusChangedEventCallback;
216
217         /// <summary>
218         /// The FocusGroupChanged will be triggered after the current focused view has been changed.
219         /// </summary>
220         /// <since_tizen> 3 </since_tizen>
221         public event EventHandler<FocusChangedEventArgs> FocusChanged
222         {
223             add
224             {
225                 if (_focusChangedEventCallback == null)
226                 {
227                     _focusChangedEventCallback = OnFocusChanged;
228                     FocusChangedSignal().Connect(_focusChangedEventCallback);
229                 }
230                 _focusChangedEventHandler += value;
231             }
232             remove
233             {
234                 _focusChangedEventHandler -= value;
235
236                 if (_focusChangedEventCallback == null && FocusChangedSignal().Empty() == false)
237                 {
238                     FocusChangedSignal().Disconnect(_focusChangedEventCallback);
239                 }
240             }
241         }
242
243         private void OnFocusChanged(IntPtr current, IntPtr next)
244         {
245             FocusChangedEventArgs e = new FocusChangedEventArgs();
246
247             e.CurrentView = Registry.GetManagedBaseHandleFromNativePtr(current) as View;
248             e.NextView = Registry.GetManagedBaseHandleFromNativePtr(next) as View;
249
250             if (_focusChangedEventHandler != null)
251             {
252                 _focusChangedEventHandler(this, e);
253             }
254         }
255
256         ///<summary>
257         /// Event arguments that passed via the FocusGroupChanged signal.
258         /// </summary>
259         /// <since_tizen> 3 </since_tizen>
260         public class FocusGroupChangedEventArgs : EventArgs
261         {
262             private View _current;
263             private bool _forwardDirection;
264
265             /// <summary>
266             /// The current focus view.
267             /// </summary>
268             /// <since_tizen> 3 </since_tizen>
269             public View CurrentView
270             {
271                 get
272                 {
273                     return _current;
274                 }
275                 set
276                 {
277                     _current = value;
278                 }
279             }
280
281             /// <summary>
282             /// The forward direction.
283             /// </summary>
284             /// <since_tizen> 3 </since_tizen>
285             public bool ForwardDirection
286             {
287                 get
288                 {
289                     return _forwardDirection;
290                 }
291                 set
292                 {
293                     _forwardDirection = value;
294                 }
295             }
296         }
297
298         private EventHandler<FocusGroupChangedEventArgs> _focusGroupChangedEventHandler;
299         [UnmanagedFunctionPointer(CallingConvention.StdCall)]
300         private delegate void FocusGroupChangedEventCallback(IntPtr current, bool forwardDirection);
301         private FocusGroupChangedEventCallback _focusGroupChangedEventCallback;
302
303         /// <summary>
304         /// The FocusGroupChanged will be triggered when the focus group has been changed.<br />
305         /// 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 />
306         /// If not, the application has to set the new focus.<br />
307         /// </summary>
308         /// <since_tizen> 3 </since_tizen>
309         public event EventHandler<FocusGroupChangedEventArgs> FocusGroupChanged
310         {
311             add
312             {
313                 if (_focusGroupChangedEventCallback == null)
314                 {
315                     _focusGroupChangedEventCallback = OnFocusGroupChanged;
316                     FocusGroupChangedSignal().Connect(_focusGroupChangedEventCallback);
317                 }
318                 _focusGroupChangedEventHandler += value;
319             }
320             remove
321             {
322                 _focusGroupChangedEventHandler -= value;
323
324                 if (_focusGroupChangedEventCallback == null && FocusGroupChangedSignal().Empty() == false)
325                 {
326                     FocusGroupChangedSignal().Disconnect(_focusGroupChangedEventCallback);
327                 }
328             }
329         }
330
331         private void OnFocusGroupChanged(IntPtr current, bool forwardDirection)
332         {
333             FocusGroupChangedEventArgs e = new FocusGroupChangedEventArgs();
334
335             e.CurrentView = Registry.GetManagedBaseHandleFromNativePtr(current) as View;
336             e.ForwardDirection = forwardDirection;
337
338             if (_focusGroupChangedEventHandler != null)
339             {
340                 _focusGroupChangedEventHandler(this, e);
341             }
342         }
343
344         ///<summary>
345         /// Event arguments that passed via the FocusedViewEnterKey signal.
346         /// </summary>
347         /// <since_tizen> 3 </since_tizen>
348         public class FocusedViewActivatedEventArgs : EventArgs
349         {
350             private View _view;
351
352             /// <summary>
353             /// View.
354             /// </summary>
355             /// <since_tizen> 3 </since_tizen>
356             public View View
357             {
358                 get
359                 {
360                     return _view;
361                 }
362                 set
363                 {
364                     _view = value;
365                 }
366             }
367         }
368
369         private EventHandler<FocusedViewActivatedEventArgs> _focusedViewEnterKeyEventHandler;
370         [UnmanagedFunctionPointer(CallingConvention.StdCall)]
371         private delegate void FocusedViewEnterKeyEventCallback(IntPtr view);
372         private FocusedViewEnterKeyEventCallback _focusedViewEnterKeyEventCallback;
373
374         /// <summary>
375         /// The FocusedViewActivated will be triggered when the current focused view has the enter key pressed on it.
376         /// </summary>
377         /// <since_tizen> 3 </since_tizen>
378         public event EventHandler<FocusedViewActivatedEventArgs> FocusedViewActivated
379         {
380             add
381             {
382                 if (_focusedViewEnterKeyEventCallback == null)
383                 {
384                     _focusedViewEnterKeyEventCallback = OnFocusedViewEnterKey;
385                     FocusedViewEnterKeySignal().Connect(_focusedViewEnterKeyEventCallback);
386                 }
387                 _focusedViewEnterKeyEventHandler += value;
388             }
389             remove
390             {
391                 _focusedViewEnterKeyEventHandler -= value;
392
393                 if (_focusedViewEnterKeyEventCallback != null && FocusedViewEnterKeySignal().Empty() == false)
394                 {
395                     FocusedViewEnterKeySignal().Disconnect(_focusedViewEnterKeyEventCallback);
396                 }
397             }
398         }
399
400         private void OnFocusedViewEnterKey(IntPtr view)
401         {
402             FocusedViewActivatedEventArgs e = new FocusedViewActivatedEventArgs();
403
404             e.View = Registry.GetManagedBaseHandleFromNativePtr(view) as View;
405
406             if (_focusedViewEnterKeyEventHandler != null)
407             {
408                 _focusedViewEnterKeyEventHandler(this, e);
409             }
410         }
411
412
413         internal FocusManager() : this(NDalicManualPINVOKE.new_FocusManager(), true)
414         {
415             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
416         }
417
418         internal static FocusManager Get()
419         {
420             FocusManager ret = new FocusManager(NDalicManualPINVOKE.FocusManager_Get(), true);
421             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
422             return ret;
423         }
424
425         /// <summary>
426         /// Moves the keyboard focus to the given view.<br />
427         /// Only one view can be focused at the same time.<br />
428         /// The view must be in the stage already and keyboard focusable.<br />
429         /// </summary>
430         /// <param name="view">The view to be focused.</param>
431         /// <returns>Whether the focus is successful or not.</returns>
432         /// <since_tizen> 3 </since_tizen>
433         public bool SetCurrentFocusView(View view)
434         {
435             if (view == null)
436             {
437                 throw new ArgumentNullException("the target view should not be null");
438             }
439
440             bool ret = NDalicManualPINVOKE.FocusManager_SetCurrentFocusActor(swigCPtr, View.getCPtr(view));
441             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
442             return ret;
443         }
444
445         /// <summary>
446         /// Gets the current focused view.
447         /// </summary>
448         /// <returns>A handle to the current focused view or an empty handle if no view is focused.</returns>
449         /// <since_tizen> 3 </since_tizen>
450         public View GetCurrentFocusView()
451         {
452             //to fix memory leak issue, match the handle count with native side.
453             IntPtr cPtr = NDalicManualPINVOKE.FocusManager_GetCurrentFocusActor(swigCPtr);
454             HandleRef CPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr);
455             View ret = Registry.GetManagedBaseHandleFromNativePtr(CPtr.Handle) as View;
456             NDalicPINVOKE.delete_BaseHandle(CPtr);
457             CPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
458
459             return ret;
460         }
461
462         /// <summary>
463         /// Moves the focus to the next focusable view in the focus chain in the given direction (according to the focus traversal order).
464         /// </summary>
465         /// <param name="direction">The direction of the focus movement.</param>
466         /// <returns>True if the movement was successful.</returns>
467         /// <since_tizen> 3 </since_tizen>
468         public bool MoveFocus(View.FocusDirection direction)
469         {
470             bool ret = NDalicManualPINVOKE.FocusManager_MoveFocus(swigCPtr, (int)direction);
471             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
472             return ret;
473         }
474
475         /// <summary>
476         /// Clears the focus from the current focused view if any, so that no view is focused in the focus chain.<br />
477         /// It will emit the FocusChanged event without the current focused view.<br />
478         /// </summary>
479         /// <since_tizen> 3 </since_tizen>
480         public void ClearFocus()
481         {
482             NDalicManualPINVOKE.FocusManager_ClearFocus(swigCPtr);
483             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
484         }
485
486         /// <summary>
487         /// Move the focus to previous focused view.
488         /// </summary>
489         /// <since_tizen> 3 </since_tizen>
490         public void MoveFocusBackward()
491         {
492             NDalicManualPINVOKE.FocusManager_MoveFocusBackward(swigCPtr);
493             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
494         }
495
496         /// <summary>
497         /// Gets or sets the status of whether the focus movement should be looped within the same focus group.<br />
498         /// The focus movement is not looped by default.<br />
499         /// </summary>
500         /// <since_tizen> 3 </since_tizen>
501         public bool FocusGroupLoop
502         {
503             set
504             {
505                 SetFocusGroupLoop(value);
506             }
507             get
508             {
509                 return GetFocusGroupLoop();
510             }
511         }
512
513         internal void SetFocusGroupLoop(bool enabled)
514         {
515             NDalicManualPINVOKE.FocusManager_SetFocusGroupLoop(swigCPtr, enabled);
516             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
517         }
518
519         internal bool GetFocusGroupLoop()
520         {
521             bool ret = NDalicManualPINVOKE.FocusManager_GetFocusGroupLoop(swigCPtr);
522             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
523             return ret;
524         }
525
526         /// <summary>
527         /// 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 />
528         /// Layout controls set themselves as focus groups by default.<br />
529         /// </summary>
530         /// <param name="view">The view to be set as a focus group.</param>
531         /// <param name="isFocusGroup">Whether to set the view as a focus group or not.</param>
532         /// <since_tizen> 3 </since_tizen>
533         public void SetAsFocusGroup(View view, bool isFocusGroup)
534         {
535             NDalicManualPINVOKE.FocusManager_SetAsFocusGroup(swigCPtr, View.getCPtr(view), isFocusGroup);
536             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
537         }
538
539         /// <summary>
540         /// Checks whether the view is set as a focus group or not.
541         /// </summary>
542         /// <param name="view">The view to be checked.</param>
543         /// <returns>Whether the view is set as a focus group.</returns>
544         /// <since_tizen> 3 </since_tizen>
545         public bool IsFocusGroup(View view)
546         {
547             bool ret = NDalicManualPINVOKE.FocusManager_IsFocusGroup(swigCPtr, View.getCPtr(view));
548             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
549             return ret;
550         }
551
552         /// <summary>
553         /// Returns the closest ancestor of the given view that is a focus group.
554         /// </summary>
555         /// <param name="view">The view to be checked for its focus group.</param>
556         /// <returns>The focus group the given view belongs to or an empty handle if the given view.</returns>
557         /// <since_tizen> 3 </since_tizen>
558         public View GetFocusGroup(View view)
559         {
560             //to fix memory leak issue, match the handle count with native side.
561             IntPtr cPtr = NDalicManualPINVOKE.FocusManager_GetFocusGroup(swigCPtr, View.getCPtr(view));
562             HandleRef CPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr);
563             View ret = Registry.GetManagedBaseHandleFromNativePtr(CPtr.Handle) as View;
564             NDalicPINVOKE.delete_BaseHandle(CPtr);
565             CPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
566
567             return ret;
568         }
569
570         /// <summary>
571         /// Gets or sets the focus indicator view.<br />
572         /// This will replace the default focus indicator view in the FocusManager and will be added to the focused view as a highlight.<br />
573         /// </summary>
574         /// <since_tizen> 3 </since_tizen>
575         public View FocusIndicator
576         {
577             set
578             {
579                 SetFocusIndicatorView(value);
580             }
581             get
582             {
583                 return GetFocusIndicatorView();
584             }
585         }
586
587         internal void SetFocusIndicatorView(View indicator)
588         {
589             NDalicManualPINVOKE.FocusManager_SetFocusIndicatorActor(swigCPtr, View.getCPtr(indicator));
590             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
591         }
592
593         internal View GetFocusIndicatorView()
594         {
595             //to fix memory leak issue, match the handle count with native side.
596             IntPtr cPtr = NDalicManualPINVOKE.FocusManager_GetFocusIndicatorActor(swigCPtr);
597             HandleRef CPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr);
598             View ret = Registry.GetManagedBaseHandleFromNativePtr(CPtr.Handle) as View;
599             NDalicPINVOKE.delete_BaseHandle(CPtr);
600             CPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
601
602             return ret;
603         }
604
605         /// <summary>
606         /// Provides the implementation of a custom focus algorithm interface to allow the application to define the focus logic.<br />
607         /// </summary>
608         /// <param name="arg0">The user's implementation of ICustomFocusAlgorithm.</param>
609         /// <since_tizen> 3 </since_tizen>
610         public void SetCustomAlgorithm(ICustomFocusAlgorithm arg0)
611         {
612             _customAlgorithmInterfaceWrapper = new CustomAlgorithmInterfaceWrapper();
613             _customAlgorithmInterfaceWrapper.SetFocusAlgorithm(arg0);
614
615             NDalicPINVOKE.SetCustomAlgorithm(swigCPtr, CustomAlgorithmInterface.getCPtr(_customAlgorithmInterfaceWrapper));
616             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
617         }
618
619         internal PreFocusChangeSignal PreFocusChangeSignal()
620         {
621             PreFocusChangeSignal ret = new PreFocusChangeSignal(NDalicManualPINVOKE.FocusManager_PreFocusChangeSignal(swigCPtr), false);
622             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
623             return ret;
624         }
625
626         internal FocusChangedSignal FocusChangedSignal()
627         {
628             FocusChangedSignal ret = new FocusChangedSignal(NDalicManualPINVOKE.FocusManager_FocusChangedSignal(swigCPtr), false);
629             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
630             return ret;
631         }
632
633         internal FocusGroupChangedSignal FocusGroupChangedSignal()
634         {
635             FocusGroupChangedSignal ret = new FocusGroupChangedSignal(NDalicManualPINVOKE.FocusManager_FocusGroupChangedSignal(swigCPtr), false);
636             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
637             return ret;
638         }
639
640         internal ViewSignal FocusedViewEnterKeySignal()
641         {
642             ViewSignal ret = new ViewSignal(NDalicManualPINVOKE.FocusManager_FocusedActorEnterKeySignal(swigCPtr), false);
643             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
644             return ret;
645         }
646
647         private static readonly FocusManager instance = FocusManager.Get();
648
649         /// <summary>
650         /// Gets the singleton of the FocusManager object.
651         /// </summary>
652         /// <since_tizen> 3 </since_tizen>
653         public static FocusManager Instance
654         {
655             get
656             {
657                 return instance;
658             }
659         }
660
661         /// <summary>
662         /// ICustomFocusAlgorithm is used to provide the custom keyboard focus algorithm for retrieving the next focusable view.<br />
663         /// The application can implement the interface and override the keyboard focus behavior.<br />
664         /// If the focus is changing within a layout container, then the layout container is queried first to provide the next focusable view.<br />
665         /// If this does not provide a valid view, then the Keyboard FocusManager will check focusable properties to determine the next focusable actor.<br />
666         /// If focusable properties are not set, then the keyboard FocusManager calls the GetNextFocusableView() method of this interface.<br />
667         /// </summary>
668         /// <since_tizen> 3 </since_tizen>
669         public interface ICustomFocusAlgorithm
670         {
671             /// <summary>
672             /// Get the next focus actor.
673             /// </summary>
674             /// <param name="current">The current focus view.</param>
675             /// <param name="proposed">The proposed focus view</param>
676             /// <param name="direction">The focus move direction</param>
677             /// <returns>The next focus actor.</returns>
678             /// <since_tizen> 3 </since_tizen>
679             View GetNextFocusableView(View current, View proposed, View.FocusDirection direction);
680         }
681
682         private class CustomAlgorithmInterfaceWrapper : CustomAlgorithmInterface
683         {
684             private FocusManager.ICustomFocusAlgorithm _customFocusAlgorithm;
685
686             public CustomAlgorithmInterfaceWrapper()
687             {
688             }
689
690             public void SetFocusAlgorithm(FocusManager.ICustomFocusAlgorithm customFocusAlgorithm)
691             {
692                 _customFocusAlgorithm = customFocusAlgorithm;
693             }
694
695             public override View GetNextFocusableView(View current, View proposed, View.FocusDirection direction)
696             {
697                 return _customFocusAlgorithm.GetNextFocusableView(current, proposed, direction);
698             }
699         }
700
701
702         /// <summary>
703         /// Please do not use! this will be deprecated
704         /// </summary>
705         /// <since_tizen> 3 </since_tizen>
706         /// Please do not use! this will be deprecated.
707         /// Instead please use FocusedViewActivatedEventArgs.
708         [Obsolete("Please do not use! This will be deprecated! Please use FocusedViewActivatedEventArgs instead! " +
709             "Like: " +
710             "FocusManager.Instance.FocusedViewActivated = OnFocusedViewActivated; " +
711             "private void OnFocusedViewActivated(object source, FocusManager.FocusedViewActivatedEventArgs arg)" +
712             "{...}")]
713         [EditorBrowsable(EditorBrowsableState.Never)]
714         public class FocusedViewEnterKeyEventArgs : EventArgs
715         {
716             private View _view;
717
718             /// <summary>
719             /// View.
720             /// </summary>
721             /// <since_tizen> 3 </since_tizen>
722             public View View
723             {
724                 get
725                 {
726                     return _view;
727                 }
728                 set
729                 {
730                     _view = value;
731                 }
732             }
733         }
734
735         private EventHandler<FocusedViewEnterKeyEventArgs> _focusedViewEnterKeyEventHandler2;
736         [UnmanagedFunctionPointer(CallingConvention.StdCall)]
737         private delegate void FocusedViewEnterKeyEventCallback2(IntPtr view);
738         private FocusedViewEnterKeyEventCallback2 _focusedViewEnterKeyEventCallback2;
739
740         /// <summary>
741         /// [Obsolete("Please do not use! this will be deprecated")]
742         /// </summary>
743         /// <since_tizen> 3 </since_tizen>
744         /// Please do not use! this will be deprecated!
745         /// Instead please use FocusedViewActivated.
746         [Obsolete("Please do not use! This will be deprecated! Please use FocusManager.FocusedViewActivated instead! " +
747             "Like: " +
748             "FocusManager.Instance.FocusedViewActivated = OnFocusedViewActivated; " +
749             "private void OnFocusedViewActivated(object source, FocusManager.FocusedViewActivatedEventArgs args) {...}")]
750         [EditorBrowsable(EditorBrowsableState.Never)]
751         public event EventHandler<FocusedViewEnterKeyEventArgs> FocusedViewEnterKeyPressed
752         {
753             add
754             {
755                 if (_focusedViewEnterKeyEventCallback2 == null)
756                 {
757                     _focusedViewEnterKeyEventCallback2 = OnFocusedViewEnterKey2;
758                     FocusedViewEnterKeySignal().Connect(_focusedViewEnterKeyEventCallback2);
759                 }
760                 _focusedViewEnterKeyEventHandler2 += value;
761             }
762             remove
763             {
764                 _focusedViewEnterKeyEventHandler2 -= value;
765
766                 if (_focusedViewEnterKeyEventCallback2 != null && FocusedViewEnterKeySignal().Empty() == false)
767                 {
768                     FocusedViewEnterKeySignal().Disconnect(_focusedViewEnterKeyEventCallback2);
769                 }
770             }
771         }
772
773         /// <summary>
774         /// Please do not use! this will be deprecated!
775         /// </summary>
776         /// Please do not use! this will be deprecated!
777         /// Instead please use OnFocusedViewEnterKey.
778         [Obsolete("Please do not use! This will be deprecated! Please use FocusManager.OnFocusedViewEnterKey instead!")]
779         [EditorBrowsable(EditorBrowsableState.Never)]
780         private void OnFocusedViewEnterKey2(IntPtr view)
781         {
782             FocusedViewActivatedEventArgs e = new FocusedViewActivatedEventArgs();
783
784             e.View = Registry.GetManagedBaseHandleFromNativePtr(view) as View;
785
786             if (_focusedViewEnterKeyEventHandler != null)
787             {
788                 _focusedViewEnterKeyEventHandler(this, e);
789             }
790         }
791     }
792 }