Skip to content

Instantly share code, notes, and snippets.

@jimkang
Created December 7, 2012 01:53
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jimkang/4230096 to your computer and use it in GitHub Desktop.
Save jimkang/4230096 to your computer and use it in GitHub Desktop.
Subclass of NGUI's UIGrid that adds support for variable size cells. Update: Turns out it's mostly unnecessary; UITable does much of the same - DOH
using UnityEngine;
using System.Collections.Generic;
// This is a subclass of NGUI's UIGrid that supports cells of varying sizes,
// in addition to fixed sizes.
// http://ghostcrabworkshop.com
public class UIVariableCellSizeGrid : UIGrid
{
// If neither of these is set to true, spacing will be exactly as it
// is in UIGrid.
public bool useCellCollidersForHeight = false;
public bool useCellCollidersForWidth = false;
// Set this delegate to sort the cells in a different way.
// Should return 0 if both should be at the same rank.
// Should return a positive value if a ranks higher than b.
// Should return a negative value if b ranks higher than a.
public delegate int SortDelegate(Transform a, Transform b);
public SortDelegate customSortMethod = null;
protected int sortMethod(Transform a, Transform b)
{
if (this.customSortMethod != null)
{
return this.customSortMethod(a, b);
}
else
{
return UIGrid.SortByName(a, b);
}
}
public override void Reposition()
{
if (!mStarted)
{
repositionNow = true;
return;
}
Transform myTrans = transform;
int x = 0;
int y = 0;
int rightEdgeOfPrevVariableCell = 0;
int bottomEdgeOfPrevVariableCell = 0;
if (sorted)
{
List<Transform> list = new List<Transform>();
for (int i = 0; i < myTrans.childCount; ++i)
{
Transform t = myTrans.GetChild(i);
if (t) list.Add(t);
}
list.Sort(this.sortMethod);
for (int i = 0, imax = list.Count; i < imax; ++i)
{
Transform t = list[i];
this.updateCellTransformPosition(t, x, y,
ref rightEdgeOfPrevVariableCell,
ref bottomEdgeOfPrevVariableCell);
if (++x >= maxPerLine && maxPerLine > 0)
{
x = 0;
++y;
}
}
}
else
{
for (int i = 0; i < myTrans.childCount; ++i)
{
Transform t = myTrans.GetChild(i);
this.updateCellTransformPosition(t, x, y,
ref rightEdgeOfPrevVariableCell,
ref bottomEdgeOfPrevVariableCell);
if (++x >= maxPerLine && maxPerLine > 0)
{
x = 0;
++y;
}
}
}
UIDraggablePanel drag = NGUITools.FindInParents<UIDraggablePanel>(gameObject);
if (drag != null) drag.UpdateScrollbars(true);
}
// Updates the position of the given transform and updates the
// rightEdgeOfPrevVariableCell and bottomEdgeOfPrevVariableCell params, if we're in
// variable cell size mode.
protected void updateCellTransformPosition(Transform t, int col, int row,
ref int rightOfLastCell, ref int bottomOfLastCell)
{
if (!NGUITools.GetActive(t.gameObject) && hideInactive) return;
float depth = t.localPosition.z;
int cellX = 0;
int cellY = 0;
if (arrangement == Arrangement.Horizontal)
{
if (this.useCellCollidersForWidth)
{
Vector3 cellSize =
UIVariableCellSizeGrid.colliderSizeForTransform(t);
// The current cell's center should go at the right edge of the
// last cell plus half the width of the current cell.
int cellHalfWidth = (int)(cellSize.x/2);
cellX = rightOfLastCell + cellHalfWidth;
// Record the right edge of this cell for the next iteration's
// use.
rightOfLastCell = cellX + cellHalfWidth;
}
else
{
cellX = (int)(cellWidth * col);
}
cellY = (int)(-cellHeight * row);
}
else // Arrangement.Vertical
{
cellX = (int)(cellWidth * row);
if (this.useCellCollidersForHeight)
{
Vector3 cellSize =
UIVariableCellSizeGrid.colliderSizeForTransform(t);
// The current cell's center should go at the bottom edge of the
// last cell plus half the height of the current cell.
int cellHalfHeight = (int)(cellSize.y/2);
cellY = bottomOfLastCell - cellHalfHeight;
// Record the right edge of this cell for the next
// iteration's use.
bottomOfLastCell = cellY - cellHalfHeight;
}
else
{
cellY = (int)(cellWidth * row);
}
}
// Using ints even though Vector3 takes floats to avoid half-pixel
// values.
t.localPosition = new Vector3((float)cellX, (float)cellY, depth);
}
static protected Vector3 colliderSizeForTransform(Transform transform)
{
Collider collider = transform.gameObject.GetComponent<Collider>();
if (collider)
{
return collider.bounds.size;
}
else
{
return Vector3.zero;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment