2025-06-07 17:43:34 +08:00

491 lines
14 KiB
C#
Raw Permalink 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;
namespace FairyGUI
{
/// <summary>
///
/// </summary>
[Obsolete("Use GTree and GTreeNode instead")]
public class TreeView : EventDispatcher
{
/// <summary>
/// TreeView使用的List对象
/// </summary>
public GList list { get; private set; }
/// <summary>
/// TreeView的顶层节点这是个虚拟节点也就是他不会显示出来。
/// </summary>
public TreeNode root { get; private set; }
/// <summary>
/// TreeView每级的缩进单位像素。
/// </summary>
public int indent;
public delegate GComponent TreeNodeCreateCellDelegate(TreeNode node);
public delegate void TreeNodeRenderDelegate(TreeNode node);
public delegate void TreeNodeWillExpandDelegate(TreeNode node, bool expand);
/// <summary>
/// 当TreeNode需要创建对象的显示对象时回调
/// </summary>
public TreeNodeCreateCellDelegate treeNodeCreateCell;
/// <summary>
/// 当TreeNode需要更新时回调
/// </summary>
public TreeNodeRenderDelegate treeNodeRender;
/// <summary>
/// 当TreeNode即将展开或者收缩时回调。可以在回调中动态增加子节点。
/// </summary>
public TreeNodeWillExpandDelegate treeNodeWillExpand;
/// <summary>
/// 点击任意TreeNode时触发
/// </summary>
public EventListener onClickNode { get; private set; }
/// <summary>
/// 右键点击任意TreeNode时触发
/// </summary>
public EventListener onRightClickNode { get; private set; }
/// <summary>
///
/// </summary>
/// <param name="list"></param>
public TreeView(GList list)
{
this.list = list;
list.onClickItem.Add(__clickItem);
list.onRightClickItem.Add(__clickItem);
list.RemoveChildrenToPool();
root = new TreeNode(true);
root.SetTree(this);
root.cell = list;
root.expanded = true;
indent = 30;
onClickNode = new EventListener(this, "onClickNode");
onRightClickNode = new EventListener(this, "onRightClickNode");
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public TreeNode GetSelectedNode()
{
if (list.selectedIndex != -1)
return (TreeNode)list.GetChildAt(list.selectedIndex).data;
else
return null;
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public List<TreeNode> GetSelection()
{
List<int> sels = list.GetSelection();
int cnt = sels.Count;
List<TreeNode> ret = new List<TreeNode>();
for (int i = 0; i < cnt; i++)
{
TreeNode node = (TreeNode)list.GetChildAt(sels[i]).data;
ret.Add(node);
}
return ret;
}
/// <summary>
///
/// </summary>
/// <param name="node"></param>
/// <param name="scrollItToView"></param>
public void AddSelection(TreeNode node, bool scrollItToView = false)
{
TreeNode parentNode = node.parent;
while (parentNode != null && parentNode != root)
{
parentNode.expanded = true;
parentNode = parentNode.parent;
}
list.AddSelection(list.GetChildIndex(node.cell), scrollItToView);
}
/// <summary>
///
/// </summary>
/// <param name="node"></param>
public void RemoveSelection(TreeNode node)
{
list.RemoveSelection(list.GetChildIndex(node.cell));
}
/// <summary>
///
/// </summary>
public void ClearSelection()
{
list.ClearSelection();
}
/// <summary>
///
/// </summary>
/// <param name="node"></param>
/// <returns></returns>
public int GetNodeIndex(TreeNode node)
{
return list.GetChildIndex(node.cell);
}
/// <summary>
///
/// </summary>
/// <param name="node"></param>
public void UpdateNode(TreeNode node)
{
if (node.cell == null)
return;
if (treeNodeRender != null)
treeNodeRender(node);
}
/// <summary>
///
/// </summary>
/// <param name="nodes"></param>
public void UpdateNodes(List<TreeNode> nodes)
{
int cnt = nodes.Count;
for (int i = 0; i < cnt; i++)
{
TreeNode node = nodes[i];
if (node.cell == null)
return;
if (treeNodeRender != null)
treeNodeRender(node);
}
}
/// <summary>
///
/// </summary>
/// <param name="folderNode"></param>
public void ExpandAll(TreeNode folderNode)
{
folderNode.expanded = true;
int cnt = folderNode.numChildren;
for (int i = 0; i < cnt; i++)
{
TreeNode node = folderNode.GetChildAt(i);
if (node.isFolder)
ExpandAll(node);
}
}
/// <summary>
///
/// </summary>
/// <param name="folderNode"></param>
public void CollapseAll(TreeNode folderNode)
{
if (folderNode != root)
folderNode.expanded = false;
int cnt = folderNode.numChildren;
for (int i = 0; i < cnt; i++)
{
TreeNode node = folderNode.GetChildAt(i);
if (node.isFolder)
CollapseAll(node);
}
}
/// <summary>
///
/// </summary>
/// <param name="node"></param>
void CreateCell(TreeNode node)
{
if (treeNodeCreateCell != null)
node.cell = treeNodeCreateCell(node);
else
node.cell = list.itemPool.GetObject(list.defaultItem) as GComponent;
if (node.cell == null)
throw new Exception("Unable to create tree cell");
node.cell.data = node;
GObject indentObj = node.cell.GetChild("indent");
if (indentObj != null)
indentObj.width = (node.level - 1) * indent;
GButton expandButton = (GButton)node.cell.GetChild("expandButton");
if (expandButton != null)
{
if (node.isFolder)
{
expandButton.visible = true;
expandButton.onClick.Add(__clickExpandButton);
expandButton.data = node;
expandButton.selected = node.expanded;
}
else
expandButton.visible = false;
}
if (treeNodeRender != null)
treeNodeRender(node);
}
/// <summary>
///
/// </summary>
/// <param name="node"></param>
internal void AfterInserted(TreeNode node)
{
CreateCell(node);
int index = GetInsertIndexForNode(node);
list.AddChildAt(node.cell, index);
if (treeNodeRender != null)
treeNodeRender(node);
if (node.isFolder && node.expanded)
CheckChildren(node, index);
}
/// <summary>
///
/// </summary>
/// <param name="node"></param>
/// <returns></returns>
int GetInsertIndexForNode(TreeNode node)
{
TreeNode prevNode = node.GetPrevSibling();
if (prevNode == null)
prevNode = node.parent;
int insertIndex = list.GetChildIndex(prevNode.cell) + 1;
int myLevel = node.level;
int cnt = list.numChildren;
for (int i = insertIndex; i < cnt; i++)
{
TreeNode testNode = (TreeNode)list.GetChildAt(i).data;
if (testNode.level <= myLevel)
break;
insertIndex++;
}
return insertIndex;
}
/// <summary>
///
/// </summary>
/// <param name="node"></param>
internal void AfterRemoved(TreeNode node)
{
RemoveNode(node);
}
/// <summary>
///
/// </summary>
/// <param name="node"></param>
internal void AfterExpanded(TreeNode node)
{
if (node != root && treeNodeWillExpand != null)
treeNodeWillExpand(node, true);
if (node.cell == null)
return;
if (node != root)
{
if (treeNodeRender != null)
treeNodeRender(node);
GButton expandButton = (GButton)node.cell.GetChild("expandButton");
if (expandButton != null)
expandButton.selected = true;
}
if (node.cell.parent != null)
CheckChildren(node, list.GetChildIndex(node.cell));
}
/// <summary>
///
/// </summary>
/// <param name="node"></param>
internal void AfterCollapsed(TreeNode node)
{
if (node != root && treeNodeWillExpand != null)
treeNodeWillExpand(node, false);
if (node.cell == null)
return;
if (node != root)
{
if (treeNodeRender != null)
treeNodeRender(node);
GButton expandButton = (GButton)node.cell.GetChild("expandButton");
if (expandButton != null)
expandButton.selected = false;
}
if (node.cell.parent != null)
HideFolderNode(node);
}
/// <summary>
///
/// </summary>
/// <param name="node"></param>
internal void AfterMoved(TreeNode node)
{
if (!node.isFolder)
list.RemoveChild(node.cell);
else
HideFolderNode(node);
int index = GetInsertIndexForNode(node);
list.AddChildAt(node.cell, index);
if (node.isFolder && node.expanded)
CheckChildren(node, index);
}
/// <summary>
///
/// </summary>
/// <param name="folderNode"></param>
/// <param name="index"></param>
/// <returns></returns>
int CheckChildren(TreeNode folderNode, int index)
{
int cnt = folderNode.numChildren;
for (int i = 0; i < cnt; i++)
{
index++;
TreeNode node = folderNode.GetChildAt(i);
if (node.cell == null)
CreateCell(node);
if (node.cell.parent == null)
list.AddChildAt(node.cell, index);
if (node.isFolder && node.expanded)
index = CheckChildren(node, index);
}
return index;
}
/// <summary>
///
/// </summary>
/// <param name="folderNode"></param>
void HideFolderNode(TreeNode folderNode)
{
int cnt = folderNode.numChildren;
for (int i = 0; i < cnt; i++)
{
TreeNode node = folderNode.GetChildAt(i);
if (node.cell != null)
{
if (node.cell.parent != null)
list.RemoveChild(node.cell);
list.itemPool.ReturnObject(node.cell);
node.cell.data = null;
node.cell = null;
}
if (node.isFolder && node.expanded)
HideFolderNode(node);
}
}
/// <summary>
///
/// </summary>
/// <param name="node"></param>
void RemoveNode(TreeNode node)
{
if (node.cell != null)
{
if (node.cell.parent != null)
list.RemoveChild(node.cell);
list.itemPool.ReturnObject(node.cell);
node.cell.data = null;
node.cell = null;
}
if (node.isFolder)
{
int cnt = node.numChildren;
for (int i = 0; i < cnt; i++)
{
TreeNode node2 = node.GetChildAt(i);
RemoveNode(node2);
}
}
}
void __clickExpandButton(EventContext context)
{
context.StopPropagation();
GButton expandButton = (GButton)context.sender;
TreeNode node = (TreeNode)expandButton.parent.data;
if (list.scrollPane != null)
{
float posY = list.scrollPane.posY;
if (expandButton.selected)
node.expanded = true;
else
node.expanded = false;
list.scrollPane.posY = posY;
list.scrollPane.ScrollToView(node.cell);
}
else
{
if (expandButton.selected)
node.expanded = true;
else
node.expanded = false;
}
}
void __clickItem(EventContext context)
{
float posY = 0;
if (list.scrollPane != null)
posY = list.scrollPane.posY;
TreeNode node = (TreeNode)((GObject)context.data).data;
if (context.type == list.onRightClickItem.type)
onRightClickNode.Call(node);
else
onClickNode.Call(node);
if (list.scrollPane != null)
{
list.scrollPane.posY = posY;
list.scrollPane.ScrollToView(node.cell);
}
}
}
}