Only show the logo once per inspector pane

This commit is contained in:
bd_ 2022-11-10 20:30:10 -08:00
parent f284ab7df2
commit b7e4409d6b
10 changed files with 148 additions and 40 deletions

View File

@ -12,7 +12,7 @@ using Debug = System.Diagnostics.Debug;
namespace net.fushizen.modular_avatar.core.editor
{
[CustomEditor(typeof(ModularAvatarParameters))]
public class AvatarParametersEditor : Editor
internal class AvatarParametersEditor : MAEditorBase
{
/**********************************************************************
* | Field name | Remap to / config |
@ -410,11 +410,8 @@ namespace net.fushizen.modular_avatar.core.editor
if (!_devMode) EditorGUI.LabelField(rightHalf, G("params.remapto"));
}
public override void OnInspectorGUI()
protected override void OnInnerInspectorGUI()
{
LogoDisplay.DisplayLogo();
InspectorCommon.DisplayOutOfAvatarWarning(targets);
EditorGUI.BeginChangeCheck();
_devMode = EditorGUILayout.Toggle(G("params.devmode"), _devMode);
if (EditorGUI.EndChangeCheck() || _reorderableList == null || _needsRebuild) SetupList();

View File

@ -14,7 +14,7 @@ namespace net.fushizen.modular_avatar.core.editor
{
[CustomEditor(typeof(ModularAvatarBlendshapeSync))]
[CanEditMultipleObjects]
internal class BlendshapeSyncEditor : Editor
internal class BlendshapeSyncEditor : MAEditorBase
{
private static FieldInfo f_m_SerializedObject;
private BlendshapeSelectWindow _window;
@ -242,12 +242,8 @@ namespace net.fushizen.modular_avatar.core.editor
return selections;
}
public override void OnInspectorGUI()
protected override void OnInnerInspectorGUI()
{
LogoDisplay.DisplayLogo();
InspectorCommon.DisplayOutOfAvatarWarning(targets);
serializedObject.Update();
_list.DoLayoutList();

View File

@ -11,7 +11,7 @@ namespace net.fushizen.modular_avatar.core.editor
[CustomEditor(typeof(ModularAvatarBoneProxy))]
[CanEditMultipleObjects]
internal class BoneProxyEditor : Editor
internal class BoneProxyEditor : MAEditorBase
{
private bool foldout = false;
@ -26,11 +26,8 @@ namespace net.fushizen.modular_avatar.core.editor
}
}
public override void OnInspectorGUI()
protected override void OnInnerInspectorGUI()
{
LogoDisplay.DisplayLogo();
InspectorCommon.DisplayOutOfAvatarWarning(targets);
GameObject parentAvatar = null;
bool suppressTarget = false;

View File

@ -5,7 +5,7 @@ using UnityEngine;
namespace net.fushizen.modular_avatar.core.editor
{
[CustomEditor(typeof(ModularAvatarVisibleHeadAccessory))]
public class FirstPersonVisibleEditor : Editor
internal class FirstPersonVisibleEditor : MAEditorBase
{
private VisibleHeadAccessoryProcessor _processor;
@ -17,13 +17,10 @@ namespace net.fushizen.modular_avatar.core.editor
if (avatar != null) _processor = new VisibleHeadAccessoryProcessor(avatar);
}
public override void OnInspectorGUI()
protected override void OnInnerInspectorGUI()
{
var target = (ModularAvatarVisibleHeadAccessory) this.target;
LogoDisplay.DisplayLogo();
InspectorCommon.DisplayOutOfAvatarWarning(targets);
#if UNITY_ANDROID
EditorGUILayout.HelpBox(Localization.S("fpvisible.quest"), MessageType.Warning);

View File

@ -12,7 +12,7 @@ namespace net.fushizen.modular_avatar.core.editor
private static GUIStyle STYLE => new GUIStyle()
{
fixedHeight = TARGET_HEIGHT,
fixedWidth = TARGET_HEIGHT * (LOGO_ASSET.width / (float)LOGO_ASSET.height),
fixedWidth = TARGET_HEIGHT * (LOGO_ASSET.width / (float) LOGO_ASSET.height),
stretchHeight = false,
stretchWidth = false,
imagePosition = ImagePosition.ImageOnly
@ -21,7 +21,7 @@ namespace net.fushizen.modular_avatar.core.editor
static LogoDisplay()
{
var placeholderPath = AssetDatabase.GUIDToAssetPath("2a2bb4e0b8e906743890ef10c778e65c");
var path = placeholderPath.Substring(0, placeholderPath.LastIndexOf("/", StringComparison.Ordinal));
path += "/ma_logo.png";
@ -35,10 +35,11 @@ namespace net.fushizen.modular_avatar.core.editor
if (LOGO_ASSET == null) return;
var height = TARGET_HEIGHT;
var width = (height / (float)LOGO_ASSET.height) * LOGO_ASSET.width;
var width = (height / (float) LOGO_ASSET.height) * LOGO_ASSET.width;
var rect = GUILayoutUtility.GetRect(width, height);
GUI.DrawTexture(rect, LOGO_ASSET, ScaleMode.ScaleToFit);
GUILayoutUtility.GetRect(width, EditorStyles.label.lineHeight / 2);
}
}
}

View File

@ -0,0 +1,125 @@
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine.UIElements;
namespace net.fushizen.modular_avatar.core.editor
{
// This class performs common setup for Modular Avatar editors, including ensuring that only one instance of the\
// logo is rendered per container.
internal abstract class MAEditorBase : Editor
{
private static Dictionary<VisualElement, MAVisualElement>
_logoDisplayNode = new Dictionary<VisualElement, MAVisualElement>();
private static void Cleanup()
{
_logoDisplayNode.Clear();
EditorApplication.update -= Cleanup;
}
private static MAVisualElement GetCachedLogoDisplayNode(VisualElement start)
{
while (start?.parent != null && start.GetType() != typeof(InspectorElement))
{
start = start.parent;
}
// Next one up is an EditorElement, followed by the container of all Editors
var container = start?.parent?.parent;
if (container == null) return null;
if (_logoDisplayNode.TryGetValue(container, out var elem)) return elem;
var node = FindLogoDisplayNode(container);
if (node != null) _logoDisplayNode[container] = node;
EditorApplication.update += Cleanup;
return node;
}
private static MAVisualElement FindLogoDisplayNode(VisualElement container)
{
// Now walk down to find the MAVisualElements. We only walk one level past an InspectorElement to avoid
// descending too deep into madness.
List<MAVisualElement> elements = new List<MAVisualElement>();
WalkTree(container);
return elements.FirstOrDefault(e => e.resolvedStyle.visibility == Visibility.Visible);
void WalkTree(VisualElement visualElement)
{
if (visualElement.resolvedStyle.visibility == Visibility.Hidden ||
visualElement.resolvedStyle.height < 0.5) return;
var isInspector = visualElement.GetType() == typeof(InspectorElement);
foreach (var child in visualElement.Children())
{
if (child is MAVisualElement maChild)
{
elements.Add(maChild);
return;
}
else if (!isInspector)
{
WalkTree(child);
}
}
}
}
private class MAVisualElement : VisualElement
{
}
private MAVisualElement _visualElement;
private bool _suppressOnceDefaultMargins;
protected virtual VisualElement CreateInnerInspectorGUI()
{
var throwaway = new InspectorElement();
MethodInfo m = typeof(InspectorElement).GetMethod("CreateIMGUIInspectorFromEditor",
BindingFlags.NonPublic | BindingFlags.Instance);
return m.Invoke(throwaway, new object[] {serializedObject, this, false}) as VisualElement;
}
public sealed override VisualElement CreateInspectorGUI()
{
// CreateInspectorElementFromEditor does a bunch of extra setup that makes our inspector look a little bit
// nicer. In particular, the label column won't auto-size if we just use IMGUIElement, for some reason
var inner = CreateInnerInspectorGUI();
_visualElement = new MAVisualElement();
_visualElement.Add(inner);
_suppressOnceDefaultMargins = true;
return _visualElement;
}
public override bool UseDefaultMargins()
{
var useDefaults = !_suppressOnceDefaultMargins;
_suppressOnceDefaultMargins = false;
return useDefaults;
}
public sealed override void OnInspectorGUI()
{
if (GetCachedLogoDisplayNode(_visualElement) == _visualElement)
{
LogoDisplay.DisplayLogo();
}
InspectorCommon.DisplayOutOfAvatarWarning(targets);
OnInnerInspectorGUI();
}
protected abstract void OnInnerInspectorGUI();
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 5abd585ebadf4f71931ecb3328bf10e8
timeCreated: 1668058504

View File

@ -10,7 +10,7 @@ namespace net.fushizen.modular_avatar.core.editor
{
[CustomEditor(typeof(ModularAvatarMenuInstaller))]
[CanEditMultipleObjects]
public class MenuInstallerEditor : Editor
internal class MenuInstallerEditor : MAEditorBase
{
private ModularAvatarMenuInstaller _installer;
private Editor _innerMenuEditor;
@ -47,11 +47,8 @@ namespace net.fushizen.modular_avatar.core.editor
}
}
public override void OnInspectorGUI()
protected override void OnInnerInspectorGUI()
{
LogoDisplay.DisplayLogo();
InspectorCommon.DisplayOutOfAvatarWarning(targets);
SetupMenuEditor();
var installTo = serializedObject.FindProperty(nameof(ModularAvatarMenuInstaller.installTargetMenu));

View File

@ -1,5 +1,6 @@
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
using static net.fushizen.modular_avatar.core.editor.Localization;
namespace net.fushizen.modular_avatar.core.editor
@ -27,7 +28,7 @@ namespace net.fushizen.modular_avatar.core.editor
}
[CustomEditor(typeof(ModularAvatarMergeAnimator))]
class MergeAnimationEditor : Editor
class MergeAnimationEditor : MAEditorBase
{
private SerializedProperty prop_animator,
prop_layerType,
@ -46,11 +47,8 @@ namespace net.fushizen.modular_avatar.core.editor
serializedObject.FindProperty(nameof(ModularAvatarMergeAnimator.matchAvatarWriteDefaults));
}
public override void OnInspectorGUI()
protected override void OnInnerInspectorGUI()
{
LogoDisplay.DisplayLogo();
InspectorCommon.DisplayOutOfAvatarWarning(targets);
serializedObject.Update();
EditorGUILayout.PropertyField(prop_animator, G("merge_animator.animator"));

View File

@ -6,7 +6,7 @@ using static net.fushizen.modular_avatar.core.editor.Localization;
namespace net.fushizen.modular_avatar.core.editor
{
[CustomEditor(typeof(ModularAvatarMergeArmature))]
public class MergeArmatureEditor : Editor
internal class MergeArmatureEditor : MAEditorBase
{
private SerializedProperty prop_mergeTarget, prop_prefix, prop_suffix, prop_locked;
@ -30,11 +30,8 @@ namespace net.fushizen.modular_avatar.core.editor
serializedObject.ApplyModifiedProperties();
}
public override void OnInspectorGUI()
protected override void OnInnerInspectorGUI()
{
LogoDisplay.DisplayLogo();
InspectorCommon.DisplayOutOfAvatarWarning(targets);
var target = (ModularAvatarMergeArmature) this.target;
var priorMergeTarget = target.mergeTargetObject;