Exemple #1
0
        public static void SetDock(IArrangedElement element, DockStyle value)
        {
            Debug.Assert(!HasCachedBounds(element.Container), "Do not call this method with an active cached bounds list.");

            if (GetDock(element) != value)
            {
                SourceGenerated.EnumValidator.Validate(value);

                bool dockNeedsLayout = CommonProperties.GetNeedsDockLayout(element);
                CommonProperties.xSetDock(element, value);

                using (new LayoutTransaction(element.Container as Control, element, PropertyNames.Dock))
                {
                    // if the item is autosized, calling setbounds performs a layout, which
                    // if we havent set the anchor info properly yet makes dock/anchor layout cranky.
                    if (value == DockStyle.None)
                    {
                        if (dockNeedsLayout)
                        {
                            // We are transitioning from docked to not docked, restore the original bounds.
                            element.SetBounds(CommonProperties.GetSpecifiedBounds(element), BoundsSpecified.None);
                            // Restore Anchor information as its now relevant again.
                            UpdateAnchorInfo(element);
                        }
                    }
                    else
                    {
                        // Now setup the new bounds.
                        element.SetBounds(CommonProperties.GetSpecifiedBounds(element), BoundsSpecified.All);
                    }
                }
            }

            Debug.Assert(GetDock(element) == value, "Error setting Dock value.");
        }
 public static void SetDock(IArrangedElement element, DockStyle value)
 {
     if (GetDock(element) != value)
     {
         if (!System.Windows.Forms.ClientUtils.IsEnumValid(value, (int)value, 0, 5))
         {
             throw new InvalidEnumArgumentException("value", (int)value, typeof(DockStyle));
         }
         bool needsDockLayout = CommonProperties.GetNeedsDockLayout(element);
         CommonProperties.xSetDock(element, value);
         using (new LayoutTransaction(element.Container as Control, element, PropertyNames.Dock))
         {
             if (value == DockStyle.None)
             {
                 if (needsDockLayout)
                 {
                     element.SetBounds(CommonProperties.GetSpecifiedBounds(element), BoundsSpecified.None);
                     UpdateAnchorInfo(element);
                 }
             }
             else
             {
                 element.SetBounds(CommonProperties.GetSpecifiedBounds(element), BoundsSpecified.All);
             }
         }
     }
 }
        public static void SetAnchor(IArrangedElement container, IArrangedElement element, AnchorStyles value)
        {
            AnchorStyles anchor = GetAnchor(element);

            if (anchor != value)
            {
                if (CommonProperties.GetNeedsDockLayout(element))
                {
                    SetDock(element, DockStyle.None);
                }
                CommonProperties.xSetAnchor(element, value);
                if (CommonProperties.GetNeedsAnchorLayout(element))
                {
                    UpdateAnchorInfo(element);
                }
                else
                {
                    SetAnchorInfo(element, null);
                }
                if (element.Container != null)
                {
                    bool flag  = IsAnchored(anchor, AnchorStyles.Right) && !IsAnchored(value, AnchorStyles.Right);
                    bool flag2 = IsAnchored(anchor, AnchorStyles.Bottom) && !IsAnchored(value, AnchorStyles.Bottom);
                    if ((element.Container.Container != null) && (flag | flag2))
                    {
                        LayoutTransaction.DoLayout(element.Container.Container, element, PropertyNames.Anchor);
                    }
                    LayoutTransaction.DoLayout(element.Container, element, PropertyNames.Anchor);
                }
            }
        }
        private static Size GetAnchorPreferredSize(IArrangedElement container)
        {
            Size empty = Size.Empty;

            for (int i = container.Children.Count - 1; i >= 0; i--)
            {
                IArrangedElement element = container.Children[i];
                if (!CommonProperties.GetNeedsDockLayout(element) && element.ParticipatesInLayout)
                {
                    AnchorStyles anchor    = GetAnchor(element);
                    Padding      margin    = CommonProperties.GetMargin(element);
                    Rectangle    rectangle = LayoutUtils.InflateRect(GetCachedBounds(element), margin);
                    if (IsAnchored(anchor, AnchorStyles.Left) && !IsAnchored(anchor, AnchorStyles.Right))
                    {
                        empty.Width = Math.Max(empty.Width, rectangle.Right);
                    }
                    if (!IsAnchored(anchor, AnchorStyles.Bottom))
                    {
                        empty.Height = Math.Max(empty.Height, rectangle.Bottom);
                    }
                    if (IsAnchored(anchor, AnchorStyles.Right))
                    {
                        Rectangle rectangle2 = GetAnchorDestination(element, Rectangle.Empty, true);
                        if (rectangle2.Width < 0)
                        {
                            empty.Width = Math.Max(empty.Width, rectangle.Right + rectangle2.Width);
                        }
                        else
                        {
                            empty.Width = Math.Max(empty.Width, rectangle2.Right);
                        }
                    }
                    if (IsAnchored(anchor, AnchorStyles.Bottom))
                    {
                        Rectangle rectangle3 = GetAnchorDestination(element, Rectangle.Empty, true);
                        if (rectangle3.Height < 0)
                        {
                            empty.Height = Math.Max(empty.Height, rectangle.Bottom + rectangle3.Height);
                        }
                        else
                        {
                            empty.Height = Math.Max(empty.Height, rectangle3.Bottom);
                        }
                    }
                }
            }
            return(empty);
        }
