/******************************************************************************
* Copyright (C) Ultraleap, Inc. 2011-2021. *
* *
* Use subject to the terms of the Apache License 2.0 available at *
* http://www.apache.org/licenses/LICENSE-2.0, or another agreement *
* between Ultraleap and you, your company or other organization. *
******************************************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace Leap.Unity
{
///
/// This attribute is used to add items to the Leap Motion preferences window.
/// This allows each module to define their own preferences and still have them
/// all show up under the same window.
///
/// The usage is very similar to the built-in PreferenceItem attribute. You
/// add the attribute onto a static method that should be run whenever the
/// preference window is visited. This method is a gui method and should use
/// GuiLayout and EditorGuiLayout in order to draw the preferences. You can
/// specify the name of the preferences as well as an order value to specify
/// how the preferences are ordered relative to other preferences.
///
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class LeapPreferences : Attribute
{
public readonly string header;
public readonly int order;
public LeapPreferences(string header, int order)
{
this.header = header;
this.order = order;
}
#if UNITY_EDITOR
private static List _leapPreferenceItems = null;
private struct LeapPreferenceItem
{
public Action drawPreferenceGui;
public LeapPreferences attribute;
}
private static void ensurePreferenceItemsLoaded()
{
if (_leapPreferenceItems != null)
{
return;
}
_leapPreferenceItems = new List();
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (var type in assemblies.SelectMany(a => a.GetTypes()))
{
foreach (var method in type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static))
{
var attributes = method.GetCustomAttributes(typeof(LeapPreferences), inherit: true);
if (attributes.Length == 0)
{
continue;
}
var attribute = attributes[0] as LeapPreferences;
_leapPreferenceItems.Add(new LeapPreferenceItem()
{
drawPreferenceGui = () =>
{
EditorGUILayout.LabelField(attribute.header, EditorStyles.boldLabel);
using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox))
{
method.Invoke(null, null);
}
EditorGUILayout.Space();
EditorGUILayout.Space();
EditorGUILayout.Space();
},
attribute = attribute
});
}
}
_leapPreferenceItems.Sort((a, b) => a.attribute.order.CompareTo(b.attribute.order));
}
#if UNITY_2018_3_OR_NEWER
// Implementations Leap Motion settings using the new SettingsProvider API.
private class LeapMotionSettingsProvider : SettingsProvider
{
public LeapMotionSettingsProvider(string path, SettingsScope scopes = SettingsScope.User)
: base(path, scopes)
{ }
public override void OnGUI(string searchContext)
{
DrawPreferencesGUI();
}
}
[SettingsProvider]
static SettingsProvider GetSettingsProvider()
{
return new LeapMotionSettingsProvider("Preferences/Leap Motion");
}
#else
[PreferenceItem("Leap Motion")]
#endif
public static void DrawPreferencesGUI()
{
ensurePreferenceItemsLoaded();
foreach (var item in _leapPreferenceItems)
{
item.drawPreferenceGui();
}
}
#endif
}
}