2024-09-18 15:19:38 +00:00
|
|
|
|
using System;
|
2024-09-14 15:38:57 +00:00
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using Godot;
|
|
|
|
|
|
|
|
|
|
namespace ColdMint.scripts.utils;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// <para>UI Group</para>
|
|
|
|
|
/// <para>UI组</para>
|
|
|
|
|
/// </summary>
|
|
|
|
|
public partial class UiGroup : Control
|
|
|
|
|
{
|
|
|
|
|
private readonly HashSet<Control> _visibleControls = [];
|
2024-09-18 15:19:38 +00:00
|
|
|
|
private readonly Dictionary<string, Func<Control?>> _controlFunc = new();
|
2024-09-14 15:38:57 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
2024-09-18 15:19:38 +00:00
|
|
|
|
/// <para>Holds the node that has been instantiated</para>
|
|
|
|
|
/// <para>持有已实例化的节点</para>
|
2024-09-14 15:38:57 +00:00
|
|
|
|
/// </summary>
|
2024-09-18 15:19:38 +00:00
|
|
|
|
private readonly Dictionary<string, Control> _instantiatedControl = new();
|
2024-09-14 15:38:57 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
2024-09-18 15:19:38 +00:00
|
|
|
|
/// <para>Registered control node</para>
|
|
|
|
|
/// <para>注册控制节点</para>
|
2024-09-14 15:38:57 +00:00
|
|
|
|
/// </summary>
|
2024-09-18 15:19:38 +00:00
|
|
|
|
/// <param name="key">
|
|
|
|
|
///<para>key</para>
|
|
|
|
|
///<para>控制节点的key</para>
|
|
|
|
|
/// </param>
|
|
|
|
|
/// <param name="func">
|
|
|
|
|
///<para>Creates a function to control the node. UiGroup delays calling this function to create the node.</para>
|
|
|
|
|
///<para>创建控制节点的函数,UiGroup会延迟调用这个函数创建节点。</para>
|
|
|
|
|
/// </param>
|
|
|
|
|
public void RegisterControl(string key, Func<Control?> func)
|
|
|
|
|
{
|
|
|
|
|
_controlFunc.TryAdd(key, func);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// <para>Obtain or create a controller node</para>
|
|
|
|
|
/// <para>获取或者创建控制节点</para>
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="key"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
private Control? GetOrCreateControl(string key)
|
2024-09-14 15:38:57 +00:00
|
|
|
|
{
|
2024-09-18 15:19:38 +00:00
|
|
|
|
if (_instantiatedControl.TryGetValue(key, out var instantiatedControl))
|
|
|
|
|
{
|
|
|
|
|
return instantiatedControl;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!_controlFunc.TryGetValue(key, out var func))
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var control = func.Invoke();
|
|
|
|
|
if (control == null)
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
control.Hide();
|
|
|
|
|
control.TreeExited += () => { OnTreeExited(key, control); };
|
2024-09-14 15:38:57 +00:00
|
|
|
|
NodeUtils.CallDeferredAddChild(this, control);
|
2024-09-18 15:19:38 +00:00
|
|
|
|
_instantiatedControl.Add(key, control);
|
|
|
|
|
return control;
|
2024-09-14 15:38:57 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// <para>Hide all nodes</para>
|
|
|
|
|
/// <para>隐藏全部节点</para>
|
|
|
|
|
/// </summary>
|
|
|
|
|
public void HideAllControl()
|
|
|
|
|
{
|
|
|
|
|
if (_visibleControls.Count == 0)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach (var visibleControl in _visibleControls)
|
|
|
|
|
{
|
|
|
|
|
visibleControl.Hide();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_visibleControls.Clear();
|
|
|
|
|
Hide();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// <para>Hide a node</para>
|
|
|
|
|
/// <para>隐藏某个节点</para>
|
|
|
|
|
/// </summary>
|
2024-09-18 15:19:38 +00:00
|
|
|
|
/// <param name="key"></param>
|
2024-09-14 15:38:57 +00:00
|
|
|
|
/// <returns></returns>
|
2024-09-18 15:19:38 +00:00
|
|
|
|
public bool HideControl(string key)
|
2024-09-14 15:38:57 +00:00
|
|
|
|
{
|
2024-09-18 15:19:38 +00:00
|
|
|
|
if (!_instantiatedControl.TryGetValue(key, out var control))
|
2024-09-14 15:38:57 +00:00
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-18 15:19:38 +00:00
|
|
|
|
return HideControl(control);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// <para>Hide a node</para>
|
|
|
|
|
/// <para>隐藏某个节点</para>
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="control"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public bool HideControl(Control control)
|
|
|
|
|
{
|
|
|
|
|
if (!control.IsVisible())
|
2024-09-14 15:38:57 +00:00
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
control.Hide();
|
|
|
|
|
_visibleControls.Remove(control);
|
|
|
|
|
ChangeSelfVisibility();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// <para>Show node</para>
|
|
|
|
|
/// <para>显示某个节点</para>
|
|
|
|
|
/// </summary>
|
2024-09-18 15:19:38 +00:00
|
|
|
|
/// <param name="key"></param>
|
|
|
|
|
/// <param name="beforeDisplayControl">
|
|
|
|
|
///<para>A callback function before the display node where you can generate rendered page content. For example, set the title</para>
|
|
|
|
|
///<para>在显示节点之前的回调函数,您可以在此函数内生成渲染页面内容。例如:设置标题</para>
|
|
|
|
|
/// </param>
|
2024-09-14 15:38:57 +00:00
|
|
|
|
/// <returns></returns>
|
2024-09-18 15:19:38 +00:00
|
|
|
|
public bool ShowControl(string key, Action<Control>? beforeDisplayControl = null)
|
2024-09-14 15:38:57 +00:00
|
|
|
|
{
|
2024-09-18 15:19:38 +00:00
|
|
|
|
var control = GetOrCreateControl(key);
|
|
|
|
|
if (control == null)
|
2024-09-14 15:38:57 +00:00
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-18 15:19:38 +00:00
|
|
|
|
if (control.IsVisible())
|
2024-09-14 15:38:57 +00:00
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-18 15:19:38 +00:00
|
|
|
|
if (beforeDisplayControl != null)
|
|
|
|
|
{
|
|
|
|
|
beforeDisplayControl.Invoke(control);
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-14 15:38:57 +00:00
|
|
|
|
control.Show();
|
|
|
|
|
_visibleControls.Add(control);
|
|
|
|
|
ChangeSelfVisibility();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// <para>ChangeSelfVisibility</para>
|
|
|
|
|
/// <para>改变自身的可见度</para>
|
|
|
|
|
/// </summary>
|
|
|
|
|
private void ChangeSelfVisibility()
|
|
|
|
|
{
|
|
|
|
|
if (_visibleControls.Count == 0)
|
|
|
|
|
{
|
|
|
|
|
Hide();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Show();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-18 15:19:38 +00:00
|
|
|
|
private void OnTreeExited(string key, Control control)
|
2024-09-14 15:38:57 +00:00
|
|
|
|
{
|
|
|
|
|
//The Hide method is not called when a node exits from the tree, so remove the node here to prevent empty references.
|
|
|
|
|
//当节点从节点树内退出时,并不会调用Hide方法,所以在这里移除节点,防止产生空引用。
|
|
|
|
|
_visibleControls.Remove(control);
|
2024-09-18 15:19:38 +00:00
|
|
|
|
_instantiatedControl.Remove(key);
|
2024-09-14 15:38:57 +00:00
|
|
|
|
}
|
|
|
|
|
}
|