Files
tianrunCRM/Assets/CoolapeFrame/3rd/NGUI_Enhance/RichText4Chat/Scripts/UIRichText4Chat.cs
2020-07-04 14:41:25 +08:00

457 lines
13 KiB
C#
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/// <summary>
/// User interface rich text4 chat.
/// add by chenbin
/// 2016-03-22
/// </summary>
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
/// <summary>
/// User interface rich text4 chat.
/// </summary>
public class UIRichText4Chat : MonoBehaviour
{
public UILabel _label;
public UILabel label
{
get
{
if (_label == null)
{
_label = GetComponent<UILabel>();
}
return _label;
}
set
{
_label = value;
}
}
[HideInInspector]
public UIAtlas
faceAtlas;
//表情所在的图集
public string atlasName;
public int faceSize = 30;
public float faceScaleOffset = 1;
//表情图片的大小最好是font大小的整数倍当与字体是一样大小时为最宜
// public static List<string> faceList = new List<string> ();
public string faceHead = "";
public bool isFullSpace = true;
//用一个全角空格来占表情的位置,***因次使用的font中需要包含全角空格***
// [HideInInspector]
public float
spaceSize = -1;
public static string
_FaceChar_ = " ";
[HideInInspector]
public int
spaceNumber = -1;
[HideInInspector]
public string
faceStr = "";
public static SpritePool pool = new SpritePool();
public List<UISprite> spList = new List<UISprite>();
[ContextMenu("init")]
public void init()
{
if (isFullSpace)
{
_FaceChar_ = " "; //用一个全角空格来占表情的位置,***因次使用的font中需要包含全角空格***
}
else
{
_FaceChar_ = "."; //用半角空格来占位不知道为何有问题,因此用一个“.“来占位
}
calculateSpaceSize();
}
public void calculateSpaceSize()
{
string oldStr = label.text;
mTempVerts.Clear();
mTempIndices.Clear();
label.text = _FaceChar_;
string text = label.processedText;
label.UpdateNGUIText();
NGUIText.PrintExactCharacterPositions(text, mTempVerts, mTempIndices);
if (mTempVerts.size > 1)
{
spaceSize = mTempVerts[mTempVerts.size - 1].x - mTempVerts[0].x;
spaceNumber = Mathf.CeilToInt(faceSize / spaceSize);
}
mTempVerts.Clear();
mTempIndices.Clear();
label.text = oldStr;
faceStr = "";
for (int i = 0; i < spaceNumber; i++)
{
faceStr += _FaceChar_;
}
}
string mText = "";
public string value
{
get
{
return mText;
}
set
{
if (mText != value)
{
mText = value;
onTextChanged(gameObject);
}
}
}
public string wrapFaceName(string faceName)
{
return string.IsNullOrEmpty(faceHead) ? faceName : faceHead + faceName;
}
public void onInputChanged(GameObject go)
{
if (go == null)
return;
UIInput input = go.GetComponent<UIInput>();
if (input == null)
return;
value = input.value;
}
static BetterList<Vector3> mTempVerts = new BetterList<Vector3>();
static BetterList<int> mTempIndices = new BetterList<int>();
bool isFinishInit = false;
[ContextMenu("Execute Text Changed")]
public void onTextChanged(GameObject go)
{
if (!isFinishInit)
{
isFinishInit = true;
init();
}
clean();
mTempVerts.Clear();
mTempIndices.Clear();
string str = findFace();
label.text = str;
string text = label.processedText;
label.UpdateNGUIText();
NGUIText.PrintExactCharacterPositions(label.text, mTempVerts, mTempIndices);
// for (int i=0; i < mTempVerts.size; i++) {
// Debug.Log (mTempVerts [i]);
// }
ArrayList keyList = new ArrayList();
keyList.AddRange(facesMap.Keys);
int count = keyList.Count;
int index = 0;
string faceName = "";
Vector3 pos = Vector3.zero;
for (int i = 0; i < count; i++)
{
index = (int)(keyList[i]);
if (index * 2 + 1 < mTempVerts.size)
{
faceName = facesMap[index].ToString();
// Debug.Log ("index==" + index);
// Debug.Log("faceName==" + faceName);
pos = calculatePos(mTempVerts[index * 2], mTempVerts[index * 2 + 1]);
showFace(faceName, pos);
}
}
keyList.Clear();
mTempVerts.Clear();
mTempIndices.Clear();
}
/// <summary>
/// Calculates the position. search for #xx#
/// </summary>
/// <returns>The position.</returns>
/// <param name="pos1">Pos1.</param>
/// <param name="pos2">Pos2.</param>
public Vector3 calculatePos(Vector3 pos1, Vector3 pos2)
{
float offsetX = label.printedSize.x;
if (label.overflowMethod == UILabel.Overflow.ResizeHeight)
{
offsetX = label.localSize.x;
}
Vector3 pos = pos1;
Vector3 diff = pos2 - pos;
switch (label.pivot)
{
case UIWidget.Pivot.Center:
pos.x -= offsetX / 2.0f;
pos.y += label.printedSize.y / 2.0f;
pos.y += diff.y / 2.0f;
break;
case UIWidget.Pivot.TopLeft:
pos.y += diff.y / 2.0f;
break;
case UIWidget.Pivot.BottomLeft:
pos.y += label.printedSize.y;
pos.y += diff.y / 2.0f;
break;
case UIWidget.Pivot.Left:
pos.y += label.printedSize.y / 2.0f;
pos.y += diff.y / 2.0f;
break;
case UIWidget.Pivot.Right:
pos.x -= offsetX;
pos.y += label.printedSize.y / 2.0f;
pos.y += diff.y / 2.0f;
break;
case UIWidget.Pivot.TopRight:
pos.x -= offsetX;
pos.y += diff.y / 2.0f;
break;
case UIWidget.Pivot.BottomRight:
pos.x -= offsetX;
pos.y += label.printedSize.y;
pos.y += diff.y / 2.0f;
break;
case UIWidget.Pivot.Top:
pos.x -= offsetX / 2.0f;
pos.y += diff.y / 2.0f;
break;
case UIWidget.Pivot.Bottom:
pos.x -= offsetX / 2.0f;
pos.y += label.printedSize.y;
pos.y += diff.y / 2.0f;
break;
}
return pos;
}
public void showFace(string faceName, Vector3 pos)
{
UISprite sp = pool.getSprite();
spList.Add(sp);
NGUITools.SetLayer(sp.gameObject, gameObject.layer);
sp.pivot = UIWidget.Pivot.Left;
sp.atlas = faceAtlas;
sp.spriteName = wrapFaceName(faceName);
sp.SetDimensions(faceSize, faceSize);
sp.transform.parent = transform;
sp.transform.localScale = Vector3.one * faceScaleOffset;
if (sp.transform.parent == label.transform)
{
sp.transform.localPosition = pos;
}
else
{
sp.transform.localPosition = pos + label.transform.localPosition;
}
sp.depth = label.depth + 1;
NGUITools.SetActive(sp.gameObject, true);
}
Hashtable facesMap = new Hashtable();
public string findFace()
{
facesMap.Clear();
if (string.IsNullOrEmpty(value))
return "";
int len = value.Length;
string str = "";
int offset = 0;
string faceName = "";
for (int i = 0; i < len; i++)
{
// Debug.Log("val==[" + value[i] + "]");
if (value[i] == '\n')
{
offset += 1;
}
else if (value[i] == '\\' && (i + 1 < len) && value[i + 1] == 'n')
{
offset += 2;
}
else if (value[i] == '[' && i + 7 < len && value[i + 7] == ']')
{
offset += 8;
}
else if (value[i] == '[' && i + 2 < len && value[i + 1] == '-' && value[i + 2] == ']')
{
offset += 3;
}
// Debug.Log ("val==[" + value [i] + "]==" + offset);
if (value[i] == '#')
{
faceName = "";
for (int j = i + 1; j < len; j++)
{
if (value[j] == '\n')
{
offset += 1;
}
else if (value[j] == '\\' && (j + 1 < len) && value[j + 1] == 'n')
{
offset += 2;
}
else if (value[i] == '[' && i + 7 < len && value[i + 7] == ']')
{
offset += 8;
}
else if (value[i] == '[' && i + 2 < len && value[i + 1] == '-' && value[i + 2] == ']')
{
offset += 3;
}
// Debug.Log ("val==[" + value [j] + "]==" + offset);
if (value[j] == '#')
{
if (faceAtlas.spriteMap.Contains(wrapFaceName(faceName)))
{
facesMap[str.Length - offset] = faceName;
str += faceStr;
faceName = "";
i = j;
}
else
{
str += ("#" + faceName);
faceName = "";
i = j - 1;
}
break;
}
else
{
faceName += value[j];
if (j == len - 1)
{
i = j;
}
}
}
}
else
{
str += value[i];
}
}
if (!string.IsNullOrEmpty(faceName))
{
str += "#" + faceName;
}
return str;
}
[ContextMenu("Clean")]
public void clean()
{
int count = spList.Count;
for (int i = 0; i < count; i++)
{
pool.retSprite(spList[i]);
// spList [i].transform.parent = null;
// NGUITools.SetActive (spList [i].gameObject, false);
}
spList.Clear();
}
public void OnDestroy()
{
clean();
UISprite[] sps = label.GetComponentsInChildren<UISprite>(true);
int count = sps.Length;
for (int i = 0; i < count; i++)
{
if (sps[i].name == "__Sprite__")
{
sps[i].transform.parent = null;
}
}
}
public void OnDisable()
{
clean();
}
public void OnEnable()
{
onTextChanged(gameObject);
}
//图表对像池
public class SpritePool
{
Queue<UISprite> queue = new Queue<UISprite>();
public void clean()
{
queue.Clear();
}
public UISprite getSprite()
{
if (queue.Count <= 0)
{
return newSprite();
}
else
{
UISprite sp = queue.Dequeue();
try
{
if (sp == null && sp.gameObject == null)
{
return getSprite();
}
else
{
return sp;
}
}
catch (System.Exception e)
{
// Debug.LogError (e);
return getSprite();
}
}
}
public void retSprite(UISprite sp)
{
try
{
queue.Enqueue(sp);
NGUITools.SetActive(sp.gameObject, false);
//sp.gameObject.transform.parent = null;
}
catch (System.Exception e)
{
Debug.LogWarning(e);
}
}
public UISprite newSprite()
{
GameObject go = new GameObject("__Sprite__");
go.transform.parent = null;
UISprite sp = go.AddComponent<UISprite>();
NGUITools.SetActive(go, false);
return sp;
}
}
}