Update PanelDragger to handle multiple panels, add panel 'focusing'

This commit is contained in:
Sinai 2021-04-17 04:05:27 +10:00
parent 876cffd864
commit 2e5fb72716
4 changed files with 164 additions and 73 deletions

View File

@ -6,12 +6,55 @@ using System.Text;
using UnityEngine; using UnityEngine;
using UnityEngine.UI; using UnityEngine.UI;
using UnityExplorer.Core.Config; using UnityExplorer.Core.Config;
using UnityExplorer.Core.Input;
using UnityExplorer.UI.Utility; using UnityExplorer.UI.Utility;
namespace UnityExplorer.UI.Models namespace UnityExplorer.UI.Models
{ {
public abstract class UIPanel : UIBehaviourModel 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<UIPanel> instances = new List<UIPanel>();
private static readonly Dictionary<int, UIPanel> transformToPanelDict = new Dictionary<int, UIPanel>();
public UIPanel()
{
instances.Add(this);
}
public override void Destroy()
{
instances.Remove(this);
base.Destroy();
}
public override GameObject UIRoot => uiRoot; public override GameObject UIRoot => uiRoot;
protected GameObject uiRoot; protected GameObject uiRoot;
protected RectTransform mainPanelRect; protected RectTransform mainPanelRect;
@ -23,12 +66,13 @@ namespace UnityExplorer.UI.Models
public override void ConstructUI(GameObject parent) public override void ConstructUI(GameObject parent)
{ {
// create core canvas // create core canvas
var panel = UIFactory.CreatePanel(Name, out GameObject panelContent); uiRoot = UIFactory.CreatePanel(Name, out GameObject panelContent);
uiRoot = panel; mainPanelRect = this.uiRoot.GetComponent<RectTransform>();
mainPanelRect = uiRoot.GetComponent<RectTransform>();
content = panelContent; content = panelContent;
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(uiRoot, true, true, true, true, 0, 0, 0, 0, 0, TextAnchor.UpperLeft); transformToPanelDict.Add(this.uiRoot.transform.GetInstanceID(), this);
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(this.uiRoot, true, true, true, true, 0, 0, 0, 0, 0, TextAnchor.UpperLeft);
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(content, true, true, true, true, 2, 2, 2, 2, 2, TextAnchor.UpperLeft); UIFactory.SetLayoutGroup<VerticalLayoutGroup>(content, true, true, true, true, 2, 2, 2, 2, 2, TextAnchor.UpperLeft);
// always apply default pos and anchors (save data may only be partial) // always apply default pos and anchors (save data may only be partial)

View File

@ -89,6 +89,8 @@ namespace UnityExplorer.UI
if (InputManager.GetKeyDown(ConfigManager.Force_Unlock_Keybind.Value)) if (InputManager.GetKeyDown(ConfigManager.Force_Unlock_Keybind.Value))
CursorUnlocker.Unlock = !CursorUnlocker.Unlock; CursorUnlocker.Unlock = !CursorUnlocker.Unlock;
UIPanel.UpdateFocus();
UIBehaviourModel.UpdateInstances(); UIBehaviourModel.UpdateInstances();
if (EventSystem.current != EventSys) if (EventSystem.current != EventSys)

View File

@ -5,24 +5,63 @@ using UnityEngine.UI;
using UnityExplorer.Core.Input; using UnityExplorer.Core.Input;
using System.IO; using System.IO;
using System.Diagnostics; using System.Diagnostics;
using UnityExplorer.UI.Models;
using System.Linq;
namespace UnityExplorer.UI.Utility namespace UnityExplorer.UI.Utility
{ {
public class PanelDragger 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<PanelDragger> Instances = new List<PanelDragger>(); internal static List<PanelDragger> Instances = new List<PanelDragger>();
private enum MouseState
{
Down,
Held,
NotPressed
}
private static bool handledInstanceThisFrame;
public static void UpdateInstances() 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) foreach (var instance in Instances)
instance.Update(); {
instance.Update(state, InputManager.MousePosition);
if (handledInstanceThisFrame)
break;
}
} }
// ------- Instance -------
public RectTransform Panel { get; set; } public RectTransform Panel { get; set; }
public event Action<RectTransform> OnFinishResize; public event Action<RectTransform> OnFinishResize;
public event Action<RectTransform> OnFinishDrag; public event Action<RectTransform> OnFinishDrag;
private readonly RectTransform refCanvasTransform; private readonly RectTransform canvasTransform;
// Dragging // Dragging
public RectTransform DragableArea { get; set; } public RectTransform DragableArea { get; set; }
@ -32,7 +71,7 @@ namespace UnityExplorer.UI.Utility
// Resizing // Resizing
private const int RESIZE_THICKNESS = 10; private const int RESIZE_THICKNESS = 10;
public GameObject m_resizeCursorObj; public static GameObject s_resizeCursorObj;
internal readonly Vector2 minResize = new Vector2(200, 50); internal readonly Vector2 minResize = new Vector2(200, 50);
@ -50,84 +89,90 @@ namespace UnityExplorer.UI.Utility
Instances.Add(this); Instances.Add(this);
DragableArea = dragArea; DragableArea = dragArea;
Panel = panelToDrag; Panel = panelToDrag;
refCanvasTransform = Panel.GetComponentInParent<Canvas>().GetComponent<RectTransform>();
if (!canvasTransform)
canvasTransform = Panel.GetComponentInParent<Canvas>().GetComponent<RectTransform>();
UpdateResizeCache(); UpdateResizeCache();
} }
public void Destroy() public void Destroy()
{ {
if (m_resizeCursorObj) if (s_resizeCursorObj)
GameObject.Destroy(m_resizeCursorObj); GameObject.Destroy(s_resizeCursorObj);
if (Instances.Contains(this)) if (Instances.Contains(this))
Instances.Remove(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; ResizeTypes type;
Vector3 resizePos = Panel.InverseTransformPoint(rawMousePos); Vector3 resizePos = Panel.InverseTransformPoint(rawMousePos);
Vector3 dragPos = DragableArea.InverseTransformPoint(rawMousePos); Vector3 dragPos = DragableArea.InverseTransformPoint(rawMousePos);
bool inDragPos = DragableArea.rect.Contains(dragPos); bool inDragPos = DragableArea.rect.Contains(dragPos);
if (WasHoveringResize && m_resizeCursorObj) if (WasHoveringResize && s_resizeCursorObj)
UpdateHoverImagePos(); UpdateHoverImagePos();
// If Mouse pressed this frame switch (state)
if (InputManager.GetMouseButtonDown(0))
{ {
if (inDragPos) case MouseState.Down:
{ if (handledInstanceThisFrame)
OnBeginDrag(); break;
return; if (inDragPos)
}
else if (MouseInResizeArea(resizePos))
{
type = GetResizeType(resizePos);
if (type != ResizeTypes.NONE)
{ {
OnBeginResize(type); OnBeginDrag();
handledInstanceThisFrame = true;
return;
} }
} else if (MouseInResizeArea(resizePos))
} {
// If mouse still pressed from last frame type = GetResizeType(resizePos);
else if (InputManager.GetMouseButton(0)) if (type != ResizeTypes.NONE)
{ {
if (WasDragging) OnBeginResize(type);
{ handledInstanceThisFrame = true;
OnDrag(); }
} }
else if (WasResizing) break;
{
OnResize(); case MouseState.Held:
} if (WasDragging)
} {
// If mouse not pressed OnDrag();
else handledInstanceThisFrame = true;
{ }
if (WasDragging) else if (WasResizing)
{ {
OnEndDrag(); OnResize();
} handledInstanceThisFrame = true;
else if (WasResizing) }
{ break;
OnEndResize();
} case MouseState.NotPressed:
else if (!inDragPos && MouseInResizeArea(resizePos) && (type = GetResizeType(resizePos)) != ResizeTypes.NONE) if (WasDragging)
{ {
OnHoverResize(type); OnEndDrag();
} handledInstanceThisFrame = true;
else if (WasHoveringResize) }
{ else if (WasResizing)
OnHoverResizeEnd(); {
} 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; return;
@ -263,7 +308,8 @@ namespace UnityExplorer.UI.Utility
WasHoveringResize = true; WasHoveringResize = true;
m_lastResizeHoverType = resizeType; m_lastResizeHoverType = resizeType;
m_resizeCursorObj.SetActive(true); s_resizeCursorObj.SetActive(true);
s_resizeCursorObj.transform.SetAsLastSibling();
// set the rotation for the resize icon // set the rotation for the resize icon
float iconRotation = 0f; float iconRotation = 0f;
@ -280,9 +326,9 @@ namespace UnityExplorer.UI.Utility
iconRotation = 135f; break; iconRotation = 135f; break;
} }
Quaternion rot = m_resizeCursorObj.transform.rotation; Quaternion rot = s_resizeCursorObj.transform.rotation;
rot.eulerAngles = new Vector3(0, 0, iconRotation); rot.eulerAngles = new Vector3(0, 0, iconRotation);
m_resizeCursorObj.transform.rotation = rot; s_resizeCursorObj.transform.rotation = rot;
UpdateHoverImagePos(); UpdateHoverImagePos();
} }
@ -290,13 +336,13 @@ namespace UnityExplorer.UI.Utility
// update the resize icon position to be above the mouse // update the resize icon position to be above the mouse
private void UpdateHoverImagePos() private void UpdateHoverImagePos()
{ {
m_resizeCursorObj.transform.localPosition = refCanvasTransform.InverseTransformPoint(InputManager.MousePosition); s_resizeCursorObj.transform.localPosition = canvasTransform.InverseTransformPoint(InputManager.MousePosition);
} }
public void OnHoverResizeEnd() public void OnHoverResizeEnd()
{ {
WasHoveringResize = false; WasHoveringResize = false;
m_resizeCursorObj.SetActive(false); s_resizeCursorObj.SetActive(false);
} }
public void OnBeginResize(ResizeTypes resizeType) public void OnBeginResize(ResizeTypes resizeType)
@ -357,18 +403,18 @@ namespace UnityExplorer.UI.Utility
OnFinishResize?.Invoke(Panel); OnFinishResize?.Invoke(Panel);
} }
internal void CreateCursorUI() internal static void CreateCursorUI()
{ {
try try
{ {
var text = UIFactory.CreateLabel(refCanvasTransform.gameObject, "ResizeCursor", "↔", TextAnchor.MiddleCenter, Color.white, true, 35); var text = UIFactory.CreateLabel(UIManager.CanvasRoot, "ResizeCursor", "↔", TextAnchor.MiddleCenter, Color.white, true, 35);
m_resizeCursorObj = text.gameObject; s_resizeCursorObj = text.gameObject;
RectTransform rect = m_resizeCursorObj.GetComponent<RectTransform>(); RectTransform rect = s_resizeCursorObj.GetComponent<RectTransform>();
rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, 64); rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, 64);
rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 64); rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 64);
m_resizeCursorObj.SetActive(false); s_resizeCursorObj.SetActive(false);
} }
catch (Exception e) catch (Exception e)
{ {

View File

@ -277,7 +277,6 @@
<Compile Include="UI\Widgets\InfiniteScroll\InfiniteScrollRect.cs" /> <Compile Include="UI\Widgets\InfiniteScroll\InfiniteScrollRect.cs" />
<Compile Include="UI\Widgets\InfiniteScroll\UIExtensions.cs" /> <Compile Include="UI\Widgets\InfiniteScroll\UIExtensions.cs" />
<Compile Include="UI\Widgets\InputFieldScroller.cs" /> <Compile Include="UI\Widgets\InputFieldScroller.cs" />
<Compile Include="UI\Widgets\PageHandler.cs" />
<Compile Include="UI\Widgets\SimpleList\SimpleCell.cs" /> <Compile Include="UI\Widgets\SimpleList\SimpleCell.cs" />
<Compile Include="UI\Widgets\SimpleList\SimpleListSource.cs" /> <Compile Include="UI\Widgets\SimpleList\SimpleListSource.cs" />
<Compile Include="UI\Widgets\SliderScrollbar.cs" /> <Compile Include="UI\Widgets\SliderScrollbar.cs" />