namespace UIWidgets
{
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Serialization;
///
/// Base class for the SnapGrid.
///
#if UNITY_2018_4_OR_NEWER
[ExecuteAlways]
#else
[ExecuteInEditMode]
#endif
public abstract partial class SnapGridBase : UIBehaviourConditional
{
///
/// Lines at X axis.
///
protected List LinesX = new List();
///
/// Lines at Y axis.
///
protected List LinesY = new List();
[SerializeField]
[FormerlySerializedAs("snapBorderInside")]
Border snapBorderInner;
///
/// Allow snapping to the inner side of the border.
///
public Border SnapBorderInnner
{
get
{
return snapBorderInner;
}
set
{
if (snapBorderInner != value)
{
snapBorderInner = value;
UpdateLines();
}
}
}
[SerializeField]
[FormerlySerializedAs("snapBorderOutside")]
Border snapBorderOuter;
///
/// Allow snapping to the outer side of the border.
///
public Border SnapBorderOuter
{
get
{
return snapBorderOuter;
}
set
{
if (snapBorderOuter != value)
{
snapBorderOuter = value;
UpdateLines();
}
}
}
///
/// Event on lines changed.
///
[SerializeField]
public UnityEvent OnLinesChanged = new UnityEvent();
///
/// Snap lines at X axis.
///
protected List SnapLinesX = new List();
///
/// Snap lines at Y axis.
///
protected List SnapLinesY = new List();
RectTransform rectTransform;
///
/// RectTransform.
///
public RectTransform RectTransform
{
get
{
if (rectTransform == null)
{
rectTransform = transform as RectTransform;
}
return rectTransform;
}
}
///
/// Process the Start event.
///
protected override void Start()
{
base.Start();
Init();
}
///
/// Init this instance.
///
public virtual void Init()
{
UpdateLines();
}
///
/// Process dimensions changed event.
///
protected override void OnRectTransformDimensionsChange()
{
base.OnRectTransformDimensionsChange();
UpdateLines();
}
#if UNITY_EDITOR
///
/// Process validate event.
///
protected override void OnValidate()
{
base.OnValidate();
UpdateLines();
}
#endif
///
/// Update lines.
///
protected abstract void UpdateLines();
///
/// Get lines at X axis.
///
/// Include borders if snap borders enabled.
/// Result.
public virtual void GetLinesX(bool includeBorders, List output)
{
if (includeBorders && (SnapBorderInnner.Left || SnapBorderOuter.Left))
{
output.Add(0f);
}
foreach (var line in LinesX)
{
output.Add(line.X);
}
if (includeBorders && (SnapBorderInnner.Right || SnapBorderOuter.Right))
{
output.Add(RectTransform.rect.width);
}
}
///
/// Get lines at Y axis.
///
/// Include borders if snap borders enabled.
/// Result.
public void GetLinesY(bool includeBorders, List output)
{
if (includeBorders && (SnapBorderInnner.Bottom || SnapBorderOuter.Bottom))
{
output.Add(0f);
}
foreach (var line in LinesY)
{
output.Add(line.Y);
}
if (includeBorders && (SnapBorderInnner.Top || SnapBorderOuter.Top))
{
output.Add(RectTransform.rect.height);
}
}
///
/// Get lines at X axis.
///
/// Result.
public virtual void GetLinesX(List output)
{
if (SnapBorderInnner.Left || SnapBorderOuter.Left)
{
output.Add(new LineX(0f, SnapBorderInnner.Left, SnapBorderOuter.Left));
}
output.AddRange(LinesX);
if (SnapBorderInnner.Right || SnapBorderOuter.Right)
{
output.Add(new LineX(RectTransform.rect.width, SnapBorderOuter.Right, SnapBorderInnner.Right));
}
}
///
/// Get grid position.
///
/// Position.
protected virtual Vector2 GridPosition()
{
var size = RectTransform.rect.size;
var pivot = RectTransform.pivot;
var position = RectTransform.position;
var scale = RectTransform.lossyScale;
position.x = (position.x / scale.x) - (size.x * pivot.x);
position.y = (position.y / scale.y) - (size.y * pivot.y);
return position;
}
///
/// Get lines at Y axis.
///
/// Result.
public virtual void GetLinesY(List output)
{
if (SnapBorderInnner.Bottom || SnapBorderOuter.Bottom)
{
output.Add(new LineY(0f, SnapBorderInnner.Bottom, SnapBorderOuter.Bottom));
}
output.AddRange(LinesY);
if (SnapBorderInnner.Top || SnapBorderOuter.Top)
{
output.Add(new LineY(RectTransform.rect.height, SnapBorderOuter.Top, SnapBorderInnner.Top));
}
}
///
/// Snap point.
///
/// Point.
/// Maximum distance to snap.
/// Distance to the nearest line or lines.
public virtual Result Snap(Point point, Vector2 snapDistance)
{
var distance = new Distance(float.MaxValue);
Snap(point, ref distance);
return distance.Snap(snapDistance);
}
///
/// Snap point.
///
/// Point.
/// Distance.
public virtual void Snap(Point point, ref Distance distance)
{
var current_position = GridPosition();
foreach (var line in SnapLinesX)
{
var x = current_position.x + line.X - point.X;
if (line.SnapLeft && point.Left)
{
distance.Left(x);
}
if (line.SnapRight && point.Right)
{
distance.Right(x);
}
}
foreach (var line in SnapLinesY)
{
var y = current_position.y + line.Y - point.Y;
if (line.SnapTop && point.Top)
{
distance.Top(y);
}
if (line.SnapBottom && point.Bottom)
{
distance.Bottom(y);
}
}
}
///
/// Snap points.
///
/// Points.
/// Maximum distance to snap.
/// Distance to the nearest line or lines.
public virtual Result Snap(List points, Vector2 snapDistance)
{
var distance = new Distance(float.MaxValue);
Snap(points, ref distance);
return distance.Snap(snapDistance);
}
///
/// Snap points.
///
/// Points.
/// Distance.
public virtual void Snap(List points, ref Distance distance)
{
SnapLinesX.Clear();
GetLinesX(SnapLinesX);
SnapLinesY.Clear();
GetLinesY(SnapLinesY);
var current_position = GridPosition();
foreach (var point in points)
{
foreach (var line in SnapLinesX)
{
var x = current_position.x + line.X - point.X;
if (line.SnapLeft && point.Left)
{
distance.Left(x);
}
if (line.SnapRight && point.Right)
{
distance.Right(x);
}
}
foreach (var line in SnapLinesY)
{
var y = current_position.y + line.Y - point.Y;
if (line.SnapTop && point.Top)
{
distance.Top(y);
}
if (line.SnapBottom && point.Bottom)
{
distance.Bottom(y);
}
}
}
}
List tempPoints = new List(4);
///
/// Snap target.
///
/// Target.
/// Maximum distance to snap.
/// Distance to the nearest line or lines.
public virtual Result Snap(RectTransform target, Vector2 snapDistance)
{
tempPoints.Add(new Point(target, this, true, true));
tempPoints.Add(new Point(target, this, true, false));
tempPoints.Add(new Point(target, this, false, true));
tempPoints.Add(new Point(target, this, false, false));
var result = Snap(tempPoints, snapDistance);
tempPoints.Clear();
return result;
}
///
/// Snap target.
///
/// Target.
/// Distance.
public virtual void Snap(RectTransform target, ref Distance distance)
{
tempPoints.Add(new Point(target, this, true, true));
tempPoints.Add(new Point(target, this, true, false));
tempPoints.Add(new Point(target, this, false, true));
tempPoints.Add(new Point(target, this, false, false));
Snap(tempPoints, ref distance);
tempPoints.Clear();
}
///
/// Snap target.
///
/// Snap grids.
/// Snap distance.
/// Target.
/// Distance to the nearest line or lines.
public static Result Snap(List snapGrids, Vector2 snapDistance, RectTransform target)
{
if (snapGrids == null)
{
return default(Result);
}
if (snapGrids.Count == 0)
{
return default(Result);
}
var distance = new Distance(float.MaxValue);
foreach (var snap_grid in snapGrids)
{
if (snap_grid == null)
{
continue;
}
snap_grid.Snap(target, ref distance);
}
return distance.Snap(snapDistance);
}
}
}