using UnityEditor; using UnityEngine; namespace Unity.VisualScripting { public sealed class SidebarPanel { public SidebarPanel(ISidebarPanelContent content) { Ensure.That(nameof(content)).IsNotNull(content); this.content = content; } [DoNotSerialize] public Sidebars sidebars { get; set; } [DoNotSerialize] public Sidebar sidebar => sidebars[anchor]; [DoNotSerialize] public bool enabled { get; private set; } [Serialize] private object controlHint; [Serialize] public float height { get; set; } [Serialize] public SidebarAnchor anchor { get; set; } [Serialize] private Vector2 scroll; [Serialize] public int order { get; set; } [DoNotSerialize] private EventWrapper e; [DoNotSerialize] private ISidebarPanelContent _content; [DoNotSerialize] public ISidebarPanelContent content { get => _content; private set { _content = value; controlHint = content?.sidebarControlHint; e = new EventWrapper(controlHint); enabled = content != null; } } [DoNotSerialize] private bool isResizing; public bool TryAssociate(ISidebarPanelContent content) { if (content.sidebarControlHint == controlHint) { this.content = content; return true; } else { return false; } } public void Disable() { _content = null; enabled = false; } public void OnGUI(Rect position, ref float y, float? heightOverride = null) { if (content == null) { var message = "Missing sidebar content."; var messageType = MessageType.Warning; var messageHeight = LudiqGUIUtility.GetHelpBoxHeight(message, messageType, position.width); EditorGUI.HelpBox(position.VerticalSection(ref y, messageHeight), message, messageType); return; } var height = heightOverride ?? this.height; var panelPosition = new Rect ( position.x, y, position.width, height ); var titlePosition = new Rect ( position.x, y, position.width, Styles.title.fixedHeight ); if (e.IsRepaint) { Styles.title.Draw(titlePosition, content.titleContent, false, false, false, false); } var orderSpinnerPosition = new Rect ( position.xMax - Styles.orderSpinnerWidth, y, Styles.orderSpinnerWidth, titlePosition.height ); sidebar.OrderSpinner(orderSpinnerPosition, this); var anchorButtonPosition = new Rect ( orderSpinnerPosition.x - Styles.anchorButtonWidth, y, Styles.anchorButtonWidth, titlePosition.height ); DrawAnchorButton(anchorButtonPosition); y += titlePosition.height; var panelContentPosition = new Rect ( position.x, y, position.width, height - titlePosition.height ); if (e.IsRepaint) { Styles.background.Draw(panelContentPosition, false, false, false, false); } LudiqGUIUtility.BeginScrollablePanel(panelContentPosition, content.GetHeight, out var panelInnerPosition, ref scroll, new RectOffset(1, 1, 0, 0)); content.OnGUI(panelInnerPosition); LudiqGUIUtility.EndScrollablePanel(); y += panelContentPosition.height; if (heightOverride == null) { HandleResize(panelPosition); } } private void DrawAnchorButton(Rect position) { SidebarAnchor destination; EditorTexture icon; switch (anchor) { case SidebarAnchor.Left: destination = SidebarAnchor.Right; icon = BoltCore.Icons.sidebarAnchorRight; break; case SidebarAnchor.Right: destination = SidebarAnchor.Left; icon = BoltCore.Icons.sidebarAnchorLeft; break; default: throw new UnexpectedEnumValueException(anchor); } if (GUI.Button(position, icon?.Single(), LudiqStyles.toolbarButton)) { anchor = destination; } } private void HandleResize(Rect panelPosition) { var resizeArea = new Rect ( panelPosition.x, panelPosition.yMax - (Styles.resizeGrip / 2), panelPosition.width - Styles.orderSpinnerWidth, Styles.resizeGrip ); EditorGUIUtility.AddCursorRect(resizeArea, MouseCursor.ResizeVertical); e.HandleCapture(resizeArea.Contains(e.mousePosition), false); if (e.IsMouseDown(MouseButton.Left) && resizeArea.Contains(e.mousePosition)) { isResizing = true; } if (isResizing && e.IsMouseUp(MouseButton.Left)) { isResizing = false; } if (isResizing && e.IsMouseDrag(MouseButton.Left)) { height = e.mousePosition.y - panelPosition.y; } e.HandleRelease(); } private static class Styles { public static readonly GUIStyle background; public static readonly GUIStyle title; public static readonly float resizeGrip = 14f; public static readonly float orderSpinnerWidth = LudiqGUIUtility.scrollBarWidth; public static readonly float anchorButtonWidth = 22; static Styles() { background = ColorPalette.unityBackgroundLight.CreateBackground(); title = new GUIStyle(EditorStyles.toolbar); title.fontSize = 11; title.alignment = TextAnchor.MiddleLeft; title.padding = new RectOffset(4, 4, 0, 0); title.imagePosition = ImagePosition.ImageLeft; title.fixedHeight = 18; } } } }