[NUI] Apply SetFocusFinderRootView() to DialogPage only when DefaultAlgorithm Enabled
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI.Components / Controls / Navigation / Page.cs
1 /*
2  * Copyright(c) 2021 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 using System;
18 using System.ComponentModel;
19 using Tizen.NUI.Binding;
20
21 namespace Tizen.NUI.Components
22 {
23     /// <summary>
24     /// PageAppearingEventArgs is a class to record <see cref="Page.Appearing"/> event arguments which will be sent to user.
25     /// </summary>
26     /// <since_tizen> 9 </since_tizen>
27     public class PageAppearingEventArgs : EventArgs
28     {
29     }
30
31     /// <summary>
32     /// PageDisappearingEventArgs is a class to record <see cref="Page.Disappearing"/> event arguments which will be sent to user.
33     /// </summary>
34     /// <since_tizen> 9 </since_tizen>
35     public class PageDisappearingEventArgs : EventArgs
36     {
37     }
38
39     /// <summary>
40     /// PageAppearedEventArgs is a class to record <see cref="Page.Appeared"/> event arguments which will be sent to user.
41     /// </summary>
42     /// <since_tizen> 9 </since_tizen>
43     public class PageAppearedEventArgs : EventArgs
44     {
45     }
46
47     /// <summary>
48     /// PageDisappearedEventArgs is a class to record <see cref="Page.Disappeared"/> event arguments which will be sent to user.
49     /// </summary>
50     /// <since_tizen> 9 </since_tizen>
51     public class PageDisappearedEventArgs : EventArgs
52     {
53     }
54
55     /// <summary>
56     /// The Page class is a class which is an element of navigation.
57     /// </summary>
58     /// <since_tizen> 9 </since_tizen>
59     public abstract class Page : Control
60     {
61         /// <summary>
62         /// AppearingTransitionProperty
63         /// </summary>
64         [EditorBrowsable(EditorBrowsableState.Never)]
65         public static readonly BindableProperty AppearingTransitionProperty = BindableProperty.Create(nameof(AppearingTransition), typeof(TransitionBase), typeof(Page), null, propertyChanged: (bindable, oldValue, newValue) =>
66         {
67             var instance = (Page)bindable;
68             if (newValue != null)
69             {
70                 instance.InternalAppearingTransition = newValue as TransitionBase;
71             }
72         },
73         defaultValueCreator: (bindable) =>
74         {
75             var instance = (Page)bindable;
76             return instance.InternalAppearingTransition;
77         });
78
79         /// <summary>
80         /// DisappearingTransitionProperty
81         /// </summary>
82         [EditorBrowsable(EditorBrowsableState.Never)]
83         public static readonly BindableProperty DisappearingTransitionProperty = BindableProperty.Create(nameof(DisappearingTransition), typeof(TransitionBase), typeof(Page), null, propertyChanged: (bindable, oldValue, newValue) =>
84         {
85             var instance = (Page)bindable;
86             if (newValue != null)
87             {
88                 instance.InternalDisappearingTransition = newValue as TransitionBase;
89             }
90         },
91         defaultValueCreator: (bindable) =>
92         {
93             var instance = (Page)bindable;
94             return instance.InternalDisappearingTransition;
95         });
96
97         /// <inheritdoc/>
98         [EditorBrowsable(EditorBrowsableState.Never)]
99         protected internal BaseComponents.View LastFocusedView = null;
100
101         private Navigator navigator = null;
102
103         // Default transition is Fade.
104         private TransitionBase appearingTransition = null;
105
106         private TransitionBase disappearingTransition = null;
107
108         /// <summary>
109         /// Creates a new instance of a Page.
110         /// </summary>
111         /// <since_tizen> 9 </since_tizen>
112         public Page() : base()
113         {
114         }
115
116         /// <summary>
117         /// Navigator which has pushed the Page into its stack.
118         /// If this Page has not been pushed into any Navigator, then Navigator is null.
119         /// </summary>
120         /// <since_tizen> 9 </since_tizen>
121         public Navigator Navigator
122         {
123             get
124             {
125                 return navigator;
126             }
127             internal set
128             {
129                 if (navigator == value)
130                 {
131                     return;
132                 }
133
134                 navigator = value;
135             }
136         }
137
138         /// <summary>
139         /// Transition properties for the transition of Views in this page during this page is pushed to Navigator.
140         /// </summary>
141         [EditorBrowsable(EditorBrowsableState.Never)]
142         public TransitionBase AppearingTransition
143         {
144             get
145             {
146                 return GetValue(AppearingTransitionProperty) as TransitionBase;
147             }
148             set
149             {
150                 SetValue(AppearingTransitionProperty, value);
151                 NotifyPropertyChanged();
152             }
153         }
154         private TransitionBase InternalAppearingTransition
155         {
156             set
157             {
158                 appearingTransition = value;
159             }
160             get
161             {
162                 return appearingTransition;
163             }
164         }
165
166         /// <summary>
167         /// Transition properties for the transition of Views in this page during this page is popped from Navigator.
168         /// </summary>
169         [EditorBrowsable(EditorBrowsableState.Never)]
170         public TransitionBase DisappearingTransition
171         {
172             get
173             {
174                 return GetValue(DisappearingTransitionProperty) as TransitionBase;
175             }
176             set
177             {
178                 SetValue(DisappearingTransitionProperty, value);
179                 NotifyPropertyChanged();
180             }
181         }
182         private TransitionBase InternalDisappearingTransition
183         {
184             set
185             {
186                 disappearingTransition = value;
187             }
188             get
189             {
190                 return disappearingTransition;
191             }
192         }
193
194         /// <summary>
195         /// Appearing event is invoked right before the page appears.
196         /// </summary>
197         /// <since_tizen> 9 </since_tizen>
198         public event EventHandler<PageAppearingEventArgs> Appearing;
199
200         /// <summary>
201         /// Disappearing event is invoked right before the page disappears.
202         /// </summary>
203         /// <since_tizen> 9 </since_tizen>
204         public event EventHandler<PageDisappearingEventArgs> Disappearing;
205
206         /// <summary>
207         /// Appeared event is invoked right after the page appears.
208         /// </summary>
209         /// <since_tizen> 9 </since_tizen>
210         public event EventHandler<PageAppearedEventArgs> Appeared;
211
212         /// <summary>
213         /// Disappeared event is invoked right after the page disappears.
214         /// </summary>
215         /// <since_tizen> 9 </since_tizen>
216         public event EventHandler<PageDisappearedEventArgs> Disappeared;
217
218         internal void InvokeAppearing()
219         {
220             Appearing?.Invoke(this, new PageAppearingEventArgs());
221         }
222
223         internal void InvokeDisappearing()
224         {
225             Disappearing?.Invoke(this, new PageDisappearingEventArgs());
226         }
227
228         internal void InvokeAppeared()
229         {
230             Appeared?.Invoke(this, new PageAppearedEventArgs());
231         }
232
233         internal void InvokeDisappeared()
234         {
235             Disappeared?.Invoke(this, new PageDisappearedEventArgs());
236         }
237
238         /// <summary>
239         /// works only when DefaultAlgorithm is enabled.
240         /// to save the currently focused View when disappeared.
241         /// </summary>
242         [EditorBrowsable(EditorBrowsableState.Never)]
243         protected internal virtual void SaveKeyFocus()
244         {
245             if (FocusManager.Instance.IsDefaultAlgorithmEnabled())
246             {
247                 if (this is DialogPage)
248                 {
249                     FocusManager.Instance.ResetFocusFinderRootView();
250                 }
251
252                 var currentFocusedView = FocusManager.Instance.GetCurrentFocusView();
253                 if (currentFocusedView)
254                 {
255                     var findChild = FindDescendantByID(currentFocusedView.ID);
256                     if (findChild)
257                     {
258                         LastFocusedView = findChild;
259                         return;
260                     }
261                 }
262                 LastFocusedView = null;
263             }
264         }
265
266         /// <summary>
267         /// works only when DefaultAlgorithm is enabled.
268         /// to set key focused View when showing.
269         /// </summary>
270         [EditorBrowsable(EditorBrowsableState.Never)]
271         protected internal virtual void RestoreKeyFocus()
272         {
273             if (FocusManager.Instance.IsDefaultAlgorithmEnabled())
274             {
275                 if (LastFocusedView)
276                 {
277                     FocusManager.Instance.SetCurrentFocusView(LastFocusedView);
278                 }
279                 else
280                 {
281                     var temp = new Tizen.NUI.BaseComponents.View()
282                     {
283                         Size = new Size(0.1f, 0.1f, 0.0f),
284                         Position = new Position(0, 0, 0),
285                         Focusable = true,
286                     };
287                     this.Add(temp);
288                     temp.LowerToBottom();
289                     FocusManager.Instance.SetCurrentFocusView(temp);
290                     var focused = FocusManager.Instance.GetNearestFocusableActor(this, temp, Tizen.NUI.BaseComponents.View.FocusDirection.Down);
291                     if (focused)
292                     {
293                         FocusManager.Instance.SetCurrentFocusView(focused);
294                     }
295                     else
296                     {
297                         FocusManager.Instance.ClearFocus();
298                     }
299                     temp.Unparent();
300                     temp.Dispose();
301                 }
302
303                 if (this is DialogPage)
304                 {
305                     FocusManager.Instance.SetFocusFinderRootView(this);
306                 }
307             }
308
309         }
310
311     }
312 }