/// <summary>
        /// Single-use constraint enforcement.
        /// </summary>
        public static void EnforceConstraint(this UIControl control, UIConstraint constraint)
        {
            var constrainer = new UIConstrainer();

            constrainer.AddConstraint(constraint);

            EnforceConstraints(control, constrainer);
        }
        /// <summary>
        /// Single-use constraint enforcement.
        /// </summary>
        public static void EnforceConstraint(this UIControl control, UIConstraint constraint)
        {
            var constrainer = new UIConstrainer();
            constrainer.AddConstraint(constraint);

            EnforceConstraints(control, constrainer);
        }
        private static void EnforceConstraints(this UIControl control, UIConstrainer constrainer, ConstraintCategory category = ConstraintCategory.All)
        {
            if (constrainer != null)
            {
                foreach (UIConstraint constraint in constrainer.Constraints)
                {
                    // Check whether the constraint should be enforced.
                    if (category != ConstraintCategory.All && !category.ContainsFlag(constraint.Category))
                    {
                        continue;
                    }

                    Edge controlEdge = constraint.ControlEdge;
                    UIControl anchor = constraint.Anchor;
                    float distance = constraint.Distance;
                    bool anchorVisible = true;

                    Vector2 pos = Vector2.Zero;
                    Vector2 anchorSize = Engine.ScreenSize;

                    if (anchor != null)
                    {
                        anchorVisible = anchor.Visible;
                        anchorSize = anchorVisible ? (anchor.Size * anchor.scale).Max(anchor.MinimumSize * anchor.scale) : Vector2.Zero;
                        if (anchor.Parent == control.Parent)    // Is anchor and control children of the same parent?
                        {
                            pos = anchor.position;              // ..then set control position relative to the anchor.
                        }

                        Vector2 scaleDelta = anchor.ScaledSize - anchor.Size;
                        pos -= anchor.NormalizedOrigin * scaleDelta;
                    }

                    Vector2 halfAnchorSize = anchorSize * 0.5f;

                    switch (constraint.AnchorEdge)
                    {
                        case Edge.Left:
                            pos.X += distance;
                            break;
                        case Edge.Top:
                            pos.Y += distance;
                            break;
                        case Edge.Right:
                            pos.X += anchorSize.X - distance;
                            break;
                        case Edge.Bottom:
                            pos.Y += anchorSize.Y - distance;
                            break;
                        case Edge.CenterX:
                            pos.X += halfAnchorSize.X + distance;
                            break;
                        case Edge.CenterY:
                            pos.Y += halfAnchorSize.Y + distance;
                            break;
                    }
                    if (!constrainer.AnchoredOpposite(controlEdge))
                    {
                        switch (controlEdge)
                        {
                            case Edge.Left:
                                control.position.X = pos.X;
                                break;
                            case Edge.Top:
                                control.position.Y = pos.Y;
                                break;
                            case Edge.Right:
                                control.position.X = pos.X - Math.Max(control.Width, control.MinimumSize.X);
                                break;
                            case Edge.Bottom:
                                control.position.Y = pos.Y - Math.Max(control.Height, control.MinimumSize.Y);
                                break;
                            case Edge.CenterX:
                                control.position.X = pos.X - Math.Max(control.HalfWidth, control.MinimumSize.X * 0.5f);
                                break;
                            case Edge.CenterY:
                                control.position.Y = pos.Y - Math.Max(control.HalfHeight, control.MinimumSize.Y * 0.5f);
                                break;
                        }
                    }
                    else
                    {
                        switch (controlEdge)
                        {
                            case Edge.Left:
                            case Edge.CenterX:
                                control.size.X += control.position.X - pos.X;
                                control.position.X = pos.X;
                                break;
                            case Edge.Top:
                            case Edge.CenterY:
                                control.size.Y += control.position.Y - pos.Y;
                                control.position.Y = pos.Y;
                                break;
                            case Edge.Right:
                                control.size.X += (pos.X - control.Width) - control.position.X;
                                if (!anchorVisible)
                                {
                                    control.size.X += anchor.size.X; // TODO: Needs proper testing
                                }
                                //control.location.X += pos.X - control.size.X;
                                break;
                            case Edge.Bottom:
                                control.size.Y += (pos.Y - control.Height) - control.position.Y;
                                if (!anchorVisible)
                                {
                                    control.size.Y += anchor.size.Y; // TODO: Needs proper testing
                                }
                                //control.location.Y += pos.Y - control.size.Y;
                                break;
                        }
                        control.UpdateTransformation = true; // Control transformation needs a recalculation when its size is updated.
                    }
                }
            }

            if (control.MinimumSize != Vector2.Zero)
            {
                control.size = control.size.Max(control.MinimumSize);
                control.UpdateTransformation = true;
            }

            _UpdateDrawPosition(control);
        }
