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 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<RectTransform>(), mainPanelRect);
dragger.OnFinishResize += OnFinishResize;
dragger.OnFinishDrag += OnFinishDrag;
Dragger = new PanelDragger(titleTxt.GetComponent<RectTransform>(), 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
}

View File

@ -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<PanelDragger> Instances = new List<PanelDragger>();
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<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
{
@ -60,7 +71,11 @@ namespace UnityExplorer.UI.Utility
}
}
// ------- Instance -------
#endregion
// Instance
public bool AllowDragAndResize { get; set; }
public RectTransform Panel { get; set; }
public event Action<RectTransform> 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()