| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557 | using System;using System.Collections.Generic;using FairyGUI.Utils;namespace FairyGUI{    /// <summary>    ///     /// </summary>    public class GTree : GList    {        public delegate void TreeNodeRenderDelegate(GTreeNode node, GComponent obj);        public delegate void TreeNodeWillExpandDelegate(GTreeNode node, bool expand);        /// <summary>        /// 当TreeNode需要更新时回调        /// </summary>        public TreeNodeRenderDelegate treeNodeRender;        /// <summary>        /// 当TreeNode即将展开或者收缩时回调。可以在回调中动态增加子节点。        /// </summary>        public TreeNodeWillExpandDelegate treeNodeWillExpand;        int _indent;        GTreeNode _rootNode;        int _clickToExpand;        bool _expandedStatusInEvt;        private static List<int> helperIntList = new List<int>();        /// <summary>        ///         /// </summary>        public GTree()        {            _indent = 30;            _rootNode = new GTreeNode(true);            _rootNode._SetTree(this);            _rootNode.expanded = true;        }        /// <summary>        /// TreeView的顶层节点,这是个虚拟节点,也就是他不会显示出来。        /// </summary>        public GTreeNode rootNode        {            get { return _rootNode; }        }        /// <summary>        /// TreeView每级的缩进,单位像素。        /// </summary>        public int indent        {            get { return _indent; }            set { _indent = value; }        }        /// <summary>        ///         /// </summary>        public int clickToExpand        {            get { return _clickToExpand; }            set { _clickToExpand = value; }        }        /// <summary>        ///         /// </summary>        /// <returns></returns>        public GTreeNode GetSelectedNode()        {            int i = this.selectedIndex;            if (i != -1)                return (GTreeNode)this.GetChildAt(i)._treeNode;            else                return null;        }        /// <summary>		/// 		/// </summary>		/// <returns></returns>		public List<GTreeNode> GetSelectedNodes()        {            return GetSelectedNodes(null);        }        /// <summary>        ///         /// </summary>        /// <param name="result"></param>        /// <returns></returns>        public List<GTreeNode> GetSelectedNodes(List<GTreeNode> result)        {            if (result == null)                result = new List<GTreeNode>();            helperIntList.Clear();            List<int> sels = GetSelection(helperIntList);            int cnt = sels.Count;            for (int i = 0; i < cnt; i++)            {                GTreeNode node = GetChildAt(sels[i])._treeNode;                result.Add(node);            }            return result;        }        /// <summary>		/// 		/// </summary>		/// <param name="node"></param>        public void SelectNode(GTreeNode node)        {            SelectNode(node, false);        }        /// <summary>        ///         /// </summary>        /// <param name="node"></param>        /// <param name="scrollItToView"></param>        public void SelectNode(GTreeNode node, bool scrollItToView)        {            GTreeNode parentNode = node.parent;            while (parentNode != null && parentNode != _rootNode)            {                parentNode.expanded = true;                parentNode = parentNode.parent;            }            AddSelection(GetChildIndex(node.cell), scrollItToView);        }        /// <summary>        ///         /// </summary>        /// <param name="node"></param>        public void UnselectNode(GTreeNode node)        {            RemoveSelection(GetChildIndex(node.cell));        }        /// <summary>		/// 		/// </summary>        public void ExpandAll()        {            ExpandAll(_rootNode);        }        /// <summary>        ///         /// </summary>        /// <param name="folderNode"></param>        public void ExpandAll(GTreeNode folderNode)        {            folderNode.expanded = true;            int cnt = folderNode.numChildren;            for (int i = 0; i < cnt; i++)            {                GTreeNode node = folderNode.GetChildAt(i);                if (node.isFolder)                    ExpandAll(node);            }        }        /// <summary>        ///         /// </summary>        /// <param name="folderNode"></param>        public void CollapseAll()        {            CollapseAll(_rootNode);        }        /// <summary>        ///         /// </summary>        /// <param name="folderNode"></param>        public void CollapseAll(GTreeNode folderNode)        {            if (folderNode != _rootNode)                folderNode.expanded = false;            int cnt = folderNode.numChildren;            for (int i = 0; i < cnt; i++)            {                GTreeNode node = folderNode.GetChildAt(i);                if (node.isFolder)                    CollapseAll(node);            }        }        /// <summary>        ///         /// </summary>        /// <param name="node"></param>        void CreateCell(GTreeNode node)        {            GComponent child = itemPool.GetObject(string.IsNullOrEmpty(node._resURL) ? this.defaultItem : node._resURL) as GComponent;            if (child == null)                throw new Exception("FairyGUI: cannot create tree node object.");            child.displayObject.home = this.displayObject.cachedTransform;            child._treeNode = node;            node._cell = child;            GObject indentObj = node.cell.GetChild("indent");            if (indentObj != null)                indentObj.width = (node.level - 1) * indent;            Controller cc;            cc = child.GetController("expanded");            if (cc != null)            {                cc.onChanged.Add(__expandedStateChanged);                cc.selectedIndex = node.expanded ? 1 : 0;            }            cc = child.GetController("leaf");            if (cc != null)                cc.selectedIndex = node.isFolder ? 0 : 1;            if (node.isFolder)                child.onTouchBegin.Add(__cellTouchBegin);            if (treeNodeRender != null)                treeNodeRender(node, node._cell);        }        /// <summary>        ///         /// </summary>        /// <param name="node"></param>        internal void _AfterInserted(GTreeNode node)        {            if (node._cell == null)                CreateCell(node);            int index = GetInsertIndexForNode(node);            AddChildAt(node.cell, index);            if (treeNodeRender != null)                treeNodeRender(node, node._cell);            if (node.isFolder && node.expanded)                CheckChildren(node, index);        }        /// <summary>        ///         /// </summary>        /// <param name="node"></param>        /// <returns></returns>        int GetInsertIndexForNode(GTreeNode node)        {            GTreeNode prevNode = node.GetPrevSibling();            if (prevNode == null)                prevNode = node.parent;            int insertIndex = GetChildIndex(prevNode.cell) + 1;            int myLevel = node.level;            int cnt = this.numChildren;            for (int i = insertIndex; i < cnt; i++)            {                GTreeNode testNode = GetChildAt(i)._treeNode;                if (testNode.level <= myLevel)                    break;                insertIndex++;            }            return insertIndex;        }        /// <summary>        ///         /// </summary>        /// <param name="node"></param>        internal void _AfterRemoved(GTreeNode node)        {            RemoveNode(node);        }        /// <summary>        ///         /// </summary>        /// <param name="node"></param>        internal void _AfterExpanded(GTreeNode node)        {            if (node == _rootNode)            {                CheckChildren(_rootNode, 0);                return;            }            if (this.treeNodeWillExpand != null)                this.treeNodeWillExpand(node, true);            if (node._cell == null)                return;            if (this.treeNodeRender != null)                this.treeNodeRender(node, node._cell);            Controller cc = node._cell.GetController("expanded");            if (cc != null)                cc.selectedIndex = 1;            if (node._cell.parent != null)                CheckChildren(node, GetChildIndex(node._cell));        }        /// <summary>        ///         /// </summary>        /// <param name="node"></param>        internal void _AfterCollapsed(GTreeNode node)        {            if (node == _rootNode)            {                CheckChildren(_rootNode, 0);                return;            }            if (this.treeNodeWillExpand != null)                this.treeNodeWillExpand(node, false);            if (node._cell == null)                return;            if (this.treeNodeRender != null)                this.treeNodeRender(node, node._cell);            Controller cc = node._cell.GetController("expanded");            if (cc != null)                cc.selectedIndex = 0;            if (node._cell.parent != null)                HideFolderNode(node);        }        /// <summary>        ///         /// </summary>        /// <param name="node"></param>        internal void _AfterMoved(GTreeNode node)        {            int startIndex = GetChildIndex(node._cell);            int endIndex;            if (node.isFolder)                endIndex = GetFolderEndIndex(startIndex, node.level);            else                endIndex = startIndex + 1;            int insertIndex = GetInsertIndexForNode(node);            int cnt = endIndex - startIndex;            if (insertIndex < startIndex)            {                for (int i = 0; i < cnt; i++)                {                    GObject obj = GetChildAt(startIndex + i);                    SetChildIndex(obj, insertIndex + i);                }            }            else            {                for (int i = 0; i < cnt; i++)                {                    GObject obj = GetChildAt(startIndex);                    SetChildIndex(obj, insertIndex);                }            }        }        private int GetFolderEndIndex(int startIndex, int level)        {            int cnt = this.numChildren;            for (int i = startIndex + 1; i < cnt; i++)            {                GTreeNode node = GetChildAt(i)._treeNode;                if (node.level <= level)                    return i;            }            return cnt;        }        /// <summary>        ///         /// </summary>        /// <param name="folderNode"></param>        /// <param name="index"></param>        /// <returns></returns>        int CheckChildren(GTreeNode folderNode, int index)        {            int cnt = folderNode.numChildren;            for (int i = 0; i < cnt; i++)            {                index++;                GTreeNode node = folderNode.GetChildAt(i);                if (node.cell == null)                    CreateCell(node);                if (node.cell.parent == null)                    AddChildAt(node.cell, index);                if (node.isFolder && node.expanded)                    index = CheckChildren(node, index);            }            return index;        }        /// <summary>        ///         /// </summary>        /// <param name="folderNode"></param>        void HideFolderNode(GTreeNode folderNode)        {            int cnt = folderNode.numChildren;            for (int i = 0; i < cnt; i++)            {                GTreeNode node = folderNode.GetChildAt(i);                if (node.cell != null && node.cell.parent != null)                    RemoveChild(node.cell);                if (node.isFolder && node.expanded)                    HideFolderNode(node);            }        }        /// <summary>        ///         /// </summary>        /// <param name="node"></param>        void RemoveNode(GTreeNode node)        {            if (node.cell != null)            {                if (node.cell.parent != null)                    RemoveChild(node.cell);                itemPool.ReturnObject(node.cell);                node._cell._treeNode = null;                node._cell = null;            }            if (node.isFolder)            {                int cnt = node.numChildren;                for (int i = 0; i < cnt; i++)                {                    GTreeNode node2 = node.GetChildAt(i);                    RemoveNode(node2);                }            }        }        void __cellTouchBegin(EventContext context)        {            GTreeNode node = ((GObject)context.sender)._treeNode;            _expandedStatusInEvt = node.expanded;        }        void __expandedStateChanged(EventContext context)        {            Controller cc = (Controller)context.sender;            GTreeNode node = cc.parent._treeNode;            node.expanded = cc.selectedIndex == 1;        }        override protected void DispatchItemEvent(GObject item, EventContext context)        {            if (_clickToExpand != 0)            {                GTreeNode node = item._treeNode;                if (node != null && _expandedStatusInEvt == node.expanded)                {                    if (_clickToExpand == 2)                    {                        if (context.inputEvent.isDoubleClick)                            node.expanded = !node.expanded;                    }                    else                        node.expanded = !node.expanded;                }            }            base.DispatchItemEvent(item, context);        }        override public void Setup_BeforeAdd(ByteBuffer buffer, int beginPos)        {            base.Setup_BeforeAdd(buffer, beginPos);            buffer.Seek(beginPos, 9);            _indent = buffer.ReadInt();            _clickToExpand = buffer.ReadByte();        }        override protected void ReadItems(ByteBuffer buffer)        {            int nextPos;            string str;            bool isFolder;            GTreeNode lastNode = null;            int level;            int prevLevel = 0;            int cnt = buffer.ReadShort();            for (int i = 0; i < cnt; i++)            {                nextPos = buffer.ReadShort();                nextPos += buffer.position;                str = buffer.ReadS();                if (str == null)                {                    str = this.defaultItem;                    if (str == null)                    {                        buffer.position = nextPos;                        continue;                    }                }                isFolder = buffer.ReadBool();                level = buffer.ReadByte();                GTreeNode node = new GTreeNode(isFolder, str);                node.expanded = true;                if (i == 0)                    _rootNode.AddChild(node);                else                {                    if (level > prevLevel)                        lastNode.AddChild(node);                    else if (level < prevLevel)                    {                        for (int j = level; j <= prevLevel; j++)                            lastNode = lastNode.parent;                        lastNode.AddChild(node);                    }                    else                        lastNode.parent.AddChild(node);                }                lastNode = node;                prevLevel = level;                SetupItem(buffer, node.cell);                buffer.position = nextPos;            }        }    }}
 |