2 using System.Collections.Generic;
4 using System.Threading.Tasks;
7 namespace Tizen.NUI.XamlBinding
12 internal class NavigationProxy : INavigation
15 Lazy<List<Page>> _modalStack = new Lazy<List<Page>>(() => new List<Page>());
17 Lazy<List<Page>> _pushStack = new Lazy<List<Page>>(() => new List<Page>());
19 internal INavigation Inner
21 get { return _inner; }
27 // reverse so that things go into the new stack in the same order
28 // null out to release memory that will likely never be needed again
30 if (ReferenceEquals(_inner, null))
32 _pushStack = new Lazy<List<Page>>(() => new List<Page>());
33 _modalStack = new Lazy<List<Page>>(() => new List<Page>());
37 if (_pushStack != null && _pushStack.IsValueCreated)
39 foreach (Page page in _pushStack.Value)
41 _inner.PushAsync(page);
45 if (_modalStack != null && _modalStack.IsValueCreated)
47 foreach (Page page in _modalStack.Value)
49 _inner.PushModalAsync(page);
60 /// Inserts a page in the navigation stack before an existing page in the stack.
62 /// <param name="page">The page to add.</param>
63 /// <param name="before">The existing page, before which page will be inserted.</param>
64 public void InsertPageBefore(Page page, Page before)
66 OnInsertPageBefore(page, before);
70 /// Gets the modal navigation stack.
72 public IReadOnlyList<Page> ModalStack
74 get { return GetModalStack(); }
78 /// Gets the stack of pages in the navigation.
80 public IReadOnlyList<Page> NavigationStack
82 get { return GetNavigationStack(); }
86 /// Asynchronously removes the most recent Page from the navigation stack.
88 /// <returns>The Page that had been at the top of the navigation stack.</returns>
89 public Task<Page> PopAsync()
91 return OnPopAsync(true);
95 /// Asynchronously removes the top Page from the navigation stack, with optional animation.
97 /// <param name="animated">Whether to animate the pop.</param>
98 /// <returns>The Page that had been at the top of the navigation stack.</returns>
99 public Task<Page> PopAsync(bool animated)
101 return OnPopAsync(animated);
105 /// Asynchronously dismisses the most recent modally presented Page.
107 /// <returns>An awaitable instance, indicating the PopModalAsync completion. The Task.Result is the Page that has been popped.</returns>
108 public Task<Page> PopModalAsync()
110 return OnPopModal(true);
114 /// Asynchronously removes the top Page from the navigation stack, with optional animation.
116 /// <param name="animated">Whether to animate the pop.</param>
117 /// <returns>The Page that had been at the top of the navigation stack.</returns>
118 public Task<Page> PopModalAsync(bool animated)
120 return OnPopModal(animated);
124 /// Pops all but the root Page off the navigation stack.
126 /// <returns>A task representing the asynchronous dismiss operation.</returns>
127 public Task PopToRootAsync()
129 return OnPopToRootAsync(true);
133 /// Pops all but the root Page off the navigation stack, with optional animation.
135 /// <param name="animated">Whether to animate the pop.</param>
136 /// <returns>A task representing the asynchronous dismiss operation.</returns>
137 public Task PopToRootAsync(bool animated)
139 return OnPopToRootAsync(animated);
143 /// Asynchronously adds a Page to the top of the navigation stack.
145 /// <param name="root">The Page to be pushed on top of the navigation stack.</param>
146 /// <returns>A task that represents the asynchronous push operation.</returns>
147 public Task PushAsync(Page root)
149 return PushAsync(root, true);
153 /// Asynchronously adds a Page to the top of the navigation stack, with optional animation.
155 /// <param name="root">The page to push.</param>
156 /// <param name="animated">Whether to animate the push.</param>
157 /// <returns>A task that represents the asynchronous push operation.</returns>
158 public Task PushAsync(Page root, bool animated)
160 if (root.RealParent != null)
161 throw new InvalidOperationException("Page must not already have a parent.");
162 return OnPushAsync(root, animated);
166 /// Presents a Page modally.
168 /// <param name="modal">The Page to present modally.</param>
169 /// <returns>An awaitable Task, indicating the PushModal completion.</returns>
170 public Task PushModalAsync(Page modal)
172 return PushModalAsync(modal, true);
176 /// Presents a Page modally, with optional animation.
178 /// <param name="modal">The page to push.</param>
179 /// <param name="animated">Whether to animate the push.</param>
180 /// <returns>An awaitable Task, indicating the PushModal completion.</returns>
181 public Task PushModalAsync(Page modal, bool animated)
183 if (modal.RealParent != null)
184 throw new InvalidOperationException("Page must not already have a parent.");
185 return OnPushModal(modal, animated);
189 /// Removes the specified page from the navigation stack.
191 /// <param name="page">The page to remove.</param>
192 public void RemovePage(Page page)
198 /// For internal use. Returns the modal navigation stack.
200 /// <returns>The modal navigation stack.</returns>
201 protected virtual IReadOnlyList<Page> GetModalStack()
203 INavigation currentInner = Inner;
204 return currentInner == null ? _modalStack.Value : currentInner.ModalStack;
208 /// For internal use. Returns the stack of pages in the navigation.
210 /// <returns>The stack of pages in the navigation.</returns>
211 protected virtual IReadOnlyList<Page> GetNavigationStack()
213 INavigation currentInner = Inner;
214 return currentInner == null ? _pushStack.Value : currentInner.NavigationStack;
218 /// The method called when insert a page in the navigation stack before an existing page in the stack.
220 /// <param name="page">The page to add.</param>
221 /// <param name="before">The existing page, before which page will be inserted.</param>
222 protected virtual void OnInsertPageBefore(Page page, Page before)
224 INavigation currentInner = Inner;
225 if (currentInner == null)
227 int index = _pushStack.Value.IndexOf(before);
229 throw new ArgumentException("before must be in the pushed stack of the current context");
230 _pushStack.Value.Insert(index, page);
234 currentInner.InsertPageBefore(page, before);
239 /// This method calls when removes the top Page from the navigation stack
241 /// <param name="animated">Whether to animate the pop.</param>
242 /// <returns></returns>
243 protected virtual Task<Page> OnPopAsync(bool animated)
245 INavigation inner = Inner;
246 return inner == null ? Task.FromResult(Pop()) : inner.PopAsync(animated);
250 /// This method calls when removes the top Page from the navigation stack
252 /// <param name="animated">Whether to animate the pop.</param>
253 /// <returns>An awaitable instance, indicating the PopModalAsync completion</returns>
254 protected virtual Task<Page> OnPopModal(bool animated)
256 INavigation innerNav = Inner;
257 return innerNav == null ? Task.FromResult(PopModal()) : innerNav.PopModalAsync(animated);
261 /// This method calls when Pops all but the root Page off the navigation stack.
263 /// <param name="animated">Whether to animate the pop.</param>
264 /// <returns>A task representing the asynchronous dismiss operation.</returns>
265 protected virtual Task OnPopToRootAsync(bool animated)
267 INavigation currentInner = Inner;
268 if (currentInner == null)
270 Page root = _pushStack.Value.Last();
271 _pushStack.Value.Clear();
272 _pushStack.Value.Add(root);
273 return Task.FromResult(root);
275 return currentInner.PopToRootAsync(animated);
279 /// This method calls when adds a Page to the top of the navigation stack, with optional animation.
281 /// <param name="page">The page to add</param>
282 /// <param name="animated">Whether to animate the pop.</param>
283 /// <returns>A task that represents the asynchronous push operation.</returns>
284 protected virtual Task OnPushAsync(Page page, bool animated)
286 INavigation currentInner = Inner;
287 if (currentInner == null)
289 _pushStack.Value.Add(page);
290 return Task.FromResult(page);
292 return currentInner.PushAsync(page, animated);
296 /// This method calls when Presents a Page modally, with optional animation.
298 /// <param name="modal">The page to push.</param>
299 /// <param name="animated">Whether to animate the pop.</param>
300 /// <returns>An awaitable Task, indicating the PushModal completion.</returns>
301 protected virtual Task OnPushModal(Page modal, bool animated)
303 INavigation currentInner = Inner;
304 if (currentInner == null)
306 _modalStack.Value.Add(modal);
307 return Task.FromResult<object>(null);
309 return currentInner.PushModalAsync(modal, animated);
313 /// This method calls when Removes the specified page from the navigation stack.
315 /// <param name="page">The page to add.</param>
316 protected virtual void OnRemovePage(Page page)
318 INavigation currentInner = Inner;
319 if (currentInner == null)
321 _pushStack.Value.Remove(page);
325 currentInner.RemovePage(page);
331 List<Page> list = _pushStack.Value;
332 Page result = list[list.Count - 1];
333 list.RemoveAt(list.Count - 1);
339 List<Page> list = _modalStack.Value;
340 Page result = list[list.Count - 1];
341 list.RemoveAt(list.Count - 1);