diff --git a/Runtime/Core/Vessel/XericUIExtendHelper.cs b/Runtime/Core/Vessel/XericUIExtendHelper.cs index a5528b5..2116633 100644 --- a/Runtime/Core/Vessel/XericUIExtendHelper.cs +++ b/Runtime/Core/Vessel/XericUIExtendHelper.cs @@ -10,7 +10,7 @@ namespace XericUI.Core.Vessel /// /// /// - public static bool IsValid(this ObjectVessel obj) + public static bool IsValidVessel(this ObjectVessel obj) where T0 : Object => obj != null && obj.Target != null; /// @@ -20,7 +20,7 @@ namespace XericUI.Core.Vessel /// /// /// - public static bool IsValid(this ObjectVessel obj) + public static bool IsValidVessel(this ObjectVessel obj) where T0 : Object where T1 : Object => obj != null && obj.Target0 != null && obj.Target1 != null; @@ -32,7 +32,7 @@ namespace XericUI.Core.Vessel /// /// /// - public static bool IsValid(this ObjectVessel obj) + public static bool IsValidVessel(this ObjectVessel obj) where T0 : Object where T1 : Object where T2 : Object diff --git a/Runtime/FlipPage/FlipPageComponentManager.cs b/Runtime/FlipPage/FlipPageComponentManager.cs index dfdeade..df61ab9 100644 --- a/Runtime/FlipPage/FlipPageComponentManager.cs +++ b/Runtime/FlipPage/FlipPageComponentManager.cs @@ -1,9 +1,13 @@ using System; using System.Collections.Generic; +using System.ComponentModel; +using JetBrains.Annotations; using Sirenix.OdinInspector; using UnityEngine; using UnityEngine.UI; +using XericLibrary.Runtime.MacroLibrary; using XericUI.Core.Vessel; +using Component = UnityEngine.Component; namespace XericUI.FlipPage { @@ -16,6 +20,17 @@ namespace XericUI.FlipPage { #region 界�属性 + /// + /// 候选页数� + /// +#if ODIN_INSPECTOR + [LabelText("候选页按最多显示")] + [BoxGroup("设定", centerLabel: true)] +#endif + [Tooltip("候选页按最多数�展示")] + [SerializeField] + protected bool inMaximumCandidatesNumber = true; + /// /// 首页按钮 /// @@ -52,20 +67,38 @@ namespace XericUI.FlipPage /// 总页�数�文本 /// #if ODIN_INSPECTOR + [Space(2)] [LabelText("总页�数�文本")] [BoxGroup("组件")] #endif public ObjectVessel labelTextTotalPageCount = new ObjectVessel(); - + /// - /// 总页�数�文本 + /// 总页�数�文本格�化 /// #if ODIN_INSPECTOR - [LabelText("总页�数�文本")] [BoxGroup("组件")] + [LabelText("总页�数�文本格�化")] [BoxGroup("设定")] +#endif + public string totalPageCountFormat = "共$1页"; + + /// + /// 页�索引文本格�化 + /// +#if ODIN_INSPECTOR + [LabelText("页�索引文本格�化")] [BoxGroup("设定")] +#endif + public string pageIndexFormat = "$1"; + + /// + /// 页�选择组件列表 + /// +#if ODIN_INSPECTOR + [LabelText("页�选择组件列表")] [BoxGroup("组件")] // [ListDrawerSettings(ShowIndexLabels = true)] #endif - public List> pageSelectButton = - new List>(); + [Tooltip("首个组件应当作为主�的节点管�")] + public List> pageSelectButton = + new List>(); /// /// 页�跳转输入框 @@ -73,8 +106,7 @@ namespace XericUI.FlipPage #if ODIN_INSPECTOR [LabelText("页�跳转输入框")] [BoxGroup("组件")] #endif - public ObjectVessel inputFieldFlipPageIndex = - new ObjectVessel(); + public ObjectVessel inputFieldFlipPageIndex; /// /// 翻页到索引按钮池 @@ -86,26 +118,114 @@ namespace XericUI.FlipPage #endregion + #region 字段属性 + + protected ToggleGroup ToggleGroup; + + #endregion + + #region 类内类型 + + /// + /// 页�与组件信� + /// + public class PageComponentInfo : PageInfo + { + /// + /// 页�翻页按钮 + /// +#if ODIN_INSPECTOR + [LabelText("页�翻页按钮")] +#endif + [CanBeNull] + internal ObjectVessel pageIndexSelectable; + + protected internal override void OnPageVisible(bool quickVisit) + { + if (quickVisit) + return; + + // 自动补全外部交互动画 + if (pageIndexSelectable.IsValidVessel() && + pageIndexSelectable.Target0 is Toggle toggle && + !toggle.isOn) + { + toggle.SetIsOnWithoutNotify(true); + + } + } + + protected internal override void OnPageInvisible(bool quickVisit) + { + } + } + + /// + /// 项目与组件信� + /// + public class ItemComponentInfo : ItemInfo + { + protected internal override void OnItemVisible() + { + } + + protected internal override void OnItemInvisible() + { + } + } + + #endregion + #region 生命周期 +#if UNITY_EDITOR + protected override void OnValidate() + { + base.OnValidate(); + // pageButtonPool.Prefab.GetComponent(); + } +#endif + protected override void Awake() { base.Awake(); - if (buttonStartPage.IsValid()) // 翻到开头 + if (buttonStartPage.IsValidVessel()) // 翻到开头 buttonStartPage.Target.onClick.AddListener(FlipPageToStart); - if (buttonPreviousPage.IsValid()) // 翻到上一页 + if (buttonPreviousPage.IsValidVessel()) // 翻到上一页 buttonPreviousPage.Target.onClick.AddListener(FlipPageToPrevious); - if (buttonNextPage.IsValid()) // 翻到下一页 + if (buttonNextPage.IsValidVessel()) // 翻到下一页 buttonNextPage.Target.onClick.AddListener(FlipPageToNext); - if (buttoneEndPage.IsValid()) // 翻到结尾 + if (buttoneEndPage.IsValidVessel()) // 翻到结尾 buttoneEndPage.Target.onClick.AddListener(FlipPageToEnd); + if (inputFieldFlipPageIndex.IsValidVessel()) // 翻到指定 + inputFieldFlipPageIndex.Target.onValueChanged.AddListener(s => FlipPage(s)); pageButtonPool.Init(); + + // 根�组件类型创建相关内容 + var prefabSelectable = pageButtonPool.Prefab.GetComponent(); + switch (prefabSelectable) + { + // �选项就创建但选项组 + case Toggle toggle: + ToggleGroup = transform.GetComponentAnyway(); + break; + case Button button: + break; + default: + break; + } } - private void Update() + protected override void OnFlipPage() { - if (labelTextTotalPageCount.IsValid()) // 页数 - labelTextTotalPageCount.Target.text = PageInfos.Count.ToString(); + base.OnFlipPage(); + + + // 刷新所有�员的层级顺� + for (int i = 0; i < pageSelectButton.Count; i++) + { + pageSelectButton[i].Target0.transform.SetSiblingIndex(i); + } } public override void FlipPage(int pageIndex, bool forceRefresh = false) @@ -114,10 +234,88 @@ namespace XericUI.FlipPage } - public override void AddPage(PageInfo pageInfo) + public override void AddPageFirst(PageInfo pageInfo) { - base.AddPage(pageInfo); - pageSelectButton.Add(GetPageIndexButton()); + if (pageInfo is not PageComponentInfo componentPageInfo) + { + Debug.LogError($"页�容器{currentPage}�支�当�管�器,其必须由{nameof(FlipPageComponentManager)}.{nameof(PageComponentInfo)}继承/声�,�则无法支��续功能", this); + return; + } + + AddPageIndexButton(componentPageInfo); + base.AddPageFirst(pageInfo); + + RefreshLabelTextTotalPageCount(); + RefreshPageIndeButtonState(); + } + + public override void AddPageLast(PageInfo pageInfo) + { + if (pageInfo is not PageComponentInfo componentPageInfo) + { + Debug.LogError($"页�容器{currentPage}�支�当�管�器,其必须由{nameof(FlipPageComponentManager)}.{nameof(PageComponentInfo)}继承/声�,�则无法支��续功能", this); + return; + } + + AddPageIndexButton(componentPageInfo); + base.AddPageLast(pageInfo); + + RefreshLabelTextTotalPageCount(); + RefreshPageIndeButtonState(); + } + + public override void RemovePage(int pageIndex) + { + base.RemovePage(pageIndex); + + pageButtonPool.DirectlyRelease(pageSelectButton[pageIndex].Target0.gameObject); + pageSelectButton.RemoveAt(pageIndex); + + RefreshPageIndeButtonState(); + } + + /// + /// 在页�上添加按钮 + /// + /// + private void AddPageIndexButton(PageComponentInfo pageInfo) + { + var pageIndexSelectable = GetPageIndexButton(); + pageInfo.pageIndexSelectable = pageIndexSelectable; + } + + /// + /// 刷新所有页�按钮的��性,索引 + /// + private void RefreshPageIndeButtonState() + { + var min = currentPageIndex - candidatesNumber / 2; + var max = currentPageIndex + candidatesNumber / 2; + for (int i = 0; i < pageSelectButton.Count; i++) + { + pageSelectButton[i].Target0.transform.SetSiblingIndex(i); + + // 显示数�控制 + if (inMaximumCandidatesNumber) + pageSelectButton[i].Target0.gameObject.SetActive(min <= i && i <= max); + else + pageSelectButton[i].Target0.gameObject.SetActive(min < i && i < max); + + // 更新索引 + if (pageSelectButton[i].Target0.gameObject.activeSelf) + { + pageSelectButton[i].Target1.text = MacroRegex.RegexReplace(pageIndexFormat, i); + } + } + } + + /// + /// 更新总页数 + /// + private void RefreshLabelTextTotalPageCount() + { + if (labelTextTotalPageCount.IsValidVessel()) // 总页数更新 + labelTextTotalPageCount.Target.text = MacroRegex.RegexReplace(totalPageCountFormat, PageInfos.Count.ToString()); } #endregion @@ -128,24 +326,26 @@ namespace XericUI.FlipPage /// 获�页�索引按钮 /// /// - protected virtual ObjectVessel GetPageIndexButton() + protected virtual ObjectVessel GetPageIndexButton() { var obj = pageButtonPool.Get(); - var button = obj.GetComponent