备份CatanBuilding瘦身独立工程
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
using HeurekaGames.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Profiling;
|
||||
|
||||
namespace HeurekaGames.AssetHunterPRO.BaseTreeviewImpl.DependencyGraph
|
||||
{
|
||||
[System.Serializable]
|
||||
public class AH_DepGraphElement : TreeElement, ISerializationCallbackReceiver
|
||||
{
|
||||
#region Fields
|
||||
[SerializeField]
|
||||
private string relativePath;
|
||||
/*[SerializeField]
|
||||
private string assetName;*/
|
||||
[SerializeField]
|
||||
private Type assetType;
|
||||
private Texture icon;
|
||||
[SerializeField]
|
||||
private string assetTypeSerialized;
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
public string RelativePath
|
||||
{
|
||||
get
|
||||
{
|
||||
return relativePath;
|
||||
}
|
||||
}
|
||||
|
||||
public string AssetName
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Name;
|
||||
}
|
||||
}
|
||||
|
||||
public Type AssetType
|
||||
{
|
||||
get
|
||||
{
|
||||
return assetType;
|
||||
}
|
||||
}
|
||||
|
||||
public Texture Icon
|
||||
{
|
||||
get
|
||||
{
|
||||
return icon;
|
||||
}
|
||||
}
|
||||
|
||||
public string AssetTypeSerialized
|
||||
{
|
||||
get
|
||||
{
|
||||
return assetTypeSerialized;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public AH_DepGraphElement(string name, int depth, int id, string relativepath) : base(name, depth, id)
|
||||
{
|
||||
this.relativePath = relativepath;
|
||||
var stringSplit = relativepath.Split('/');
|
||||
//this.assetName = stringSplit.Last();
|
||||
this.assetType = UnityEditor.AssetDatabase.GetMainAssetTypeAtPath(relativepath);
|
||||
if (this.assetType != null)
|
||||
this.assetTypeSerialized = Heureka_Serializer.SerializeType(assetType);
|
||||
this.icon = UnityEditor.EditorGUIUtility.ObjectContent(null, assetType).image;
|
||||
}
|
||||
|
||||
#region Serialization callbacks
|
||||
//TODO Maybe we can store type infos in BuildInfoTreeView instead of on each individual element, might be performance heavy
|
||||
|
||||
//Store serializable string so we can retrieve type after serialization
|
||||
public void OnBeforeSerialize()
|
||||
{
|
||||
if (assetType != null)
|
||||
assetTypeSerialized = Heureka_Serializer.SerializeType(assetType);
|
||||
}
|
||||
|
||||
//Set type from serialized property
|
||||
public void OnAfterDeserialize()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(AssetTypeSerialized))
|
||||
{
|
||||
this.assetType = Heureka_Serializer.DeSerializeType(AssetTypeSerialized);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c926e474704fe51438030a9808922819
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,56 @@
|
||||
|
||||
using System;
|
||||
using UnityEditor;
|
||||
using UnityEditor.IMGUI.Controls;
|
||||
using UnityEngine;
|
||||
|
||||
namespace HeurekaGames.AssetHunterPRO.BaseTreeviewImpl.DependencyGraph
|
||||
{
|
||||
internal class AH_DepGraphHeader : MultiColumnHeader
|
||||
{
|
||||
Mode m_Mode;
|
||||
public enum Mode
|
||||
{
|
||||
Treeview,
|
||||
SortedList
|
||||
}
|
||||
|
||||
public AH_DepGraphHeader(MultiColumnHeaderState state) : base(state)
|
||||
{
|
||||
mode = Mode.Treeview;
|
||||
}
|
||||
|
||||
public Mode mode
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Mode;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_Mode = value;
|
||||
switch (m_Mode)
|
||||
{
|
||||
case Mode.Treeview:
|
||||
canSort = true;
|
||||
height = DefaultGUI.minimumHeight;
|
||||
break;
|
||||
case Mode.SortedList:
|
||||
canSort = true;
|
||||
height = DefaultGUI.defaultHeight;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void ColumnHeaderClicked(MultiColumnHeaderState.Column column, int columnIndex)
|
||||
{
|
||||
if (mode == Mode.Treeview)
|
||||
{
|
||||
mode = Mode.SortedList;
|
||||
}
|
||||
|
||||
base.ColumnHeaderClicked(column, columnIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7b7689f8140a16040a570611162bd75e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,305 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEditor.IMGUI.Controls;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Assertions;
|
||||
|
||||
namespace HeurekaGames.AssetHunterPRO.BaseTreeviewImpl.DependencyGraph
|
||||
{
|
||||
internal class AH_DepGraphTreeviewWithModel : TreeViewWithTreeModel<AH_DepGraphElement>
|
||||
{
|
||||
const float kRowHeights = 20f;
|
||||
const float kToggleWidth = 18f;
|
||||
|
||||
// All columns
|
||||
enum MyColumns
|
||||
{
|
||||
Icon,
|
||||
Name
|
||||
}
|
||||
|
||||
public enum SortOption
|
||||
{
|
||||
AssetType,
|
||||
Name
|
||||
}
|
||||
|
||||
// Sort options per column
|
||||
SortOption[] m_SortOptions =
|
||||
{
|
||||
SortOption.AssetType,
|
||||
SortOption.Name
|
||||
};
|
||||
|
||||
public static void TreeToList(TreeViewItem root, IList<TreeViewItem> result)
|
||||
{
|
||||
if (root == null)
|
||||
throw new NullReferenceException("root");
|
||||
if (result == null)
|
||||
throw new NullReferenceException("result");
|
||||
|
||||
result.Clear();
|
||||
|
||||
if (root.children == null)
|
||||
return;
|
||||
|
||||
Stack<TreeViewItem> stack = new Stack<TreeViewItem>();
|
||||
for (int i = root.children.Count - 1; i >= 0; i--)
|
||||
stack.Push(root.children[i]);
|
||||
|
||||
while (stack.Count > 0)
|
||||
{
|
||||
TreeViewItem current = stack.Pop();
|
||||
result.Add(current);
|
||||
|
||||
if (current.hasChildren && current.children[0] != null)
|
||||
{
|
||||
for (int i = current.children.Count - 1; i >= 0; i--)
|
||||
{
|
||||
stack.Push(current.children[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public AH_DepGraphTreeviewWithModel(TreeViewState state, MultiColumnHeader multicolumnHeader, TreeModel<AH_DepGraphElement> model) : base(state, multicolumnHeader, model)
|
||||
{
|
||||
Assert.AreEqual(m_SortOptions.Length, Enum.GetValues(typeof(MyColumns)).Length, "Ensure number of sort options are in sync with number of MyColumns enum values");
|
||||
|
||||
// Custom setup
|
||||
rowHeight = kRowHeights;
|
||||
columnIndexForTreeFoldouts = 1;
|
||||
showAlternatingRowBackgrounds = true;
|
||||
showBorder = true;
|
||||
customFoldoutYOffset = (kRowHeights - EditorGUIUtility.singleLineHeight) * 0.5f; // center foldout in the row since we also center content. See RowGUI
|
||||
extraSpaceBeforeIconAndLabel = kToggleWidth;
|
||||
multicolumnHeader.sortingChanged += OnSortingChanged;
|
||||
//IF we want to start expanded one level
|
||||
if (model.root.hasChildren)
|
||||
SetExpanded(model.root.children[0].id, true);
|
||||
|
||||
Reload();
|
||||
}
|
||||
|
||||
protected override void SingleClickedItem(int id)
|
||||
{
|
||||
base.SingleClickedItem(id);
|
||||
var clickedObject = getObjectFromID(id);
|
||||
EditorGUIUtility.PingObject(clickedObject);
|
||||
}
|
||||
|
||||
protected override void DoubleClickedItem(int id)
|
||||
{
|
||||
base.DoubleClickedItem(id);
|
||||
|
||||
var clickedObject = getObjectFromID(id);
|
||||
Selection.activeObject = clickedObject;
|
||||
}
|
||||
|
||||
private UnityEngine.Object getObjectFromID(int id)
|
||||
{
|
||||
var refGraphElement = FindItem(id, rootItem) as TreeViewItem<AH_DepGraphElement>;
|
||||
return AssetDatabase.LoadMainAssetAtPath(refGraphElement.data.RelativePath);
|
||||
}
|
||||
|
||||
protected override bool RequiresSorting()
|
||||
{
|
||||
//Show as list if base requires sorting OR if we chose sortedList
|
||||
return base.RequiresSorting() || ((AH_DepGraphHeader)multiColumnHeader).mode == AH_DepGraphHeader.Mode.SortedList;
|
||||
}
|
||||
|
||||
// Note we We only build the visible rows, only the backend has the full tree information.
|
||||
// The treeview only creates info for the row list.
|
||||
protected override IList<TreeViewItem> BuildRows(TreeViewItem root)
|
||||
{
|
||||
var rows = base.BuildRows(root);
|
||||
SortIfNeeded(root, rows);
|
||||
return rows;
|
||||
}
|
||||
|
||||
void OnSortingChanged(MultiColumnHeader multiColumnHeader)
|
||||
{
|
||||
ModelChanged();
|
||||
SortIfNeeded(rootItem, GetRows());
|
||||
}
|
||||
|
||||
void SortIfNeeded(TreeViewItem root, IList<TreeViewItem> rows)
|
||||
{
|
||||
if (rows.Count <= 1)
|
||||
return;
|
||||
|
||||
if (multiColumnHeader.sortedColumnIndex == -1)
|
||||
{
|
||||
return; // No column to sort for (just use the order the data are in)
|
||||
}
|
||||
|
||||
SortByMultipleColumns();
|
||||
TreeToList(root, rows);
|
||||
|
||||
Repaint();
|
||||
}
|
||||
|
||||
void SortByMultipleColumns()
|
||||
{
|
||||
var sortedColumns = multiColumnHeader.state.sortedColumns;
|
||||
|
||||
if (sortedColumns.Length == 0)
|
||||
return;
|
||||
|
||||
var myTypes = rootItem.children.Cast<TreeViewItem<AH_DepGraphElement>>();
|
||||
var orderedQuery = InitialOrder(myTypes, sortedColumns);
|
||||
for (int i = 1; i < sortedColumns.Length; i++)
|
||||
{
|
||||
SortOption sortOption = m_SortOptions[sortedColumns[i]];
|
||||
bool ascending = multiColumnHeader.IsSortedAscending(sortedColumns[i]);
|
||||
|
||||
switch (sortOption)
|
||||
{
|
||||
case SortOption.Name:
|
||||
orderedQuery = orderedQuery.ThenBy(l => l.data.AssetName, ascending);
|
||||
break;
|
||||
case SortOption.AssetType:
|
||||
orderedQuery = orderedQuery.ThenBy(l => l.data.AssetType, ascending);
|
||||
break;
|
||||
/*case SortOption.Path:
|
||||
orderedQuery = orderedQuery.ThenBy(l => l.data.RelativePath, ascending);
|
||||
break;*/
|
||||
default:
|
||||
Assert.IsTrue(false, "Unhandled enum");
|
||||
break;
|
||||
}
|
||||
}
|
||||
rootItem.children = orderedQuery.Cast<TreeViewItem>().ToList();
|
||||
}
|
||||
|
||||
IOrderedEnumerable<TreeViewItem<AH_DepGraphElement>> InitialOrder(IEnumerable<TreeViewItem<AH_DepGraphElement>> myTypes, int[] history)
|
||||
{
|
||||
SortOption sortOption = m_SortOptions[history[0]];
|
||||
bool ascending = multiColumnHeader.IsSortedAscending(history[0]);
|
||||
switch (sortOption)
|
||||
{
|
||||
case SortOption.Name:
|
||||
return myTypes.Order(l => l.data.AssetName, ascending);
|
||||
case SortOption.AssetType:
|
||||
return myTypes.Order(l => l.data.AssetTypeSerialized, ascending);
|
||||
default:
|
||||
Assert.IsTrue(false, "Unhandled enum");
|
||||
break;
|
||||
}
|
||||
|
||||
// default
|
||||
return myTypes.Order(l => l.data.AssetName, ascending);
|
||||
}
|
||||
|
||||
protected override void RowGUI(RowGUIArgs args)
|
||||
{
|
||||
var item = (TreeViewItem<AH_DepGraphElement>)args.item;
|
||||
|
||||
for (int i = 0; i < args.GetNumVisibleColumns(); ++i)
|
||||
{
|
||||
CellGUI(args.GetCellRect(i), item, (MyColumns)args.GetColumn(i), ref args);
|
||||
}
|
||||
}
|
||||
|
||||
void CellGUI(Rect cellRect, TreeViewItem<AH_DepGraphElement> item, MyColumns column, ref RowGUIArgs args)
|
||||
{
|
||||
// Center cell rect vertically (makes it easier to place controls, icons etc in the cells)
|
||||
CenterRectUsingSingleLineHeight(ref cellRect);
|
||||
AH_DepGraphElement element = (AH_DepGraphElement)item.data;
|
||||
|
||||
switch (column)
|
||||
{
|
||||
case MyColumns.Icon:
|
||||
{
|
||||
if (item.data.AssetType != null)
|
||||
GUI.DrawTexture(cellRect, item.data.Icon, ScaleMode.ScaleToFit);
|
||||
}
|
||||
break;
|
||||
case MyColumns.Name:
|
||||
{
|
||||
Rect nameRect = cellRect;
|
||||
nameRect.x += GetContentIndent(item);
|
||||
DefaultGUI.Label(nameRect, item.data.AssetName, args.selected, args.focused);
|
||||
}
|
||||
break;
|
||||
/*case MyColumns.Path:
|
||||
{
|
||||
Rect nameRect = cellRect;
|
||||
nameRect.x += GetContentIndent(item);
|
||||
DefaultGUI.Label(nameRect, item.data.RelativePath, args.selected, args.focused);
|
||||
}
|
||||
break;*/
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool CanMultiSelect(TreeViewItem item)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public static MultiColumnHeaderState CreateDefaultMultiColumnHeaderState(float treeViewWidth)
|
||||
{
|
||||
var columns = new[]
|
||||
{
|
||||
new MultiColumnHeaderState.Column
|
||||
{
|
||||
headerContent = new GUIContent(EditorGUIUtility.FindTexture("FilterByType"), "Type of asset"),
|
||||
contextMenuText = "Type",
|
||||
headerTextAlignment = TextAlignment.Center,
|
||||
sortedAscending = true,
|
||||
sortingArrowAlignment = TextAlignment.Right,
|
||||
width = 30,
|
||||
minWidth = 30,
|
||||
maxWidth = 30,
|
||||
autoResize = false,
|
||||
allowToggleVisibility = true
|
||||
},
|
||||
new MultiColumnHeaderState.Column
|
||||
{
|
||||
headerContent = new GUIContent("Name"),
|
||||
headerTextAlignment = TextAlignment.Left,
|
||||
sortedAscending = true,
|
||||
sortingArrowAlignment = TextAlignment.Center,
|
||||
//width = 320,
|
||||
minWidth = 200,
|
||||
autoResize = true,
|
||||
allowToggleVisibility = false
|
||||
}
|
||||
};
|
||||
|
||||
Assert.AreEqual(columns.Length, Enum.GetValues(typeof(MyColumns)).Length, "Number of columns should match number of enum values: You probably forgot to update one of them.");
|
||||
|
||||
var state = new MultiColumnHeaderState(columns);
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
static class MyExtensionMethods
|
||||
{
|
||||
public static IOrderedEnumerable<T> Order<T, TKey>(this IEnumerable<T> source, Func<T, TKey> selector, bool ascending)
|
||||
{
|
||||
if (ascending)
|
||||
{
|
||||
return source.OrderBy(selector);
|
||||
}
|
||||
else
|
||||
{
|
||||
return source.OrderByDescending(selector);
|
||||
}
|
||||
}
|
||||
|
||||
public static IOrderedEnumerable<T> ThenBy<T, TKey>(this IOrderedEnumerable<T> source, Func<T, TKey> selector, bool ascending)
|
||||
{
|
||||
if (ascending)
|
||||
{
|
||||
return source.ThenBy(selector);
|
||||
}
|
||||
else
|
||||
{
|
||||
return source.ThenByDescending(selector);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 897092982376e0c4886fc38c96e04090
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user