2 using System.Collections.Generic;
3 using System.ComponentModel;
5 using System.Threading.Tasks;
7 namespace Tizen.NUI.Binding
12 [EditorBrowsable(EditorBrowsableState.Never)]
13 internal class NavigationProxy : INavigation
16 Lazy<List<Page>> _modalStack = new Lazy<List<Page>>(() => new List<Page>());
18 Lazy<List<Page>> _pushStack = new Lazy<List<Page>>(() => new List<Page>());
20 internal INavigation Inner
22 get { return _inner; }
28 // reverse so that things go into the new stack in the same order
29 // null out to release memory that will likely never be needed again
31 if (ReferenceEquals(_inner, null))
33 _pushStack = new Lazy<List<Page>>(() => new List<Page>());
34 _modalStack = new Lazy<List<Page>>(() => new List<Page>());
38 if (_pushStack != null && _pushStack.IsValueCreated)
40 foreach (Page page in _pushStack.Value)
42 _inner.PushAsync(page);
46 if (_modalStack != null && _modalStack.IsValueCreated)
48 foreach (Page page in _modalStack.Value)
50 _inner.PushModalAsync(page);
61 /// Inserts a page in the navigation stack before an existing page in the stack.
63 /// <param name="page">The page to add.</param>
64 /// <param name="before">The existing page, before which page will be inserted.</param>
65 public void InsertPageBefore(Page page, Page before)
67 OnInsertPageBefore(page, before);
71 /// Gets the modal navigation stack.
73 public IReadOnlyList<Page> ModalStack
75 get { return GetModalStack(); }
79 /// Gets the stack of pages in the navigation.
81 public IReadOnlyList<Page> NavigationStack
83 get { return GetNavigationStack(); }
87 /// Asynchronously removes the most recent Page from the navigation stack.
89 /// <returns>The Page that had been at the top of the navigation stack.</returns>
90 public Task<Page> PopAsync()
92 return OnPopAsync(true);
96 /// Asynchronously removes the top Page from the navigation stack, with optional animation.
98 /// <param name="animated">Whether to animate the pop.</param>
99 /// <returns>The Page that had been at the top of the navigation stack.</returns>
100 public Task<Page> PopAsync(bool animated)
102 return OnPopAsync(animated);
106 /// Asynchronously dismisses the most recent modally presented Page.
108 /// <returns>An awaitable instance, indicating the PopModalAsync completion. The Task.Result is the Page that has been popped.</returns>
109 public Task<Page> PopModalAsync()
111 return OnPopModal(true);
115 /// Asynchronously removes the top Page from the navigation stack, with optional animation.
117 /// <param name="animated">Whether to animate the pop.</param>
118 /// <returns>The Page that had been at the top of the navigation stack.</returns>
119 public Task<Page> PopModalAsync(bool animated)
121 return OnPopModal(animated);
125 /// Pops all but the root Page off the navigation stack.
127 /// <returns>A task representing the asynchronous dismiss operation.</returns>
128 public Task PopToRootAsync()
130 return OnPopToRootAsync(true);
134 /// Pops all but the root Page off the navigation stack, with optional animation.
136 /// <param name="animated">Whether to animate the pop.</param>
137 /// <returns>A task representing the asynchronous dismiss operation.</returns>
138 public Task PopToRootAsync(bool animated)
140 return OnPopToRootAsync(animated);
144 /// Asynchronously adds a Page to the top of the navigation stack.
146 /// <param name="root">The Page to be pushed on top of the navigation stack.</param>
147 /// <returns>A task that represents the asynchronous push operation.</returns>
148 public Task PushAsync(Page root)
150 return PushAsync(root, true);
154 /// Asynchronously adds a Page to the top of the navigation stack, with optional animation.
156 /// <param name="root">The page to push.</param>
157 /// <param name="animated">Whether to animate the push.</param>
158 /// <returns>A task that represents the asynchronous push operation.</returns>
159 public Task PushAsync(Page root, bool animated)
161 if (root.RealParent != null)
162 throw new InvalidOperationException("Page must not already have a parent.");
163 return OnPushAsync(root, animated);
167 /// Presents a Page modally.
169 /// <param name="modal">The Page to present modally.</param>
170 /// <returns>An awaitable Task, indicating the PushModal completion.</returns>
171 public Task PushModalAsync(Page modal)
173 return PushModalAsync(modal, true);
177 /// Presents a Page modally, with optional animation.
179 /// <param name="modal">The page to push.</param>
180 /// <param name="animated">Whether to animate the push.</param>
181 /// <returns>An awaitable Task, indicating the PushModal completion.</returns>
182 public Task PushModalAsync(Page modal, bool animated)
184 if (modal.RealParent != null)
185 throw new InvalidOperationException("Page must not already have a parent.");
186 return OnPushModal(modal, animated);
190 /// Removes the specified page from the navigation stack.
192 /// <param name="page">The page to remove.</param>
193 public void RemovePage(Page page)
199 /// For internal use. Returns the modal navigation stack.
201 /// <returns>The modal navigation stack.</returns>
202 protected virtual IReadOnlyList<Page> GetModalStack()
204 INavigation currentInner = Inner;
205 return currentInner == null ? _modalStack.Value : currentInner.ModalStack;
209 /// For internal use. Returns the stack of pages in the navigation.
211 /// <returns>The stack of pages in the navigation.</returns>
212 protected virtual IReadOnlyList<Page> GetNavigationStack()
214 INavigation currentInner = Inner;
215 return currentInner == null ? _pushStack.Value : currentInner.NavigationStack;
219 /// The method called when insert a page in the navigation stack before an existing page in the stack.
221 /// <param name="page">The page to add.</param>
222 /// <param name="before">The existing page, before which page will be inserted.</param>
223 protected virtual void OnInsertPageBefore(Page page, Page before)
225 INavigation currentInner = Inner;
226 if (currentInner == null)
228 int index = _pushStack.Value.IndexOf(before);
230 throw new ArgumentException("before must be in the pushed stack of the current context");
231 _pushStack.Value.Insert(index, page);
235 currentInner.InsertPageBefore(page, before);
240 /// This method calls when removes the top Page from the navigation stack
242 /// <param name="animated">Whether to animate the pop.</param>
243 /// <returns></returns>
244 protected virtual Task<Page> OnPopAsync(bool animated)
246 INavigation inner = Inner;
247 return inner == null ? Task.FromResult(Pop()) : inner.PopAsync(animated);
251 /// This method calls when removes the top Page from the navigation stack
253 /// <param name="animated">Whether to animate the pop.</param>
254 /// <returns>An awaitable instance, indicating the PopModalAsync completion</returns>
255 protected virtual Task<Page> OnPopModal(bool animated)
257 INavigation innerNav = Inner;
258 return innerNav == null ? Task.FromResult(PopModal()) : innerNav.PopModalAsync(animated);
262 /// This method calls when Pops all but the root Page off the navigation stack.
264 /// <param name="animated">Whether to animate the pop.</param>
265 /// <returns>A task representing the asynchronous dismiss operation.</returns>
266 protected virtual Task OnPopToRootAsync(bool animated)
268 INavigation currentInner = Inner;
269 if (currentInner == null)
271 Page root = _pushStack.Value.Last();
272 _pushStack.Value.Clear();
273 _pushStack.Value.Add(root);
274 return Task.FromResult(root);
276 return currentInner.PopToRootAsync(animated);
280 /// This method calls when adds a Page to the top of the navigation stack, with optional animation.
282 /// <param name="page">The page to add</param>
283 /// <param name="animated">Whether to animate the pop.</param>
284 /// <returns>A task that represents the asynchronous push operation.</returns>
285 protected virtual Task OnPushAsync(Page page, bool animated)
287 INavigation currentInner = Inner;
288 if (currentInner == null)
290 _pushStack.Value.Add(page);
291 return Task.FromResult(page);
293 return currentInner.PushAsync(page, animated);
297 /// This method calls when Presents a Page modally, with optional animation.
299 /// <param name="modal">The page to push.</param>
300 /// <param name="animated">Whether to animate the pop.</param>
301 /// <returns>An awaitable Task, indicating the PushModal completion.</returns>
302 protected virtual Task OnPushModal(Page modal, bool animated)
304 INavigation currentInner = Inner;
305 if (currentInner == null)
307 _modalStack.Value.Add(modal);
308 return Task.FromResult<object>(null);
310 return currentInner.PushModalAsync(modal, animated);
314 /// This method calls when Removes the specified page from the navigation stack.
316 /// <param name="page">The page to add.</param>
317 protected virtual void OnRemovePage(Page page)
319 INavigation currentInner = Inner;
320 if (currentInner == null)
322 _pushStack.Value.Remove(page);
326 currentInner.RemovePage(page);
332 List<Page> list = _pushStack.Value;
333 Page result = list[list.Count - 1];
334 list.RemoveAt(list.Count - 1);
340 List<Page> list = _modalStack.Value;
341 Page result = list[list.Count - 1];
342 list.RemoveAt(list.Count - 1);