private Size StarMeasurePass(Size availableSize)
        {
            Size originalDesiredSize     = DesiredSize;
            UIElementCollection children = InternalChildren;
            int childCount = children.Count;
            int starLayoutCombinationCount = _starLayoutCombinations.Count;

            for (int i = 0; i < childCount; i++)
            {
                UIElement child = children[i];
                if (IsStarChild(child))
                {
                    if (_childIndexToStarLayoutIndexMap.ContainsKey(i))
                    {
                        int starLayoutIndex = _childIndexToStarLayoutIndexMap[i];
                        if (starLayoutIndex < starLayoutCombinationCount)
                        {
                            StarLayoutInfo starLayoutInfo = _starLayoutCombinations[starLayoutIndex];
                            child.Measure(new Size(starLayoutInfo.AllocatedStarWidth, availableSize.Height));
                        }
                    }
                }
            }

            double desiredWidth = originalDesiredSize.Width;

            AdjustDesiredWidthForStars(children, ref desiredWidth);

            return(new Size(desiredWidth, originalDesiredSize.Height));
        }
        private void CreateStarLayoutCombination(Size constraint,
                                                 double starWeight,
                                                 double starMinWidth,
                                                 double starMaxWidth,
                                                 List <int> starChildIndices)
        {
            if (starChildIndices.Count > 0)
            {
                StarLayoutInfo starLayoutInfo = new StarLayoutInfo()
                {
                    RequestedStarMinWidth = starMinWidth,
                    RequestedStarMaxWidth = starMaxWidth,
                    RequestedStarWeight   = starWeight
                };
                _starLayoutCombinations.Add(starLayoutInfo);

                UIElementCollection children = InternalChildren;
                int starLayoutIndex          = _starLayoutCombinations.Count - 1;
                foreach (int starChildIndex in starChildIndices)
                {
                    _childIndexToStarLayoutIndexMap[starChildIndex] = starLayoutIndex;
                    children[starChildIndex].Measure(new Size(starLayoutInfo.RequestedStarMinWidth, constraint.Height));
                }
                starChildIndices.Clear();
            }
        }
예제 #3
0
        /// <summary>
        ///     Distributes the remaining space after step 1 equally among all the
        ///     qualified member, such that they are constrained by their min/max constraints
        ///     maintaining (but not necessarily attaining) the goal of making perstarvalue of
        ///     all the elements as equal as possible.
        /// </summary>
        private static void DistributeRemainingSpace(List <StarLayoutInfo> starInfoList,
                                                     int distributionCount,
                                                     ref double remainingSpace)
        {
            Debug.Assert(distributionCount > 0 && distributionCount <= starInfoList.Count);
            Debug.Assert(DoubleUtil.GreaterThan(remainingSpace, 0));

            double remainingStarWeight = 0;

            for (int i = 0; i < distributionCount; i++)
            {
                remainingStarWeight += starInfoList[i].RequestedStarWeight;
            }

            double impactPerStar = 0;

            for (int i = 0; i < distributionCount; i++)
            {
                StarLayoutInfo starInfo = starInfoList[i];
                if (DoubleUtil.GreaterThan(remainingSpace, 0))
                {
                    double currentContribution = starInfo.RequestedStarMaxWidth - starInfo.AllocatedStarWidth;
                    currentContribution -= (impactPerStar * starInfo.RequestedStarWeight);
                    currentContribution /= starInfo.RequestedStarWeight;
                    if (DoubleUtil.GreaterThan(currentContribution * remainingStarWeight, remainingSpace))
                    {
                        currentContribution = remainingSpace / remainingStarWeight;
                    }
                    impactPerStar  += currentContribution;
                    remainingSpace -= (currentContribution * remainingStarWeight);
                }
                starInfo.AllocatedStarWidth += (impactPerStar * starInfo.RequestedStarWeight);
                remainingStarWeight         -= starInfo.RequestedStarWeight;
            }
        }
        protected override Size ArrangeOverride(Size finalSize)
        {
            UIElementCollection children   = InternalChildren;
            int    childCount              = children.Count;
            double remainingHeightInColumn = finalSize.Height;
            double columnWidth             = 0;
            double currentX = 0;
            double starLayoutCombinationCount = _starLayoutCombinations.Count;

            for (int i = 0; i < childCount; i++)
            {
                UIElement child            = children[i];
                Size      childDesiredSize = child.DesiredSize;
                if (DoubleUtil.GreaterThan(childDesiredSize.Height, remainingHeightInColumn))
                {
                    currentX   += columnWidth;
                    columnWidth = childDesiredSize.Width;
                    if (IsStarChild(child))
                    {
                        if (_childIndexToStarLayoutIndexMap.ContainsKey(i))
                        {
                            int starLayoutIndex = _childIndexToStarLayoutIndexMap[i];
                            if (starLayoutIndex < starLayoutCombinationCount)
                            {
                                StarLayoutInfo starLayoutInfo = _starLayoutCombinations[starLayoutIndex];
                                columnWidth = starLayoutInfo.AllocatedStarWidth;
                            }
                        }
                    }
                    child.Arrange(new Rect(currentX, 0, columnWidth, childDesiredSize.Height));
                    remainingHeightInColumn = Math.Max(0, finalSize.Height - childDesiredSize.Height);
                }
                else
                {
                    double arrangeWidth = child.DesiredSize.Width;
                    if (IsStarChild(child))
                    {
                        if (_childIndexToStarLayoutIndexMap.ContainsKey(i))
                        {
                            int starLayoutIndex = _childIndexToStarLayoutIndexMap[i];
                            if (starLayoutIndex < starLayoutCombinationCount)
                            {
                                if (CanChildStretch(child))
                                {
                                    // If the child's HorizontalAlignment is Left/Right, then
                                    // use its desired width as arrange width.
                                    StarLayoutInfo starLayoutInfo = _starLayoutCombinations[starLayoutIndex];
                                    arrangeWidth = starLayoutInfo.AllocatedStarWidth;
                                }
                            }
                        }
                    }
                    columnWidth = Math.Max(columnWidth, arrangeWidth);
                    child.Arrange(new Rect(currentX, (finalSize.Height - remainingHeightInColumn), arrangeWidth, childDesiredSize.Height));
                    remainingHeightInColumn -= childDesiredSize.Height;
                }
            }
            return(finalSize);
        }
