async Task <bool> PopToNavigationState(NavigationState state) { int index = navigationStateStack.FindIndex((ns) => ns == state); if (index == -1) { return(false); } for (int i = navigationStateStack.Count - 1; i > index; i--) { if (!await navigationStateStack [i].Hide()) { return(false); } if (!await navigationStateStack [i].Unload()) { return(false); } navigationStateStack [i].ScreenState.Dispose(); navigationStateStack.RemoveAt(i); if (!await App.Current.Navigation.Pop(null)) { return(false); } } if (!await state.Show()) { return(false); } await App.Current.EventsBroker.Publish(new NavigationEvent { Name = state.Name }); return(await App.Current.Navigation.Push(state.ScreenState.Panel)); }
public async Task <bool> Unload() { NavigationStateStatus newStatus = NavigationStateStatus.Unloaded; if (IsAlreadyInSameStatus(newStatus)) { return(true); } bool result = await ScreenState.UnloadState(); if (result) { UpdateState(newStatus); } if (freezingState != null && freezingState.Completion.Task.Status != TaskStatus.RanToCompletion) { freezingState.Completion.SetResult(true); freezingState = null; } // FIXME: when quit is done a double home navigation is done // this causes that the hide/unload of the state is done twice // because the stack is not empty, the hide state is the one creating // the second home transition if (Completion.Task.Status != TaskStatus.RanToCompletion && completeWhenUnload) { Completion.SetResult(result); } return(result); }
public async Task <bool> Unfreeze() { NavigationStateStatus newStatus = NavigationStateStatus.Shown; if (IsAlreadyInSameStatus(newStatus)) { return(true); } bool result = await ScreenState.UnfreezeState(); if (result) { UpdateState(newStatus); } var freezingStateMemento = freezingState; freezingState = null; if (freezingStateMemento.Completion.Task.Status != TaskStatus.RanToCompletion) { freezingStateMemento.Completion.SetResult(result); } return(result); }
async Task <bool> PopNavigationState() { NavigationState navigationState = navigationStateStack [navigationStateStack.Count - 1]; IScreenState screenToPop = navigationState.ScreenState; navigationStateStack.RemoveAt(navigationStateStack.Count - 1); NavigationState lastState = LastNavigationState(); if (!await screenToPop.HideState()) { return(false); } if (!await App.Current.Navigation.Pop(lastState?.ScreenState.Panel)) { return(false); } await App.Current.EventsBroker.Publish(new NavigationEvent { Name = Current.Name }); if (!await navigationState.Unload()) { return(false); } screenToPop.Dispose(); return(true); }
async Task <bool> PushNavigationState(string transition, IScreenState state) { NavigationState navState; if (transition == home?.Name) { navState = home; } else { navState = new NavigationState(transition, state); navigationStateStack.Add(navState); } if (!await App.Current.Navigation.Push(state.Panel)) { return(false); } if (!await navState.Show()) { return(false); } await App.Current.EventsBroker.Publish(new NavigationEvent { Name = transition }); return(true); }
/// <summary> /// Moves the back to previous transition. It also considers Home name transition and goes back home /// </summary> /// <returns>Ture: If transition could be performed. False otherwise</returns> /// <param name="transition">Transition name</param> public async Task <bool> MoveBackTo(string transition) { try { NavigationState state = LastStateFromTransition(transition); if (state == null) { Log.Debug("Moving failed because transition " + transition + " is not in history moves"); return(false); } if (!CanMove(state)) { return(false); } if (home != null && state == home) { return(await MoveToHome()); } //Check for modals to delete them. if (!await PopAllModalStates()) { return(false); } return(await PopToNavigationState(state)); } catch (Exception ex) { Log.Exception(ex); throw; } }
public override bool Equals(object obj) { NavigationState navState = obj as NavigationState; if (navState == null) { return(false); } return(navState.Name == Name && navState.ScreenState == ScreenState); }
// FIXME: Enqueue instead of blocking navigation bool CanMove(NavigationState current) { bool canMove = current == null || (current.CurrentStatus == NavigationStateStatus.Shown || current.CurrentStatus == NavigationStateStatus.Hidden); if (canMove) { App.Current.EventsBroker.Publish <NavigatingEvent> (); } return(canMove); }
async Task <bool> PushModalState(NavigationState state, IScreenState current) { modalStateStack.Add(state); if (!await state.Show()) { return(false); } await App.Current.EventsBroker.Publish(new NavigationEvent { Name = state.ScreenState.Name, IsModal = true }); await App.Current.Navigation.PushModal(state.ScreenState.Panel, current.Panel); return(true); }
/// <summary> /// Moves Back to the previous transition Panel or Modal. /// </summary> /// <returns>True: If the transition could be performed. False Otherwise</returns> public async Task <bool> MoveBack() { if (modalStateStack.Count == 0 && navigationStateStack.Count <= 1 && home == null) { Log.Debug("Moving back failed because is last transition and there isn't any home"); return(false); } try { bool triggeredFromModal; NavigationState current = LastState(out triggeredFromModal); if (!CanMove(current)) { return(false); } Log.Debug("Moving Back"); if (current != null) { if (!triggeredFromModal) { if (!await PopNavigationState()) { return(false); } } else { if (!await PopModalState(current)) { return(false); } } current = LastState(); if (triggeredFromModal) { return(await current.Unfreeze()); } else { return(await current.Show()); } } return(true); } catch (Exception ex) { Log.Exception(ex); throw; } }
/// <summary> /// Sets the home transition. Needs to be registered first. /// </summary> /// <returns>True if the home transition could be executed. False otherwise</returns> /// <param name="transition">Transition.</param> public async Task <bool> SetHomeTransition(string transition, dynamic properties) { try { Log.Debug("Setting Home to " + transition); IScreenState homeState = destination [transition] (); if (!await homeState.LoadState(properties)) { return(false); } home = new NavigationState(transition, homeState); return(await MoveToHome(true)); } catch (Exception ex) { Log.Exception(ex); throw; } }
/// <summary> /// Moves to a Modal window /// </summary> /// <returns>True if the Move could be performed. False otherwise</returns> /// <param name="transition">Transition.</param> public async Task <bool> MoveToModal(string transition, dynamic properties, bool waitUntilClose = false) { Log.Debug("Moving to " + transition + " in modal mode"); if (!destination.ContainsKey(transition)) { Log.Debug("Moving failed because transition " + transition + " is not in destination dictionary."); return(false); } try { IScreenState state = destination [transition] (); NavigationState transitionState = new NavigationState(transition, state, !waitUntilClose); NavigationState lastState = LastState(); if (!CanMove(lastState)) { return(false); } if (!await lastState.Freeze(transitionState)) { return(false); } bool ok = await state.LoadState(properties); if (ok) { await PushModalState(transitionState, LastState()?.ScreenState); NavigationState resultantState = LastState(); if (waitUntilClose && resultantState.Name == transition) { await resultantState.Completion.Task; } } else { Log.Debug("Moving failed because panel " + state.Name + " cannot move."); } return(ok); } catch (Exception ex) { Log.Exception(ex); throw; } }
public async Task <bool> Freeze(NavigationState freezingState) { NavigationStateStatus newStatus = NavigationStateStatus.Frozen; if (IsAlreadyInSameStatus(newStatus)) { return(true); } this.freezingState = freezingState; bool result = await ScreenState.FreezeState(); if (result) { UpdateState(newStatus); } return(result); }
async Task <bool> PopModalState(NavigationState current) { NavigationState navigationState = modalStateStack [modalStateStack.Count - 1]; IScreenState screenToPop = navigationState.ScreenState; if (!await screenToPop.HideState()) { return(false); } if (!await navigationState.Unload()) { return(false); } modalStateStack.RemoveAt(modalStateStack.Count - 1); await App.Current.EventsBroker.Publish(new NavigationEvent { Name = Current.Name, IsModal = modalStateStack.Any() }); await App.Current.Navigation.PopModal(screenToPop.Panel); screenToPop.Dispose(); return(true); }
/// <summary> /// Moves to a Panel inside the main window. If it has some previous modal windows /// It Pops them all. /// </summary> /// <returns>True if the move could be performed. False otherwise</returns> /// <param name="transition">Transition.</param> public async Task <bool> MoveTo(string transition, dynamic properties, bool emptyStack = false, bool forceMove = false) { Log.Debug("Moving to " + transition); if (!destination.ContainsKey(transition)) { Log.Debug("Moving failed because transition " + transition + " is not in destination dictionary."); return(false); } try { bool isModal = false; NavigationState lastState = LastState(out isModal); if (!forceMove && lastState != null && lastState.Name == transition) { Log.Debug("Not moved to " + transition + "because we're already there"); return(true); } if (!CanMove(lastState) && !forceMove) { return(false); } if (emptyStack) { if (!await EmptyStateStack()) { return(false); } if (lastState == home && home.Name != transition) { if (!await lastState.Hide()) { Log.Debug("Moving failed because home panel " + lastState.Name + " cannot move."); return(false); } } } else if (isModal) { if (!await PopAllModalStates()) { return(false); } } else if (lastState != null) { if (!await lastState.Hide()) { Log.Debug("Moving failed because panel " + lastState.Name + " cannot move."); return(false); } } IScreenState state; bool isHome = transition == home?.Name; if (isHome) { state = home.ScreenState; } else { state = destination [transition] (); if (!await state.LoadState(properties)) { // If the transition failed and the stack is empty, load the home, // otherwise show again the last state that was hidden at the start of the // MoveTo if (emptyStack) { await PushNavigationState(home.Name, home.ScreenState); } else { if (!await lastState.Show()) { // This shouldn't fail... but just in case Log.Error("Last state couldn't be shown again, we'll move back home"); await PushNavigationState(home.Name, home.ScreenState); } } return(false); } } return(await PushNavigationState(transition, state)); } catch (Exception ex) { Log.Exception(ex); throw; } }