From 30f847dc2388d3f35f223187f3519f8739a106fa Mon Sep 17 00:00:00 2001 From: Sinai Date: Sat, 24 Apr 2021 04:00:58 +1000 Subject: [PATCH] Some improvements to panel dragging logic --- src/UI/Models/UIPanel.cs | 68 ++++++++----- src/UI/{Utility => Panels}/PanelDragger.cs | 109 +++++++++++++-------- 2 files changed, 112 insertions(+), 65 deletions(-) rename src/UI/{Utility => Panels}/PanelDragger.cs (84%) diff --git a/src/UI/Models/UIPanel.cs b/src/UI/Models/UIPanel.cs index 1d7e628..9c0dd4d 100644 --- a/src/UI/Models/UIPanel.cs +++ b/src/UI/Models/UIPanel.cs @@ -7,6 +7,7 @@ using UnityEngine; using UnityEngine.UI; using UnityExplorer.Core.Config; using UnityExplorer.Core.Input; +using UnityExplorer.UI.Panels; using UnityExplorer.UI.Utility; namespace UnityExplorer.UI.Models @@ -16,30 +17,41 @@ namespace UnityExplorer.UI.Models // STATIC public static event Action OnPanelsReordered; + public static event Action OnClickedOutsidePanels; public static void UpdateFocus() { + // if the user is clicking if (InputManager.GetMouseButtonDown(0) || InputManager.GetMouseButtonDown(1)) { int count = UIManager.PanelHolder.transform.childCount; var mousePos = InputManager.MousePosition; + bool clickedInAny = false; for (int i = count - 1; i >= 0; i--) { + // make sure this is a real recognized panel var transform = UIManager.PanelHolder.transform.GetChild(i); - if (transformToPanelDict.TryGetValue(transform.GetInstanceID(), out UIPanel panel)) + if (!transformToPanelDict.TryGetValue(transform.GetInstanceID(), out UIPanel panel)) + continue; + + // check if our mouse is clicking inside the panel + var pos = panel.mainPanelRect.InverseTransformPoint(mousePos); + if (!panel.Enabled || !panel.mainPanelRect.rect.Contains(pos)) + continue; + + // if this is not the top panel, reorder and invoke the onchanged event + if (transform.GetSiblingIndex() != count - 1) { - var pos = panel.mainPanelRect.InverseTransformPoint(mousePos); - if (panel.Enabled && panel.mainPanelRect.rect.Contains(pos)) - { - if (transform.GetSiblingIndex() != count - 1) - { - transform.SetAsLastSibling(); - OnPanelsReordered?.Invoke(); - } - break; - } + transform.SetAsLastSibling(); + OnPanelsReordered?.Invoke(); } + // panel was found, break + clickedInAny = true; + break; } + + if (!clickedInAny) + OnClickedOutsidePanels?.Invoke(); } } @@ -54,16 +66,19 @@ namespace UnityExplorer.UI.Models } public abstract UIManager.Panels PanelType { get; } - public abstract string Name { get; } public virtual bool ShouldSaveActiveState => true; + public virtual bool CanDrag => true; + //public virtual bool CanResize => true; + + public PanelDragger Dragger; + public override GameObject UIRoot => uiRoot; protected GameObject uiRoot; protected RectTransform mainPanelRect; public GameObject content; - public PanelDragger dragger; public abstract void ConstructPanelContent(); @@ -83,7 +98,7 @@ namespace UnityExplorer.UI.Models base.Destroy(); } - public override void ConstructUI(GameObject parent) + public void ConstructUI() { // create core canvas uiRoot = UIFactory.CreatePanel(Name, out GameObject panelContent); @@ -118,11 +133,16 @@ namespace UnityExplorer.UI.Models RuntimeProvider.Instance.SetColorBlock(closeBtn, new Color(0.63f, 0.32f, 0.31f), new Color(0.81f, 0.25f, 0.2f), new Color(0.6f, 0.18f, 0.16f)); + if (!CanDrag) + titleGroup.SetActive(false); + // Panel dragger - dragger = new PanelDragger(titleTxt.GetComponent(), mainPanelRect); - dragger.OnFinishResize += OnFinishResize; - dragger.OnFinishDrag += OnFinishDrag; + Dragger = new PanelDragger(titleTxt.GetComponent(), mainPanelRect); + Dragger.OnFinishResize += OnFinishResize; + Dragger.OnFinishDrag += OnFinishDrag; + Dragger.AllowDragAndResize = this.CanDrag; + //Dragger.CanResize = this.CanResize; // content (abstract) @@ -132,7 +152,7 @@ namespace UnityExplorer.UI.Models try { LoadSaveData(); - dragger.OnEndResize(); + Dragger.OnEndResize(); } catch (Exception ex) { @@ -146,7 +166,9 @@ namespace UnityExplorer.UI.Models SaveToConfigManager(); }; } - + + public override void ConstructUI(GameObject parent) => ConstructUI(); + // SAVE DATA public abstract void SaveToConfigManager(); @@ -190,10 +212,10 @@ namespace UnityExplorer.UI.Models } } + #region WINDOW ANCHORS / POSITION HELPERS + public static class RectSaveExtensions { - #region WINDOW ANCHORS / POSITION HELPERS - // Window Anchors helpers internal static CultureInfo _enCulture = new CultureInfo("en-US"); @@ -255,7 +277,7 @@ namespace UnityExplorer.UI.Models vector.y = float.Parse(split[1], _enCulture); rect.localPosition = vector; } - - #endregion } + + #endregion } diff --git a/src/UI/Utility/PanelDragger.cs b/src/UI/Panels/PanelDragger.cs similarity index 84% rename from src/UI/Utility/PanelDragger.cs rename to src/UI/Panels/PanelDragger.cs index 9395ba5..4dbcf89 100644 --- a/src/UI/Utility/PanelDragger.cs +++ b/src/UI/Panels/PanelDragger.cs @@ -7,11 +7,16 @@ using System.IO; using System.Diagnostics; using UnityExplorer.UI.Models; using System.Linq; +using UnityExplorer.UI.Widgets.AutoComplete; -namespace UnityExplorer.UI.Utility +namespace UnityExplorer.UI.Panels { public class PanelDragger { + #region Static + + internal static List Instances = new List(); + static PanelDragger() { UIPanel.OnPanelsReordered += OnPanelsReordered; @@ -20,9 +25,15 @@ namespace UnityExplorer.UI.Utility public static void OnPanelsReordered() { Instances.Sort((a, b) => b.Panel.GetSiblingIndex().CompareTo(a.Panel.GetSiblingIndex())); - } - internal static List Instances = new List(); + // move AutoCompleter to bottom + if (AutoCompleter.Instance != null) + { + var idx = Instances.IndexOf(AutoCompleter.Instance.Dragger); + Instances.RemoveAt(idx); + Instances.Insert(0, AutoCompleter.Instance.Dragger); + } + } private enum MouseState { @@ -60,7 +71,11 @@ namespace UnityExplorer.UI.Utility } } - // ------- Instance ------- + #endregion + + // Instance + + public bool AllowDragAndResize { get; set; } public RectTransform Panel { get; set; } public event Action OnFinishResize; @@ -80,6 +95,8 @@ namespace UnityExplorer.UI.Utility internal readonly Vector2 minResize = new Vector2(200, 50); + private static int currentResizePanel; + private bool WasResizing { get; set; } private ResizeTypes m_currentResizeType = ResizeTypes.NONE; private Vector2 m_lastResizePos; @@ -114,6 +131,7 @@ namespace UnityExplorer.UI.Utility { ResizeTypes type; Vector3 resizePos = Panel.InverseTransformPoint(rawMousePos); + bool inResizePos = MouseInResizeArea(resizePos); Vector3 dragPos = DragableArea.InverseTransformPoint(rawMousePos); bool inDragPos = DragableArea.rect.Contains(dragPos); @@ -124,22 +142,20 @@ namespace UnityExplorer.UI.Utility switch (state) { case MouseState.Down: - if (handledInstanceThisFrame) - break; if (inDragPos) { - OnBeginDrag(); + if (AllowDragAndResize) + OnBeginDrag(); handledInstanceThisFrame = true; return; } - else if (MouseInResizeArea(resizePos)) + else if (inResizePos) { type = GetResizeType(resizePos); if (type != ResizeTypes.NONE) - { OnBeginResize(type); - handledInstanceThisFrame = true; - } + + handledInstanceThisFrame = true; } break; @@ -157,22 +173,27 @@ namespace UnityExplorer.UI.Utility break; case MouseState.NotPressed: - if (WasDragging) + if (AllowDragAndResize && inDragPos) { - OnEndDrag(); + if (WasDragging) + OnEndDrag(); + + if (WasHoveringResize) + OnHoverResizeEnd(); + handledInstanceThisFrame = true; } - else if (WasResizing) + else if (inResizePos) { - OnEndResize(); - handledInstanceThisFrame = true; - } - else if (!inDragPos && MouseInResizeArea(resizePos)) - { - if ((type = GetResizeType(resizePos)) != ResizeTypes.NONE) + if (WasResizing) + OnEndResize(); + + type = GetResizeType(resizePos); + if (type != ResizeTypes.NONE) OnHoverResize(type); else if (WasHoveringResize) OnHoverResizeEnd(); + handledInstanceThisFrame = true; } else if (WasHoveringResize) @@ -237,7 +258,7 @@ namespace UnityExplorer.UI.Utility BottomRight = Bottom | Right, } - private const int HALF_THICKESS = RESIZE_THICKNESS / 2; + // private const int HALF_THICKESS = RESIZE_THICKNESS / 2; private const int DBL_THICKESS = RESIZE_THICKNESS * 2; private void UpdateResizeCache() @@ -248,30 +269,32 @@ namespace UnityExplorer.UI.Utility Panel.rect.height + DBL_THICKESS - 2); // calculate the four cross sections to use as flags + if (AllowDragAndResize) + { + m_resizeMask[ResizeTypes.Bottom] = new Rect( + m_totalResizeRect.x, + m_totalResizeRect.y, + m_totalResizeRect.width, + RESIZE_THICKNESS); - m_resizeMask[ResizeTypes.Bottom] = new Rect( - m_totalResizeRect.x, - m_totalResizeRect.y, - m_totalResizeRect.width, - RESIZE_THICKNESS); + m_resizeMask[ResizeTypes.Left] = new Rect( + m_totalResizeRect.x, + m_totalResizeRect.y, + RESIZE_THICKNESS, + m_totalResizeRect.height); - m_resizeMask[ResizeTypes.Left] = new Rect( - m_totalResizeRect.x, - m_totalResizeRect.y, - RESIZE_THICKNESS, - m_totalResizeRect.height); + m_resizeMask[ResizeTypes.Top] = new Rect( + m_totalResizeRect.x, + Panel.rect.y + Panel.rect.height - 2, + m_totalResizeRect.width, + RESIZE_THICKNESS); - m_resizeMask[ResizeTypes.Top] = new Rect( - m_totalResizeRect.x, - Panel.rect.y + Panel.rect.height - 2, - m_totalResizeRect.width, - RESIZE_THICKNESS); - - m_resizeMask[ResizeTypes.Right] = new Rect( - m_totalResizeRect.x + Panel.rect.width + RESIZE_THICKNESS - 2, - m_totalResizeRect.y, - RESIZE_THICKNESS, - m_totalResizeRect.height); + m_resizeMask[ResizeTypes.Right] = new Rect( + m_totalResizeRect.x + Panel.rect.width + RESIZE_THICKNESS - 2, + m_totalResizeRect.y, + RESIZE_THICKNESS, + m_totalResizeRect.height); + } } private bool MouseInResizeArea(Vector2 mousePos) @@ -355,6 +378,7 @@ namespace UnityExplorer.UI.Utility m_currentResizeType = resizeType; m_lastResizePos = InputManager.MousePosition; WasResizing = true; + currentResizePanel = this.Panel.GetInstanceID(); } public void OnResize() @@ -406,6 +430,7 @@ namespace UnityExplorer.UI.Utility WasResizing = false; UpdateResizeCache(); OnFinishResize?.Invoke(Panel); + currentResizePanel = -1; } internal static void CreateCursorUI()