Beispiel #1
0
            /// <summary>
            /// Prioritizes elements for layouting.  First treat the entrypoints, starting from top-left then around.
            /// Then select the ones with dependencies that are already laid out.
            /// </summary>
            /// <param name="cluster"></param>
            /// <returns></returns>
            private IFrameworkElement[] OrderClusterForLayouting(List <Sibling> cluster)
            {
                // Give weight to panel alignments.  Weight 3 for top or left so that a left-aligned only
                // element (3) has precedence over a bottom-right aligned element (1+1)
                var orderedByAlignment = new List <Sibling>(cluster
                                                            .OrderByDescending(s =>
                                                                               (IsAlignLeftWithPanel(s.Element) ? 3 : 0) +
                                                                               (IsAlignTopWithPanel(s.Element) ? 3 : 0) +
                                                                               (RelativePanel.GetAlignRightWithPanel(s.Element) ? 1 : 0) +
                                                                               (RelativePanel.GetAlignBottomWithPanel(s.Element) ? 1 : 0)
                                                                               )
                                                            );

                var ordered = new List <Sibling>();

                while (orderedByAlignment.Count != 0)
                {
                    // Take the first item in the previous list that has no direct dependency that have not already been selected
                    var next = orderedByAlignment.First(s => s.Dependencies
                                                        .Where(sd => !sd.IsInferred)
                                                        .Select(sd => sd.Sibling)
                                                        .Except(ordered)
                                                        .Empty()
                                                        );

                    orderedByAlignment.Remove(next);
                    ordered.Add(next);
                }

                return(ordered
                       .SelectToArray(s => s.Element));
            }
Beispiel #2
0
 /// <summary>
 /// Returns true if the child is top aligned with Panel or has no vertical alignment instructions
 /// </summary>
 private bool IsAlignTopWithPanel(IFrameworkElement child)
 {
     return(RelativePanel.GetAlignTopWithPanel(child) ||
            !(
                RelativePanel.GetAlignBottomWithPanel(child) ||
                RelativePanel.GetAlignVerticalCenterWithPanel(child) ||
                RelativePanel.GetAlignTopWith(child) != null ||
                RelativePanel.GetAlignBottomWith(child) != null ||
                RelativePanel.GetAbove(child) != null ||
                RelativePanel.GetBelow(child) != null
                ));
 }
Beispiel #3
0
 /// <summary>
 /// Returns true if the child is left aligned with Panel or has no horizontal alignment instructions
 /// </summary>
 private bool IsAlignLeftWithPanel(IFrameworkElement child)
 {
     return(RelativePanel.GetAlignLeftWithPanel(child) ||
            !(
                RelativePanel.GetAlignRightWithPanel(child) ||
                RelativePanel.GetAlignHorizontalCenterWithPanel(child) ||
                RelativePanel.GetAlignLeftWith(child) != null ||
                RelativePanel.GetAlignRightWith(child) != null ||
                RelativePanel.GetRightOf(child) != null ||
                RelativePanel.GetLeftOf(child) != null
                ));
 }
Beispiel #4
0
            /// <summary>
            /// Checks if the given FrameworkElement has any dependencies that would provide a bottom boundary using the existing layout info
            /// </summary>
            private double ComputeChildBottomBound(
                IFrameworkElement child,
                Size availableSize,
                Dictionary <IFrameworkElement, SiblingLayoutInfo> siblingLayoutInfos,
                double childTop,
                Thickness graphPadding,
                bool useInferred = false
                )
            {
                var above = GetAvailableDependencies(GetSibling(child), DependencyType.Above, useInferred, siblingLayoutInfos);

                if (above.Length != 0)
                {
                    ExecuteOnSiblingLayoutInfoIfAvailable(child, siblingLayoutInfos, sli => sli.IsBottomBound = !useInferred);
                    return(above.Min(d => siblingLayoutInfos[d.Sibling.Element].Area.Top));
                }

                var bottomAlign = GetAvailableDependencies(GetSibling(child), DependencyType.AlignBottomWith, useInferred, siblingLayoutInfos);

                if (bottomAlign.Length != 0)
                {
                    ExecuteOnSiblingLayoutInfoIfAvailable(child, siblingLayoutInfos, sli => sli.IsBottomBound = !useInferred);
                    return(bottomAlign.Min(d => siblingLayoutInfos[d.Sibling.Element].Area.Bottom));
                }

                if (RelativePanel.GetAlignBottomWithPanel(child))
                {
                    ExecuteOnSiblingLayoutInfoIfAvailable(child, siblingLayoutInfos, sli => sli.IsBottomBound = true);
                    return(availableSize.Height - graphPadding.Bottom);
                }

                if (!useInferred)
                {
                    ComputeChildBottomBound(child, availableSize, siblingLayoutInfos, childTop, graphPadding, true);
                }

                // If there is no dependency, base yourself off of the available height, margins and Height/Min/Max properties
                var spacing = childTop + child.Margin.Top + child.Margin.Bottom;

                return(double.IsNaN(child.Height) ?
                       Math.Max(
                           Math.Min(
                               availableSize.Height - graphPadding.Bottom,
                               child.MaxHeight + spacing
                               ),
                           child.MinHeight + spacing
                           ) :
                       child.Height + spacing);
            }
