using System;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine;
using UnityEngine.UIElements;
using UnityObject = UnityEngine.Object;
namespace Unity.Tutorials.Core.Editor
{
///
/// An utility class for common UIElements setup method
///
internal static class UIElementsUtils
{
internal static readonly string s_UIResourcesPath = $"Packages/{FrameworkSettings.k_PackageName}/Editor/UI/";
///
/// Loads an asset from the common UI resource folder.
///
/// type fo the file to load
/// name of the file
/// A reference to the loaded file
internal static T LoadUIAsset(string filename) where T : UnityObject => AssetDatabase.LoadAssetAtPath($"{s_UIResourcesPath}/{filename}");
internal static Button SetupButton(string buttonName, Action onClickAction, bool isEnabled, VisualElement parent, string text = "", string tooltip = "", bool showIfEnabled = true, bool localize = false)
{
Button button = parent.Query(buttonName);
button.SetEnabled(isEnabled);
button.clickable = new Clickable(() => onClickAction?.Invoke());
button.text = localize ? Localization.Tr(text) : text;
button.tooltip = string.IsNullOrEmpty(tooltip) ? button.text : tooltip;
if (showIfEnabled && isEnabled)
{
Show(button);
}
return button;
}
internal static Label SetupLabel(string labelName, string text, VisualElement parent, bool localize, Manipulator manipulator = null)
{
Label label = parent.Query(labelName);
label.text = localize ? Localization.Tr(text) : text;
if (manipulator != null)
{
label.AddManipulator(manipulator);
}
return label;
}
internal static Foldout SetupFoldout(string name, string text, VisualElement parent, bool localize, bool open)
{
Foldout foldout = parent.Query(name);
foldout.text = localize ? Localization.Tr(text) : text;
foldout.value = open;
return foldout;
}
internal static EnumField SetupEnumField(string enumName, string text, EventCallback> onValueChanged, VisualElement parent, T defaultValue, bool localize) where T : Enum
{
EnumField uxmlField = parent.Q(enumName);
uxmlField.label = localize ? Localization.Tr(text) : text;
uxmlField.Init(defaultValue);
uxmlField.value = defaultValue;
uxmlField.RegisterCallback(onValueChanged);
return uxmlField;
}
internal static EnumFlagsField SetupEnumFlagField(string enumName, string text, EventCallback> onValueChanged, VisualElement parent, T defaultValue, bool localize) where T : Enum
{
var uxmlField = parent.Q(enumName);
uxmlField.label = localize ? Localization.Tr(text) : text;
uxmlField.Init(defaultValue);
uxmlField.value = defaultValue;
uxmlField.RegisterCallback(onValueChanged);
return uxmlField;
}
internal static void SetupObjectField(string fieldName, EventCallback> onValueChanged, VisualElement parent, T defaultValue) where T : UnityEngine.Object
{
ObjectField spriteField = parent.Q(fieldName);
spriteField.objectType = typeof(T);
spriteField.value = defaultValue;
spriteField.RegisterCallback(onValueChanged);
}
internal static Toggle SetupToggle(string name, string label, string text, bool defaultValue, EventCallback> onValueChanged, VisualElement parent, bool localize)
{
Toggle uxmlField = parent.Q(name);
uxmlField.label = localize ? Localization.Tr(label) : label;
uxmlField.text = localize ? Localization.Tr(text) : text;
uxmlField.value = defaultValue;
uxmlField.SetEnabled(true);
uxmlField.RegisterCallback(onValueChanged);
return uxmlField;
}
internal static ToolbarSearchField SetupToolbarSearchField(string name, EventCallback> onValueChanged, VisualElement parent)
{
ToolbarSearchField uxmlField = parent.Q(name);
uxmlField.value = string.Empty;
uxmlField.SetEnabled(true);
uxmlField.RegisterCallback(onValueChanged);
return uxmlField;
}
internal static IntegerField SetupIntegerField(string name, int value, EventCallback> onValueChanged, VisualElement parent)
{
IntegerField uxmlField = parent.Q(name);
uxmlField.value = value;
uxmlField.SetEnabled(true);
uxmlField.RegisterCallback(onValueChanged);
return uxmlField;
}
internal static TextField SetupStringField(string name, string localizationKey, string value, EventCallback> onValueChanged, VisualElement parent, bool localize)
{
TextField uxmlField = parent.Q(name);
uxmlField.label = localize ? Localization.Tr(localizationKey) : localizationKey;
uxmlField.value = value;
uxmlField.SetEnabled(true);
uxmlField.RegisterCallback(onValueChanged);
return uxmlField;
}
internal static void ShowOrHide(string elementName, VisualElement parent, bool show)
{
if (show)
{
Show(elementName, parent);
return;
}
Hide(elementName, parent);
}
internal static void Hide(string elementName, VisualElement parent)
{
Hide(parent.Query(elementName));
}
internal static void Show(string elementName, VisualElement parent)
{
Show(parent.Query(elementName));
}
internal static void Hide(VisualElement element)
{
element.style.display = DisplayStyle.None;
}
internal static void Show(VisualElement element)
{
element.style.display = DisplayStyle.Flex;
}
internal static VisualTreeAsset LoadUXML(string fileName)
{
string path = $"{s_UIResourcesPath}{fileName}.uxml";
return AssetDatabase.LoadAssetAtPath(path);
}
internal static void LoadSkinStyleSheet(out StyleSheet styleSheet, VisualElement target)
{
string theme = EditorGUIUtility.isProSkin ? "_Dark" : "_Light";
string themedStyleSheet = $"{s_UIResourcesPath}Styles{theme}.uss";
styleSheet = AssetDatabase.LoadAssetAtPath(themedStyleSheet);
target.styleSheets.Add(styleSheet);
}
internal static void LoadCommonStyleSheet(VisualElement target)
{
string commonStyleSheetFilePath = $"{s_UIResourcesPath}Styles.uss";
var styleSheet = AssetDatabase.LoadAssetAtPath(commonStyleSheetFilePath);
target.styleSheets.Add(styleSheet);
}
internal static void RemoveStyleSheet(StyleSheet styleSheet, VisualElement target)
{
if (!styleSheet) { return; }
if (!target.styleSheets.Contains(styleSheet)) { return; }
target.styleSheets.Remove(styleSheet);
}
}
///
/// Represents a MouseManipulator that allows a visual element to react when left clicked
///
internal class LeftClickManipulator : MouseManipulator
{
Action m_OnClick;
bool m_Active;
///
/// Initializes and returns an instance of LeftClickManipulator.
///
/// The default callback that will be triggered when the element is clicked
public LeftClickManipulator(Action OnClick)
{
activators.Add(new ManipulatorActivationFilter { button = MouseButton.LeftMouse });
m_OnClick = OnClick;
}
protected override void RegisterCallbacksOnTarget()
{
target.RegisterCallback(OnMouseDown);
target.RegisterCallback(OnMouseUp);
}
protected override void UnregisterCallbacksFromTarget()
{
target.UnregisterCallback(OnMouseUp);
target.UnregisterCallback(OnMouseDown);
}
///
/// Called when the mouse is clicked on the target, when the user starts pressing the button
///
///
protected void OnMouseDown(MouseDownEvent e)
{
if (m_Active)
{
e.StopImmediatePropagation();
return;
}
if (CanStartManipulation(e))
{
m_Active = true;
target.CaptureMouse();
e.StopPropagation();
}
}
///
/// Called when the mouse is clicked on the target, when the user stops pressing the button
///
///
protected void OnMouseUp(MouseUpEvent e)
{
if (!m_Active || !target.HasMouseCapture() || !CanStopManipulation(e)) { return; }
m_Active = false;
target.ReleaseMouse();
e.StopPropagation();
if (m_OnClick == null) { return; }
m_OnClick.Invoke(target);
}
}
}