VirtualFramework/Assets/Scripts/UI/UIBody3DMenuTree.cs
2025-02-18 13:30:35 +08:00

226 lines
8.7 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 UnityEngine;
using UnityEngine.UI;
using XMLTool;
using System.Collections.Generic;
using TMPro;
namespace QFramework.Example
{
public class UIBody3DMenuTreeData : UIPanelData
{
public Body3D.Body body;
}
public partial class UIBody3DMenuTree : UIPanel
{
/// <summary>
/// 搜索结果按钮与菜单按钮的对应
/// </summary>
Dictionary<GameObject, GameObject> searchItemMap = new Dictionary<GameObject, GameObject>();
protected override void OnInit(IUIData uiData = null)
{
// please add init code here
Close.onClick.AddListener(() =>
{
Hide();
UIKit.OpenPanelAsync<UIBody3D>().ToAction().StartGlobal();
});
Input.onSelect.AddListener(str =>
{
Debug.LogError("onSelect:" + str);
SearchContent.gameObject.SetActive(true);
Content.gameObject.SetActive(false);
});
Input.onEndEdit.AddListener(str =>
{
Debug.LogError("onEndEdit:" + str);
if (string.IsNullOrEmpty(str))
{
SearchContent.gameObject.SetActive(false);
Content.gameObject.SetActive(true);
SearchContent.RemoveAllChildren();
}
else
{
SearchContent.gameObject.SetActive(true);
Content.gameObject.SetActive(false);
RefreshSearchContent(str);
}
});
}
protected override void OnOpen(IUIData uiData = null)
{
mData = uiData as UIBody3DMenuTreeData ?? new UIBody3DMenuTreeData();
Content.RemoveAllChildren();
BuildTreeUI(mData.body);
}
private void BuildTreeUI(Body3D.Body data, int depth = 0, Transform parent = null)
{
foreach (var bodyPair in data.subBody)
{
Body3D.Body body = bodyPair.Value;
// 确定父容器
Transform targetParent = parent != null ? parent : Content;
// 创建Toggle
GameObject toggleObj = GameObject.Instantiate(Item.gameObject, targetParent);
toggleObj.name = body.Name;
Toggle uiToggle = toggleObj.transform.Find("ToggleContent/UI").GetComponent<Toggle>();
Toggle objToggle = toggleObj.transform.Find("ToggleContent/Obj").GetComponent<Toggle>();
TextMeshProUGUI label = toggleObj.transform.Find("ToggleContent/Label").GetComponentInChildren<TextMeshProUGUI>();
label.text = body.Name; // 根据深度添加缩进
toggleObj.transform.Find("ToggleContent").GetComponent<HorizontalLayoutGroup>().padding = new RectOffset(depth * 15, 5, 2, 2);
if (depth != 0)
{
toggleObj.SetActive(false);
}
// 递归构建子节点
Transform subContent = toggleObj.transform.Find("SubContent");
// 设置Toggle的监听事件
uiToggle.onValueChanged.AddListener((isOn) =>
{
for (int i = 0; i < subContent.childCount; i++)
{
subContent.GetChild(i).gameObject.SetActive(isOn);
}
});
// 为objToggle添加点击事件处理逻辑
objToggle.onValueChanged.AddListener((isOn) =>
{
SetObjectVisibility(body, isOn, subContent);
});
if (body.subBody.Count > 0)
{
uiToggle.gameObject.SetActive(true);
BuildTreeUI(body, depth + 1, subContent);
//HideSubBody(body); // 初始时隐藏子节点
}
else
{
uiToggle.gameObject.SetActive(false);
Debug.Log($"节点 {body.Name} 没有子节点。");
}
}
}
// 根据body和subbody中的path设置物体的显隐同时设置子UI中的objToggle状态
private void SetObjectVisibility(Body3D.Body body, bool isOn, Transform subContent)
{
// 处理当前body的path对应的物体
GameObject targetObj = Utility.FindObj(body.Path);
if (targetObj != null)
{
targetObj.SetActive(isOn);
}
// 递归处理subbody中的path对应的物体并设置子UI中的objToggle状态
int index = 0;
foreach (var subBodyPair in body.subBody)
{
Body3D.Body subBody = subBodyPair.Value;
if (subContent.childCount > index)
{
Transform childToggleObj = subContent.GetChild(index);
Toggle childObjToggle = childToggleObj.transform.Find("ToggleContent/Obj").GetComponent<Toggle>();
childObjToggle.isOn = isOn; // 设置子UI中的objToggle状态
Transform childSubContent = childToggleObj.transform.Find("SubContent");
SetObjectVisibility(subBody, isOn, childSubContent);
}
index++;
}
}
// 实现RefreshSearchContent函数
private void RefreshSearchContent(string str)
{
// 清空SearchContent下的所有子物体
searchItemMap.Clear();
SearchContent.RemoveAllChildren();
// 递归检查子物体的子物体
CheckChildren(Content, str);
}
// 递归检查子物体的子物体
private void CheckChildren(Transform parent, string str)
{
// 遍历当前父物体下的所有子物体
for (int i = 0; i < parent.childCount; i++)
{
Transform child = parent.GetChild(i);
// 尝试查找 ToggleContent/Label 组件
Transform labelTransform = child.Find("ToggleContent/Label");
if (labelTransform != null)
{
TextMeshProUGUI textComponent = labelTransform.GetComponent<TextMeshProUGUI>();
if (textComponent != null)
{
string name = textComponent.text;
// 检查子物体的名字是否包含搜索字符串
if (name.Contains(str))
{
// 复制该子物体到 SearchContent 中
GameObject clone = GameObject.Instantiate(SearchItem.gameObject, SearchContent);
searchItemMap.Add(clone, child.gameObject);
Transform subContent = child.Find("SubContent");
// 检查是否有子内容
if (subContent.childCount > 0)
{
Button btn = clone.transform.Find("Button").GetComponent<Button>();
btn.onClick.AddListener(() =>
{
child.Find("ToggleContent/Obj").GetComponent<Toggle>().isOn = true;
});
Transform buttonLabel = btn.transform.Find("Label");
if (buttonLabel != null)
{
TextMeshProUGUI buttonText = buttonLabel.GetComponent<TextMeshProUGUI>();
if (buttonText != null)
{
buttonText.text = "(组)" + name + ">";
}
}
// 递归检查当前子物体的子物体
CheckChildren(subContent, str);
}
else
{
Transform buttonLabel = clone.transform.Find("Button/Label");
if (buttonLabel != null)
{
TextMeshProUGUI buttonText = buttonLabel.GetComponent<TextMeshProUGUI>();
if (buttonText != null)
{
buttonText.text = name + ">";
}
}
}
}
}
}
}
}
protected override void OnShow()
{
}
protected override void OnHide()
{
}
protected override void OnClose()
{
}
}
}