Example #1
0
        internal static List <string> CollapsePath(
            string[] myRoute,
            IEnumerable <string> currentRouteStack,
            bool removeUserDefinedRoute)
        {
            var localRouteStack = currentRouteStack.ToList();

            for (var i = localRouteStack.Count - 1; i >= 0; i--)
            {
                var route = localRouteStack[i];
                if (Routing.IsImplicit(route) ||
                    (Routing.IsDefault(route) && removeUserDefinedRoute))
                {
                    localRouteStack.RemoveAt(i);
                }
            }

            var paths = myRoute.ToList();

            // collapse similar leaves
            int walkBackCurrentStackIndex = -1;

            if (paths.Count > 0)
            {
                walkBackCurrentStackIndex = localRouteStack.IndexOf(paths[0]);
            }

            while (paths.Count > 1 && walkBackCurrentStackIndex >= 0)
            {
                if (localRouteStack.Count <= walkBackCurrentStackIndex)
                {
                    break;
                }

                if (paths[0] == localRouteStack[walkBackCurrentStackIndex])
                {
                    paths.RemoveAt(0);
                }
                else
                {
                    break;
                }

                walkBackCurrentStackIndex++;
            }

            return(paths);
        }
Example #2
0
            public Uri GetUri()
            {
                List <string> paths = new List <string>();

                paths.Add(Shell.RouteHost);
                paths.Add(Shell.Route);
                if (Item != null && !Routing.IsImplicit(Item))
                {
                    paths.Add(Item.Route);
                }
                if (Section != null && !Routing.IsImplicit(Section))
                {
                    paths.Add(Section.Route);
                }
                if (Content != null && !Routing.IsImplicit(Content))
                {
                    paths.Add(Content.Route);
                }

                string uri = String.Join(_pathSeparator, paths);

                return(new Uri($"{Shell.RouteScheme}://{uri}"));
            }
Example #3
0
        public override void Add(ShellItem item)
        {
            /*
             * This is purely for the case where a user is only specifying Tabs at the highest level
             * <shell>
             * <tab></tab>
             * <tab></tab>
             * </shell>
             * */
            if (Routing.IsImplicit(item) &&
                item is TabBar
                )
            {
                int i = Count - 1;
                if (i >= 0 && this[i] is TabBar && Routing.IsImplicit(this[i]))
                {
                    (this[i] as ShellItem).Items.Add(item.Items[0]);
                    return;
                }
            }

            Inner.Add(item);
        }
Example #4
0
        public static void ApplyQueryAttributes(Element element, ShellRouteParameters query, bool isLastItem, bool isPopping)
        {
            string prefix = "";

            if (!isLastItem)
            {
                var route = Routing.GetRoute(element);
                if (string.IsNullOrEmpty(route) || Routing.IsImplicit(route))
                {
                    return;
                }
                prefix = route + ".";
            }

            //if the lastItem is implicitly wrapped, get the actual ShellContent
            if (isLastItem)
            {
                if (element is IShellItemController shellitem && shellitem.GetItems().FirstOrDefault() is ShellSection section)
                {
                    element = section;
                }
                if (element is IShellSectionController shellsection && shellsection.GetItems().FirstOrDefault() is ShellContent content)
                {
                    element = content;
                }
                if (element is ShellContent shellcontent && shellcontent.Content is Element e)
                {
                    element = e;
                }
            }

            if (!(element is BaseShellItem baseShellItem))
            {
                baseShellItem = element?.Parent as BaseShellItem;
            }

            //filter the query to only apply the keys with matching prefix
            var filteredQuery = new ShellRouteParameters(query.Count);

            foreach (var q in query)
            {
                if (!q.Key.StartsWith(prefix, StringComparison.Ordinal))
                {
                    continue;
                }
                var key = q.Key.Substring(prefix.Length);
                if (key.IndexOf(".", StringComparison.Ordinal) != -1)
                {
                    continue;
                }
                filteredQuery.Add(key, q.Value);
            }


            if (baseShellItem is ShellContent)
            {
                baseShellItem.ApplyQueryAttributes(MergeData(element, filteredQuery, isPopping));
            }
            else if (isLastItem)
            {
                element.SetValue(ShellContent.QueryAttributesProperty, MergeData(element, query, isPopping));
            }

            ShellRouteParameters MergeData(Element shellElement, ShellRouteParameters data, bool isPopping)
            {
                if (!isPopping)
                {
                    return(data);
                }

                var returnValue = new ShellRouteParameters(data);

                var existing = (ShellRouteParameters)shellElement.GetValue(ShellContent.QueryAttributesProperty);

                if (existing == null)
                {
                    return(data);
                }

                foreach (var datum in existing)
                {
                    if (!returnValue.ContainsKey(datum.Key))
                    {
                        returnValue[datum.Key] = datum.Value;
                    }
                }

                return(returnValue);
            }
        }
