using System.Collections.Generic; using UnityEditor.Experimental.GraphView; using UnityEngine; using UnityEngine.UIElements; using UnityEditor.ShaderGraph.Drawing.Interfaces; namespace UnityEditor.ShaderGraph.Drawing { class StickyNodeChangeEvent : EventBase { public static StickyNodeChangeEvent GetPooled(StickyNote target, Change change) { var evt = GetPooled(); evt.target = target; evt.change = change; return evt; } public enum Change { title, contents, theme, textSize, } public Change change { get; protected set; } } class StickyNote : GraphElement, ISGResizable { GraphData m_Graph; public new StickyNoteData userData { get => (StickyNoteData)base.userData; set => base.userData = value; } public enum Theme { Classic, Black, Orange, Green, Blue, Red, Purple, Teal } Theme m_Theme = Theme.Classic; public Theme theme { get { return m_Theme; } set { if (m_Theme != value) { m_Theme = value; UpdateThemeClasses(); } } } public enum TextSize { Small, Medium, Large, Huge } TextSize m_TextSize = TextSize.Medium; public TextSize textSize { get { return m_TextSize; } set { if (m_TextSize != value) { m_TextSize = value; UpdateSizeClasses(); } } } public virtual void OnStartResize() { } public virtual void OnResized() { userData.position = new Rect(resolvedStyle.left, resolvedStyle.top, style.width.value.value, style.height.value.value); } public bool CanResizePastParentBounds() { return true; } Vector2 AllExtraSpace(VisualElement element) { return new Vector2( element.resolvedStyle.marginLeft + element.resolvedStyle.marginRight + element.resolvedStyle.paddingLeft + element.resolvedStyle.paddingRight + element.resolvedStyle.borderRightWidth + element.resolvedStyle.borderLeftWidth, element.resolvedStyle.marginTop + element.resolvedStyle.marginBottom + element.resolvedStyle.paddingTop + element.resolvedStyle.paddingBottom + element.resolvedStyle.borderBottomWidth + element.resolvedStyle.borderTopWidth ); } void OnFitToText(DropdownMenuAction a) { FitText(false); } public void FitText(bool onlyIfSmaller) { Vector2 preferredTitleSize = Vector2.zero; if (!string.IsNullOrEmpty(m_Title.text)) preferredTitleSize = m_Title.MeasureTextSize(m_Title.text, 0, MeasureMode.Undefined, 0, MeasureMode.Undefined); // This is the size of the string with the current title font and such preferredTitleSize += AllExtraSpace(m_Title); preferredTitleSize.x += m_Title.ChangeCoordinatesTo(this, Vector2.zero).x + resolvedStyle.width - m_Title.ChangeCoordinatesTo(this, new Vector2(m_Title.layout.width, 0)).x; Vector2 preferredContentsSizeOneLine = m_Contents.MeasureTextSize(m_Contents.text, 0, MeasureMode.Undefined, 0, MeasureMode.Undefined); Vector2 contentExtraSpace = AllExtraSpace(m_Contents); preferredContentsSizeOneLine += contentExtraSpace; Vector2 extraSpace = new Vector2(resolvedStyle.width, resolvedStyle.height) - m_Contents.ChangeCoordinatesTo(this, new Vector2(m_Contents.layout.width, m_Contents.layout.height)); extraSpace += m_Title.ChangeCoordinatesTo(this, Vector2.zero); preferredContentsSizeOneLine += extraSpace; float width = 0; float height = 0; // The content in one line is smaller than the current width. // Set the width to fit both title and content. // Set the height to have only one line in the content if (preferredContentsSizeOneLine.x < Mathf.Max(preferredTitleSize.x, resolvedStyle.width)) { width = Mathf.Max(preferredContentsSizeOneLine.x, preferredTitleSize.x); height = preferredContentsSizeOneLine.y + preferredTitleSize.y; } else // The width is not enough for the content: keep the width or use the title width if bigger. { width = Mathf.Max(preferredTitleSize.x + extraSpace.x, resolvedStyle.width); float contextWidth = width - extraSpace.x - contentExtraSpace.x; Vector2 preferredContentsSize = m_Contents.MeasureTextSize(m_Contents.text, contextWidth, MeasureMode.Exactly, 0, MeasureMode.Undefined); preferredContentsSize += contentExtraSpace; height = preferredTitleSize.y + preferredContentsSize.y + extraSpace.y; } if (!onlyIfSmaller || resolvedStyle.width < width) style.width = width; if (!onlyIfSmaller || resolvedStyle.height < height) style.height = height; OnResized(); } void UpdateThemeClasses() { foreach (Theme value in System.Enum.GetValues(typeof(Theme))) { if (m_Theme != value) { RemoveFromClassList("theme-" + value.ToString().ToLower()); } else { AddToClassList("theme-" + value.ToString().ToLower()); } } } void UpdateSizeClasses() { foreach (TextSize value in System.Enum.GetValues(typeof(TextSize))) { if (m_TextSize != value) { RemoveFromClassList("size-" + value.ToString().ToLower()); } else { AddToClassList("size-" + value.ToString().ToLower()); } } } public static readonly Vector2 defaultSize = new Vector2(200, 160); public StickyNote(Rect position, GraphData graph) : this("UXML/StickyNote", position, graph) { styleSheets.Add(Resources.Load("Selectable")); styleSheets.Add(Resources.Load("StickyNote")); RegisterCallback(OnAttachToPanel); } public string displayName => $"{m_Title.text} (Sticky Note)"; public StickyNote(string uiFile, Rect position, GraphData graph) { m_Graph = graph; var tpl = Resources.Load(uiFile); tpl.CloneTree(this); capabilities = Capabilities.Movable | Capabilities.Deletable | Capabilities.Ascendable | Capabilities.Selectable | Capabilities.Copiable | Capabilities.Groupable; m_Title = this.Q