[NUI] Add EnableBackNavigation to Page
[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         /// <summary>
98         /// EnableBackNavigationProperty
99         /// </summary>
100         [EditorBrowsable(EditorBrowsableState.Never)]
101         public static readonly BindableProperty EnableBackNavigationProperty = BindableProperty.Create(nameof(EnableBackNavigation), typeof(bool), typeof(Page), default(bool), propertyChanged: (bindable, oldValue, newValue) =>
102         {
103             var instance = (Page)bindable;
104             if (newValue != null)
105             {
106                 instance.InternalEnableBackNavigation = (bool)newValue;
107             }
108         },
109         defaultValueCreator: (bindable) =>
110         {
111             var instance = (Page)bindable;
112             return instance.InternalEnableBackNavigation;
113         });
114
115         /// <inheritdoc/>
116         [EditorBrowsable(EditorBrowsableState.Never)]
117         protected internal BaseComponents.View LastFocusedView = null;
118
119         private Navigator navigator = null;
120
121         // Default transition is Fade.
122         private TransitionBase appearingTransition = null;
123
124         private TransitionBase disappearingTransition = null;
125
126         private bool enableBackNavigation = true;
127
128         /// <summary>
129         /// Creates a new instance of a Page.
130         /// </summary>
131         /// <since_tizen> 9 </since_tizen>
132         public Page() : base()
133         {
134         }
135
136         /// <summary>
137         /// Creates a new instance of a Page with style.
138         /// </summary>
139         /// <param name="style">A style applied to the newly created Page.</param>
140         [EditorBrowsable(EditorBrowsableState.Never)]
141         public Page(ControlStyle style) : base(style)
142         {
143         }
144
145         /// <summary>
146         /// Navigator which has pushed the Page into its stack.
147         /// If this Page has not been pushed into any Navigator, then Navigator is null.
148         /// </summary>
149         /// <since_tizen> 9 </since_tizen>
150         public Navigator Navigator
151         {
152             get
153             {
154                 return navigator;
155             }
156             internal set
157             {
158                 if (navigator == value)
159                 {
160                     return;
161                 }
162
163                 navigator = value;
164             }
165         }
166
167         /// <summary>
168         /// Transition properties for the transition of Views in this page during this page is pushed to Navigator.
169         /// </summary>
170         [EditorBrowsable(EditorBrowsableState.Never)]
171         public TransitionBase AppearingTransition
172         {
173             get
174             {
175                 return GetValue(AppearingTransitionProperty) as TransitionBase;
176             }
177             set
178             {
179                 SetValue(AppearingTransitionProperty, value);
180                 NotifyPropertyChanged();
181             }
182         }
183         private TransitionBase InternalAppearingTransition
184         {
185             set
186             {
187                 appearingTransition = value;
188             }
189             get
190             {
191                 return appearingTransition;
192             }
193         }
194
195         /// <summary>
196         /// Transition properties for the transition of Views in this page during this page is popped from Navigator.
197         /// </summary>
198         [EditorBrowsable(EditorBrowsableState.Never)]
199         public TransitionBase DisappearingTransition
200         {
201             get
202             {
203                 return GetValue(DisappearingTransitionProperty) as TransitionBase;
204             }
205             set
206             {
207                 SetValue(DisappearingTransitionProperty, value);
208                 NotifyPropertyChanged();
209             }
210         }
211         private TransitionBase InternalDisappearingTransition
212         {
213             set
214             {
215                 disappearingTransition = value;
216             }
217             get
218             {
219                 return disappearingTransition;
220             }
221         }
222
223         /// <summary>
224         /// Appearing event is invoked right before the page appears.
225         /// </summary>
226         /// <since_tizen> 9 </since_tizen>
227         public event EventHandler<PageAppearingEventArgs> Appearing;
228
229         /// <summary>
230         /// Disappearing event is invoked right before the page disappears.
231         /// </summary>
232         /// <since_tizen> 9 </since_tizen>
233         public event EventHandler<PageDisappearingEventArgs> Disappearing;
234
235         /// <summary>
236         /// Appeared event is invoked right after the page appears.
237         /// </summary>
238         /// <since_tizen> 9 </since_tizen>
239         public event EventHandler<PageAppearedEventArgs> Appeared;
240
241         /// <summary>
242         /// Disappeared event is invoked right after the page disappears.
243         /// </summary>
244         /// <since_tizen> 9 </since_tizen>
245         public event EventHandler<PageDisappearedEventArgs> Disappeared;
246
247         /// <summary>
248         /// Gets or sets if this page is popped when back button or back key is pressed and released.
249         /// </summary>
250         [EditorBrowsable(EditorBrowsableState.Never)]
251         public bool EnableBackNavigation
252         {
253             get
254             {
255                 return (bool)GetValue(EnableBackNavigationProperty);
256             }
257             set
258             {
259                 SetValue(EnableBackNavigationProperty, value);
260                 NotifyPropertyChanged();
261             }
262         }
263
264         private bool InternalEnableBackNavigation
265         {
266             set
267             {
268                 enableBackNavigation = value;
269             }
270             get
271             {
272                 return enableBackNavigation;
273             }
274         }
275
276         internal void InvokeAppearing()
277         {
278             Appearing?.Invoke(this, new PageAppearingEventArgs());
279         }
280
281         internal void InvokeDisappearing()
282         {
283             Disappearing?.Invoke(this, new PageDisappearingEventArgs());
284         }
285
286         internal void InvokeAppeared()
287         {
288             Appeared?.Invoke(this, new PageAppearedEventArgs());
289         }
290
291         internal void InvokeDisappeared()
292         {
293             Disappeared?.Invoke(this, new PageDisappearedEventArgs());
294         }
295
296         /// <summary>
297         /// works only when DefaultAlgorithm is enabled.
298         /// to save the currently focused View when disappeared.
299         /// </summary>
300         [EditorBrowsable(EditorBrowsableState.Never)]
301         protected internal virtual void SaveKeyFocus()
302         {
303             if (FocusManager.Instance.IsDefaultAlgorithmEnabled())
304             {
305                 if (this is DialogPage)
306                 {
307                     FocusManager.Instance.ResetFocusFinderRootView();
308                 }
309
310                 var currentFocusedView = FocusManager.Instance.GetCurrentFocusView();
311                 if (currentFocusedView)
312                 {
313                     var findChild = FindDescendantByID(currentFocusedView.ID);
314                     if (findChild)
315                     {
316                         LastFocusedView = findChild;
317                         return;
318                     }
319                 }
320                 LastFocusedView = null;
321             }
322         }
323
324         /// <summary>
325         /// works only when DefaultAlgorithm is enabled.
326         /// to set key focused View when showing.
327         /// </summary>
328         [EditorBrowsable(EditorBrowsableState.Never)]
329         protected internal virtual void RestoreKeyFocus()
330         {
331             if (FocusManager.Instance.IsDefaultAlgorithmEnabled())
332             {
333                 if (LastFocusedView)
334                 {
335                     FocusManager.Instance.SetCurrentFocusView(LastFocusedView);
336                 }
337                 else
338                 {
339                     var temp = new Tizen.NUI.BaseComponents.View()
340                     {
341                         Size = new Size(0.1f, 0.1f, 0.0f),
342                         Position = new Position(0, 0, 0),
343                         Focusable = true,
344                     };
345                     this.Add(temp);
346                     temp.LowerToBottom();
347                     FocusManager.Instance.SetCurrentFocusView(temp);
348                     var focused = FocusManager.Instance.GetNearestFocusableActor(this, temp, Tizen.NUI.BaseComponents.View.FocusDirection.Down);
349                     if (focused)
350                     {
351                         FocusManager.Instance.SetCurrentFocusView(focused);
352                     }
353                     else
354                     {
355                         FocusManager.Instance.ClearFocus();
356                     }
357                     temp.Unparent();
358                     temp.Dispose();
359                 }
360
361                 if (this is DialogPage)
362                 {
363                     FocusManager.Instance.SetFocusFinderRootView(this);
364                 }
365             }
366         }
367
368     }
369 }