Files
Fishing2/Assets/Scripts/UI/Common/List/ListSelector.cs
2025-10-30 23:54:43 +08:00

158 lines
4.1 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections.Generic;
using FairyGUI;
using UnityEngine;
namespace NBF
{
public class ListSelector
{
private GList _list;
private readonly List<Type> _ignores = new List<Type>();
// private readonly List<GObject> _items = new List<GObject>();
private float itemWidth = 200f;
private float itemHeight = 180f;
public ListSelector(GList list, params Type[] ignores)
{
_list = list;
if (ignores != null && _ignores.Count > 0)
{
_ignores.AddRange(_ignores);
}
}
#region
public void Refresh()
{
var children = _list.GetChildren();
foreach (var item in children)
{
if (_ignores.Contains(item.GetType())) continue;
itemWidth = item.width;
itemHeight = item.height;
break;
}
}
#endregion
#region
public void Up()
{
Move(Vector2.up);
}
public void Down()
{
Move(Vector2.down);
}
public void Right()
{
Move(Vector2.right);
}
public void Left()
{
Move(Vector2.left);
}
public void Move(Vector2 direction)
{
if (_list.selectedIndex == -1)
{
// 首次选择第一个可选中项
SelectFirstSelectable();
return;
}
var currentPos = GetItemPosition(_list.selectedIndex);
var nearestIndex = FindNearestSelectableItem(currentPos, direction);
if (nearestIndex != -1)
{
SetSelection(nearestIndex);
}
}
#endregion
#region
private Vector2 GetItemPosition(int index)
{
var item = _list.GetChildAt(index);
return item.position;
}
private int FindNearestSelectableItem(Vector2 fromPos, Vector2 direction)
{
var bestIndex = -1;
var bestDistance = float.MaxValue;
for (var i = 0; i < _list.numItems; i++)
{
if (!IsSelectableItem(i)) continue;
var targetPos = GetItemPosition(i);
var diff = targetPos - fromPos;
// 检查方向匹配度
if (IsDirectionMatch(direction, diff))
{
var distance = Vector2.Distance(fromPos, targetPos);
if (distance < bestDistance && distance > 0.1f)
{
bestDistance = distance;
bestIndex = i;
}
}
}
return bestIndex;
}
private bool IsDirectionMatch(Vector2 direction, Vector2 diff)
{
if (direction == Vector2.up)
return diff.y < 0 && Mathf.Abs(diff.x) < itemWidth; // 修正向上应该是Y值更小
if (direction == Vector2.down)
return diff.y > 0 && Mathf.Abs(diff.x) < itemWidth; // 修正向下应该是Y值更大
if (direction == Vector2.left)
return diff.x < 0 && Mathf.Abs(diff.y) < itemHeight;
if (direction == Vector2.right)
return diff.x > 0 && Mathf.Abs(diff.y) < itemHeight;
return false;
}
private bool IsSelectableItem(int index)
{
var item = _list.GetChildAt(index);
return !_ignores.Contains(item.GetType());
}
private void SelectFirstSelectable()
{
for (var i = 0; i < _list.numItems; i++)
{
if (IsSelectableItem(i))
{
SetSelection(i);
break;
}
}
}
private void SetSelection(int index)
{
_list.selectedIndex = index;
// selection.position = items[index].position;
}
#endregion
}
}