holopy3/Assets/Klak/Spout/Editor/SpoutReceiverEditor.cs
2020-12-10 15:25:12 +01:00

118 lines
3.9 KiB
C#

// KlakSpout - Spout video frame sharing plugin for Unity
// https://github.com/keijiro/KlakSpout
using UnityEngine;
using UnityEditor;
namespace Klak.Spout
{
[CanEditMultipleObjects]
[CustomEditor(typeof(SpoutReceiver))]
sealed class SpoutReceiverEditor : Editor
{
SerializedProperty _sourceName;
SerializedProperty _targetTexture;
SerializedProperty _targetRenderer;
SerializedProperty _targetMaterialProperty;
static double _prevRepaintTime;
static class Labels
{
public static readonly GUIContent Property = new GUIContent("Property");
public static readonly GUIContent Select = new GUIContent("Select");
}
// Request receiver reconnection.
void RequestReconnect()
{
foreach (SpoutReceiver receiver in targets) receiver.RequestReconnect();
}
// Check and request repaint with 0.1s interval.
void CheckRepaint()
{
var time = EditorApplication.timeSinceStartup;
if (time - _prevRepaintTime < 0.1) return;
UnityEditorInternal.InternalEditorUtility.RepaintAllViews();
_prevRepaintTime = time;
}
// Create and show the source name dropdown.
void ShowSourceNameDropdown(Rect rect)
{
var menu = new GenericMenu();
var count = PluginEntry.ScanSharedObjects();
for (var i = 0; i < count; i++)
{
var name = PluginEntry.GetSharedObjectNameString(i);
menu.AddItem(new GUIContent(name), false, OnSelectSource, name);
}
menu.DropDown(rect);
}
// Source name selection callback
void OnSelectSource(object name)
{
serializedObject.Update();
_sourceName.stringValue = (string)name;
serializedObject.ApplyModifiedProperties();
RequestReconnect();
}
void OnEnable()
{
_sourceName = serializedObject.FindProperty("_sourceName");
_targetTexture = serializedObject.FindProperty("_targetTexture");
_targetRenderer = serializedObject.FindProperty("_targetRenderer");
_targetMaterialProperty = serializedObject.FindProperty("_targetMaterialProperty");
EditorApplication.update += CheckRepaint;
}
void OnDisable()
{
EditorApplication.update -= CheckRepaint;
}
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.BeginHorizontal();
// Source name text field
EditorGUI.BeginChangeCheck();
EditorGUILayout.DelayedTextField(_sourceName);
if (EditorGUI.EndChangeCheck()) RequestReconnect();
// Source name dropdown
var rect = EditorGUILayout.GetControlRect(false, GUILayout.Width(60));
if (EditorGUI.DropdownButton(rect, Labels.Select, FocusType.Keyboard))
ShowSourceNameDropdown(rect);
EditorGUILayout.EndHorizontal();
// Target texture/renderer
EditorGUILayout.PropertyField(_targetTexture);
EditorGUILayout.PropertyField(_targetRenderer);
EditorGUI.indentLevel++;
if (_targetRenderer.hasMultipleDifferentValues)
{
// Multiple renderers selected: Show a simple text field.
EditorGUILayout.PropertyField(_targetMaterialProperty, Labels.Property);
}
else if (_targetRenderer.objectReferenceValue != null)
{
// Single renderer: Show the material property selection dropdown.
MaterialPropertySelector.DropdownList(_targetRenderer, _targetMaterialProperty);
}
EditorGUI.indentLevel--;
serializedObject.ApplyModifiedProperties();
}
}
}