/// <summary>
/// Show the popup list dialog.
/// </summary>
public void Show ()
{
if (enabled && NGUITools.GetActive(gameObject) && mChild == null && atlas != null && isValid && items.Count > 0)
{
mLabelList.Clear();
// Automatically locate the panel responsible for this object
if (mPanel == null)
{
mPanel = UIPanel.Find(transform);
if (mPanel == null) return;
}
// Disable the navigation script
handleEvents = true;
// Calculate the dimensions of the object triggering the popup list so we can position it below it
Transform myTrans = transform;
Bounds bounds = NGUIMath.CalculateRelativeWidgetBounds(myTrans.parent, myTrans);
// Create the root object for the list
mChild = new GameObject("Drop-down List");
mChild.layer = gameObject.layer;
Transform t = mChild.transform;
t.parent = myTrans.parent;
t.localPosition = bounds.min;
t.localRotation = Quaternion.identity;
t.localScale = Vector3.one;
// Add a sprite for the background
mBackground = NGUITools.AddSprite(mChild, atlas, backgroundSprite);
mBackground.pivot = UIWidget.Pivot.TopLeft;
mBackground.depth = NGUITools.CalculateNextDepth(mPanel.gameObject);
mBackground.color = backgroundColor;
// We need to know the size of the background sprite for padding purposes
Vector4 bgPadding = mBackground.border;
mBgBorder = bgPadding.y;
mBackground.cachedTransform.localPosition = new Vector3(0f, bgPadding.y, 0f);
// Add a sprite used for the selection
mHighlight = NGUITools.AddSprite(mChild, atlas, highlightSprite);
mHighlight.pivot = UIWidget.Pivot.TopLeft;
mHighlight.color = highlightColor;
UISpriteData hlsp = mHighlight.GetAtlasSprite();
if (hlsp == null) return;
float hlspHeight = hlsp.borderTop;
float fontHeight = activeFontSize;
float dynScale = activeFontScale;
float labelHeight = fontHeight * dynScale;
float x = 0f, y = -padding.y;
int labelFontSize = (bitmapFont != null) ? bitmapFont.defaultSize : fontSize;
List<UILabel> labels = new List<UILabel>();
// Clear the selection if it's no longer present
if (!items.Contains(mSelectedItem))
mSelectedItem = null;
// Run through all items and create labels for each one
for (int i = 0, imax = items.Count; i < imax; ++i)
{
string s = items[i];
UILabel lbl = NGUITools.AddWidget<UILabel>(mChild);
lbl.name = i.ToString();
lbl.pivot = UIWidget.Pivot.TopLeft;
lbl.bitmapFont = bitmapFont;
lbl.trueTypeFont = trueTypeFont;
lbl.fontSize = labelFontSize;
lbl.fontStyle = fontStyle;
lbl.text = isLocalized ? Localization.Get(s) : s;
lbl.color = textColor;
lbl.cachedTransform.localPosition = new Vector3(bgPadding.x + padding.x, y, -1f);
lbl.overflowMethod = UILabel.Overflow.ResizeFreely;
lbl.alignment = alignment;
lbl.MakePixelPerfect();
if (dynScale != 1f) lbl.cachedTransform.localScale = Vector3.one * dynScale;
labels.Add(lbl);
y -= labelHeight;
y -= padding.y;
x = Mathf.Max(x, lbl.printedSize.x);
// Add an event listener
UIEventListener listener = UIEventListener.Get(lbl.gameObject);
listener.onHover = OnItemHover;
listener.onPress = OnItemPress;
listener.onClick = OnItemClick;
listener.parameter = s;
// Move the selection here if this is the right label
if (mSelectedItem == s || (i == 0 && string.IsNullOrEmpty(mSelectedItem)))
Highlight(lbl, true);
// Add this label to the list
mLabelList.Add(lbl);
}
// The triggering widget's width should be the minimum allowed width
x = Mathf.Max(x, bounds.size.x * dynScale - (bgPadding.x + padding.x) * 2f);
float cx = x / dynScale;
Vector3 bcCenter = new Vector3(cx * 0.5f, -fontHeight * 0.5f, 0f);
Vector3 bcSize = new Vector3(cx, (labelHeight + padding.y) / dynScale, 1f);
// Run through all labels and add colliders
for (int i = 0, imax = labels.Count; i < imax; ++i)
{
UILabel lbl = labels[i];
NGUITools.AddWidgetCollider(lbl.gameObject);
lbl.autoResizeBoxCollider = false;
BoxCollider bc = lbl.GetComponent<BoxCollider>();
if (bc != null)
{
bcCenter.z = bc.center.z;
bc.center = bcCenter;
bc.size = bcSize;
}
else
{
BoxCollider2D b2d = lbl.GetComponent<BoxCollider2D>();
b2d.offset = bcCenter;
b2d.size = bcSize;
}
}
int lblWidth = Mathf.RoundToInt(x);
x += (bgPadding.x + padding.x) * 2f;
y -= bgPadding.y;
// Scale the background sprite to envelop the entire set of items
mBackground.width = Mathf.RoundToInt(x);
mBackground.height = Mathf.RoundToInt(-y + bgPadding.y);
// Set the label width to make alignment work
for (int i = 0, imax = labels.Count; i < imax; ++i)
{
UILabel lbl = labels[i];
lbl.overflowMethod = UILabel.Overflow.ShrinkContent;
lbl.width = lblWidth;
}
// Scale the highlight sprite to envelop a single item
float scaleFactor = 2f * atlas.pixelSize;
float w = x - (bgPadding.x + padding.x) * 2f + hlsp.borderLeft * scaleFactor;
float h = labelHeight + hlspHeight * scaleFactor;
mHighlight.width = Mathf.RoundToInt(w);
mHighlight.height = Mathf.RoundToInt(h);
bool placeAbove = (position == Position.Above);
if (position == Position.Auto)
{
UICamera cam = UICamera.FindCameraForLayer(gameObject.layer);
if (cam != null)
{
Vector3 viewPos = cam.cachedCamera.WorldToViewportPoint(myTrans.position);
placeAbove = (viewPos.y < 0.5f);
}
}
// If the list should be animated, let's animate it by expanding it
if (isAnimated)
{
float bottom = y + labelHeight;
Animate(mHighlight, placeAbove, bottom);
for (int i = 0, imax = labels.Count; i < imax; ++i) Animate(labels[i], placeAbove, bottom);
AnimateColor(mBackground);
AnimateScale(mBackground, placeAbove, bottom);
}
// If we need to place the popup list above the item, we need to reposition everything by the size of the list
if (placeAbove)
{
t.localPosition = new Vector3(bounds.min.x, bounds.max.y - y - bgPadding.y, bounds.min.z);
}
}
else OnSelect(false);
}