123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349 |
- namespace textUtility
- {
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using textUtility;
- using UnityEngine;
- using UnityEngine.EventSystems;
- using UnityEngine.UI;
-
- [Serializable]
- public class RichTextImage : Image, IPointerClickHandler
- {
- #region Config
-
- private bool EnableOverflowClick;
- [SerializeField] private Button Button;
- [SerializeField] private RichText RichText;
-
- private List<BaseMatch> SpriteMatches = new List<BaseMatch>();
- private List<BaseMatch> UnderlineMatches = new List<BaseMatch>();
- private List<BaseMatch> SuperlinkMatches = new List<BaseMatch>();
- public RichTextImageManager ImageManager;
- private Dictionary<int, List<Vector3>> SuperlinkPositionsDictionary = new Dictionary<int, List<Vector3>>();
-
- #endregion
-
- protected override void OnPopulateMesh(VertexHelper toFill)
- {
- //Debug.Log(1);
-
- toFill.Clear();
-
- List<BaseMatch> baseMatches = new List<BaseMatch>();
- baseMatches.AddRange(SpriteMatches);
- baseMatches.AddRange(UnderlineMatches);
- baseMatches.AddRange(SuperlinkMatches);
- //Debug.Log(baseMatches.Count);
- List<int> triangles = new List<int>();
- List<UIVertex> vertices = new List<UIVertex>();
- foreach (var baseMatch in baseMatches)
- {
- List<List<UIVertex>> verticesList = GetRenderVerticesList(baseMatch);
- foreach (var tempVertices in verticesList)
- {
- triangles.AddRange(GetTriangles(vertices));
- vertices.AddRange(tempVertices);
- }
- }
- //Debug.Log(vertices.Count);
- //Debug.Log(triangles.Count);
- toFill.AddUIVertexStream(vertices, triangles);
- }
-
-
- public void AddMatch(BaseMatch baseMatch)
- {
- if (baseMatch is SpriteMatch)
- {
- SpriteMatches.Add(baseMatch);
- sprite = Sprite.Create((baseMatch as SpriteMatch).SpriteInfo.Sprite.texture, new Rect(), new Vector2(0.5f, 0.5f));
- }
- else if (baseMatch is UnderlineMatch)
- {
- UnderlineMatches.Add(baseMatch);
- }
- else if (baseMatch is SuperlinkMatch)
- {
- SuperlinkMatches.Add(baseMatch);
- if (EnableOverflowClick)
- {
- if (Button == null)
- {
- Button = gameObject.AddComponent<Button>();
- }
- Button.enabled = true;
- }
- }
- else
- {
- throw new Exception();
- }
- }
-
- public void ClearMatches()
- {
- SpriteMatches = new List<BaseMatch>();
- UnderlineMatches = new List<BaseMatch>();
- SuperlinkMatches = new List<BaseMatch>();
- SuperlinkPositionsDictionary = new Dictionary<int, List<Vector3>>();
- sprite = null;
- if (Button != null)
- {
- Button.enabled = false;
- }
- }
-
- private List<List<UIVertex>> GetRenderVerticesList(BaseMatch baseMatch)
- {
- if (baseMatch is SpriteMatch)
- {
- return GetSpriteRenderVerticesList(baseMatch);
- }
- else if (baseMatch is UnderlineMatch)
- {
- return GetUnderlineRenderVerticesList(baseMatch);
- }
- else if (baseMatch is SuperlinkMatch)
- {
- return GetSuperlinkRenderVerticesList(baseMatch);
- }
- else
- {
- throw new Exception();
- }
- }
-
- private List<List<UIVertex>> GetSpriteRenderVerticesList(BaseMatch baseMatch)
- {
- List<List<UIVertex>> verticesList = new List<List<UIVertex>>();
- SpriteMatch spriteMatch = (SpriteMatch) baseMatch;
- Vector3 middleCenter = new Vector3();
- float x;
- float y;
- int startIndex = spriteMatch.StartIndex;
- int endIndex = spriteMatch.EndIndex;
- if (startIndex == 0 || RichText.text[startIndex - 1] == '\n' || !RichText.IsSameLine(RichText.cachedTextGenerator, startIndex - 1, startIndex))
- {
- x = (ImageManager.Vertices[2 + endIndex*6].position.x + ImageManager.Vertices[4 + startIndex*6].position.x)/2;
- }
- else
- {
- startIndex--;
- x = (ImageManager.Vertices[2 + endIndex*6].position.x + ImageManager.Vertices[2 + startIndex*6].position.x)/2;
- }
- int lineIndex = RichText.GetLineIndex(RichText.cachedTextGenerator, startIndex);
- y = RichText.GetLineCenterY(lineIndex, RichText.cachedTextGenerator.lineCount);
- middleCenter.x = x;
- middleCenter.y = y;
- UIVertex upperLeft = new UIVertex();
- UIVertex upperRight = new UIVertex();
- UIVertex lowerRight = new UIVertex();
- UIVertex lowerLeft = new UIVertex();
- upperLeft.position = middleCenter + new Vector3(-spriteMatch.ScaledWidth/2, spriteMatch.ScaledHeight/2, 0);
- upperRight.position = middleCenter + new Vector3(spriteMatch.ScaledWidth/2, spriteMatch.ScaledHeight/2, 0);
- lowerRight.position = middleCenter + new Vector3(spriteMatch.ScaledWidth/2, -spriteMatch.ScaledHeight/2, 0);
- lowerLeft.position = middleCenter + new Vector3(-spriteMatch.ScaledWidth/2, -spriteMatch.ScaledHeight/2, 0);
- upperLeft.uv0 = spriteMatch.SpriteInfo.UVs[0];
- upperRight.uv0 = spriteMatch.SpriteInfo.UVs[1];
- lowerRight.uv0 = spriteMatch.SpriteInfo.UVs[2];
- lowerLeft.uv0 = spriteMatch.SpriteInfo.UVs[3];
- upperLeft.color = spriteMatch.SpriteInfo.SpriteSetting.Color;
- upperRight.color = spriteMatch.SpriteInfo.SpriteSetting.Color;
- lowerRight.color = spriteMatch.SpriteInfo.SpriteSetting.Color;
- lowerLeft.color = spriteMatch.SpriteInfo.SpriteSetting.Color;
- verticesList.Add(new List<UIVertex> {upperLeft, upperRight, lowerRight, lowerLeft});
- for (int i = 0; i < verticesList.Count; i++)
- {
- List<UIVertex> tempVertices = verticesList[i];
- Vector3 position0 = transform.TransformPoint(tempVertices[0].position);
- Vector3 position1 = transform.TransformPoint(tempVertices[1].position);
- Vector3 position2 = transform.TransformPoint(tempVertices[2].position);
- Vector3 position3 = transform.TransformPoint(tempVertices[3].position);
-
- Debug.DrawLine(position0, position1, Color.red, 999);
- Debug.DrawLine(position1, position2, Color.red, 999);
- Debug.DrawLine(position2, position3, Color.red, 999);
- Debug.DrawLine(position3, position0, Color.red, 999);
- }
- return verticesList;
- }
-
- private List<List<UIVertex>> GetUnderlineRenderVerticesList(BaseMatch baseMatch)
- {
- List<List<UIVertex>> verticesList = new List<List<UIVertex>>();
- UnderlineMatch underlineMatch = (UnderlineMatch) baseMatch;
- RichText.GetSegments(RichText.text, RichText.cachedTextGenerator, underlineMatch, underlineMatch.UnderlineSetting.UnderlineExcludeChars);
- for (int j = 0; j < underlineMatch.Segments.Count; j++)
- {
- int startIndex = underlineMatch.Segments[j][0];
- int endIndex = underlineMatch.Segments[j][1];
- int lineIndex = RichText.GetLineIndex(RichText.cachedTextGenerator, startIndex);
- float penPositionY = RichText.GetPenPositionY(lineIndex, RichText.cachedTextGenerator.lineCount);
- float charHeight = RichText.cachedTextGenerator.lines[lineIndex].height;
- Vector3 position0 = ImageManager.Vertices[4 + startIndex*6].position;
- Vector3 position1 = ImageManager.Vertices[2 + endIndex*6].position;
- position0.y = penPositionY;
- position1.y = penPositionY;
- Vector3 position2 = position1;
- Vector3 position3 = position0;
- position2.y -= charHeight* underlineMatch.UnderlineSetting.Scale;
- position3.y -= charHeight* underlineMatch.UnderlineSetting.Scale;
- UIVertex upperLeft = new UIVertex();
- UIVertex upperRight = new UIVertex();
- UIVertex lowerRight = new UIVertex();
- UIVertex lowerLeft = new UIVertex();
- upperLeft.position = position0;
- upperRight.position = position1;
- lowerRight.position = position2;
- lowerLeft.position = position3;
- upperLeft.color = underlineMatch.UnderlineSetting.Color;
- upperRight.color = underlineMatch.UnderlineSetting.Color;
- lowerRight.color = underlineMatch.UnderlineSetting.Color;
- lowerLeft.color = underlineMatch.UnderlineSetting.Color;
- verticesList.Add(new List<UIVertex> {upperLeft, upperRight, lowerRight, lowerLeft});
- position0 = transform.TransformPoint(position0);
- position1 = transform.TransformPoint(position1);
- position2 = transform.TransformPoint(position2);
- position3 = transform.TransformPoint(position3);
- Debug.DrawLine(position0, position1, Color.blue, 999);
- Debug.DrawLine(position1, position2, Color.blue, 999);
- Debug.DrawLine(position2, position3, Color.blue, 999);
- Debug.DrawLine(position3, position0, Color.blue, 999);
- }
- return verticesList;
- }
-
- private List<List<UIVertex>> GetSuperlinkRenderVerticesList(BaseMatch baseMatch)
- {
- List<List<UIVertex>> verticesList = new List<List<UIVertex>>();
- SuperlinkMatch superlinkMatch = (SuperlinkMatch)baseMatch;
- RichText.GetSegments(RichText.text, RichText.cachedTextGenerator, superlinkMatch, superlinkMatch.SuperlinkSetting.SuperlinkExcludeChars);
- for (int j = 0; j < superlinkMatch.Segments.Count; j++)
- {
- int startIndex = superlinkMatch.Segments[j][0];
- int endIndex = superlinkMatch.Segments[j][1];
- int lineIndex = RichText.GetLineIndex(RichText.cachedTextGenerator, startIndex);
- float lineCenterY = RichText.GetLineCenterY(lineIndex, RichText.cachedTextGenerator.lineCount);
- float lineHeight = RichText.cachedTextGenerator.lines[lineIndex].height;
- EnableOverflowClick = superlinkMatch.SuperlinkSetting.EnableOverflowClick;
- float lineMaxY = lineCenterY + (lineHeight/2)* superlinkMatch.SuperlinkSetting.Scale;
- float lineMinY = lineCenterY - (lineHeight/2)* superlinkMatch.SuperlinkSetting.Scale;
- List<Vector3> superlinkPositions = new List<Vector3>();
- Vector3 position0 = ImageManager.Vertices[4 + startIndex*6].position;
- Vector3 position1 = ImageManager.Vertices[2 + endIndex*6].position;
- Vector3 position2 = position1;
- Vector3 position3 = position0;
- position0.y = lineMinY;
- position1.y = lineMinY;
- position2.y = lineMaxY;
- position3.y = lineMaxY;
- superlinkPositions.Add(position0);
- superlinkPositions.Add(position1);
- superlinkPositions.Add(position2);
- superlinkPositions.Add(position3);
- SuperlinkPositionsDictionary.Add(superlinkMatch.ID, superlinkPositions);
- position0 = transform.TransformPoint(position0);
- position1 = transform.TransformPoint(position1);
- position2 = transform.TransformPoint(position2);
- position3 = transform.TransformPoint(position3);
- Debug.DrawLine(position0, position1, Color.green, 999);
- Debug.DrawLine(position1, position2, Color.green, 999);
- Debug.DrawLine(position2, position3, Color.green, 999);
- Debug.DrawLine(position3, position0, Color.green, 999);
- }
- return verticesList;
- }
-
- private List<int> GetTriangles(List<UIVertex> vertices)
- {
- List<int> triangles = new List<int>();
- triangles.Add(vertices.Count);
- triangles.Add(vertices.Count + 1);
- triangles.Add(vertices.Count + 2);
- triangles.Add(vertices.Count + 2);
- triangles.Add(vertices.Count + 3);
- triangles.Add(vertices.Count);
- return triangles;
- }
-
-
- public static RichTextImage CreateImage(RichText richText)
- {
- GameObject go = new GameObject("RichTextImage");
- go.transform.SetParent(richText.transform);
- RichTextImage image = go.AddComponent<RichTextImage>();
- image.RichText = richText;
- image.rectTransform.localPosition = Vector3.zero;
- image.rectTransform.localScale = Vector3.one;
- image.rectTransform.anchorMin = Vector2.zero;
- image.rectTransform.anchorMax = Vector2.one;
- image.rectTransform.offsetMin = Vector2.zero;
- image.rectTransform.offsetMax = Vector2.zero;
- image.rectTransform.sizeDelta = Vector2.zero;
- return image;
- }
-
-
- private void Update()
- {
- if (!EnableOverflowClick)
- {
- return;
- }
-
- if (Input.GetMouseButtonDown(0)) //Overflow的情况下检测超链接是否被点击
- {
- Graphic graphic = GetComponent<Graphic>();
- Graphic selectedGraphic = EventSystem.current.currentSelectedGameObject == null ? null : EventSystem.current.currentSelectedGameObject.GetComponent<Graphic>();
- if (selectedGraphic == null)
- {
- OnPointerClick(Input.mousePosition);
- }
- else if (graphic != selectedGraphic && graphic.depth > selectedGraphic.depth)
- {
- OnPointerClick(Input.mousePosition);
- }
- }
- }
-
- public void OnPointerClick(PointerEventData eventData)
- {
- //Vector3 clickPosition = eventData.position;
- //Debug.Log(clickPosition);
- OnPointerClick(eventData.position);
- }
-
- public void OnPointerClick(Vector3 worldPosition)
- {
- Vector3 clickPosition = rectTransform.InverseTransformPoint(worldPosition);
- foreach (var kv in SuperlinkPositionsDictionary)
- {
- float minX = kv.Value.MyMin(vector => vector.x).x;
- float maxX = kv.Value.MyMax(vector => vector.x).x;
- float minY = kv.Value.MyMin(vector => vector.y).y;
- float maxY = kv.Value.MyMax(vector => vector.y).y;
- //Debug.Log(clickPosition);
- //Debug.Log(minX + " " + maxX + " " + minY + " " + maxY);
- if ((minX <= clickPosition.x && clickPosition.x <= maxX) && (minY <= clickPosition.y && clickPosition.y <= maxY))
- {
- if (RichText.SuperlinkCallbackDictionary.ContainsKey(kv.Key))
- {
- RichText.SuperlinkCallbackDictionary[kv.Key].Invoke(kv.Key);
- }
- else
- {
- throw new Exception(string.Format("没有找到事件 id : {0}", kv.Key));
- }
- }
- }
- }
- }
- }
|