Exemple #5
0
        public static void SetAnchor(IArrangedElement element, AnchorStyles value)
        {
            AnchorStyles oldValue = GetAnchor(element);

            if (oldValue != value)
            {
                if (CommonProperties.GetNeedsDockLayout(element))
                {
                    // We set dock back to none to cause the element to size back to its original bounds.
                    SetDock(element, DockStyle.None);
                }

                CommonProperties.xSetAnchor(element, value);

                // Updating AnchorInfo is only needed when control is ready for layout. Oneway to check this precondition is to
                // check if the control is parented. This helps avoid calculating AnchorInfo with default initial values of the Control.
                // AnchorInfo is recalculated everytime there is a layout change.
                if (CommonProperties.GetNeedsAnchorLayout(element) && element is Control control && control.Parent is not null)
                {
                    UpdateAnchorInfo(element);
                }
                else
                {
                    SetAnchorInfo(element, null);
                }

                if (element.Container is not null)
                {
                    bool rightReleased  = IsAnchored(oldValue, AnchorStyles.Right) && !IsAnchored(value, AnchorStyles.Right);
                    bool bottomReleased = IsAnchored(oldValue, AnchorStyles.Bottom) && !IsAnchored(value, AnchorStyles.Bottom);
                    if (element.Container.Container is not null && (rightReleased || bottomReleased))
                    {
                        // If the right or bottom anchor is being released, we have a special case where the element's
                        // margin may affect preferredSize where it didn't previously. Rather than do an expensive
                        // check for this in OnLayout, we just detect the case her and force a relayout.
                        LayoutTransaction.DoLayout(element.Container.Container, element, PropertyNames.Anchor);
                    }

                    LayoutTransaction.DoLayout(element.Container, element, PropertyNames.Anchor);
                }
            }
Exemple #6
0
        public static void SetAnchor(IArrangedElement container, IArrangedElement element, AnchorStyles value)
        {
            AnchorStyles oldValue = GetAnchor(element);

            if (oldValue != value)
            {
                if (CommonProperties.GetNeedsDockLayout(element))
                {
                    // We set dock back to none to cause the element to size back to its original bounds.
                    SetDock(element, DockStyle.None);
                }

                CommonProperties.xSetAnchor(element, value);

                if (CommonProperties.GetNeedsAnchorLayout(element))
                {
                    UpdateAnchorInfo(element);
                }
                else
                {
                    SetAnchorInfo(element, null);
                }

                if (element.Container != null)
                {
                    bool rightReleased  = IsAnchored(oldValue, AnchorStyles.Right) && !IsAnchored(value, AnchorStyles.Right);
                    bool bottomReleased = IsAnchored(oldValue, AnchorStyles.Bottom) && !IsAnchored(value, AnchorStyles.Bottom);
                    if (element.Container.Container != null && (rightReleased || bottomReleased))
                    {
                        // If the right or bottom anchor is being released, we have a special case where the element's
                        // margin may affect preferredSize where it didn't previously. Rather than do an expensive
                        // check for this in OnLayout, we just detect the case her and force a relayout.
                        LayoutTransaction.DoLayout(element.Container.Container, element, PropertyNames.Anchor);
                    }

                    LayoutTransaction.DoLayout(element.Container, element, PropertyNames.Anchor);
                }
            }
        }
Exemple #7
0
        private static Size GetAnchorPreferredSize(IArrangedElement container)
        {
            Size prefSize = Size.Empty;

            ArrangedElementCollection children = container.Children;

            for (int i = children.Count - 1; i >= 0; i--)
            {
                IArrangedElement element = container.Children[i];
                if (!CommonProperties.GetNeedsDockLayout(element) && element.ParticipatesInLayout)
                {
                    AnchorStyles anchor       = GetAnchor(element);
                    Padding      margin       = CommonProperties.GetMargin(element);
                    Rectangle    elementSpace = LayoutUtils.InflateRect(GetCachedBounds(element), margin);

                    if (IsAnchored(anchor, AnchorStyles.Left) && !IsAnchored(anchor, AnchorStyles.Right))
                    {
                        // If we are anchored to the left we make sure the container is large enough not to clip us
                        // (unless we are right anchored, in which case growing the container will just resize us.)
                        prefSize.Width = Math.Max(prefSize.Width, elementSpace.Right);
                    }

                    if (!IsAnchored(anchor, AnchorStyles.Bottom))
                    {
                        // If we are anchored to the top we make sure the container is large enough not to clip us
                        // (unless we are bottom anchored, in which case growing the container will just resize us.)
                        prefSize.Height = Math.Max(prefSize.Height, elementSpace.Bottom);
                    }

                    if (IsAnchored(anchor, AnchorStyles.Right))
                    {
                        // If we are right anchored, see what the anchor distance between our right edge and
                        // the container is, and make sure our container is large enough to accomodate us.
                        Rectangle anchorDest = GetAnchorDestination(element, Rectangle.Empty, /*measureOnly=*/ true);
                        if (anchorDest.Width < 0)
                        {
                            prefSize.Width = Math.Max(prefSize.Width, elementSpace.Right + anchorDest.Width);
                        }
                        else
                        {
                            prefSize.Width = Math.Max(prefSize.Width, anchorDest.Right);
                        }
                    }

                    if (IsAnchored(anchor, AnchorStyles.Bottom))
                    {
                        // If we are right anchored, see what the anchor distance between our right edge and
                        // the container is, and make sure our container is large enough to accomodate us.
                        Rectangle anchorDest = GetAnchorDestination(element, Rectangle.Empty, /*measureOnly=*/ true);
                        if (anchorDest.Height < 0)
                        {
                            prefSize.Height = Math.Max(prefSize.Height, elementSpace.Bottom + anchorDest.Height);
                        }
                        else
                        {
                            prefSize.Height = Math.Max(prefSize.Height, anchorDest.Bottom);
                        }
                    }
                }
            }

            return(prefSize);
        }
Exemple #8
0
        private static bool TryCalculatePreferredSize(IArrangedElement container, bool measureOnly, out Size preferredSize)
        {
            ArrangedElementCollection children = container.Children;

            // PreferredSize is garbage unless measureOnly is specified
            preferredSize = new Size(-7103, -7105);

            // Short circuit for items with no children
            if (!measureOnly && children.Count == 0)
            {
                return(CommonProperties.GetAutoSize(container));
            }

            bool dock     = false;
            bool anchor   = false;
            bool autoSize = false;

            for (int i = children.Count - 1; i >= 0; i--)
            {
                IArrangedElement element = children[i];
                if (CommonProperties.GetNeedsDockAndAnchorLayout(element))
                {
                    if (!dock && CommonProperties.GetNeedsDockLayout(element))
                    {
                        dock = true;
                    }

                    if (!anchor && CommonProperties.GetNeedsAnchorLayout(element))
                    {
                        anchor = true;
                    }

                    if (!autoSize && CommonProperties.xGetAutoSizedAndAnchored(element))
                    {
                        autoSize = true;
                    }
                }
            }

            Debug.WriteLineIf(CompModSwitches.RichLayout.TraceInfo, "\tanchor : " + anchor.ToString());
            Debug.WriteLineIf(CompModSwitches.RichLayout.TraceInfo, "\tdock :   " + dock.ToString());

            Size preferredSizeForDocking   = Size.Empty;
            Size preferredSizeForAnchoring = Size.Empty;

            if (dock)
            {
                preferredSizeForDocking = LayoutDockedControls(container, measureOnly);
            }

            if (anchor && !measureOnly)
            {
                // In the case of anchor, where we currently are defines the preferred size,
                // so dont recalculate the positions of everything.
                LayoutAnchoredControls(container);
            }

            if (autoSize)
            {
                LayoutAutoSizedControls(container);
            }

            if (!measureOnly)
            {
                // Set the anchored controls to their computed positions.
                ApplyCachedBounds(container);
            }
            else
            {
                // Finish the preferredSize computation and clear cached anchored positions.
                preferredSizeForAnchoring = GetAnchorPreferredSize(container);

                Padding containerPadding = Padding.Empty;
                if (container is Control control)
                {
                    // Calling this will respect Control.DefaultPadding.
                    containerPadding = control.Padding;
                }
                else
                {
                    // Not likely to happen but handle this gracefully.
                    containerPadding = CommonProperties.GetPadding(container, Padding.Empty);
                }

                preferredSizeForAnchoring.Width  -= containerPadding.Left;
                preferredSizeForAnchoring.Height -= containerPadding.Top;

                ClearCachedBounds(container);
                preferredSize = LayoutUtils.UnionSizes(preferredSizeForDocking, preferredSizeForAnchoring);
            }

            return(CommonProperties.GetAutoSize(container));
        }
Exemple #9
0
        private static Size LayoutDockedControls(IArrangedElement container, bool measureOnly)
        {
            Debug.WriteLineIf(CompModSwitches.RichLayout.TraceInfo, "\tDock Processing");
            Debug.Assert(!HasCachedBounds(container), "Do not call this method with an active cached bounds list.");

            // If measuring, we start with an empty rectangle and add as needed.
            // If doing actual layout, we start with the container's rect and subtract as we layout.
            Rectangle remainingBounds = measureOnly ? Rectangle.Empty : container.DisplayRectangle;
            Size      preferredSize   = Size.Empty;

            IArrangedElement mdiClient = null;

            // Docking layout is order dependent. After much debate, we decided to use z-order as the
            // docking order. (Introducing a DockOrder property was a close second)
            ArrangedElementCollection children = container.Children;

            for (int i = children.Count - 1; i >= 0; i--)
            {
                IArrangedElement element = children[i];
                Debug.Assert(element.Bounds == GetCachedBounds(element), "Why do we have cachedBounds for a docked element?");
                if (CommonProperties.GetNeedsDockLayout(element))
                {
                    // Some controls modify their bounds when you call SetBoundsCore. We
                    // therefore need to read the value of bounds back when adjusting our layout rectangle.
                    switch (GetDock(element))
                    {
                    case DockStyle.Top:
                    {
                        Size      elementSize      = GetVerticalDockedSize(element, remainingBounds.Size, measureOnly);
                        Rectangle newElementBounds = new Rectangle(remainingBounds.X, remainingBounds.Y, elementSize.Width, elementSize.Height);

                        TryCalculatePreferredSizeDockedControl(element, newElementBounds, measureOnly, ref preferredSize, ref remainingBounds);

                        // What we are really doing here: top += element.Bounds.Height;
                        remainingBounds.Y      += element.Bounds.Height;
                        remainingBounds.Height -= element.Bounds.Height;
                        break;
                    }

                    case DockStyle.Bottom:
                    {
                        Size      elementSize      = GetVerticalDockedSize(element, remainingBounds.Size, measureOnly);
                        Rectangle newElementBounds = new Rectangle(remainingBounds.X, remainingBounds.Bottom - elementSize.Height, elementSize.Width, elementSize.Height);

                        TryCalculatePreferredSizeDockedControl(element, newElementBounds, measureOnly, ref preferredSize, ref remainingBounds);

                        // What we are really doing here: bottom -= element.Bounds.Height;
                        remainingBounds.Height -= element.Bounds.Height;

                        break;
                    }

                    case DockStyle.Left:
                    {
                        Size      elementSize      = GetHorizontalDockedSize(element, remainingBounds.Size, measureOnly);
                        Rectangle newElementBounds = new Rectangle(remainingBounds.X, remainingBounds.Y, elementSize.Width, elementSize.Height);

                        TryCalculatePreferredSizeDockedControl(element, newElementBounds, measureOnly, ref preferredSize, ref remainingBounds);

                        // What we are really doing here: left += element.Bounds.Width;
                        remainingBounds.X     += element.Bounds.Width;
                        remainingBounds.Width -= element.Bounds.Width;
                        break;
                    }

                    case DockStyle.Right:
                    {
                        Size      elementSize      = GetHorizontalDockedSize(element, remainingBounds.Size, measureOnly);
                        Rectangle newElementBounds = new Rectangle(remainingBounds.Right - elementSize.Width, remainingBounds.Y, elementSize.Width, elementSize.Height);

                        TryCalculatePreferredSizeDockedControl(element, newElementBounds, measureOnly, ref preferredSize, ref remainingBounds);

                        // What we are really doing here: right -= element.Bounds.Width;
                        remainingBounds.Width -= element.Bounds.Width;
                        break;
                    }

                    case DockStyle.Fill:
                        if (element is MdiClient)
                        {
                            Debug.Assert(mdiClient is null, "How did we end up with multiple MdiClients?");
                            mdiClient = element;
                        }
                        else
                        {
                            Size      elementSize      = remainingBounds.Size;
                            Rectangle newElementBounds = new Rectangle(remainingBounds.X, remainingBounds.Y, elementSize.Width, elementSize.Height);

                            TryCalculatePreferredSizeDockedControl(element, newElementBounds, measureOnly, ref preferredSize, ref remainingBounds);
                        }
                        break;

                    default:
                        Debug.Fail("Unsupported value for dock.");
                        break;
                    }
                }

                // Treat the MDI client specially, since it's supposed to blend in with the parent form
                if (mdiClient != null)
                {
                    SetCachedBounds(mdiClient, remainingBounds);
                }
            }

            return(preferredSize);
        }
        private static bool xLayout(IArrangedElement container, bool measureOnly, out Size preferredSize)
        {
            ArrangedElementCollection children = container.Children;

            preferredSize = new Size(-7103, -7105);
            if (measureOnly || (children.Count != 0))
            {
                bool flag  = false;
                bool flag2 = false;
                bool flag3 = false;
                for (int i = children.Count - 1; i >= 0; i--)
                {
                    IArrangedElement element = children[i];
                    if (CommonProperties.GetNeedsDockAndAnchorLayout(element))
                    {
                        if (!flag && CommonProperties.GetNeedsDockLayout(element))
                        {
                            flag = true;
                        }
                        if (!flag2 && CommonProperties.GetNeedsAnchorLayout(element))
                        {
                            flag2 = true;
                        }
                        if (!flag3 && CommonProperties.xGetAutoSizedAndAnchored(element))
                        {
                            flag3 = true;
                        }
                    }
                }
                Size empty = Size.Empty;
                Size b     = Size.Empty;
                if (flag)
                {
                    empty = LayoutDockedControls(container, measureOnly);
                }
                if (flag2 && !measureOnly)
                {
                    LayoutAnchoredControls(container);
                }
                if (flag3)
                {
                    LayoutAutoSizedControls(container);
                }
                if (!measureOnly)
                {
                    ApplyCachedBounds(container);
                }
                else
                {
                    b = GetAnchorPreferredSize(container);
                    Padding padding = Padding.Empty;
                    Control control = container as Control;
                    if (control != null)
                    {
                        padding = control.Padding;
                    }
                    else
                    {
                        padding = CommonProperties.GetPadding(container, Padding.Empty);
                    }
                    b.Width  -= padding.Left;
                    b.Height -= padding.Top;
                    ClearCachedBounds(container);
                    preferredSize = LayoutUtils.UnionSizes(empty, b);
                }
            }
            return(CommonProperties.GetAutoSize(container));
        }
        private static Size LayoutDockedControls(IArrangedElement container, bool measureOnly)
        {
            Rectangle                 remainingBounds = measureOnly ? Rectangle.Empty : container.DisplayRectangle;
            Size                      empty           = Size.Empty;
            IArrangedElement          element         = null;
            ArrangedElementCollection children        = container.Children;

            for (int i = children.Count - 1; i >= 0; i--)
            {
                IArrangedElement element2 = children[i];
                if (CommonProperties.GetNeedsDockLayout(element2))
                {
                    switch (GetDock(element2))
                    {
                    case DockStyle.Top:
                    {
                        Size      size2      = GetVerticalDockedSize(element2, remainingBounds.Size, measureOnly);
                        Rectangle rectangle2 = new Rectangle(remainingBounds.X, remainingBounds.Y, size2.Width, size2.Height);
                        xLayoutDockedControl(element2, rectangle2, measureOnly, ref empty, ref remainingBounds);
                        remainingBounds.Y      += element2.Bounds.Height;
                        remainingBounds.Height -= element2.Bounds.Height;
                        break;
                    }

                    case DockStyle.Bottom:
                    {
                        Size      size3      = GetVerticalDockedSize(element2, remainingBounds.Size, measureOnly);
                        Rectangle rectangle4 = new Rectangle(remainingBounds.X, remainingBounds.Bottom - size3.Height, size3.Width, size3.Height);
                        xLayoutDockedControl(element2, rectangle4, measureOnly, ref empty, ref remainingBounds);
                        remainingBounds.Height -= element2.Bounds.Height;
                        break;
                    }

                    case DockStyle.Left:
                    {
                        Size      size4      = GetHorizontalDockedSize(element2, remainingBounds.Size, measureOnly);
                        Rectangle rectangle5 = new Rectangle(remainingBounds.X, remainingBounds.Y, size4.Width, size4.Height);
                        xLayoutDockedControl(element2, rectangle5, measureOnly, ref empty, ref remainingBounds);
                        remainingBounds.X     += element2.Bounds.Width;
                        remainingBounds.Width -= element2.Bounds.Width;
                        break;
                    }

                    case DockStyle.Right:
                    {
                        Size      size5      = GetHorizontalDockedSize(element2, remainingBounds.Size, measureOnly);
                        Rectangle rectangle6 = new Rectangle(remainingBounds.Right - size5.Width, remainingBounds.Y, size5.Width, size5.Height);
                        xLayoutDockedControl(element2, rectangle6, measureOnly, ref empty, ref remainingBounds);
                        remainingBounds.Width -= element2.Bounds.Width;
                        break;
                    }

                    case DockStyle.Fill:
                        //if (!(element2 is MdiClient))
                        //{
                        //    goto Label_025B;
                        //}
                        element = element2;
                        break;
                    }
                }
                goto Label_0295;
                // MDI SUPPORT.... Not Sure... #TODO - MDIClient#
                //   Label_025B:
                //size6 = remainingBounds.Size;
                //Rectangle newElementBounds = new Rectangle(remainingBounds.X, remainingBounds.Y, size6.Width, size6.Height);
                //xLayoutDockedControl(element2, newElementBounds, measureOnly, ref empty, ref remainingBounds);
Label_0295:
                if (element != null)
                {
                    SetCachedBounds(element, remainingBounds);
                }
            }
            return(empty);
        }