mirror of
https://github.com/storytold/Azure-Kinect-Sample-for-Unity.git
synced 2026-10-13 23:53:23 +00:00
sample
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 42064bc130be4c44b288d249a44b356f
|
||||
timeCreated: 1504191962
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
using UnityEngine.Experimental.UIElements;
|
||||
|
||||
namespace UnityEditor.PackageManager.UI
|
||||
{
|
||||
#if !UNITY_2018_3_OR_NEWER
|
||||
internal class AlertFactory : UxmlFactory<Alert>
|
||||
{
|
||||
protected override Alert DoCreate(IUxmlAttributes bag, CreationContext cc)
|
||||
{
|
||||
return new Alert();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
internal class Alert : VisualElement
|
||||
{
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
internal new class UxmlFactory : UxmlFactory<Alert> { }
|
||||
#endif
|
||||
|
||||
private const string TemplatePath = PackageManagerWindow.ResourcesPath + "Templates/Alert.uxml";
|
||||
private readonly VisualElement root;
|
||||
private const float originalPositionRight = 5.0f;
|
||||
private const float positionRightWithScroll = 12.0f;
|
||||
|
||||
public Action OnCloseError;
|
||||
|
||||
public Alert()
|
||||
{
|
||||
UIUtils.SetElementDisplay(this, false);
|
||||
|
||||
root = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>(TemplatePath).CloneTree(null);
|
||||
Add(root);
|
||||
root.StretchToParentSize();
|
||||
|
||||
CloseButton.clickable.clicked += () =>
|
||||
{
|
||||
if (null != OnCloseError)
|
||||
OnCloseError();
|
||||
ClearError();
|
||||
};
|
||||
}
|
||||
|
||||
public void SetError(Error error)
|
||||
{
|
||||
var message = "An error occured.";
|
||||
if (error != null)
|
||||
message = error.message ?? string.Format("An error occurred ({0})", error.errorCode.ToString());
|
||||
|
||||
AlertMessage.text = message;
|
||||
UIUtils.SetElementDisplay(this, true);
|
||||
}
|
||||
|
||||
public void ClearError()
|
||||
{
|
||||
UIUtils.SetElementDisplay(this, false);
|
||||
AdjustSize(false);
|
||||
AlertMessage.text = "";
|
||||
OnCloseError = null;
|
||||
}
|
||||
|
||||
public void AdjustSize(bool verticalScrollerVisible)
|
||||
{
|
||||
if (verticalScrollerVisible)
|
||||
style.positionRight = originalPositionRight + positionRightWithScroll;
|
||||
else
|
||||
style.positionRight = originalPositionRight;
|
||||
}
|
||||
|
||||
private Label AlertMessage { get { return root.Q<Label>("alertMessage"); } }
|
||||
private Button CloseButton { get { return root.Q<Button>("close"); } }
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b274f3d1ea05d4bd8a13f4556f7797d2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.Experimental.UIElements;
|
||||
|
||||
namespace UnityEditor.PackageManager.UI
|
||||
{
|
||||
#if !UNITY_2018_3_OR_NEWER
|
||||
internal class LoadingSpinnerFactory : UxmlFactory<LoadingSpinner>
|
||||
{
|
||||
protected override LoadingSpinner DoCreate(IUxmlAttributes bag, CreationContext cc)
|
||||
{
|
||||
return new LoadingSpinner();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
internal class LoadingSpinner : VisualElement
|
||||
{
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
internal new class UxmlFactory : UxmlFactory<LoadingSpinner, UxmlTraits>
|
||||
{
|
||||
}
|
||||
|
||||
// This works around an issue with UXML instantiation
|
||||
// See https://fogbugz.unity3d.com/f/cases/1046459/
|
||||
internal new class UxmlTraits : VisualElement.UxmlTraits
|
||||
{
|
||||
public override void Init(VisualElement ve, IUxmlAttributes bag, CreationContext cc)
|
||||
{
|
||||
base.Init(ve, bag, cc);
|
||||
UIUtils.SetElementDisplay(ve, false);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
public bool InvertColor { get; set; }
|
||||
public bool Started { get; private set; }
|
||||
|
||||
private int rotation;
|
||||
|
||||
public LoadingSpinner()
|
||||
{
|
||||
InvertColor = false;
|
||||
Started = false;
|
||||
UIUtils.SetElementDisplay(this, false);
|
||||
}
|
||||
|
||||
private void UpdateProgress()
|
||||
{
|
||||
if (parent == null)
|
||||
return;
|
||||
|
||||
parent.transform.rotation = Quaternion.Euler(0, 0, rotation);
|
||||
rotation += 3;
|
||||
if (rotation > 360)
|
||||
rotation -= 360;
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
if (Started)
|
||||
return;
|
||||
|
||||
// Weird hack to make sure loading spinner doesn't generate an error every frame.
|
||||
// Cannot put in constructor as it give really strange result.
|
||||
if (parent != null && parent.parent != null)
|
||||
parent.parent.clippingOptions = ClippingOptions.ClipAndCacheContents;
|
||||
|
||||
rotation = 0;
|
||||
|
||||
EditorApplication.update += UpdateProgress;
|
||||
|
||||
Started = true;
|
||||
UIUtils.SetElementDisplay(this, true);
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
if (!Started)
|
||||
return;
|
||||
|
||||
EditorApplication.update -= UpdateProgress;
|
||||
|
||||
Started = false;
|
||||
UIUtils.SetElementDisplay(this, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 06f8e3404d534cab82fe852ff33dad77
|
||||
timeCreated: 1504191988
|
||||
+186
@@ -0,0 +1,186 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Experimental.UIElements;
|
||||
|
||||
namespace UnityEditor.PackageManager.UI
|
||||
{
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
internal class PopupField<T> : Experimental.UIElements.PopupField<T>
|
||||
{
|
||||
private Func<T, string> m_Callback;
|
||||
|
||||
public override T value
|
||||
{
|
||||
get { return base.value; }
|
||||
set
|
||||
{
|
||||
base.value = value;
|
||||
if (m_Callback != null)
|
||||
m_TextElement.text = m_Callback(m_Value);
|
||||
else
|
||||
m_TextElement.text = m_Value.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Callback that will return the string to be set in the field's label.
|
||||
/// </summary>
|
||||
/// <param name="callback"></param>
|
||||
public void SetLabelCallback(Func<T, string> callback)
|
||||
{
|
||||
m_Callback = callback;
|
||||
}
|
||||
|
||||
public PopupField(List<T> choices, T defaultValue) :
|
||||
base(choices, defaultValue)
|
||||
{
|
||||
}
|
||||
|
||||
public PopupField(List<T> choices, int defaultIndex) :
|
||||
base(choices, defaultIndex)
|
||||
{
|
||||
}
|
||||
}
|
||||
#else
|
||||
internal class PopupField<T> : BaseTextElement, INotifyValueChanged<T>
|
||||
{
|
||||
private readonly List<T> m_PossibleValues;
|
||||
private Func<T, string> m_Callback;
|
||||
private EventCallback<ChangeEvent<T>> m_valueCallback;
|
||||
private T m_Value;
|
||||
public T value
|
||||
{
|
||||
get { return m_Value; }
|
||||
set
|
||||
{
|
||||
if (EqualityComparer<T>.Default.Equals(m_Value, value))
|
||||
return;
|
||||
|
||||
if (!m_PossibleValues.Contains(value))
|
||||
throw new ArgumentException(string.Format("Value {0} is not present in the list of possible values", value));
|
||||
|
||||
m_Value = value;
|
||||
m_Index = m_PossibleValues.IndexOf(m_Value);
|
||||
if (m_Callback != null)
|
||||
text = m_Callback(m_Value);
|
||||
else
|
||||
text = m_Value.ToString();
|
||||
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
MarkDirtyRepaint();
|
||||
#else
|
||||
Dirty(ChangeType.Repaint);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
private int m_Index = -1;
|
||||
public int index
|
||||
{
|
||||
get { return m_Index; }
|
||||
set
|
||||
{
|
||||
if (value != m_Index)
|
||||
{
|
||||
if (value >= m_PossibleValues.Count || value < 0)
|
||||
throw new ArgumentException(string.Format("Index {0} is beyond the scope of possible value", value));
|
||||
m_Index = value;
|
||||
this.value = m_PossibleValues[m_Index];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Callback that will return the string to be set in the field's label.
|
||||
/// </summary>
|
||||
/// <param name="callback"></param>
|
||||
public void SetLabelCallback(Func<T, string> callback)
|
||||
{
|
||||
m_Callback = callback;
|
||||
}
|
||||
|
||||
private PopupField(List<T> possibleValues)
|
||||
{
|
||||
if (possibleValues == null)
|
||||
throw new ArgumentNullException("possibleValues can't be null");
|
||||
|
||||
m_PossibleValues = possibleValues;
|
||||
|
||||
AddToClassList("popupField");
|
||||
}
|
||||
|
||||
public PopupField(List<T> possibleValues, T defaultValue) :
|
||||
this(possibleValues)
|
||||
{
|
||||
if (defaultValue == null)
|
||||
throw new ArgumentNullException("defaultValue can't be null");
|
||||
|
||||
if (!m_PossibleValues.Contains(defaultValue))
|
||||
throw new ArgumentException(string.Format("Default value {0} is not present in the list of possible values", defaultValue));
|
||||
|
||||
// note: idx will be set when setting value
|
||||
value = defaultValue;
|
||||
}
|
||||
|
||||
public PopupField(List<T> possibleValues, int defaultIndex) :
|
||||
this(possibleValues)
|
||||
{
|
||||
if (defaultIndex >= m_PossibleValues.Count || defaultIndex < 0)
|
||||
throw new ArgumentException(string.Format("Default Index {0} is beyond the scope of possible value", value));
|
||||
|
||||
// note: value will be set when setting idx
|
||||
index = defaultIndex;
|
||||
}
|
||||
|
||||
public void SetValueAndNotify(T newValue)
|
||||
{
|
||||
if (!EqualityComparer<T>.Default.Equals(newValue, value))
|
||||
{
|
||||
using (ChangeEvent<T> evt = ChangeEvent<T>.GetPooled(value, newValue))
|
||||
{
|
||||
value = newValue;
|
||||
if (m_valueCallback != null)
|
||||
m_valueCallback(evt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void OnValueChanged(EventCallback<ChangeEvent<T>> callback)
|
||||
{
|
||||
m_valueCallback = callback;
|
||||
RegisterCallback(callback);
|
||||
}
|
||||
|
||||
protected override void ExecuteDefaultAction(EventBase evt)
|
||||
{
|
||||
base.ExecuteDefaultAction(evt);
|
||||
|
||||
if (evt.GetEventTypeId() == MouseDownEvent.TypeId())
|
||||
OnMouseDown();
|
||||
}
|
||||
|
||||
private void OnMouseDown()
|
||||
{
|
||||
var menu = new GenericMenu();
|
||||
|
||||
foreach (T item in m_PossibleValues)
|
||||
{
|
||||
bool isSelected = EqualityComparer<T>.Default.Equals(item, value);
|
||||
menu.AddItem(new GUIContent(item.ToString()), isSelected,
|
||||
() => ChangeValueFromMenu(item));
|
||||
}
|
||||
|
||||
var menuPosition = new Vector2(0.0f, layout.height);
|
||||
menuPosition = this.LocalToWorld(menuPosition);
|
||||
var menuRect = new Rect(menuPosition, Vector2.zero);
|
||||
menu.DropDown(menuRect);
|
||||
}
|
||||
|
||||
private void ChangeValueFromMenu(T menuItem)
|
||||
{
|
||||
SetValueAndNotify(menuItem);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9e69df8ff024a4dc1a9e5c22725e4863
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
using UnityEngine.Experimental.UIElements;
|
||||
|
||||
namespace UnityEditor.PackageManager.UI
|
||||
{
|
||||
internal static class UIUtils
|
||||
{
|
||||
private const string DisplayNone = "display-none";
|
||||
|
||||
public static void SetElementDisplay(VisualElement element, bool value)
|
||||
{
|
||||
if (element == null)
|
||||
return;
|
||||
|
||||
if (value)
|
||||
element.RemoveFromClassList(DisplayNone);
|
||||
else
|
||||
element.AddToClassList(DisplayNone);
|
||||
|
||||
element.visible = value;
|
||||
}
|
||||
|
||||
public static void SetElementDisplayNonEmpty(Label element)
|
||||
{
|
||||
if (element == null)
|
||||
return;
|
||||
|
||||
var empty = string.IsNullOrEmpty(element.text);
|
||||
if (empty)
|
||||
element.AddToClassList(DisplayNone);
|
||||
else
|
||||
element.RemoveFromClassList(DisplayNone);
|
||||
|
||||
element.visible = !empty;
|
||||
}
|
||||
|
||||
public static void SetElementDisplayNonEmpty(Button element)
|
||||
{
|
||||
if (element == null)
|
||||
return;
|
||||
|
||||
var empty = string.IsNullOrEmpty(element.text);
|
||||
if (empty)
|
||||
element.AddToClassList(DisplayNone);
|
||||
else
|
||||
element.RemoveFromClassList(DisplayNone);
|
||||
|
||||
element.visible = !empty;
|
||||
}
|
||||
|
||||
public static bool IsElementVisible(VisualElement element)
|
||||
{
|
||||
return element.visible && !element.ClassListContains(DisplayNone);
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0edd86f97b0648f685604a5582cff608
|
||||
timeCreated: 1508956933
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
namespace UnityEditor.PackageManager.UI
|
||||
{
|
||||
internal class VersionItem
|
||||
{
|
||||
internal PackageInfo Version;
|
||||
|
||||
public string MenuName { get; set; }
|
||||
|
||||
// Base label
|
||||
public string Label
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Version == null)
|
||||
return MenuName;
|
||||
|
||||
var label = Version.VersionWithoutTag;
|
||||
|
||||
return label;
|
||||
}
|
||||
}
|
||||
|
||||
public string DropdownLabel
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Version == null)
|
||||
return MenuName;
|
||||
|
||||
var label = MenuName + Label;
|
||||
|
||||
if (Version.IsLocal)
|
||||
label += " - local";
|
||||
if (Version.IsCurrent)
|
||||
label += " - current";
|
||||
if (Version.IsVerified)
|
||||
label += " - verified";
|
||||
else if (!string.IsNullOrEmpty(Version.Version.Prerelease))
|
||||
label += string.Format(" - {0}", Version.Version.Prerelease);
|
||||
else if (Version.IsPreview)
|
||||
label += " - preview";
|
||||
|
||||
return label;
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return DropdownLabel;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(obj, null)) return false;
|
||||
if (ReferenceEquals(this, obj)) return true;
|
||||
|
||||
var other = (VersionItem)obj;
|
||||
return Version == other.Version;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Version.GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3877b2be7ee07495d8918dc8937e6de2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bfd715cd54ab84c22b128149c12b516c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
using UnityEngine.Experimental.UIElements;
|
||||
|
||||
namespace UnityEditor.PackageManager.UI
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface for Package Manager UI Extension
|
||||
/// </summary>
|
||||
public interface IPackageManagerExtension
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates the extension UI visual element.
|
||||
/// </summary>
|
||||
/// <returns>A visual element that represents the UI or null if none</returns>
|
||||
VisualElement CreateExtensionUI();
|
||||
|
||||
/// <summary>
|
||||
/// Called by the Package Manager UI when the package selection changed.
|
||||
/// </summary>
|
||||
/// <param name="packageInfo">The newly selected package information (can be null)</param>
|
||||
void OnPackageSelectionChange(PackageManager.PackageInfo packageInfo);
|
||||
|
||||
/// <summary>
|
||||
/// Called by the Package Manager UI when a package is added or updated.
|
||||
/// </summary>
|
||||
/// <param name="packageInfo">The package information</param>
|
||||
void OnPackageAddedOrUpdated(PackageManager.PackageInfo packageInfo);
|
||||
|
||||
/// <summary>
|
||||
/// Called by the Package Manager UI when a package is removed.
|
||||
/// </summary>
|
||||
/// <param name="packageInfo">The package information</param>
|
||||
void OnPackageRemoved(PackageManager.PackageInfo packageInfo);
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 66083b7f6dc2e433eae33f3244b2ce88
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+134
@@ -0,0 +1,134 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.Experimental.UIElements;
|
||||
|
||||
namespace UnityEditor.PackageManager.UI
|
||||
{
|
||||
#if !UNITY_2018_3_OR_NEWER
|
||||
internal class PackageAddFromUrlFieldFactory : UxmlFactory<PackageAddFromUrlField>
|
||||
{
|
||||
protected override PackageAddFromUrlField DoCreate(IUxmlAttributes bag, CreationContext cc)
|
||||
{
|
||||
return new PackageAddFromUrlField();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
internal class PackageAddFromUrlField : VisualElement
|
||||
{
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
internal new class UxmlFactory : UxmlFactory<PackageAddFromUrlField> { }
|
||||
#endif
|
||||
private string urlText;
|
||||
|
||||
private readonly VisualElement root;
|
||||
|
||||
public PackageAddFromUrlField()
|
||||
{
|
||||
root = Resources.GetTemplate("PackageAddFromUrlField.uxml");
|
||||
Add(root);
|
||||
|
||||
UrlTextField.value = urlText;
|
||||
|
||||
AddButton.SetEnabled(!string.IsNullOrEmpty(urlText));
|
||||
AddButton.clickable.clicked += OnAddButtonClick;
|
||||
|
||||
RegisterCallback<AttachToPanelEvent>(OnEnterPanel);
|
||||
RegisterCallback<DetachFromPanelEvent>(OnLeavePanel);
|
||||
}
|
||||
|
||||
private void OnUrlTextFieldChange(ChangeEvent<string> evt)
|
||||
{
|
||||
urlText = evt.newValue;
|
||||
AddButton.SetEnabled(!string.IsNullOrEmpty(urlText));
|
||||
}
|
||||
|
||||
private void OnUrlTextFieldFocus(FocusEvent evt)
|
||||
{
|
||||
Show();
|
||||
}
|
||||
|
||||
private void OnUrlTextFieldFocusOut(FocusOutEvent evt)
|
||||
{
|
||||
Hide();
|
||||
}
|
||||
|
||||
private void OnContainerFocus(FocusEvent evt)
|
||||
{
|
||||
UrlTextField.Focus();
|
||||
}
|
||||
|
||||
private void OnContainerFocusOut(FocusOutEvent evt)
|
||||
{
|
||||
Hide();
|
||||
}
|
||||
|
||||
private void OnEnterPanel(AttachToPanelEvent evt)
|
||||
{
|
||||
AddFromUrlFieldContainer.RegisterCallback<FocusEvent>(OnContainerFocus);
|
||||
AddFromUrlFieldContainer.RegisterCallback<FocusOutEvent>(OnContainerFocusOut);
|
||||
UrlTextField.RegisterCallback<FocusEvent>(OnUrlTextFieldFocus);
|
||||
UrlTextField.RegisterCallback<FocusOutEvent>(OnUrlTextFieldFocusOut);
|
||||
UrlTextField.RegisterCallback<ChangeEvent<string>>(OnUrlTextFieldChange);
|
||||
UrlTextField.RegisterCallback<KeyDownEvent>(OnKeyDownShortcut);
|
||||
Hide();
|
||||
}
|
||||
|
||||
private void OnLeavePanel(DetachFromPanelEvent evt)
|
||||
{
|
||||
AddFromUrlFieldContainer.UnregisterCallback<FocusEvent>(OnContainerFocus);
|
||||
AddFromUrlFieldContainer.UnregisterCallback<FocusOutEvent>(OnContainerFocusOut);
|
||||
UrlTextField.UnregisterCallback<FocusEvent>(OnUrlTextFieldFocus);
|
||||
UrlTextField.UnregisterCallback<FocusOutEvent>(OnUrlTextFieldFocusOut);
|
||||
UrlTextField.UnregisterCallback<ChangeEvent<string>>(OnUrlTextFieldChange);
|
||||
UrlTextField.UnregisterCallback<KeyDownEvent>(OnKeyDownShortcut);
|
||||
}
|
||||
|
||||
private void OnKeyDownShortcut(KeyDownEvent evt)
|
||||
{
|
||||
switch (evt.keyCode)
|
||||
{
|
||||
case KeyCode.Escape:
|
||||
Hide();
|
||||
break;
|
||||
case KeyCode.Return:
|
||||
case KeyCode.KeypadEnter:
|
||||
OnAddButtonClick();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnAddButtonClick()
|
||||
{
|
||||
var path = urlText;
|
||||
if (!string.IsNullOrEmpty(path) && !Package.AddRemoveOperationInProgress)
|
||||
{
|
||||
Package.AddFromLocalDisk(path);
|
||||
Hide();
|
||||
}
|
||||
}
|
||||
|
||||
internal void Hide()
|
||||
{
|
||||
UIUtils.SetElementDisplay(this, false);
|
||||
}
|
||||
|
||||
internal void Show(bool reset = false)
|
||||
{
|
||||
if (reset)
|
||||
Reset();
|
||||
UIUtils.SetElementDisplay(this, true);
|
||||
}
|
||||
|
||||
private void Reset()
|
||||
{
|
||||
UrlTextField.value = string.Empty;
|
||||
urlText = string.Empty;
|
||||
AddButton.SetEnabled(false);
|
||||
UrlTextField.Focus();
|
||||
}
|
||||
|
||||
private VisualElement AddFromUrlFieldContainer { get { return root.Q<VisualElement>("addFromUrlFieldContainer"); }}
|
||||
private TextField UrlTextField { get { return root.Q<TextField>("urlTextField"); } }
|
||||
private Button AddButton{ get { return root.Q<Button>("addFromUrlButton"); }}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 40f980217d9196e4baa9ebd2ac1328af
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+626
@@ -0,0 +1,626 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Semver;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Experimental.UIElements;
|
||||
|
||||
namespace UnityEditor.PackageManager.UI
|
||||
{
|
||||
#if !UNITY_2018_3_OR_NEWER
|
||||
internal class PackageDetailsFactory : UxmlFactory<PackageDetails>
|
||||
{
|
||||
protected override PackageDetails DoCreate(IUxmlAttributes bag, CreationContext cc)
|
||||
{
|
||||
return new PackageDetails();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
internal class PackageDetails : VisualElement
|
||||
{
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
internal new class UxmlFactory : UxmlFactory<PackageDetails> { }
|
||||
#endif
|
||||
|
||||
private readonly VisualElement root;
|
||||
private Package package;
|
||||
private const string emptyDescriptionClass = "empty";
|
||||
private List<VersionItem> VersionItems;
|
||||
internal PopupField<VersionItem> VersionPopup;
|
||||
private PackageInfo DisplayPackage;
|
||||
|
||||
private PackageInfo SelectedPackage
|
||||
{
|
||||
get { return VersionPopup.value.Version != null ? VersionPopup.value.Version : null; }
|
||||
}
|
||||
|
||||
internal enum PackageAction
|
||||
{
|
||||
Add,
|
||||
Remove,
|
||||
Update,
|
||||
Downgrade,
|
||||
Enable,
|
||||
Disable,
|
||||
UpToDate,
|
||||
Current,
|
||||
Local,
|
||||
Git,
|
||||
Embedded
|
||||
}
|
||||
|
||||
private static readonly VersionItem EmptyVersion = new VersionItem {Version = null};
|
||||
internal static readonly string[] PackageActionVerbs = { "Install", "Remove", "Update to", "Update to", "Enable", "Disable", "Up to date", "Current", "Local", "Git", "Embedded" };
|
||||
internal static readonly string[] PackageActionInProgressVerbs = { "Installing", "Removing", "Updating to", "Updating to", "Enabling", "Disabling", "Up to date", "Current", "Local", "Git", "Embedded" };
|
||||
|
||||
public PackageDetails()
|
||||
{
|
||||
UIUtils.SetElementDisplay(this, false);
|
||||
|
||||
root = Resources.GetTemplate("PackageDetails.uxml");
|
||||
Add(root);
|
||||
|
||||
foreach (var extension in PackageManagerExtensions.Extensions)
|
||||
CustomContainer.Add(extension.CreateExtensionUI());
|
||||
|
||||
root.StretchToParentSize();
|
||||
|
||||
SetUpdateVisibility(false);
|
||||
RemoveButton.visible = false;
|
||||
UpdateBuiltIn.visible = false;
|
||||
|
||||
UpdateButton.clickable.clicked += UpdateClick;
|
||||
UpdateBuiltIn.clickable.clicked += UpdateClick;
|
||||
RemoveButton.clickable.clicked += RemoveClick;
|
||||
ViewDocButton.clickable.clicked += ViewDocClick;
|
||||
ViewChangelogButton.clickable.clicked += ViewChangelogClick;
|
||||
ViewLicenses.clickable.clicked += ViewLicensesClick;
|
||||
|
||||
VersionItems = new List<VersionItem> {EmptyVersion};
|
||||
VersionPopup = new PopupField<VersionItem>(VersionItems, 0);
|
||||
VersionPopup.SetLabelCallback(VersionSelectionSetLabel);
|
||||
VersionPopup.AddToClassList("popup");
|
||||
VersionPopup.OnValueChanged(VersionSelectionChanged);
|
||||
|
||||
if (VersionItems.Count == 1)
|
||||
VersionPopup.SetEnabled(false);
|
||||
|
||||
UpdateDropdownContainer.Add(VersionPopup);
|
||||
VersionPopup.StretchToParentSize();
|
||||
|
||||
|
||||
// Fix button on dark skin but overlapping edge pixel perfectly
|
||||
if (EditorGUIUtility.isProSkin)
|
||||
{
|
||||
VersionPopup.style.positionLeft = -1;
|
||||
UpdateDropdownContainer.style.sliceLeft = 4;
|
||||
}
|
||||
}
|
||||
|
||||
private string VersionSelectionSetLabel(VersionItem item)
|
||||
{
|
||||
return item.Label;
|
||||
}
|
||||
|
||||
private void VersionSelectionChanged(ChangeEvent<VersionItem> e)
|
||||
{
|
||||
RefreshAddButton();
|
||||
}
|
||||
|
||||
private void SetUpdateVisibility(bool value)
|
||||
{
|
||||
if (UpdateContainer != null)
|
||||
UIUtils.SetElementDisplay(UpdateContainer, value);
|
||||
}
|
||||
|
||||
internal void SetDisplayPackage(PackageInfo packageInfo)
|
||||
{
|
||||
DisplayPackage = packageInfo;
|
||||
|
||||
var detailVisible = true;
|
||||
Error error = null;
|
||||
|
||||
if (package == null || DisplayPackage == null)
|
||||
{
|
||||
detailVisible = false;
|
||||
UIUtils.SetElementDisplay(DocumentationContainer, false);
|
||||
UIUtils.SetElementDisplay(CustomContainer, false);
|
||||
UIUtils.SetElementDisplay(UpdateBuiltIn, false);
|
||||
|
||||
foreach (var extension in PackageManagerExtensions.Extensions)
|
||||
extension.OnPackageSelectionChange(null);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetUpdateVisibility(true);
|
||||
UIUtils.SetElementDisplay(ViewDocButton, true);
|
||||
RemoveButton.visible = true;
|
||||
|
||||
if (string.IsNullOrEmpty(DisplayPackage.Description))
|
||||
{
|
||||
DetailDesc.text = "There is no description for this package.";
|
||||
DetailDesc.AddToClassList(emptyDescriptionClass);
|
||||
}
|
||||
else
|
||||
{
|
||||
DetailDesc.text = DisplayPackage.Description;
|
||||
DetailDesc.RemoveFromClassList(emptyDescriptionClass);
|
||||
}
|
||||
|
||||
root.Q<Label>("detailTitle").text = DisplayPackage.DisplayName;
|
||||
DetailVersion.text = "Version " + DisplayPackage.VersionWithoutTag;
|
||||
|
||||
if (DisplayPackage.IsInDevelopment || DisplayPackage.HasVersionTag(PackageTag.preview))
|
||||
UIUtils.SetElementDisplay(GetTag(PackageTag.verified), false);
|
||||
else
|
||||
{
|
||||
var unityVersionParts = Application.unityVersion.Split('.');
|
||||
var unityVersion = string.Format("{0}.{1}", unityVersionParts[0], unityVersionParts[1]);
|
||||
VerifyLabel.text = unityVersion + " verified";
|
||||
UIUtils.SetElementDisplay(GetTag(PackageTag.verified), DisplayPackage.IsVerified);
|
||||
}
|
||||
|
||||
UIUtils.SetElementDisplay(GetTag(PackageTag.inDevelopment), DisplayPackage.IsInDevelopment);
|
||||
UIUtils.SetElementDisplay(GetTag(PackageTag.local), DisplayPackage.IsLocal);
|
||||
UIUtils.SetElementDisplay(GetTag(PackageTag.preview), DisplayPackage.IsPreview);
|
||||
|
||||
UIUtils.SetElementDisplay(DocumentationContainer, DisplayPackage.Origin != PackageSource.BuiltIn);
|
||||
UIUtils.SetElementDisplay(ChangelogContainer, DisplayPackage.HasChangelog(DisplayPackage));
|
||||
|
||||
root.Q<Label>("detailName").text = DisplayPackage.Name;
|
||||
root.Q<ScrollView>("detailView").scrollOffset = new Vector2(0, 0);
|
||||
|
||||
DetailModuleReference.text = "";
|
||||
var isBuiltIn = DisplayPackage.IsBuiltIn;
|
||||
if (isBuiltIn)
|
||||
DetailModuleReference.text = DisplayPackage.BuiltInDescription;
|
||||
|
||||
DetailAuthor.text = "";
|
||||
if (!string.IsNullOrEmpty(DisplayPackage.Author))
|
||||
DetailAuthor.text = string.Format("Author: {0}", DisplayPackage.Author);
|
||||
|
||||
UIUtils.SetElementDisplay(DetailDesc, !isBuiltIn);
|
||||
UIUtils.SetElementDisplay(DetailVersion, !isBuiltIn);
|
||||
UIUtils.SetElementDisplayNonEmpty(DetailModuleReference);
|
||||
UIUtils.SetElementDisplayNonEmpty(DetailAuthor);
|
||||
|
||||
if (DisplayPackage.Errors.Count > 0)
|
||||
error = DisplayPackage.Errors.First();
|
||||
|
||||
RefreshAddButton();
|
||||
RefreshRemoveButton();
|
||||
UIUtils.SetElementDisplay(CustomContainer, true);
|
||||
|
||||
package.AddSignal.OnOperation += OnAddOperation;
|
||||
package.RemoveSignal.OnOperation += OnRemoveOperation;
|
||||
foreach (var extension in PackageManagerExtensions.Extensions)
|
||||
extension.OnPackageSelectionChange(DisplayPackage.Info);
|
||||
}
|
||||
|
||||
// Set visibility
|
||||
root.Q<VisualElement>("detail").visible = detailVisible;
|
||||
|
||||
if (null == error)
|
||||
error = PackageCollection.Instance.GetPackageError(package);
|
||||
|
||||
if (error != null)
|
||||
SetError(error);
|
||||
else
|
||||
DetailError.ClearError();
|
||||
}
|
||||
|
||||
private void ResetVersionItems(PackageInfo displayPackage)
|
||||
{
|
||||
VersionItems.Clear();
|
||||
VersionPopup.SetEnabled(true);
|
||||
|
||||
if (displayPackage == null)
|
||||
return;
|
||||
|
||||
//
|
||||
// Get key versions -- Latest, Verified, LatestPatch, Current.
|
||||
var keyVersions = new List<PackageInfo>();
|
||||
if (package.LatestRelease != null) keyVersions.Add(package.LatestRelease);
|
||||
if (package.Current != null) keyVersions.Add(package.Current);
|
||||
if (package.Verified != null && package.Verified != package.Current) keyVersions.Add(package.Verified);
|
||||
if (package.LatestPatch != null && package.IsAfterCurrentVersion(package.LatestPatch)) keyVersions.Add(package.LatestPatch);
|
||||
if (package.Current == null && package.LatestRelease == null && package.Latest != null) keyVersions.Add(package.Latest);
|
||||
if (Package.ShouldProposeLatestVersions && package.Latest != package.LatestRelease && package.Latest != null) keyVersions.Add(package.Latest);
|
||||
keyVersions.Add(package.LatestUpdate); // Make sure LatestUpdate is always in the list.
|
||||
|
||||
foreach (var version in keyVersions.OrderBy(package => package.Version).Reverse())
|
||||
{
|
||||
var item = new VersionItem {Version = version};
|
||||
VersionItems.Add(item);
|
||||
|
||||
if (version == package.LatestUpdate)
|
||||
VersionPopup.value = item;
|
||||
}
|
||||
|
||||
//
|
||||
// Add all versions
|
||||
foreach (var version in package.Versions.Reverse())
|
||||
{
|
||||
var item = new VersionItem {Version = version};
|
||||
item.MenuName = "All Versions/";
|
||||
VersionItems.Add(item);
|
||||
}
|
||||
|
||||
if (VersionItems.Count == 0)
|
||||
{
|
||||
VersionItems.Add(EmptyVersion);
|
||||
VersionPopup.value = EmptyVersion;
|
||||
VersionPopup.SetEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetPackage(Package package)
|
||||
{
|
||||
if (this.package != null)
|
||||
{
|
||||
if (this.package.AddSignal.Operation != null)
|
||||
{
|
||||
this.package.AddSignal.Operation.OnOperationError -= OnAddOperationError;
|
||||
this.package.AddSignal.Operation.OnOperationSuccess -= OnAddOperationSuccess;
|
||||
}
|
||||
this.package.AddSignal.ResetEvents();
|
||||
|
||||
if (this.package.RemoveSignal.Operation != null)
|
||||
{
|
||||
this.package.RemoveSignal.Operation.OnOperationSuccess -= OnRemoveOperationSuccess;
|
||||
this.package.RemoveSignal.Operation.OnOperationError -= OnRemoveOperationError;
|
||||
}
|
||||
this.package.RemoveSignal.ResetEvents();
|
||||
}
|
||||
|
||||
UIUtils.SetElementDisplay(this, true);
|
||||
|
||||
this.package = package;
|
||||
var displayPackage = package != null ? package.VersionToDisplay : null;
|
||||
ResetVersionItems(displayPackage);
|
||||
SetDisplayPackage(displayPackage);
|
||||
}
|
||||
|
||||
private void SetError(Error error)
|
||||
{
|
||||
DetailError.AdjustSize(DetailView.verticalScroller.visible);
|
||||
DetailError.SetError(error);
|
||||
DetailError.OnCloseError = () =>
|
||||
{
|
||||
PackageCollection.Instance.RemovePackageErrors(package);
|
||||
PackageCollection.Instance.UpdatePackageCollection();
|
||||
};
|
||||
}
|
||||
|
||||
private void OnAddOperation(IAddOperation operation)
|
||||
{
|
||||
operation.OnOperationError += OnAddOperationError;
|
||||
operation.OnOperationSuccess += OnAddOperationSuccess;
|
||||
}
|
||||
|
||||
private void OnAddOperationError(Error error)
|
||||
{
|
||||
if (package != null && package.AddSignal.Operation != null)
|
||||
{
|
||||
package.AddSignal.Operation.OnOperationSuccess -= OnAddOperationSuccess;
|
||||
package.AddSignal.Operation.OnOperationError -= OnAddOperationError;
|
||||
package.AddSignal.Operation = null;
|
||||
}
|
||||
|
||||
PackageCollection.Instance.AddPackageError(package, error);
|
||||
|
||||
SetError(error);
|
||||
if (package != null)
|
||||
ResetVersionItems(package.VersionToDisplay);
|
||||
PackageCollection.Instance.UpdatePackageCollection();
|
||||
}
|
||||
|
||||
private void OnAddOperationSuccess(PackageInfo packageInfo)
|
||||
{
|
||||
if (package != null && package.AddSignal.Operation != null)
|
||||
{
|
||||
package.AddSignal.Operation.OnOperationSuccess -= OnAddOperationSuccess;
|
||||
package.AddSignal.Operation.OnOperationError -= OnAddOperationError;
|
||||
package.AddSignal.Operation = null;
|
||||
}
|
||||
|
||||
foreach (var extension in PackageManagerExtensions.Extensions)
|
||||
extension.OnPackageAddedOrUpdated(packageInfo.Info);
|
||||
}
|
||||
|
||||
private void OnRemoveOperation(IRemoveOperation operation)
|
||||
{
|
||||
// Make sure we are not already registered
|
||||
operation.OnOperationError -= OnRemoveOperationError;
|
||||
operation.OnOperationSuccess -= OnRemoveOperationSuccess;
|
||||
|
||||
operation.OnOperationError += OnRemoveOperationError;
|
||||
operation.OnOperationSuccess += OnRemoveOperationSuccess;
|
||||
}
|
||||
|
||||
private void OnRemoveOperationError(Error error)
|
||||
{
|
||||
if (package != null && package.RemoveSignal.Operation != null)
|
||||
{
|
||||
package.RemoveSignal.Operation.OnOperationSuccess -= OnRemoveOperationSuccess;
|
||||
package.RemoveSignal.Operation.OnOperationError -= OnRemoveOperationError;
|
||||
package.RemoveSignal.Operation = null;
|
||||
}
|
||||
|
||||
PackageCollection.Instance.AddPackageError(package, error);
|
||||
|
||||
SetError(error);
|
||||
PackageCollection.Instance.UpdatePackageCollection();
|
||||
}
|
||||
|
||||
private void OnRemoveOperationSuccess(PackageInfo packageInfo)
|
||||
{
|
||||
if (package != null && package.RemoveSignal.Operation != null)
|
||||
{
|
||||
package.RemoveSignal.Operation.OnOperationSuccess -= OnRemoveOperationSuccess;
|
||||
package.RemoveSignal.Operation.OnOperationError -= OnRemoveOperationError;
|
||||
package.RemoveSignal.Operation = null;
|
||||
}
|
||||
|
||||
foreach (var extension in PackageManagerExtensions.Extensions)
|
||||
extension.OnPackageRemoved(packageInfo.Info);
|
||||
}
|
||||
|
||||
private void RefreshAddButton()
|
||||
{
|
||||
if (package.Current != null && package.Current.IsInDevelopment)
|
||||
{
|
||||
UIUtils.SetElementDisplay(UpdateBuiltIn, false);
|
||||
UIUtils.SetElementDisplay(UpdateCombo, false);
|
||||
UIUtils.SetElementDisplay(UpdateButton, false);
|
||||
return;
|
||||
}
|
||||
|
||||
var targetVersion = SelectedPackage;
|
||||
if (targetVersion == null)
|
||||
return;
|
||||
|
||||
var enableButton = !Package.AddRemoveOperationInProgress;
|
||||
var enableVersionButton = true;
|
||||
|
||||
var action = PackageAction.Update;
|
||||
var inprogress = false;
|
||||
var isBuiltIn = package.IsBuiltIn;
|
||||
SemVersion version = null;
|
||||
|
||||
if (package.AddSignal.Operation != null)
|
||||
{
|
||||
if (isBuiltIn)
|
||||
{
|
||||
action = PackageAction.Enable;
|
||||
inprogress = true;
|
||||
enableButton = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
var addOperationVersion = package.AddSignal.Operation.PackageInfo.Version;
|
||||
if (package.Current == null)
|
||||
{
|
||||
action = PackageAction.Add;
|
||||
inprogress = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
action = addOperationVersion.CompareByPrecedence(package.Current.Version) >= 0
|
||||
? PackageAction.Update : PackageAction.Downgrade;
|
||||
inprogress = true;
|
||||
}
|
||||
|
||||
enableButton = false;
|
||||
enableVersionButton = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (package.Current != null)
|
||||
{
|
||||
// Installed
|
||||
if (package.Current.IsVersionLocked)
|
||||
{
|
||||
if (package.Current.Origin == PackageSource.Embedded)
|
||||
action = PackageAction.Embedded;
|
||||
else if (package.Current.Origin == PackageSource.Git)
|
||||
action = PackageAction.Git;
|
||||
|
||||
enableButton = false;
|
||||
enableVersionButton = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (targetVersion.IsCurrent)
|
||||
{
|
||||
if (targetVersion == package.LatestUpdate)
|
||||
action = PackageAction.UpToDate;
|
||||
else
|
||||
action = PackageAction.Current;
|
||||
|
||||
enableButton = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
action = targetVersion.Version.CompareByPrecedence(package.Current.Version) >= 0
|
||||
? PackageAction.Update : PackageAction.Downgrade;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not Installed
|
||||
if (package.Versions.Any())
|
||||
{
|
||||
if (isBuiltIn)
|
||||
action = PackageAction.Enable;
|
||||
else
|
||||
action = PackageAction.Add;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (package.RemoveSignal.Operation != null)
|
||||
enableButton = false;
|
||||
|
||||
if (EditorApplication.isCompiling)
|
||||
{
|
||||
enableButton = false;
|
||||
enableVersionButton = false;
|
||||
|
||||
EditorApplication.update -= CheckCompilationStatus;
|
||||
EditorApplication.update += CheckCompilationStatus;
|
||||
}
|
||||
|
||||
var button = isBuiltIn ? UpdateBuiltIn : UpdateButton;
|
||||
button.SetEnabled(enableButton);
|
||||
VersionPopup.SetEnabled(enableVersionButton);
|
||||
button.text = GetButtonText(action, inprogress, version);
|
||||
|
||||
var visibleFlag = !(package.Current != null && package.Current.IsVersionLocked);
|
||||
UIUtils.SetElementDisplay(UpdateBuiltIn, isBuiltIn && visibleFlag);
|
||||
UIUtils.SetElementDisplay(UpdateCombo, !isBuiltIn && visibleFlag);
|
||||
UIUtils.SetElementDisplay(UpdateButton, !isBuiltIn && visibleFlag);
|
||||
}
|
||||
|
||||
private void RefreshRemoveButton()
|
||||
{
|
||||
var visibleFlag = false;
|
||||
|
||||
var current = package.Current;
|
||||
|
||||
// Show only if there is a current package installed
|
||||
if (current != null)
|
||||
{
|
||||
visibleFlag = current.CanBeRemoved && !package.IsPackageManagerUI;
|
||||
|
||||
var action = current.IsBuiltIn ? PackageAction.Disable : PackageAction.Remove;
|
||||
var inprogress = package.RemoveSignal.Operation != null;
|
||||
|
||||
var enableButton = visibleFlag && !EditorApplication.isCompiling && !inprogress && !Package.AddRemoveOperationInProgress;
|
||||
|
||||
if (EditorApplication.isCompiling)
|
||||
{
|
||||
EditorApplication.update -= CheckCompilationStatus;
|
||||
EditorApplication.update += CheckCompilationStatus;
|
||||
}
|
||||
|
||||
RemoveButton.SetEnabled(enableButton);
|
||||
RemoveButton.text = GetButtonText(action, inprogress);
|
||||
}
|
||||
|
||||
UIUtils.SetElementDisplay(RemoveButton, visibleFlag);
|
||||
}
|
||||
|
||||
private void CheckCompilationStatus()
|
||||
{
|
||||
if (EditorApplication.isCompiling)
|
||||
return;
|
||||
|
||||
RefreshAddButton();
|
||||
RefreshRemoveButton();
|
||||
EditorApplication.update -= CheckCompilationStatus;
|
||||
}
|
||||
|
||||
private static string GetButtonText(PackageAction action, bool inProgress = false, SemVersion version = null)
|
||||
{
|
||||
return version == null ?
|
||||
string.Format("{0}", inProgress ? PackageActionInProgressVerbs[(int) action] : PackageActionVerbs[(int) action]) :
|
||||
string.Format("{0} {1}", inProgress ? PackageActionInProgressVerbs[(int) action] : PackageActionVerbs[(int) action], version);
|
||||
}
|
||||
|
||||
private void UpdateClick()
|
||||
{
|
||||
if (package.IsPackageManagerUI)
|
||||
{
|
||||
// Let's not allow updating of the UI if there are build errrors, as for now, that will prevent the UI from reloading properly.
|
||||
if (EditorUtility.scriptCompilationFailed)
|
||||
{
|
||||
EditorUtility.DisplayDialog("Unity Package Manager", "The Package Manager UI cannot be updated while there are script compilation errors in your project. Please fix the errors and try again.", "Ok");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!EditorUtility.DisplayDialog("Unity Package Manager", "Updating this package will close the Package Manager window. You will have to re-open it after the update is done. Do you want to continue?", "Yes", "No"))
|
||||
return;
|
||||
|
||||
if (package.AddSignal.Operation != null)
|
||||
{
|
||||
package.AddSignal.Operation.OnOperationSuccess -= OnAddOperationSuccess;
|
||||
package.AddSignal.Operation.OnOperationError -= OnAddOperationError;
|
||||
package.AddSignal.ResetEvents();
|
||||
package.AddSignal.Operation = null;
|
||||
}
|
||||
|
||||
DetailError.ClearError();
|
||||
EditorApplication.update += CloseAndUpdate;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
DetailError.ClearError();
|
||||
package.Add(SelectedPackage);
|
||||
RefreshAddButton();
|
||||
RefreshRemoveButton();
|
||||
}
|
||||
|
||||
private void CloseAndUpdate()
|
||||
{
|
||||
EditorApplication.update -= CloseAndUpdate;
|
||||
package.Add(SelectedPackage);
|
||||
|
||||
var windows = UnityEngine.Resources.FindObjectsOfTypeAll<PackageManagerWindow>();
|
||||
if (windows.Length > 0)
|
||||
{
|
||||
windows[0].Close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void RemoveClick()
|
||||
{
|
||||
DetailError.ClearError();
|
||||
package.Remove();
|
||||
RefreshRemoveButton();
|
||||
RefreshAddButton();
|
||||
}
|
||||
|
||||
|
||||
private void ViewDocClick()
|
||||
{
|
||||
Application.OpenURL(DisplayPackage.GetDocumentationUrl());
|
||||
}
|
||||
|
||||
private void ViewChangelogClick()
|
||||
{
|
||||
Application.OpenURL(DisplayPackage.GetChangelogUrl());
|
||||
}
|
||||
|
||||
private void ViewLicensesClick()
|
||||
{
|
||||
Application.OpenURL(DisplayPackage.GetLicensesUrl());
|
||||
}
|
||||
|
||||
private Label DetailDesc { get { return root.Q<Label>("detailDesc"); } }
|
||||
internal Button UpdateButton { get { return root.Q<Button>("update"); } }
|
||||
private Button RemoveButton { get { return root.Q<Button>("remove"); } }
|
||||
private Button ViewDocButton { get { return root.Q<Button>("viewDocumentation"); } }
|
||||
private VisualElement DocumentationContainer { get { return root.Q<VisualElement>("documentationContainer"); } }
|
||||
private Button ViewChangelogButton { get { return root.Q<Button>("viewChangelog"); } }
|
||||
private VisualElement ChangelogContainer { get { return root.Q<VisualElement>("changeLogContainer"); } }
|
||||
private VisualElement ViewLicensesContainer { get { return root.Q<VisualElement>("viewLicensesContainer"); } }
|
||||
private Button ViewLicenses { get { return root.Q<Button>("viewLicenses"); } }
|
||||
private VisualElement UpdateContainer { get { return root.Q<VisualElement>("updateContainer"); } }
|
||||
private Alert DetailError { get { return root.Q<Alert>("detailError"); } }
|
||||
private ScrollView DetailView { get { return root.Q<ScrollView>("detailView"); } }
|
||||
private Label DetailModuleReference { get { return root.Q<Label>("detailModuleReference"); } }
|
||||
private Label DetailVersion { get { return root.Q<Label>("detailVersion"); }}
|
||||
private Label DetailAuthor { get { return root.Q<Label>("detailAuthor"); }}
|
||||
private Label VerifyLabel { get { return root.Q<Label>("tagVerify"); } }
|
||||
private VisualElement CustomContainer { get { return root.Q<VisualElement>("detailCustomContainer"); } }
|
||||
internal VisualElement GetTag(PackageTag tag) {return root.Q<VisualElement>("tag-" + tag); }
|
||||
private VisualElement UpdateDropdownContainer { get { return root.Q<VisualElement>("updateDropdownContainer"); } }
|
||||
internal VisualElement UpdateCombo { get { return root.Q<VisualElement>("updateCombo"); } }
|
||||
internal Button UpdateBuiltIn { get { return root.Q<Button>("updateBuiltIn"); } }
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3f3e22b18940a4e828a5170574a3617e
|
||||
timeCreated: 1502224642
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
using UnityEngine.Experimental.UIElements;
|
||||
|
||||
namespace UnityEditor.PackageManager.UI
|
||||
{
|
||||
internal static class PackageFiltering
|
||||
{
|
||||
private static bool FilterByText(PackageInfo info, string text)
|
||||
{
|
||||
if (info == null)
|
||||
return false;
|
||||
|
||||
if (info.Name.IndexOf(text, StringComparison.CurrentCultureIgnoreCase) >= 0)
|
||||
return true;
|
||||
|
||||
if (!string.IsNullOrEmpty(info.DisplayName) && info.DisplayName.IndexOf(text, StringComparison.CurrentCultureIgnoreCase) >= 0)
|
||||
return true;
|
||||
|
||||
if (!info.IsBuiltIn)
|
||||
{
|
||||
var prerelease = text.StartsWith("-") ? text.Substring(1) : text;
|
||||
if (info.Version != null && info.Version.Prerelease.IndexOf(prerelease, StringComparison.CurrentCultureIgnoreCase) >= 0)
|
||||
return true;
|
||||
|
||||
if (info.VersionWithoutTag.StartsWith(text, StringComparison.CurrentCultureIgnoreCase))
|
||||
return true;
|
||||
|
||||
if (info.IsPreview)
|
||||
{
|
||||
if (PackageTag.preview.ToString().IndexOf(text, StringComparison.CurrentCultureIgnoreCase) >= 0)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (info.IsVerified)
|
||||
{
|
||||
if (PackageTag.verified.ToString().IndexOf(text, StringComparison.CurrentCultureIgnoreCase) >= 0)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
internal static bool FilterByText(Package package, string text)
|
||||
{
|
||||
if (string.IsNullOrEmpty(text))
|
||||
return true;
|
||||
|
||||
var trimText = text.Trim(' ', '\t');
|
||||
trimText = Regex.Replace(trimText, @"[ ]{2,}", " ");
|
||||
return string.IsNullOrEmpty(trimText) || FilterByText(package.Current ?? package.Latest, trimText);
|
||||
}
|
||||
|
||||
private static bool FilterByText(PackageItem item, string text)
|
||||
{
|
||||
return item.package != null && FilterByText(item.package, text);
|
||||
}
|
||||
|
||||
public static void FilterPackageList(PackageList packageList)
|
||||
{
|
||||
PackageItem firstItem = null;
|
||||
PackageItem lastItem = null;
|
||||
var selectedItemInFilter = false;
|
||||
var selectedItem = packageList.selectedItem;
|
||||
var packageItems = packageList.Query<PackageItem>().ToList();
|
||||
foreach (var item in packageItems)
|
||||
{
|
||||
if (FilterByText(item, PackageSearchFilter.Instance.SearchText))
|
||||
{
|
||||
if (firstItem == null)
|
||||
firstItem = item;
|
||||
if (item == selectedItem)
|
||||
selectedItemInFilter = true;
|
||||
|
||||
UIUtils.SetElementDisplay(item, true);
|
||||
|
||||
if (lastItem != null)
|
||||
lastItem.nextItem = item;
|
||||
|
||||
item.previousItem = lastItem;
|
||||
item.nextItem = null;
|
||||
|
||||
lastItem = item;
|
||||
}
|
||||
else
|
||||
UIUtils.SetElementDisplay(item, false);
|
||||
}
|
||||
|
||||
if (firstItem == null)
|
||||
packageList.ShowNoResults();
|
||||
else
|
||||
packageList.ShowResults(selectedItemInFilter ? selectedItem : firstItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5ffd2adf615994485991e37bacbf735c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
using System.Linq;
|
||||
using UnityEngine.Experimental.UIElements;
|
||||
|
||||
namespace UnityEditor.PackageManager.UI
|
||||
{
|
||||
#if !UNITY_2018_3_OR_NEWER
|
||||
internal class PackageGroupFactory : UxmlFactory<PackageGroup>
|
||||
{
|
||||
protected override PackageGroup DoCreate(IUxmlAttributes bag, CreationContext cc)
|
||||
{
|
||||
return new PackageGroup(bag.GetPropertyString("name"));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
internal class PackageGroup : VisualElement
|
||||
{
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
internal new class UxmlFactory : UxmlFactory<PackageGroup> { }
|
||||
#endif
|
||||
|
||||
private readonly VisualElement root;
|
||||
internal readonly PackageGroupOrigins Origin;
|
||||
|
||||
public PackageGroup previousGroup;
|
||||
public PackageGroup nextGroup;
|
||||
|
||||
public PackageItem firstPackage;
|
||||
public PackageItem lastPackage;
|
||||
|
||||
public PackageGroup() : this(string.Empty)
|
||||
{
|
||||
}
|
||||
|
||||
public PackageGroup(string groupName)
|
||||
{
|
||||
name = groupName;
|
||||
root = Resources.GetTemplate("PackageGroup.uxml");
|
||||
Add(root);
|
||||
|
||||
if (string.IsNullOrEmpty(groupName) || groupName != PackageGroupOrigins.BuiltInPackages.ToString())
|
||||
{
|
||||
HeaderTitle.text = "Packages";
|
||||
Origin = PackageGroupOrigins.Packages;
|
||||
}
|
||||
else
|
||||
{
|
||||
HeaderTitle.text = "Built In Packages";
|
||||
Origin = PackageGroupOrigins.BuiltInPackages;
|
||||
}
|
||||
}
|
||||
|
||||
internal PackageItem AddPackage(Package package)
|
||||
{
|
||||
var packageItem = new PackageItem(package) {packageGroup = this};
|
||||
var lastItem = List.Children().LastOrDefault() as PackageItem;
|
||||
if (lastItem != null)
|
||||
{
|
||||
lastItem.nextItem = packageItem;
|
||||
packageItem.previousItem = lastItem;
|
||||
packageItem.nextItem = null;
|
||||
}
|
||||
|
||||
List.Add(packageItem);
|
||||
|
||||
if (firstPackage == null) firstPackage = packageItem;
|
||||
lastPackage = packageItem;
|
||||
|
||||
return packageItem;
|
||||
}
|
||||
|
||||
private VisualElement List { get { return root.Q<VisualElement>("groupContainer"); } }
|
||||
private Label HeaderTitle { get { return root.Q<Label>("headerTitle"); } }
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 760934a36e5f490db3c9fcaf497625a4
|
||||
timeCreated: 1508509771
|
||||
+150
@@ -0,0 +1,150 @@
|
||||
using UnityEngine.Experimental.UIElements;
|
||||
using System;
|
||||
|
||||
namespace UnityEditor.PackageManager.UI
|
||||
{
|
||||
#if !UNITY_2018_3_OR_NEWER
|
||||
internal class PackageItemFactory : UxmlFactory<PackageItem>
|
||||
{
|
||||
protected override PackageItem DoCreate(IUxmlAttributes bag, CreationContext cc)
|
||||
{
|
||||
return new PackageItem();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
internal class PackageItem : VisualElement
|
||||
{
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
internal new class UxmlFactory : UxmlFactory<PackageItem> { }
|
||||
#endif
|
||||
|
||||
public static string SelectedClassName = "selected";
|
||||
|
||||
public event Action<PackageItem> OnSelected = delegate { };
|
||||
|
||||
private readonly VisualElement root;
|
||||
private string currentStateClass;
|
||||
public Package package { get; private set; }
|
||||
|
||||
public PackageItem previousItem;
|
||||
public PackageItem nextItem;
|
||||
|
||||
public PackageGroup packageGroup;
|
||||
|
||||
public PackageItem() : this(null)
|
||||
{
|
||||
}
|
||||
|
||||
public PackageItem(Package package)
|
||||
{
|
||||
root = Resources.GetTemplate("PackageItem.uxml");
|
||||
Add(root);
|
||||
|
||||
root.AddManipulator(new Clickable(Select));
|
||||
SetItem(package);
|
||||
}
|
||||
|
||||
private void Select()
|
||||
{
|
||||
OnSelected(this);
|
||||
}
|
||||
|
||||
public void SetSelected(bool value)
|
||||
{
|
||||
if (value)
|
||||
PackageContainer.AddToClassList(SelectedClassName);
|
||||
else
|
||||
PackageContainer.RemoveFromClassList(SelectedClassName);
|
||||
|
||||
Spinner.InvertColor = value;
|
||||
}
|
||||
|
||||
private void SetItem(Package package)
|
||||
{
|
||||
var displayPackage = package != null ? package.VersionToDisplay : null;
|
||||
if (displayPackage == null)
|
||||
return;
|
||||
|
||||
this.package = package;
|
||||
OnPackageChanged();
|
||||
this.package.AddSignal.WhenOperation(OnPackageAdd);
|
||||
this.package.RemoveSignal.WhenOperation(OnPackageRemove);
|
||||
}
|
||||
|
||||
private void OnPackageRemove(IRemoveOperation operation)
|
||||
{
|
||||
operation.OnOperationError += error => StopSpinner();
|
||||
OnPackageUpdate();
|
||||
}
|
||||
|
||||
private void OnPackageAdd(IAddOperation operation)
|
||||
{
|
||||
operation.OnOperationError += error => StopSpinner();
|
||||
OnPackageUpdate();
|
||||
}
|
||||
|
||||
private void OnPackageChanged()
|
||||
{
|
||||
var displayPackage = package != null ? package.VersionToDisplay : null;
|
||||
if (displayPackage == null)
|
||||
return;
|
||||
|
||||
NameLabel.text = displayPackage.DisplayName;
|
||||
VersionLabel.text = displayPackage.Version.ToString();
|
||||
|
||||
var stateClass = GetIconStateId(displayPackage);
|
||||
if (displayPackage.State == PackageState.Outdated && package.LatestUpdate == package.Current)
|
||||
stateClass = GetIconStateId(PackageState.UpToDate);
|
||||
if (PackageCollection.Instance.GetPackageError(package) != null)
|
||||
stateClass = GetIconStateId(PackageState.Error);
|
||||
if (stateClass == GetIconStateId(PackageState.UpToDate) && package.Current != null)
|
||||
stateClass = "installed";
|
||||
|
||||
StateLabel.RemoveFromClassList(currentStateClass);
|
||||
StateLabel.AddToClassList(stateClass);
|
||||
|
||||
UIUtils.SetElementDisplay(VersionLabel, !displayPackage.IsBuiltIn);
|
||||
|
||||
currentStateClass = stateClass;
|
||||
if (displayPackage.State != PackageState.InProgress && Spinner.Started)
|
||||
StopSpinner();
|
||||
}
|
||||
|
||||
private void OnPackageUpdate()
|
||||
{
|
||||
StartSpinner();
|
||||
}
|
||||
|
||||
private void StartSpinner()
|
||||
{
|
||||
Spinner.Start();
|
||||
StateLabel.AddToClassList("no-icon");
|
||||
}
|
||||
|
||||
private void StopSpinner()
|
||||
{
|
||||
Spinner.Stop();
|
||||
StateLabel.RemoveFromClassList("no-icon");
|
||||
}
|
||||
|
||||
private Label NameLabel { get { return root.Q<Label>("packageName"); } }
|
||||
private Label StateLabel { get { return root.Q<Label>("packageState"); } }
|
||||
private Label VersionLabel { get { return root.Q<Label>("packageVersion"); } }
|
||||
private VisualElement PackageContainer { get { return root.Q<VisualElement>("packageContainer"); } }
|
||||
private LoadingSpinner Spinner { get { return root.Q<LoadingSpinner>("packageSpinner"); } }
|
||||
|
||||
public static string GetIconStateId(PackageInfo packageInfo)
|
||||
{
|
||||
if (packageInfo == null)
|
||||
return "";
|
||||
|
||||
return GetIconStateId(packageInfo.State);
|
||||
}
|
||||
|
||||
public static string GetIconStateId(PackageState state)
|
||||
{
|
||||
return state.ToString().ToLower();
|
||||
}
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c68ba5b432ef64e67ae0bf74960908a8
|
||||
timeCreated: 1502224642
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+408
@@ -0,0 +1,408 @@
|
||||
using UnityEngine.Experimental.UIElements;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.PackageManager.UI
|
||||
{
|
||||
#if !UNITY_2018_3_OR_NEWER
|
||||
internal class PackageListFactory : UxmlFactory<PackageList>
|
||||
{
|
||||
protected override PackageList DoCreate(IUxmlAttributes bag, CreationContext cc)
|
||||
{
|
||||
return new PackageList();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
internal class PackageList : VisualElement
|
||||
{
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
internal new class UxmlFactory : UxmlFactory<PackageList> { }
|
||||
#endif
|
||||
|
||||
public event Action<Package> OnSelected = delegate { };
|
||||
public event Action OnLoaded = delegate { };
|
||||
public event Action OnFocusChange = delegate { };
|
||||
|
||||
private readonly VisualElement root;
|
||||
internal PackageItem selectedItem;
|
||||
private List<PackageGroup> Groups;
|
||||
|
||||
public PackageList()
|
||||
{
|
||||
Groups = new List<PackageGroup>();
|
||||
|
||||
root = Resources.GetTemplate("PackageList.uxml");
|
||||
Add(root);
|
||||
root.StretchToParentSize();
|
||||
|
||||
UIUtils.SetElementDisplay(Empty, false);
|
||||
UIUtils.SetElementDisplay(NoResult, false);
|
||||
|
||||
PackageCollection.Instance.OnPackagesChanged += SetPackages;
|
||||
|
||||
RegisterCallback<AttachToPanelEvent>(OnEnterPanel);
|
||||
RegisterCallback<DetachFromPanelEvent>(OnLeavePanel);
|
||||
|
||||
Reload();
|
||||
}
|
||||
|
||||
public void GrabFocus()
|
||||
{
|
||||
if (selectedItem == null)
|
||||
return;
|
||||
|
||||
selectedItem.Focus();
|
||||
}
|
||||
|
||||
public void ShowResults(PackageItem item)
|
||||
{
|
||||
NoResultText.text = string.Empty;
|
||||
UIUtils.SetElementDisplay(NoResult, false);
|
||||
|
||||
Select(item);
|
||||
|
||||
EditorApplication.delayCall += ScrollIfNeeded;
|
||||
|
||||
UpdateGroups();
|
||||
}
|
||||
|
||||
public void ShowNoResults()
|
||||
{
|
||||
NoResultText.text = string.Format("No results for \"{0}\"", PackageSearchFilter.Instance.SearchText);
|
||||
UIUtils.SetElementDisplay(NoResult, true);
|
||||
foreach (var group in Groups)
|
||||
{
|
||||
UIUtils.SetElementDisplay(group, false);
|
||||
}
|
||||
Select(null);
|
||||
OnSelected(null);
|
||||
}
|
||||
|
||||
private void UpdateGroups()
|
||||
{
|
||||
foreach (var group in Groups)
|
||||
{
|
||||
PackageItem firstPackage = null;
|
||||
PackageItem lastPackage = null;
|
||||
|
||||
var listGroup = group.Query<PackageItem>().ToList();
|
||||
foreach (var item in listGroup)
|
||||
{
|
||||
if (!item.visible)
|
||||
continue;
|
||||
|
||||
if (firstPackage == null) firstPackage = item;
|
||||
lastPackage = item;
|
||||
}
|
||||
|
||||
if (firstPackage == null && lastPackage == null)
|
||||
{
|
||||
UIUtils.SetElementDisplay(group, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
UIUtils.SetElementDisplay(group, true);
|
||||
group.firstPackage = firstPackage;
|
||||
group.lastPackage = lastPackage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnEnterPanel(AttachToPanelEvent e)
|
||||
{
|
||||
panel.visualTree.RegisterCallback<KeyDownEvent>(OnKeyDownShortcut);
|
||||
}
|
||||
|
||||
private void OnLeavePanel(DetachFromPanelEvent e)
|
||||
{
|
||||
panel.visualTree.UnregisterCallback<KeyDownEvent>(OnKeyDownShortcut);
|
||||
}
|
||||
|
||||
private void ScrollIfNeeded()
|
||||
{
|
||||
EditorApplication.delayCall -= ScrollIfNeeded;
|
||||
|
||||
if (selectedItem == null)
|
||||
return;
|
||||
|
||||
var minY = List.worldBound.yMin;
|
||||
var maxY = List.worldBound.yMax;
|
||||
var itemMinY = selectedItem.worldBound.yMin;
|
||||
var itemMaxY = selectedItem.worldBound.yMax;
|
||||
var scroll = List.scrollOffset;
|
||||
|
||||
if (itemMinY < minY)
|
||||
{
|
||||
scroll.y -= minY - itemMinY;
|
||||
if (scroll.y <= minY)
|
||||
scroll.y = 0;
|
||||
List.scrollOffset = scroll;
|
||||
}
|
||||
else if (itemMaxY > maxY)
|
||||
{
|
||||
scroll.y += itemMaxY - maxY;
|
||||
List.scrollOffset = scroll;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnKeyDownShortcut(KeyDownEvent evt)
|
||||
{
|
||||
if (selectedItem == null)
|
||||
return;
|
||||
|
||||
if (evt.keyCode == KeyCode.Tab)
|
||||
{
|
||||
OnFocusChange();
|
||||
evt.StopPropagation();
|
||||
return;
|
||||
}
|
||||
|
||||
if (evt.keyCode == KeyCode.UpArrow)
|
||||
{
|
||||
if (selectedItem.previousItem != null)
|
||||
{
|
||||
Select(selectedItem.previousItem);
|
||||
ScrollIfNeeded();
|
||||
}
|
||||
else if (selectedItem.packageGroup.previousGroup != null && selectedItem.packageGroup.previousGroup.visible)
|
||||
{
|
||||
Select(selectedItem.packageGroup.previousGroup.lastPackage);
|
||||
ScrollIfNeeded();
|
||||
}
|
||||
evt.StopPropagation();
|
||||
return;
|
||||
}
|
||||
|
||||
if (evt.keyCode == KeyCode.DownArrow)
|
||||
{
|
||||
if (selectedItem.nextItem != null)
|
||||
{
|
||||
Select(selectedItem.nextItem);
|
||||
ScrollIfNeeded();
|
||||
}
|
||||
else if (selectedItem.packageGroup.nextGroup != null && selectedItem.packageGroup.nextGroup.visible)
|
||||
{
|
||||
Select(selectedItem.packageGroup.nextGroup.firstPackage);
|
||||
ScrollIfNeeded();
|
||||
}
|
||||
evt.StopPropagation();
|
||||
return;
|
||||
}
|
||||
|
||||
if (evt.keyCode == KeyCode.PageUp)
|
||||
{
|
||||
if (selectedItem.packageGroup != null)
|
||||
{
|
||||
if (selectedItem == selectedItem.packageGroup.lastPackage && selectedItem != selectedItem.packageGroup.firstPackage)
|
||||
{
|
||||
Select(selectedItem.packageGroup.firstPackage);
|
||||
ScrollIfNeeded();
|
||||
}
|
||||
else if (selectedItem == selectedItem.packageGroup.firstPackage && selectedItem.packageGroup.previousGroup != null && selectedItem.packageGroup.previousGroup.visible)
|
||||
{
|
||||
Select(selectedItem.packageGroup.previousGroup.lastPackage);
|
||||
ScrollIfNeeded();
|
||||
}
|
||||
else if (selectedItem != selectedItem.packageGroup.lastPackage && selectedItem != selectedItem.packageGroup.firstPackage)
|
||||
{
|
||||
Select(selectedItem.packageGroup.firstPackage);
|
||||
ScrollIfNeeded();
|
||||
}
|
||||
}
|
||||
evt.StopPropagation();
|
||||
return;
|
||||
}
|
||||
|
||||
if (evt.keyCode == KeyCode.PageDown)
|
||||
{
|
||||
if (selectedItem.packageGroup != null)
|
||||
{
|
||||
if (selectedItem == selectedItem.packageGroup.firstPackage && selectedItem != selectedItem.packageGroup.lastPackage)
|
||||
{
|
||||
Select(selectedItem.packageGroup.lastPackage);
|
||||
ScrollIfNeeded();
|
||||
}
|
||||
else if (selectedItem == selectedItem.packageGroup.lastPackage && selectedItem.packageGroup.nextGroup != null && selectedItem.packageGroup.nextGroup.visible)
|
||||
{
|
||||
Select(selectedItem.packageGroup.nextGroup.firstPackage);
|
||||
ScrollIfNeeded();
|
||||
}
|
||||
else if (selectedItem != selectedItem.packageGroup.firstPackage && selectedItem != selectedItem.packageGroup.lastPackage)
|
||||
{
|
||||
Select(selectedItem.packageGroup.lastPackage);
|
||||
ScrollIfNeeded();
|
||||
}
|
||||
}
|
||||
evt.StopPropagation();
|
||||
}
|
||||
}
|
||||
|
||||
private void Reload()
|
||||
{
|
||||
// Force a re-init to initial condition
|
||||
PackageCollection.Instance.UpdatePackageCollection();
|
||||
SelectLastSelection();
|
||||
}
|
||||
|
||||
private void ClearAll()
|
||||
{
|
||||
List.Clear();
|
||||
Groups.Clear();
|
||||
|
||||
UIUtils.SetElementDisplay(Empty, false);
|
||||
UIUtils.SetElementDisplay(NoResult, false);
|
||||
}
|
||||
|
||||
private void SetPackages(IEnumerable<Package> packages)
|
||||
{
|
||||
if (PackageCollection.Instance.Filter == PackageFilter.Modules)
|
||||
{
|
||||
packages = packages.Where(pkg => pkg.IsBuiltIn);
|
||||
}
|
||||
else if (PackageCollection.Instance.Filter== PackageFilter.All)
|
||||
{
|
||||
packages = packages.Where(pkg => !pkg.IsBuiltIn);
|
||||
}
|
||||
else
|
||||
{
|
||||
packages = packages.Where(pkg => !pkg.IsBuiltIn);
|
||||
packages = packages.Where(pkg => pkg.Current != null);
|
||||
}
|
||||
|
||||
OnLoaded();
|
||||
ClearAll();
|
||||
|
||||
var packagesGroup = new PackageGroup(PackageGroupOrigins.Packages.ToString());
|
||||
Groups.Add(packagesGroup);
|
||||
List.Add(packagesGroup);
|
||||
packagesGroup.previousGroup = null;
|
||||
|
||||
var builtInGroup = new PackageGroup(PackageGroupOrigins.BuiltInPackages.ToString());
|
||||
Groups.Add(builtInGroup);
|
||||
List.Add(builtInGroup);
|
||||
|
||||
if ((PackageCollection.Instance.Filter & PackageFilter.Modules) == PackageFilter.Modules)
|
||||
{
|
||||
packagesGroup.nextGroup = builtInGroup;
|
||||
builtInGroup.previousGroup = packagesGroup;
|
||||
builtInGroup.nextGroup = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
packagesGroup.nextGroup = null;
|
||||
UIUtils.SetElementDisplay(builtInGroup, false);
|
||||
}
|
||||
|
||||
var lastSelection = PackageCollection.Instance.SelectedPackage;
|
||||
Select(null);
|
||||
|
||||
PackageItem defaultSelection = null;
|
||||
|
||||
foreach (var package in packages.OrderBy(pkg => pkg.Versions.FirstOrDefault() == null ? pkg.Name : pkg.Versions.FirstOrDefault().DisplayName))
|
||||
{
|
||||
var item = AddPackage(package);
|
||||
|
||||
if (null == selectedItem && defaultSelection == null)
|
||||
defaultSelection = item;
|
||||
|
||||
if (null == selectedItem && !string.IsNullOrEmpty(lastSelection) && package.Name.Equals(lastSelection))
|
||||
Select(item);
|
||||
}
|
||||
|
||||
if (selectedItem == null)
|
||||
Select(defaultSelection);
|
||||
|
||||
PackageFiltering.FilterPackageList(this);
|
||||
}
|
||||
|
||||
public void SelectLastSelection()
|
||||
{
|
||||
var lastSelection = PackageCollection.Instance.SelectedPackage;
|
||||
if (lastSelection == null)
|
||||
return;
|
||||
|
||||
var list = List.Query<PackageItem>().ToList();
|
||||
PackageItem defaultSelection = null;
|
||||
|
||||
foreach (var item in list)
|
||||
{
|
||||
if (defaultSelection == null)
|
||||
defaultSelection = item;
|
||||
|
||||
if (!string.IsNullOrEmpty(lastSelection) && item.package.Name.Equals(lastSelection))
|
||||
{
|
||||
defaultSelection = item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
selectedItem = null;
|
||||
Select(defaultSelection);
|
||||
}
|
||||
|
||||
private PackageItem AddPackage(Package package)
|
||||
{
|
||||
var groupName = package.Latest != null ? package.Latest.Group : package.Current.Group;
|
||||
var group = GetOrCreateGroup(groupName);
|
||||
var packageItem = group.AddPackage(package);
|
||||
|
||||
packageItem.OnSelected += Select;
|
||||
|
||||
return packageItem;
|
||||
}
|
||||
|
||||
private PackageGroup GetOrCreateGroup(string groupName)
|
||||
{
|
||||
foreach (var g in Groups)
|
||||
{
|
||||
if (g.name == groupName)
|
||||
return g;
|
||||
}
|
||||
|
||||
var group = new PackageGroup(groupName);
|
||||
var latestGroup = Groups.LastOrDefault();
|
||||
Groups.Add(group);
|
||||
List.Add(group);
|
||||
|
||||
group.previousGroup = null;
|
||||
if (latestGroup != null)
|
||||
{
|
||||
latestGroup.nextGroup = group;
|
||||
group.previousGroup = latestGroup;
|
||||
group.nextGroup = null;
|
||||
}
|
||||
return group;
|
||||
}
|
||||
|
||||
private void Select(PackageItem packageItem)
|
||||
{
|
||||
if (packageItem == selectedItem)
|
||||
return;
|
||||
|
||||
var selectedPackageName = packageItem != null ? packageItem.package.Name : null;
|
||||
PackageCollection.Instance.SelectedPackage = selectedPackageName;
|
||||
|
||||
if (selectedItem != null)
|
||||
selectedItem.SetSelected(false); // Clear Previous selection
|
||||
|
||||
selectedItem = packageItem;
|
||||
if (selectedItem == null)
|
||||
{
|
||||
OnSelected(null);
|
||||
return;
|
||||
}
|
||||
|
||||
selectedItem.SetSelected(true);
|
||||
ScrollIfNeeded();
|
||||
OnSelected(selectedItem.package);
|
||||
}
|
||||
|
||||
private ScrollView List { get { return root.Q<ScrollView>("scrollView"); } }
|
||||
private VisualElement Empty { get { return root.Q<VisualElement>("emptyArea"); } }
|
||||
private VisualElement NoResult { get { return root.Q<VisualElement>("noResult"); } }
|
||||
private Label NoResultText { get { return root.Q<Label>("noResultText"); } }
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2d77b2d58287d46a6a61f12c861bfc2f
|
||||
timeCreated: 1502224642
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UnityEditor.PackageManager.UI
|
||||
{
|
||||
/// <summary>
|
||||
/// Package Manager UI Extensions
|
||||
/// </summary>
|
||||
public static class PackageManagerExtensions
|
||||
{
|
||||
internal static List<IPackageManagerExtension> Extensions { get { return extensions ?? (extensions = new List<IPackageManagerExtension>()); } }
|
||||
private static List<IPackageManagerExtension> extensions;
|
||||
|
||||
/// <summary>
|
||||
/// Registers a new Package Manager UI extension
|
||||
/// </summary>
|
||||
/// <param name="extension">A Package Manager UI extension</param>
|
||||
public static void RegisterExtension(IPackageManagerExtension extension)
|
||||
{
|
||||
if (extension == null)
|
||||
return;
|
||||
|
||||
Extensions.Add(extension);
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 20a8ca0a6d82545f6bfd6f2d898d61f7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
using System.Linq;
|
||||
|
||||
namespace UnityEditor.PackageManager.UI
|
||||
{
|
||||
internal static class PackageManagerPrefs
|
||||
{
|
||||
private const string kShowPreviewPackagesPrefKeyPrefix = "PackageManager.ShowPreviewPackages_";
|
||||
private const string kShowPreviewPackagesWarningPrefKey = "PackageManager.ShowPreviewPackagesWarning";
|
||||
|
||||
private static string GetProjectIdentifier()
|
||||
{
|
||||
// PlayerSettings.productGUID is already used as LocalProjectID by Analytics, so we use it too
|
||||
return PlayerSettings.productGUID.ToString();
|
||||
}
|
||||
|
||||
public static bool ShowPreviewPackages
|
||||
{
|
||||
get
|
||||
{
|
||||
var key = kShowPreviewPackagesPrefKeyPrefix + GetProjectIdentifier();
|
||||
|
||||
// If user manually choose to show or not preview packages, use this value
|
||||
if (EditorPrefs.HasKey(key))
|
||||
return EditorPrefs.GetBool(key);
|
||||
|
||||
// Returns true if at least one preview package is installed, false otherwise
|
||||
return PackageCollection.Instance.LatestListPackages.Any(p => p.IsPreview && p.IsCurrent);
|
||||
}
|
||||
set
|
||||
{
|
||||
EditorPrefs.SetBool(kShowPreviewPackagesPrefKeyPrefix + GetProjectIdentifier(), value);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool ShowPreviewPackagesWarning
|
||||
{
|
||||
get { return EditorPrefs.GetBool(kShowPreviewPackagesWarningPrefKey, true); }
|
||||
set { EditorPrefs.SetBool(kShowPreviewPackagesWarningPrefKey, value); }
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 566f8bae715954c65a2a7a4b5818fc7a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+164
@@ -0,0 +1,164 @@
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Experimental.UIElements;
|
||||
|
||||
namespace UnityEditor.PackageManager.UI
|
||||
{
|
||||
#if !UNITY_2018_3_OR_NEWER
|
||||
internal class PackageManangerToolbarFactory : UxmlFactory<PackageManagerToolbar>
|
||||
{
|
||||
protected override PackageManagerToolbar DoCreate(IUxmlAttributes bag, CreationContext cc)
|
||||
{
|
||||
return new PackageManagerToolbar();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
internal class PackageManagerToolbar : VisualElement
|
||||
{
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
internal new class UxmlFactory : UxmlFactory<PackageManagerToolbar> { }
|
||||
#endif
|
||||
private readonly VisualElement root;
|
||||
|
||||
[SerializeField]
|
||||
private PackageFilter selectedFilter = PackageFilter.All;
|
||||
|
||||
public PackageManagerToolbar()
|
||||
{
|
||||
root = Resources.GetTemplate("PackageManagerToolbar.uxml");
|
||||
Add(root);
|
||||
root.StretchToParentSize();
|
||||
|
||||
SetFilter(PackageCollection.Instance.Filter);
|
||||
|
||||
RegisterCallback<AttachToPanelEvent>(OnEnterPanel);
|
||||
RegisterCallback<DetachFromPanelEvent>(OnLeavePanel);
|
||||
}
|
||||
|
||||
public void GrabFocus()
|
||||
{
|
||||
SearchToolbar.GrabFocus();
|
||||
}
|
||||
|
||||
public new void SetEnabled(bool enable)
|
||||
{
|
||||
base.SetEnabled(enable);
|
||||
FilterButton.SetEnabled(enable);
|
||||
AdvancedButton.SetEnabled(enable);
|
||||
SearchToolbar.SetEnabled(enable);
|
||||
}
|
||||
|
||||
private static string GetFilterDisplayName(PackageFilter filter)
|
||||
{
|
||||
switch (filter)
|
||||
{
|
||||
case PackageFilter.All:
|
||||
return "All packages";
|
||||
case PackageFilter.Local:
|
||||
return "In Project";
|
||||
case PackageFilter.Modules:
|
||||
return "Built-in packages";
|
||||
case PackageFilter.None:
|
||||
return "None";
|
||||
default:
|
||||
return filter.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
private void SetFilter(object obj)
|
||||
{
|
||||
var previouSelectedFilter = selectedFilter;
|
||||
selectedFilter = (PackageFilter) obj;
|
||||
FilterButton.text = string.Format("{0} ▾", GetFilterDisplayName(selectedFilter));
|
||||
|
||||
if (selectedFilter != previouSelectedFilter)
|
||||
PackageCollection.Instance.SetFilter(selectedFilter);
|
||||
}
|
||||
|
||||
private void OnFilterButtonMouseDown(MouseDownEvent evt)
|
||||
{
|
||||
if (evt.propagationPhase != PropagationPhase.AtTarget)
|
||||
return;
|
||||
|
||||
var menu = new GenericMenu();
|
||||
menu.AddItem(new GUIContent(GetFilterDisplayName(PackageFilter.All)),
|
||||
selectedFilter == PackageFilter.All,
|
||||
SetFilter, PackageFilter.All);
|
||||
menu.AddItem(new GUIContent(GetFilterDisplayName(PackageFilter.Local)),
|
||||
selectedFilter == PackageFilter.Local,
|
||||
SetFilter, PackageFilter.Local);
|
||||
menu.AddSeparator("");
|
||||
menu.AddItem(new GUIContent(GetFilterDisplayName(PackageFilter.Modules)),
|
||||
selectedFilter == PackageFilter.Modules,
|
||||
SetFilter, PackageFilter.Modules);
|
||||
var menuPosition = new Vector2(FilterButton.layout.xMin, FilterButton.layout.center.y);
|
||||
menuPosition = this.LocalToWorld(menuPosition);
|
||||
var menuRect = new Rect(menuPosition, Vector2.zero);
|
||||
menu.DropDown(menuRect);
|
||||
}
|
||||
|
||||
private void OnAdvancedButtonMouseDown(MouseDownEvent evt)
|
||||
{
|
||||
if (evt.propagationPhase != PropagationPhase.AtTarget)
|
||||
return;
|
||||
|
||||
var menu = new GenericMenu();
|
||||
|
||||
menu.AddItem(new GUIContent("Show preview packages"), PackageManagerPrefs.ShowPreviewPackages, TogglePreviewPackages);
|
||||
//menu.AddItem(new GUIContent("Reset to defaults"), false, ResetToDefaultsClick);
|
||||
|
||||
var menuPosition = new Vector2(AdvancedButton.layout.xMax + 30, AdvancedButton.layout.center.y);
|
||||
menuPosition = this.LocalToWorld(menuPosition);
|
||||
var menuRect = new Rect(menuPosition, Vector2.zero);
|
||||
menu.DropDown(menuRect);
|
||||
}
|
||||
|
||||
private static void TogglePreviewPackages()
|
||||
{
|
||||
var showPreviewPackages = PackageManagerPrefs.ShowPreviewPackages;
|
||||
if (!showPreviewPackages && PackageManagerPrefs.ShowPreviewPackagesWarning)
|
||||
{
|
||||
const string message = "Preview packages are not verified with Unity, may be unstable, and are unsupported in production. Are you sure you want to show preview packages?";
|
||||
if (!EditorUtility.DisplayDialog("Unity Package Manager", message, "Yes", "No"))
|
||||
return;
|
||||
PackageManagerPrefs.ShowPreviewPackagesWarning = false;
|
||||
}
|
||||
PackageManagerPrefs.ShowPreviewPackages = !showPreviewPackages;
|
||||
PackageCollection.Instance.UpdatePackageCollection(true);
|
||||
}
|
||||
|
||||
private void ResetToDefaultsClick()
|
||||
{
|
||||
if (!EditorUtility.DisplayDialog("Unity Package Manager", "Operation will reset all your packages to Editor defaults. Do you want to continue?", "Yes", "No"))
|
||||
return;
|
||||
|
||||
// Registered on callback
|
||||
AssemblyReloadEvents.beforeAssemblyReload += PackageManagerWindow.ShowPackageManagerWindow;
|
||||
|
||||
Client.ResetToEditorDefaults();
|
||||
|
||||
var windows = UnityEngine.Resources.FindObjectsOfTypeAll<PackageManagerWindow>();
|
||||
if (windows.Length > 0)
|
||||
{
|
||||
windows[0].Close();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnEnterPanel(AttachToPanelEvent evt)
|
||||
{
|
||||
FilterButton.RegisterCallback<MouseDownEvent>(OnFilterButtonMouseDown);
|
||||
AdvancedButton.RegisterCallback<MouseDownEvent>(OnAdvancedButtonMouseDown);
|
||||
}
|
||||
|
||||
private void OnLeavePanel(DetachFromPanelEvent evt)
|
||||
{
|
||||
FilterButton.UnregisterCallback<MouseDownEvent>(OnFilterButtonMouseDown);
|
||||
AdvancedButton.UnregisterCallback<MouseDownEvent>(OnAdvancedButtonMouseDown);
|
||||
}
|
||||
|
||||
private Label FilterButton { get { return root.Q<Label>("toolbarFilterButton"); } }
|
||||
private Label AdvancedButton { get { return root.Q<Label>("toolbarAdvancedButton"); } }
|
||||
internal PackageSearchToolbar SearchToolbar { get { return root.Q<PackageSearchToolbar>("toolbarSearch"); } }
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b6d1682724bab428496b2bd2d8c7b194
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Experimental.UIElements;
|
||||
using UnityEditor.Experimental.UIElements;
|
||||
|
||||
namespace UnityEditor.PackageManager.UI
|
||||
{
|
||||
internal class PackageManagerWindow : EditorWindow
|
||||
{
|
||||
public const string PackagePath = "Packages/com.unity.package-manager-ui/";
|
||||
public const string ResourcesPath = PackagePath + "Editor/Resources/";
|
||||
private const string TemplatePath = ResourcesPath + "Templates/PackageManagerWindow.uxml";
|
||||
private const string DarkStylePath = ResourcesPath + "Styles/Main_Dark.uss";
|
||||
private const string LightStylePath = ResourcesPath + "Styles/Main_Light.uss";
|
||||
|
||||
private const double targetVersionNumber = 2018.1;
|
||||
|
||||
public PackageCollection Collection;
|
||||
public PackageSearchFilter SearchFilter;
|
||||
|
||||
#if UNITY_2018_1_OR_NEWER
|
||||
|
||||
public void OnEnable()
|
||||
{
|
||||
PackageCollection.InitInstance(ref Collection);
|
||||
PackageSearchFilter.InitInstance(ref SearchFilter);
|
||||
|
||||
this.GetRootVisualContainer().AddStyleSheetPath(EditorGUIUtility.isProSkin ? DarkStylePath : LightStylePath);
|
||||
|
||||
var windowResource = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>(TemplatePath);
|
||||
if (windowResource != null)
|
||||
{
|
||||
var template = windowResource.CloneTree(null);
|
||||
this.GetRootVisualContainer().Add(template);
|
||||
template.StretchToParentSize();
|
||||
|
||||
PackageList.OnSelected += OnPackageSelected;
|
||||
PackageList.OnLoaded += OnPackagesLoaded;
|
||||
PackageList.OnFocusChange += OnListFocusChange;
|
||||
|
||||
PackageManagerToolbar.SearchToolbar.OnSearchChange += OnSearchChange;
|
||||
PackageManagerToolbar.SearchToolbar.OnFocusChange += OnToolbarFocusChange;
|
||||
|
||||
// Disable filter while fetching first results
|
||||
if (!PackageCollection.Instance.LatestListPackages.Any())
|
||||
PackageManagerToolbar.SetEnabled(false);
|
||||
else
|
||||
PackageList.SelectLastSelection();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnListFocusChange()
|
||||
{
|
||||
PackageManagerToolbar.GrabFocus();
|
||||
}
|
||||
|
||||
private void OnToolbarFocusChange()
|
||||
{
|
||||
PackageList.GrabFocus();
|
||||
}
|
||||
|
||||
private void OnSearchChange(string searchText)
|
||||
{
|
||||
PackageSearchFilter.Instance.SearchText = searchText;
|
||||
PackageFiltering.FilterPackageList(PackageList);
|
||||
}
|
||||
|
||||
public void OnDisable()
|
||||
{
|
||||
// Package list item may not be valid here.
|
||||
if (PackageList != null)
|
||||
{
|
||||
PackageList.OnSelected -= OnPackageSelected;
|
||||
PackageList.OnLoaded -= OnPackagesLoaded;
|
||||
}
|
||||
|
||||
if (PackageManagerToolbar != null)
|
||||
{
|
||||
PackageManagerToolbar.SearchToolbar.OnSearchChange -= OnSearchChange;
|
||||
PackageManagerToolbar.SearchToolbar.OnFocusChange -= OnToolbarFocusChange;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnDestroy()
|
||||
{
|
||||
PackageSearchFilter.Instance.ResetSearch();
|
||||
PackageCollection.Instance.SetFilter(PackageFilter.All, false);
|
||||
}
|
||||
|
||||
private void OnPackageSelected(Package package)
|
||||
{
|
||||
PackageDetails.SetPackage(package);
|
||||
}
|
||||
|
||||
private void OnPackagesLoaded()
|
||||
{
|
||||
PackageManagerToolbar.SetEnabled(true);
|
||||
}
|
||||
|
||||
private PackageList PackageList
|
||||
{
|
||||
get {return this.GetRootVisualContainer().Q<PackageList>("packageList");}
|
||||
}
|
||||
|
||||
private PackageDetails PackageDetails
|
||||
{
|
||||
get {return this.GetRootVisualContainer().Q<PackageDetails>("detailsGroup");}
|
||||
}
|
||||
|
||||
private PackageManagerToolbar PackageManagerToolbar
|
||||
{
|
||||
get {return this.GetRootVisualContainer().Q<PackageManagerToolbar>("toolbarContainer");}
|
||||
}
|
||||
|
||||
internal Alert ErrorBanner { get { return this.GetRootVisualContainer().Q<Alert>("errorBanner"); } }
|
||||
|
||||
#endif
|
||||
|
||||
[MenuItem("Window/Package Manager", priority = 1500)]
|
||||
internal static void ShowPackageManagerWindow()
|
||||
{
|
||||
#if UNITY_2018_1_OR_NEWER
|
||||
var window = GetWindow<PackageManagerWindow>(false, "Packages", true);
|
||||
window.minSize = new Vector2(700, 250);
|
||||
window.Show();
|
||||
#else
|
||||
EditorUtility.DisplayDialog("Unsupported Unity Version", string.Format("The Package Manager requires Unity Version {0} or higher to operate.", targetVersionNumber), "Ok");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 650ea1d167b834d0f86d94e1e8c3b80f
|
||||
timeCreated: 1502224642
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+153
@@ -0,0 +1,153 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Experimental.UIElements;
|
||||
|
||||
namespace UnityEditor.PackageManager.UI
|
||||
{
|
||||
#if !UNITY_2018_3_OR_NEWER
|
||||
internal class PackageSearchToolbarFactory : UxmlFactory<PackageSearchToolbar>
|
||||
{
|
||||
protected override PackageSearchToolbar DoCreate(IUxmlAttributes bag, CreationContext cc)
|
||||
{
|
||||
return new PackageSearchToolbar();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
internal class PackageSearchToolbar : VisualElement
|
||||
{
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
internal new class UxmlFactory : UxmlFactory<PackageSearchToolbar> { }
|
||||
#endif
|
||||
private const string kPlaceHolder = "Search by package name, verified, preview or version number...";
|
||||
|
||||
public event Action OnFocusChange = delegate { };
|
||||
public event Action<string> OnSearchChange = delegate { };
|
||||
|
||||
private string searchText;
|
||||
private bool showingPlaceHolder;
|
||||
|
||||
private readonly VisualElement root;
|
||||
|
||||
public PackageSearchToolbar()
|
||||
{
|
||||
root = Resources.GetTemplate("PackageSearchToolbar.uxml");
|
||||
Add(root);
|
||||
root.StretchToParentSize();
|
||||
|
||||
SearchTextField.value = searchText;
|
||||
SearchTextField.maxLength = 54;
|
||||
SearchCancelButton.clickable.clicked += SearchCancelButtonClick;
|
||||
|
||||
RegisterCallback<AttachToPanelEvent>(OnEnterPanel);
|
||||
RegisterCallback<DetachFromPanelEvent>(OnLeavePanel);
|
||||
|
||||
searchText = PackageSearchFilter.Instance.SearchText;
|
||||
|
||||
if (string.IsNullOrEmpty(searchText))
|
||||
{
|
||||
showingPlaceHolder = true;
|
||||
SearchTextField.value = kPlaceHolder;
|
||||
SearchTextField.AddToClassList("placeholder");
|
||||
}
|
||||
else
|
||||
{
|
||||
showingPlaceHolder = false;
|
||||
SearchTextField.value = searchText;
|
||||
SearchTextField.RemoveFromClassList("placeholder");
|
||||
}
|
||||
}
|
||||
|
||||
public void GrabFocus()
|
||||
{
|
||||
SearchTextField.Focus();
|
||||
}
|
||||
|
||||
public new void SetEnabled(bool enable)
|
||||
{
|
||||
base.SetEnabled(enable);
|
||||
SearchTextField.SetEnabled(enable);
|
||||
SearchCancelButton.SetEnabled(enable);
|
||||
}
|
||||
|
||||
private void OnSearchTextFieldChange(ChangeEvent<string> evt)
|
||||
{
|
||||
if (showingPlaceHolder && evt.newValue == kPlaceHolder)
|
||||
return;
|
||||
if (!string.IsNullOrEmpty(evt.newValue))
|
||||
SearchCancelButton.AddToClassList("on");
|
||||
else
|
||||
SearchCancelButton.RemoveFromClassList("on");
|
||||
|
||||
searchText = evt.newValue;
|
||||
OnSearchChange(searchText);
|
||||
}
|
||||
|
||||
private void OnSearchTextFieldFocus(FocusEvent evt)
|
||||
{
|
||||
if (showingPlaceHolder)
|
||||
{
|
||||
SearchTextField.value = string.Empty;
|
||||
SearchTextField.RemoveFromClassList("placeholder");
|
||||
showingPlaceHolder = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnSearchTextFieldFocusOut(FocusOutEvent evt)
|
||||
{
|
||||
if (string.IsNullOrEmpty(searchText))
|
||||
{
|
||||
showingPlaceHolder = true;
|
||||
SearchTextField.AddToClassList("placeholder");
|
||||
SearchTextField.value = kPlaceHolder;
|
||||
}
|
||||
}
|
||||
|
||||
private void SearchCancelButtonClick()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(SearchTextField.value))
|
||||
{
|
||||
SearchTextField.value = string.Empty;
|
||||
}
|
||||
|
||||
showingPlaceHolder = true;
|
||||
SearchTextField.AddToClassList("placeholder");
|
||||
SearchTextField.value = kPlaceHolder;
|
||||
}
|
||||
|
||||
private void OnEnterPanel(AttachToPanelEvent evt)
|
||||
{
|
||||
SearchTextField.RegisterCallback<FocusEvent>(OnSearchTextFieldFocus);
|
||||
SearchTextField.RegisterCallback<FocusOutEvent>(OnSearchTextFieldFocusOut);
|
||||
SearchTextField.RegisterCallback<ChangeEvent<string>>(OnSearchTextFieldChange);
|
||||
SearchTextField.RegisterCallback<KeyDownEvent>(OnKeyDownShortcut);
|
||||
}
|
||||
|
||||
private void OnLeavePanel(DetachFromPanelEvent evt)
|
||||
{
|
||||
SearchTextField.UnregisterCallback<FocusEvent>(OnSearchTextFieldFocus);
|
||||
SearchTextField.UnregisterCallback<FocusOutEvent>(OnSearchTextFieldFocusOut);
|
||||
SearchTextField.UnregisterCallback<ChangeEvent<string>>(OnSearchTextFieldChange);
|
||||
SearchTextField.UnregisterCallback<KeyDownEvent>(OnKeyDownShortcut);
|
||||
}
|
||||
|
||||
private void OnKeyDownShortcut(KeyDownEvent evt)
|
||||
{
|
||||
if (evt.keyCode == KeyCode.Escape)
|
||||
{
|
||||
SearchCancelButtonClick();
|
||||
SearchCancelButton.Focus();
|
||||
evt.StopImmediatePropagation();
|
||||
return;
|
||||
}
|
||||
|
||||
if (evt.keyCode == KeyCode.Tab)
|
||||
{
|
||||
OnFocusChange();
|
||||
evt.StopImmediatePropagation();
|
||||
}
|
||||
}
|
||||
private TextField SearchTextField { get { return root.Q<TextField>("searchTextField"); } }
|
||||
private Button SearchCancelButton { get { return root.Q<Button>("searchCancelButton"); } }
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f74142ec8a4cd4fb1b0ff6cf5c3075af
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+150
@@ -0,0 +1,150 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Experimental.UIElements;
|
||||
|
||||
namespace UnityEditor.PackageManager.UI
|
||||
{
|
||||
#if !UNITY_2018_3_OR_NEWER
|
||||
internal class PackageStatusBarFactory : UxmlFactory<PackageStatusBar>
|
||||
{
|
||||
protected override PackageStatusBar DoCreate(IUxmlAttributes bag, CreationContext cc)
|
||||
{
|
||||
return new PackageStatusBar();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
internal class PackageStatusBar : VisualElement
|
||||
{
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
internal new class UxmlFactory : UxmlFactory<PackageStatusBar> { }
|
||||
#endif
|
||||
|
||||
private readonly VisualElement root;
|
||||
private string LastErrorMessage;
|
||||
|
||||
private List<IBaseOperation> operationsInProgress;
|
||||
|
||||
private enum StatusType {Normal, Loading, Error};
|
||||
|
||||
public PackageStatusBar()
|
||||
{
|
||||
root = Resources.GetTemplate("PackageStatusBar.uxml");
|
||||
Add(root);
|
||||
|
||||
MoreAddOptionsButton.clickable.clicked += OnMoreAddOptionsButtonClick;
|
||||
|
||||
LastErrorMessage = string.Empty;
|
||||
operationsInProgress = new List<IBaseOperation>();
|
||||
|
||||
SetDefaultMessage();
|
||||
|
||||
PackageCollection.Instance.ListSignal.WhenOperation(OnListOrSearchOperation);
|
||||
PackageCollection.Instance.SearchSignal.WhenOperation(OnListOrSearchOperation);
|
||||
}
|
||||
|
||||
private void SetDefaultMessage()
|
||||
{
|
||||
if(!string.IsNullOrEmpty(PackageCollection.Instance.lastUpdateTime))
|
||||
SetStatusMessage(StatusType.Normal, "Last update " + PackageCollection.Instance.lastUpdateTime);
|
||||
else
|
||||
SetStatusMessage(StatusType.Normal, string.Empty);
|
||||
}
|
||||
|
||||
private void OnListOrSearchOperation(IBaseOperation operation)
|
||||
{
|
||||
if (operation == null || operation.IsCompleted)
|
||||
return;
|
||||
operationsInProgress.Add(operation);
|
||||
operation.OnOperationFinalized += () => { OnOperationFinalized(operation); };
|
||||
operation.OnOperationError += OnOperationError;
|
||||
|
||||
SetStatusMessage(StatusType.Loading, "Loading packages...");
|
||||
}
|
||||
|
||||
private void OnOperationFinalized(IBaseOperation operation)
|
||||
{
|
||||
operationsInProgress.Remove(operation);
|
||||
|
||||
if (operationsInProgress.Any()) return;
|
||||
|
||||
var errorMessage = LastErrorMessage;
|
||||
|
||||
if (Application.internetReachability == NetworkReachability.NotReachable)
|
||||
{
|
||||
EditorApplication.update -= CheckInternetReachability;
|
||||
EditorApplication.update += CheckInternetReachability;
|
||||
|
||||
errorMessage = "You seem to be offline.";
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(errorMessage))
|
||||
SetStatusMessage(StatusType.Error, errorMessage);
|
||||
else
|
||||
SetDefaultMessage();
|
||||
}
|
||||
|
||||
private void OnOperationError(Error error)
|
||||
{
|
||||
LastErrorMessage = "Cannot load packages, see console.";
|
||||
}
|
||||
|
||||
private void CheckInternetReachability()
|
||||
{
|
||||
if (Application.internetReachability == NetworkReachability.NotReachable) return;
|
||||
|
||||
PackageCollection.Instance.FetchListCache(true);
|
||||
PackageCollection.Instance.FetchSearchCache(true);
|
||||
EditorApplication.update -= CheckInternetReachability;
|
||||
}
|
||||
|
||||
private void SetStatusMessage(StatusType status, string message)
|
||||
{
|
||||
if (status == StatusType.Loading)
|
||||
LoadingSpinner.Start();
|
||||
else
|
||||
LoadingSpinner.Stop();
|
||||
|
||||
UIUtils.SetElementDisplay(LoadingIcon, status == StatusType.Error);
|
||||
if (status == StatusType.Error)
|
||||
LoadingText.AddToClassList("icon");
|
||||
else
|
||||
LoadingText.RemoveFromClassList("icon");
|
||||
|
||||
LoadingText.text = message;
|
||||
}
|
||||
|
||||
private void OnMoreAddOptionsButtonClick()
|
||||
{
|
||||
var menu = new GenericMenu();
|
||||
|
||||
var addPackageFromDiskItem = new GUIContent("Add package from disk...");
|
||||
|
||||
/* // Disable adding from url field before the feature is ready
|
||||
var addPackageFromUrlItem = new GUIContent("Add package from URL...");
|
||||
menu.AddItem(addPackageFromUrlItem, false, delegate
|
||||
{
|
||||
AddFromUrlField.Show(true);
|
||||
});
|
||||
*/
|
||||
|
||||
menu.AddItem(addPackageFromDiskItem, false, delegate
|
||||
{
|
||||
var path = EditorUtility.OpenFilePanelWithFilters("Select package on disk", "", new[] { "package.json file", "json" });
|
||||
if (!string.IsNullOrEmpty(path) && !Package.AddRemoveOperationInProgress)
|
||||
Package.AddFromLocalDisk(path);
|
||||
});
|
||||
var menuPosition = MoreAddOptionsButton.LocalToWorld(new Vector2(MoreAddOptionsButton.layout.width, 0));
|
||||
var menuRect = new Rect(menuPosition, Vector2.zero);
|
||||
menu.DropDown(menuRect);
|
||||
}
|
||||
|
||||
private PackageAddFromUrlField AddFromUrlField { get { return root.Q<PackageAddFromUrlField>("packageAddFromUrlField"); }}
|
||||
private VisualElement LoadingSpinnerContainer { get { return root.Q<VisualElement>("loadingSpinnerContainer"); }}
|
||||
private LoadingSpinner LoadingSpinner { get { return root.Q<LoadingSpinner>("packageSpinner"); }}
|
||||
private Label LoadingIcon { get { return root.Q<Label>("loadingIcon"); }}
|
||||
private Label LoadingText { get { return root.Q<Label>("loadingText"); }}
|
||||
private Button MoreAddOptionsButton{ get { return root.Q<Button>("moreAddOptionsButton"); }}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f34f5fa2437664b2a81b4a7f34df87ad
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user