using System;
using UnityEngine;
using UnityEngine.UIElements;
namespace UnityEditor.Tilemaps.External
{
///
/// Label that can be renamed.
///
class RenameableLabel : VisualElement
{
static readonly string k_USSFilePath = "Packages/com.unity.2d.tilemap/Editor/UI/External/RenameableLabel.uss";
public static readonly string ussClassName = "u2d-renameable-label";
///
/// Text to display.
///
internal string text
{
get => label.text;
set => label.text = value;
}
internal bool isRenaming { get; set; }
internal event Action renameEnding;
Label label { get; } = new();
TextField textField { get; } = new();
internal RenameableLabel() : base()
{
name = ussClassName;
AddToClassList(ussClassName);
styleSheets.Add(AssetDatabase.LoadAssetAtPath(k_USSFilePath));
focusable = true;
delegatesFocus = false;
Add(label);
Add(textField);
label.RegisterCallback(OnLabelMouseUpEvent);
textField.selectAllOnFocus = true;
textField.selectAllOnMouseUp = false;
textField.style.display = DisplayStyle.None;
textField.RegisterCallback(OnMouseUpEvent);
textField.RegisterCallback(OnKeyDownEvent);
textField.RegisterCallback(OnBlurEvent);
}
internal void BeginRename()
{
if (isRenaming)
return;
isRenaming = true;
delegatesFocus = true;
label.style.display = DisplayStyle.None;
textField.style.display = DisplayStyle.Flex;
textField.value = text;
textField.Q().Focus();
}
internal void CancelRename()
{
if (isRenaming)
EndRename(false);
}
void EndRename(bool canceled = false)
{
isRenaming = false;
delegatesFocus = false;
schedule.Execute(Focus);
textField.style.display = DisplayStyle.None;
label.style.display = DisplayStyle.Flex;
if (!canceled) // When the rename is canceled, the label keep its current value.
label.text = textField.value;
renameEnding?.Invoke(this, canceled);
}
void OnLabelMouseUpEvent(MouseUpEvent evt)
{
if (isRenaming)
return;
BeginRename();
evt.StopPropagation();
}
void OnMouseUpEvent(MouseUpEvent evt)
{
if (!isRenaming)
return;
textField.Q().Focus();
evt.StopPropagation();
}
void OnKeyDownEvent(KeyDownEvent evt)
{
if (isRenaming && evt.keyCode == KeyCode.Escape)
EndRename(true);
}
void OnBlurEvent(BlurEvent evt)
{
if (!isRenaming)
return;
EndRename();
}
}
}