/******************************************/
/* */
/* Copyright (c) 2018 monitor1394 */
/* https://github.com/monitor1394 */
/* */
/******************************************/
using System;
using UnityEngine;
using UnityEngine.UI;
namespace XCharts
{
///
/// 文本字符限制和自适应。当文本长度超过设定的长度时进行裁剪,并将后缀附加在最后。
/// 只在类目轴中有效。
///
[Serializable]
public class TextLimit : SubComponent
{
[SerializeField] private bool m_Enable = true;
[SerializeField] private float m_MaxWidth = 0;
[SerializeField] private float m_Gap = 1;
[SerializeField] private string m_Suffix = "...";
///
/// 是否启用文本自适应。默认为true。
///
public bool enable
{
get { return m_Enable; }
set { if (PropertyUtility.SetStruct(ref m_Enable, value)) SetComponentDirty(); }
}
///
/// 设定最大宽度。默认为0表示自动获取,否则表示自定义。当文本的宽度大于该值进行裁剪。
///
public float maxWidth
{
get { return m_MaxWidth; }
set { if (PropertyUtility.SetStruct(ref m_MaxWidth, value)) SetComponentDirty(); }
}
///
/// 两边留白像素距离。默认为10
///
public float gap
{
get { return m_Gap; }
set { if (PropertyUtility.SetStruct(ref m_Gap, value)) SetComponentDirty(); }
}
///
/// 长度超出时的后缀。
///
public string suffix
{
get { return m_Suffix; }
set { if (PropertyUtility.SetClass(ref m_Suffix, value)) SetComponentDirty(); }
}
private Text m_RelatedText;
private TextGenerationSettings m_RelatedTextSettings;
private float m_RelatedTextWidth = 0;
public void SetRelatedText(Text txt, float labelWidth)
{
m_RelatedText = txt;
m_RelatedTextSettings = txt.GetGenerationSettings(Vector2.zero);
m_RelatedTextWidth = labelWidth;
}
public string GetLimitContent(string content)
{
float checkWidth = m_MaxWidth > 0 ? m_MaxWidth : m_RelatedTextWidth;
if (m_RelatedText == null || checkWidth <= 0) return content;
else
{
if (m_Enable)
{
float len = m_RelatedText.cachedTextGenerator.GetPreferredWidth(content, m_RelatedTextSettings);
float suffixLen = m_RelatedText.cachedTextGenerator.GetPreferredWidth(suffix, m_RelatedTextSettings);
if (len >= checkWidth - m_Gap * 2)
{
return content.Substring(0, GetAdaptLength(content, suffixLen)) + suffix;
}
else
{
return content;
}
}
else
{
return content;
}
}
}
private int GetAdaptLength(string content, float suffixLen)
{
int start = 0;
int middle = content.Length / 2;
int end = content.Length;
float checkWidth = m_MaxWidth > 0 ? m_MaxWidth : m_RelatedTextWidth;
float limit = checkWidth - m_Gap * 2 - suffixLen;
if (limit < 0) return 0;
float len = 0;
while (len != limit && middle != start)
{
len = m_RelatedText.cachedTextGenerator.GetPreferredWidth(content.Substring(0, middle), m_RelatedTextSettings);
if (len < limit)
{
start = middle;
}
else if (len > limit)
{
end = middle;
}
else
{
break;
}
middle = (start + end) / 2;
}
return middle;
}
}
}