You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

156 lines
5.4 KiB
C#

1 year ago
using System;
using System.Collections.Generic;
using UnityEditor.IMGUI.Controls;
using UnityEngine;
using UnityEngine.Timeline;
namespace UnityEditor.Timeline.Signals
{
class SignalReceiverTreeView : TreeView
{
public bool dirty { private get; set; }
SerializedProperty signals { get; set; }
SerializedProperty events { get; set; }
readonly SignalReceiver m_Target;
const float k_VerticalPadding = 5;
const float k_HorizontalPadding = 5;
public SignalReceiverTreeView(TreeViewState state, MultiColumnHeader multiColumnHeader, SignalReceiver receiver, SerializedObject serializedObject)
: base(state, multiColumnHeader)
{
m_Target = receiver;
useScrollView = true;
SetSerializedProperties(serializedObject);
getNewSelectionOverride = (item, selection, shift) => new List<int>(); // Disable Selection
}
SignalAsset signalAssetContext { get; set; }
public bool readonlySignals { get; set; }
public void SetSignalContext(SignalAsset assetContext = null)
{
signalAssetContext = assetContext;
dirty = true;
}
void SetSerializedProperties(SerializedObject serializedObject)
{
signals = SignalReceiverUtility.FindSignalsProperty(serializedObject);
events = SignalReceiverUtility.FindEventsProperty(serializedObject);
Reload();
}
public void Draw()
{
var rect = EditorGUILayout.GetControlRect(true, GetTotalHeight());
OnGUI(rect);
}
public void RefreshIfDirty()
{
var signalsListSizeHasChanged = signals.arraySize != GetRows().Count;
if (dirty || signalsListSizeHasChanged)
Reload();
dirty = false;
}
public static MultiColumnHeaderState.Column[] GetColumns()
{
return new[]
{
new MultiColumnHeaderState.Column
{
headerContent = L10n.TextContent("Signal"),
contextMenuText = "",
headerTextAlignment = TextAlignment.Center,
width = 50, minWidth = 50,
autoResize = true,
allowToggleVisibility = false,
canSort = false
},
new MultiColumnHeaderState.Column
{
headerContent = L10n.TextContent("Reaction"),
contextMenuText = "",
headerTextAlignment = TextAlignment.Center,
width = 120, minWidth = 120,
autoResize = true,
allowToggleVisibility = false,
canSort = false
}
};
}
protected override TreeViewItem BuildRoot()
{
var root = new TreeViewItem(-1, -1) { children = new List<TreeViewItem>() };
var matchingId = signalAssetContext != null && readonlySignals ? FindIdForSignal(signals, signalAssetContext) : -1;
if (matchingId >= 0)
AddItem(root, matchingId);
for (var i = 0; i < signals.arraySize; ++i)
{
if (i == matchingId) continue;
AddItem(root, i, !readonlySignals);
}
return root;
}
protected override void RowGUI(RowGUIArgs args)
{
var item = (SignalReceiverItem)args.item;
for (var i = 0; i < args.GetNumVisibleColumns(); ++i)
{
var rect = args.GetCellRect(i);
rect.y += k_VerticalPadding;
item.Draw(rect, args.GetColumn(i), args.row, k_HorizontalPadding, m_Target);
}
}
protected override float GetCustomRowHeight(int row, TreeViewItem treeItem)
{
var item = treeItem as SignalReceiverItem;
return item.GetHeight() + k_VerticalPadding;
}
void AddItem(TreeViewItem root, int id, bool enabled = true)
{
var signal = signals.GetArrayElementAtIndex(id);
var evt = events.GetArrayElementAtIndex(id);
root.children.Add(new SignalReceiverItem(signal, evt, id, readonlySignals, enabled, this));
}
float GetTotalHeight()
{
var height = 0.0f;
foreach (var item in GetRows())
{
var signalListItem = item as SignalReceiverItem;
height += signalListItem.GetHeight() + k_VerticalPadding;
}
var scrollbarPadding = showingHorizontalScrollBar ? GUI.skin.horizontalScrollbar.fixedHeight : k_VerticalPadding;
return height + multiColumnHeader.height + scrollbarPadding;
}
static int FindIdForSignal(SerializedProperty signals, SignalAsset signalToFind)
{
for (var i = 0; i < signals.arraySize; ++i)
{
//signal in the receiver that matches the current signal asset will be displayed first
var serializedProperty = signals.GetArrayElementAtIndex(i);
var signalReferenceValue = serializedProperty.objectReferenceValue;
var signalToFindRefValue = signalToFind;
if (signalReferenceValue != null && signalReferenceValue == signalToFindRefValue)
return i;
}
return -1;
}
}
}