nui 0.2.28 release
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / public / FocusManager.cs
1 // Copyright (c) 2017 Samsung Electronics Co., Ltd.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 //
16 // This File has been auto-generated by SWIG and then modified using DALi Ruby Scripts
17 // Some have been manually changed
18
19
20 namespace Tizen.NUI
21 {
22
23     using System;
24     using System.Runtime.InteropServices;
25     using Tizen.NUI.BaseComponents;
26
27     /// <summary>
28     /// Provides the functionality of handling keyboard navigation and maintaining the two dimensional keyboard focus chain.<br>
29     /// It provides functionality of setting the focus and moving the focus in four directions(i.e.Left, Right, Up and Down).<br>
30     /// It also draws a highlight for the focused View and sends a event when the focus is changed.<br>
31     /// </summary>
32     public class FocusManager : BaseHandle
33     {
34         private global::System.Runtime.InteropServices.HandleRef swigCPtr;
35         private CustomAlgorithmInterfaceWrapper _customAlgorithmInterfaceWrapper;
36
37         internal FocusManager(global::System.IntPtr cPtr, bool cMemoryOwn) : base(NDalicManualPINVOKE.FocusManager_SWIGUpcast(cPtr), cMemoryOwn)
38         {
39             swigCPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr);
40         }
41
42         internal static global::System.Runtime.InteropServices.HandleRef getCPtr(FocusManager obj)
43         {
44             return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr;
45         }
46
47         /// <summary>
48         /// To make FocusManager instance be disposed.
49         /// </summary>
50         public override void Dispose()
51         {
52             if (!Window.IsInstalled())
53             {
54                 DisposeQueue.Instance.Add(this);
55                 return;
56             }
57
58             lock (this)
59             {
60                 if (swigCPtr.Handle != global::System.IntPtr.Zero)
61                 {
62                     if (swigCMemOwn)
63                     {
64                         swigCMemOwn = false;
65                         NDalicManualPINVOKE.delete_FocusManager(swigCPtr);
66                     }
67                     swigCPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
68                 }
69                 global::System.GC.SuppressFinalize(this);
70                 base.Dispose();
71             }
72         }
73
74
75         ///<summary>
76         ///Event arguments that passed via PreFocusChange signal
77         /// </summary>
78         public class PreFocusChangeEventArgs : EventArgs
79         {
80             private View _current;
81             private View _proposed;
82             private View.FocusDirection _direction;
83
84             public View CurrentView
85             {
86                 get
87                 {
88                     return _current;
89                 }
90                 set
91                 {
92                     _current = value;
93                 }
94             }
95
96             public View ProposedView
97             {
98                 get
99                 {
100                     return _proposed;
101                 }
102                 set
103                 {
104                     _proposed = value;
105                 }
106             }
107
108             public View.FocusDirection Direction
109             {
110                 get
111                 {
112                     return _direction;
113                 }
114                 set
115                 {
116                     _direction = value;
117                 }
118             }
119         }
120
121         private EventHandlerWithReturnType<object, PreFocusChangeEventArgs, View> _preFocusChangeEventHandler;
122         [UnmanagedFunctionPointer(CallingConvention.StdCall)]
123         internal delegate IntPtr PreFocusChangeEventCallback(IntPtr current, IntPtr proposed, View.FocusDirection direction);
124         private PreFocusChangeEventCallback _preFocusChangeCallback;
125
126         /// <summary>
127         /// PreFocusChange will be triggered before the focus is going to be changed.<br>
128         /// FocusManager makes the best guess for which view to focus towards the given direction, but applications might want to change that.<br>
129         /// By connecting with this event, they can check the proposed view to focus and return a different view if they wish.<br>
130         /// This event is only triggered when the navigation key is pressed and KeyboardFocusManager tries to move the focus automatically.<br>
131         /// It won't be emitted for focus movement by calling SetCurrentFocusView directly.<br>
132         /// </summary>
133         public event EventHandlerWithReturnType<object, PreFocusChangeEventArgs, View> PreFocusChange
134         {
135             add
136             {
137                 if (_preFocusChangeEventHandler == null)
138                 {
139 #if DEBUG_ON
140                     Tizen.Log.Debug("NUI", "con1) PreFocusChangeSignal().Empty = " + PreFocusChangeSignal().Empty());
141                     Tizen.Log.Debug("NUI", "con2) PreFocusChangeSignal().GetConnectionCount = " + PreFocusChangeSignal().GetConnectionCount());
142 #endif
143                     _preFocusChangeCallback = OnPreFocusChange;
144                     PreFocusChangeSignal().Connect(_preFocusChangeCallback);
145 #if DEBUG_ON
146                     Tizen.Log.Debug("NUI", "con3) PreFocusChangeSignal().Empty = " + PreFocusChangeSignal().Empty());
147                     Tizen.Log.Debug("NUI", "con4) PreFocusChangeSignal().GetConnectionCount = " + PreFocusChangeSignal().GetConnectionCount());
148 #endif
149                 }
150                 _preFocusChangeEventHandler += value;
151             }
152             remove
153             {
154                 _preFocusChangeEventHandler -= value;
155                 if (_preFocusChangeEventHandler == null && PreFocusChangeSignal().Empty() == false)
156                 {
157 #if DEBUG_ON
158                     Tizen.Log.Debug("NUI", "discon1) PreFocusChangeSignal().Empty = " + PreFocusChangeSignal().Empty());
159                     Tizen.Log.Debug("NUI", "discon2) PreFocusChangeSignal().GetConnectionCount = " + PreFocusChangeSignal().GetConnectionCount());
160 #endif
161                     PreFocusChangeSignal().Disconnect(_preFocusChangeCallback);
162 #if DEBUG_ON
163                     Tizen.Log.Debug("NUI", "discon3) PreFocusChangeSignal().Empty = " + PreFocusChangeSignal().Empty());
164                     Tizen.Log.Debug("NUI", "discon4) PreFocusChangeSignal().GetConnectionCount = " + PreFocusChangeSignal().GetConnectionCount());
165 #endif
166                 }
167             }
168         }
169
170         private IntPtr OnPreFocusChange(IntPtr current, IntPtr proposed, View.FocusDirection direction)
171         {
172             View view = null;
173             PreFocusChangeEventArgs e = new PreFocusChangeEventArgs();
174
175             if (current != global::System.IntPtr.Zero)
176             {
177                 e.CurrentView = View.GetViewFromPtr(current);
178             }
179             if (proposed != global::System.IntPtr.Zero)
180             {
181                 e.ProposedView = View.GetViewFromPtr(proposed);
182             }
183             e.Direction = direction;
184
185             if (_preFocusChangeEventHandler != null)
186             {
187                 view = _preFocusChangeEventHandler(this, e);
188             }
189
190             if (view)
191             {
192                 return view.GetPtrfromView();
193             }
194             else
195             {
196                 //if (e.ProposedView) return proposed;
197                 //else return current;
198                 return current; //xb.teng
199             }
200         }
201
202         ///<summary>
203         ///Event arguments that passed via FocusChanged signal.
204         /// </summary>
205         public class FocusChangedEventArgs : EventArgs
206         {
207             private View _current;
208             private View _next;
209
210             public View CurrentView
211             {
212                 get
213                 {
214                     return _current;
215                 }
216                 set
217                 {
218                     _current = value;
219                 }
220             }
221
222             public View NextView
223             {
224                 get
225                 {
226                     return _next;
227                 }
228                 set
229                 {
230                     _next = value;
231                 }
232             }
233         }
234
235         private EventHandler<FocusChangedEventArgs> _focusChangedEventHandler;
236         [UnmanagedFunctionPointer(CallingConvention.StdCall)]
237         internal delegate void FocusChangedEventCallback(IntPtr current, IntPtr next);
238         private FocusChangedEventCallback _focusChangedEventCallback;
239
240         /// <summary>
241         /// FocusGroupChanged will be triggered after the current focused view has been changed.
242         /// </summary>
243         public event EventHandler<FocusChangedEventArgs> FocusChanged
244         {
245             add
246             {
247                 if (_focusChangedEventCallback == null)
248                 {
249                     _focusChangedEventCallback = OnFocusChanged;
250                     FocusChangedSignal().Connect(_focusChangedEventCallback);
251                 }
252                 _focusChangedEventHandler += value;
253             }
254             remove
255             {
256                 _focusChangedEventHandler -= value;
257
258                 if (_focusChangedEventCallback == null && FocusChangedSignal().Empty() == false)
259                 {
260                     FocusChangedSignal().Disconnect(_focusChangedEventCallback);
261                 }
262             }
263         }
264
265         private void OnFocusChanged(IntPtr current, IntPtr next)
266         {
267             FocusChangedEventArgs e = new FocusChangedEventArgs();
268
269             e.CurrentView = View.GetViewFromPtr(current);
270             e.NextView = View.GetViewFromPtr(next);
271
272             if (_focusChangedEventHandler != null)
273             {
274                 _focusChangedEventHandler(this, e);
275             }
276         }
277
278         ///<summary>
279         ///Event arguments that passed via FocusGroupChanged signal.
280         /// </summary>
281         public class FocusGroupChangedEventArgs : EventArgs
282         {
283             private View _current;
284             private bool _forwardDirection;
285
286             public View CurrentView
287             {
288                 get
289                 {
290                     return _current;
291                 }
292                 set
293                 {
294                     _current = value;
295                 }
296             }
297
298             public bool ForwardDirection
299             {
300                 get
301                 {
302                     return _forwardDirection;
303                 }
304                 set
305                 {
306                     _forwardDirection = value;
307                 }
308             }
309         }
310
311         private EventHandler<FocusGroupChangedEventArgs> _focusGroupChangedEventHandler;
312         [UnmanagedFunctionPointer(CallingConvention.StdCall)]
313         private delegate void FocusGroupChangedEventCallback(IntPtr current, bool forwardDirection);
314         private FocusGroupChangedEventCallback _focusGroupChangedEventCallback;
315
316         /// <summary>
317         /// FocusGroupChanged will be triggered when the focus group has been changed.<br>
318         /// If the current focus group has a parent layout control, FocusManager will make the best guess for the next focus group to move the focus to in the given direction (forward or backward).<br>
319         /// If not, the application has to set the new focus.<br>
320         /// </summary>
321         public event EventHandler<FocusGroupChangedEventArgs> FocusGroupChanged
322         {
323             add
324             {
325                 if (_focusGroupChangedEventCallback == null)
326                 {
327                     _focusGroupChangedEventCallback = OnFocusGroupChanged;
328                     FocusGroupChangedSignal().Connect(_focusGroupChangedEventCallback);
329                 }
330                 _focusGroupChangedEventHandler += value;
331             }
332             remove
333             {
334                 _focusGroupChangedEventHandler -= value;
335
336                 if (_focusGroupChangedEventCallback == null && FocusGroupChangedSignal().Empty() == false)
337                 {
338                     FocusGroupChangedSignal().Disconnect(_focusGroupChangedEventCallback);
339                 }
340             }
341         }
342
343         private void OnFocusGroupChanged(IntPtr current, bool forwardDirection)
344         {
345             FocusGroupChangedEventArgs e = new FocusGroupChangedEventArgs();
346
347             e.CurrentView = View.GetViewFromPtr(current);
348             e.ForwardDirection = forwardDirection;
349
350             if (_focusGroupChangedEventHandler != null)
351             {
352                 _focusGroupChangedEventHandler(this, e);
353             }
354         }
355
356         ///<summary>
357         ///Event arguments that passed via FocusedViewEnterKey signal
358         /// </summary>
359         public class FocusedViewEnterKeyEventArgs : EventArgs
360         {
361             private View _view;
362
363             public View View
364             {
365                 get
366                 {
367                     return _view;
368                 }
369                 set
370                 {
371                     _view = value;
372                 }
373             }
374         }
375
376         private EventHandler<FocusedViewEnterKeyEventArgs> _focusedViewEnterKeyEventHandler;
377         [UnmanagedFunctionPointer(CallingConvention.StdCall)]
378         private delegate void FocusedViewEnterKeyEventCallback(IntPtr view);
379         private FocusedViewEnterKeyEventCallback _focusedViewEnterKeyEventCallback;
380
381         /// <summary>
382         /// FocusedViewEnterKeyPressed will be triggered when the current focused view has the enter key pressed on it.
383         /// </summary>
384         public event EventHandler<FocusedViewEnterKeyEventArgs> FocusedViewEnterKeyPressed
385         {
386             add
387             {
388                 if (_focusedViewEnterKeyEventCallback == null)
389                 {
390                     _focusedViewEnterKeyEventCallback = OnFocusedViewEnterKey;
391                     FocusedViewEnterKeySignal().Connect(_focusedViewEnterKeyEventCallback);
392                 }
393                 _focusedViewEnterKeyEventHandler += value;
394             }
395             remove
396             {
397                 _focusedViewEnterKeyEventHandler -= value;
398
399                 if (_focusedViewEnterKeyEventCallback == null && FocusedViewEnterKeySignal().Empty() == false)
400                 {
401                     FocusedViewEnterKeySignal().Disconnect(_focusedViewEnterKeyEventCallback);
402                 }
403             }
404         }
405
406         private void OnFocusedViewEnterKey(IntPtr view)
407         {
408             FocusedViewEnterKeyEventArgs e = new FocusedViewEnterKeyEventArgs();
409
410             e.View = View.GetViewFromPtr(view);
411
412             if (_focusedViewEnterKeyEventHandler != null)
413             {
414                 _focusedViewEnterKeyEventHandler(this, e);
415             }
416         }
417
418
419         internal FocusManager() : this(NDalicManualPINVOKE.new_FocusManager(), true)
420         {
421             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
422         }
423
424         internal static FocusManager Get()
425         {
426             FocusManager ret = new FocusManager(NDalicManualPINVOKE.FocusManager_Get(), true);
427             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
428             return ret;
429         }
430
431         /// <summary>
432         /// Moves the keyboard focus to the given View.<br>
433         /// Only one View can be focused at the same time.<br>
434         /// The View must be in the stage already and keyboard focusable.<br>
435         /// </summary>
436         /// <param name="view">The View to be focused</param>
437         /// <returns>Whether the focus is successful or not</returns>
438         public bool SetCurrentFocusView(View view)
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         public View GetCurrentFocusView()
450         {
451             View ret = new View(NDalicManualPINVOKE.FocusManager_GetCurrentFocusActor(swigCPtr), true);
452             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
453             if (ret.HasBody() == false)
454             {
455                 return null;
456             }
457             return ret;
458         }
459
460         /// <summary>
461         /// Moves the focus to the next focusable View in the focus chain in the given direction(according to the focus traversal order).
462         /// </summary>
463         /// <param name="direction">The direction of focus movement</param>
464         /// <returns>true if the movement was successful</returns>
465         public bool MoveFocus(View.FocusDirection direction)
466         {
467             bool ret = NDalicManualPINVOKE.FocusManager_MoveFocus(swigCPtr, (int)direction);
468             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
469             return ret;
470         }
471
472         /// <summary>
473         /// Clears the focus from the current focused view if any, so that no view is focused in the focus chain.<br>
474         /// It will emit FocusChanged event without current focused View.<br>
475         /// </summary>
476         public void ClearFocus()
477         {
478             NDalicManualPINVOKE.FocusManager_ClearFocus(swigCPtr);
479             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
480         }
481
482         /// <summary>
483         /// Sets/Gets the status of whether the focus movement should be looped within the same focus group.<br>
484         /// The focus movement is not looped by default.<br>
485         /// </summary>
486         public bool FocusGroupLoop
487         {
488             set
489             {
490                 SetFocusGroupLoop(value);
491             }
492             get
493             {
494                 return GetFocusGroupLoop();
495             }
496         }
497
498         internal void SetFocusGroupLoop(bool enabled)
499         {
500             NDalicManualPINVOKE.FocusManager_SetFocusGroupLoop(swigCPtr, enabled);
501             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
502         }
503
504         internal bool GetFocusGroupLoop()
505         {
506             bool ret = NDalicManualPINVOKE.FocusManager_GetFocusGroupLoop(swigCPtr);
507             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
508             return ret;
509         }
510
511         /// <summary>
512         /// Sets whether an View is a focus group that can limit the scope of focus movement to its child views in the focus chain.<br>
513         /// Layout controls set themselves as focus groups by default.<br>
514         /// </summary>
515         /// <param name="view">The View to be set as a focus group</param>
516         /// <param name="isFocusGroup">Whether to set the View as a focus group or not</param>
517         public void SetAsFocusGroup(View view, bool isFocusGroup)
518         {
519             NDalicManualPINVOKE.FocusManager_SetAsFocusGroup(swigCPtr, View.getCPtr(view), isFocusGroup);
520             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
521         }
522
523         /// <summary>
524         /// Checks whether the view is set as a focus group or not.
525         /// </summary>
526         /// <param name="view">The View to be checked</param>
527         /// <returns>Whether the View is set as a focus group</returns>
528         public bool IsFocusGroup(View view)
529         {
530             bool ret = NDalicManualPINVOKE.FocusManager_IsFocusGroup(swigCPtr, View.getCPtr(view));
531             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
532             return ret;
533         }
534
535         /// <summary>
536         /// Returns the closest ancestor of the given view that is a focus group.
537         /// </summary>
538         /// <param name="view">The View to be checked for its focus group</param>
539         /// <returns>The focus group the given view belongs to or an empty handle if the given view</returns>
540         public View GetFocusGroup(View view)
541         {
542             View ret = new View(NDalicManualPINVOKE.FocusManager_GetFocusGroup(swigCPtr, View.getCPtr(view)), true);
543             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
544             if (ret.HasBody() == false)
545             {
546                 return null;
547             }
548             return ret;
549         }
550
551         /// <summary>
552         /// Sets/Gets the focus indicator View.<br>
553         /// This will replace the default focus indicator view in FocusManager and will be added to the focused view as a highlight.<br>
554         /// </summary>
555         public View FocusIndicator
556         {
557             set
558             {
559                 SetFocusIndicatorView(value);
560             }
561             get
562             {
563                 return GetFocusIndicatorView();
564             }
565         }
566
567         internal void SetFocusIndicatorView(View indicator)
568         {
569             NDalicManualPINVOKE.FocusManager_SetFocusIndicatorActor(swigCPtr, View.getCPtr(indicator));
570             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
571         }
572
573         internal View GetFocusIndicatorView()
574         {
575             View ret = new View(NDalicManualPINVOKE.FocusManager_GetFocusIndicatorActor(swigCPtr), true);
576             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
577             if (ret.HasBody() == false)
578             { 
579                 return null;
580             }
581             return ret;
582         }
583
584         /// <summary>
585         /// Provide the implementation of custom Focus algorithm interface to allow the app define the focus logic.<br>
586         /// </summary>
587         /// <param name="arg0">The user's implementation of ICustomFocusAlgorithm</param>
588         public void SetCustomAlgorithm(ICustomFocusAlgorithm arg0)
589         {
590             _customAlgorithmInterfaceWrapper = new CustomAlgorithmInterfaceWrapper();
591             _customAlgorithmInterfaceWrapper.SetFocusAlgorithm(arg0);
592
593             NDalicPINVOKE.SetCustomAlgorithm(swigCPtr, CustomAlgorithmInterface.getCPtr(_customAlgorithmInterfaceWrapper));
594             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
595         }
596
597         internal PreFocusChangeSignal PreFocusChangeSignal()
598         {
599             PreFocusChangeSignal ret = new PreFocusChangeSignal(NDalicManualPINVOKE.FocusManager_PreFocusChangeSignal(swigCPtr), false);
600             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
601             return ret;
602         }
603
604         internal FocusChangedSignal FocusChangedSignal()
605         {
606             FocusChangedSignal ret = new FocusChangedSignal(NDalicManualPINVOKE.FocusManager_FocusChangedSignal(swigCPtr), false);
607             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
608             return ret;
609         }
610
611         internal FocusGroupChangedSignal FocusGroupChangedSignal()
612         {
613             FocusGroupChangedSignal ret = new FocusGroupChangedSignal(NDalicManualPINVOKE.FocusManager_FocusGroupChangedSignal(swigCPtr), false);
614             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
615             return ret;
616         }
617
618         internal ViewSignal FocusedViewEnterKeySignal()
619         {
620             ViewSignal ret = new ViewSignal(NDalicManualPINVOKE.FocusManager_FocusedActorEnterKeySignal(swigCPtr), false);
621             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
622             return ret;
623         }
624
625         private static readonly FocusManager instance = FocusManager.Get();
626
627         /// <summary>
628         /// Gets the singleton of FocusManager object.
629         /// </summary>
630         public static FocusManager Instance
631         {
632             get
633             {
634                 return instance;
635             }
636         }
637
638         /// <summary>
639         /// ICustomFocusAlgorithm is used to provide custom keyboard focus algorithm for retrieving the next focusable view.<br>
640         /// The application can implement the interface and override the keyboard focus behaviour.<br>
641         /// If focus is changing within a layout container, then the layout container is queried first to provide the next focusable view.<br>
642         /// If this does not provide a valid view, then the Keyboard FocusManager will check focusable properties to determine next focusable actor.<br>
643         /// If focusable properties are not set, then the Keyboard FocusManager calls the GetNextFocusableView() method of this interface.<br>
644         /// </summary>
645         public interface ICustomFocusAlgorithm
646         {
647             View GetNextFocusableView(View current, View proposed, View.FocusDirection direction);
648         }
649
650         private class CustomAlgorithmInterfaceWrapper : CustomAlgorithmInterface
651         {
652             private FocusManager.ICustomFocusAlgorithm _customFocusAlgorithm;
653
654             public CustomAlgorithmInterfaceWrapper()
655             {
656             }
657
658             public void SetFocusAlgorithm(FocusManager.ICustomFocusAlgorithm customFocusAlgorithm)
659             {
660                 _customFocusAlgorithm = customFocusAlgorithm;
661             }
662
663             public override View GetNextFocusableView(View current, View proposed, View.FocusDirection direction)
664             {
665                 View currentView = View.DownCast<View>(current);
666                 View proposedView = View.DownCast<View>(proposed);
667                 return _customFocusAlgorithm.GetNextFocusableView(currentView, proposedView, direction);
668             }
669         }
670     }
671 }