Some improvements to panel dragging logic

This commit is contained in:
Sinai 2021-04-24 04:00:58 +10:00
parent 7ffaf62895
commit 30f847dc23
2 changed files with 112 additions and 65 deletions

View File

@ -7,6 +7,7 @@ using UnityEngine;
using UnityEngine.UI; using UnityEngine.UI;
using UnityExplorer.Core.Config; using UnityExplorer.Core.Config;
using UnityExplorer.Core.Input; using UnityExplorer.Core.Input;
using UnityExplorer.UI.Panels;
using UnityExplorer.UI.Utility; using UnityExplorer.UI.Utility;
namespace UnityExplorer.UI.Models namespace UnityExplorer.UI.Models
@ -16,30 +17,41 @@ namespace UnityExplorer.UI.Models
// STATIC // STATIC
public static event Action OnPanelsReordered; public static event Action OnPanelsReordered;
public static event Action OnClickedOutsidePanels;
public static void UpdateFocus() public static void UpdateFocus()
{ {
// if the user is clicking
if (InputManager.GetMouseButtonDown(0) || InputManager.GetMouseButtonDown(1)) if (InputManager.GetMouseButtonDown(0) || InputManager.GetMouseButtonDown(1))
{ {
int count = UIManager.PanelHolder.transform.childCount; int count = UIManager.PanelHolder.transform.childCount;
var mousePos = InputManager.MousePosition; var mousePos = InputManager.MousePosition;
bool clickedInAny = false;
for (int i = count - 1; i >= 0; i--) for (int i = count - 1; i >= 0; i--)
{ {
// make sure this is a real recognized panel
var transform = UIManager.PanelHolder.transform.GetChild(i); 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); transform.SetAsLastSibling();
if (panel.Enabled && panel.mainPanelRect.rect.Contains(pos)) OnPanelsReordered?.Invoke();
{
if (transform.GetSiblingIndex() != count - 1)
{
transform.SetAsLastSibling();
OnPanelsReordered?.Invoke();
}
break;
}
} }
// 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 UIManager.Panels PanelType { get; }
public abstract string Name { get; } public abstract string Name { get; }
public virtual bool ShouldSaveActiveState => true; public virtual bool ShouldSaveActiveState => true;
public virtual bool CanDrag => true;
//public virtual bool CanResize => true;
public PanelDragger Dragger;
public override GameObject UIRoot => uiRoot; public override GameObject UIRoot => uiRoot;
protected GameObject uiRoot; protected GameObject uiRoot;
protected RectTransform mainPanelRect; protected RectTransform mainPanelRect;
public GameObject content; public GameObject content;
public PanelDragger dragger;
public abstract void ConstructPanelContent(); public abstract void ConstructPanelContent();
@ -83,7 +98,7 @@ namespace UnityExplorer.UI.Models
base.Destroy(); base.Destroy();
} }
public override void ConstructUI(GameObject parent) public void ConstructUI()
{ {
// create core canvas // create core canvas
uiRoot = UIFactory.CreatePanel(Name, out GameObject panelContent); 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), 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)); new Color(0.81f, 0.25f, 0.2f), new Color(0.6f, 0.18f, 0.16f));
if (!CanDrag)
titleGroup.SetActive(false);
// Panel dragger // Panel dragger
dragger = new PanelDragger(titleTxt.GetComponent<RectTransform>(), mainPanelRect); Dragger = new PanelDragger(titleTxt.GetComponent<RectTransform>(), mainPanelRect);
dragger.OnFinishResize += OnFinishResize; Dragger.OnFinishResize += OnFinishResize;
dragger.OnFinishDrag += OnFinishDrag; Dragger.OnFinishDrag += OnFinishDrag;
Dragger.AllowDragAndResize = this.CanDrag;
//Dragger.CanResize = this.CanResize;
// content (abstract) // content (abstract)
@ -132,7 +152,7 @@ namespace UnityExplorer.UI.Models
try try
{ {
LoadSaveData(); LoadSaveData();
dragger.OnEndResize(); Dragger.OnEndResize();
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -146,7 +166,9 @@ namespace UnityExplorer.UI.Models
SaveToConfigManager(); SaveToConfigManager();
}; };
} }
public override void ConstructUI(GameObject parent) => ConstructUI();
// SAVE DATA // SAVE DATA
public abstract void SaveToConfigManager(); public abstract void SaveToConfigManager();
@ -190,10 +212,10 @@ namespace UnityExplorer.UI.Models
} }
} }
#region WINDOW ANCHORS / POSITION HELPERS
public static class RectSaveExtensions public static class RectSaveExtensions
{ {
#region WINDOW ANCHORS / POSITION HELPERS
// Window Anchors helpers // Window Anchors helpers
internal static CultureInfo _enCulture = new CultureInfo("en-US"); internal static CultureInfo _enCulture = new CultureInfo("en-US");
@ -255,7 +277,7 @@ namespace UnityExplorer.UI.Models
vector.y = float.Parse(split[1], _enCulture); vector.y = float.Parse(split[1], _enCulture);
rect.localPosition = vector; rect.localPosition = vector;
} }
#endregion
} }
#endregion
} }

