Files
UltimateFishing/Assets/Scripts/Assembly-CSharp/UIWidgets/ResizableHeader.cs
2026-02-21 16:45:37 +08:00

466 lines
12 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
namespace UIWidgets
{
[RequireComponent(typeof(LayoutGroup))]
public class ResizableHeader : MonoBehaviour, IDropSupport<ResizableHeaderDragCell>
{
[SerializeField]
public ListViewBase List;
[SerializeField]
public bool AllowResize = true;
[SerializeField]
public bool AllowReorder = true;
[NonSerialized]
[HideInInspector]
public bool ProcessCellReorder;
[SerializeField]
public bool OnDragUpdate = true;
[SerializeField]
public float ActiveRegion = 5f;
[SerializeField]
public Camera CurrentCamera;
[SerializeField]
public Texture2D CursorTexture;
[SerializeField]
public Vector2 CursorHotSpot = new Vector2(16f, 16f);
[SerializeField]
public Texture2D AllowDropCursor;
[SerializeField]
public Vector2 AllowDropCursorHotSpot = new Vector2(4f, 2f);
[SerializeField]
public Texture2D DeniedDropCursor;
[SerializeField]
public Vector2 DeniedDropCursorHotSpot = new Vector2(4f, 2f);
[SerializeField]
public Texture2D DefaultCursorTexture;
[SerializeField]
public Vector2 DefaultCursorHotSpot;
private RectTransform rectTransform;
private Canvas canvas;
private RectTransform canvasRect;
private List<LayoutElement> childrenLayouts = new List<LayoutElement>();
private List<RectTransform> children = new List<RectTransform>();
private List<int> positions;
private LayoutElement leftTarget;
private LayoutElement rightTarget;
private bool processDrag;
private List<float> widths;
private LayoutGroup layout;
private bool inActiveRegion;
private float widthLimit;
private List<RaycastResult> raycastResults = new List<RaycastResult>();
public RectTransform RectTransform
{
get
{
if (rectTransform == null)
{
rectTransform = base.transform as RectTransform;
}
return rectTransform;
}
}
public bool InActiveRegion
{
get
{
return inActiveRegion;
}
}
private void Start()
{
layout = GetComponent<LayoutGroup>();
if (layout != null)
{
Utilites.UpdateLayout(layout);
}
Init();
}
public void OnInitializePotentialDrag(PointerEventData eventData)
{
}
public void Init()
{
canvasRect = Utilites.FindCanvas(base.transform) as RectTransform;
canvas = canvasRect.GetComponent<Canvas>();
children.Clear();
childrenLayouts.Clear();
int num = 0;
foreach (Transform item2 in base.transform)
{
LayoutElement item = item2.GetComponent<LayoutElement>() ?? item2.gameObject.AddComponent<LayoutElement>();
children.Add(item2 as RectTransform);
childrenLayouts.Add(item);
ResizableHeaderDragCell resizableHeaderDragCell = item2.gameObject.AddComponent<ResizableHeaderDragCell>();
resizableHeaderDragCell.Position = num;
resizableHeaderDragCell.ResizableHeader = this;
resizableHeaderDragCell.AllowDropCursor = AllowDropCursor;
resizableHeaderDragCell.AllowDropCursorHotSpot = AllowDropCursorHotSpot;
resizableHeaderDragCell.DeniedDropCursor = DeniedDropCursor;
resizableHeaderDragCell.DeniedDropCursorHotSpot = DeniedDropCursorHotSpot;
ResizableHeaderCell resizableHeaderCell = item2.gameObject.AddComponent<ResizableHeaderCell>();
resizableHeaderCell.OnInitializePotentialDragEvent.AddListener(OnInitializePotentialDrag);
resizableHeaderCell.OnBeginDragEvent.AddListener(OnBeginDrag);
resizableHeaderCell.OnDragEvent.AddListener(OnDrag);
resizableHeaderCell.OnEndDragEvent.AddListener(OnEndDrag);
num++;
}
positions = Enumerable.Range(0, num).ToList();
CalculateWidths();
}
private void LateUpdate()
{
if (AllowResize && !processDrag && !ProcessCellReorder && !(CursorTexture == null) && Input.mousePresent)
{
inActiveRegion = CheckInActiveRegion(Input.mousePosition, CurrentCamera);
if (inActiveRegion)
{
Cursor.SetCursor(CursorTexture, CursorHotSpot, Utilites.GetCursorMode());
}
else
{
Cursor.SetCursor(DefaultCursorTexture, DefaultCursorHotSpot, Utilites.GetCursorMode());
}
}
}
private bool CheckInActiveRegion(Vector2 position, Camera currentCamera)
{
bool flag = false;
Vector2 localPoint;
if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(RectTransform, position, currentCamera, out localPoint))
{
return false;
}
Rect rect = RectTransform.rect;
if (!rect.Contains(localPoint))
{
return false;
}
localPoint += new Vector2(rect.width * RectTransform.pivot.x, 0f);
int num = 0;
foreach (RectTransform child in children)
{
if (num != 0)
{
flag = CheckLeft(child, localPoint);
if (flag)
{
break;
}
}
if (num != children.Count - 1)
{
flag = CheckRight(child, localPoint);
if (flag)
{
break;
}
}
num++;
}
return flag;
}
public virtual void OnBeginDrag(PointerEventData eventData)
{
if (!AllowResize || ProcessCellReorder)
{
return;
}
processDrag = false;
Vector2 localPoint;
if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(RectTransform, eventData.pressPosition, eventData.pressEventCamera, out localPoint))
{
return;
}
localPoint += new Vector2(RectTransform.rect.width * RectTransform.pivot.x, 0f);
int num = 0;
foreach (RectTransform child in children)
{
if (num != 0)
{
processDrag = CheckLeft(child, localPoint);
if (processDrag)
{
leftTarget = childrenLayouts[num - 1];
rightTarget = childrenLayouts[num];
widthLimit = children[num - 1].rect.width + children[num].rect.width;
break;
}
}
if (num != children.Count - 1)
{
processDrag = CheckRight(child, localPoint);
if (processDrag)
{
leftTarget = childrenLayouts[num];
rightTarget = childrenLayouts[num + 1];
widthLimit = children[num].rect.width + children[num + 1].rect.width;
break;
}
}
num++;
}
}
private bool CheckLeft(RectTransform childRectTransform, Vector2 point)
{
Rect rect = childRectTransform.rect;
rect.position += new Vector2(childRectTransform.anchoredPosition.x, 0f);
rect.width = ActiveRegion;
return rect.Contains(point);
}
private bool CheckRight(RectTransform childRectTransform, Vector2 point)
{
Rect rect = childRectTransform.rect;
rect.position += new Vector2(childRectTransform.anchoredPosition.x, 0f);
rect.position = new Vector2(rect.position.x + rect.width - ActiveRegion - 1f, rect.position.y);
rect.width = ActiveRegion + 1f;
return rect.Contains(point);
}
public void OnEndDrag(PointerEventData eventData)
{
if (processDrag)
{
Cursor.SetCursor(DefaultCursorTexture, DefaultCursorHotSpot, Utilites.GetCursorMode());
CalculateWidths();
ResetChildren();
if (!OnDragUpdate)
{
Resize();
}
processDrag = false;
}
}
public void OnDrag(PointerEventData eventData)
{
if (processDrag)
{
if (canvas == null)
{
throw new MissingComponentException(base.gameObject.name + " not in Canvas hierarchy.");
}
Cursor.SetCursor(CursorTexture, CursorHotSpot, Utilites.GetCursorMode());
Vector2 localPoint;
RectTransformUtility.ScreenPointToLocalPointInRectangle(RectTransform, eventData.position, CurrentCamera, out localPoint);
Vector2 localPoint2;
RectTransformUtility.ScreenPointToLocalPointInRectangle(RectTransform, eventData.position - eventData.delta, CurrentCamera, out localPoint2);
Vector2 vector = localPoint - localPoint2;
if (vector.x > 0f)
{
leftTarget.preferredWidth = Mathf.Min(leftTarget.preferredWidth + vector.x, widthLimit - rightTarget.minWidth);
rightTarget.preferredWidth = widthLimit - leftTarget.preferredWidth;
}
else
{
rightTarget.preferredWidth = Mathf.Min(rightTarget.preferredWidth - vector.x, widthLimit - leftTarget.minWidth);
leftTarget.preferredWidth = widthLimit - rightTarget.preferredWidth;
}
if (layout != null)
{
Utilites.UpdateLayout(layout);
}
if (OnDragUpdate)
{
CalculateWidths();
Resize();
}
}
}
private float GetRectWidth(RectTransform rect)
{
return rect.rect.width;
}
private void CalculateWidths()
{
widths = children.Select(GetRectWidth).ToList();
}
private void ResetChildren()
{
childrenLayouts.ForEach(ResetChildrenWidth);
}
private void ResetChildrenWidth(LayoutElement element, int index)
{
element.preferredWidth = widths[index];
}
public void Resize()
{
if (!(List == null) && widths.Count >= 2)
{
List.Start();
List.ForEachComponent(ResizeComponent);
}
}
private void Reorder()
{
if (!(List == null) && widths.Count >= 2)
{
List.Start();
List.ForEachComponent(ReorderComponent);
}
}
private void ResizeGameObject(GameObject go, int i)
{
LayoutElement component = go.GetComponent<LayoutElement>();
int index = positions.IndexOf(i);
if ((bool)component)
{
component.preferredWidth = widths[index];
}
else
{
(go.transform as RectTransform).SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, widths[index]);
}
}
private void ResizeComponent(ListViewItem component)
{
IResizableItem resizableItem = component as IResizableItem;
if (resizableItem != null)
{
resizableItem.ObjectsToResize.ForEach(ResizeGameObject);
}
}
private void ReorderComponent(ListViewItem component)
{
IResizableItem resizableItem = component as IResizableItem;
if (resizableItem == null)
{
return;
}
GameObject[] objectsToResize = resizableItem.ObjectsToResize;
int num = 0;
foreach (int position in positions)
{
objectsToResize[position].transform.SetSiblingIndex(num);
num++;
}
}
public void Reorder(int oldColumnPosition, int newColumnPosition)
{
int num = positions.IndexOf(oldColumnPosition);
int num2 = positions.IndexOf(newColumnPosition);
children[num].SetSiblingIndex(num2);
ChangePosition(childrenLayouts, num, num2);
ChangePosition(children, num, num2);
ChangePosition(positions, num, num2);
Reorder();
}
public bool CanReceiveDrop(ResizableHeaderDragCell cell, PointerEventData eventData)
{
if (!AllowReorder)
{
return false;
}
ResizableHeaderDragCell resizableHeaderDragCell = FindTarget(eventData);
return resizableHeaderDragCell != null && resizableHeaderDragCell != cell;
}
public void Drop(ResizableHeaderDragCell cell, PointerEventData eventData)
{
ResizableHeaderDragCell resizableHeaderDragCell = FindTarget(eventData);
Reorder(cell.Position, resizableHeaderDragCell.Position);
}
public void DropCanceled(ResizableHeaderDragCell cell, PointerEventData eventData)
{
}
private void ChangePosition<T>(List<T> list, int oldPosition, int newPosition)
{
T item = list[oldPosition];
list.RemoveAt(oldPosition);
list.Insert(newPosition, item);
}
private ResizableHeaderDragCell FindTarget(PointerEventData eventData)
{
raycastResults.Clear();
EventSystem.current.RaycastAll(eventData, raycastResults);
foreach (RaycastResult raycastResult in raycastResults)
{
if (raycastResult.isValid)
{
ResizableHeaderDragCell component = raycastResult.gameObject.GetComponent<ResizableHeaderDragCell>();
if (component != null && component.transform.IsChildOf(base.transform))
{
return component;
}
}
}
return null;
}
private void OnDestroy()
{
children.Clear();
childrenLayouts.Clear();
foreach (Transform item in base.transform)
{
ResizableHeaderCell component = item.GetComponent<ResizableHeaderCell>();
if (!(component == null))
{
component.OnInitializePotentialDragEvent.RemoveListener(OnInitializePotentialDrag);
component.OnBeginDragEvent.RemoveListener(OnBeginDrag);
component.OnDragEvent.RemoveListener(OnDrag);
component.OnEndDragEvent.RemoveListener(OnEndDrag);
}
}
}
}
}