RenderNodeBase.cs 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. using System.Collections.Generic;
  2. using UnityEngine;
  3. using UnityEngine.UI;
  4. namespace WXB
  5. {
  6. public enum EffectType
  7. {
  8. Null, // 无类型
  9. // 特效类型
  10. Shadow, // 阴影
  11. Outline, // 描边
  12. }
  13. public abstract class NodeBase
  14. {
  15. public Owner owner;
  16. float d_nextLineX = 0;
  17. protected float NextLineX = 0;
  18. public virtual void Reset(Owner o, Anchor hf)
  19. {
  20. d_bNewLine = false;
  21. owner = o;
  22. formatting = hf;
  23. d_nextLineX = 0;
  24. }
  25. protected static float AlignedFormatting(Owner owner, Anchor formatting, float maxWidth, float curWidth, float lineX)
  26. {
  27. if (formatting == Anchor.Null)
  28. formatting = owner.anchor;
  29. float value = 0.0f;
  30. switch (formatting)
  31. {
  32. case Anchor.UpperRight:
  33. case Anchor.MiddleRight:
  34. case Anchor.LowerRight:
  35. value = (maxWidth - curWidth);
  36. break;
  37. case Anchor.UpperLeft:
  38. case Anchor.MiddleLeft:
  39. case Anchor.LowerLeft:
  40. value = lineX;
  41. break;
  42. case Anchor.MiddleCenter:
  43. case Anchor.UpperCenter:
  44. case Anchor.LowerCenter:
  45. value = (maxWidth - curWidth) / 2;
  46. break;
  47. }
  48. return value;
  49. }
  50. public abstract float getHeight();
  51. public abstract float getWidth();
  52. public void setNewLine(bool line)
  53. {
  54. d_bNewLine = line;
  55. }
  56. public bool isNewLine()
  57. {
  58. return d_bNewLine;
  59. }
  60. public Anchor formatting = Anchor.Null;
  61. public abstract void render(
  62. float maxWidth,
  63. RenderCache cache,
  64. ref float x,
  65. ref uint yline,
  66. List<Line> lines,
  67. float offsetX,
  68. float offsetY);
  69. protected virtual void AlterX(ref float x, float maxWidth)
  70. {
  71. }
  72. // lineX下一行的偏移量
  73. public virtual void fill(ref Vector2 currentpos, List<Line> lines, float maxWidth, float pixelsPerUnit)
  74. {
  75. NextLineX = d_nextLineX * pixelsPerUnit;
  76. List<Element> TempList;
  77. UpdateWidthList(out TempList, pixelsPerUnit);
  78. float height = getHeight();
  79. AlterX(ref currentpos.x, maxWidth);
  80. if (TempList.Count == 0)
  81. return;
  82. Around around = owner.around;
  83. bool isContain = false; // 当前行是否包含此元素
  84. for (int i = 0; i < TempList.Count;)
  85. {
  86. float totalwidth = TempList[i].totalwidth;
  87. float newx = 0f;
  88. if (((currentpos.x + totalwidth) > maxWidth))
  89. {
  90. currentpos = TempList[i].Next(this, currentpos, lines, maxWidth, NextLineX, height, around, totalwidth, ref isContain);
  91. ++i;
  92. }
  93. else if (around != null && !around.isContain(currentpos.x, currentpos.y, totalwidth, height, out newx))
  94. {
  95. // 放置不下了
  96. currentpos.x = newx;
  97. }
  98. else
  99. {
  100. currentpos.x += totalwidth;
  101. isContain = true;
  102. ++i;
  103. }
  104. }
  105. Line bl = lines.back();
  106. bl.x = currentpos.x;
  107. bl.y = Mathf.Max(height, bl.y);
  108. if (d_bNewLine)
  109. {
  110. lines.Add(new Line(Vector2.zero));
  111. currentpos.y += height;
  112. currentpos.x = NextLineX;
  113. }
  114. }
  115. // 一个元素,此元素尽量要在同一行显示,如果当前是在行首,一行还放不下,那只能分行处理了
  116. public struct Element
  117. {
  118. public Element(List<float> ws)
  119. {
  120. #if UNITY_EDITOR
  121. text = string.Empty;
  122. #endif
  123. widthList = ws;
  124. totalWidth = 0f;
  125. for (int i = 0; i < widthList.Count; ++i)
  126. {
  127. totalWidth += ws[i];
  128. }
  129. }
  130. public Element(float width)
  131. {
  132. #if UNITY_EDITOR
  133. text = string.Empty;
  134. #endif
  135. totalWidth = width;
  136. widthList = null;
  137. }
  138. List<float> widthList;
  139. float totalWidth;
  140. public float totalwidth
  141. {
  142. get
  143. {
  144. return totalWidth;
  145. }
  146. }
  147. public List<float> widths
  148. {
  149. get { return widthList; }
  150. }
  151. public int count
  152. {
  153. get { return widthList == null ? 1 : widthList.Count; }
  154. }
  155. #if UNITY_EDITOR
  156. public string text;
  157. public override string ToString()
  158. {
  159. return string.Format("text:{0} w:{1}", text, totalwidth);
  160. }
  161. #endif
  162. public Vector2 Next(NodeBase n, Vector2 currentPos, List<Line> lines, float maxWidth, float lineX, float height, Around round, float tw, ref bool currentLineContain)
  163. {
  164. if (currentPos.x != 0f)
  165. {
  166. Line bl = lines.back();
  167. bl.x = currentPos.x;
  168. if (currentLineContain)
  169. {
  170. bl.y = Mathf.Max(bl.y, height);
  171. }
  172. // 当前行有数据,在新行里处理
  173. currentPos.x = lineX;
  174. currentPos.y += bl.y;
  175. currentLineContain = false;
  176. lines.Add(new Line(new Vector2(lineX, 0)));
  177. }
  178. else
  179. {
  180. // 当前行没有数据,直接在此行处理
  181. }
  182. if (round != null)
  183. {
  184. float newx = 0f;
  185. while (!round.isContain(currentPos.x, currentPos.y, tw, height, out newx))
  186. {
  187. currentPos.x = newx;
  188. if (currentPos.x + tw > maxWidth)
  189. {
  190. currentPos.x = lineX;
  191. lines.Add(new Line(new Vector2(lineX, height)));
  192. currentPos.y += height;
  193. }
  194. }
  195. }
  196. if (widthList != null)
  197. {
  198. for (int i = 0; i < widthList.Count; ++i)
  199. {
  200. currentPos = Add(n, currentPos, widthList[i], maxWidth, lineX, lines, height, ref currentLineContain);
  201. }
  202. }
  203. else
  204. {
  205. currentPos = Add(n, currentPos, totalWidth, maxWidth, lineX, lines, height, ref currentLineContain);
  206. }
  207. lines.back().x = currentPos.x;
  208. return currentPos;
  209. }
  210. Vector2 Add(NodeBase n, Vector2 currentPos, float width, float maxWidth, float lineX, List<Line> lines, float height, ref bool currentLineContain)
  211. {
  212. if (currentPos.x + width > maxWidth)
  213. {
  214. // 需要换新行了
  215. Line bl = lines.back();
  216. bl.x = currentPos.x;
  217. if (currentLineContain)
  218. bl.y = Mathf.Max(bl.y, height);
  219. currentPos.x = lineX + width;
  220. lines.Add(new Line(new Vector2(currentPos.x, height)));
  221. currentPos.y += height;
  222. }
  223. else
  224. {
  225. currentPos.x += width;
  226. }
  227. currentLineContain = true;
  228. return currentPos;
  229. }
  230. }
  231. protected static List<Element> TempElementList = new List<Element>();
  232. protected virtual void UpdateWidthList(out List<Element> widths, float pixelsPerUnit)
  233. {
  234. TempElementList.Clear();
  235. TempElementList.Add(new Element(getWidth()));
  236. widths = TempElementList;
  237. }
  238. public virtual void onMouseEnter()
  239. {
  240. }
  241. public virtual void onMouseLeave()
  242. {
  243. }
  244. protected bool d_bNewLine;
  245. public bool d_bBlink; // 是否闪烁
  246. public bool d_bOffset; // 偏移效果
  247. public Rect d_rectOffset; // 偏移范围
  248. public Color d_color;
  249. public LineAlignment lineAlignment = LineAlignment.Default;
  250. // 用户数据
  251. public object userdata { get; set; }
  252. public long keyPrefix
  253. {
  254. get
  255. {
  256. long key = 0;
  257. if (d_bBlink)
  258. key = 1 << 63;
  259. if (d_bOffset)
  260. {
  261. key += 1 << 62;
  262. key += ((byte)(d_rectOffset.xMin)) << 58;
  263. key += ((byte)(d_rectOffset.xMax)) << 54;
  264. key += ((byte)(d_rectOffset.yMin)) << 50;
  265. key += ((byte)(d_rectOffset.yMax)) << 46;
  266. }
  267. return key;
  268. }
  269. }
  270. public virtual void SetConfig(TextParser.Config c)
  271. {
  272. d_nextLineX = c.nextLineX;
  273. d_bBlink = c.isBlink;
  274. lineAlignment = c.lineAlignment;
  275. d_color = c.fontColor;
  276. d_bOffset = c.isOffset;
  277. if (c.isOffset)
  278. d_rectOffset = c.offsetRect;
  279. else
  280. d_rectOffset.Set(0, 0, 0, 0);
  281. }
  282. public virtual void Release()
  283. {
  284. d_color = Color.white;
  285. d_bNewLine = false;
  286. owner = null;
  287. formatting = Anchor.Null;
  288. d_bBlink = false;
  289. d_bOffset = false;
  290. d_rectOffset.Set(0, 0, 0, 0);
  291. userdata = null;
  292. }
  293. };
  294. }