using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
namespace UnityEngine.Perception.GroundTruth
{
///
/// Heads up display panel used to publish a key value pair on the screen. Items added to this need
/// to have their values updated every frame, or else, they will be determined to be stale and removed
/// from the view and re-used for a new entry.
///
public class HUDPanel : MonoBehaviour
{
readonly Dictionary> m_Entries = new Dictionary>();
GUIStyle m_KeyStyle;
GUIStyle m_ValueStyle;
const int k_LineHeight = 22;
const int k_XPadding = 10;
const int k_YPadding = 10;
const int k_BoxWidth = 200;
const int k_YLineSpacing = 4;
const int k_MaxKeyLength = 20;
///
/// The number of labelers currently displaying real-time information on the visualization HUD
///
public int entryCount => m_Entries.Keys.Count();
void Awake()
{
m_KeyStyle = new GUIStyle
{
alignment = TextAnchor.MiddleLeft,
padding = new RectOffset(10, 10, 5, 5),
normal = {textColor = Color.white}
};
m_ValueStyle = new GUIStyle
{
alignment = TextAnchor.MiddleRight,
padding = new RectOffset(10, 10, 5, 5),
normal = {textColor = Color.white}
};
}
///
/// Updates (or creates) an entry with the passed in key value pair
///
/// The labeler that requested the HUD entry
/// The key of the HUD entry
/// The value of the entry
public void UpdateEntry(CameraLabeler labeler, string key, string value)
{
if (!m_Entries.ContainsKey(labeler))
{
m_Entries[labeler] = new Dictionary();
}
m_Entries[labeler][key] = value;
}
Vector2 m_ScrollPosition;
bool m_GUIStylesInitialized = false;
void SetUpGUIStyles()
{
GUI.skin.label.fontSize = 12;
GUI.skin.label.font = Resources.Load("Inter-Light");
GUI.skin.label.padding = new RectOffset(0, 0, 1, 1);
GUI.skin.label.margin = new RectOffset(0, 0, 1, 1);
GUI.skin.label.wordWrap = false;
GUI.skin.label.clipping = TextClipping.Clip;
GUI.skin.box.padding = new RectOffset(5, 5, 5, 5);
GUI.skin.toggle.margin = new RectOffset(0, 0, 0, 0);
GUI.skin.horizontalSlider.margin = new RectOffset(0, 0, 0, 0);
m_GUIStylesInitialized = true;
}
int EntriesCount()
{
return m_Entries.Count + m_Entries.Sum(entry => entry.Value.Count);
}
internal void OnDrawGUI()
{
if (m_Entries.Count == 0) return;
if (!m_GUIStylesInitialized) SetUpGUIStyles();
GUI.depth = 0; // Draw HUD objects on the top of other UI objects
var height = Math.Min(k_LineHeight * EntriesCount(), Screen.height * 0.5f - k_YPadding * 2);
var xPos = Screen.width - k_BoxWidth - k_XPadding;
var yPos = Screen.height - height - k_YPadding;
GUILayout.BeginArea(new Rect(xPos, yPos, k_BoxWidth, height), GUI.skin.box);
m_ScrollPosition = GUILayout.BeginScrollView(m_ScrollPosition);
var firstTime = true;
foreach (var labeler in m_Entries.Keys)
{
if (!firstTime) GUILayout.Space(k_YLineSpacing);
firstTime = false;
GUILayout.Label(labeler.GetType().Name);
foreach (var entry in m_Entries[labeler])
{
GUILayout.BeginHorizontal();
GUILayout.Space(5);
var k = new StringBuilder(entry.Key.Substring(0, Math.Min(entry.Key.Length, k_MaxKeyLength)));
if (k.Length != entry.Key.Length)
k.Append("...");
GUILayout.Label(k.ToString());
GUILayout.FlexibleSpace();
GUILayout.Label(entry.Value);
GUILayout.EndHorizontal();
}
}
GUILayout.EndScrollView();
GUILayout.EndArea();
}
///
/// Removes the key value pair from the HUD
///
/// The labeler that requested the removal
/// The key of the entry to remove
public void RemoveEntry(CameraLabeler labeler, string key)
{
if (m_Entries.ContainsKey(labeler))
{
m_Entries[labeler].Remove(key);
}
}
///
/// Removes all of the passed in entries from the HUD
///
/// The labeler that requested the removal
public void RemoveEntries(CameraLabeler labeler)
{
m_Entries.Remove(labeler);
}
}
}