// https://github.com/ShadowIgnition/Unity-Note-Attribute using System; using UnityEditor; using UnityEngine; namespace Nullframes.Intrigues { [CustomPropertyDrawer(typeof(NoteAttribute))] public class NoteDrawer : DecoratorDrawer { // /// Overrides OnGUI() to draw the note attribute in the Inspector. /// /// The position of the drawer in the Inspector. public override void OnGUI(Rect position) { CachePreviewHeight(Attribute.Description, position.width); if (Math.Abs(m_Height - m_ScrollViewHeight) > double.Epsilon) { Rect scrollArea = GetRect(position, true); Rect content = scrollArea; // Adjust xMax to account for vertical scrollbar content.xMax -= 14; using (var scrollScope = new GUI.ScrollViewScope(position, scrollPos, content)) { scrollPos = scrollScope.scrollPosition; GUI.Box(content, Attribute.Description, GetNoteStyle()); } } else { GUI.Box(GetRect(position, false), Attribute.Description, GetNoteStyle()); } } /// /// Gets the height of the drawer. /// /// The height of the drawer. public override float GetHeight() { return m_Height; } /// /// Gets the cached note style. /// /// The GUIStyle for the note. static GUIStyle GetNoteStyle() { if (Style == null) { GUIStyle style = GUI.skin.box; style.padding = new RectOffset(4, 16, 4, 4); style.normal.background = Texture2D.grayTexture; style.wordWrap = true; style.alignment = TextAnchor.UpperLeft; style.richText = true; Style = style; } return Style; } /// /// Caches the height of the note text area. /// /// The note string. /// The width of the text area. void CachePreviewHeight(string note, float width) { if (Attribute.LineHeight > 0) { // If a custom line height is specified, use it m_Height = GetPaddedLineHeight(Attribute.LineHeight); m_ScrollViewHeight = m_Height; } else { // Calculate the height of the text area m_Height = GUI.skin.textArea.CalcHeight(new GUIContent(note), width) + (GUI.skin.textArea.lineHeight / 2); // Store the unclamped height, so we can use for a scroll view later if needed m_ScrollViewHeight = m_Height; // Clamp the height within the specified range (Don't want to be able to make the editor preview too big) m_Height = Mathf.Clamp(m_Height, GetPaddedLineHeight(AUTO_MIN_HEIGHT), GetPaddedLineHeight(AUTO_MAX_HEIGHT)); } } /// /// Gets the rect for drawing the note area. /// /// The position of the drawer in the Inspector. /// Flag indicating if the drawer is part of a scroll view. /// The rect for drawing the note area. Rect GetRect(Rect position, bool isScrollView) { return new Rect(position.x, position.y, position.width, isScrollView ? m_ScrollViewHeight : m_Height); } /// /// Gets the padded line height based on the number of lines. /// /// The number of lines. /// The padded line height. float GetPaddedLineHeight(uint lineCount) { return (GUI.skin.textArea.lineHeight * lineCount) + (GUI.skin.textArea.lineHeight / 2); } /// /// Gets the associated with this drawer. /// NoteAttribute Attribute { get { return attribute as NoteAttribute; } } static GUIStyle Style; Vector2 scrollPos; // Current Scroll position float m_Height; // Height of the note text area float m_ScrollViewHeight; // Height of the note text area const uint AUTO_MAX_HEIGHT = 5; // Maximum number of lines for the text area const uint AUTO_MIN_HEIGHT = 2; // Minimum number of lines for the text area } }