/// <summary> /// Inserts the specified <see cref="IMXView"/> object into an appropriate stack and renders it. /// </summary> /// <param name="view">The view to be inserted into a stack.</param> /// <exception cref="ArgumentNullException">Thrown when the <paramref name="view"/> is <c>null</c>.</exception> public void DisplayView(IMXView view) { if (view == null) { throw new ArgumentNullException("view"); } var entry = view as IHistoryEntry; if (entry != null && entry.StackID == null) { entry.StackID = view.GetType().FullName; } var navContext = new iLayer.NavigationContext { OutputOnPane = GetPreferredPaneForView(view), NavigatedActiveTab = iApp.CurrentNavContext.ActiveTab, NavigatedActivePane = iApp.CurrentNavContext.ActivePane, }; var stack = FindStack(view); var layer = view.GetModel() as iLayer; if (layer != null) { if (stack.Contains(view)) { layer.NavContext.NavigatedActivePane = navContext.NavigatedActivePane; layer.NavContext.ClearPaneHistoryOnOutput = false; } layer.NavContext.OutputOnPane = navContext.OutputOnPane; layer.NavContext.NavigatedActiveTab = navContext.NavigatedActiveTab; navContext = layer.NavContext; } var originalPane = navContext.OutputOnPane; if (stack.Contains(view)) { originalPane = stack.FindPane(); iApp.CurrentNavContext.ActivePane = originalPane; navContext.NavigatedActivePane = originalPane; if (entry != null) { entry.OutputPane = originalPane; } } for (navContext.OutputOnPane = Pane.Popover; navContext.OutputOnPane > originalPane; navContext.OutputOnPane--) { var clearStack = FromNavContext(navContext); if (clearStack != null && clearStack.FindPane() > originalPane) { clearStack.PopToRoot(); } } stack.DisplayView(view, navContext.NavigatedActivePane < navContext.OutputOnPane || navContext.ClearPaneHistoryOnOutput); }
internal Pane GetPreferredPaneForView(IMXView view) { if (view == null) { throw new ArgumentNullException("view"); } // Order of importance: iLayer > IHistoryEntry > PreferredPane var layer = view.GetModel() as iLayer; if (layer != null) { return(layer.NavContext.OutputOnPane); } var entry = view as IHistoryEntry; if (entry != null && entry.OutputPane != Pane.Tabs) { return(entry.OutputPane); } var topPane = TopmostPane.OutputOnPane; var paneAttribute = Device.Reflector.GetCustomAttribute <PreferredPaneAttribute>(view.GetType(), true); if (topPane < Pane.Detail && paneAttribute == null) { if (topPane == Pane.Tabs) { return(Pane.Master); } var detail = FromNavContext(Pane.Detail, 0); if (detail != null && detail.FindPane() == Pane.Detail) { return(Pane.Detail); } } return(paneAttribute != null && paneAttribute.Pane > topPane ? paneAttribute.Pane : topPane); }
/// <summary> /// Initiates a navigation using the specified Link. /// </summary> /// <param name='link'>A <see cref="Link"/> containing the URL to navigate to with the parameters to pass through.</param> /// <param name="fromView">The <see cref="IMXView"/> instance from which the navigation was initiated.</param> public static void Navigate(Link link, IMXView fromView) { if (link == null) { Log.Warn("Navigation to null link cancelled."); return; } // Add layer's ActionParameters to Link var layer = fromView == null ? null : fromView.GetModel() as iLayer; if (layer != null && layer.ActionParameters != null) { if (link.Parameters == null) { link.Parameters = new Dictionary <string, string>(); } link.Parameters.AddRange(layer.ActionParameters); } if (fromView is ITabView) { CurrentNavContext.ActivePane = Pane.Tabs; CurrentNavContext.ActiveTab = (fromView as ITabView).SelectedIndex; } else { var entry = fromView as IHistoryEntry; if (entry != null) { CurrentNavContext.ActivePane = entry.OutputPane == Pane.Tabs ? Pane.Master : entry.OutputPane; } else if (layer != null) { CurrentNavContext.ActivePane = layer.NavContext.OutputOnPane; } } #region Link actions if (fromView != null) { link.Address = Resolve(PaneManager.Instance.GetNavigatedURI(fromView), link.Address); } if (link.Action == ActionType.Submit) { var listview = fromView as IListView; if (listview != null) { var newLink = link.Clone(); newLink.Action = ActionType.Undefined; listview.Submit(newLink); return; } var gridview = fromView as IGridView; if (gridview != null) { var newLink = link.Clone(); newLink.Action = ActionType.Undefined; gridview.Submit(newLink); return; } } if (link.Action == ActionType.None) { return; } #endregion if (!string.IsNullOrEmpty(link.ConfirmationText)) { var newLink = link.Clone(); newLink.ConfirmationText = null; var alert = new Alert(link.ConfirmationText, Factory.GetResourceString("ConfirmTitle"), AlertButtons.OKCancel); alert.OKLink = newLink; alert.Show(); return; } if (link.Address == null) { Log.Warn("Navigation to null URI cancelled."); return; } var parameters = link.Parameters == null ? new Dictionary <string, string>() : new Dictionary <string, string>(link.Parameters); Factory.LastActivityDate = DateTime.Now; Log.Info("Navigating to: " + link.Address); // Determine which mapping has a matching pattern to the URL to navigate to var navMap = Instance.NavigationMap.MatchUrl(link.Address); iLayer navLayer; // If there is no result, assume the URL is external and create a new Browser Layer if (navMap == null) { if (link.RequestType == RequestType.NewWindow) { new BrowserView <string>().LaunchExternal(link.Address); Factory.StopBlockingUserInput(); return; } var browserLayer = new Browser(link.Address); browserLayer.OnLoadComplete += TargetFactory.TheApp.LayerLoadCompleted; navLayer = browserLayer; } else { navLayer = navMap.Controller as iLayer; } // UI elements could be accessed while figuring out nav context, so ensure that it happens on the UI thread Thread.ExecuteOnMainThread(() => { Pane pane = Pane.Master; var topPane = PaneManager.Instance.TopmostPane.OutputOnPane; var stack = PaneManager.Instance.FromNavContext(topPane); if (fromView == null && stack != null && stack.CurrentView != null) { var history = stack.CurrentView as IHistoryEntry; CurrentNavContext.ActivePane = history == null ? topPane : history.OutputPane; } if (navLayer != null) { // Set up the Layer's navigation context var navContext = navLayer.NavContext; navContext.NavigatedUrl = link.Address == string.Empty && navMap != null ? navMap.Pattern : link.Address; var navUriEntry = PaneManager.Instance.NavigatedURIs.FirstOrDefault(p => p.Value == navContext.NavigatedUrl); var existingView = navUriEntry.Key as IHistoryEntry; var activePane = CurrentNavContext.ActivePane; var targetPane = existingView == null ? navLayer.FindTarget() : existingView.OutputPane; stack = PaneManager.Instance.FromNavContext(targetPane, CurrentNavContext.ActiveTab); if (existingView != null && !stack.Contains(existingView as IMXView)) { targetPane = navLayer.FindTarget(); } if (targetPane > activePane && (targetPane != Pane.Detail || Factory.LargeFormFactor && Instance.FormFactor == FormFactor.SplitView)) { navContext.ClearPaneHistoryOnOutput = true; } else { if (CurrentNavContext.ActivePane != targetPane && (stack == null || stack.Views.OfType <IHistoryEntry>().All(v => v.StackID != navLayer.Name))) { targetPane = PaneManager.Instance.TopmostPane.OutputOnPane; } navContext.OutputOnPane = activePane = CurrentNavContext.ActivePane = targetPane; navContext.ClearPaneHistoryOnOutput = false; } // Always render to Master from Tabs, otherwise target the targetPane navContext.OutputOnPane = (activePane == Pane.Tabs) ? Pane.Master : targetPane; navContext.NavigatedActivePane = activePane; navContext.NavigatedActiveTab = CurrentNavContext.ActiveTab; navLayer.LayerStyle = Instance.Style.Clone(); pane = navContext.OutputOnPane; } Link navLink = link.Clone(); navLink.Parameters = parameters; if (PaneManager.Instance.ShouldNavigate(navLink, pane, NavigationType.Forward)) { Factory.ActivateLoadTimer(link.LoadIndicatorTitle, link.LoadIndicatorDelay); // Initiate the layer loading for the associated layer passing all parameters CurrentNavContext.ActiveLayer = navLayer; if (navMap == null) { Factory.LoadLayer(fromView, navLayer, navLink.Address, navLink.Parameters); } else { MXContainer.Navigate(fromView, navLink.Address, navLink.Parameters); } } else { Factory.StopBlockingUserInput(); } }); }
internal void Attach(IMXView view, HistoryStack stack) { if (GridControl.Bitmaps.Any()) { var bitmaps = new Dictionary <GridControl, System.Drawing.Bitmap>(GridControl.Bitmaps); GridControl.Bitmaps.Clear(); GridControl.mem = 0; foreach (var bit in bitmaps) { bit.Value.Dispose(); } } Device.Thread.ExecuteOnMainThread(() => { if (view == null) { return; } iApp.CurrentNavContext.ActivePane = stack.Context.ActivePane; var t = CompactFactory.MetricStopwatch.ElapsedTicks; var absView = view as IView; var list = view as IListView; var grid = view as IGridView; var browser = view as IBrowserView; var history = view as IHistoryEntry; var concreteView = view as System.Windows.Forms.Control ?? (view is IPairable ? ((IPairable)view).Pair as System.Windows.Forms.Control : null); if (absView != null) { Text = absView.Title; } var listbox = ActiveView as SmoothListbox; if (listbox != null) { listbox.animationTimer.Enabled = false; } Controls.Clear(); int top = CompactFactory.TopPadding; if (list != null && list.SearchBox != null) { var box = CompactFactory.GetNativeObject <System.Windows.Forms.Control>(list.SearchBox, "SearchBox"); box.Parent = this; var min = new Size(Width, 0); var max = new Size(Width, 50 * CompactFactory.Instance.DpiScale); box.Size = ((IGridBase)box).PerformLayout(min, max).ToSize(); box.Top = top; top = box.Bottom; } if (concreteView != null) { var h = Screen.PrimaryScreen.WorkingArea.Height - SystemInformation.MenuHeight; concreteView.Size = new System.Drawing.Size(Width, h); concreteView.Parent = this; concreteView.Location = new Point(0, top); } Menu.MenuItems.Clear(); var back = history == null ? null : history.BackLink; var backButton = new MenuItem { Text = iApp.Factory.GetResourceString("Back") }; backButton.Click += (sender, args) => stack.HandleBackLink(back, stack.Context.ActivePane); Menu.MenuItems.Add(backButton); var layer = view.GetModel() as iLayer; backButton.Enabled = stack.DisplayBackButton(back) || stack.Context.ActivePane == Pane.Popover && !(layer is LoginLayer) && stack.Views.Count() < 2; if (MenuTabView.Instance != null && !(layer is LoginLayer) && (layer == null || stack.Context.ActivePane != Pane.Popover)) { Menu.MenuItems.Add(MenuTabView.Instance); } var menu = (list != null ? list.Menu : grid != null ? grid.Menu : browser != null ? browser.Menu : null); if (menu != null) { MenuItem menuButton; if (menu.ButtonCount == 1) { menuButton = CompactFactory.GetNativeObject <MenuItem>(menu.GetButton(0), "menu[0]"); } else { menuButton = new MenuItem { Text = iApp.Factory.GetResourceString("Menu") }; for (int i = 0; i < menu.ButtonCount; i++) { menuButton.MenuItems.Add(CompactFactory.GetNativeObject <MenuItem>(menu.GetButton(i), "menu[" + i + "]")); } } Menu.MenuItems.Add(menuButton); } MinimizeBox = layer == null || layer.ActionButtons.All(b => b.Action != Button.ActionType.Submit); listbox = ActiveView as SmoothListbox; if (listbox != null) { listbox.animationTimer.Enabled = true; } CompactFactory.NavigatedAddresses.Clear(); Debug.WriteLineIf(CompactFactory.MetricStopwatch.IsRunning, string.Format("[{1}] Attach IMXView took {0}ms", new TimeSpan(CompactFactory.MetricStopwatch.ElapsedTicks - t).TotalMilliseconds, CompactFactory.MetricStopwatch.ElapsedMilliseconds)); Debug.WriteLineIf(CompactFactory.MetricStopwatch.IsRunning, string.Format("Total elapsed layer load time: {0}ms", CompactFactory.MetricStopwatch.ElapsedMilliseconds)); CompactFactory.MetricStopwatch.Stop(); }); }