desktop-maesty/steve
6 years ago
85 changed files with 5615 additions and 1849 deletions
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: a747a40b0f1ab6f48b28b29fdb77f2ed |
||||
folderAsset: yes |
||||
DefaultImporter: |
||||
externalObjects: {} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,12 @@
|
||||
// Copyright (c) Rotorz Limited. All rights reserved. |
||||
// Licensed under the MIT license. See LICENSE file in the project root. |
||||
|
||||
using System.Collections.Generic; |
||||
using UnityEngine; |
||||
|
||||
public class DemoBehaviour : MonoBehaviour { |
||||
|
||||
public List<string> wishlist = new List<string>(); |
||||
public List<Vector2> points = new List<Vector2>(); |
||||
|
||||
} |
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2 |
||||
guid: acf5477b21448904ebe3636dcb6a0276 |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,8 @@
|
||||
// Copyright (c) Rotorz Limited. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root.
|
||||
#pragma strict |
||||
|
||||
import System.Collections.Generic; |
||||
|
||||
var wishlist:List.<String> = new List.<String>(); |
||||
var points:List.<Vector2> = new List.<Vector2>(); |
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 253f52cce58987b4e8f2108722555925 |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: bd53be4000846a648b766b6c79bf6bbd |
||||
folderAsset: yes |
||||
DefaultImporter: |
||||
externalObjects: {} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,30 @@
|
||||
// Copyright (c) Rotorz Limited. All rights reserved. |
||||
// Licensed under the MIT license. See LICENSE file in the project root. |
||||
|
||||
using Rotorz.ReorderableList; |
||||
using UnityEditor; |
||||
|
||||
[CustomEditor(typeof(DemoBehaviour))] |
||||
public class DemoBehaviourEditor : Editor { |
||||
|
||||
private SerializedProperty _wishlistProperty; |
||||
private SerializedProperty _pointsProperty; |
||||
|
||||
private void OnEnable() { |
||||
_wishlistProperty = serializedObject.FindProperty("wishlist"); |
||||
_pointsProperty = serializedObject.FindProperty("points"); |
||||
} |
||||
|
||||
public override void OnInspectorGUI() { |
||||
serializedObject.Update(); |
||||
|
||||
ReorderableListGUI.Title("Wishlist"); |
||||
ReorderableListGUI.ListField(_wishlistProperty); |
||||
|
||||
ReorderableListGUI.Title("Points"); |
||||
ReorderableListGUI.ListField(_pointsProperty); |
||||
|
||||
serializedObject.ApplyModifiedProperties(); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 036558d96cb3f6a418344bd5fb29215e |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,184 @@
|
||||
using UnityEngine; |
||||
using UnityEditor; |
||||
using Rotorz.ReorderableList; |
||||
using System.Collections.Generic; |
||||
|
||||
public class MultiListEditorWindowDemo : EditorWindow { |
||||
|
||||
[MenuItem("Window/Multi List Demo (C#)")] |
||||
private static void ShowWindow() { |
||||
GetWindow<MultiListEditorWindowDemo>("Multi List"); |
||||
} |
||||
|
||||
private class ExampleListAdaptor : GenericListAdaptor<string>, IReorderableListDropTarget { |
||||
|
||||
private const float MouseDragThresholdInPixels = 0.6f; |
||||
|
||||
// Static reference to the list adaptor of the selected item. |
||||
private static ExampleListAdaptor s_SelectedList; |
||||
// Static reference limits selection to one item in one list. |
||||
private static string s_SelectedItem; |
||||
// Position in GUI where mouse button was anchored before dragging occurred. |
||||
private static Vector2 s_MouseDownPosition; |
||||
|
||||
// Holds data representing the item that is being dragged. |
||||
private class DraggedItem { |
||||
|
||||
public static readonly string TypeName = typeof(DraggedItem).FullName; |
||||
|
||||
public readonly ExampleListAdaptor SourceListAdaptor; |
||||
public readonly int Index; |
||||
public readonly string ShoppingItem; |
||||
|
||||
public DraggedItem(ExampleListAdaptor sourceList, int index, string shoppingItem) { |
||||
SourceListAdaptor = sourceList; |
||||
Index = index; |
||||
ShoppingItem = shoppingItem; |
||||
} |
||||
|
||||
} |
||||
|
||||
public ExampleListAdaptor(IList<string> list) : base(list, null, 16f) { |
||||
} |
||||
|
||||
public override void DrawItemBackground(Rect position, int index) { |
||||
if (this == s_SelectedList && List[index] == s_SelectedItem) { |
||||
Color restoreColor = GUI.color; |
||||
GUI.color = ReorderableListStyles.SelectionBackgroundColor; |
||||
GUI.DrawTexture(position, EditorGUIUtility.whiteTexture); |
||||
GUI.color = restoreColor; |
||||
} |
||||
} |
||||
|
||||
public override void DrawItem(Rect position, int index) { |
||||
string shoppingItem = List[index]; |
||||
|
||||
int controlID = GUIUtility.GetControlID(FocusType.Passive); |
||||
|
||||
switch (Event.current.GetTypeForControl(controlID)) { |
||||
case EventType.MouseDown: |
||||
Rect totalItemPosition = ReorderableListGUI.CurrentItemTotalPosition; |
||||
if (totalItemPosition.Contains(Event.current.mousePosition)) { |
||||
// Select this list item. |
||||
s_SelectedList = this; |
||||
s_SelectedItem = shoppingItem; |
||||
} |
||||
|
||||
// Calculate rectangle of draggable area of the list item. |
||||
// This example excludes the grab handle at the left. |
||||
Rect draggableRect = totalItemPosition; |
||||
draggableRect.x = position.x; |
||||
draggableRect.width = position.width; |
||||
|
||||
if (Event.current.button == 0 && draggableRect.Contains(Event.current.mousePosition)) { |
||||
// Select this list item. |
||||
s_SelectedList = this; |
||||
s_SelectedItem = shoppingItem; |
||||
|
||||
// Lock onto this control whilst left mouse button is held so |
||||
// that we can start a drag-and-drop operation when user drags. |
||||
GUIUtility.hotControl = controlID; |
||||
s_MouseDownPosition = Event.current.mousePosition; |
||||
Event.current.Use(); |
||||
} |
||||
break; |
||||
|
||||
case EventType.MouseDrag: |
||||
if (GUIUtility.hotControl == controlID) { |
||||
GUIUtility.hotControl = 0; |
||||
|
||||
// Begin drag-and-drop operation when the user drags the mouse |
||||
// pointer across the threshold. This threshold helps to avoid |
||||
// inadvertently starting a drag-and-drop operation. |
||||
if (Vector2.Distance(s_MouseDownPosition, Event.current.mousePosition) >= MouseDragThresholdInPixels) { |
||||
// Prepare data that will represent the item. |
||||
var item = new DraggedItem(this, index, shoppingItem); |
||||
|
||||
// Start drag-and-drop operation with the Unity API. |
||||
DragAndDrop.PrepareStartDrag(); |
||||
// Need to reset `objectReferences` and `paths` because `PrepareStartDrag` |
||||
// doesn't seem to reset these (at least, in Unity 4.x). |
||||
DragAndDrop.objectReferences = new Object[0]; |
||||
DragAndDrop.paths = new string[0]; |
||||
|
||||
DragAndDrop.SetGenericData(DraggedItem.TypeName, item); |
||||
DragAndDrop.StartDrag(shoppingItem); |
||||
} |
||||
|
||||
// Use this event so that the host window gets repainted with |
||||
// each mouse movement. |
||||
Event.current.Use(); |
||||
} |
||||
break; |
||||
|
||||
case EventType.Repaint: |
||||
EditorStyles.label.Draw(position, shoppingItem, false, false, false, false); |
||||
break; |
||||
} |
||||
} |
||||
|
||||
public bool CanDropInsert(int insertionIndex) { |
||||
if (!ReorderableListControl.CurrentListPosition.Contains(Event.current.mousePosition)) |
||||
return false; |
||||
|
||||
// Drop insertion is possible if the current drag-and-drop operation contains |
||||
// the supported type of custom data. |
||||
return DragAndDrop.GetGenericData(DraggedItem.TypeName) is DraggedItem; |
||||
} |
||||
|
||||
public void ProcessDropInsertion(int insertionIndex) { |
||||
if (Event.current.type == EventType.DragPerform) { |
||||
var draggedItem = DragAndDrop.GetGenericData(DraggedItem.TypeName) as DraggedItem; |
||||
|
||||
// Are we just reordering within the same list? |
||||
if (draggedItem.SourceListAdaptor == this) { |
||||
Move(draggedItem.Index, insertionIndex); |
||||
} |
||||
else { |
||||
// Nope, we are moving the item! |
||||
List.Insert(insertionIndex, draggedItem.ShoppingItem); |
||||
draggedItem.SourceListAdaptor.Remove(draggedItem.Index); |
||||
|
||||
// Ensure that the item remains selected at its new location! |
||||
s_SelectedList = this; |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
private List<string> _shoppingList; |
||||
private ExampleListAdaptor _shoppingListAdaptor; |
||||
|
||||
private List<string> _purchaseList; |
||||
private ExampleListAdaptor _purchaseListAdaptor; |
||||
|
||||
private void OnEnable() { |
||||
_shoppingList = new List<string>() { "Bread", "Carrots", "Beans", "Steak", "Coffee", "Fries" }; |
||||
_shoppingListAdaptor = new ExampleListAdaptor(_shoppingList); |
||||
|
||||
_purchaseList = new List<string>() { "Cheese", "Crackers" }; |
||||
_purchaseListAdaptor = new ExampleListAdaptor(_purchaseList); |
||||
} |
||||
|
||||
private void OnGUI() { |
||||
GUILayout.BeginHorizontal(); |
||||
|
||||
var columnWidth = GUILayout.Width(position.width / 2f - 6); |
||||
|
||||
// Draw list control on left side of the window. |
||||
GUILayout.BeginVertical(columnWidth); |
||||
ReorderableListGUI.Title("Shopping List"); |
||||
ReorderableListGUI.ListField(_shoppingListAdaptor); |
||||
GUILayout.EndVertical(); |
||||
|
||||
// Draw list control on right side of the window. |
||||
GUILayout.BeginVertical(columnWidth); |
||||
ReorderableListGUI.Title("Purchase List"); |
||||
ReorderableListGUI.ListField(_purchaseListAdaptor); |
||||
GUILayout.EndVertical(); |
||||
|
||||
GUILayout.EndHorizontal(); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2 |
||||
guid: a42361912a901e04bbe1405e84b81b8d |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,79 @@
|
||||
// Copyright (c) Rotorz Limited. All rights reserved. |
||||
// Licensed under the MIT license. See LICENSE file in the project root. |
||||
|
||||
using Rotorz.ReorderableList; |
||||
using System.Collections.Generic; |
||||
using UnityEditor; |
||||
using UnityEngine; |
||||
|
||||
public class ReorderableListDemo : EditorWindow { |
||||
|
||||
[MenuItem("Window/List Demo (C#)")] |
||||
static void ShowWindow() { |
||||
GetWindow<ReorderableListDemo>("List Demo"); |
||||
} |
||||
|
||||
public List<string> shoppingList; |
||||
public List<string> purchaseList; |
||||
|
||||
private void OnEnable() { |
||||
shoppingList = new List<string>(); |
||||
shoppingList.Add("Bread"); |
||||
shoppingList.Add("Carrots"); |
||||
shoppingList.Add("Beans"); |
||||
shoppingList.Add("Steak"); |
||||
shoppingList.Add("Coffee"); |
||||
shoppingList.Add("Fries"); |
||||
|
||||
purchaseList = new List<string>(); |
||||
purchaseList.Add("Cheese"); |
||||
purchaseList.Add("Crackers"); |
||||
} |
||||
|
||||
private Vector2 _scrollPosition; |
||||
|
||||
private void OnGUI() { |
||||
_scrollPosition = GUILayout.BeginScrollView(_scrollPosition); |
||||
|
||||
ReorderableListGUI.Title("Shopping List"); |
||||
ReorderableListGUI.ListField(shoppingList, PendingItemDrawer, DrawEmpty); |
||||
|
||||
ReorderableListGUI.Title("Purchased Items"); |
||||
ReorderableListGUI.ListField(purchaseList, PurchasedItemDrawer, DrawEmpty, ReorderableListFlags.HideAddButton | ReorderableListFlags.DisableReordering); |
||||
|
||||
GUILayout.EndScrollView(); |
||||
} |
||||
|
||||
private string PendingItemDrawer(Rect position, string itemValue) { |
||||
// Text fields do not like null values! |
||||
if (itemValue == null) |
||||
itemValue = ""; |
||||
|
||||
position.width -= 50; |
||||
itemValue = EditorGUI.TextField(position, itemValue); |
||||
|
||||
position.x = position.xMax + 5; |
||||
position.width = 45; |
||||
if (GUI.Button(position, "Info")) { |
||||
} |
||||
|
||||
return itemValue; |
||||
} |
||||
|
||||
private string PurchasedItemDrawer(Rect position, string itemValue) { |
||||
position.width -= 50; |
||||
GUI.Label(position, itemValue); |
||||
|
||||
position.x = position.xMax + 5; |
||||
position.width = 45; |
||||
if (GUI.Button(position, "Info")) { |
||||
} |
||||
|
||||
return itemValue; |
||||
} |
||||
|
||||
private void DrawEmpty() { |
||||
GUILayout.Label("No items in list.", EditorStyles.miniLabel); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2 |
||||
guid: a8187beba641e99409b4648cca1becd3 |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -1,9 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 1351e3cf05fcef04cbafc172b277cd32 |
||||
folderAsset: yes |
||||
timeCreated: 1434110041 |
||||
licenseType: Free |
||||
DefaultImporter: |
||||
externalObjects: {} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
||||
|
Binary file not shown.
@ -1,22 +0,0 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 21d076cb9a4ec214a8cb820e69657bc3 |
||||
PluginImporter: |
||||
serializedVersion: 1 |
||||
iconMap: {} |
||||
executionOrder: {} |
||||
isPreloaded: 0 |
||||
platformData: |
||||
Any: |
||||
enabled: 0 |
||||
settings: {} |
||||
Editor: |
||||
enabled: 1 |
||||
settings: |
||||
DefaultValueInitialized: true |
||||
WindowsStoreApps: |
||||
enabled: 0 |
||||
settings: |
||||
CPU: AnyCPU |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
File diff suppressed because it is too large
Load Diff
@ -1,6 +0,0 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 087430efbff5ee54a8c8273aee1508fc |
||||
TextScriptImporter: |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 646cdcce8adedda43a7b99aaefae2f4a |
||||
folderAsset: yes |
||||
DefaultImporter: |
||||
externalObjects: {} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,109 @@
|
||||
// Copyright (c) Rotorz Limited. All rights reserved. |
||||
// Licensed under the MIT license. See LICENSE file in the project root. |
||||
|
||||
using System; |
||||
|
||||
namespace Rotorz.ReorderableList { |
||||
|
||||
/// <summary> |
||||
/// Factory methods that create <see cref="IElementAdderMenuBuilder{TContext}"/> |
||||
/// instances that can then be used to build element adder menus. |
||||
/// </summary> |
||||
/// <example> |
||||
/// <para>The following example demonstrates how to build and display a menu which |
||||
/// allows the user to add elements to a given context object upon clicking a button:</para> |
||||
/// <code language="csharp"><![CDATA[ |
||||
/// public class ShoppingListElementAdder : IElementAdder<ShoppingList> { |
||||
/// public ShoppingListElementAdder(ShoppingList shoppingList) { |
||||
/// Object = shoppingList; |
||||
/// } |
||||
/// |
||||
/// public ShoppingList Object { get; private set; } |
||||
/// |
||||
/// public bool CanAddElement(Type type) { |
||||
/// return true; |
||||
/// } |
||||
/// public object AddElement(Type type) { |
||||
/// var instance = Activator.CreateInstance(type); |
||||
/// shoppingList.Add((ShoppingItem)instance); |
||||
/// return instance; |
||||
/// } |
||||
/// } |
||||
/// |
||||
/// private void DrawAddMenuButton(ShoppingList shoppingList) { |
||||
/// var content = new GUIContent("Add Menu"); |
||||
/// Rect position = GUILayoutUtility.GetRect(content, GUI.skin.button); |
||||
/// if (GUI.Button(position, content)) { |
||||
/// var builder = ElementAdderMenuBuilder.For<ShoppingList>(ShoppingItem); |
||||
/// builder.SetElementAdder(new ShoppingListElementAdder(shoppingList)); |
||||
/// var menu = builder.GetMenu(); |
||||
/// menu.DropDown(buttonPosition); |
||||
/// } |
||||
/// } |
||||
/// ]]></code> |
||||
/// <code language="unityscript"><![CDATA[ |
||||
/// public class ShoppingListElementAdder extends IElementAdder.<ShoppingList> { |
||||
/// var _object:ShoppingList; |
||||
/// |
||||
/// function ShoppingListElementAdder(shoppingList:ShoppingList) { |
||||
/// Object = shoppingList; |
||||
/// } |
||||
/// |
||||
/// function get Object():ShoppingList { return _object; } |
||||
/// |
||||
/// function CanAddElement(type:Type):boolean { |
||||
/// return true; |
||||
/// } |
||||
/// function AddElement(type:Type):System.Object { |
||||
/// var instance = Activator.CreateInstance(type); |
||||
/// shoppingList.Add((ShoppingItem)instance); |
||||
/// return instance; |
||||
/// } |
||||
/// } |
||||
/// |
||||
/// function DrawAddMenuButton(shoppingList:ShoppingList) { |
||||
/// var content = new GUIContent('Add Menu'); |
||||
/// var position = GUILayoutUtility.GetRect(content, GUI.skin.button); |
||||
/// if (GUI.Button(position, content)) { |
||||
/// var builder = ElementAdderMenuBuilder.For.<ShoppingList>(ShoppingItem); |
||||
/// builder.SetElementAdder(new ShoppingListElementAdder(shoppingList)); |
||||
/// var menu = builder.GetMenu(); |
||||
/// menu.DropDown(buttonPosition); |
||||
/// } |
||||
/// } |
||||
/// ]]></code> |
||||
/// </example> |
||||
public static class ElementAdderMenuBuilder { |
||||
|
||||
/// <summary> |
||||
/// Gets a <see cref="IElementAdderMenuBuilder{TContext}"/> to build an element |
||||
/// adder menu for a context object of the type <typeparamref name="TContext"/>. |
||||
/// </summary> |
||||
/// <typeparam name="TContext">Type of the context object that elements can be added to.</typeparam> |
||||
/// <returns> |
||||
/// A new <see cref="IElementAdderMenuBuilder{TContext}"/> instance. |
||||
/// </returns> |
||||
/// <seealso cref="IElementAdderMenuBuilder{TContext}.SetContractType(Type)"/> |
||||
public static IElementAdderMenuBuilder<TContext> For<TContext>() { |
||||
return new GenericElementAdderMenuBuilder<TContext>(); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Gets a <see cref="IElementAdderMenuBuilder{TContext}"/> to build an element |
||||
/// adder menu for a context object of the type <typeparamref name="TContext"/>. |
||||
/// </summary> |
||||
/// <typeparam name="TContext">Type of the context object that elements can be added to.</typeparam> |
||||
/// <param name="contractType">Contract type of addable elements.</param> |
||||
/// <returns> |
||||
/// A new <see cref="IElementAdderMenuBuilder{TContext}"/> instance. |
||||
/// </returns> |
||||
/// <seealso cref="IElementAdderMenuBuilder{TContext}.SetContractType(Type)"/> |
||||
public static IElementAdderMenuBuilder<TContext> For<TContext>(Type contractType) { |
||||
var builder = For<TContext>(); |
||||
builder.SetContractType(contractType); |
||||
return builder; |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2 |
||||
guid: e6152605dacd77c4db43aa59c2498ba6 |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,67 @@
|
||||
// Copyright (c) Rotorz Limited. All rights reserved. |
||||
// Licensed under the MIT license. See LICENSE file in the project root. |
||||
|
||||
using System; |
||||
|
||||
namespace Rotorz.ReorderableList { |
||||
|
||||
/// <summary> |
||||
/// Annotate <see cref="IElementAdderMenuCommand{TContext}"/> implementations with a |
||||
/// <see cref="ElementAdderMenuCommandAttribute"/> to associate it with the contract |
||||
/// type of addable elements. |
||||
/// </summary> |
||||
/// <example> |
||||
/// <para>The following source code demonstrates how to add a helper menu command to |
||||
/// the add element menu of a shopping list:</para> |
||||
/// <code language="csharp"><![CDATA[ |
||||
/// [ElementAdderMenuCommand(typeof(ShoppingItem))] |
||||
/// public class AddFavoriteShoppingItemsCommand : IElementAdderMenuCommand<ShoppingList> { |
||||
/// public AddFavoriteShoppingItemsCommand() { |
||||
/// Content = new GUIContent("Add Favorite Items"); |
||||
/// } |
||||
/// |
||||
/// public GUIContent Content { get; private set; } |
||||
/// |
||||
/// public bool CanExecute(IElementAdder<ShoppingList> elementAdder) { |
||||
/// return true; |
||||
/// } |
||||
/// public void Execute(IElementAdder<ShoppingList> elementAdder) { |
||||
/// // TODO: Add favorite items to the shopping list! |
||||
/// } |
||||
/// } |
||||
/// ]]></code> |
||||
/// <code language="unityscript"><![CDATA[ |
||||
/// @ElementAdderMenuCommand(ShoppingItem) |
||||
/// class AddFavoriteShoppingItemsCommand extends IElementAdderMenuCommand.<ShoppingList> { |
||||
/// var _content:GUIContent = new GUIContent('Add Favorite Items'); |
||||
/// |
||||
/// function get Content():GUIContent { return _content; } |
||||
/// |
||||
/// function CanExecute(elementAdder:IElementAdder.<ShoppingList>):boolean { |
||||
/// return true; |
||||
/// } |
||||
/// function Execute(elementAdder:IElementAdder.<ShoppingList>) { |
||||
/// // TODO: Add favorite items to the shopping list! |
||||
/// } |
||||
/// } |
||||
/// ]]></code> |
||||
/// </example> |
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = false)] |
||||
public sealed class ElementAdderMenuCommandAttribute : Attribute { |
||||
|
||||
/// <summary> |
||||
/// Initializes a new instance of the <see cref="ElementAdderMenuCommandAttribute"/> class. |
||||
/// </summary> |
||||
/// <param name="contractType">Contract type of addable elements.</param> |
||||
public ElementAdderMenuCommandAttribute(Type contractType) { |
||||
ContractType = contractType; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Gets the contract type of addable elements. |
||||
/// </summary> |
||||
public Type ContractType { get; private set; } |
||||
|
||||
} |
||||
|
||||
} |
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2 |
||||
guid: dab0906e0834f954b9c6427d5af66288 |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,170 @@
|
||||
// Copyright (c) Rotorz Limited. All rights reserved. |
||||
// Licensed under the MIT license. See LICENSE file in the project root. |
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
|
||||
namespace Rotorz.ReorderableList { |
||||
|
||||
/// <summary> |
||||
/// Provides meta information which is useful when creating new implementations of |
||||
/// the <see cref="IElementAdderMenuBuilder{TContext}"/> interface. |
||||
/// </summary> |
||||
public static class ElementAdderMeta { |
||||
|
||||
#region Adder Menu Command Types |
||||
|
||||
private static Dictionary<Type, Dictionary<Type, List<Type>>> s_ContextMap = new Dictionary<Type, Dictionary<Type, List<Type>>>(); |
||||
|
||||
private static IEnumerable<Type> GetMenuCommandTypes<TContext>() { |
||||
return |
||||
from a in AppDomain.CurrentDomain.GetAssemblies() |
||||
from t in a.GetTypes() |
||||
where t.IsClass && !t.IsAbstract && t.IsDefined(typeof(ElementAdderMenuCommandAttribute), false) |
||||
where typeof(IElementAdderMenuCommand<TContext>).IsAssignableFrom(t) |
||||
select t; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Gets an array of the <see cref="IElementAdderMenuCommand{TContext}"/> types |
||||
/// that are associated with the specified <paramref name="contractType"/>. |
||||
/// </summary> |
||||
/// <typeparam name="TContext">Type of the context object that elements can be added to.</typeparam> |
||||
/// <param name="contractType">Contract type of addable elements.</param> |
||||
/// <returns> |
||||
/// An array containing zero or more <see cref="System.Type"/>. |
||||
/// </returns> |
||||
/// <exception cref="System.ArgumentNullException"> |
||||
/// If <paramref name="contractType"/> is <c>null</c>. |
||||
/// </exception> |
||||
/// <seealso cref="GetMenuCommands{TContext}(Type)"/> |
||||
public static Type[] GetMenuCommandTypes<TContext>(Type contractType) { |
||||
if (contractType == null) |
||||
throw new ArgumentNullException("contractType"); |
||||
|
||||
Dictionary<Type, List<Type>> contractMap; |
||||
List<Type> commandTypes; |
||||
if (s_ContextMap.TryGetValue(typeof(TContext), out contractMap)) { |
||||
if (contractMap.TryGetValue(contractType, out commandTypes)) |
||||
return commandTypes.ToArray(); |
||||
} |
||||
else { |
||||
contractMap = new Dictionary<Type, List<Type>>(); |
||||
s_ContextMap[typeof(TContext)] = contractMap; |
||||
} |
||||
|
||||
commandTypes = new List<Type>(); |
||||
|
||||
foreach (var commandType in GetMenuCommandTypes<TContext>()) { |
||||
var attributes = (ElementAdderMenuCommandAttribute[])Attribute.GetCustomAttributes(commandType, typeof(ElementAdderMenuCommandAttribute)); |
||||
if (!attributes.Any(a => a.ContractType == contractType)) |
||||
continue; |
||||
|
||||
commandTypes.Add(commandType); |
||||
} |
||||
|
||||
contractMap[contractType] = commandTypes; |
||||
return commandTypes.ToArray(); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Gets an array of <see cref="IElementAdderMenuCommand{TContext}"/> instances |
||||
/// that are associated with the specified <paramref name="contractType"/>. |
||||
/// </summary> |
||||
/// <typeparam name="TContext">Type of the context object that elements can be added to.</typeparam> |
||||
/// <param name="contractType">Contract type of addable elements.</param> |
||||
/// <returns> |
||||
/// An array containing zero or more <see cref="IElementAdderMenuCommand{TContext}"/> instances. |
||||
/// </returns> |
||||
/// <exception cref="System.ArgumentNullException"> |
||||
/// If <paramref name="contractType"/> is <c>null</c>. |
||||
/// </exception> |
||||
/// <seealso cref="GetMenuCommandTypes{TContext}(Type)"/> |
||||
public static IElementAdderMenuCommand<TContext>[] GetMenuCommands<TContext>(Type contractType) { |
||||
var commandTypes = GetMenuCommandTypes<TContext>(contractType); |
||||
var commands = new IElementAdderMenuCommand<TContext>[commandTypes.Length]; |
||||
for (int i = 0; i < commandTypes.Length; ++i) |
||||
commands[i] = (IElementAdderMenuCommand<TContext>)Activator.CreateInstance(commandTypes[i]); |
||||
return commands; |
||||
} |
||||
|
||||
#endregion |
||||
|
||||
#region Concrete Element Types |
||||
|
||||
private static Dictionary<Type, Type[]> s_ConcreteElementTypes = new Dictionary<Type, Type[]>(); |
||||
|
||||
private static IEnumerable<Type> GetConcreteElementTypesHelper(Type contractType) { |
||||
if (contractType == null) |
||||
throw new ArgumentNullException("contractType"); |
||||
|
||||
Type[] concreteTypes; |
||||
if (!s_ConcreteElementTypes.TryGetValue(contractType, out concreteTypes)) { |
||||
concreteTypes = |
||||
(from a in AppDomain.CurrentDomain.GetAssemblies() |
||||
from t in a.GetTypes() |
||||
where t.IsClass && !t.IsAbstract && contractType.IsAssignableFrom(t) |
||||
orderby t.Name |
||||
select t |
||||
).ToArray(); |
||||
s_ConcreteElementTypes[contractType] = concreteTypes; |
||||
} |
||||
|
||||
return concreteTypes; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Gets a filtered array of the concrete element types that implement the |
||||
/// specified <paramref name="contractType"/>. |
||||
/// </summary> |
||||
/// <remarks> |
||||
/// <para>A type is excluded from the resulting array when one or more of the |
||||
/// specified <paramref name="filters"/> returns a value of <c>false</c>.</para> |
||||
/// </remarks> |
||||
/// <param name="contractType">Contract type of addable elements.</param> |
||||
/// <param name="filters">An array of zero or more filters.</param> |
||||
/// <returns> |
||||
/// An array of zero or more concrete element types. |
||||
/// </returns> |
||||
/// <exception cref="System.ArgumentNullException"> |
||||
/// If <paramref name="contractType"/> is <c>null</c>. |
||||
/// </exception> |
||||
/// <seealso cref="GetConcreteElementTypes(Type)"/> |
||||
public static Type[] GetConcreteElementTypes(Type contractType, Func<Type, bool>[] filters) { |
||||
return |
||||
(from t in GetConcreteElementTypesHelper(contractType) |
||||
where IsTypeIncluded(t, filters) |
||||
select t |
||||
).ToArray(); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Gets an array of all the concrete element types that implement the specified |
||||
/// <paramref name="contractType"/>. |
||||
/// </summary> |
||||
/// <param name="contractType">Contract type of addable elements.</param> |
||||
/// <returns> |
||||
/// An array of zero or more concrete element types. |
||||
/// </returns> |
||||
/// <exception cref="System.ArgumentNullException"> |
||||
/// If <paramref name="contractType"/> is <c>null</c>. |
||||
/// </exception> |
||||
/// <seealso cref="GetConcreteElementTypes(Type, Func{Type, bool}[])"/> |
||||
public static Type[] GetConcreteElementTypes(Type contractType) { |
||||
return GetConcreteElementTypesHelper(contractType).ToArray(); |
||||
} |
||||
|
||||
private static bool IsTypeIncluded(Type concreteType, Func<Type, bool>[] filters) { |
||||
if (filters != null) |
||||
foreach (var filter in filters) |
||||
if (!filter(concreteType)) |
||||
return false; |
||||
return true; |
||||
} |
||||
|
||||
#endregion |
||||
|
||||
} |
||||
|
||||
} |
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 159bf54b15add1440aaed680e94b81fc |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,38 @@
|
||||
// Copyright (c) Rotorz Limited. All rights reserved. |
||||
// Licensed under the MIT license. See LICENSE file in the project root. |
||||
|
||||
using UnityEditor; |
||||
using UnityEngine; |
||||
|
||||
namespace Rotorz.ReorderableList { |
||||
|
||||
internal sealed class GenericElementAdderMenu : IElementAdderMenu { |
||||
|
||||
private GenericMenu _innerMenu = new GenericMenu(); |
||||
|
||||
public GenericElementAdderMenu() { |
||||
} |
||||
|
||||
public void AddItem(GUIContent content, GenericMenu.MenuFunction handler) { |
||||
_innerMenu.AddItem(content, false, handler); |
||||
} |
||||
|
||||
public void AddDisabledItem(GUIContent content) { |
||||
_innerMenu.AddDisabledItem(content); |
||||
} |
||||
|
||||
public void AddSeparator(string path = "") { |
||||
_innerMenu.AddSeparator(path); |
||||
} |
||||
|
||||
public bool IsEmpty { |
||||
get { return _innerMenu.GetItemCount() == 0; } |
||||
} |
||||
|
||||
public void DropDown(Rect position) { |
||||
_innerMenu.DropDown(position); |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 662b5dcb25b78f94f9afe8d3f402b628 |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,102 @@
|
||||
// Copyright (c) Rotorz Limited. All rights reserved. |
||||
// Licensed under the MIT license. See LICENSE file in the project root. |
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using UnityEditor; |
||||
using UnityEngine; |
||||
|
||||
namespace Rotorz.ReorderableList { |
||||
|
||||
internal sealed class GenericElementAdderMenuBuilder<TContext> : IElementAdderMenuBuilder<TContext> { |
||||
|
||||
private static string NicifyTypeName(Type type) { |
||||
return ObjectNames.NicifyVariableName(type.Name); |
||||
} |
||||
|
||||
private Type _contractType; |
||||
private IElementAdder<TContext> _elementAdder; |
||||
private Func<Type, string> _typeDisplayNameFormatter; |
||||
private List<Func<Type, bool>> _typeFilters = new List<Func<Type, bool>>(); |
||||
private List<IElementAdderMenuCommand<TContext>> _customCommands = new List<IElementAdderMenuCommand<TContext>>(); |
||||
|
||||
public GenericElementAdderMenuBuilder() { |
||||
_typeDisplayNameFormatter = NicifyTypeName; |
||||
} |
||||
|
||||
public void SetContractType(Type contractType) { |
||||
_contractType = contractType; |
||||
} |
||||
|
||||
public void SetElementAdder(IElementAdder<TContext> elementAdder) { |
||||
_elementAdder = elementAdder; |
||||
} |
||||
|
||||
public void SetTypeDisplayNameFormatter(Func<Type, string> formatter) { |
||||
_typeDisplayNameFormatter = formatter ?? NicifyTypeName; |
||||
} |
||||
|
||||
public void AddTypeFilter(Func<Type, bool> typeFilter) { |
||||
if (typeFilter == null) |
||||
throw new ArgumentNullException("typeFilter"); |
||||
|
||||
_typeFilters.Add(typeFilter); |
||||
} |
||||
|
||||
public void AddCustomCommand(IElementAdderMenuCommand<TContext> command) { |
||||
if (command == null) |
||||
throw new ArgumentNullException("command"); |
||||
|
||||
_customCommands.Add(command); |
||||
} |
||||
|
||||
public IElementAdderMenu GetMenu() { |
||||
var menu = new GenericElementAdderMenu(); |
||||
|
||||
AddCommandsToMenu(menu, _customCommands); |
||||
|
||||
if (_contractType != null) { |
||||
AddCommandsToMenu(menu, ElementAdderMeta.GetMenuCommands<TContext>(_contractType)); |
||||
AddConcreteTypesToMenu(menu, ElementAdderMeta.GetConcreteElementTypes(_contractType, _typeFilters.ToArray())); |
||||
} |
||||
|
||||
return menu; |
||||
} |
||||
|
||||
private void AddCommandsToMenu(GenericElementAdderMenu menu, IList<IElementAdderMenuCommand<TContext>> commands) { |
||||
if (commands.Count == 0) |
||||
return; |
||||
|
||||
if (!menu.IsEmpty) |
||||
menu.AddSeparator(); |
||||
|
||||
foreach (var command in commands) { |
||||
if (_elementAdder != null && command.CanExecute(_elementAdder)) |
||||
menu.AddItem(command.Content, () => command.Execute(_elementAdder)); |
||||
else |
||||
menu.AddDisabledItem(command.Content); |
||||
} |
||||
} |
||||
|
||||
private void AddConcreteTypesToMenu(GenericElementAdderMenu menu, Type[] concreteTypes) { |
||||
if (concreteTypes.Length == 0) |
||||
return; |
||||
|
||||
if (!menu.IsEmpty) |
||||
menu.AddSeparator(); |
||||
|
||||
foreach (var concreteType in concreteTypes) { |
||||
var content = new GUIContent(_typeDisplayNameFormatter(concreteType)); |
||||
if (_elementAdder != null && _elementAdder.CanAddElement(concreteType)) |
||||
menu.AddItem(content, () => { |
||||
if (_elementAdder.CanAddElement(concreteType)) |
||||
_elementAdder.AddElement(concreteType); |
||||
}); |
||||
else |
||||
menu.AddDisabledItem(content); |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2 |
||||
guid: da8782cb7448c234fb86e9503326ce9c |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,43 @@
|
||||
// Copyright (c) Rotorz Limited. All rights reserved. |
||||
// Licensed under the MIT license. See LICENSE file in the project root. |
||||
|
||||
using System; |
||||
|
||||
namespace Rotorz.ReorderableList { |
||||
|
||||
/// <summary> |
||||
/// Interface for an object which adds elements to a context object of the type |
||||
/// <typeparamref name="TContext"/>. |
||||
/// </summary> |
||||
/// <typeparam name="TContext">Type of the context object that elements can be added to.</typeparam> |
||||
public interface IElementAdder<TContext> { |
||||
|
||||
/// <summary> |
||||
/// Gets the context object. |
||||
/// </summary> |
||||
TContext Object { get; } |
||||
|
||||
/// <summary> |
||||
/// Determines whether a new element of the specified <paramref name="type"/> can |
||||
/// be added to the associated context object. |
||||
/// </summary> |
||||
/// <param name="type">Type of element to add.</param> |
||||
/// <returns> |
||||
/// A value of <c>true</c> if an element of the specified type can be added; |
||||
/// otherwise, a value of <c>false</c>. |
||||
/// </returns> |
||||
bool CanAddElement(Type type); |
||||
|
||||
/// <summary> |
||||
/// Adds an element of the specified <paramref name="type"/> to the associated |
||||
/// context object. |
||||
/// </summary> |
||||
/// <param name="type">Type of element to add.</param> |
||||
/// <returns> |
||||
/// The new element. |
||||
/// </returns> |
||||
object AddElement(Type type); |
||||
|
||||
} |
||||
|
||||
} |
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 811c0b5125dc50746b66457b5c96741d |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,33 @@
|
||||
// Copyright (c) Rotorz Limited. All rights reserved. |
||||
// Licensed under the MIT license. See LICENSE file in the project root. |
||||
|
||||
using UnityEngine; |
||||
|
||||
namespace Rotorz.ReorderableList { |
||||
|
||||
/// <summary> |
||||
/// Interface for a menu interface. |
||||
/// </summary> |
||||
public interface IElementAdderMenu { |
||||
|
||||
/// <summary> |
||||
/// Gets a value indicating whether the menu contains any items. |
||||
/// </summary> |
||||
/// <value> |
||||
/// <c>true</c> if the menu contains one or more items; otherwise, <c>false</c>. |
||||
/// </value> |
||||
bool IsEmpty { get; } |
||||
|
||||
/// <summary> |
||||
/// Displays the drop-down menu inside an editor GUI. |
||||
/// </summary> |
||||
/// <remarks> |
||||
/// <para>This method should only be used during <b>OnGUI</b> and <b>OnSceneGUI</b> |
||||
/// events; for instance, inside an editor window, a custom inspector or scene view.</para> |
||||
/// </remarks> |
||||
/// <param name="position">Position of menu button in the GUI.</param> |
||||
void DropDown(Rect position); |
||||
|
||||
} |
||||
|
||||
} |
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 7452dc2d2d6305947ab39a48354ab4bb |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,76 @@
|
||||
// Copyright (c) Rotorz Limited. All rights reserved. |
||||
// Licensed under the MIT license. See LICENSE file in the project root. |
||||
|
||||
using System; |
||||
|
||||
namespace Rotorz.ReorderableList { |
||||
|
||||
/// <summary> |
||||
/// Interface for building an <see cref="IElementAdderMenu"/>. |
||||
/// </summary> |
||||
/// <typeparam name="TContext">Type of the context object that elements can be added to.</typeparam> |
||||
public interface IElementAdderMenuBuilder<TContext> { |
||||
|
||||
/// <summary> |
||||
/// Sets contract type of the elements that can be included in the <see cref="IElementAdderMenu"/>. |
||||
/// Only non-abstract class types that are assignable from the <paramref name="contractType"/> |
||||
/// will be included in the built menu. |
||||
/// </summary> |
||||
/// <param name="contractType">Contract type of addable elements.</param> |
||||
void SetContractType(Type contractType); |
||||
|
||||
/// <summary> |
||||
/// Set the <see cref="IElementAdder{TContext}"/> implementation which is used |
||||
/// when adding new elements to the context object. |
||||
/// </summary> |
||||
/// <remarks> |
||||
/// <para>Specify a value of <c>null</c> for <paramref name="elementAdder"/> to |
||||
/// prevent the selection of any types.</para> |
||||
/// </remarks> |
||||
/// <param name="elementAdder">Element adder.</param> |
||||
void SetElementAdder(IElementAdder<TContext> elementAdder); |
||||
|
||||
/// <summary> |
||||
/// Set the function that formats the display of type names in the user interface. |
||||
/// </summary> |
||||
/// <remarks> |
||||
/// <para>Specify a value of <c>null</c> for <paramref name="formatter"/> to |
||||
/// assume the default formatting function.</para> |
||||
/// </remarks> |
||||
/// <param name="formatter">Function that formats display name of type; or <c>null</c>.</param> |
||||
void SetTypeDisplayNameFormatter(Func<Type, string> formatter); |
||||
|
||||
/// <summary> |
||||
/// Adds a filter function which determines whether types can be included or |
||||
/// whether they need to be excluded. |
||||
/// </summary> |
||||
/// <remarks> |
||||
/// <para>If a filter function returns a value of <c>false</c> then that type |
||||
/// will not be included in the menu interface.</para> |
||||
/// </remarks> |
||||
/// <param name="typeFilter">Filter function.</param> |
||||
/// <exception cref="System.ArgumentNullException"> |
||||
/// If <paramref name="typeFilter"/> is <c>null</c>. |
||||
/// </exception> |
||||
void AddTypeFilter(Func<Type, bool> typeFilter); |
||||
|
||||
/// <summary> |
||||
/// Adds a custom command to the menu. |
||||
/// </summary> |
||||
/// <param name="command">The custom command.</param> |
||||
/// <exception cref="System.ArgumentNullException"> |
||||
/// If <paramref name="command"/> is <c>null</c>. |
||||
/// </exception> |
||||
void AddCustomCommand(IElementAdderMenuCommand<TContext> command); |
||||
|
||||
/// <summary> |
||||
/// Builds and returns a new <see cref="IElementAdderMenu"/> instance. |
||||
/// </summary> |
||||
/// <returns> |
||||
/// A new <see cref="IElementAdderMenu"/> instance each time the method is invoked. |
||||
/// </returns> |
||||
IElementAdderMenu GetMenu(); |
||||
|
||||
} |
||||
|
||||
} |
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 2810812b845cceb4e9a0f7c0de842f29 |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,41 @@
|
||||
// Copyright (c) Rotorz Limited. All rights reserved. |
||||
// Licensed under the MIT license. See LICENSE file in the project root. |
||||
|
||||
using UnityEngine; |
||||
|
||||
namespace Rotorz.ReorderableList { |
||||
|
||||
/// <summary> |
||||
/// Interface for a menu command that can be included in an <see cref="IElementAdderMenu"/> |
||||
/// either by annotating an implementation of the <see cref="IElementAdderMenuCommand{TContext}"/> |
||||
/// interface with <see cref="ElementAdderMenuCommandAttribute"/> or directly by |
||||
/// calling <see cref="IElementAdderMenuBuilder{TContext}.AddCustomCommand"/>. |
||||
/// </summary> |
||||
/// <typeparam name="TContext">Type of the context object that elements can be added to.</typeparam> |
||||
public interface IElementAdderMenuCommand<TContext> { |
||||
|
||||
/// <summary> |
||||
/// Gets the content of the menu command. |
||||
/// </summary> |
||||
GUIContent Content { get; } |
||||
|
||||
/// <summary> |
||||
/// Determines whether the command can be executed. |
||||
/// </summary> |
||||
/// <param name="elementAdder">The associated element adder provides access to |
||||
/// the <typeparamref name="TContext"/> instance.</param> |
||||
/// <returns> |
||||
/// A value of <c>true</c> if the command can execute; otherwise, <c>false</c>. |
||||
/// </returns> |
||||
bool CanExecute(IElementAdder<TContext> elementAdder); |
||||
|
||||
/// <summary> |
||||
/// Executes the command. |
||||
/// </summary> |
||||
/// <param name="elementAdder">The associated element adder provides access to |
||||
/// the <typeparamref name="TContext"/> instance.</param> |
||||
void Execute(IElementAdder<TContext> elementAdder); |
||||
|
||||
} |
||||
|
||||
} |
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 3fc42d99c85c1bc409897df1dae25bd4 |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,145 @@
|
||||
// Copyright (c) Rotorz Limited. All rights reserved. |
||||
// Licensed under the MIT license. See LICENSE file in the project root. |
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using UnityEngine; |
||||
|
||||
namespace Rotorz.ReorderableList { |
||||
|
||||
/// <summary> |
||||
/// Reorderable list adaptor for generic list. |
||||
/// </summary> |
||||
/// <remarks> |
||||
/// <para>This adaptor can be subclassed to add special logic to item height calculation. |
||||
/// You may want to implement a custom adaptor class where specialised functionality |
||||
/// is needed.</para> |
||||
/// <para>List elements which implement the <see cref="System.ICloneable"/> interface are |
||||
/// cloned using that interface upon duplication; otherwise the item value or reference is |
||||
/// simply copied.</para> |
||||
/// </remarks> |
||||
/// <typeparam name="T">Type of list element.</typeparam> |
||||
public class GenericListAdaptor<T> : IReorderableListAdaptor { |
||||
|
||||
private IList<T> _list; |
||||
|
||||
private ReorderableListControl.ItemDrawer<T> _itemDrawer; |
||||
|
||||
/// <summary> |
||||
/// Fixed height of each list item. |
||||
/// </summary> |
||||
public float FixedItemHeight; |
||||
|
||||
/// <summary> |
||||
/// Gets the underlying list data structure. |
||||
/// </summary> |
||||
public IList<T> List { |
||||
get { return _list; } |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Gets element from list. |
||||
/// </summary> |
||||
/// <param name="index">Zero-based index of element.</param> |
||||
/// <returns> |
||||
/// The element. |
||||
/// </returns> |
||||
public T this[int index] { |
||||
get { return _list[index]; } |
||||
} |
||||
|
||||
#region Construction |
||||
|
||||
/// <summary> |
||||
/// Initializes a new instance of <see cref="GenericListAdaptor{T}"/>. |
||||
/// </summary> |
||||
/// <param name="list">The list which can be reordered.</param> |
||||
/// <param name="itemDrawer">Callback to draw list item.</param> |
||||
/// <param name="itemHeight">Height of list item in pixels.</param> |
||||
public GenericListAdaptor(IList<T> list, ReorderableListControl.ItemDrawer<T> itemDrawer, float itemHeight) { |
||||
this._list = list; |
||||
this._itemDrawer = itemDrawer ?? ReorderableListGUI.DefaultItemDrawer; |
||||
this.FixedItemHeight = itemHeight; |
||||
} |
||||
|
||||
#endregion |
||||
|
||||
#region IReorderableListAdaptor - Implementation |
||||
|
||||
/// <inheritdoc/> |
||||
public int Count { |
||||
get { return _list.Count; } |
||||
} |
||||
|
||||
/// <inheritdoc/> |
||||
public virtual bool CanDrag(int index) { |
||||
return true; |
||||
} |
||||
/// <inheritdoc/> |
||||
public virtual bool CanRemove(int index) { |
||||
return true; |
||||
} |
||||
|
||||
/// <inheritdoc/> |
||||
public virtual void Add() { |
||||
_list.Add(default(T)); |
||||
} |
||||
/// <inheritdoc/> |
||||
public virtual void Insert(int index) { |
||||
_list.Insert(index, default(T)); |
||||
} |
||||
/// <inheritdoc/> |
||||
public virtual void Duplicate(int index) { |
||||
T newItem = _list[index]; |
||||
|
||||
ICloneable existingItem = newItem as ICloneable; |
||||
if (existingItem != null) |
||||
newItem = (T)existingItem.Clone(); |
||||
|
||||
_list.Insert(index + 1, newItem); |
||||
} |
||||
/// <inheritdoc/> |
||||
public virtual void Remove(int index) { |
||||
_list.RemoveAt(index); |
||||
} |
||||
/// <inheritdoc/> |
||||
public virtual void Move(int sourceIndex, int destIndex) { |
||||
if (destIndex > sourceIndex) |
||||
--destIndex; |
||||
|
||||
T item = _list[sourceIndex]; |
||||
_list.RemoveAt(sourceIndex); |
||||
_list.Insert(destIndex, item); |
||||
} |
||||
/// <inheritdoc/> |
||||
public virtual void Clear() { |
||||
_list.Clear(); |
||||
} |
||||
|
||||
/// <inheritdoc/> |
||||
public virtual void BeginGUI() { |
||||
} |
||||
|
||||
/// <inheritdoc/> |
||||
public virtual void EndGUI() { |
||||
} |
||||
|
||||
/// <inheritdoc/> |
||||
public virtual void DrawItemBackground(Rect position, int index) { |
||||
} |
||||
|
||||
/// <inheritdoc/> |
||||
public virtual void DrawItem(Rect position, int index) { |
||||
_list[index] = _itemDrawer(position, _list[index]); |
||||
} |
||||
|
||||
/// <inheritdoc/> |
||||
public virtual float GetItemHeight(int index) { |
||||
return FixedItemHeight; |
||||
} |
||||
|
||||
#endregion |
||||
|
||||
} |
||||
|
||||
} |
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 9860e7f6c1d1b8d45b13889a965e172f |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,131 @@
|
||||
// Copyright (c) Rotorz Limited. All rights reserved. |
||||
// Licensed under the MIT license. See LICENSE file in the project root. |
||||
|
||||
using UnityEngine; |
||||
|
||||
namespace Rotorz.ReorderableList { |
||||
|
||||
/// <summary> |
||||
/// Adaptor allowing reorderable list control to interface with list data. |
||||
/// </summary> |
||||
/// <see cref="IReorderableListDropTarget"/> |
||||
public interface IReorderableListAdaptor { |
||||
|
||||
/// <summary> |
||||
/// Gets count of elements in list. |
||||
/// </summary> |
||||
int Count { get; } |
||||
|
||||
/// <summary> |
||||
/// Determines whether an item can be reordered by dragging mouse. |
||||
/// </summary> |
||||
/// <remarks> |
||||
/// <para>This should be a light-weight method since it will be used to determine |
||||
/// whether grab handle should be included for each item in a reorderable list.</para> |
||||
/// <para>Please note that returning a value of <c>false</c> does not prevent movement |
||||
/// on list item since other draggable items can be moved around it.</para> |
||||
/// </remarks> |
||||
/// <param name="index">Zero-based index for list element.</param> |
||||
/// <returns> |
||||
/// A value of <c>true</c> if item can be dragged; otherwise <c>false</c>. |
||||
/// </returns> |
||||
bool CanDrag(int index); |
||||
/// <summary> |
||||
/// Determines whether an item can be removed from list. |
||||
/// </summary> |
||||
/// <remarks> |
||||
/// <para>This should be a light-weight method since it will be used to determine |
||||
/// whether remove button should be included for each item in list.</para> |
||||
/// <para>This is redundant when <see cref="ReorderableListFlags.HideRemoveButtons"/> |
||||
/// is specified.</para> |
||||
/// </remarks> |
||||
/// <param name="index">Zero-based index for list element.</param> |
||||
/// <returns> |
||||
/// A value of <c>true</c> if item can be removed; otherwise <c>false</c>. |
||||
/// </returns> |
||||
bool CanRemove(int index); |
||||
|
||||
/// <summary> |
||||
/// Add new element at end of list. |
||||
/// </summary> |
||||
void Add(); |
||||
/// <summary> |
||||
/// Insert new element at specified index. |
||||
/// </summary> |
||||
/// <param name="index">Zero-based index for list element.</param> |
||||
void Insert(int index); |
||||
/// <summary> |
||||
/// Duplicate existing element. |
||||
/// </summary> |
||||
/// <remarks> |
||||
/// <para>Consider using the <see cref="System.ICloneable"/> interface to |
||||
/// duplicate list elements where appropriate.</para> |
||||
/// </remarks> |
||||
/// <param name="index">Zero-based index of list element.</param> |
||||
void Duplicate(int index); |
||||
/// <summary> |
||||
/// Remove element at specified index. |
||||
/// </summary> |
||||
/// <param name="index">Zero-based index of list element.</param> |
||||
void Remove(int index); |
||||
/// <summary> |
||||
/// Move element from source index to destination index. |
||||
/// </summary> |
||||
/// <param name="sourceIndex">Zero-based index of source element.</param> |
||||
/// <param name="destIndex">Zero-based index of destination element.</param> |
||||
void Move(int sourceIndex, int destIndex); |
||||
/// <summary> |
||||
/// Clear all elements from list. |
||||
/// </summary> |
||||
void Clear(); |
||||
|
||||
/// <summary> |
||||
/// Occurs before any list items are drawn. |
||||
/// </summary> |
||||
/// <remarks> |
||||
/// <para>This method is only used to handle GUI repaint events.</para> |
||||
/// </remarks> |
||||
/// <see cref="EndGUI()"/> |
||||
void BeginGUI(); |
||||
/// <summary> |
||||
/// Occurs after all list items have been drawn. |
||||
/// </summary> |
||||
/// <remarks> |
||||
/// <para>This method is only used to handle GUI repaint events.</para> |
||||
/// </remarks> |
||||
/// <see cref="BeginGUI()"/> |
||||
void EndGUI(); |
||||
|
||||
/// <summary> |
||||
/// Draws background of a list item. |
||||
/// </summary> |
||||
/// <remarks> |
||||
/// <para>This method is only used to handle GUI repaint events.</para> |
||||
/// <para>Background of list item spans a slightly larger area than the main |
||||
/// interface that is drawn by <see cref="DrawItem(Rect, int)"/> since it is |
||||
/// drawn behind the grab handle.</para> |
||||
/// </remarks> |
||||
/// <param name="position">Total position of list element in GUI.</param> |
||||
/// <param name="index">Zero-based index of array element.</param> |
||||
void DrawItemBackground(Rect position, int index); |
||||
/// <summary> |
||||
/// Draws main interface for a list item. |
||||
/// </summary> |
||||
/// <remarks> |
||||
/// <para>This method is used to handle all GUI events.</para> |
||||
/// </remarks> |
||||
/// <param name="position">Position in GUI.</param> |
||||
/// <param name="index">Zero-based index of array element.</param> |
||||
void DrawItem(Rect position, int index); |
||||
/// <summary> |
||||
/// Gets height of list item in pixels. |
||||
/// </summary> |
||||
/// <param name="index">Zero-based index of array element.</param> |
||||
/// <returns> |
||||
/// Measurement in pixels. |
||||
/// </returns> |
||||
float GetItemHeight(int index); |
||||
|
||||
} |
||||
|
||||
} |
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 27a7bce836d771f4a84b172af5132fe7 |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,49 @@
|
||||
// Copyright (c) Rotorz Limited. All rights reserved. |
||||
// Licensed under the MIT license. See LICENSE file in the project root. |
||||
|
||||
namespace Rotorz.ReorderableList { |
||||
|
||||
/// <summary> |
||||
/// Can be implemented along with <see cref="IReorderableListAdaptor"/> when drop |
||||
/// insertion or ordering is desired. |
||||
/// </summary> |
||||
/// <remarks> |
||||
/// <para>This type of "drop" functionality can occur when the "drag" phase of the |
||||
/// drag and drop operation was initiated elsewhere. For example, a custom |
||||
/// <see cref="IReorderableListAdaptor"/> could insert entirely new items by |
||||
/// dragging and dropping from the Unity "Project" window.</para> |
||||
/// </remarks> |
||||
/// <see cref="IReorderableListAdaptor"/> |
||||
public interface IReorderableListDropTarget { |
||||
|
||||
/// <summary> |
||||
/// Determines whether an item is being dragged and that it can be inserted |
||||
/// or moved by dropping somewhere into the reorderable list control. |
||||
/// </summary> |
||||
/// <remarks> |
||||
/// <para>This method is always called whilst drawing an editor GUI.</para> |
||||
/// </remarks> |
||||
/// <param name="insertionIndex">Zero-based index of insertion.</param> |
||||
/// <returns> |
||||
/// A value of <c>true</c> if item can be dropped; otherwise <c>false</c>. |
||||
/// </returns> |
||||
/// <see cref="UnityEditor.DragAndDrop"/> |
||||
bool CanDropInsert(int insertionIndex); |
||||
|
||||
/// <summary> |
||||
/// Processes the current drop insertion operation when <see cref="CanDropInsert(int)"/> |
||||
/// returns a value of <c>true</c> to process, accept or cancel. |
||||
/// </summary> |
||||
/// <remarks> |
||||
/// <para>This method is always called whilst drawing an editor GUI.</para> |
||||
/// <para>This method is only called when <see cref="CanDropInsert(int)"/> |
||||
/// returns a value of <c>true</c>.</para> |
||||
/// </remarks> |
||||
/// <param name="insertionIndex">Zero-based index of insertion.</param> |
||||
/// <see cref="ReorderableListGUI.CurrentListControlID"/> |
||||
/// <see cref="UnityEditor.DragAndDrop"/> |
||||
void ProcessDropInsertion(int insertionIndex); |
||||
|
||||
} |
||||
|
||||
} |
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2 |
||||
guid: d1806c8b705782141acdbee308edf82c |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 1080d4950a85a2b4da9d5653fff71a13 |
||||
folderAsset: yes |
||||
DefaultImporter: |
||||
externalObjects: {} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,140 @@
|
||||
// Copyright (c) Rotorz Limited. All rights reserved. |
||||
// Licensed under the MIT license. See LICENSE file in the project root. |
||||
|
||||
using System; |
||||
using System.Reflection; |
||||
using UnityEditor; |
||||
using UnityEngine; |
||||
|
||||
namespace Rotorz.ReorderableList.Internal { |
||||
|
||||
/// <summary> |
||||
/// Utility functions to assist with GUIs. |
||||
/// </summary> |
||||
/// <exclude/> |
||||
public static class GUIHelper { |
||||
|
||||
static GUIHelper() { |
||||
var tyGUIClip = Type.GetType("UnityEngine.GUIClip,UnityEngine"); |
||||
if (tyGUIClip != null) { |
||||
var piVisibleRect = tyGUIClip.GetProperty("visibleRect", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); |
||||
if (piVisibleRect != null) { |
||||
var getMethod = piVisibleRect.GetGetMethod(true) ?? piVisibleRect.GetGetMethod(false); |
||||
VisibleRect = (Func<Rect>)Delegate.CreateDelegate(typeof(Func<Rect>), getMethod); |
||||
} |
||||
} |
||||
|
||||
var miFocusTextInControl = typeof(EditorGUI).GetMethod("FocusTextInControl", BindingFlags.Static | BindingFlags.Public); |
||||
if (miFocusTextInControl == null) |
||||
miFocusTextInControl = typeof(GUI).GetMethod("FocusControl", BindingFlags.Static | BindingFlags.Public); |
||||
|
||||
FocusTextInControl = (Action<string>)Delegate.CreateDelegate(typeof(Action<string>), miFocusTextInControl); |
||||
|
||||
s_SeparatorColor = EditorGUIUtility.isProSkin |
||||
? new Color(0.11f, 0.11f, 0.11f) |
||||
: new Color(0.5f, 0.5f, 0.5f); |
||||
|
||||
s_SeparatorStyle = new GUIStyle(); |
||||
s_SeparatorStyle.normal.background = EditorGUIUtility.whiteTexture; |
||||
s_SeparatorStyle.stretchWidth = true; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Gets visible rectangle within GUI. |
||||
/// </summary> |
||||
/// <remarks> |
||||
/// <para>VisibleRect = TopmostRect + scrollViewOffsets</para> |
||||
/// </remarks> |
||||
public static Func<Rect> VisibleRect; |
||||
|
||||
/// <summary> |
||||
/// Focus control and text editor where applicable. |
||||
/// </summary> |
||||
public static Action<string> FocusTextInControl; |
||||
|
||||
private static GUIStyle s_TempStyle = new GUIStyle(); |
||||
|
||||
/// <summary> |
||||
/// Draw texture using <see cref="GUIStyle"/> to workaround bug in Unity where |
||||
/// <see cref="GUI.DrawTexture"/> flickers when embedded inside a property drawer. |
||||
/// </summary> |
||||
/// <param name="position">Position of which to draw texture in space of GUI.</param> |
||||
/// <param name="texture">Texture.</param> |
||||
public static void DrawTexture(Rect position, Texture2D texture) { |
||||
if (Event.current.type != EventType.Repaint) |
||||
return; |
||||
|
||||
s_TempStyle.normal.background = texture; |
||||
|
||||
s_TempStyle.Draw(position, GUIContent.none, false, false, false, false); |
||||
} |
||||
|
||||
private static GUIContent s_TempIconContent = new GUIContent(); |
||||
private static readonly int s_IconButtonHint = "_ReorderableIconButton_".GetHashCode(); |
||||
|
||||
public static bool IconButton(Rect position, bool visible, Texture2D iconNormal, Texture2D iconActive, GUIStyle style) { |
||||
int controlID = GUIUtility.GetControlID(s_IconButtonHint, FocusType.Passive); |
||||
bool result = false; |
||||
|
||||
position.height += 1; |
||||
|
||||
switch (Event.current.GetTypeForControl(controlID)) { |
||||
case EventType.MouseDown: |
||||
// Do not allow button to be pressed using right mouse button since |
||||
// context menu should be shown instead! |
||||
if (GUI.enabled && Event.current.button != 1 && position.Contains(Event.current.mousePosition)) { |
||||
GUIUtility.hotControl = controlID; |
||||
GUIUtility.keyboardControl = 0; |
||||
Event.current.Use(); |
||||
} |
||||
break; |
||||
|
||||
case EventType.MouseDrag: |
||||
if (GUIUtility.hotControl == controlID) |
||||
Event.current.Use(); |
||||
break; |
||||
|
||||
case EventType.MouseUp: |
||||
if (GUIUtility.hotControl == controlID) { |
||||
GUIUtility.hotControl = 0; |
||||
result = position.Contains(Event.current.mousePosition); |
||||
Event.current.Use(); |
||||
} |
||||
break; |
||||
|
||||
case EventType.Repaint: |
||||
if (visible) { |
||||
bool isActive = GUIUtility.hotControl == controlID && position.Contains(Event.current.mousePosition); |
||||
s_TempIconContent.image = isActive ? iconActive : iconNormal; |
||||
position.height -= 1; |
||||
style.Draw(position, s_TempIconContent, isActive, isActive, false, false); |
||||
} |
||||
break; |
||||
} |
||||
|
||||
return result; |
||||
} |
||||
|
||||
public static bool IconButton(Rect position, Texture2D iconNormal, Texture2D iconActive, GUIStyle style) { |
||||
return IconButton(position, true, iconNormal, iconActive, style); |
||||
} |
||||
|
||||
private static readonly Color s_SeparatorColor; |
||||
private static readonly GUIStyle s_SeparatorStyle; |
||||
|
||||
public static void Separator(Rect position, Color color) { |
||||
if (Event.current.type == EventType.Repaint) { |
||||
Color restoreColor = GUI.color; |
||||
GUI.color = color; |
||||
s_SeparatorStyle.Draw(position, false, false, false, false); |
||||
GUI.color = restoreColor; |
||||
} |
||||
} |
||||
|
||||
public static void Separator(Rect position) { |
||||
Separator(position, s_SeparatorColor); |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 26c2c1b444cf6a446b03219116f2f827 |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,193 @@
|
||||
// Copyright (c) Rotorz Limited. All rights reserved. |
||||
// Licensed under the MIT license. See LICENSE file in the project root. |
||||
|
||||
using System; |
||||
using UnityEditor; |
||||
using UnityEngine; |
||||
|
||||
namespace Rotorz.ReorderableList.Internal { |
||||
|
||||
/// <exclude/> |
||||
public enum ReorderableListTexture { |
||||
Icon_Add_Normal = 0, |
||||
Icon_Add_Active, |
||||
Icon_AddMenu_Normal, |
||||
Icon_AddMenu_Active, |
||||
Icon_Menu_Normal, |
||||
Icon_Menu_Active, |
||||
Icon_Remove_Normal, |
||||
Icon_Remove_Active, |
||||
Button_Normal, |
||||
Button_Active, |
||||
Button2_Normal, |
||||
Button2_Active, |
||||
TitleBackground, |
||||
ContainerBackground, |
||||
Container2Background, |
||||
GrabHandle, |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Resources to assist with reorderable list control. |
||||
/// </summary> |
||||
/// <exclude/> |
||||
public static class ReorderableListResources { |
||||
|
||||
static ReorderableListResources() { |
||||
GenerateSpecialTextures(); |
||||
LoadResourceAssets(); |
||||
} |
||||
|
||||
#region Texture Resources |
||||
|
||||
/// <summary> |
||||
/// Resource assets for light skin. |
||||
/// </summary> |
||||
/// <remarks> |
||||
/// <para>Resource assets are PNG images which have been encoded using a base-64 |
||||
/// string so that actual asset files are not necessary.</para> |
||||
/// </remarks> |
||||
private static string[] s_LightSkin = { |
||||
"iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACxJREFUeNpi/P//PwMM6OvrgzkXL15khIkxMRAABBUw6unp/afMBNo7EiDAAEKeD5EsXZcTAAAAAElFTkSuQmCC", |
||||
"iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAC1JREFUeNpi/P//PwMM3L17F8xRVlZmhIkxMRAABBUw3rlz5z9lJtDekQABBgCvqxGbQWpEqwAAAABJRU5ErkJggg==", |
||||
"iVBORw0KGgoAAAANSUhEUgAAABYAAAAICAYAAAD9aA/QAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAERJREFUeNpi/P//PwMxQF9fH6zw4sWLjMSoZ2KgEaCZwYz4ggLmfVwAX7AMjIuJjTxsPqOKi9EtA/GpFhQww2E0QIABAPF5IGHNU7adAAAAAElFTkSuQmCC", |
||||
"iVBORw0KGgoAAAANSUhEUgAAABYAAAAICAYAAAD9aA/QAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAERJREFUeNpi/P//PwMx4O7du2CFysrKjMSoZ2KgEaCZwYz4ggLmfVwAX7AMjIuJjTxsPqOKi9EtA/GpFhQww2E0QIABACBuGkOOEiPJAAAAAElFTkSuQmCC", |
||||
"iVBORw0KGgoAAAANSUhEUgAAAAUAAAAICAYAAAAx8TU7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADBJREFUeNpi/P//PwM6YGLAAigUZNHX18ewienixYuMyAJgPshJIKynp/cfxgYIMACCMhb+oVNPwwAAAABJRU5ErkJggg==", |
||||
"iVBORw0KGgoAAAANSUhEUgAAAAUAAAAICAYAAAAx8TU7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADFJREFUeNpi/P//PwM6YGLAAigUZLl79y6GTUzKysqMyAJgPshJIHznzp3/MDZAgAEAkoIW/jHg7H4AAAAASUVORK5CYII=", |
||||
"iVBORw0KGgoAAAANSUhEUgAAAAgAAAACCAIAAADq9gq6AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAABVJREFUeNpiVFZWZsAGmBhwAIAAAwAURgBt4C03ZwAAAABJRU5ErkJggg==", |
||||
"iVBORw0KGgoAAAANSUhEUgAAAAgAAAACCAIAAADq9gq6AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAABVJREFUeNpivHPnDgM2wMSAAwAEGAB8VgKYlvqkBwAAAABJRU5ErkJggg==", |
||||
"iVBORw0KGgoAAAANSUhEUgAAAAcAAAAFCAYAAACJmvbYAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAEFJREFUeNpiKCoq+v/p06f/ly9fhmMQHyTOxIAH4JVkARHv379nkJeXhwuC+CDA+P//f4bi4uL/6Lp6e3sZAQIMACmoI7rWhl0KAAAAAElFTkSuQmCC", |
||||
"iVBORw0KGgoAAAANSUhEUgAAAAcAAAAFCAYAAACJmvbYAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAEFJREFUeNpiFBER+f/jxw8GNjY2Bhj49esXAwcHBwMTAx6AV5IFRPz58wdFEMZn/P//P4OoqOh/dF2vX79mBAgwADpeFCsbeaC+AAAAAElFTkSuQmCC", |
||||
"iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAYAAADEUlfTAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAFBJREFUeNpi/P//P0NxcfF/BjTQ29vLyFBUVPT/4cOH/z99+gTHID5InAWkSlBQkAEoANclLy8PppkY8AC8kmBj379/DzcKxgcBRnyuBQgwACVNLqBePwzmAAAAAElFTkSuQmCC", |
||||
"iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAYAAADEUlfTAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAElJREFUeNp8jjEKADEIBNdDrCz1/w+0tRQMOchxpHC6dVhW6m64e+MiIojMrDMTzPyJqoKq4r1sISJ3GQ8GRsln48/JNH27BBgAUhQbSyMxqzEAAAAASUVORK5CYII=", |
||||
"iVBORw0KGgoAAAANSUhEUgAAAAUAAAAECAYAAABGM/VAAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAEFJREFUeNpi/P//P0NxcfF/BgRgZP78+fN/VVVVhpCQEAZjY2OGs2fPNrCApBwdHRkePHgAVwoWnDVrFgMyAAgwAAt4E1dCq1obAAAAAElFTkSuQmCC", |
||||
"iVBORw0KGgoAAAANSUhEUgAAAAUAAAAECAYAAABGM/VAAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADtJREFUeNpi/P//P0NxcfF/Bijo7e1lZCgqKvr/6dOn/5cvXwbTID4TSPb9+/cM8vLyYBoEGLFpBwgwAHGiI8KoD3BZAAAAAElFTkSuQmCC", |
||||
"iVBORw0KGgoAAAANSUhEUgAAAAUAAAAECAIAAADJUWIXAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACJJREFUeNpiDA0NZUACLEDc2dkJ4ZSXlzMxoAJGNPUAAQYAwbcFBwYygqkAAAAASUVORK5CYII=", |
||||
"iVBORw0KGgoAAAANSUhEUgAAAAkAAAAFCAYAAACXU8ZrAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACdJREFUeNpi/PTp038GAoClvr6ekBoGxv//CRrEwPL582fqWAcQYAAnaA2zsd+RkQAAAABJRU5ErkJggg==", |
||||
}; |
||||
/// <summary> |
||||
/// Resource assets for dark skin. |
||||
/// </summary> |
||||
/// <remarks> |
||||
/// <para>Resource assets are PNG images which have been encoded using a base-64 |
||||
/// string so that actual asset files are not necessary.</para> |
||||
/// </remarks> |
||||
private static string[] s_DarkSkin = { |
||||
"iVBORw0KGgoAAAANSUhEUgAAAAgAAAAKCAYAAACJxx+AAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAE9JREFUeNpi/P//PwM+wITMOXr06H8QxqmAoAnYAOORI0f+U2aCsrIy3ISFCxeC6fj4eIQCZG/CfGBtbc1IvBXIJqioqIA5d+7cgZsAEGAAsHYfVsuw0XYAAAAASUVORK5CYII=", |
||||
"iVBORw0KGgoAAAANSUhEUgAAAAgAAAAKCAYAAACJxx+AAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAEZJREFUeNpi/P//PwM+wITM+Q8FOBUQNAEbYPmPxRHIYoRN4OLignO+ffsGppHFGJFtgBnNCATEW4HMgRn9/ft3uBhAgAEAbZ0gJEmOtOAAAAAASUVORK5CYII=", |
||||
"iVBORw0KGgoAAAANSUhEUgAAABYAAAAKCAYAAACwoK7bAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAG1JREFUeNpi/P//PwMtABOxCo8ePfofhKluMM1cTCpgxBfGhLxubW3NOLhcrKKiApdcuHAhmI6Pj4fL37lzhxGXzxiJTW4wzdi8D3IAzGKY5VQJCpDLYT4B0WCfgFxMDFZWVv4PwoTUwNgAAQYA7Mltu4fEN4wAAAAASUVORK5CYII=", |
||||
"iVBORw0KGgoAAAANSUhEUgAAABYAAAAKCAYAAACwoK7bAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAGVJREFUeNpi/P//PwMtABOxCv9DAdUNppmLSQWM+HxHyOuMQEB3F7Pgk+Ti4oKzv337hiH2/ft3nD5jJDaiYZqxeZ+Tk/M/zGKY5VQJCqDLGWE+AdEgPtEuBrkKZgg+NTB5gAADAJGHOCAbby7zAAAAAElFTkSuQmCC", |
||||
"iVBORw0KGgoAAAANSUhEUgAAAAUAAAAKCAYAAAB8OZQwAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADpJREFUeNpi/P//PwM6YGLAAmghyHL06FEM65ni4+NRBMB8kDuVlZX/Hzly5D+IBrsbRMAkYGyAAAMAB7YiCOfAQ0cAAAAASUVORK5CYII=", |
||||
"iVBORw0KGgoAAAANSUhEUgAAAAUAAAAKCAYAAAB8OZQwAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADdJREFUeNpi/P//PwM6YGLAAmghyPIfi/VMXFxcKAJgPkghBwfH/3///v0H0WCNIAImAWMDBBgA09Igc2M/ueMAAAAASUVORK5CYII=", |
||||
"iVBORw0KGgoAAAANSUhEUgAAAAgAAAAECAYAAACzzX7wAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACJJREFUeNpi/P//PwM+wHL06FG8KpgYCABGZWVlvCYABBgA7/sHvGw+cz8AAAAASUVORK5CYII=", |
||||
"iVBORw0KGgoAAAANSUhEUgAAAAgAAAAECAYAAACzzX7wAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACBJREFUeNpi/P//PwM+wPKfgAomBgKAhYuLC68CgAADAAxjByOjCHIRAAAAAElFTkSuQmCC", |
||||
"iVBORw0KGgoAAAANSUhEUgAAAAcAAAAFCAYAAACJmvbYAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAERJREFUeNpiVFZW/u/i4sLw4sULBhiQkJBg2LNnDwMTAx6AV5IFRLx9+xZsFAyA+CDA+P//fwYVFZX/6Lru3LnDCBBgAEqlFEYRrf2nAAAAAElFTkSuQmCC", |
||||
"iVBORw0KGgoAAAANSUhEUgAAAAcAAAAFCAYAAACJmvbYAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAEFJREFUeNpiFBER+f/jxw8GNjY2Bhj49esXAwcHBwMTAx6AV5IFRPz58wdFEMZn/P//P4OoqOh/dF2vX79mBAgwADpeFCsbeaC+AAAAAElFTkSuQmCC", |
||||
"iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAYAAADEUlfTAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAExJREFUeNpi/P//P4OKisp/BjRw584dRhaQhKGhIYOwsDBc4u3bt2ANLCAOSOLFixdwSQkJCTDNxIAH4JVkgdkBMwrGBwFGfK4FCDAAV1AdhemEguIAAAAASUVORK5CYII=", |
||||
"iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAYAAADEUlfTAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAElJREFUeNp8jjEKADEIBNdDrCz1/w+0tRQMOchxpHC6dVhW6m64e+MiIojMrDMTzPyJqoKq4r1sISJ3GQ8GRsln48/JNH27BBgAUhQbSyMxqzEAAAAASUVORK5CYII=", |
||||
"iVBORw0KGgoAAAANSUhEUgAAAAUAAAAECAYAAABGM/VAAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADtJREFUeNpi/P//P4OKisp/Bii4c+cOIwtIQE9Pj+HLly9gQRCfBcQACbx69QqmmAEseO/ePQZkABBgAD04FXsmmijSAAAAAElFTkSuQmCC", |
||||
"iVBORw0KGgoAAAANSUhEUgAAAAUAAAAECAYAAABGM/VAAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAD1JREFUeNpi/P//P4OKisp/Bii4c+cOIwtIwMXFheHFixcMEhISYAVMINm3b9+CBUA0CDCiazc0NGQECDAAdH0YelA27kgAAAAASUVORK5CYII=", |
||||
"iVBORw0KGgoAAAANSUhEUgAAAAUAAAAECAYAAABGM/VAAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACZJREFUeNpi/P//vxQDGmABEffv3/8ME1BUVORlYsACGLFpBwgwABaWCjfQEetnAAAAAElFTkSuQmCC", |
||||
"iVBORw0KGgoAAAANSUhEUgAAAAkAAAAFCAYAAACXU8ZrAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACRJREFUeNpizM3N/c9AADAqKysTVMTi5eXFSFAREFPHOoAAAwBCfwcAO8g48QAAAABJRU5ErkJggg==", |
||||
}; |
||||
|
||||
/// <summary> |
||||
/// Gets light or dark version of the specified texture. |
||||
/// </summary> |
||||
/// <param name="name"></param> |
||||
/// <returns></returns> |
||||
public static Texture2D GetTexture(ReorderableListTexture name) { |
||||
return s_Cached[(int)name]; |
||||
} |
||||
|
||||
#endregion |
||||
|
||||
#region Generated Resources |
||||
|
||||
public static Texture2D texHighlightColor { get; private set; } |
||||
|
||||
/// <summary> |
||||
/// Generate special textures. |
||||
/// </summary> |
||||
private static void GenerateSpecialTextures() { |
||||
texHighlightColor = CreatePixelTexture("(Generated) Highlight Color", ReorderableListStyles.SelectionBackgroundColor); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Create 1x1 pixel texture of specified color. |
||||
/// </summary> |
||||
/// <param name="name">Name for texture object.</param> |
||||
/// <param name="color">Pixel color.</param> |
||||
/// <returns> |
||||
/// The new <c>Texture2D</c> instance. |
||||
/// </returns> |
||||
public static Texture2D CreatePixelTexture(string name, Color color) { |
||||
var tex = new Texture2D(1, 1, TextureFormat.ARGB32, false, true); |
||||
tex.name = name; |
||||
tex.hideFlags = HideFlags.HideAndDontSave; |
||||
tex.filterMode = FilterMode.Point; |
||||
tex.SetPixel(0, 0, color); |
||||
tex.Apply(); |
||||
return tex; |
||||
} |
||||
|
||||
#endregion |
||||
|
||||
#region Load PNG from Base-64 Encoded String |
||||
|
||||
private static Texture2D[] s_Cached; |
||||
|
||||
/// <summary> |
||||
/// Read textures from base-64 encoded strings. Automatically selects assets based |
||||
/// upon whether the light or dark (pro) skin is active. |
||||
/// </summary> |
||||
private static void LoadResourceAssets() { |
||||
var skin = EditorGUIUtility.isProSkin ? s_DarkSkin : s_LightSkin; |
||||
s_Cached = new Texture2D[skin.Length]; |
||||
|
||||
for (int i = 0; i < s_Cached.Length; ++i) { |
||||
// Get image data (PNG) from base64 encoded strings. |
||||
byte[] imageData = Convert.FromBase64String(skin[i]); |
||||
|
||||
// Gather image size from image data. |
||||
int texWidth, texHeight; |
||||
GetImageSize(imageData, out texWidth, out texHeight); |
||||
|
||||
// Generate texture asset. |
||||
var tex = new Texture2D(texWidth, texHeight, TextureFormat.ARGB32, false, true); |
||||
tex.hideFlags = HideFlags.HideAndDontSave; |
||||
tex.name = "(Generated) ReorderableList:" + i; |
||||
tex.filterMode = FilterMode.Point; |
||||
#if UNITY_2017_1_OR_NEWER |
||||
ImageConversion.LoadImage(tex, imageData, markNonReadable: true); |
||||
#else |
||||
tex.LoadImage(imageData); |
||||
#endif |
||||
|
||||
s_Cached[i] = tex; |
||||
} |
||||
|
||||
s_LightSkin = null; |
||||
s_DarkSkin = null; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Read width and height if PNG file in pixels. |
||||
/// </summary> |
||||
/// <param name="imageData">PNG image data.</param> |
||||
/// <param name="width">Width of image in pixels.</param> |
||||
/// <param name="height">Height of image in pixels.</param> |
||||
private static void GetImageSize(byte[] imageData, out int width, out int height) { |
||||
width = ReadInt(imageData, 3 + 15); |
||||
height = ReadInt(imageData, 3 + 15 + 2 + 2); |
||||
} |
||||
|
||||
private static int ReadInt(byte[] imageData, int offset) { |
||||
return (imageData[offset] << 8) | imageData[offset + 1]; |
||||
} |
||||
|
||||
#endregion |
||||
|
||||
} |
||||
|
||||
} |
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 1d9acb5346b0f3c478d5678c6a0e4f42 |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,179 @@
|
||||
// Copyright (c) Rotorz Limited. All rights reserved. |
||||
// Licensed under the MIT license. See LICENSE file in the project root. |
||||
|
||||
using System; |
||||
using UnityEditor; |
||||
using UnityEngine; |
||||
|
||||
namespace Rotorz.ReorderableList.Internal { |
||||
|
||||
/// <summary> |
||||
/// Utility functionality for <see cref="SerializedPropertyAdaptor"/> implementations. |
||||
/// </summary> |
||||
public static class SerializedPropertyUtility { |
||||
|
||||
/// <summary> |
||||
/// Reset the value of a property. |
||||
/// </summary> |
||||
/// <param name="property">Serialized property for a serialized property.</param> |
||||
public static void ResetValue(SerializedProperty property) { |
||||
if (property == null) |
||||
throw new ArgumentNullException("property"); |
||||
|
||||
switch (property.propertyType) { |
||||
case SerializedPropertyType.Integer: |
||||
property.intValue = 0; |
||||
break; |
||||
case SerializedPropertyType.Boolean: |
||||
property.boolValue = false; |
||||
break; |
||||
case SerializedPropertyType.Float: |
||||
property.floatValue = 0f; |
||||
break; |
||||
case SerializedPropertyType.String: |
||||
property.stringValue = ""; |
||||
break; |
||||
case SerializedPropertyType.Color: |
||||
property.colorValue = Color.black; |
||||
break; |
||||
case SerializedPropertyType.ObjectReference: |
||||
property.objectReferenceValue = null; |
||||
break; |
||||
case SerializedPropertyType.LayerMask: |
||||
property.intValue = 0; |
||||
break; |
||||
case SerializedPropertyType.Enum: |
||||
property.enumValueIndex = 0; |
||||
break; |
||||
case SerializedPropertyType.Vector2: |
||||
property.vector2Value = default(Vector2); |
||||
break; |
||||
case SerializedPropertyType.Vector3: |
||||
property.vector3Value = default(Vector3); |
||||
break; |
||||
case SerializedPropertyType.Vector4: |
||||
property.vector4Value = default(Vector4); |
||||
break; |
||||
case SerializedPropertyType.Rect: |
||||
property.rectValue = default(Rect); |
||||
break; |
||||
case SerializedPropertyType.ArraySize: |
||||
property.intValue = 0; |
||||
break; |
||||
case SerializedPropertyType.Character: |
||||
property.intValue = 0; |
||||
break; |
||||
case SerializedPropertyType.AnimationCurve: |
||||
property.animationCurveValue = AnimationCurve.Linear(0f, 0f, 1f, 1f); |
||||
break; |
||||
case SerializedPropertyType.Bounds: |
||||
property.boundsValue = default(Bounds); |
||||
break; |
||||
case SerializedPropertyType.Gradient: |
||||
//!TODO: Amend when Unity add a public API for setting the gradient. |
||||
break; |
||||
} |
||||
|
||||
if (property.isArray) { |
||||
property.arraySize = 0; |
||||
} |
||||
|
||||
ResetChildPropertyValues(property); |
||||
} |
||||
|
||||
private static void ResetChildPropertyValues(SerializedProperty element) { |
||||
if (!element.hasChildren) |
||||
return; |
||||
|
||||
var childProperty = element.Copy(); |
||||
int elementPropertyDepth = element.depth; |
||||
bool enterChildren = true; |
||||
|
||||
while (childProperty.Next(enterChildren) && childProperty.depth > elementPropertyDepth) { |
||||
enterChildren = false; |
||||
ResetValue(childProperty); |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Copies value of <paramref name="sourceProperty"/> into <pararef name="destProperty"/>. |
||||
/// </summary> |
||||
/// <param name="destProperty">Destination property.</param> |
||||
/// <param name="sourceProperty">Source property.</param> |
||||
public static void CopyPropertyValue(SerializedProperty destProperty, SerializedProperty sourceProperty) { |
||||
if (destProperty == null) |
||||
throw new ArgumentNullException("destProperty"); |
||||
if (sourceProperty == null) |
||||
throw new ArgumentNullException("sourceProperty"); |
||||
|
||||
sourceProperty = sourceProperty.Copy(); |
||||
destProperty = destProperty.Copy(); |
||||
|
||||
CopyPropertyValueSingular(destProperty, sourceProperty); |
||||
|
||||
if (sourceProperty.hasChildren) { |
||||
int elementPropertyDepth = sourceProperty.depth; |
||||
while (sourceProperty.Next(true) && destProperty.Next(true) && sourceProperty.depth > elementPropertyDepth) |
||||
CopyPropertyValueSingular(destProperty, sourceProperty); |
||||
} |
||||
} |
||||
|
||||
private static void CopyPropertyValueSingular(SerializedProperty destProperty, SerializedProperty sourceProperty) { |
||||
switch (destProperty.propertyType) { |
||||
case SerializedPropertyType.Integer: |
||||
destProperty.intValue = sourceProperty.intValue; |
||||
break; |
||||
case SerializedPropertyType.Boolean: |
||||
destProperty.boolValue = sourceProperty.boolValue; |
||||
break; |
||||
case SerializedPropertyType.Float: |
||||
destProperty.floatValue = sourceProperty.floatValue; |
||||
break; |
||||
case SerializedPropertyType.String: |
||||
destProperty.stringValue = sourceProperty.stringValue; |
||||
break; |
||||
case SerializedPropertyType.Color: |
||||
destProperty.colorValue = sourceProperty.colorValue; |
||||
break; |
||||
case SerializedPropertyType.ObjectReference: |
||||
destProperty.objectReferenceValue = sourceProperty.objectReferenceValue; |
||||
break; |
||||
case SerializedPropertyType.LayerMask: |
||||
destProperty.intValue = sourceProperty.intValue; |
||||
break; |
||||
case SerializedPropertyType.Enum: |
||||
destProperty.enumValueIndex = sourceProperty.enumValueIndex; |
||||
break; |
||||
case SerializedPropertyType.Vector2: |
||||
destProperty.vector2Value = sourceProperty.vector2Value; |
||||
break; |
||||
case SerializedPropertyType.Vector3: |
||||
destProperty.vector3Value = sourceProperty.vector3Value; |
||||
break; |
||||
case SerializedPropertyType.Vector4: |
||||
destProperty.vector4Value = sourceProperty.vector4Value; |
||||
break; |
||||
case SerializedPropertyType.Rect: |
||||
destProperty.rectValue = sourceProperty.rectValue; |
||||
break; |
||||
case SerializedPropertyType.ArraySize: |
||||
destProperty.intValue = sourceProperty.intValue; |
||||
break; |
||||
case SerializedPropertyType.Character: |
||||
destProperty.intValue = sourceProperty.intValue; |
||||
break; |
||||
case SerializedPropertyType.AnimationCurve: |
||||
destProperty.animationCurveValue = sourceProperty.animationCurveValue; |
||||
break; |
||||
case SerializedPropertyType.Bounds: |
||||
destProperty.boundsValue = sourceProperty.boundsValue; |
||||
break; |
||||
case SerializedPropertyType.Gradient: |
||||
//!TODO: Amend when Unity add a public API for setting the gradient. |
||||
break; |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2 |
||||
guid: e720cba766c708b40a725fddfbdb4436 |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 02045e26a7a39c440ba538e3c9ca2248 |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,216 @@
|
||||
// Copyright (c) Rotorz Limited. All rights reserved. |
||||
// Licensed under the MIT license. See LICENSE file in the project root. |
||||
|
||||
using System; |
||||
using System.ComponentModel; |
||||
using UnityEngine; |
||||
|
||||
namespace Rotorz.ReorderableList { |
||||
|
||||
/// <summary> |
||||
/// Arguments which are passed to <see cref="AddMenuClickedEventHandler"/>. |
||||
/// </summary> |
||||
public sealed class AddMenuClickedEventArgs : EventArgs { |
||||
|
||||
/// <summary> |
||||
/// Gets adaptor to reorderable list container. |
||||
/// </summary> |
||||
public IReorderableListAdaptor Adaptor { get; private set; } |
||||
/// <summary> |
||||
/// Gets position of the add menu button. |
||||
/// </summary> |
||||
public Rect ButtonPosition { get; internal set; } |
||||
|
||||
/// <summary> |
||||
/// Initializes a new instance of <see cref="ItemMovedEventArgs"/>. |
||||
/// </summary> |
||||
/// <param name="adaptor">Reorderable list adaptor.</param> |
||||
/// <param name="buttonPosition">Position of the add menu button.</param> |
||||
public AddMenuClickedEventArgs(IReorderableListAdaptor adaptor, Rect buttonPosition) { |
||||
this.Adaptor = adaptor; |
||||
this.ButtonPosition = buttonPosition; |
||||
} |
||||
|
||||
} |
||||
|
||||
/// <summary> |
||||
/// An event handler which is invoked when the "Add Menu" button is clicked. |
||||
/// </summary> |
||||
/// <param name="sender">Object which raised event.</param> |
||||
/// <param name="args">Event arguments.</param> |
||||
public delegate void AddMenuClickedEventHandler(object sender, AddMenuClickedEventArgs args); |
||||
|
||||
/// <summary> |
||||
/// Arguments which are passed to <see cref="ItemInsertedEventHandler"/>. |
||||
/// </summary> |
||||
public sealed class ItemInsertedEventArgs : EventArgs { |
||||
|
||||
/// <summary> |
||||
/// Gets adaptor to reorderable list container which contains element. |
||||
/// </summary> |
||||
public IReorderableListAdaptor Adaptor { get; private set; } |
||||
/// <summary> |
||||
/// Gets zero-based index of item which was inserted. |
||||
/// </summary> |
||||
public int ItemIndex { get; private set; } |
||||
|
||||
/// <summary> |
||||
/// Indicates if inserted item was duplicated from another item. |
||||
/// </summary> |
||||
public bool WasDuplicated { get; private set; } |
||||
|
||||
/// <summary> |
||||
/// Initializes a new instance of <see cref="ItemInsertedEventArgs"/>. |
||||
/// </summary> |
||||
/// <param name="adaptor">Reorderable list adaptor.</param> |
||||
/// <param name="itemIndex">Zero-based index of item.</param> |
||||
/// <param name="wasDuplicated">Indicates if inserted item was duplicated from another item.</param> |
||||
public ItemInsertedEventArgs(IReorderableListAdaptor adaptor, int itemIndex, bool wasDuplicated) { |
||||
this.Adaptor = adaptor; |
||||
this.ItemIndex = itemIndex; |
||||
this.WasDuplicated = wasDuplicated; |
||||
} |
||||
|
||||
} |
||||
|
||||
/// <summary> |
||||
/// An event handler which is invoked after new list item is inserted. |
||||
/// </summary> |
||||
/// <param name="sender">Object which raised event.</param> |
||||
/// <param name="args">Event arguments.</param> |
||||
public delegate void ItemInsertedEventHandler(object sender, ItemInsertedEventArgs args); |
||||
|
||||
/// <summary> |
||||
/// Arguments which are passed to <see cref="ItemRemovingEventHandler"/>. |
||||
/// </summary> |
||||
public sealed class ItemRemovingEventArgs : CancelEventArgs { |
||||
|
||||
/// <summary> |
||||
/// Gets adaptor to reorderable list container which contains element. |
||||
/// </summary> |
||||
public IReorderableListAdaptor Adaptor { get; private set; } |
||||
/// <summary> |
||||
/// Gets zero-based index of item which is being removed. |
||||
/// </summary> |
||||
public int ItemIndex { get; internal set; } |
||||
|
||||
/// <summary> |
||||
/// Initializes a new instance of <see cref="ItemRemovingEventArgs"/>. |
||||
/// </summary> |
||||
/// <param name="adaptor">Reorderable list adaptor.</param> |
||||
/// <param name="itemIndex">Zero-based index of item.</param> |
||||
public ItemRemovingEventArgs(IReorderableListAdaptor adaptor, int itemIndex) { |
||||
this.Adaptor = adaptor; |
||||
this.ItemIndex = itemIndex; |
||||
} |
||||
|
||||
} |
||||
|
||||
/// <summary> |
||||
/// An event handler which is invoked before a list item is removed. |
||||
/// </summary> |
||||
/// <remarks> |
||||
/// <para>Item removal can be cancelled by setting <see cref="CancelEventArgs.Cancel"/> |
||||
/// to <c>true</c>.</para> |
||||
/// </remarks> |
||||
/// <param name="sender">Object which raised event.</param> |
||||
/// <param name="args">Event arguments.</param> |
||||
public delegate void ItemRemovingEventHandler(object sender, ItemRemovingEventArgs args); |
||||
|
||||
/// <summary> |
||||
/// Arguments which are passed to <see cref="ItemMovingEventHandler"/>. |
||||
/// </summary> |
||||
public sealed class ItemMovingEventArgs : CancelEventArgs { |
||||
|
||||
/// <summary> |
||||
/// Gets adaptor to reorderable list container which contains element. |
||||
/// </summary> |
||||
public IReorderableListAdaptor Adaptor { get; private set; } |
||||
/// <summary> |
||||
/// Gets current zero-based index of item which is going to be moved. |
||||
/// </summary> |
||||
public int ItemIndex { get; internal set; } |
||||
/// <summary> |
||||
/// Gets the new candidate zero-based index for the item. |
||||
/// </summary> |
||||
/// <seealso cref="NewItemIndex"/> |
||||
public int DestinationItemIndex { get; internal set; } |
||||
|
||||
/// <summary> |
||||
/// Gets zero-based index of item <strong>after</strong> it has been moved. |
||||
/// </summary> |
||||
/// <seealso cref="DestinationItemIndex"/> |
||||
public int NewItemIndex { |
||||
get { |
||||
int result = DestinationItemIndex; |
||||
if (result > ItemIndex) |
||||
--result; |
||||
return result; |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Initializes a new instance of <see cref="ItemMovingEventArgs"/>. |
||||
/// </summary> |
||||
/// <param name="adaptor">Reorderable list adaptor.</param> |
||||
/// <param name="itemIndex">Zero-based index of item.</param> |
||||
/// <param name="destinationItemIndex">Xero-based index of item destination.</param> |
||||
public ItemMovingEventArgs(IReorderableListAdaptor adaptor, int itemIndex, int destinationItemIndex) { |
||||
this.Adaptor = adaptor; |
||||
this.ItemIndex = itemIndex; |
||||
this.DestinationItemIndex = destinationItemIndex; |
||||
} |
||||
|
||||
} |
||||
|
||||
/// <summary> |
||||
/// An event handler which is invoked before a list item is moved. |
||||
/// </summary> |
||||
/// <remarks> |
||||
/// <para>Moving of item can be cancelled by setting <see cref="CancelEventArgs.Cancel"/> |
||||
/// to <c>true</c>.</para> |
||||
/// </remarks> |
||||
/// <param name="sender">Object which raised event.</param> |
||||
/// <param name="args">Event arguments.</param> |
||||
public delegate void ItemMovingEventHandler(object sender, ItemMovingEventArgs args); |
||||
|
||||
/// <summary> |
||||
/// Arguments which are passed to <see cref="ItemMovedEventHandler"/>. |
||||
/// </summary> |
||||
public sealed class ItemMovedEventArgs : EventArgs { |
||||
|
||||
/// <summary> |
||||
/// Gets adaptor to reorderable list container which contains element. |
||||
/// </summary> |
||||
public IReorderableListAdaptor Adaptor { get; private set; } |
||||
/// <summary> |
||||
/// Gets old zero-based index of the item which was moved. |
||||
/// </summary> |
||||
public int OldItemIndex { get; internal set; } |
||||
/// <summary> |
||||
/// Gets new zero-based index of the item which was moved. |
||||
/// </summary> |
||||
public int NewItemIndex { get; internal set; } |
||||
|
||||
/// <summary> |
||||
/// Initializes a new instance of <see cref="ItemMovedEventArgs"/>. |
||||
/// </summary> |
||||
/// <param name="adaptor">Reorderable list adaptor.</param> |
||||
/// <param name="oldItemIndex">Old zero-based index of item.</param> |
||||
/// <param name="newItemIndex">New zero-based index of item.</param> |
||||
public ItemMovedEventArgs(IReorderableListAdaptor adaptor, int oldItemIndex, int newItemIndex) { |
||||
this.Adaptor = adaptor; |
||||
this.OldItemIndex = oldItemIndex; |
||||
this.NewItemIndex = newItemIndex; |
||||
} |
||||
|
||||
} |
||||
|
||||
/// <summary> |
||||
/// An event handler which is invoked after a list item is moved. |
||||
/// </summary> |
||||
/// <param name="sender">Object which raised event.</param> |
||||
/// <param name="args">Event arguments.</param> |
||||
public delegate void ItemMovedEventHandler(object sender, ItemMovedEventArgs args); |
||||
|
||||
} |
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 1d75c9b7fc704a6488376beccd1a93a4 |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,62 @@
|
||||
// Copyright (c) Rotorz Limited. All rights reserved. |
||||
// Licensed under the MIT license. See LICENSE file in the project root. |
||||
|
||||
using System; |
||||
|
||||
namespace Rotorz.ReorderableList { |
||||
|
||||
/// <summary> |
||||
/// Additional flags which can be passed into reorderable list field. |
||||
/// </summary> |
||||
/// <example> |
||||
/// <para>Multiple flags can be specified if desired:</para> |
||||
/// <code language="csharp"><![CDATA[ |
||||
/// var flags = ReorderableListFlags.HideAddButton | ReorderableListFlags.HideRemoveButtons; |
||||
/// ReorderableListGUI.ListField(list, flags); |
||||
/// ]]></code> |
||||
/// </example> |
||||
[Flags] |
||||
public enum ReorderableListFlags { |
||||
/// <summary> |
||||
/// Hide grab handles and disable reordering of list items. |
||||
/// </summary> |
||||
DisableReordering = 0x0001, |
||||
/// <summary> |
||||
/// Hide add button at base of control. |
||||
/// </summary> |
||||
HideAddButton = 0x0002, |
||||
/// <summary> |
||||
/// Hide remove buttons from list items. |
||||
/// </summary> |
||||
HideRemoveButtons = 0x0004, |
||||
/// <summary> |
||||
/// Do not display context menu upon right-clicking grab handle. |
||||
/// </summary> |
||||
DisableContextMenu = 0x0008, |
||||
/// <summary> |
||||
/// Hide "Duplicate" option from context menu. |
||||
/// </summary> |
||||
DisableDuplicateCommand = 0x0010, |
||||
/// <summary> |
||||
/// Do not automatically focus first control of newly added items. |
||||
/// </summary> |
||||
DisableAutoFocus = 0x0020, |
||||
/// <summary> |
||||
/// Show zero-based index of array elements. |
||||
/// </summary> |
||||
ShowIndices = 0x0040, |
||||
/// <exclude/> |
||||
[Obsolete("This flag is redundant because the clipping optimization was removed.")] |
||||
DisableClipping = 0x0080, |
||||
/// <summary> |
||||
/// Do not attempt to automatically scroll when list is inside a scroll view and |
||||
/// the mouse pointer is dragged outside of the visible portion of the list. |
||||
/// </summary> |
||||
DisableAutoScroll = 0x0100, |
||||
/// <summary> |
||||
/// Show "Size" field at base of list control. |
||||
/// </summary> |
||||
ShowSizeField = 0x0200, |
||||
} |
||||
|
||||
} |
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 8413004edec065f4c881fdb12b5d48b4 |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,576 @@
|
||||
// Copyright (c) Rotorz Limited. All rights reserved. |
||||
// Licensed under the MIT license. See LICENSE file in the project root. |
||||
|
||||
using System.Collections.Generic; |
||||
using UnityEditor; |
||||
using UnityEngine; |
||||
|
||||
namespace Rotorz.ReorderableList { |
||||
|
||||
/// <summary> |
||||
/// Utility class for drawing reorderable lists. |
||||
/// </summary> |
||||
public static class ReorderableListGUI { |
||||
|
||||
/// <summary> |
||||
/// Default list item height is 18 pixels. |
||||
/// </summary> |
||||
public const float DefaultItemHeight = 18; |
||||
|
||||
/// <summary> |
||||
/// Gets or sets the zero-based index of the last item that was changed. A value of -1 |
||||
/// indicates that no item was changed by list. |
||||
/// </summary> |
||||
/// <remarks> |
||||
/// <para>This property should not be set when items are added or removed.</para> |
||||
/// </remarks> |
||||
public static int IndexOfChangedItem { get; internal set; } |
||||
|
||||
/// <summary> |
||||
/// Gets the control ID of the list that is currently being drawn. |
||||
/// </summary> |
||||
public static int CurrentListControlID { |
||||
get { return ReorderableListControl.CurrentListControlID; } |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Gets the position of the list control that is currently being drawn. |
||||
/// </summary> |
||||
/// <remarks> |
||||
/// <para>The value of this property should be ignored for <see cref="EventType.Layout"/> |
||||
/// type events when using reorderable list controls with automatic layout.</para> |
||||
/// </remarks> |
||||
/// <see cref="CurrentItemTotalPosition"/> |
||||
public static Rect CurrentListPosition { |
||||
get { return ReorderableListControl.CurrentListPosition; } |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Gets the zero-based index of the list item that is currently being drawn; |
||||
/// or a value of -1 if no item is currently being drawn. |
||||
/// </summary> |
||||
public static int CurrentItemIndex { |
||||
get { return ReorderableListControl.CurrentItemIndex; } |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Gets the total position of the list item that is currently being drawn. |
||||
/// </summary> |
||||
/// <remarks> |
||||
/// <para>The value of this property should be ignored for <see cref="EventType.Layout"/> |
||||
/// type events when using reorderable list controls with automatic layout.</para> |
||||
/// </remarks> |
||||
/// <see cref="CurrentItemIndex"/> |
||||
/// <see cref="CurrentListPosition"/> |
||||
public static Rect CurrentItemTotalPosition { |
||||
get { return ReorderableListControl.CurrentItemTotalPosition; } |
||||
} |
||||
|
||||
#region Basic Item Drawers |
||||
|
||||
/// <summary> |
||||
/// Default list item drawer implementation. |
||||
/// </summary> |
||||
/// <remarks> |
||||
/// <para>Always presents the label "Item drawer not implemented.".</para> |
||||
/// </remarks> |
||||
/// <param name="position">Position to draw list item control(s).</param> |
||||
/// <param name="item">Value of list item.</param> |
||||
/// <returns> |
||||
/// Unmodified value of list item. |
||||
/// </returns> |
||||
/// <typeparam name="T">Type of list item.</typeparam> |
||||
public static T DefaultItemDrawer<T>(Rect position, T item) { |
||||
GUI.Label(position, "Item drawer not implemented."); |
||||
return item; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Draws text field allowing list items to be edited. |
||||
/// </summary> |
||||
/// <remarks> |
||||
/// <para>Null values are automatically changed to empty strings since null |
||||
/// values cannot be edited using a text field.</para> |
||||
/// <para>Value of <c>GUI.changed</c> is set to <c>true</c> if value of item |
||||
/// is modified.</para> |
||||
/// </remarks> |
||||
/// <param name="position">Position to draw list item control(s).</param> |
||||
/// <param name="item">Value of list item.</param> |
||||
/// <returns> |
||||
/// Modified value of list item. |
||||
/// </returns> |
||||
public static string TextFieldItemDrawer(Rect position, string item) { |
||||
if (item == null) { |
||||
item = ""; |
||||
GUI.changed = true; |
||||
} |
||||
return EditorGUI.TextField(position, item); |
||||
} |
||||
|
||||
#endregion |
||||
|
||||
/// <summary> |
||||
/// Gets the default list control implementation. |
||||
/// </summary> |
||||
private static ReorderableListControl DefaultListControl { get; set; } |
||||
|
||||
static ReorderableListGUI() { |
||||
DefaultListControl = new ReorderableListControl(); |
||||
|
||||
// Duplicate default styles to prevent user scripts from interferring with |
||||
// the default list control instance. |
||||
DefaultListControl.ContainerStyle = new GUIStyle(ReorderableListStyles.Container); |
||||
DefaultListControl.FooterButtonStyle = new GUIStyle(ReorderableListStyles.FooterButton); |
||||
DefaultListControl.ItemButtonStyle = new GUIStyle(ReorderableListStyles.ItemButton); |
||||
|
||||
IndexOfChangedItem = -1; |
||||
} |
||||
|
||||
private static GUIContent s_Temp = new GUIContent(); |
||||
|
||||
#region Title Control |
||||
|
||||
/// <summary> |
||||
/// Draw title control for list field. |
||||
/// </summary> |
||||
/// <remarks> |
||||
/// <para>When needed, should be shown immediately before list field.</para> |
||||
/// </remarks> |
||||
/// <example> |
||||
/// <code language="csharp"><![CDATA[ |
||||
/// ReorderableListGUI.Title(titleContent); |
||||
/// ReorderableListGUI.ListField(list, DynamicListGU.TextFieldItemDrawer); |
||||
/// ]]></code> |
||||
/// <code language="unityscript"><![CDATA[ |
||||
/// ReorderableListGUI.Title(titleContent); |
||||
/// ReorderableListGUI.ListField(list, DynamicListGU.TextFieldItemDrawer); |
||||
/// ]]></code> |
||||
/// </example> |
||||
/// <param name="title">Content for title control.</param> |
||||
public static void Title(GUIContent title) { |
||||
Rect position = GUILayoutUtility.GetRect(title, ReorderableListStyles.Title); |
||||
Title(position, title); |
||||
GUILayout.Space(-1); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Draw title control for list field. |
||||
/// </summary> |
||||
/// <remarks> |
||||
/// <para>When needed, should be shown immediately before list field.</para> |
||||
/// </remarks> |
||||
/// <example> |
||||
/// <code language="csharp"><![CDATA[ |
||||
/// ReorderableListGUI.Title("Your Title"); |
||||
/// ReorderableListGUI.ListField(list, DynamicListGU.TextFieldItemDrawer); |
||||
/// ]]></code> |
||||
/// <code language="unityscript"><![CDATA[ |
||||
/// ReorderableListGUI.Title('Your Title'); |
||||
/// ReorderableListGUI.ListField(list, DynamicListGU.TextFieldItemDrawer); |
||||
/// ]]></code> |
||||
/// </example> |
||||
/// <param name="title">Text for title control.</param> |
||||
public static void Title(string title) { |
||||
s_Temp.text = title; |
||||
Title(s_Temp); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Draw title control for list field with absolute positioning. |
||||
/// </summary> |
||||
/// <param name="position">Position of control.</param> |
||||
/// <param name="title">Content for title control.</param> |
||||
public static void Title(Rect position, GUIContent title) { |
||||
if (Event.current.type == EventType.Repaint) |
||||
ReorderableListStyles.Title.Draw(position, title, false, false, false, false); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Draw title control for list field with absolute positioning. |
||||
/// </summary> |
||||
/// <param name="position">Position of control.</param> |
||||
/// <param name="text">Text for title control.</param> |
||||
public static void Title(Rect position, string text) { |
||||
s_Temp.text = text; |
||||
Title(position, s_Temp); |
||||
} |
||||
|
||||
#endregion |
||||
|
||||
#region List<T> Control |
||||
|
||||
/// <summary> |
||||
/// Draw list field control. |
||||
/// </summary> |
||||
/// <param name="list">The list which can be reordered.</param> |
||||
/// <param name="drawItem">Callback to draw list item.</param> |
||||
/// <param name="drawEmpty">Callback to draw custom content for empty list (optional).</param> |
||||
/// <param name="itemHeight">Height of a single list item.</param> |
||||
/// <param name="flags">Optional flags to pass into list field.</param> |
||||
/// <typeparam name="T">Type of list item.</typeparam> |
||||
private static void DoListField<T>(IList<T> list, ReorderableListControl.ItemDrawer<T> drawItem, ReorderableListControl.DrawEmpty drawEmpty, float itemHeight, ReorderableListFlags flags) { |
||||
var adaptor = new GenericListAdaptor<T>(list, drawItem, itemHeight); |
||||
ReorderableListControl.DrawControlFromState(adaptor, drawEmpty, flags); |
||||
} |
||||
/// <summary> |
||||
/// Draw list field control with absolute positioning. |
||||
/// </summary> |
||||
/// <param name="position">Position of control.</param> |
||||
/// <param name="list">The list which can be reordered.</param> |
||||
/// <param name="drawItem">Callback to draw list item.</param> |
||||
/// <param name="drawEmpty">Callback to draw custom content for empty list (optional).</param> |
||||
/// <param name="itemHeight">Height of a single list item.</param> |
||||
/// <param name="flags">Optional flags to pass into list field.</param> |
||||
/// <typeparam name="T">Type of list item.</typeparam> |
||||
private static void DoListFieldAbsolute<T>(Rect position, IList<T> list, ReorderableListControl.ItemDrawer<T> drawItem, ReorderableListControl.DrawEmptyAbsolute drawEmpty, float itemHeight, ReorderableListFlags flags) { |
||||
var adaptor = new GenericListAdaptor<T>(list, drawItem, itemHeight); |
||||
ReorderableListControl.DrawControlFromState(position, adaptor, drawEmpty, flags); |
||||
} |
||||
|
||||
|
||||
/// <inheritdoc cref="DoListField{T}(IList{T}, ReorderableListControl.ItemDrawer{T}, ReorderableListControl.DrawEmpty, float, ReorderableListFlags)"/> |
||||
public static void ListField<T>(IList<T> list, ReorderableListControl.ItemDrawer<T> drawItem, ReorderableListControl.DrawEmpty drawEmpty, float itemHeight, ReorderableListFlags flags) { |
||||
DoListField<T>(list, drawItem, drawEmpty, itemHeight, flags); |
||||
} |
||||
/// <inheritdoc cref="DoListFieldAbsolute{T}(Rect, IList{T}, ReorderableListControl.ItemDrawer{T}, ReorderableListControl.DrawEmptyAbsolute, float, ReorderableListFlags)"/> |
||||
public static void ListFieldAbsolute<T>(Rect position, IList<T> list, ReorderableListControl.ItemDrawer<T> drawItem, ReorderableListControl.DrawEmptyAbsolute drawEmpty, float itemHeight, ReorderableListFlags flags) { |
||||
DoListFieldAbsolute<T>(position, list, drawItem, drawEmpty, itemHeight, flags); |
||||
} |
||||
|
||||
|
||||
/// <inheritdoc cref="DoListField{T}(IList{T}, ReorderableListControl.ItemDrawer{T}, ReorderableListControl.DrawEmpty, float, ReorderableListFlags)"/> |
||||
public static void ListField<T>(IList<T> list, ReorderableListControl.ItemDrawer<T> drawItem, ReorderableListControl.DrawEmpty drawEmpty, float itemHeight) { |
||||
DoListField<T>(list, drawItem, drawEmpty, itemHeight, 0); |
||||
} |
||||
/// <inheritdoc cref="DoListFieldAbsolute{T}(Rect, IList{T}, ReorderableListControl.ItemDrawer{T}, ReorderableListControl.DrawEmptyAbsolute, float, ReorderableListFlags)"/> |
||||
public static void ListFieldAbsolute<T>(Rect position, IList<T> list, ReorderableListControl.ItemDrawer<T> drawItem, ReorderableListControl.DrawEmptyAbsolute drawEmpty, float itemHeight) { |
||||
DoListFieldAbsolute<T>(position, list, drawItem, drawEmpty, itemHeight, 0); |
||||
} |
||||
|
||||
|
||||
/// <inheritdoc cref="DoListField{T}(IList{T}, ReorderableListControl.ItemDrawer{T}, ReorderableListControl.DrawEmpty, float, ReorderableListFlags)"/> |
||||
public static void ListField<T>(IList<T> list, ReorderableListControl.ItemDrawer<T> drawItem, ReorderableListControl.DrawEmpty drawEmpty, ReorderableListFlags flags) { |
||||
DoListField<T>(list, drawItem, drawEmpty, DefaultItemHeight, flags); |
||||
} |
||||
/// <inheritdoc cref="DoListFieldAbsolute{T}(Rect, IList{T}, ReorderableListControl.ItemDrawer{T}, ReorderableListControl.DrawEmptyAbsolute, float, ReorderableListFlags)"/> |
||||
public static void ListFieldAbsolute<T>(Rect position, IList<T> list, ReorderableListControl.ItemDrawer<T> drawItem, ReorderableListControl.DrawEmptyAbsolute drawEmpty, ReorderableListFlags flags) { |
||||
DoListFieldAbsolute<T>(position, list, drawItem, drawEmpty, DefaultItemHeight, flags); |
||||
} |
||||
|
||||
|
||||
/// <inheritdoc cref="DoListField{T}(IList{T}, ReorderableListControl.ItemDrawer{T}, ReorderableListControl.DrawEmpty, float, ReorderableListFlags)"/> |
||||
public static void ListField<T>(IList<T> list, ReorderableListControl.ItemDrawer<T> drawItem, ReorderableListControl.DrawEmpty drawEmpty) { |
||||
DoListField<T>(list, drawItem, drawEmpty, DefaultItemHeight, 0); |
||||
} |
||||
/// <inheritdoc cref="DoListFieldAbsolute{T}(Rect, IList{T}, ReorderableListControl.ItemDrawer{T}, ReorderableListControl.DrawEmptyAbsolute, float, ReorderableListFlags)"/> |
||||
public static void ListFieldAbsolute<T>(Rect position, IList<T> list, ReorderableListControl.ItemDrawer<T> drawItem, ReorderableListControl.DrawEmptyAbsolute drawEmpty) { |
||||
DoListFieldAbsolute<T>(position, list, drawItem, drawEmpty, DefaultItemHeight, 0); |
||||
} |
||||
|
||||
|
||||
/// <inheritdoc cref="DoListField{T}(IList{T}, ReorderableListControl.ItemDrawer{T}, ReorderableListControl.DrawEmpty, float, ReorderableListFlags)"/> |
||||
public static void ListField<T>(IList<T> list, ReorderableListControl.ItemDrawer<T> drawItem, float itemHeight, ReorderableListFlags flags) { |
||||
DoListField<T>(list, drawItem, null, itemHeight, flags); |
||||
} |
||||
/// <inheritdoc cref="DoListFieldAbsolute{T}(Rect, IList{T}, ReorderableListControl.ItemDrawer{T}, ReorderableListControl.DrawEmptyAbsolute, float, ReorderableListFlags)"/> |
||||
public static void ListFieldAbsolute<T>(Rect position, IList<T> list, ReorderableListControl.ItemDrawer<T> drawItem, float itemHeight, ReorderableListFlags flags) { |
||||
DoListFieldAbsolute<T>(position, list, drawItem, null, itemHeight, flags); |
||||
} |
||||
|
||||
|
||||
/// <inheritdoc cref="DoListField{T}(IList{T}, ReorderableListControl.ItemDrawer{T}, ReorderableListControl.DrawEmpty, float, ReorderableListFlags)"/> |
||||
public static void ListField<T>(IList<T> list, ReorderableListControl.ItemDrawer<T> drawItem, float itemHeight) { |
||||
DoListField<T>(list, drawItem, null, itemHeight, 0); |
||||
} |
||||
/// <inheritdoc cref="DoListFieldAbsolute{T}(Rect, IList{T}, ReorderableListControl.ItemDrawer{T}, ReorderableListControl.DrawEmptyAbsolute, float, ReorderableListFlags)"/> |
||||
public static void ListFieldAbsolute<T>(Rect position, IList<T> list, ReorderableListControl.ItemDrawer<T> drawItem, float itemHeight) { |
||||
DoListFieldAbsolute<T>(position, list, drawItem, null, itemHeight, 0); |
||||
} |
||||
|
||||
|
||||
/// <inheritdoc cref="DoListField{T}(IList{T}, ReorderableListControl.ItemDrawer{T}, ReorderableListControl.DrawEmpty, float, ReorderableListFlags)"/> |
||||
public static void ListField<T>(IList<T> list, ReorderableListControl.ItemDrawer<T> drawItem, ReorderableListFlags flags) { |
||||
DoListField<T>(list, drawItem, null, DefaultItemHeight, flags); |
||||
} |
||||
/// <inheritdoc cref="DoListFieldAbsolute{T}(Rect, IList{T}, ReorderableListControl.ItemDrawer{T}, ReorderableListControl.DrawEmptyAbsolute, float, ReorderableListFlags)"/> |
||||
public static void ListFieldAbsolute<T>(Rect position, IList<T> list, ReorderableListControl.ItemDrawer<T> drawItem, ReorderableListFlags flags) { |
||||
DoListFieldAbsolute<T>(position, list, drawItem, null, DefaultItemHeight, flags); |
||||
} |
||||
|
||||
|
||||
/// <inheritdoc cref="DoListField{T}(IList{T}, ReorderableListControl.ItemDrawer{T}, ReorderableListControl.DrawEmpty, float, ReorderableListFlags)"/> |
||||
public static void ListField<T>(IList<T> list, ReorderableListControl.ItemDrawer<T> drawItem) { |
||||
DoListField<T>(list, drawItem, null, DefaultItemHeight, 0); |
||||
} |
||||
/// <inheritdoc cref="DoListFieldAbsolute{T}(Rect, IList{T}, ReorderableListControl.ItemDrawer{T}, ReorderableListControl.DrawEmptyAbsolute, float, ReorderableListFlags)"/> |
||||
public static void ListFieldAbsolute<T>(Rect position, IList<T> list, ReorderableListControl.ItemDrawer<T> drawItem) { |
||||
DoListFieldAbsolute<T>(position, list, drawItem, null, DefaultItemHeight, 0); |
||||
} |
||||
|
||||
|
||||
/// <summary> |
||||
/// Calculate height of list field for absolute positioning. |
||||
/// </summary> |
||||
/// <param name="itemCount">Count of items in list.</param> |
||||
/// <param name="itemHeight">Fixed height of list item.</param> |
||||
/// <param name="flags">Optional flags to pass into list field.</param> |
||||
/// <returns> |
||||
/// Required list height in pixels. |
||||
/// </returns> |
||||
public static float CalculateListFieldHeight(int itemCount, float itemHeight, ReorderableListFlags flags) { |
||||
// We need to push/pop flags so that nested controls are properly calculated. |
||||
var restoreFlags = DefaultListControl.Flags; |
||||
try { |
||||
DefaultListControl.Flags = flags; |
||||
return DefaultListControl.CalculateListHeight(itemCount, itemHeight); |
||||
} |
||||
finally { |
||||
DefaultListControl.Flags = restoreFlags; |
||||
} |
||||
} |
||||
|
||||
/// <inheritdoc cref="CalculateListFieldHeight(int, float, ReorderableListFlags)"/> |
||||
public static float CalculateListFieldHeight(int itemCount, ReorderableListFlags flags) { |
||||
return CalculateListFieldHeight(itemCount, DefaultItemHeight, flags); |
||||
} |
||||
/// <inheritdoc cref="CalculateListFieldHeight(int, float, ReorderableListFlags)"/> |
||||
public static float CalculateListFieldHeight(int itemCount, float itemHeight) { |
||||
return CalculateListFieldHeight(itemCount, itemHeight, 0); |
||||
} |
||||
/// <inheritdoc cref="CalculateListFieldHeight(int, float, ReorderableListFlags)"/> |
||||
public static float CalculateListFieldHeight(int itemCount) { |
||||
return CalculateListFieldHeight(itemCount, DefaultItemHeight, 0); |
||||
} |
||||
|
||||
#endregion |
||||
|
||||
#region SerializedProperty Control |
||||
|
||||
/// <summary> |
||||
/// Draw list field control for serializable property array. |
||||
/// </summary> |
||||
/// <param name="arrayProperty">Serializable property.</param> |
||||
/// <param name="fixedItemHeight">Use fixed height for items rather than <see cref="UnityEditor.EditorGUI.GetPropertyHeight(SerializedProperty)"/>.</param> |
||||
/// <param name="drawEmpty">Callback to draw custom content for empty list (optional).</param> |
||||
/// <param name="flags">Optional flags to pass into list field.</param> |
||||
private static void DoListField(SerializedProperty arrayProperty, float fixedItemHeight, ReorderableListControl.DrawEmpty drawEmpty, ReorderableListFlags flags) { |
||||
var adaptor = new SerializedPropertyAdaptor(arrayProperty, fixedItemHeight); |
||||
ReorderableListControl.DrawControlFromState(adaptor, drawEmpty, flags); |
||||
} |
||||
/// <summary> |
||||
/// Draw list field control for serializable property array. |
||||
/// </summary> |
||||
/// <param name="position">Position of control.</param> |
||||
/// <param name="arrayProperty">Serializable property.</param> |
||||
/// <param name="fixedItemHeight">Use fixed height for items rather than <see cref="UnityEditor.EditorGUI.GetPropertyHeight(SerializedProperty)"/>.</param> |
||||
/// <param name="drawEmpty">Callback to draw custom content for empty list (optional).</param> |
||||
/// <param name="flags">Optional flags to pass into list field.</param> |
||||
private static void DoListFieldAbsolute(Rect position, SerializedProperty arrayProperty, float fixedItemHeight, ReorderableListControl.DrawEmptyAbsolute drawEmpty, ReorderableListFlags flags) { |
||||
var adaptor = new SerializedPropertyAdaptor(arrayProperty, fixedItemHeight); |
||||
ReorderableListControl.DrawControlFromState(position, adaptor, drawEmpty, flags); |
||||
} |
||||
|
||||
|
||||
/// <inheritdoc cref="DoListField(SerializedProperty, float, ReorderableListControl.DrawEmpty, ReorderableListFlags)"/> |
||||
public static void ListField(SerializedProperty arrayProperty, ReorderableListControl.DrawEmpty drawEmpty, ReorderableListFlags flags) { |
||||
DoListField(arrayProperty, 0, drawEmpty, flags); |
||||
} |
||||
/// <inheritdoc cref="DoListFieldAbsolute(Rect, SerializedProperty, float, ReorderableListControl.DrawEmptyAbsolute, ReorderableListFlags)"/> |
||||
public static void ListFieldAbsolute(Rect position, SerializedProperty arrayProperty, ReorderableListControl.DrawEmptyAbsolute drawEmpty, ReorderableListFlags flags) { |
||||
DoListFieldAbsolute(position, arrayProperty, 0, drawEmpty, flags); |
||||
} |
||||
|
||||
|
||||
/// <inheritdoc cref="DoListField(SerializedProperty, float, ReorderableListControl.DrawEmpty, ReorderableListFlags)"/> |
||||
public static void ListField(SerializedProperty arrayProperty, ReorderableListControl.DrawEmpty drawEmpty) { |
||||
DoListField(arrayProperty, 0, drawEmpty, 0); |
||||
} |
||||
/// <inheritdoc cref="DoListFieldAbsolute(Rect, SerializedProperty, float, ReorderableListControl.DrawEmptyAbsolute, ReorderableListFlags)"/> |
||||
public static void ListFieldAbsolute(Rect position, SerializedProperty arrayProperty, ReorderableListControl.DrawEmptyAbsolute drawEmpty) { |
||||
DoListFieldAbsolute(position, arrayProperty, 0, drawEmpty, 0); |
||||
} |
||||
|
||||
|
||||
/// <inheritdoc cref="DoListField(SerializedProperty, float, ReorderableListControl.DrawEmpty, ReorderableListFlags)"/> |
||||
public static void ListField(SerializedProperty arrayProperty, ReorderableListFlags flags) { |
||||
DoListField(arrayProperty, 0, null, flags); |
||||
} |
||||
/// <inheritdoc cref="DoListFieldAbsolute(Rect, SerializedProperty, float, ReorderableListControl.DrawEmptyAbsolute, ReorderableListFlags)"/> |
||||
public static void ListFieldAbsolute(Rect position, SerializedProperty arrayProperty, ReorderableListFlags flags) { |
||||
DoListFieldAbsolute(position, arrayProperty, 0, null, flags); |
||||
} |
||||
|
||||
|
||||
/// <inheritdoc cref="DoListField(SerializedProperty, float, ReorderableListControl.DrawEmpty, ReorderableListFlags)"/> |
||||
public static void ListField(SerializedProperty arrayProperty) { |
||||
DoListField(arrayProperty, 0, null, 0); |
||||
} |
||||
/// <inheritdoc cref="DoListFieldAbsolute(Rect, SerializedProperty, float, ReorderableListControl.DrawEmptyAbsolute, ReorderableListFlags)"/> |
||||
public static void ListFieldAbsolute(Rect position, SerializedProperty arrayProperty) { |
||||
DoListFieldAbsolute(position, arrayProperty, 0, null, 0); |
||||
} |
||||
|
||||
|
||||
/// <summary> |
||||
/// Calculate height of list field for absolute positioning. |
||||
/// </summary> |
||||
/// <param name="arrayProperty">Serializable property.</param> |
||||
/// <param name="flags">Optional flags to pass into list field.</param> |
||||
/// <returns> |
||||
/// Required list height in pixels. |
||||
/// </returns> |
||||
public static float CalculateListFieldHeight(SerializedProperty arrayProperty, ReorderableListFlags flags) { |
||||
// We need to push/pop flags so that nested controls are properly calculated. |
||||
var restoreFlags = DefaultListControl.Flags; |
||||
try { |
||||
DefaultListControl.Flags = flags; |
||||
return DefaultListControl.CalculateListHeight(new SerializedPropertyAdaptor(arrayProperty)); |
||||
} |
||||
finally { |
||||
DefaultListControl.Flags = restoreFlags; |
||||
} |
||||
} |
||||
|
||||
/// <inheritdoc cref="CalculateListFieldHeight(SerializedProperty, ReorderableListFlags)"/> |
||||
public static float CalculateListFieldHeight(SerializedProperty arrayProperty) { |
||||
return CalculateListFieldHeight(arrayProperty, 0); |
||||
} |
||||
|
||||
#endregion |
||||
|
||||
#region SerializedProperty Control (Fixed Item Height) |
||||
|
||||
/// <inheritdoc cref="DoListField(SerializedProperty, float, ReorderableListControl.DrawEmpty, ReorderableListFlags)"/> |
||||
public static void ListField(SerializedProperty arrayProperty, float fixedItemHeight, ReorderableListControl.DrawEmpty drawEmpty, ReorderableListFlags flags) { |
||||
DoListField(arrayProperty, fixedItemHeight, drawEmpty, flags); |
||||
} |
||||
/// <inheritdoc cref="DoListFieldAbsolute(Rect, SerializedProperty, float, ReorderableListControl.DrawEmptyAbsolute, ReorderableListFlags)"/> |
||||
public static void ListFieldAbsolute(Rect position, SerializedProperty arrayProperty, float fixedItemHeight, ReorderableListControl.DrawEmptyAbsolute drawEmpty, ReorderableListFlags flags) { |
||||
DoListFieldAbsolute(position, arrayProperty, fixedItemHeight, drawEmpty, flags); |
||||
} |
||||
|
||||
|
||||
/// <inheritdoc cref="DoListField(SerializedProperty, float, ReorderableListControl.DrawEmpty, ReorderableListFlags)"/> |
||||
public static void ListField(SerializedProperty arrayProperty, float fixedItemHeight, ReorderableListControl.DrawEmpty drawEmpty) { |
||||
DoListField(arrayProperty, fixedItemHeight, drawEmpty, 0); |
||||
} |
||||
/// <inheritdoc cref="DoListFieldAbsolute(Rect, SerializedProperty, float, ReorderableListControl.DrawEmptyAbsolute, ReorderableListFlags)"/> |
||||
public static void ListFieldAbsolute(Rect position, SerializedProperty arrayProperty, float fixedItemHeight, ReorderableListControl.DrawEmptyAbsolute drawEmpty) { |
||||
DoListFieldAbsolute(position, arrayProperty, fixedItemHeight, drawEmpty, 0); |
||||
} |
||||
|
||||
|
||||
/// <inheritdoc cref="DoListField(SerializedProperty, float, ReorderableListControl.DrawEmpty, ReorderableListFlags)"/> |
||||
public static void ListField(SerializedProperty arrayProperty, float fixedItemHeight, ReorderableListFlags flags) { |
||||
DoListField(arrayProperty, fixedItemHeight, null, flags); |
||||
} |
||||
/// <inheritdoc cref="DoListFieldAbsolute(Rect, SerializedProperty, float, ReorderableListControl.DrawEmptyAbsolute, ReorderableListFlags)"/> |
||||
public static void ListFieldAbsolute(Rect position, SerializedProperty arrayProperty, float fixedItemHeight, ReorderableListFlags flags) { |
||||
DoListFieldAbsolute(position, arrayProperty, fixedItemHeight, null, flags); |
||||
} |
||||
|
||||
|
||||
/// <inheritdoc cref="DoListField(SerializedProperty, float, ReorderableListControl.DrawEmpty, ReorderableListFlags)"/> |
||||
public static void ListField(SerializedProperty arrayProperty, float fixedItemHeight) { |
||||
DoListField(arrayProperty, fixedItemHeight, null, 0); |
||||
} |
||||
/// <inheritdoc cref="DoListFieldAbsolute(Rect, SerializedProperty, float, ReorderableListControl.DrawEmptyAbsolute, ReorderableListFlags)"/> |
||||
public static void ListFieldAbsolute(Rect position, SerializedProperty arrayProperty, float fixedItemHeight) { |
||||
DoListFieldAbsolute(position, arrayProperty, fixedItemHeight, null, 0); |
||||
} |
||||
|
||||
#endregion |
||||
|
||||
#region Adaptor Control |
||||
|
||||
/// <summary> |
||||
/// Draw list field control for adapted collection. |
||||
/// </summary> |
||||
/// <param name="adaptor">Reorderable list adaptor.</param> |
||||
/// <param name="drawEmpty">Callback to draw custom content for empty list (optional).</param> |
||||
/// <param name="flags">Optional flags to pass into list field.</param> |
||||
private static void DoListField(IReorderableListAdaptor adaptor, ReorderableListControl.DrawEmpty drawEmpty, ReorderableListFlags flags = 0) { |
||||
ReorderableListControl.DrawControlFromState(adaptor, drawEmpty, flags); |
||||
} |
||||
/// <summary> |
||||
/// Draw list field control for adapted collection. |
||||
/// </summary> |
||||
/// <param name="position">Position of control.</param> |
||||
/// <param name="adaptor">Reorderable list adaptor.</param> |
||||
/// <param name="drawEmpty">Callback to draw custom content for empty list (optional).</param> |
||||
/// <param name="flags">Optional flags to pass into list field.</param> |
||||
private static void DoListFieldAbsolute(Rect position, IReorderableListAdaptor adaptor, ReorderableListControl.DrawEmptyAbsolute drawEmpty, ReorderableListFlags flags = 0) { |
||||
ReorderableListControl.DrawControlFromState(position, adaptor, drawEmpty, flags); |
||||
} |
||||
|
||||
|
||||
/// <inheritdoc cref="DoListField(IReorderableListAdaptor, ReorderableListControl.DrawEmpty, ReorderableListFlags)"/> |
||||
public static void ListField(IReorderableListAdaptor adaptor, ReorderableListControl.DrawEmpty drawEmpty, ReorderableListFlags flags) { |
||||
DoListField(adaptor, drawEmpty, flags); |
||||
} |
||||
/// <inheritdoc cref="DoListFieldAbsolute(Rect, IReorderableListAdaptor, ReorderableListControl.DrawEmptyAbsolute, ReorderableListFlags)"/> |
||||
public static void ListFieldAbsolute(Rect position, IReorderableListAdaptor adaptor, ReorderableListControl.DrawEmptyAbsolute drawEmpty, ReorderableListFlags flags) { |
||||
DoListFieldAbsolute(position, adaptor, drawEmpty, flags); |
||||
} |
||||
|
||||
|
||||
/// <inheritdoc cref="DoListField(IReorderableListAdaptor, ReorderableListControl.DrawEmpty, ReorderableListFlags)"/> |
||||
public static void ListField(IReorderableListAdaptor adaptor, ReorderableListControl.DrawEmpty drawEmpty) { |
||||
DoListField(adaptor, drawEmpty, 0); |
||||
} |
||||
/// <inheritdoc cref="DoListFieldAbsolute(Rect, IReorderableListAdaptor, ReorderableListControl.DrawEmptyAbsolute, ReorderableListFlags)"/> |
||||
public static void ListFieldAbsolute(Rect position, IReorderableListAdaptor adaptor, ReorderableListControl.DrawEmptyAbsolute drawEmpty) { |
||||
DoListFieldAbsolute(position, adaptor, drawEmpty, 0); |
||||
} |
||||
|
||||
|
||||
/// <inheritdoc cref="DoListField(IReorderableListAdaptor, ReorderableListControl.DrawEmpty, ReorderableListFlags)"/> |
||||
public static void ListField(IReorderableListAdaptor adaptor, ReorderableListFlags flags) { |
||||
DoListField(adaptor, null, flags); |
||||
} |
||||
/// <inheritdoc cref="DoListFieldAbsolute(Rect, IReorderableListAdaptor, ReorderableListControl.DrawEmptyAbsolute, ReorderableListFlags)"/> |
||||
public static void ListFieldAbsolute(Rect position, IReorderableListAdaptor adaptor, ReorderableListFlags flags) { |
||||
DoListFieldAbsolute(position, adaptor, null, flags); |
||||
} |
||||
|
||||
|
||||
/// <inheritdoc cref="DoListField(IReorderableListAdaptor, ReorderableListControl.DrawEmpty, ReorderableListFlags)"/> |
||||
public static void ListField(IReorderableListAdaptor adaptor) { |
||||
DoListField(adaptor, null, 0); |
||||
} |
||||
/// <inheritdoc cref="DoListFieldAbsolute(Rect, IReorderableListAdaptor, ReorderableListControl.DrawEmptyAbsolute, ReorderableListFlags)"/> |
||||
public static void ListFieldAbsolute(Rect position, IReorderableListAdaptor adaptor) { |
||||
DoListFieldAbsolute(position, adaptor, null, 0); |
||||
} |
||||
|
||||
|
||||
/// <summary> |
||||
/// Calculate height of list field for adapted collection. |
||||
/// </summary> |
||||
/// <param name="adaptor">Reorderable list adaptor.</param> |
||||
/// <param name="flags">Optional flags to pass into list field.</param> |
||||
/// <returns> |
||||
/// Required list height in pixels. |
||||
/// </returns> |
||||
public static float CalculateListFieldHeight(IReorderableListAdaptor adaptor, ReorderableListFlags flags) { |
||||
// We need to push/pop flags so that nested controls are properly calculated. |
||||
var restoreFlags = DefaultListControl.Flags; |
||||
try { |
||||
DefaultListControl.Flags = flags; |
||||
return DefaultListControl.CalculateListHeight(adaptor); |
||||
} |
||||
finally { |
||||
DefaultListControl.Flags = restoreFlags; |
||||
} |
||||
} |
||||
|
||||
/// <inheritdoc cref="CalculateListFieldHeight(IReorderableListAdaptor, ReorderableListFlags)"/> |
||||
public static float CalculateListFieldHeight(IReorderableListAdaptor adaptor) { |
||||
return CalculateListFieldHeight(adaptor, 0); |
||||
} |
||||
|
||||
#endregion |
||||
|
||||
} |
||||
|
||||
} |
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 0cda42c9be3a73c469749c5422090d9a |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,114 @@
|
||||
// Copyright (c) Rotorz Limited. All rights reserved. |
||||
// Licensed under the MIT license. See LICENSE file in the project root. |
||||
|
||||
using Rotorz.ReorderableList.Internal; |
||||
using UnityEditor; |
||||
using UnityEngine; |
||||
|
||||
namespace Rotorz.ReorderableList { |
||||
|
||||
/// <summary> |
||||
/// Styles for the <see cref="ReorderableListControl"/>. |
||||
/// </summary> |
||||
public static class ReorderableListStyles { |
||||
|
||||
static ReorderableListStyles() { |
||||
Title = new GUIStyle(); |
||||
Title.border = new RectOffset(2, 2, 2, 1); |
||||
Title.margin = new RectOffset(5, 5, 5, 0); |
||||
Title.padding = new RectOffset(5, 5, 3, 3); |
||||
Title.alignment = TextAnchor.MiddleLeft; |
||||
Title.normal.background = ReorderableListResources.GetTexture(ReorderableListTexture.TitleBackground); |
||||
Title.normal.textColor = EditorGUIUtility.isProSkin |
||||
? new Color(0.8f, 0.8f, 0.8f) |
||||
: new Color(0.2f, 0.2f, 0.2f); |
||||
|
||||
Container = new GUIStyle(); |
||||
Container.border = new RectOffset(2, 2, 2, 2); |
||||
Container.margin = new RectOffset(5, 5, 0, 0); |
||||
Container.padding = new RectOffset(2, 2, 2, 2); |
||||
Container.normal.background = ReorderableListResources.GetTexture(ReorderableListTexture.ContainerBackground); |
||||
|
||||
Container2 = new GUIStyle(Container); |
||||
Container2.normal.background = ReorderableListResources.GetTexture(ReorderableListTexture.Container2Background); |
||||
|
||||
FooterButton = new GUIStyle(); |
||||
FooterButton.fixedHeight = 16; |
||||
FooterButton.alignment = TextAnchor.MiddleCenter; |
||||
FooterButton.normal.background = ReorderableListResources.GetTexture(ReorderableListTexture.Button_Normal); |
||||
FooterButton.active.background = ReorderableListResources.GetTexture(ReorderableListTexture.Button_Active); |
||||
FooterButton.border = new RectOffset(3, 3, 1, 3); |
||||
FooterButton.padding = new RectOffset(2, 2, 0, 2); |
||||
FooterButton.clipping = TextClipping.Overflow; |
||||
|
||||
FooterButton2 = new GUIStyle(); |
||||
FooterButton2.fixedHeight = 18; |
||||
FooterButton2.alignment = TextAnchor.MiddleCenter; |
||||
FooterButton2.normal.background = ReorderableListResources.GetTexture(ReorderableListTexture.Button2_Normal); |
||||
FooterButton2.active.background = ReorderableListResources.GetTexture(ReorderableListTexture.Button2_Active); |
||||
FooterButton2.border = new RectOffset(3, 3, 3, 3); |
||||
FooterButton2.padding = new RectOffset(2, 2, 2, 2); |
||||
FooterButton2.clipping = TextClipping.Overflow; |
||||
|
||||
ItemButton = new GUIStyle(); |
||||
ItemButton.active.background = ReorderableListResources.CreatePixelTexture("Dark Pixel (List GUI)", new Color32(18, 18, 18, 255)); |
||||
ItemButton.imagePosition = ImagePosition.ImageOnly; |
||||
ItemButton.alignment = TextAnchor.MiddleCenter; |
||||
ItemButton.overflow = new RectOffset(0, 0, -1, 0); |
||||
ItemButton.padding = new RectOffset(0, 0, 1, 0); |
||||
ItemButton.contentOffset = new Vector2(0, -1f); |
||||
|
||||
SelectedItem = new GUIStyle(); |
||||
SelectedItem.normal.background = ReorderableListResources.texHighlightColor; |
||||
SelectedItem.normal.textColor = Color.white; |
||||
SelectedItem.fontSize = 12; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Gets style for title header. |
||||
/// </summary> |
||||
public static GUIStyle Title { get; private set; } |
||||
|
||||
/// <summary> |
||||
/// Gets style for the background of list control. |
||||
/// </summary> |
||||
public static GUIStyle Container { get; private set; } |
||||
/// <summary> |
||||
/// Gets an alternative style for the background of list control. |
||||
/// </summary> |
||||
public static GUIStyle Container2 { get; private set; } |
||||
/// <summary> |
||||
/// Gets style for footer button. |
||||
/// </summary> |
||||
public static GUIStyle FooterButton { get; private set; } |
||||
/// <summary> |
||||
/// Gets an alternative style for footer button. |
||||
/// </summary> |
||||
public static GUIStyle FooterButton2 { get; private set; } |
||||
/// <summary> |
||||
/// Gets style for remove item button. |
||||
/// </summary> |
||||
public static GUIStyle ItemButton { get; private set; } |
||||
|
||||
/// <summary> |
||||
/// Gets style for the background of a selected item. |
||||
/// </summary> |
||||
public static GUIStyle SelectedItem { get; private set; } |
||||
|
||||
/// <summary> |
||||
/// Gets color for the horizontal lines that appear between list items. |
||||
/// </summary> |
||||
public static Color HorizontalLineColor { |
||||
get { return EditorGUIUtility.isProSkin ? new Color(1f, 1f, 1f, 0.14f) : new Color(0.59f, 0.59f, 0.59f, 0.55f); } |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Gets color of background for a selected list item. |
||||
/// </summary> |
||||
public static Color SelectionBackgroundColor { |
||||
get { return EditorGUIUtility.isProSkin ? new Color32(62, 95, 150, 255) : new Color32(62, 125, 231, 255); } |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2 |
||||
guid: c4843f314e955fb459f99b33194fbebd |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,159 @@
|
||||
// Copyright (c) Rotorz Limited. All rights reserved. |
||||
// Licensed under the MIT license. See LICENSE file in the project root. |
||||
|
||||
using Rotorz.ReorderableList.Internal; |
||||
using System; |
||||
using UnityEditor; |
||||
using UnityEngine; |
||||
|
||||
namespace Rotorz.ReorderableList { |
||||
|
||||
/// <summary> |
||||
/// Reorderable list adaptor for serialized array property. |
||||
/// </summary> |
||||
/// <remarks> |
||||
/// <para>This adaptor can be subclassed to add special logic to item height calculation. |
||||
/// You may want to implement a custom adaptor class where specialised functionality |
||||
/// is needed.</para> |
||||
/// <para>List elements are <b>not</b> cloned using the <see cref="System.ICloneable"/> |
||||
/// interface when using a <see cref="UnityEditor.SerializedProperty"/> to |
||||
/// manipulate lists.</para> |
||||
/// </remarks> |
||||
public class SerializedPropertyAdaptor : IReorderableListAdaptor { |
||||
|
||||
private SerializedProperty _arrayProperty; |
||||
|
||||
/// <summary> |
||||
/// Fixed height of each list item. |
||||
/// </summary> |
||||
/// <remarks> |
||||
/// <para>Non-zero value overrides property drawer height calculation |
||||
/// which is more efficient.</para> |
||||
/// </remarks> |
||||
public float FixedItemHeight; |
||||
|
||||
/// <summary> |
||||
/// Gets element from list. |
||||
/// </summary> |
||||
/// <param name="index">Zero-based index of element.</param> |
||||
/// <returns> |
||||
/// Serialized property wrapper for array element. |
||||
/// </returns> |
||||
public SerializedProperty this[int index] { |
||||
get { return _arrayProperty.GetArrayElementAtIndex(index); } |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Gets the underlying serialized array property. |
||||
/// </summary> |
||||
public SerializedProperty arrayProperty { |
||||
get { return _arrayProperty; } |
||||
} |
||||
|
||||
#region Construction |
||||
|
||||
/// <summary> |
||||
/// Initializes a new instance of <see cref="SerializedPropertyAdaptor"/>. |
||||
/// </summary> |
||||
/// <param name="arrayProperty">Serialized property for entire array.</param> |
||||
/// <param name="fixedItemHeight">Non-zero height overrides property drawer height calculation.</param> |
||||
public SerializedPropertyAdaptor(SerializedProperty arrayProperty, float fixedItemHeight) { |
||||
if (arrayProperty == null) |
||||
throw new ArgumentNullException("Array property was null."); |
||||
if (!arrayProperty.isArray) |
||||
throw new InvalidOperationException("Specified serialized propery is not an array."); |
||||
|
||||
this._arrayProperty = arrayProperty; |
||||
this.FixedItemHeight = fixedItemHeight; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Initializes a new instance of <see cref="SerializedPropertyAdaptor"/>. |
||||
/// </summary> |
||||
/// <param name="arrayProperty">Serialized property for entire array.</param> |
||||
public SerializedPropertyAdaptor(SerializedProperty arrayProperty) : this(arrayProperty, 0f) { |
||||
} |
||||
|
||||
#endregion |
||||
|
||||
#region IReorderableListAdaptor - Implementation |
||||
|
||||
/// <inheritdoc/> |
||||
public int Count { |
||||
get { return _arrayProperty.arraySize; } |
||||
} |
||||
|
||||
/// <inheritdoc/> |
||||
public virtual bool CanDrag(int index) { |
||||
return true; |
||||
} |
||||
/// <inheritdoc/> |
||||
public virtual bool CanRemove(int index) { |
||||
return true; |
||||
} |
||||
|
||||
/// <inheritdoc/> |
||||
public void Add() { |
||||
int newIndex = _arrayProperty.arraySize; |
||||
++_arrayProperty.arraySize; |
||||
SerializedPropertyUtility.ResetValue(_arrayProperty.GetArrayElementAtIndex(newIndex)); |
||||
} |
||||
/// <inheritdoc/> |
||||
public void Insert(int index) { |
||||
_arrayProperty.InsertArrayElementAtIndex(index); |
||||
SerializedPropertyUtility.ResetValue(_arrayProperty.GetArrayElementAtIndex(index)); |
||||
} |
||||
/// <inheritdoc/> |
||||
public void Duplicate(int index) { |
||||
_arrayProperty.InsertArrayElementAtIndex(index); |
||||
} |
||||
/// <inheritdoc/> |
||||
public void Remove(int index) { |
||||
// Unity doesn't remove element when it contains an object reference. |
||||
var elementProperty = _arrayProperty.GetArrayElementAtIndex(index); |
||||
if (elementProperty.propertyType == SerializedPropertyType.ObjectReference) |
||||
elementProperty.objectReferenceValue = null; |
||||
|
||||
_arrayProperty.DeleteArrayElementAtIndex(index); |
||||
} |
||||
/// <inheritdoc/> |
||||
public void Move(int sourceIndex, int destIndex) { |
||||
if (destIndex > sourceIndex) |
||||
--destIndex; |
||||
_arrayProperty.MoveArrayElement(sourceIndex, destIndex); |
||||
} |
||||
/// <inheritdoc/> |
||||
public void Clear() { |
||||
_arrayProperty.ClearArray(); |
||||
} |
||||
|
||||
/// <inheritdoc/> |
||||
public virtual void BeginGUI() { |
||||
} |
||||
|
||||
/// <inheritdoc/> |
||||
public virtual void EndGUI() { |
||||
} |
||||
|
||||
/// <inheritdoc/> |
||||
public virtual void DrawItemBackground(Rect position, int index) { |
||||
} |
||||
|
||||
/// <inheritdoc/> |
||||
public virtual void DrawItem(Rect position, int index) { |
||||
EditorGUI.PropertyField(position, this[index], GUIContent.none, false); |
||||
} |
||||
|
||||
/// <inheritdoc/> |
||||
public virtual float GetItemHeight(int index) { |
||||
return FixedItemHeight != 0f |
||||
? FixedItemHeight |
||||
: EditorGUI.GetPropertyHeight(this[index], GUIContent.none, false) |
||||
; |
||||
} |
||||
|
||||
#endregion |
||||
|
||||
} |
||||
|
||||
} |
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 591bfb933f0cb1a429927d177e35f97d |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -1,6 +1,7 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 8fc66c8c3ee484548a40e9b4cb50f206 |
||||
TextScriptImporter: |
||||
externalObjects: {} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
||||
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: adbb9aeb25106a54e9af119d9d77e332 |
||||
folderAsset: yes |
||||
DefaultImporter: |
||||
externalObjects: {} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,36 @@
|
||||
using System.Reflection; |
||||
using System.Runtime.CompilerServices; |
||||
using System.Runtime.InteropServices; |
||||
|
||||
// General Information about an assembly is controlled through the following |
||||
// set of attributes. Change these attribute values to modify the information |
||||
// associated with an assembly. |
||||
[assembly: AssemblyTitle("Editor.ReorderableList")] |
||||
[assembly: AssemblyDescription("Reorderable list field for custom Unity editor scripts.")] |
||||
[assembly: AssemblyConfiguration("")] |
||||
[assembly: AssemblyCompany("Rotorz Limited")] |
||||
[assembly: AssemblyProduct("Editor.ReorderableList")] |
||||
[assembly: AssemblyCopyright("©2013-2016 Rotorz Limited. All rights reserved.")] |
||||
[assembly: AssemblyTrademark("")] |
||||
[assembly: AssemblyCulture("")] |
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible |
||||
// to COM components. If you need to access a type in this assembly from |
||||
// COM, set the ComVisible attribute to true on that type. |
||||
[assembly: ComVisible(false)] |
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM |
||||
[assembly: Guid("15882e08-6b4f-459f-a1d0-e4b26821f344")] |
||||
|
||||
// Version information for an assembly consists of the following four values: |
||||
// |
||||
// Major Version |
||||
// Minor Version |
||||
// Build Number |
||||
// Revision |
||||
// |
||||
// You can specify all the values or you can default the Build and Revision Numbers |
||||
// by using the '*' as shown below: |
||||
// [assembly: AssemblyVersion("1.0.*")] |
||||
[assembly: AssemblyVersion("0.0.0.0")] |
||||
[assembly: AssemblyFileVersion("0.4.4.0")] |
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 9229bf01f21bb1842a94bbabd158f241 |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -1,6 +1,7 @@
|
||||
fileFormatVersion: 2 |
||||
guid: d5735c08f13f43a44be11da81110e424 |
||||
guid: c4b649ac64aa4bd428c41192aba38c61 |
||||
TextScriptImporter: |
||||
externalObjects: {} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 457a6fa816de84a4bb30c03f176b4554 |
||||
folderAsset: yes |
||||
DefaultImporter: |
||||
externalObjects: {} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
Binary file not shown.
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2 |
||||
guid: ff01767a12436d745bc2fc6157a4f303 |
||||
DefaultImporter: |
||||
externalObjects: {} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
Binary file not shown.
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 2a6cc2b87d678a44f9aac32c49b2373f |
||||
DefaultImporter: |
||||
externalObjects: {} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
Binary file not shown.
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 560954e67fbf14b43a2d6638190e8325 |
||||
DefaultImporter: |
||||
externalObjects: {} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
Binary file not shown.
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 397430eb6d7634449b41b059589c33bc |
||||
DefaultImporter: |
||||
externalObjects: {} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
After Width: | Height: | Size: 60 KiB |
@ -0,0 +1,86 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 195bac68939599148a3fbf5108bcfc20 |
||||
TextureImporter: |
||||
fileIDToRecycleName: {} |
||||
externalObjects: {} |
||||
serializedVersion: 6 |
||||
mipmaps: |
||||
mipMapMode: 0 |
||||
enableMipMap: 0 |
||||
sRGBTexture: 1 |
||||
linearTexture: 0 |
||||
fadeOut: 0 |
||||
borderMipMap: 0 |
||||
mipMapsPreserveCoverage: 0 |
||||
alphaTestReferenceValue: 0.5 |
||||
mipMapFadeDistanceStart: 1 |
||||
mipMapFadeDistanceEnd: 3 |
||||
bumpmap: |
||||
convertToNormalMap: 0 |
||||
externalNormalMap: 0 |
||||
heightScale: 0.25 |
||||
normalMapFilter: 0 |
||||
isReadable: 0 |
||||
streamingMipmaps: 0 |
||||
streamingMipmapsPriority: 0 |
||||
grayScaleToAlpha: 0 |
||||
generateCubemap: 6 |
||||
cubemapConvolution: 0 |
||||
seamlessCubemap: 0 |
||||
textureFormat: 1 |
||||
maxTextureSize: 2048 |
||||
textureSettings: |
||||
serializedVersion: 2 |
||||
filterMode: -1 |
||||
aniso: -1 |
||||
mipBias: -100 |
||||
wrapU: 1 |
||||
wrapV: 1 |
||||
wrapW: 1 |
||||
nPOTScale: 0 |
||||
lightmap: 0 |
||||
compressionQuality: 50 |
||||
spriteMode: 1 |
||||
spriteExtrude: 1 |
||||
spriteMeshType: 1 |
||||
alignment: 0 |
||||
spritePivot: {x: 0.5, y: 0.5} |
||||
spritePixelsToUnits: 100 |
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0} |
||||
spriteGenerateFallbackPhysicsShape: 1 |
||||
alphaUsage: 1 |
||||
alphaIsTransparency: 1 |
||||
spriteTessellationDetail: -1 |
||||
textureType: 8 |
||||
textureShape: 1 |
||||
singleChannelComponent: 0 |
||||
maxTextureSizeSet: 0 |
||||
compressionQualitySet: 0 |
||||
textureFormatSet: 0 |
||||
platformSettings: |
||||
- serializedVersion: 2 |
||||
buildTarget: DefaultTexturePlatform |
||||
maxTextureSize: 2048 |
||||
resizeAlgorithm: 0 |
||||
textureFormat: -1 |
||||
textureCompression: 1 |
||||
compressionQuality: 50 |
||||
crunchedCompression: 0 |
||||
allowsAlphaSplitting: 0 |
||||
overridden: 0 |
||||
androidETC2FallbackOverride: 0 |
||||
spriteSheet: |
||||
serializedVersion: 2 |
||||
sprites: [] |
||||
outline: [] |
||||
physicsShape: [] |
||||
bones: [] |
||||
spriteID: d7ebb509f3bb7c54e835241e12983aa1 |
||||
vertices: [] |
||||
indices: |
||||
edges: [] |
||||
weights: [] |
||||
spritePackingTag: |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
After Width: | Height: | Size: 8.9 KiB |
@ -0,0 +1,86 @@
|
||||
fileFormatVersion: 2 |
||||
guid: ab7d0b47fabb22f4f84981c741f083f9 |
||||
TextureImporter: |
||||
fileIDToRecycleName: {} |
||||
externalObjects: {} |
||||
serializedVersion: 6 |
||||
mipmaps: |
||||
mipMapMode: 0 |
||||
enableMipMap: 0 |
||||
sRGBTexture: 1 |
||||
linearTexture: 0 |
||||
fadeOut: 0 |
||||
borderMipMap: 0 |
||||
mipMapsPreserveCoverage: 0 |
||||
alphaTestReferenceValue: 0.5 |
||||
mipMapFadeDistanceStart: 1 |
||||
mipMapFadeDistanceEnd: 3 |
||||
bumpmap: |
||||
convertToNormalMap: 0 |
||||
externalNormalMap: 0 |
||||
heightScale: 0.25 |
||||
normalMapFilter: 0 |
||||
isReadable: 0 |
||||
streamingMipmaps: 0 |
||||
streamingMipmapsPriority: 0 |
||||
grayScaleToAlpha: 0 |
||||
generateCubemap: 6 |
||||
cubemapConvolution: 0 |
||||
seamlessCubemap: 0 |
||||
textureFormat: 1 |
||||
maxTextureSize: 2048 |
||||
textureSettings: |
||||
serializedVersion: 2 |
||||
filterMode: -1 |
||||
aniso: -1 |
||||
mipBias: -100 |
||||
wrapU: 1 |
||||
wrapV: 1 |
||||
wrapW: 1 |
||||
nPOTScale: 0 |
||||
lightmap: 0 |
||||
compressionQuality: 50 |
||||
spriteMode: 1 |
||||
spriteExtrude: 1 |
||||
spriteMeshType: 1 |
||||
alignment: 0 |
||||
spritePivot: {x: 0.5, y: 0.5} |
||||
spritePixelsToUnits: 100 |
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0} |
||||
spriteGenerateFallbackPhysicsShape: 1 |
||||
alphaUsage: 1 |
||||
alphaIsTransparency: 1 |
||||
spriteTessellationDetail: -1 |
||||
textureType: 8 |
||||
textureShape: 1 |
||||
singleChannelComponent: 0 |
||||
maxTextureSizeSet: 0 |
||||
compressionQualitySet: 0 |
||||
textureFormatSet: 0 |
||||
platformSettings: |
||||
- serializedVersion: 2 |
||||
buildTarget: DefaultTexturePlatform |
||||
maxTextureSize: 2048 |
||||
resizeAlgorithm: 0 |
||||
textureFormat: -1 |
||||
textureCompression: 1 |
||||
compressionQuality: 50 |
||||
crunchedCompression: 0 |
||||
allowsAlphaSplitting: 0 |
||||
overridden: 0 |
||||
androidETC2FallbackOverride: 0 |
||||
spriteSheet: |
||||
serializedVersion: 2 |
||||
sprites: [] |
||||
outline: [] |
||||
physicsShape: [] |
||||
bones: [] |
||||
spriteID: 21a9e3756c473cb4daeeb1820c46b5e2 |
||||
vertices: [] |
||||
indices: |
||||
edges: [] |
||||
weights: [] |
||||
spritePackingTag: |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -1,4 +1,39 @@
|
||||
{ |
||||
"dependencies": { |
||||
} |
||||
"dependencies": { |
||||
"com.unity.ads": "2.0.8", |
||||
"com.unity.analytics": "2.0.16", |
||||
"com.unity.package-manager-ui": "1.9.11", |
||||
"com.unity.purchasing": "2.0.3", |
||||
"com.unity.textmeshpro": "1.2.4", |
||||
"com.unity.modules.ai": "1.0.0", |
||||
"com.unity.modules.animation": "1.0.0", |
||||
"com.unity.modules.assetbundle": "1.0.0", |
||||
"com.unity.modules.audio": "1.0.0", |
||||
"com.unity.modules.cloth": "1.0.0", |
||||
"com.unity.modules.director": "1.0.0", |
||||
"com.unity.modules.imageconversion": "1.0.0", |
||||
"com.unity.modules.imgui": "1.0.0", |
||||
"com.unity.modules.jsonserialize": "1.0.0", |
||||
"com.unity.modules.particlesystem": "1.0.0", |
||||
"com.unity.modules.physics": "1.0.0", |
||||
"com.unity.modules.physics2d": "1.0.0", |
||||
"com.unity.modules.screencapture": "1.0.0", |
||||
"com.unity.modules.terrain": "1.0.0", |
||||
"com.unity.modules.terrainphysics": "1.0.0", |
||||
"com.unity.modules.tilemap": "1.0.0", |
||||
"com.unity.modules.ui": "1.0.0", |
||||
"com.unity.modules.uielements": "1.0.0", |
||||
"com.unity.modules.umbra": "1.0.0", |
||||
"com.unity.modules.unityanalytics": "1.0.0", |
||||
"com.unity.modules.unitywebrequest": "1.0.0", |
||||
"com.unity.modules.unitywebrequestassetbundle": "1.0.0", |
||||
"com.unity.modules.unitywebrequestaudio": "1.0.0", |
||||
"com.unity.modules.unitywebrequesttexture": "1.0.0", |
||||
"com.unity.modules.unitywebrequestwww": "1.0.0", |
||||
"com.unity.modules.vehicles": "1.0.0", |
||||
"com.unity.modules.video": "1.0.0", |
||||
"com.unity.modules.vr": "1.0.0", |
||||
"com.unity.modules.wind": "1.0.0", |
||||
"com.unity.modules.xr": "1.0.0" |
||||
} |
||||
} |
||||
|
Loading…
Reference in new issue