dbrizov / NaughtyAttributes

Attribute Extensions for Unity
MIT License
4.47k stars 463 forks source link

Updated NaughtInspector to be Open to Extension for Inheritors #365

Closed DevinWeidinger closed 1 year ago

DevinWeidinger commented 1 year ago

These changes allow a user to inherit from NaughtyInspector and extend the functionality without needing to modify read-only source.

Example use case

    [CanEditMultipleObjects]
    [CustomEditor(typeof(Object), true, isFallback = false)]
    public class InspectorNoteEditor : NaughtyInspector
    {
        private bool isShowingNotes = true;
        private const string buttonStatePrefKey = "InspectorNoteEditor.isShowingNotes";

        protected override void OnEnable()
        {
            GetNaughtyReferences();
            isShowingNotes = EditorPrefs.GetBool(buttonStatePrefKey, true);
        }

        public override void OnInspectorGUI()
        {
            var notesAttributes = (InspectorNotesAttribute[])Attribute.GetCustomAttributes(target.GetType(), typeof(InspectorNotesAttribute));
            if (notesAttributes.Length != 0) 
                DrawNotes(notesAttributes);

            DrawNaughtyInspectorGUI();
        }

        private void DrawNotes(IEnumerable<InspectorNotesAttribute> notesAttributes)
        {
            var buttonContent = EditorGUIUtility.TrTextContentWithIcon(!isShowingNotes ? "Click to show notes" : "",
                "d_UnityEditor.InspectorWindow@2x");
            GUILayout.BeginHorizontal(isShowingNotes ? EditorStyles.helpBox : EditorStyles.toolbarButton);
            if (GUILayout.Button(buttonContent,
                    isShowingNotes ? EditorStyles.selectionRect : EditorStyles.centeredGreyMiniLabel, GUILayout.MinWidth(40),
                    GUILayout.ExpandHeight(true), GUILayout.ExpandWidth(!isShowingNotes)))
            {
                isShowingNotes = !isShowingNotes;
                EditorPrefs.SetBool(buttonStatePrefKey, isShowingNotes);
            }

            if (isShowingNotes)
            {
                GUILayout.BeginVertical();
                foreach (var noteAttribute in notesAttributes)
                {
                    GUI.backgroundColor = noteAttribute.messageType switch
                    {
                        InspectorNotesAttribute.MessageType.None => Color.black,
                        InspectorNotesAttribute.MessageType.Info => Color.cyan,
                        InspectorNotesAttribute.MessageType.Warning => Color.yellow,
                        InspectorNotesAttribute.MessageType.Error => Color.red,
                        _ => GUI.backgroundColor
                    };

                    EditorGUILayout.HelpBox(noteAttribute.notes, (MessageType)(int)noteAttribute.messageType);
                    if (!string.IsNullOrEmpty(noteAttribute.linkURL))
                    {
                        var buttonName = string.IsNullOrEmpty(noteAttribute.linkDisplayName)
                            ? noteAttribute.linkURL
                            : noteAttribute.linkDisplayName;
                        if (GUILayout.Button(buttonName, EditorStyles.miniButton))
                            Application.OpenURL(noteAttribute.linkURL);
                    }
                }

                GUILayout.EndVertical();
                GUI.backgroundColor = Color.white;
            }

            GUILayout.EndHorizontal();
        }
    }

Another example Override DrawSerializedProperties to skip m_Scripts property