//----------------------------------------------
// NGUI: Next-Gen UI kit
// Copyright © 2011-2014 Tasharen Entertainment
//----------------------------------------------
using UnityEngine;
using System.Collections.Generic;
/// <summary>
/// All children added to the game object with this script will be repositioned to be on a grid of specified dimensions.
/// If you want the cells to automatically set their scale based on the dimensions of their content, take a look at UITable.
/// </summary>
[AddComponentMenu("NGUI/Interaction/Grid")]
public class UIGrid : UIWidgetContainer
{
public delegate void OnReposition ();
public enum Arrangement
{
Horizontal,
Vertical,
}
public enum Alignment
{
Left,
Centered,
Right,
}
public Alignment alignment = Alignment.Left;
/// <summary>
/// Type of arrangement -- vertical or horizontal.
/// </summary>
public Arrangement arrangement = Arrangement.Horizontal;
/// <summary>
/// Maximum children per line.
/// If the arrangement is horizontal, this denotes the number of columns.
/// If the arrangement is vertical, this stands for the number of rows.
/// </summary>
public int maxPerLine = 0;
/// <summary>
/// The width of each of the cells.
/// </summary>
public float cellWidth = 200f;
/// <summary>
/// The height of each of the cells.
/// </summary>
public float cellHeight = 200f;
/// <summary>
/// Whether the grid will smoothly animate its children into the correct place.
/// </summary>
public bool animateSmoothly = false;
/// <summary>
/// Whether the children will be sorted alphabetically prior to repositioning.
/// </summary>
public bool sorted = false;
/// <summary>
/// Whether to ignore the disabled children or to treat them as being present.
/// </summary>
public bool hideInactive = true;
/// <summary>
/// Whether the parent container will be notified of the grid's changes.
/// </summary>
public bool keepWithinPanel = false;
/// <summary>
/// Callback triggered when the grid repositions its contents.
/// </summary>
public OnReposition onReposition;
/// <summary>
/// Reposition the children on the next Update().
/// </summary>
public bool repositionNow { set { if (value) { mReposition = true; enabled = true; } } }
bool mReposition = false;
UIPanel mPanel;
bool mInitDone = false;
void Init ()
{
mInitDone = true;
mPanel = NGUITools.FindInParents<UIPanel>(gameObject);
}
void Start ()
{
if (!mInitDone) Init();
bool smooth = animateSmoothly;
animateSmoothly = false;
Reposition();
animateSmoothly = smooth;
enabled = false;
}
void Update ()
{
if (mReposition) Reposition();
enabled = false;
}
static public int SortByName (Transform a, Transform b) { return string.Compare(a.name, b.name); }
/// <summary>
/// Recalculate the position of all elements within the grid, sorting them alphabetically if necessary.
/// </summary>
[ContextMenu("Execute")]
public void Reposition ()
{
if (Application.isPlaying && !mInitDone && NGUITools.GetActive(this))
{
mReposition = true;
return;
}
if (!mInitDone) Init();
mReposition = false;
Transform myTrans = transform;
int x = 0;
int y = 0;
if (sorted)
{
List
<Transform
> list
= new List
<Transform
>();
for (int i = 0; i < myTrans.childCount; ++i)
{
Transform t = myTrans.GetChild(i);
if (t && (!hideInactive || NGUITools.GetActive(t.gameObject))) list.Add(t);
}
list.Sort(SortByName);
for (int i = 0, imax = list.Count; i < imax; ++i)
{
Transform t = list[i];
if (!NGUITools.GetActive(t.gameObject) && hideInactive) continue;
float depth = t.localPosition.z;
Vector3 pos = (arrangement == Arrangement.Horizontal) ?
new Vector3
(cellWidth
* x,
-cellHeight
* y, depth
) : new Vector3
(cellWidth
* y,
-cellHeight
* x, depth
);
if (animateSmoothly && Application.isPlaying)
{
SpringPosition.Begin(t.gameObject, pos, 15f);
}
else t.localPosition = pos;
if (++x >= maxPerLine && maxPerLine > 0)
{
x = 0;
++y;
}
}
}
else
{
for (int i = 0; i < myTrans.childCount; ++i)
{
Transform t = myTrans.GetChild(i);
if (!NGUITools.GetActive(t.gameObject) && hideInactive) continue;
float depth = t.localPosition.z;
Vector3 pos = (arrangement == Arrangement.Horizontal) ?
new Vector3
(cellWidth
* x,
-cellHeight
* y, depth
) : new Vector3
(cellWidth
* y,
-cellHeight
* x, depth
);
if (animateSmoothly && Application.isPlaying)
{
SpringPosition.Begin(t.gameObject, pos, 15f);
}
else t.localPosition = pos;
if (++x >= maxPerLine && maxPerLine > 0)
{
x = 0;
++y;
}
}
}
switch (alignment)
{
case Alignment.Left :
myTrans
.localPosition = new Vector3
(0f, myTrans
.localPosition.y, myTrans
.localPosition.z); break;
case Alignment.Centered :
float centerOffset = myTrans.childCount * cellWidth * 0.5f;
centerOffset = -centerOffset + (centerOffset * 1/myTrans.childCount);
myTrans
.localPosition = new Vector3
(centerOffset, myTrans
.localPosition.y, myTrans
.localPosition.z); break;
case Alignment.Right :
myTrans
.localPosition = new Vector3
(-(myTrans
.childCount - 1) * cellWidth, myTrans
.localPosition.y, myTrans
.localPosition.z); break;
}
if (keepWithinPanel && mPanel != null)
mPanel.ConstrainTargetToBounds(myTrans, true);
if (onReposition != null)
onReposition();
}
}