예제 #5
0
        private static object OnCoerceAllocatedStarWidth(DependencyObject d, object baseValue)
        {
            double         allocatedWidth = (double)baseValue;
            StarLayoutInfo layoutInfo     = (StarLayoutInfo)d;

            if (DoubleUtil.LessThan(allocatedWidth, layoutInfo.RequestedStarMinWidth))
            {
                return(layoutInfo.RequestedStarMinWidth);
            }
            return(baseValue);
        }
예제 #6
0
        private static object OnCoerceRequestedStarMaxWidth(DependencyObject d, object baseValue)
        {
            double         maxWidth       = (double)baseValue;
            StarLayoutInfo starLayoutInfo = (StarLayoutInfo)d;
            double         minWidth       = starLayoutInfo.RequestedStarMinWidth;

            if (DoubleUtil.LessThan(maxWidth, minWidth))
            {
                return(minWidth);
            }
            return(baseValue);
        }
예제 #7
0
        private static double EqualizeLeftOf(List <StarLayoutInfo> starInfoList, int index, bool isChecking)
        {
            Debug.Assert(index >= 0 && index < starInfoList.Count);
            double         spaceNeeded  = 0;
            StarLayoutInfo baseStarInfo = starInfoList[index];
            double         basePerStar  = baseStarInfo.AllocatedStarWidth / baseStarInfo.RequestedStarWeight;

            for (int i = 0; i < index; i++)
            {
                StarLayoutInfo starInfo    = starInfoList[i];
                double         targetValue = Math.Min(basePerStar * starInfo.RequestedStarWeight, starInfo.RequestedStarMaxWidth);
                spaceNeeded += (targetValue - starInfo.AllocatedStarWidth);
                if (!isChecking)
                {
                    starInfo.AllocatedStarWidth = targetValue;
                }
            }
            return(spaceNeeded);
        }
 /// <summary>
 ///     Adjust the desired width for all the star
 ///     based children in a column based upon their
 ///     allocated/desired width.
 /// </summary>
 private void AdjustDesiredWidthForStarColumn(UIElementCollection children, List <int> columnStarChildren, int starLayoutIndex, ref double desiredWidth)
 {
     if (columnStarChildren != null && columnStarChildren.Count > 0 && starLayoutIndex >= 0)
     {
         bool   foundStretchableStar = false;
         double columnDesiredWidth   = 0;
         foreach (int columnChildIndex in columnStarChildren)
         {
             UIElement child = children[columnChildIndex];
             if (CanChildStretch(child))
             {
                 foundStretchableStar = true;
                 break;
             }
             else
             {
                 columnDesiredWidth = Math.Max(columnDesiredWidth, child.DesiredSize.Width);
             }
         }
         if (foundStretchableStar)
         {
             // if there are any non-item based star children
             // then desired width should be equal to that of
             // allocated width.
             StarLayoutInfo starLayoutInfo = _starLayoutCombinations[starLayoutIndex];
             desiredWidth += (starLayoutInfo.AllocatedStarWidth - starLayoutInfo.RequestedStarMinWidth);
         }
         else
         {
             // if there are no non-item based star children
             // then desired width should be equal to that of
             // computed desired width.
             StarLayoutInfo starLayoutInfo = _starLayoutCombinations[starLayoutIndex];
             desiredWidth += Math.Max((columnDesiredWidth - starLayoutInfo.RequestedStarMinWidth), 0);
         }
         columnStarChildren.Clear();
     }
 }