270 lines
9.7 KiB
C#
270 lines
9.7 KiB
C#
|
using System.Collections.Generic;
|
||
|
using System.Text;
|
||
|
using UnityEngine;
|
||
|
using UnityEngine.UI;
|
||
|
using XUGL;
|
||
|
|
||
|
namespace XCharts.Runtime
|
||
|
{
|
||
|
public class TooltipViewItem
|
||
|
{
|
||
|
public GameObject gameObject;
|
||
|
public List<ChartLabel> columns = new List<ChartLabel>();
|
||
|
}
|
||
|
public class TooltipView
|
||
|
{
|
||
|
private static Vector2 anchorMax = new Vector2(0, 1);
|
||
|
private static Vector2 anchorMin = new Vector2(0, 1);
|
||
|
private static Vector2 pivot = new Vector2(0, 1);
|
||
|
private static Vector2 v2_0_05 = new Vector2(0, 0.5f);
|
||
|
|
||
|
public Tooltip tooltip;
|
||
|
public ComponentTheme theme;
|
||
|
public GameObject gameObject;
|
||
|
public Transform transform;
|
||
|
public Image background;
|
||
|
public Outline border;
|
||
|
public VerticalLayoutGroup layout;
|
||
|
public ChartLabel title;
|
||
|
private List<TooltipViewItem> m_Items = new List<TooltipViewItem>();
|
||
|
private List<float> m_ColumnMaxWidth = new List<float>();
|
||
|
private bool m_Active = false;
|
||
|
private Vector3 m_TargetPos;
|
||
|
private Vector3 m_CurrentVelocity;
|
||
|
|
||
|
public void Update()
|
||
|
{
|
||
|
if (!m_Active)
|
||
|
return;
|
||
|
transform.localPosition = Vector3.SmoothDamp(transform.localPosition, m_TargetPos, ref m_CurrentVelocity, 0.08f);
|
||
|
}
|
||
|
|
||
|
public Vector3 GetCurrentPos()
|
||
|
{
|
||
|
return transform.localPosition;
|
||
|
}
|
||
|
|
||
|
public Vector3 GetTargetPos()
|
||
|
{
|
||
|
return m_TargetPos;
|
||
|
}
|
||
|
|
||
|
public void UpdatePosition(Vector3 pos)
|
||
|
{
|
||
|
m_TargetPos = pos;
|
||
|
}
|
||
|
|
||
|
public void SetActive(bool flag)
|
||
|
{
|
||
|
m_Active = flag && tooltip.showContent;
|
||
|
ChartHelper.SetActive(gameObject, m_Active);
|
||
|
}
|
||
|
|
||
|
public void Refresh()
|
||
|
{
|
||
|
if (tooltip == null) return;
|
||
|
var data = tooltip.context.data;
|
||
|
|
||
|
var titleActive = !string.IsNullOrEmpty(data.title);
|
||
|
if (titleActive != title.gameObject.activeSelf)
|
||
|
title.gameObject.SetActive(titleActive);
|
||
|
title.SetText(data.title);
|
||
|
|
||
|
m_ColumnMaxWidth.Clear();
|
||
|
for (int i = 0; i < data.param.Count; i++)
|
||
|
{
|
||
|
var item = GetItem(i);
|
||
|
var param = data.param[i];
|
||
|
if (param.columns.Count <= 0)
|
||
|
{
|
||
|
item.gameObject.SetActive(false);
|
||
|
continue;
|
||
|
}
|
||
|
item.gameObject.SetActive(true);
|
||
|
for (int j = 0; j < param.columns.Count; j++)
|
||
|
{
|
||
|
var column = GetItemColumn(item, j);
|
||
|
column.SetActive(true);
|
||
|
column.SetText(param.columns[j]);
|
||
|
|
||
|
if (j == 0)
|
||
|
column.text.SetColor(param.color);
|
||
|
|
||
|
if (j >= m_ColumnMaxWidth.Count)
|
||
|
m_ColumnMaxWidth.Add(0);
|
||
|
|
||
|
var columnWidth = column.GetWidth();
|
||
|
if (m_ColumnMaxWidth[j] < columnWidth)
|
||
|
m_ColumnMaxWidth[j] = columnWidth;
|
||
|
}
|
||
|
for (int j = param.columns.Count; j < item.columns.Count; j++)
|
||
|
{
|
||
|
item.columns[j].SetActive(false);
|
||
|
}
|
||
|
}
|
||
|
for (int i = data.param.Count; i < m_Items.Count; i++)
|
||
|
{
|
||
|
m_Items[i].gameObject.SetActive(false);
|
||
|
}
|
||
|
ResetSize();
|
||
|
// border.effectColor = data.param.Count == 1
|
||
|
// ? data.param[0].color
|
||
|
// : tooltip.borderColor;
|
||
|
UpdatePosition(tooltip.context.pointer + tooltip.offset);
|
||
|
tooltip.gameObject.transform.SetAsLastSibling();
|
||
|
}
|
||
|
|
||
|
private void ResetSize()
|
||
|
{
|
||
|
var maxHig = 0f;
|
||
|
var maxWid = 0f;
|
||
|
if (tooltip.fixedWidth > 0)
|
||
|
{
|
||
|
maxWid = tooltip.fixedWidth;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
maxWid = TotalMaxWidth();
|
||
|
var titleWid = title.GetTextWidth();
|
||
|
if (maxWid < titleWid)
|
||
|
maxWid = titleWid;
|
||
|
}
|
||
|
|
||
|
if (tooltip.fixedHeight > 0)
|
||
|
{
|
||
|
maxHig = tooltip.fixedHeight;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (!string.IsNullOrEmpty(title.text.GetText()))
|
||
|
maxHig += tooltip.titleHeight;
|
||
|
maxHig += tooltip.itemHeight * tooltip.context.data.param.Count;
|
||
|
maxHig += tooltip.paddingTopBottom * 2;
|
||
|
}
|
||
|
|
||
|
if (tooltip.minWidth > 0 && maxWid < tooltip.minWidth)
|
||
|
maxWid = tooltip.minWidth;
|
||
|
|
||
|
if (tooltip.minHeight > 0 && maxHig < tooltip.minHeight)
|
||
|
maxHig = tooltip.minHeight;
|
||
|
|
||
|
for (int i = 0; i < m_Items.Count; i++)
|
||
|
{
|
||
|
var item = m_Items[i];
|
||
|
item.gameObject.GetComponent<RectTransform>().sizeDelta = new Vector2(maxWid, tooltip.itemHeight);
|
||
|
var xPos = 0f;
|
||
|
for (int j = 0; j < m_ColumnMaxWidth.Count; j++)
|
||
|
{
|
||
|
var deltaX = j == m_ColumnMaxWidth.Count - 1 ? maxWid - xPos : m_ColumnMaxWidth[j];
|
||
|
item.columns[j].text.SetSizeDelta(new Vector2(deltaX, tooltip.itemHeight));
|
||
|
item.columns[j].SetRectPosition(new Vector3(xPos, 0));
|
||
|
xPos += m_ColumnMaxWidth[j];
|
||
|
}
|
||
|
}
|
||
|
tooltip.context.width = maxWid + tooltip.paddingLeftRight * 2;
|
||
|
tooltip.context.height = maxHig;
|
||
|
background.GetComponent<RectTransform>().sizeDelta = new Vector2(tooltip.context.width, tooltip.context.height);
|
||
|
}
|
||
|
|
||
|
private float TotalMaxWidth()
|
||
|
{
|
||
|
var total = 0f;
|
||
|
foreach (var max in m_ColumnMaxWidth)
|
||
|
total += max;
|
||
|
return total;
|
||
|
}
|
||
|
|
||
|
private TooltipViewItem GetItem(int i)
|
||
|
{
|
||
|
if (i < 0) i = 0;
|
||
|
if (i < m_Items.Count)
|
||
|
{
|
||
|
return m_Items[i];
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
var item = CreateViewItem(i, gameObject.transform, tooltip, theme);
|
||
|
m_Items.Add(item);
|
||
|
return item;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private ChartLabel GetItemColumn(TooltipViewItem item, int i)
|
||
|
{
|
||
|
if (i < 0) i = 0;
|
||
|
if (i < item.columns.Count)
|
||
|
{
|
||
|
return item.columns[i];
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
var column = CreateViewItemColumn(i, item.gameObject.transform, tooltip, theme);
|
||
|
item.columns.Add(column);
|
||
|
return column;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static TooltipView CreateView(Tooltip tooltip, ThemeStyle theme, Transform parent)
|
||
|
{
|
||
|
var view = new TooltipView();
|
||
|
view.tooltip = tooltip;
|
||
|
view.theme = theme.tooltip;
|
||
|
|
||
|
view.gameObject = ChartHelper.AddObject("view", parent, anchorMin, anchorMax, pivot, Vector3.zero);
|
||
|
view.gameObject.transform.localPosition = Vector3.zero;
|
||
|
view.transform = view.gameObject.transform;
|
||
|
|
||
|
view.background = ChartHelper.GetOrAddComponent<Image>(view.gameObject);
|
||
|
view.background.sprite = tooltip.backgroundImage;
|
||
|
view.background.type = tooltip.backgroundType;
|
||
|
view.background.color = ChartHelper.IsClearColor(tooltip.backgroundColor) ?
|
||
|
Color.white : tooltip.backgroundColor;
|
||
|
|
||
|
view.border = ChartHelper.GetOrAddComponent<Outline>(view.gameObject);
|
||
|
view.border.enabled = tooltip.borderWidth > 0;
|
||
|
view.border.useGraphicAlpha = false;
|
||
|
view.border.effectColor = tooltip.borderColor;
|
||
|
view.border.effectDistance = new Vector2(tooltip.borderWidth, -tooltip.borderWidth);
|
||
|
|
||
|
view.layout = ChartHelper.GetOrAddComponent<VerticalLayoutGroup>(view.gameObject);
|
||
|
view.layout.childControlHeight = false;
|
||
|
view.layout.childControlWidth = false;
|
||
|
view.layout.childForceExpandHeight = false;
|
||
|
view.layout.childForceExpandWidth = false;
|
||
|
view.layout.padding = new RectOffset(tooltip.paddingLeftRight,
|
||
|
tooltip.paddingLeftRight,
|
||
|
tooltip.paddingTopBottom,
|
||
|
tooltip.paddingTopBottom);
|
||
|
|
||
|
view.title = ChartHelper.AddChartLabel("title", view.gameObject.transform, tooltip.titleLabelStyle, theme.tooltip,
|
||
|
"", Color.clear, TextAnchor.MiddleLeft);
|
||
|
|
||
|
var item = CreateViewItem(0, view.gameObject.transform, tooltip, theme.tooltip);
|
||
|
view.m_Items.Add(item);
|
||
|
|
||
|
view.Refresh();
|
||
|
|
||
|
return view;
|
||
|
}
|
||
|
|
||
|
private static TooltipViewItem CreateViewItem(int i, Transform parent, Tooltip tooltip, ComponentTheme theme)
|
||
|
{
|
||
|
GameObject item1 = ChartHelper.AddObject("item" + i, parent, anchorMin, anchorMax, v2_0_05, Vector3.zero);
|
||
|
|
||
|
var item = new TooltipViewItem();
|
||
|
item.gameObject = item1;
|
||
|
item.columns.Add(CreateViewItemColumn(0, item1.transform, tooltip, theme));
|
||
|
item.columns.Add(CreateViewItemColumn(1, item1.transform, tooltip, theme));
|
||
|
item.columns.Add(CreateViewItemColumn(2, item1.transform, tooltip, theme));
|
||
|
return item;
|
||
|
}
|
||
|
|
||
|
private static ChartLabel CreateViewItemColumn(int i, Transform parent, Tooltip tooltip, ComponentTheme theme)
|
||
|
{
|
||
|
var labelStyle = tooltip.GetContentLabelStyle(i);
|
||
|
var label = ChartHelper.AddChartLabel("column" + i, parent, labelStyle, theme,
|
||
|
"", Color.clear, TextAnchor.MiddleLeft);
|
||
|
return label;
|
||
|
}
|
||
|
}
|
||
|
}
|