2 * Copyright(c) 2020 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.Collections.Generic;
20 using System.ComponentModel;
21 using System.Threading.Tasks;
22 using Tizen.NUI.BaseComponents;
23 using Tizen.NUI.Binding;
25 namespace Tizen.NUI.Components
28 /// The Navigator is a class which navigates pages with stack methods such
31 [EditorBrowsable(EditorBrowsableState.Never)]
32 public class Navigator : Control
34 //This will be replaced with view transition class instance.
35 private Animation _curAnimation = null;
37 //This will be replaced with view transition class instance.
38 private Animation _newAnimation = null;
40 private static Dictionary<Window, Navigator> windowNavigator = new Dictionary<Window, Navigator>();
43 /// Creates a new instance of a Navigator.
45 [EditorBrowsable(EditorBrowsableState.Never)]
46 public Navigator() : base()
51 /// List of pages of Navigator.
53 [EditorBrowsable(EditorBrowsableState.Never)]
54 public List<Page> NavigationPages { get; } = new List<Page>();
57 /// Pushes a page to Navigator.
58 /// If the page is already in Navigator, then it is not pushed.
60 /// <param name="page">The page to push to Navigator.</param>
61 /// <exception cref="ArgumentNullException">Thrown when the argument page is null.</exception>
62 [EditorBrowsable(EditorBrowsableState.Never)]
63 public void Push(Page page)
67 throw new ArgumentNullException(nameof(page), "page should not be null.");
70 //Duplicate page is not pushed.
71 if (NavigationPages.Contains(page)) return;
81 NavigationPages.Add(page);
85 page.InvokeAppearing();
86 curTop.InvokeDisappearing();
88 //TODO: The following transition codes will be replaced with view transition.
92 _curAnimation.Clear();
98 _newAnimation.Clear();
101 _curAnimation = new Animation(1000);
102 using (var scaleVec = new Vector3(0.0f, 0.0f, 1.0f))
104 _curAnimation.AnimateTo(curTop, "Scale", scaleVec, 0, 1000);
106 _curAnimation.AnimateTo(curTop, "Opacity", 0.0f, 0, 1000);
107 _curAnimation.EndAction = Animation.EndActions.Discard;
108 _curAnimation.Play();
110 using (var scaleVec = new Vector3(0.0f, 0.0f, 1.0f))
112 using (var scaleProp = new Tizen.NUI.PropertyValue(scaleVec))
114 Tizen.NUI.Object.SetProperty(page.SwigCPtr, Page.Property.SCALE, scaleProp);
117 using (var scaleProp = new Tizen.NUI.PropertyValue(0.0f))
119 Tizen.NUI.Object.SetProperty(page.SwigCPtr, Page.Property.OPACITY, scaleProp);
121 _newAnimation = new Animation(1000);
122 using (var scaleVec = new Vector3(1.0f, 1.0f, 1.0f))
124 _newAnimation.AnimateTo(page, "Scale", scaleVec, 0, 1000);
126 _newAnimation.AnimateTo(page, "Opacity", 1.0f, 0, 1000);
127 _newAnimation.Play();
131 /// Pops the top page from Navigator.
133 /// <returns>The popped page.</returns>
134 /// <exception cref="InvalidOperationException">Thrown when there is no page in Navigator.</exception>
135 [EditorBrowsable(EditorBrowsableState.Never)]
138 if (NavigationPages.Count == 0)
140 throw new InvalidOperationException("There is no page in Navigator.");
145 if (NavigationPages.Count == 1)
151 var newTop = NavigationPages[NavigationPages.Count - 2];
154 newTop.InvokeAppearing();
155 curTop.InvokeDisappearing();
157 //TODO: The following transition codes will be replaced with view transition.
160 _curAnimation.Stop();
161 _curAnimation.Clear();
166 _newAnimation.Stop();
167 _newAnimation.Clear();
170 _curAnimation = new Animation(1000);
171 using (var scaleVec = new Vector3(0.0f, 0.0f, 1.0f))
173 _curAnimation.AnimateTo(curTop, "Scale", scaleVec, 0, 1000);
175 _curAnimation.AnimateTo(curTop, "Opacity", 0.0f, 0, 1000);
176 _curAnimation.Play();
177 _curAnimation.Finished += (object sender, EventArgs e) =>
179 //Removes the current top page after transition is finished.
183 using (var scaleVec = new Vector3(0.0f, 0.0f, 1.0f))
185 using (var scaleProp = new Tizen.NUI.PropertyValue(scaleVec))
187 Tizen.NUI.Object.SetProperty(newTop.SwigCPtr, Page.Property.SCALE, scaleProp);
190 using (var opacityProp = new Tizen.NUI.PropertyValue(0.0f))
192 Tizen.NUI.Object.SetProperty(newTop.SwigCPtr, Page.Property.OPACITY, opacityProp);
194 _newAnimation = new Animation(1000);
195 using (var scaleVec = new Vector3(1.0f, 1.0f, 1.0f))
197 _newAnimation.AnimateTo(newTop, "Scale", scaleVec, 0, 1000);
199 _newAnimation.AnimateTo(newTop, "Opacity", 1.0f, 0, 1000);
200 _newAnimation.Play();
206 /// Inserts a page at the specified index of Navigator.
207 /// If the page is already in Navigator, then it is not inserted.
209 /// <param name="index">The index of Navigator where a page will be inserted.</param>
210 /// <param name="page">The page to insert to Navigator.</param>
211 /// <exception cref="ArgumentOutOfRangeException">Thrown when the argument index is less than 0, or greater than the number of pages.</exception>
212 /// <exception cref="ArgumentNullException">Thrown when the argument page is null.</exception>
213 [EditorBrowsable(EditorBrowsableState.Never)]
214 public void Insert(int index, Page page)
216 if ((index < 0) || (index > NavigationPages.Count))
218 throw new ArgumentOutOfRangeException(nameof(index), "index should be greater than or equal to 0, and less than or equal to the number of pages.");
223 throw new ArgumentNullException(nameof(page), "page should not be null.");
226 //Duplicate page is not pushed.
227 if (NavigationPages.Contains(page)) return;
229 NavigationPages.Insert(index, page);
234 /// Inserts a page to Navigator before an existing page.
235 /// If the page is already in Navigator, then it is not inserted.
237 /// <param name="before">The existing page, before which a page will be inserted.</param>
238 /// <param name="page">The page to insert to Navigator.</param>
239 /// <exception cref="ArgumentNullException">Thrown when the argument before is null.</exception>
240 /// <exception cref="ArgumentNullException">Thrown when the argument page is null.</exception>
241 /// <exception cref="ArgumentException">Thrown when the argument before does not exist in Navigator.</exception>
242 [EditorBrowsable(EditorBrowsableState.Never)]
243 public void InsertBefore(Page before, Page page)
247 throw new ArgumentNullException(nameof(before), "before should not be null.");
252 throw new ArgumentNullException(nameof(page), "page should not be null.");
255 //Find the index of before page.
256 int beforeIndex = NavigationPages.FindIndex(x => x == before);
258 //before does not exist in Navigator.
259 if (beforeIndex == -1)
261 throw new ArgumentException("before does not exist in Navigator.", nameof(before));
264 Insert(beforeIndex, page);
268 /// Removes a page from Navigator.
270 /// <param name="page">The page to remove from Navigator.</param>
271 /// <exception cref="ArgumentNullException">Thrown when the argument page is null.</exception>
272 [EditorBrowsable(EditorBrowsableState.Never)]
273 public void Remove(Page page)
277 throw new ArgumentNullException(nameof(page), "page should not be null.");
280 NavigationPages.Remove(page);
285 /// Removes a page at the specified index of Navigator.
287 /// <param name="index">The index of Navigator where a page will be removed.</param>
288 /// <exception cref="ArgumentOutOfRangeException">Thrown when the index is less than 0, or greater than or equal to the number of pages.</exception>
289 [EditorBrowsable(EditorBrowsableState.Never)]
290 public void RemoveAt(int index)
292 if ((index < 0) || (index >= NavigationPages.Count))
294 throw new ArgumentOutOfRangeException(nameof(index), "index should be greater than or equal to 0, and less than the number of pages.");
297 Remove(NavigationPages[index]);
301 /// Returns the page at the top of Navigator.
303 /// <returns>The page at the top of Navigator.</returns>
304 [EditorBrowsable(EditorBrowsableState.Never)]
307 if (NavigationPages.Count == 0) return null;
309 return NavigationPages[NavigationPages.Count - 1];
313 /// Returns the default navigator of the given window.
315 /// <returns>The default navigator of the given window.</returns>
316 /// <exception cref="ArgumentNullException">Thrown when the argument window is null.</exception>
317 [EditorBrowsable(EditorBrowsableState.Never)]
318 public static Navigator GetDefaultNavigator(Window window)
322 throw new ArgumentNullException(nameof(window), "window should not be null.");
325 if (windowNavigator.ContainsKey(window) == true)
327 return windowNavigator[window];
330 var defaultNavigator = new Navigator();
331 defaultNavigator.WidthResizePolicy = ResizePolicyType.FillToParent;
332 defaultNavigator.HeightResizePolicy = ResizePolicyType.FillToParent;
333 window.Add(defaultNavigator);
334 windowNavigator.Add(window, defaultNavigator);
336 return defaultNavigator;
340 /// Shows a dialog by pushing a page containing dialog to default navigator.
342 /// <param name="content">The content of Dialog.</param>
343 [EditorBrowsable(EditorBrowsableState.Never)]
344 public static void ShowDialog(View content = null)
346 var window = NUIApplication.GetDefaultWindow();
347 var defaultNavigator = window.GetDefaultNavigator();
349 var dialog = new Dialog(content);
350 SetDialogScrim(dialog);
352 var dialogPage = new Page(dialog);
353 defaultNavigator.Push(dialogPage);
357 /// Shows an alert dialog by pushing a page containing the alert dialog
358 /// to default navigator.
360 /// <param name="titleContent">The title content of AlertDialog.</param>
361 /// <param name="content">The content of AlertDialog.</param>
362 /// <param name="actionContent">The action content of AlertDialog.</param>
363 [EditorBrowsable(EditorBrowsableState.Never)]
364 public static void ShowAlertDialog(View titleContent, View content, View actionContent)
366 var window = NUIApplication.GetDefaultWindow();
367 var defaultNavigator = window.GetDefaultNavigator();
369 var dialog = new AlertDialog(titleContent, content, actionContent);
370 SetDialogScrim(dialog);
372 var dialogPage = new Page(dialog);
373 defaultNavigator.Push(dialogPage);
377 /// Shows an alert dialog by pushing a page containing the alert dialog
378 /// to default navigator.
380 /// <param name="title">The title of AlertDialog.</param>
381 /// <param name="message">The message of AlertDialog.</param>
382 /// <param name="positiveButtonText">The positive button text in the action content of AlertDialog.</param>
383 /// <param name="positiveButtonClickedHandler">The clicked callback of the positive button in the action content of AlertDialog.</param>
384 /// <param name="negativeButtonText">The negative button text in the action content of AlertDialog.</param>
385 /// <param name="negativeButtonClickedHandler">The clicked callback of the negative button in the action content of AlertDialog.</param>
386 [EditorBrowsable(EditorBrowsableState.Never)]
387 public static void ShowAlertDialog(string title = null, string message = null, string positiveButtonText = null, EventHandler<ClickedEventArgs> positiveButtonClickedHandler = null, string negativeButtonText = null, EventHandler<ClickedEventArgs> negativeButtonClickedHandler = null)
389 var window = NUIApplication.GetDefaultWindow();
390 var defaultNavigator = window.GetDefaultNavigator();
392 var dialog = new AlertDialog(title, message, positiveButtonText, positiveButtonClickedHandler, negativeButtonText, negativeButtonClickedHandler);
393 SetDialogScrim(dialog);
395 var dialogPage = new Page(dialog);
396 defaultNavigator.Push(dialogPage);
400 private static void SetDialogScrim(Dialog dialog)
407 var window = NUIApplication.GetDefaultWindow();
408 var defaultNavigator = window.GetDefaultNavigator();
409 var defaultScrim = dialog.Scrim;
411 //Copies default scrim's GUI properties.
412 var scrim = new VisualView();
413 scrim.BackgroundColor = defaultScrim.BackgroundColor;
414 scrim.Size = defaultScrim.Size;
415 scrim.TouchEvent += (object source, View.TouchEventArgs e) =>
417 if (e.Touch.GetState(0) == PointStateType.Up)
419 defaultNavigator.Pop();
425 dialog.Scrim = scrim;
428 } //namespace Tizen.NUI