2 using System.Collections.Generic;
4 using Microsoft.Xna.Framework;
33 #region Fields and Properties
44 get {
return parent; }
47 if (parent == value || value ==
this) {
return; }
49 RemoveFromHierarchy(displayErrors:
false);
51 if (parent !=
null && !parent.
children.Contains(
this))
61 protected readonly List<RectTransform>
children =
new List<RectTransform>();
66 private Vector2 relativeSize = Vector2.One;
72 get {
return relativeSize; }
75 if (relativeSize.NearlyEquals(value)) {
return; }
81 private Point? minSize;
88 get {
return minSize ?? Point.Zero; }
91 if (minSize == value) {
return; }
97 public readonly
static Point
MaxPoint =
new Point(
int.MaxValue,
int.MaxValue);
98 private Point? maxSize;
109 if (maxSize == value) {
return; }
115 private Point nonScaledSize;
121 get {
return nonScaledSize; }
124 if (nonScaledSize == value) {
return; }
149 private Vector2 localScale = Vector2.One;
152 get {
return localScale; }
155 if (localScale.NearlyEquals(value)) {
return; }
162 public Vector2
Scale {
get;
private set; }
164 private Vector2 relativeOffset = Vector2.Zero;
165 private Point absoluteOffset = Point.Zero;
166 private Point screenSpaceOffset = Point.Zero;
173 get {
return relativeOffset; }
176 if (relativeOffset.NearlyEquals(value)) {
return; }
177 relativeOffset = value;
178 recalculateRect =
true;
189 get {
return absoluteOffset; }
192 if (absoluteOffset == value) {
return; }
193 absoluteOffset = value;
194 recalculateRect =
true;
203 get {
return screenSpaceOffset; }
206 if (screenSpaceOffset == value) {
return; }
207 screenSpaceOffset = value;
208 recalculateRect =
true;
237 Point relativeOffset =
new Point(
245 private bool recalculateRect =
true;
254 recalculateRect =
false;
275 get {
return pivot; }
278 if (pivot == value) {
return; }
292 get {
return anchor; }
295 if (anchor == value) {
return; }
304 get {
return _scaleBasis; }
318 if (
Parent ==
null) {
return false; }
320 if (last ==
null) {
return false; }
329 if (
Parent ==
null) {
return false; }
331 if (first ==
null) {
return false; }
332 return first ==
this;
352 #region Initialization
355 Init(parent, anchor, pivot);
356 _scaleBasis = scaleBasis;
357 this.relativeSize = relativeSize;
358 this.minSize = minSize;
359 this.maxSize = maxSize;
373 Init(parent, anchor, pivot);
374 _scaleBasis = scaleBasis;
375 this.nonScaledSize = absoluteSize;
390 Enum.TryParse(element.GetAttributeString(
"anchor", defaultAnchor.ToString()), out
Anchor anchor);
391 Enum.TryParse(element.GetAttributeString(
"pivot", anchor.ToString()), out
Pivot pivot);
393 Point? minSize =
null, maxSize =
null;
395 if (element.Attribute(
"minsize") !=
null)
397 minSize = element.GetAttributePoint(
"minsize", Point.Zero);
399 if (element.Attribute(
"maxsize") !=
null)
401 maxSize = element.GetAttributePoint(
"maxsize",
new Point(1000, 1000));
403 string sb = element.GetAttributeString(
"scalebasis",
null);
406 Enum.TryParse(sb, ignoreCase:
true, out scaleBasis);
409 if (element.Attribute(
"absolutesize") !=
null)
411 rectTransform =
new RectTransform(element.GetAttributePoint(
"absolutesize",
new Point(1000, 1000)), parent, anchor, pivot, scaleBasis)
419 rectTransform =
new RectTransform(element.GetAttributeVector2(
"relativesize", Vector2.One), parent, anchor, pivot, minSize, maxSize, scaleBasis);
421 rectTransform.
RelativeOffset = element.GetAttributeVector2(
"relativeoffset", Vector2.Zero);
422 rectTransform.
AbsoluteOffset = element.GetAttributePoint(
"absoluteoffset", Point.Zero);
423 return rectTransform;
428 this.parent = parent;
435 #region Protected methods
440 Scale = parents.Any() ? parents.Select(rt => rt.LocalScale).Aggregate((parent, child) => parent * child) * scale : scale;
441 recalculateRect =
true;
448 recalculateRect =
true;
454 recalculateRect =
true;
460 recalculateRect =
true;
498 recalculateRect =
true;
509 protected void RecalculateAll(
bool resize,
bool scale =
true,
bool withChildren =
true)
527 private bool RemoveFromHierarchy(
bool displayErrors =
true)
533 DebugConsole.ThrowError(
"Parent null" + Environment.StackTrace.CleanupStackTrace());
541 DebugConsole.ThrowError(
"The children of the parent does not contain this child. This should not be possible! " + Environment.StackTrace.CleanupStackTrace());
549 DebugConsole.ThrowError(
"Unable to remove the child from the parent. " + Environment.StackTrace.CleanupStackTrace());
557 #region Public instance methods
563 recalculateRect =
true;
567 public void Resize(Point absoluteSize,
bool resizeChildren =
true)
575 public void Resize(Vector2 relativeSize,
bool resizeChildren =
true)
577 this.relativeSize = relativeSize;
619 var parents =
new List<RectTransform>();
651 if (
children.Contains(rectT)) {
return true; }
656 if (child.IsParentOf(rectT)) {
return true; }
664 if (
Parent ==
null) {
return false; }
670 children.ForEachMod(c => c.Parent =
null);
690 if (!RemoveFromHierarchy(displayErrors:
true)) {
return; }
704 if (!RemoveFromHierarchy(displayErrors:
true)) {
return false; }
709 catch (ArgumentOutOfRangeException e)
711 DebugConsole.ThrowError(e.ToString());
721 for (
int i = 0; i <
children.Count; i++)
723 children[i].RecalculateAll(resize, scale, withChildren:
true);
729 for (
int i = 0; i <
children.Count; i++)
731 children[i].GUIComponent.AddToGUIUpdateList(ignoreChildren, order);
738 private Point? animTargetPos;
744 public void MoveOverTime(Point targetPos,
float duration, Action onDoneMoving =
null)
746 animTargetPos = targetPos;
747 CoroutineManager.StartCoroutine(DoMoveAnimation(targetPos, duration, onDoneMoving));
751 CoroutineManager.StartCoroutine(DoScaleAnimation(targetSize, duration));
754 private IEnumerable<CoroutineStatus> DoMoveAnimation(Point targetPos,
float duration, Action onDoneMoving =
null)
758 while (t < duration && duration > 0.0f)
760 t += CoroutineManager.DeltaTime;
761 AbsoluteOffset = Vector2.SmoothStep(startPos, targetPos.ToVector2(), t / duration).ToPoint();
765 animTargetPos =
null;
766 onDoneMoving?.Invoke();
767 yield
return CoroutineStatus.Success;
769 private IEnumerable<CoroutineStatus> DoScaleAnimation(Point targetSize,
float duration)
773 while (t < duration && duration > 0.0f)
775 t += CoroutineManager.DeltaTime;
776 NonScaledSize = Vector2.SmoothStep(startSize, targetSize.ToVector2(), t / duration).ToPoint();
777 yield
return CoroutineStatus.Running;
780 yield
return CoroutineStatus.Success;
802 #region Static methods
805 return (
Pivot)anchor;
845 return Anchor.CenterRight;
848 return Anchor.BottomRight;
887 return Anchor.BottomCenter;
890 return Anchor.BottomRight;
904 return offset.Inverse();
907 return new Point(offset.X, -offset.Y);
910 return new Point(-offset.X, offset.Y);
924 case Pivot.TopCenter:
925 return new Point(-width / 2, 0);
927 return new Point(-width, 0);
928 case Pivot.CenterLeft:
929 return new Point(0, -height / 2);
931 return size.Divide(2).Inverse();
932 case Pivot.CenterRight:
933 return new Point(-width, -height / 2);
934 case Pivot.BottomLeft:
935 return new Point(0, -height);
936 case Pivot.BottomCenter:
937 return new Point(-width / 2, -height);
938 case Pivot.BottomRight:
939 return new Point(-width, -height);
941 throw new NotImplementedException(anchor.ToString());
950 return parent.Location;
952 return new Point(parent.Center.X, parent.Top);
954 return new Point(parent.Right, parent.Top);
956 return new Point(parent.Left, parent.Center.Y);
958 return parent.Center;
960 return new Point(parent.Right, parent.Center.Y);
962 return new Point(parent.Left, parent.Bottom);
964 return new Point(parent.Center.X, parent.Bottom);
966 return new Point(parent.Right, parent.Bottom);
968 throw new NotImplementedException(anchor.ToString());
static CoroutineStatus Running
static int GraphicsHeight