View File

@ -7,11 +7,16 @@ using System.IO;
using System.Diagnostics; using System.Diagnostics;
using UnityExplorer.UI.Models; using UnityExplorer.UI.Models;
using System.Linq; using System.Linq;
using UnityExplorer.UI.Widgets.AutoComplete;
namespace UnityExplorer.UI.Utility namespace UnityExplorer.UI.Panels
{ {
public class PanelDragger public class PanelDragger
{ {
#region Static
internal static List<PanelDragger> Instances = new List<PanelDragger>();
static PanelDragger() static PanelDragger()
{ {
UIPanel.OnPanelsReordered += OnPanelsReordered; UIPanel.OnPanelsReordered += OnPanelsReordered;
@ -20,9 +25,15 @@ namespace UnityExplorer.UI.Utility
public static void OnPanelsReordered() public static void OnPanelsReordered()
{ {
Instances.Sort((a, b) => b.Panel.GetSiblingIndex().CompareTo(a.Panel.GetSiblingIndex())); Instances.Sort((a, b) => b.Panel.GetSiblingIndex().CompareTo(a.Panel.GetSiblingIndex()));
}
internal static List<PanelDragger> Instances = new List<PanelDragger>(); // 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 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 RectTransform Panel { get; set; }
public event Action<RectTransform> OnFinishResize; public event Action<RectTransform> OnFinishResize;
@ -80,6 +95,8 @@ namespace UnityExplorer.UI.Utility
internal readonly Vector2 minResize = new Vector2(200, 50); internal readonly Vector2 minResize = new Vector2(200, 50);
private static int currentResizePanel;
private bool WasResizing { get; set; } private bool WasResizing { get; set; }
private ResizeTypes m_currentResizeType = ResizeTypes.NONE; private ResizeTypes m_currentResizeType = ResizeTypes.NONE;
private Vector2 m_lastResizePos; private Vector2 m_lastResizePos;
@ -114,6 +131,7 @@ namespace UnityExplorer.UI.Utility
{ {
ResizeTypes type; ResizeTypes type;
Vector3 resizePos = Panel.InverseTransformPoint(rawMousePos); Vector3 resizePos = Panel.InverseTransformPoint(rawMousePos);
bool inResizePos = MouseInResizeArea(resizePos);
Vector3 dragPos = DragableArea.InverseTransformPoint(rawMousePos); Vector3 dragPos = DragableArea.InverseTransformPoint(rawMousePos);
bool inDragPos = DragableArea.rect.Contains(dragPos); bool inDragPos = DragableArea.rect.Contains(dragPos);
@ -124,22 +142,20 @@ namespace UnityExplorer.UI.Utility
switch (state) switch (state)
{ {
case MouseState.Down: case MouseState.Down:
if (handledInstanceThisFrame)
break;
if (inDragPos) if (inDragPos)
{ {
OnBeginDrag(); if (AllowDragAndResize)
OnBeginDrag();
handledInstanceThisFrame = true; handledInstanceThisFrame = true;
return; return;
} }
else if (MouseInResizeArea(resizePos)) else if (inResizePos)
{ {
type = GetResizeType(resizePos); type = GetResizeType(resizePos);
if (type != ResizeTypes.NONE) if (type != ResizeTypes.NONE)
{
OnBeginResize(type); OnBeginResize(type);
handledInstanceThisFrame = true;
} handledInstanceThisFrame = true;
} }
break; break;
@ -157,22 +173,27 @@ namespace UnityExplorer.UI.Utility
break; break;
case MouseState.NotPressed: case MouseState.NotPressed:
if (WasDragging) if (AllowDragAndResize && inDragPos)
{ {
OnEndDrag(); if (WasDragging)
OnEndDrag();
if (WasHoveringResize)
OnHoverResizeEnd();
handledInstanceThisFrame = true; handledInstanceThisFrame = true;
} }
else if (WasResizing) else if (inResizePos)
{ {
OnEndResize(); if (WasResizing)
handledInstanceThisFrame = true; OnEndResize();
}
else if (!inDragPos && MouseInResizeArea(resizePos)) type = GetResizeType(resizePos);
{ if (type != ResizeTypes.NONE)
if ((type = GetResizeType(resizePos)) != ResizeTypes.NONE)
OnHoverResize(type); OnHoverResize(type);
else if (WasHoveringResize) else if (WasHoveringResize)
OnHoverResizeEnd(); OnHoverResizeEnd();
handledInstanceThisFrame = true; handledInstanceThisFrame = true;
} }
else if (WasHoveringResize) else if (WasHoveringResize)
@ -237,7 +258,7 @@ namespace UnityExplorer.UI.Utility
BottomRight = Bottom | Right, 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 const int DBL_THICKESS = RESIZE_THICKNESS * 2;
private void UpdateResizeCache() private void UpdateResizeCache()
@ -248,30 +269,32 @@ namespace UnityExplorer.UI.Utility
Panel.rect.height + DBL_THICKESS - 2); Panel.rect.height + DBL_THICKESS - 2);
// calculate the four cross sections to use as flags // 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_resizeMask[ResizeTypes.Left] = new Rect(
m_totalResizeRect.x, m_totalResizeRect.x,
m_totalResizeRect.y, m_totalResizeRect.y,
m_totalResizeRect.width, RESIZE_THICKNESS,
RESIZE_THICKNESS); m_totalResizeRect.height);
m_resizeMask[ResizeTypes.Left] = new Rect( m_resizeMask[ResizeTypes.Top] = new Rect(
m_totalResizeRect.x, m_totalResizeRect.x,
m_totalResizeRect.y, Panel.rect.y + Panel.rect.height - 2,
RESIZE_THICKNESS, m_totalResizeRect.width,
m_totalResizeRect.height); RESIZE_THICKNESS);
m_resizeMask[ResizeTypes.Top] = new Rect( m_resizeMask[ResizeTypes.Right] = new Rect(
m_totalResizeRect.x, m_totalResizeRect.x + Panel.rect.width + RESIZE_THICKNESS - 2,
Panel.rect.y + Panel.rect.height - 2, m_totalResizeRect.y,
m_totalResizeRect.width, RESIZE_THICKNESS,
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) private bool MouseInResizeArea(Vector2 mousePos)
@ -355,6 +378,7 @@ namespace UnityExplorer.UI.Utility
m_currentResizeType = resizeType; m_currentResizeType = resizeType;
m_lastResizePos = InputManager.MousePosition; m_lastResizePos = InputManager.MousePosition;
WasResizing = true; WasResizing = true;
currentResizePanel = this.Panel.GetInstanceID();
} }
public void OnResize() public void OnResize()
@ -406,6 +430,7 @@ namespace UnityExplorer.UI.Utility
WasResizing = false; WasResizing = false;
UpdateResizeCache(); UpdateResizeCache();
OnFinishResize?.Invoke(Panel); OnFinishResize?.Invoke(Panel);
currentResizePanel = -1;
} }
internal static void CreateCursorUI() internal static void CreateCursorUI()