/// <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); }
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(); }