Пример #1
0
        void ArrangeSlot(SlotData slotData, Point upperLeft, Size finalSize)
        {
            UVHelper uv = UVHelper.CreateInstance(slotData.Slot.Orientation);
            Point    runningUpperLeft = upperLeft;
            double   maxU             = uv.U(runningUpperLeft) + uv.U(finalSize);
            bool     addSizer         = false;
            Slot     previousSlot     = null;

            foreach (var child in slotData.Slot.Children)
            {
                if (addSizer)
                {
                    SlotSizer sizer = GetNextSizer();
                    sizer.SizeDirection = slotData.Slot.Orientation;
                    sizer.Slot1         = previousSlot;
                    sizer.Slot2         = child;
                    sizer.Measure(uv.Size(SlotSpacing, uv.V(finalSize)));
                    sizer.Arrange(new Rect(uv.Point(uv.U(runningUpperLeft), uv.V(runningUpperLeft)), uv.Size(SlotSpacing, uv.V(finalSize))));
                    runningUpperLeft = uv.Point(Math.Min(maxU, uv.U(runningUpperLeft) + SlotSpacing), uv.V(runningUpperLeft));
                }

                var childSlot      = slotTable[InternalGetSlotName(child)];
                var childFinalSize = uv.Size(Math.Min(uv.U(finalSize), uv.U(childSlot.FinalSize)), uv.V(finalSize));

                ArrangeSlot(childSlot, runningUpperLeft, childFinalSize);
                runningUpperLeft = uv.Point(Math.Min(maxU, uv.U(runningUpperLeft) + uv.U(childFinalSize)), uv.V(runningUpperLeft));
                addSizer         = (SlotSpacing > 0);
                previousSlot     = child;
            }

            if (slotData.Elements != null)
            {
                foreach (UIElement element in slotData.Elements)
                {
                    element.Arrange(new Rect(upperLeft, finalSize));
                }
            }

            slotData.Slot.ActualSize = finalSize;
            slotData.Slot.UpperLeft  = upperLeft;
        }
Пример #2
0
        void MeasureSlot(SlotData slotData, Size availableSize)
        {
            UVHelper uv = UVHelper.CreateInstance(slotData.Slot.Orientation);

            // Measure all 'auto' and 'absolute' children; add up the * values as we go.
            double totalU = 0, maxV = 0;
            double totalStars = 0;
            bool   addPad     = false;

            foreach (var child in slotData.Slot.Children)
            {
                var length    = child.Length;
                var childSlot = slotTable[InternalGetSlotName(child)];

                if (addPad)
                {
                    totalU += SlotSpacing;
                }

                if (length.IsAuto)
                {
                    var childU             = Math.Max(Math.Min(uv.U(availableSize), childSlot.Slot.MaxLength), childSlot.Slot.MinLength);
                    var childAvailableSize = uv.Size(childU, uv.V(availableSize));
                    MeasureSlot(childSlot, childAvailableSize);
                    childSlot.FinalSize = childSlot.DesiredSize;
                    totalU += uv.U(childSlot.FinalSize);
                    maxV    = Math.Max(maxV, uv.V(childSlot.FinalSize));
                }
                else if (length.IsAbsolute)
                {
                    var childU = Math.Max(Math.Min(length.Value, childSlot.Slot.MaxLength), childSlot.Slot.MinLength);
                    MeasureSlot(childSlot, uv.Size(childU, uv.V(availableSize)));
                    childSlot.FinalSize = uv.Size(childU, uv.V(childSlot.DesiredSize));
                    totalU += childU;
                    maxV    = Math.Max(maxV, uv.V(childSlot.FinalSize));
                }
                else
                {
                    totalStars += length.Value;
                }

                addPad = (SlotSpacing > 0);
            }

            // Now measure the * values.
            double spaceLeft = Math.Max(uv.U(availableSize) - totalU, 0);

            List <Slot> slots        = (from child in slotData.Slot.Children where child.Length.IsStar select child).ToList();
            List <Slot> proportional = new List <Slot>();

            // Determined the size for stars that are over the min or max length
            int constrained;

            do
            {
                constrained = 0;

                for (int idx = 0; idx < slots.Count; idx++)
                {
                    Slot child     = slots[idx];
                    var  childSlot = slotTable[InternalGetSlotName(child)];
                    var  childU    = (spaceLeft / totalStars) * child.Length.Value;

                    if (childU < childSlot.Slot.MinLength)
                    {
                        spaceLeft -= childSlot.Slot.MinLength - childU;
                        childU     = childSlot.Slot.MinLength;
                    }
                    else if (childU > childSlot.Slot.MaxLength)
                    {
                        spaceLeft += childSlot.Slot.MaxLength - childU;
                        childU     = childSlot.Slot.MaxLength;
                    }
                    else
                    {
                        proportional.Add(child);
                        continue;
                    }

                    constrained++;
                    var childAvailableSize = uv.Size(Math.Max(0, childU), uv.V(availableSize));
                    MeasureSlot(childSlot, childAvailableSize);
                    childSlot.FinalSize = uv.Size(MaxNonInfinite(childU, uv.U(childSlot.DesiredSize)), uv.V(childSlot.DesiredSize));
                    totalU += uv.U(childSlot.FinalSize);
                    maxV    = Math.Max(maxV, uv.V(childSlot.FinalSize));
                }

                slots        = proportional;
                proportional = new List <Slot>();
            } while (slots.Count > 0 && constrained > 0);

            // Determine the size of remaining star children
            foreach (var child in slots)
            {
                var childSlot          = slotTable[InternalGetSlotName(child)];
                var childU             = (spaceLeft / totalStars) * child.Length.Value;
                var childAvailableSize = uv.Size(Math.Max(0, childU), uv.V(availableSize));
                MeasureSlot(childSlot, childAvailableSize);
                childSlot.FinalSize = uv.Size(MaxNonInfinite(childU, uv.U(childSlot.DesiredSize)), uv.V(childSlot.DesiredSize));
                totalU += uv.U(childSlot.FinalSize);
                maxV    = Math.Max(maxV, uv.V(childSlot.FinalSize));
            }

            // Finally, measure any child elements we have
            if (slotData.Elements != null)
            {
                foreach (var e in slotData.Elements)
                {
                    e.Measure(availableSize);
                    totalU = Math.Max(totalU, uv.U(e.DesiredSize));
                    maxV   = Math.Max(maxV, uv.V(e.DesiredSize));
                }
            }

            slotData.DesiredSize = uv.Size(totalU, maxV);
        }