Beispiel #5
0
            /// <summary>
            /// Checks if the given FrameworkElement has any dependencies that would provide a right boundary using the existing layout info
            /// </summary>
            private double ComputeChildRightBound(
                IFrameworkElement child,
                Size availableSize,
                Dictionary <IFrameworkElement, SiblingLayoutInfo> siblingLayoutInfos,
                double childLeft,
                Thickness graphPadding,
                bool useInferred = false
                )
            {
                var leftOf = GetAvailableDependencies(GetSibling(child), DependencyType.LeftOf, useInferred, siblingLayoutInfos);

                if (leftOf.Length != 0)
                {
                    ExecuteOnSiblingLayoutInfoIfAvailable(child, siblingLayoutInfos, sli => sli.IsRightBound = !useInferred);
                    return(leftOf.Min(d => siblingLayoutInfos[d.Sibling.Element].Area.Left));
                }

                var rightAlign = GetAvailableDependencies(GetSibling(child), DependencyType.AlignRightWith, useInferred, siblingLayoutInfos);

                if (rightAlign.Length != 0)
                {
                    ExecuteOnSiblingLayoutInfoIfAvailable(child, siblingLayoutInfos, sli => sli.IsRightBound = !useInferred);
                    return(rightAlign.Min(d => siblingLayoutInfos[d.Sibling.Element].Area.Right));
                }

                if (RelativePanel.GetAlignRightWithPanel(child))
                {
                    ExecuteOnSiblingLayoutInfoIfAvailable(child, siblingLayoutInfos, sli => sli.IsRightBound = true);
                    return(availableSize.Width - graphPadding.Right);
                }

                if (!useInferred)
                {
                    return(ComputeChildRightBound(child, availableSize, siblingLayoutInfos, childLeft, graphPadding, true));
                }

                // If there is no dependency, base yourself off of the available width, margins and Width/Min/Max properties
                var spacing = childLeft + child.Margin.Left + child.Margin.Right;

                return(double.IsNaN(child.Width) ?
                       Math.Max(
                           Math.Min(
                               availableSize.Width - graphPadding.Right,
                               child.MaxWidth + spacing
                               ),
                           child.MinWidth + spacing
                           ) :
                       child.Width + spacing);
            }
Beispiel #6
0
            /// <summary>
            /// Makes sure dependencies in the cluster are reversed if they are based on unknown boundaries
            /// </summary>
            private void CleanupDependencies(List <Sibling> cluster, bool isHorizontallyInfinite, bool isVerticallyInfinite)
            {
                if (!isHorizontallyInfinite && !isVerticallyInfinite)
                {
                    return;
                }

                foreach (var sibling in cluster)
                {
                    if (isHorizontallyInfinite && RelativePanel.GetAlignRightWithPanel(sibling.Element))
                    {
                        ReverseDependencies(sibling, true);
                    }

                    if (isVerticallyInfinite && RelativePanel.GetAlignBottomWithPanel(sibling.Element))
                    {
                        ReverseDependencies(sibling, false);
                    }
                }
            }