Beispiel #4
0
        internal static void EnforceConstraints(this UIControl control, ConstraintCategory category = ConstraintCategory.All)
        {
            if (control.SuspendLayout)
            {
                return;
            }

            UIManager.layoutProfiler.Start();
            UIConstrainer constrainer = control.Constrainer;

            if (constrainer != null)
            {
                foreach (UIConstraint constraint in constrainer.Constraints)
                {
                    // Check whether the constaint should be enforced.
                    if (category != ConstraintCategory.All && !category.ContainsFlag(constraint.Category))
                    {
                        continue;
                    }

                    Edge      controlEdge = constraint.ControlEdge;
                    UIControl anchor      = constraint.Anchor;
                    float     distance    = constraint.Distance;

                    Vector2 pos        = Vector2.Zero;
                    Vector2 anchorSize = Engine.ScreenSize;

                    if (anchor != null)
                    {
                        anchorSize = anchor.Size * anchor.scale;
                        if (anchor.Parent == control.Parent)                            // Is anchor and control children of the same parent?
                        {
                            pos = anchor.location;                                      // ..then set control position relative to the anchor.
                        }

                        Vector2 scaleDelta = anchor.ScaledSize - anchor.Size;
                        pos -= anchor.NormalizedOrigin * scaleDelta;
                    }

                    Vector2 halfAnchorSize = anchorSize * 0.5f;

                    switch (constraint.AnchorEdge)
                    {
                    case Edge.Left:
                        pos.X += distance;
                        break;

                    case Edge.Top:
                        pos.Y += distance;
                        break;

                    case Edge.Right:
                        pos.X += anchorSize.X - distance;
                        break;

                    case Edge.Bottom:
                        pos.Y += anchorSize.Y - distance;
                        break;

                    case Edge.CenterX:
                        pos.X += halfAnchorSize.X + distance;
                        break;

                    case Edge.CenterY:
                        pos.Y += halfAnchorSize.Y + distance;
                        break;
                    }
                    if (!constrainer.ControlAnchoredOpposite(controlEdge))
                    {
                        switch (controlEdge)
                        {
                        case Edge.Left:
                            control.location.X = pos.X;
                            break;

                        case Edge.Top:
                            control.location.Y = pos.Y;
                            break;

                        case Edge.Right:
                            control.location.X = pos.X - control.Width;
                            break;

                        case Edge.Bottom:
                            control.location.Y = pos.Y - control.Height;
                            break;

                        case Edge.CenterX:
                            control.location.X = pos.X - control.HalfWidth;
                            break;

                        case Edge.CenterY:
                            control.location.Y = pos.Y - control.HalfHeight;
                            break;
                        }
                    }
                    else
                    {
                        switch (controlEdge)
                        {
                        case Edge.Left:
                        case Edge.CenterX:
                            control.size.X    += control.location.X - pos.X;
                            control.location.X = pos.X;
                            break;

                        case Edge.Top:
                        case Edge.CenterY:
                            control.size.Y    += control.location.Y - pos.Y;
                            control.location.Y = pos.Y;
                            break;

                        case Edge.Right:
                            control.size.X += (pos.X - control.Width) - control.location.X;
                            //control.location.X += pos.X - control.size.X;
                            break;

                        case Edge.Bottom:
                            control.size.Y += (pos.Y - control.Height) - control.location.Y;
                            //control.location.Y += pos.Y - control.size.Y;
                            break;
                        }
                    }
                }
            }

            _UpdateDrawLocation(control);
            UIManager.layoutProfiler.Stop();
        }
        private static void EnforceConstraints(this UIControl control, UIConstrainer constrainer, ConstraintCategory category = ConstraintCategory.All)
        {
            if (constrainer != null)
            {
                foreach (UIConstraint constraint in constrainer.Constraints)
                {
                    // Check whether the constraint should be enforced.
                    if (category != ConstraintCategory.All && !category.ContainsFlag(constraint.Category))
                    {
                        continue;
                    }

                    Edge      controlEdge   = constraint.ControlEdge;
                    UIControl anchor        = constraint.Anchor;
                    float     distance      = constraint.Distance;
                    bool      anchorVisible = true;

                    Vector2 pos        = Vector2.Zero;
                    Vector2 anchorSize = Engine.ScreenSize;

                    if (anchor != null)
                    {
                        anchorVisible = anchor.Visible;
                        anchorSize    = anchorVisible ? (anchor.Size * anchor.scale).Max(anchor.MinimumSize * anchor.scale) : Vector2.Zero;
                        if (anchor.Parent == control.Parent)                            // Is anchor and control children of the same parent?
                        {
                            pos = anchor.position;                                      // ..then set control position relative to the anchor.
                        }

                        Vector2 scaleDelta = anchor.ScaledSize - anchor.Size;
                        pos -= anchor.NormalizedOrigin * scaleDelta;
                    }

                    Vector2 halfAnchorSize = anchorSize * 0.5f;

                    switch (constraint.AnchorEdge)
                    {
                    case Edge.Left:
                        pos.X += distance;
                        break;

                    case Edge.Top:
                        pos.Y += distance;
                        break;

                    case Edge.Right:
                        pos.X += anchorSize.X - distance;
                        break;

                    case Edge.Bottom:
                        pos.Y += anchorSize.Y - distance;
                        break;

                    case Edge.CenterX:
                        pos.X += halfAnchorSize.X + distance;
                        break;

                    case Edge.CenterY:
                        pos.Y += halfAnchorSize.Y + distance;
                        break;
                    }
                    if (!constrainer.AnchoredOpposite(controlEdge))
                    {
                        switch (controlEdge)
                        {
                        case Edge.Left:
                            control.position.X = pos.X;
                            break;

                        case Edge.Top:
                            control.position.Y = pos.Y;
                            break;

                        case Edge.Right:
                            control.position.X = pos.X - Math.Max(control.Width, control.MinimumSize.X);
                            break;

                        case Edge.Bottom:
                            control.position.Y = pos.Y - Math.Max(control.Height, control.MinimumSize.Y);
                            break;

                        case Edge.CenterX:
                            control.position.X = pos.X - Math.Max(control.HalfWidth, control.MinimumSize.X * 0.5f);
                            break;

                        case Edge.CenterY:
                            control.position.Y = pos.Y - Math.Max(control.HalfHeight, control.MinimumSize.Y * 0.5f);
                            break;
                        }
                    }
                    else
                    {
                        switch (controlEdge)
                        {
                        case Edge.Left:
                        case Edge.CenterX:
                            control.size.X    += control.position.X - pos.X;
                            control.position.X = pos.X;
                            break;

                        case Edge.Top:
                        case Edge.CenterY:
                            control.size.Y    += control.position.Y - pos.Y;
                            control.position.Y = pos.Y;
                            break;

                        case Edge.Right:
                            control.size.X += (pos.X - control.Width) - control.position.X;
                            if (!anchorVisible)
                            {
                                control.size.X += anchor.size.X;                                         // TODO: Needs proper testing
                            }
                            //control.location.X += pos.X - control.size.X;
                            break;

                        case Edge.Bottom:
                            control.size.Y += (pos.Y - control.Height) - control.position.Y;
                            if (!anchorVisible)
                            {
                                control.size.Y += anchor.size.Y;                                         // TODO: Needs proper testing
                            }
                            //control.location.Y += pos.Y - control.size.Y;
                            break;
                        }
                        control.UpdateTransformation = true;                         // Control transformation needs a recalculation when its size is updated.
                    }
                }
            }

            if (control.MinimumSize != Vector2.Zero)
            {
                control.size = control.size.Max(control.MinimumSize);
                control.UpdateTransformation = true;
            }

            _UpdateDrawPosition(control);
        }