首次提交
This commit is contained in:
25
Assets/Scripts/UI/Common/List/ClassifyList.Designer.cs
generated
Normal file
25
Assets/Scripts/UI/Common/List/ClassifyList.Designer.cs
generated
Normal file
@@ -0,0 +1,25 @@
|
||||
/**本脚本为自动生成,每次生成会覆盖!请勿手动修改,生成插件文档及项目地址:https://git.whoot.com/whoot-games/whoot.fguieditorplugin**/
|
||||
|
||||
|
||||
using FairyGUI;
|
||||
using FairyGUI.Utils;
|
||||
using NBC;
|
||||
|
||||
namespace NBF
|
||||
{
|
||||
public partial class ClassifyList
|
||||
{
|
||||
public const string URL = "ui://6hgkvlaudrkwh1";
|
||||
|
||||
public GList List;
|
||||
|
||||
public override void ConstructFromXML(XML xml)
|
||||
{
|
||||
base.ConstructFromXML(xml);
|
||||
|
||||
List = (GList)GetChild("List");
|
||||
OnInited();
|
||||
UILanguage.TrySetComponentLanguage(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 75f98daf87c484ef782216da87003f53
|
||||
126
Assets/Scripts/UI/Common/List/ClassifyList.cs
Normal file
126
Assets/Scripts/UI/Common/List/ClassifyList.cs
Normal file
@@ -0,0 +1,126 @@
|
||||
// 本脚本只在不存在时会生成一次。组件逻辑写在当前脚本内。已存在不会再次生成覆盖
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using FairyGUI;
|
||||
using Fantasy;
|
||||
using Log = NBC.Log;
|
||||
|
||||
namespace NBF
|
||||
{
|
||||
public class ClassifyListTitleData
|
||||
{
|
||||
public string Title;
|
||||
}
|
||||
|
||||
public partial class ClassifyList : GComponent
|
||||
{
|
||||
private readonly List<object> _listData = new List<object>();
|
||||
|
||||
public event Action<object> OnClickItem;
|
||||
public event Action<object> OnDoubleClickItem;
|
||||
|
||||
private int _columnsCount;
|
||||
|
||||
public ListSelector Selector;
|
||||
|
||||
private void OnInited()
|
||||
{
|
||||
List.onClickItem.Add(OnClickListItem);
|
||||
Selector = new ListSelector(List, typeof(ListTitleItem));
|
||||
}
|
||||
|
||||
public void InvokeClickItem(object data)
|
||||
{
|
||||
OnClickItem?.Invoke(data);
|
||||
}
|
||||
|
||||
|
||||
public void SetListData(List<object> listData,
|
||||
ListSelectionMode selectionMode = ListSelectionMode.Single)
|
||||
{
|
||||
List.selectedIndex = -1;
|
||||
_listData.Clear();
|
||||
|
||||
foreach (var obj in listData)
|
||||
{
|
||||
_listData.Add(obj);
|
||||
}
|
||||
|
||||
List.RemoveChildrenToPool();
|
||||
List.defaultItem = ListTitleItem.URL;
|
||||
List.itemProvider = GetListItemResource;
|
||||
List.itemRenderer = OnRenderItem;
|
||||
List.selectionMode = selectionMode;
|
||||
try
|
||||
{
|
||||
List.numItems = _listData.Count;
|
||||
List.ScrollToView(0);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error(e);
|
||||
}
|
||||
|
||||
_columnsCount = 6;
|
||||
Selector.Refresh();
|
||||
}
|
||||
|
||||
void OnClickListItem(EventContext context)
|
||||
{
|
||||
OnClickItem?.Invoke(context.data);
|
||||
if (context.inputEvent.isDoubleClick)
|
||||
{
|
||||
OnDoubleClickItem?.Invoke(context.data);
|
||||
}
|
||||
}
|
||||
|
||||
void OnRenderItem(int index, GObject obj)
|
||||
{
|
||||
var itemData = _listData[index];
|
||||
if (obj is ListItemBase item)
|
||||
{
|
||||
item.SetData(itemData);
|
||||
}
|
||||
else if (obj is BagItem bagItem)
|
||||
{
|
||||
bagItem.SetData(itemData as ItemInfo);
|
||||
}
|
||||
else if (obj is ListTitleItem titleItem)
|
||||
{
|
||||
titleItem.SetData(itemData);
|
||||
titleItem.SetSize(List.width, 32);
|
||||
}
|
||||
else if (obj is ShopGearItem shopGearItem)
|
||||
{
|
||||
shopGearItem.SetData(itemData as ShopItemInfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//根据索引的不同,返回不同的资源URL
|
||||
string GetListItemResource(int index)
|
||||
{
|
||||
var itemData = _listData[index];
|
||||
|
||||
|
||||
if (itemData is ItemInfo itemInfo)
|
||||
{
|
||||
return BagItem.URL;
|
||||
}
|
||||
|
||||
if (itemData is ShopItemInfo shopItemInfo)
|
||||
{
|
||||
return ShopGearItem.URL;
|
||||
}
|
||||
|
||||
if (itemData is ClassifyListTitleData titleData)
|
||||
{
|
||||
return ListTitleItem.URL;
|
||||
}
|
||||
|
||||
return List.defaultItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
2
Assets/Scripts/UI/Common/List/ClassifyList.cs.meta
Normal file
2
Assets/Scripts/UI/Common/List/ClassifyList.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ec101ca53ba6849efa2e51492b6310cf
|
||||
27
Assets/Scripts/UI/Common/List/CommonItemList.Designer.cs
generated
Normal file
27
Assets/Scripts/UI/Common/List/CommonItemList.Designer.cs
generated
Normal file
@@ -0,0 +1,27 @@
|
||||
/**本脚本为自动生成,每次生成会覆盖!请勿手动修改,生成插件文档及项目地址:https://git.whoot.com/whoot-games/whoot.fguieditorplugin**/
|
||||
|
||||
|
||||
using FairyGUI;
|
||||
using FairyGUI.Utils;
|
||||
using NBC;
|
||||
|
||||
namespace NBF
|
||||
{
|
||||
public partial class CommonItemList
|
||||
{
|
||||
public const string URL = "ui://6hgkvlaup1fps";
|
||||
|
||||
public CommonMenu Menu;
|
||||
public ClassifyList List;
|
||||
|
||||
public override void ConstructFromXML(XML xml)
|
||||
{
|
||||
base.ConstructFromXML(xml);
|
||||
|
||||
Menu = (CommonMenu)GetChild("Menu");
|
||||
List = (ClassifyList)GetChild("List");
|
||||
OnInited();
|
||||
UILanguage.TrySetComponentLanguage(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 28dc4cb333840804fb479364c41ad525
|
||||
101
Assets/Scripts/UI/Common/List/CommonItemList.cs
Normal file
101
Assets/Scripts/UI/Common/List/CommonItemList.cs
Normal file
@@ -0,0 +1,101 @@
|
||||
// 本脚本只在不存在时会生成一次。组件逻辑写在当前脚本内。已存在不会再次生成覆盖
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using FairyGUI;
|
||||
using NBC;
|
||||
using UIPanel = NBC.UIPanel;
|
||||
|
||||
namespace NBF
|
||||
{
|
||||
public partial class CommonItemList : GComponent
|
||||
{
|
||||
private List<TabItemData> _tabList = new List<TabItemData>();
|
||||
private TabItemData _currentTab;
|
||||
|
||||
|
||||
private void OnInited()
|
||||
{
|
||||
Menu.OnTabChange += ChangeTab;
|
||||
// SubMenu.OnTabChange += ChangeSubTab;
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
Menu.OnTabChange -= ChangeTab;
|
||||
// SubMenu.OnTabChange -= ChangeSubTab;
|
||||
base.Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="tabItemList"></param>
|
||||
/// <param name="showAll">是否显示全部页签</param>
|
||||
/// <param name="showListTitle">是否列表页显示分类标题</param>
|
||||
public void SetData(List<TabItemData> tabItemList, bool showAll = false, bool showListTitle = true)
|
||||
{
|
||||
_tabList.Clear();
|
||||
_currentTab = null;
|
||||
// style.selectedIndex = 0; //一级菜单
|
||||
// if (tabItemList.Any(tabItem => tabItem.Children.Count > 0))
|
||||
// {
|
||||
// style.selectedIndex = 1; //有二级菜单
|
||||
// }
|
||||
|
||||
_tabList.AddRange(tabItemList);
|
||||
|
||||
if (showListTitle)
|
||||
{
|
||||
foreach (var tabItemData in _tabList)
|
||||
{
|
||||
tabItemData.TabItemDataAddListTitle();
|
||||
if (tabItemData.Children.Count > 0)
|
||||
{
|
||||
foreach (var itemData in tabItemData.Children)
|
||||
{
|
||||
itemData.TabItemDataAddListTitle();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (showAll)
|
||||
{
|
||||
_tabList.AddAllTabItem();
|
||||
}
|
||||
|
||||
Menu.SetTabs(_tabList);
|
||||
}
|
||||
|
||||
private void ChangeTab(int index)
|
||||
{
|
||||
if (index < 0) return;
|
||||
var tabListData = _tabList[index];
|
||||
_currentTab = tabListData;
|
||||
// if (style.selectedIndex == 0)
|
||||
{
|
||||
//只有一级菜单
|
||||
List.SetListData(_currentTab.Items);
|
||||
}
|
||||
// else
|
||||
// {
|
||||
// SubMenu.SetTabs(_currentTab.Children);
|
||||
// }
|
||||
}
|
||||
|
||||
private void ChangeSubTab(int index)
|
||||
{
|
||||
if (index < 0) return;
|
||||
if (_currentTab == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var subList = _currentTab.Children[index];
|
||||
List.SetListData(subList.Items);
|
||||
}
|
||||
}
|
||||
}
|
||||
2
Assets/Scripts/UI/Common/List/CommonItemList.cs.meta
Normal file
2
Assets/Scripts/UI/Common/List/CommonItemList.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cb564f321c6947e45a44cdd07cd48a8b
|
||||
202
Assets/Scripts/UI/Common/List/ListSelector.cs
Normal file
202
Assets/Scripts/UI/Common/List/ListSelector.cs
Normal file
@@ -0,0 +1,202 @@
|
||||
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 object SelectedItem => _list.selectedIndex > 0 ? _list.GetChildAt(_list.selectedIndex) : null;
|
||||
|
||||
public ListSelector(GList list, params Type[] ignores)
|
||||
{
|
||||
_list = list;
|
||||
if (ignores != null && ignores.Length > 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 && (direction == Vector2.left || direction == Vector2.right))
|
||||
{
|
||||
if (direction == Vector2.left)
|
||||
{
|
||||
// 寻找前一个可选项
|
||||
nearestIndex = FindPreviousSelectableItem(_list.selectedIndex);
|
||||
}
|
||||
else if (direction == Vector2.right)
|
||||
{
|
||||
// 寻找后一个可选项
|
||||
nearestIndex = FindNextSelectableItem(_list.selectedIndex);
|
||||
}
|
||||
}
|
||||
|
||||
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 int FindPreviousSelectableItem(int currentIndex)
|
||||
{
|
||||
for (int i = currentIndex - 1; i >= 0; i--)
|
||||
{
|
||||
if (IsSelectableItem(i))
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
private int FindNextSelectableItem(int currentIndex)
|
||||
{
|
||||
for (int i = currentIndex + 1; i < _list.numItems; i++)
|
||||
{
|
||||
if (IsSelectableItem(i))
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
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);
|
||||
var ret = !_ignores.Contains(item.GetType());
|
||||
if (item.GetType() == typeof(ListTitleItem))
|
||||
{
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
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;
|
||||
_list.ScrollToView(index, true);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/UI/Common/List/ListSelector.cs.meta
Normal file
3
Assets/Scripts/UI/Common/List/ListSelector.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 48f217b6f1dd4dc98d1b6e1c61f9ed65
|
||||
timeCreated: 1761838465
|
||||
Reference in New Issue
Block a user