Beispiel #7
0
        protected override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            //Single click/tap on header
            relMainPanel = (Windows.UI.Xaml.Controls.RelativePanel)GetTemplateChild("HeaderPanel");
            if (relMainPanel != null)
            {
                relMainPanel.Tapped += (object sender, TappedRoutedEventArgs e) =>
                {
                    if (!headerToolContentTapped)
                    {
                        IsExpanded = !IsExpanded;
                        setExpandState(IsExpanded);
                    }
                    else
                    {
                        headerToolContentTapped = !headerToolContentTapped;
                    }
                };
            }

            //Single click/tap on header
            headerToolContent = (Windows.UI.Xaml.Controls.ContentPresenter)GetTemplateChild("HeaderToolContent");
            if (headerToolContent != null)
            {
                headerToolContent.Tapped += (object sender, TappedRoutedEventArgs e) =>
                {
                    headerToolContentTapped = true;
                };
            }

            //Toggle button
            toggleExpander = (Windows.UI.Xaml.Controls.Primitives.ToggleButton)GetTemplateChild("ExpandCollapseButton");
            if (toggleExpander != null)
            {
                toggleExpander.Click += (object sender, RoutedEventArgs e) =>
                {
                    IsExpanded = !IsExpanded;
                    setExpandState(IsExpanded);
                    //IsExpanded = !IsExpanded;
                    //toggleExpander.IsChecked = IsExpanded;
                    //changeVisualState(_useTransitions);
                };
            }

            //Fill with content
            contentElement = (FrameworkElement)GetTemplateChild("Content");
            if (contentElement != null)
            {
                _collapsedState = (VisualState)GetTemplateChild("Collapsed");
                if ((_collapsedState != null) && (_collapsedState.Storyboard != null))
                {
                    _collapsedState.Storyboard.Completed += (object sender, object e) =>
                    {
                        contentElement.Visibility = Visibility.Collapsed;
                    };
                }
            }
            changeVisualState(false);
        }
        /// <summary>
        /// Gets all the direct dependencies of a FrameworkElement (based on the set AttachedProperties)
        /// </summary>
        private Dependency[] GetDependencies(UIElement child, IFrameworkElement[] allChildren)
        {
            var dependencies = new List <Dependency>(Dependency.DependencyTypeCount);

            IFrameworkElement element;

            element = GetChild(RelativePanel.GetAbove(child), allChildren);
            if (element != null)
            {
                dependencies.Add(new Dependency(element, DependencyType.Above));
            }

            element = GetChild(RelativePanel.GetBelow(child), allChildren);
            if (element != null)
            {
                dependencies.Add(new Dependency(element, DependencyType.Below));
            }

            element = GetChild(RelativePanel.GetLeftOf(child), allChildren);
            if (element != null)
            {
                dependencies.Add(new Dependency(element, DependencyType.LeftOf));
            }

            element = GetChild(RelativePanel.GetRightOf(child), allChildren);
            if (element != null)
            {
                dependencies.Add(new Dependency(element, DependencyType.RightOf));
            }

            element = GetChild(RelativePanel.GetAlignBottomWith(child), allChildren);
            if (element != null)
            {
                dependencies.Add(new Dependency(element, DependencyType.AlignBottomWith));
            }

            element = GetChild(RelativePanel.GetAlignHorizontalCenterWith(child), allChildren);
            if (element != null)
            {
                dependencies.Add(new Dependency(element, DependencyType.AlignHorizontalCenterWith));
            }

            element = GetChild(RelativePanel.GetAlignLeftWith(child), allChildren);
            if (element != null)
            {
                dependencies.Add(new Dependency(element, DependencyType.AlignLeftWith));
            }

            element = GetChild(RelativePanel.GetAlignRightWith(child), allChildren);
            if (element != null)
            {
                dependencies.Add(new Dependency(element, DependencyType.AlignRightWith));
            }

            element = GetChild(RelativePanel.GetAlignTopWith(child), allChildren);
            if (element != null)
            {
                dependencies.Add(new Dependency(element, DependencyType.AlignTopWith));
            }

            element = GetChild(RelativePanel.GetAlignVerticalCenterWith(child), allChildren);
            if (element != null)
            {
                dependencies.Add(new Dependency(element, DependencyType.AlignVerticalCenterWith));
            }

            return(dependencies.ToArray());
        }