/*
* @author Valentin Simonov / http://va.lent.in/
*/
using System.Text;
using TouchScript.Pointers;
using TouchScript.Utils;
using UnityEngine;
using UnityEngine.UI;
namespace TouchScript.Behaviors.Cursors
{
///
/// Abstract class for pointer cursors with text.
///
/// Pointer type.
///
public abstract class TextPointerCursor : PointerCursor where T : IPointer
{
#region Public properties
///
/// Should the value of be shown on screen on the cursor.
///
public bool ShowPointerId = true;
///
/// Should the value of be shown on screen on the cursor.
///
public bool ShowFlags = false;
///
/// The link to UI.Text component.
///
public Text Text;
#endregion
#region Private variables
private static StringBuilder stringBuilder = new StringBuilder(64);
#endregion
#region Protected methods
///
protected override void updateOnce(IPointer pointer)
{
base.updateOnce(pointer);
if (Text == null) return;
if (!textIsVisible())
{
Text.enabled = false;
return;
}
Text.enabled = true;
stringBuilder.Length = 0;
generateText((T) pointer, stringBuilder);
Text.text = stringBuilder.ToString();
}
///
/// Generates text for pointer.
///
/// The pointer.
/// The string builder to use.
protected virtual void generateText(T pointer, StringBuilder str)
{
if (ShowPointerId)
{
str.Append("Id: ");
str.Append(pointer.Id);
}
if (ShowFlags)
{
if (str.Length > 0) str.Append("\n");
str.Append("Flags: ");
BinaryUtils.ToBinaryString(pointer.Flags, str, 8);
}
}
///
/// Indicates if text should be visible.
///
/// True if pointer text should be displayed; false otherwise.
protected virtual bool textIsVisible()
{
return ShowPointerId || ShowFlags;
}
///
/// Typed version of . Returns a hash of a cursor state.
///
/// The pointer.
/// Integer hash.
protected virtual uint gethash(T pointer)
{
var hash = (uint) state;
if (ShowFlags) hash += pointer.Flags << 3;
return hash;
}
///
protected sealed override uint getPointerHash(IPointer pointer)
{
return gethash((T) pointer);
}
#endregion
}
///
/// Visual cursor implementation used by TouchScript.
///
[HelpURL("http://touchscript.github.io/docs/html/T_TouchScript_Behaviors_Cursors_PointerCursor.htm")]
public class PointerCursor : MonoBehaviour
{
#region Consts
///
/// Possible states of a cursor.
///
public enum CursorState
{
///
/// Not pressed.
///
Released,
///
/// Pressed.
///
Pressed,
///
/// Over something.
///
Over,
///
/// Over and pressed.
///
OverPressed
}
#endregion
#region Public properties
///
/// Cursor size in pixels.
///
public float Size
{
get { return size; }
set
{
size = value;
if (size > 0)
{
rect.sizeDelta = Vector2.one * size;
}
else
{
size = 0;
rect.sizeDelta = Vector2.one * defaultSize;
}
}
}
#endregion
#region Private variables
///
/// Current cursor state.
///
protected CursorState state;
///
/// CUrrent cursor state data.
///
protected object stateData;
///
/// Cached RectTransform.
///
protected RectTransform rect;
///
/// Cached Canvas.
///
protected Canvas canvas;
///
/// Cursor size.
///
protected float size = 0;
///
/// Initial cursor size in pixels.
///
protected float defaultSize;
///
/// Last data hash.
///
protected uint hash = uint.MaxValue;
#endregion
#region Public methods
///
/// Initializes (resets) the cursor.
///
/// Parent container.
/// Pointer this cursor represents.
public void Init(RectTransform parent, IPointer pointer)
{
hash = uint.MaxValue;
show();
rect.SetParent(parent);
rect.SetAsLastSibling();
state = CursorState.Released;
UpdatePointer(pointer);
}
///
/// Updates the pointer. This method is called when the pointer is moved.
///
/// Pointer this cursor represents.
public void UpdatePointer(IPointer pointer)
{
rect.anchoredPosition = pointer.Position;
var newHash = getPointerHash(pointer);
if (newHash != hash) updateOnce(pointer);
hash = newHash;
update(pointer);
}
///
/// Sets the state of the cursor.
///
/// The pointer.
/// The new state.
/// State data.
public void SetState(IPointer pointer, CursorState newState, object data = null)
{
state = newState;
stateData = data;
var newHash = getPointerHash(pointer);
if (newHash != hash) updateOnce(pointer);
hash = newHash;
}
///
/// Hides this instance.
///
public void Hide()
{
hide();
}
#endregion
#region Unity methods
private void Awake()
{
rect = transform as RectTransform;
if (rect == null)
{
Debug.LogError("PointerCursor must be on an UI element!");
enabled = false;
return;
}
canvas = GetComponent