mirror of
https://github.com/sinai-dev/UnityExplorer.git
synced 2025-01-07 18:13:35 +08:00
Update PanelDragger to handle multiple panels, add panel 'focusing'
This commit is contained in:
parent
876cffd864
commit
2e5fb72716
@ -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)
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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" />
|
||||||
|
Loading…
x
Reference in New Issue
Block a user