diff --git a/src/UI/Models/UIPanel.cs b/src/UI/Models/UIPanel.cs index 23fdff6..d2a2dd6 100644 --- a/src/UI/Models/UIPanel.cs +++ b/src/UI/Models/UIPanel.cs @@ -6,12 +6,55 @@ using System.Text; using UnityEngine; using UnityEngine.UI; using UnityExplorer.Core.Config; +using UnityExplorer.Core.Input; using UnityExplorer.UI.Utility; namespace UnityExplorer.UI.Models { public abstract class UIPanel : UIBehaviourModel { + public static event Action OnPanelsReordered; + + public static void UpdateFocus() + { + if (InputManager.GetMouseButtonDown(0) || InputManager.GetMouseButtonDown(1)) + { + int count = UIManager.CanvasRoot.transform.childCount; + var mousePos = InputManager.MousePosition; + for (int i = count - 1; i >= 0; i--) + { + var transform = UIManager.CanvasRoot.transform.GetChild(i); + if (transformToPanelDict.TryGetValue(transform.GetInstanceID(), out UIPanel panel)) + { + var pos = panel.mainPanelRect.InverseTransformPoint(mousePos); + if (panel.Enabled && panel.mainPanelRect.rect.Contains(pos)) + { + if (transform.GetSiblingIndex() != count - 1) + { + transform.SetAsLastSibling(); + OnPanelsReordered?.Invoke(); + } + break; + } + } + } + } + } + + private static readonly List instances = new List(); + private static readonly Dictionary transformToPanelDict = new Dictionary(); + + public UIPanel() + { + instances.Add(this); + } + + public override void Destroy() + { + instances.Remove(this); + base.Destroy(); + } + public override GameObject UIRoot => uiRoot; protected GameObject uiRoot; protected RectTransform mainPanelRect; @@ -23,12 +66,13 @@ namespace UnityExplorer.UI.Models public override void ConstructUI(GameObject parent) { // create core canvas - var panel = UIFactory.CreatePanel(Name, out GameObject panelContent); - uiRoot = panel; - mainPanelRect = uiRoot.GetComponent(); + uiRoot = UIFactory.CreatePanel(Name, out GameObject panelContent); + mainPanelRect = this.uiRoot.GetComponent(); content = panelContent; - UIFactory.SetLayoutGroup(uiRoot, true, true, true, true, 0, 0, 0, 0, 0, TextAnchor.UpperLeft); + transformToPanelDict.Add(this.uiRoot.transform.GetInstanceID(), this); + + UIFactory.SetLayoutGroup(this.uiRoot, true, true, true, true, 0, 0, 0, 0, 0, TextAnchor.UpperLeft); UIFactory.SetLayoutGroup(content, true, true, true, true, 2, 2, 2, 2, 2, TextAnchor.UpperLeft); // always apply default pos and anchors (save data may only be partial) diff --git a/src/UI/UIManager.cs b/src/UI/UIManager.cs index eba8ae6..54de586 100644 --- a/src/UI/UIManager.cs +++ b/src/UI/UIManager.cs @@ -89,6 +89,8 @@ namespace UnityExplorer.UI if (InputManager.GetKeyDown(ConfigManager.Force_Unlock_Keybind.Value)) CursorUnlocker.Unlock = !CursorUnlocker.Unlock; + UIPanel.UpdateFocus(); + UIBehaviourModel.UpdateInstances(); if (EventSystem.current != EventSys) diff --git a/src/UI/Utility/PanelDragger.cs b/src/UI/Utility/PanelDragger.cs index 9fa450f..c07a5d3 100644 --- a/src/UI/Utility/PanelDragger.cs +++ b/src/UI/Utility/PanelDragger.cs @@ -5,24 +5,63 @@ using UnityEngine.UI; using UnityExplorer.Core.Input; using System.IO; using System.Diagnostics; +using UnityExplorer.UI.Models; +using System.Linq; namespace UnityExplorer.UI.Utility { public class PanelDragger { + static PanelDragger() + { + UIPanel.OnPanelsReordered += OnPanelsReordered; + } + + public static void OnPanelsReordered() + { + Instances.Sort((a, b) => b.Panel.GetSiblingIndex().CompareTo(a.Panel.GetSiblingIndex())); + } + internal static List Instances = new List(); + private enum MouseState + { + Down, + Held, + NotPressed + } + + private static bool handledInstanceThisFrame; + public static void UpdateInstances() { + if (!s_resizeCursorObj) + CreateCursorUI(); + + MouseState state; + if (InputManager.GetMouseButtonDown(0)) + state = MouseState.Down; + else if (InputManager.GetMouseButton(0)) + state = MouseState.Held; + else + state = MouseState.NotPressed; + + handledInstanceThisFrame = false; foreach (var instance in Instances) - instance.Update(); + { + instance.Update(state, InputManager.MousePosition); + if (handledInstanceThisFrame) + break; + } } + // ------- Instance ------- + public RectTransform Panel { get; set; } public event Action OnFinishResize; public event Action OnFinishDrag; - private readonly RectTransform refCanvasTransform; + private readonly RectTransform canvasTransform; // Dragging public RectTransform DragableArea { get; set; } @@ -32,7 +71,7 @@ namespace UnityExplorer.UI.Utility // Resizing private const int RESIZE_THICKNESS = 10; - public GameObject m_resizeCursorObj; + public static GameObject s_resizeCursorObj; internal readonly Vector2 minResize = new Vector2(200, 50); @@ -50,84 +89,90 @@ namespace UnityExplorer.UI.Utility Instances.Add(this); DragableArea = dragArea; Panel = panelToDrag; - refCanvasTransform = Panel.GetComponentInParent().GetComponent(); + + if (!canvasTransform) + canvasTransform = Panel.GetComponentInParent().GetComponent(); UpdateResizeCache(); } public void Destroy() { - if (m_resizeCursorObj) - GameObject.Destroy(m_resizeCursorObj); + if (s_resizeCursorObj) + GameObject.Destroy(s_resizeCursorObj); if (Instances.Contains(this)) Instances.Remove(this); } - public void Update() + private void Update(MouseState state, Vector3 rawMousePos) { - if (!m_resizeCursorObj) - this.CreateCursorUI(); - - Vector3 rawMousePos = InputManager.MousePosition; - ResizeTypes type; Vector3 resizePos = Panel.InverseTransformPoint(rawMousePos); Vector3 dragPos = DragableArea.InverseTransformPoint(rawMousePos); bool inDragPos = DragableArea.rect.Contains(dragPos); - if (WasHoveringResize && m_resizeCursorObj) + if (WasHoveringResize && s_resizeCursorObj) UpdateHoverImagePos(); - // If Mouse pressed this frame - if (InputManager.GetMouseButtonDown(0)) + switch (state) { - if (inDragPos) - { - OnBeginDrag(); - return; - } - else if (MouseInResizeArea(resizePos)) - { - type = GetResizeType(resizePos); - if (type != ResizeTypes.NONE) + case MouseState.Down: + if (handledInstanceThisFrame) + break; + if (inDragPos) { - OnBeginResize(type); + OnBeginDrag(); + handledInstanceThisFrame = true; + return; } - } - } - // If mouse still pressed from last frame - else if (InputManager.GetMouseButton(0)) - { - if (WasDragging) - { - OnDrag(); - } - else if (WasResizing) - { - OnResize(); - } - } - // If mouse not pressed - else - { - if (WasDragging) - { - OnEndDrag(); - } - else if (WasResizing) - { - OnEndResize(); - } - else if (!inDragPos && MouseInResizeArea(resizePos) && (type = GetResizeType(resizePos)) != ResizeTypes.NONE) - { - OnHoverResize(type); - } - else if (WasHoveringResize) - { - OnHoverResizeEnd(); - } + else if (MouseInResizeArea(resizePos)) + { + type = GetResizeType(resizePos); + if (type != ResizeTypes.NONE) + { + OnBeginResize(type); + handledInstanceThisFrame = true; + } + } + break; + + case MouseState.Held: + if (WasDragging) + { + OnDrag(); + handledInstanceThisFrame = true; + } + else if (WasResizing) + { + OnResize(); + handledInstanceThisFrame = true; + } + break; + + case MouseState.NotPressed: + if (WasDragging) + { + OnEndDrag(); + handledInstanceThisFrame = true; + } + else if (WasResizing) + { + OnEndResize(); + handledInstanceThisFrame = true; + } + else if (!inDragPos && MouseInResizeArea(resizePos) && (type = GetResizeType(resizePos)) != ResizeTypes.NONE) + { + OnHoverResize(type); + handledInstanceThisFrame = true; + } + else if (WasHoveringResize) + { + OnHoverResizeEnd(); + handledInstanceThisFrame = true; + } + break; } return; @@ -263,7 +308,8 @@ namespace UnityExplorer.UI.Utility WasHoveringResize = true; m_lastResizeHoverType = resizeType; - m_resizeCursorObj.SetActive(true); + s_resizeCursorObj.SetActive(true); + s_resizeCursorObj.transform.SetAsLastSibling(); // set the rotation for the resize icon float iconRotation = 0f; @@ -280,9 +326,9 @@ namespace UnityExplorer.UI.Utility iconRotation = 135f; break; } - Quaternion rot = m_resizeCursorObj.transform.rotation; + Quaternion rot = s_resizeCursorObj.transform.rotation; rot.eulerAngles = new Vector3(0, 0, iconRotation); - m_resizeCursorObj.transform.rotation = rot; + s_resizeCursorObj.transform.rotation = rot; UpdateHoverImagePos(); } @@ -290,13 +336,13 @@ namespace UnityExplorer.UI.Utility // update the resize icon position to be above the mouse private void UpdateHoverImagePos() { - m_resizeCursorObj.transform.localPosition = refCanvasTransform.InverseTransformPoint(InputManager.MousePosition); + s_resizeCursorObj.transform.localPosition = canvasTransform.InverseTransformPoint(InputManager.MousePosition); } public void OnHoverResizeEnd() { WasHoveringResize = false; - m_resizeCursorObj.SetActive(false); + s_resizeCursorObj.SetActive(false); } public void OnBeginResize(ResizeTypes resizeType) @@ -357,18 +403,18 @@ namespace UnityExplorer.UI.Utility OnFinishResize?.Invoke(Panel); } - internal void CreateCursorUI() + internal static void CreateCursorUI() { try { - var text = UIFactory.CreateLabel(refCanvasTransform.gameObject, "ResizeCursor", "↔", TextAnchor.MiddleCenter, Color.white, true, 35); - m_resizeCursorObj = text.gameObject; + var text = UIFactory.CreateLabel(UIManager.CanvasRoot, "ResizeCursor", "↔", TextAnchor.MiddleCenter, Color.white, true, 35); + s_resizeCursorObj = text.gameObject; - RectTransform rect = m_resizeCursorObj.GetComponent(); + RectTransform rect = s_resizeCursorObj.GetComponent(); rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, 64); rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 64); - m_resizeCursorObj.SetActive(false); + s_resizeCursorObj.SetActive(false); } catch (Exception e) { diff --git a/src/UnityExplorer.csproj b/src/UnityExplorer.csproj index 733f408..f414b4d 100644 --- a/src/UnityExplorer.csproj +++ b/src/UnityExplorer.csproj @@ -277,7 +277,6 @@ -