Example #5
0
        bool UpdateFlyoutGroupings()
        {
            // The idea here is to create grouping such that the Flyout would
            // render correctly if it renderered each item in the groups in order
            // but put a line between the groups. This is needed because our grouping can
            // actually go 3 layers deep.

            // Ideally this lets us control where lines are drawn in the core code
            // just by changing how we generate these groupings

            var result = new List <List <Element> >();

            var currentGroup = new List <Element>();

            foreach (var shellItem in ShellController.GetItems())
            {
                if (!ShowInFlyoutMenu(shellItem))
                {
                    continue;
                }

                if (Routing.IsImplicit(shellItem) || shellItem.FlyoutDisplayOptions == FlyoutDisplayOptions.AsMultipleItems)
                {
                    if (shellItem.FlyoutDisplayOptions == FlyoutDisplayOptions.AsMultipleItems)
                    {
                        IncrementGroup();
                    }

                    foreach (var shellSection in (shellItem as IShellItemController).GetItems())
                    {
                        if (!ShowInFlyoutMenu(shellSection))
                        {
                            continue;
                        }

                        var shellContents = ((IShellSectionController)shellSection).GetItems();
                        if (Routing.IsImplicit(shellSection) || shellSection.FlyoutDisplayOptions == FlyoutDisplayOptions.AsMultipleItems)
                        {
                            foreach (var shellContent in shellContents)
                            {
                                if (!ShowInFlyoutMenu(shellContent))
                                {
                                    continue;
                                }

                                currentGroup.Add(shellContent);
                                if (shellContent == shellSection.CurrentItem)
                                {
                                    AddMenuItems(shellContent.MenuItems);
                                }
                            }

                            if (shellSection.FlyoutDisplayOptions == FlyoutDisplayOptions.AsMultipleItems)
                            {
                                IncrementGroup();
                            }
                        }
                        else
                        {
                            if (!(shellSection.Parent is TabBar))
                            {
                                if (Routing.IsImplicit(shellSection) && shellContents.Count == 1)
                                {
                                    if (!ShowInFlyoutMenu(shellContents[0]))
                                    {
                                        continue;
                                    }

                                    currentGroup.Add(shellContents[0]);
                                }
                                else
                                {
                                    currentGroup.Add(shellSection);
                                }
                            }

                            // If we have only a single child we will also show the items menu items
                            if (shellContents.Count == 1 && shellSection == shellItem.CurrentItem && shellSection.CurrentItem.MenuItems.Count > 0)
                            {
                                AddMenuItems(shellSection.CurrentItem.MenuItems);
                            }
                        }
                    }

                    if (shellItem.FlyoutDisplayOptions == FlyoutDisplayOptions.AsMultipleItems)
                    {
                        IncrementGroup();
                    }
                }
                else
                {
                    if (!(shellItem is TabBar))
                    {
                        currentGroup.Add(shellItem);
                    }
                }
            }

            IncrementGroup();

            // If the flyout groupings haven't changed just return
            // the same instance so the caller knows it hasn't changed
            // at a later point this will all get converted to an observable collection
            if (_lastGeneratedFlyoutItems?.Count == result.Count)
            {
                bool hasChanged = false;
                for (var i = 0; i < result.Count && !hasChanged; i++)
                {
                    var topLevelNew      = result[i];
                    var topLevelPrevious = _lastGeneratedFlyoutItems[i];

                    if (topLevelNew.Count != topLevelPrevious.Count)
                    {
                        hasChanged = true;
                        break;
                    }

                    for (var j = 0; j > topLevelNew.Count; j++)
                    {
                        if (topLevelNew[j] != topLevelPrevious[j])
                        {
                            hasChanged = true;
                            break;
                        }
                    }
                }

                if (!hasChanged)
                {
                    return(false);
                }
            }

            _lastGeneratedFlyoutItems = result;
            return(true);

            bool ShowInFlyoutMenu(BindableObject bo)
            {
                if (bo is MenuShellItem msi)
                {
                    return(Shell.GetFlyoutItemIsVisible(msi.MenuItem));
                }

                return(Shell.GetFlyoutItemIsVisible(bo));
            }

            void AddMenuItems(MenuItemCollection menuItems)
            {
                foreach (var item in menuItems)
                {
                    if (ShowInFlyoutMenu(item))
                    {
                        currentGroup.Add(item);
                    }
                }
            }

            void IncrementGroup()
            {
                if (currentGroup.Count > 0)
                {
                    result.Add(currentGroup);
                    currentGroup = new List <Element>();
                }
            }
        }
Example #6
0
        static void SearchPath(
            object node,
            RouteRequestBuilder currentMatchedPath,
            string[] segments,
            List <RouteRequestBuilder> possibleRoutePaths,
            int depthToStart,
            int myDepth = -1,
            NodeLocation currentLocation = null,
            bool ignoreGlobalRoutes      = true)
        {
            if (node is GlobalRouteItem && ignoreGlobalRoutes)
            {
                return;
            }

            ++myDepth;
            currentLocation = currentLocation ?? new NodeLocation();
            currentLocation.SetNode(node);

            IEnumerable items = null;

            if (depthToStart > myDepth)
            {
                items = GetItems(node);
                if (items == null)
                {
                    return;
                }

                foreach (var nextNode in items)
                {
                    SearchPath(nextNode, null, segments, possibleRoutePaths, depthToStart, myDepth, currentLocation, ignoreGlobalRoutes);
                }
                return;
            }

            string shellSegment = GetRoute(node);
            string userSegment  = null;

            if (currentMatchedPath == null)
            {
                userSegment = segments[0];
            }
            else
            {
                userSegment = currentMatchedPath.NextSegment;
            }

            if (userSegment == null)
            {
                return;
            }

            RouteRequestBuilder builder = null;

            if (shellSegment == userSegment || Routing.IsImplicit(shellSegment))
            {
                if (currentMatchedPath == null)
                {
                    builder = new RouteRequestBuilder(shellSegment, userSegment, node, segments);
                }
                else
                {
                    builder = new RouteRequestBuilder(currentMatchedPath);
                    builder.AddMatch(shellSegment, userSegment, node);
                }

                if (!Routing.IsImplicit(shellSegment) || shellSegment == userSegment)
                {
                    possibleRoutePaths.Add(builder);
                }
            }

            items = GetItems(node);
            if (items == null)
            {
                return;
            }

            foreach (var nextNode in items)
            {
                SearchPath(nextNode, builder, segments, possibleRoutePaths, depthToStart, myDepth, currentLocation, ignoreGlobalRoutes);
            }
        }