Brak opisu
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

TextLimit.cs 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. using System;
  2. using UnityEngine;
  3. using UnityEngine.UI;
  4. namespace XCharts.Runtime
  5. {
  6. /// <summary>
  7. /// Text character limitation and adaptation component. When the length of the text exceeds the set length,
  8. /// it is cropped and suffixes are appended to the end.Only valid in the category axis.
  9. /// |文本字符限制和自适应。当文本长度超过设定的长度时进行裁剪,并将后缀附加在最后。
  10. /// 只在类目轴中有效。
  11. /// </summary>
  12. [Serializable]
  13. public class TextLimit : ChildComponent
  14. {
  15. [SerializeField] private bool m_Enable = false;
  16. [SerializeField] private float m_MaxWidth = 0;
  17. [SerializeField] private float m_Gap = 1;
  18. [SerializeField] private string m_Suffix = "...";
  19. /// <summary>
  20. /// Whether to enable text limit.
  21. /// |是否启用文本自适应。
  22. /// [default:true]
  23. /// </summary>
  24. public bool enable
  25. {
  26. get { return m_Enable; }
  27. set { if (PropertyUtil.SetStruct(ref m_Enable, value)) SetComponentDirty(); }
  28. }
  29. /// <summary>
  30. /// Set the maximum width. A default of 0 indicates automatic fetch; otherwise, custom.
  31. /// |Clipping occurs when the width of the text is greater than this value.
  32. /// |设定最大宽度。默认为0表示自动获取,否则表示自定义。当文本的宽度大于该值进行裁剪。
  33. /// </summary>
  34. public float maxWidth
  35. {
  36. get { return m_MaxWidth; }
  37. set { if (PropertyUtil.SetStruct(ref m_MaxWidth, value)) SetComponentDirty(); }
  38. }
  39. /// <summary>
  40. /// White pixel distance at both ends.
  41. /// |两边留白像素距离。
  42. /// [default:10f]
  43. /// </summary>
  44. public float gap
  45. {
  46. get { return m_Gap; }
  47. set { if (PropertyUtil.SetStruct(ref m_Gap, value)) SetComponentDirty(); }
  48. }
  49. /// <summary>
  50. /// Suffixes when the length exceeds.
  51. /// |长度超出时的后缀。
  52. /// [default: "..."]
  53. /// </summary>
  54. public string suffix
  55. {
  56. get { return m_Suffix; }
  57. set { if (PropertyUtil.SetClass(ref m_Suffix, value)) SetComponentDirty(); }
  58. }
  59. private ChartText m_RelatedText;
  60. private float m_RelatedTextWidth = 0;
  61. public TextLimit Clone()
  62. {
  63. var textLimit = new TextLimit();
  64. textLimit.enable = enable;
  65. textLimit.maxWidth = maxWidth;
  66. textLimit.gap = gap;
  67. textLimit.suffix = suffix;
  68. return textLimit;
  69. }
  70. public void Copy(TextLimit textLimit)
  71. {
  72. enable = textLimit.enable;
  73. maxWidth = textLimit.maxWidth;
  74. gap = textLimit.gap;
  75. suffix = textLimit.suffix;
  76. }
  77. public void SetRelatedText(ChartText txt, float labelWidth)
  78. {
  79. m_RelatedText = txt;
  80. m_RelatedTextWidth = labelWidth;
  81. }
  82. public string GetLimitContent(string content)
  83. {
  84. float checkWidth = m_MaxWidth > 0 ? m_MaxWidth : m_RelatedTextWidth;
  85. if (m_RelatedText == null || checkWidth <= 0)
  86. {
  87. return content;
  88. }
  89. else
  90. {
  91. if (m_Enable)
  92. {
  93. float len = m_RelatedText.GetPreferredWidth(content);
  94. float suffixLen = m_RelatedText.GetPreferredWidth(suffix);
  95. if (len >= checkWidth - m_Gap * 2)
  96. {
  97. return content.Substring(0, GetAdaptLength(content, suffixLen)) + suffix;
  98. }
  99. else
  100. {
  101. return content;
  102. }
  103. }
  104. else
  105. {
  106. return content;
  107. }
  108. }
  109. }
  110. private int GetAdaptLength(string content, float suffixLen)
  111. {
  112. int start = 0;
  113. int middle = content.Length / 2;
  114. int end = content.Length;
  115. float checkWidth = m_MaxWidth > 0 ? m_MaxWidth : m_RelatedTextWidth;
  116. float limit = checkWidth - m_Gap * 2 - suffixLen;
  117. if (limit < 0)
  118. return 0;
  119. float len = 0;
  120. while (len != limit && middle != start)
  121. {
  122. len = m_RelatedText.GetPreferredWidth(content.Substring(0, middle));
  123. if (len < limit)
  124. {
  125. start = middle;
  126. }
  127. else if (len > limit)
  128. {
  129. end = middle;
  130. }
  131. else
  132. {
  133. break;
  134. }
  135. middle = (start + end) / 2;
  136. }
  137. return middle;
  138. }
  139. }
  140. }