using System;
using UnityEngine;
using UnityEngine.Serialization;
namespace TheraBytes.BetterUi
{
[Serializable]
public class RectTransformData : IScreenConfigConnection
{
public static readonly RectTransformData Invalid = new RectTransformData();
public static readonly RectTransformData Identity = new RectTransformData()
{
Rotation = Quaternion.identity,
Scale = Vector3.one,
};
public Vector3 LocalPosition;
public Vector2 AnchoredPosition;
public Vector2 SizeDelta;
public Vector2 AnchorMin;
public Vector2 AnchorMax;
public Vector2 Pivot;
public Vector3 Scale;
[FormerlySerializedAs("Rotation")]
[SerializeField]
Quaternion rotation;
public Vector3 EulerAngles;
public Quaternion Rotation
{
get
{
return (saveRotationAsEuler) ? Quaternion.Euler(EulerAngles) : rotation;
}
set
{
rotation = value;
if (saveRotationAsEuler)
{
EulerAngles = rotation.eulerAngles;
}
}
}
[SerializeField]
bool saveRotationAsEuler = false;
public bool SaveRotationAsEuler
{
get
{
return saveRotationAsEuler;
}
set
{
if (saveRotationAsEuler == value)
return;
saveRotationAsEuler = value;
}
}
///
/// The offset of the upper right corner of the rectangle relative to the upper right anchor.
///
public Vector2 OffsetMax
{
get
{
return this.AnchoredPosition + Vector2.Scale(this.SizeDelta, Vector2.one - this.Pivot);
}
set
{
Vector2 v = value - (this.AnchoredPosition + Vector2.Scale(this.SizeDelta, Vector2.one - this.Pivot));
this.SizeDelta = this.SizeDelta + v;
this.AnchoredPosition = this.AnchoredPosition + Vector2.Scale(v, this.Pivot);
}
}
///
/// The offset of the lower left corner of the rectangle relative to the lower left anchor.
///
public Vector2 OffsetMin
{
get
{
return this.AnchoredPosition - Vector2.Scale(this.SizeDelta, this.Pivot);
}
set
{
Vector2 v = value - (this.AnchoredPosition - Vector2.Scale(this.SizeDelta, this.Pivot));
this.SizeDelta = this.SizeDelta - v;
this.AnchoredPosition = this.AnchoredPosition + Vector2.Scale(v, Vector2.one - this.Pivot);
}
}
[SerializeField]
string screenConfigName;
public string ScreenConfigName { get { return screenConfigName; } set { screenConfigName = value; } }
public RectTransformData()
{
}
public RectTransformData(RectTransform rectTransform)
{
PullFromTransform(rectTransform);
}
public static RectTransformData Combine(RectTransformData original, RectTransformData addition)
{
RectTransformData result = new RectTransformData();
result.AnchoredPosition = original.AnchoredPosition + addition.AnchoredPosition;
result.AnchorMin = original.AnchorMin + addition.AnchorMin;
result.AnchorMax = original.AnchorMax + addition.AnchorMax;
result.Pivot = original.Pivot + addition.Pivot;
result.SizeDelta = original.SizeDelta + addition.SizeDelta;
result.LocalPosition = original.LocalPosition + addition.LocalPosition;
result.Scale = new Vector3(
original.Scale.x * addition.Scale.x,
original.Scale.y * addition.Scale.y,
original.Scale.z * addition.Scale.z);
result.saveRotationAsEuler = original.saveRotationAsEuler;
result.Rotation = original.Rotation * addition.Rotation;
return result;
}
public static RectTransformData Separate(RectTransformData original, RectTransformData subtraction)
{
RectTransformData result = new RectTransformData();
result.AnchoredPosition = original.AnchoredPosition - subtraction.AnchoredPosition;
result.AnchorMin = original.AnchorMin - subtraction.AnchorMin;
result.AnchorMax = original.AnchorMax - subtraction.AnchorMax;
result.Pivot = original.Pivot - subtraction.Pivot;
result.SizeDelta = original.SizeDelta - subtraction.SizeDelta;
result.LocalPosition = original.LocalPosition - subtraction.LocalPosition;
result.Scale = new Vector3(
original.Scale.x / subtraction.Scale.x,
original.Scale.y / subtraction.Scale.y,
original.Scale.z / subtraction.Scale.z);
result.saveRotationAsEuler = original.saveRotationAsEuler;
result.Rotation = original.Rotation * Quaternion.Inverse(subtraction.Rotation);
return result;
}
public RectTransformData PullFromData(RectTransformData transformData)
{
this.LocalPosition = transformData.LocalPosition;
this.AnchorMin = transformData.AnchorMin;
this.AnchorMax = transformData.AnchorMax;
this.Pivot = transformData.Pivot;
this.AnchoredPosition = transformData.AnchoredPosition;
this.SizeDelta = transformData.SizeDelta;
this.Scale = transformData.Scale;
this.saveRotationAsEuler = transformData.saveRotationAsEuler;
this.Rotation = transformData.Rotation;
this.EulerAngles = transformData.EulerAngles;
return this;
}
public void PullFromTransform(RectTransform transform)
{
this.LocalPosition = transform.localPosition;
this.AnchorMin = transform.anchorMin;
this.AnchorMax = transform.anchorMax;
this.Pivot = transform.pivot;
this.AnchoredPosition = transform.anchoredPosition;
this.SizeDelta = transform.sizeDelta;
this.Scale = transform.localScale;
this.Rotation = transform.localRotation;
this.EulerAngles = transform.localEulerAngles;
}
public void PushToTransform(RectTransform transform)
{
transform.localPosition = this.LocalPosition;
transform.anchorMin = this.AnchorMin;
transform.anchorMax = this.AnchorMax;
transform.pivot = this.Pivot;
transform.anchoredPosition = this.AnchoredPosition;
transform.sizeDelta = this.SizeDelta;
transform.localScale = this.Scale;
if (SaveRotationAsEuler)
{
transform.eulerAngles = this.EulerAngles;
}
else
{
transform.localRotation = this.Rotation;
}
}
public Rect ToRect(Rect parentRect, bool relativeSpace = false)
{
float xMin = (AnchorMin.x * parentRect.width) + AnchoredPosition.x - Pivot.x * SizeDelta.x;
float xMax = (AnchorMax.x * parentRect.width) + AnchoredPosition.x + (1 - Pivot.x) * SizeDelta.x;
float yMin = (AnchorMin.y * parentRect.height) + AnchoredPosition.y - Pivot.y * SizeDelta.y;
float yMax = (AnchorMax.y * parentRect.height) + AnchoredPosition.y + (1 - Pivot.y) * SizeDelta.y;
if(relativeSpace)
{
xMin /= parentRect.width;
xMax /= parentRect.width;
yMin /= parentRect.height;
yMax /= parentRect.height;
}
return new Rect(xMin, yMin, xMax - xMin, yMax - yMin);
}
public static RectTransformData Lerp(RectTransformData a, RectTransformData b, float amount)
{
return Lerp(a, b, amount, a.SaveRotationAsEuler || b.SaveRotationAsEuler);
}
public static RectTransformData Lerp(RectTransformData a, RectTransformData b, float amount, bool eulerRotation)
{
return new RectTransformData()
{
AnchoredPosition = Vector2.Lerp(a.AnchoredPosition, b.AnchoredPosition, amount),
AnchorMax = Vector2.Lerp(a.AnchorMax, b.AnchorMax, amount),
AnchorMin = Vector2.Lerp(a.AnchorMin, b.AnchorMin, amount),
LocalPosition = Vector3.Lerp(a.LocalPosition, b.LocalPosition, amount),
Pivot = Vector2.Lerp(a.Pivot, b.Pivot, amount),
Scale = Vector3.Lerp(a.Scale, b.Scale, amount),
SizeDelta = Vector2.Lerp(a.SizeDelta, b.SizeDelta, amount),
Rotation = Quaternion.Lerp(a.Rotation, b.Rotation, amount),
EulerAngles = Vector3.Lerp(a.EulerAngles, b.EulerAngles, amount),
SaveRotationAsEuler = eulerRotation
};
}
public static RectTransformData LerpUnclamped(RectTransformData a, RectTransformData b, float amount)
{
return LerpUnclamped(a, b, amount, a.SaveRotationAsEuler || b.SaveRotationAsEuler);
}
public static RectTransformData LerpUnclamped(RectTransformData a, RectTransformData b, float amount, bool eulerRotation)
{
return new RectTransformData()
{
AnchoredPosition = Vector2.LerpUnclamped(a.AnchoredPosition, b.AnchoredPosition, amount),
AnchorMax = Vector2.LerpUnclamped(a.AnchorMax, b.AnchorMax, amount),
AnchorMin = Vector2.LerpUnclamped(a.AnchorMin, b.AnchorMin, amount),
LocalPosition = Vector3.LerpUnclamped(a.LocalPosition, b.LocalPosition, amount),
Pivot = Vector2.LerpUnclamped(a.Pivot, b.Pivot, amount),
Scale = Vector3.LerpUnclamped(a.Scale, b.Scale, amount),
SizeDelta = Vector2.LerpUnclamped(a.SizeDelta, b.SizeDelta, amount),
Rotation = Quaternion.LerpUnclamped(a.Rotation, b.Rotation, amount),
EulerAngles = Vector3.LerpUnclamped(a.EulerAngles, b.EulerAngles, amount),
SaveRotationAsEuler = eulerRotation
};
}
public override int GetHashCode()
{
return this.AnchoredPosition.GetHashCode()
^ this.AnchorMin.GetHashCode()
^ this.AnchorMax.GetHashCode()
^ this.LocalPosition.GetHashCode()
^ this.Pivot.GetHashCode()
^ this.Scale.GetHashCode()
^ this.SizeDelta.GetHashCode()
^ this.rotation.GetHashCode()
^ this.saveRotationAsEuler.GetHashCode()
^ this.EulerAngles.GetHashCode();
}
public override bool Equals(object obj)
{
return this.GetHashCode() == obj.GetHashCode();
}
public static bool operator ==(RectTransformData a, RectTransformData b)
{
bool aIsNull = ReferenceEquals(a, null);
bool bIsNull = ReferenceEquals(b, null);
if (aIsNull || bIsNull)
return aIsNull && bIsNull;
return a.AnchoredPosition == b.AnchoredPosition
&& a.AnchorMin == b.AnchorMin
&& a.AnchorMax == b.AnchorMax
&& a.Pivot == b.Pivot
&& a.SizeDelta == b.SizeDelta
&& a.LocalPosition == b.LocalPosition
&& a.Scale == b.Scale
&& a.Rotation.Equals(b.Rotation);
}
public static bool operator !=(RectTransformData a, RectTransformData b)
{
return !(a == b);
}
public override string ToString()
{
return string.Format("RectTransformData: sizeDelta {{{0}, {1}}} - anchoredPosition {{{2}, {3}}}",
SizeDelta.x, SizeDelta.y, AnchoredPosition.x, AnchoredPosition.y);
}
}
}