| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538 | using System;using FairyGUI.Utils;using UnityEngine;namespace FairyGUI{    /// <summary>    /// GGroup class.    /// 组对象,对应编辑器里的高级组。    /// </summary>    public class GGroup : GObject    {        GroupLayoutType _layout;        int _lineGap;        int _columnGap;        bool _excludeInvisibles;        bool _autoSizeDisabled;        int _mainGridIndex;        int _mainGridMinSize;        bool _percentReady;        bool _boundsChanged;        int _mainChildIndex;        float _totalSize;        int _numChildren;        internal int _updating;        Action _refreshDelegate;        public GGroup()        {            _mainGridIndex = -1;            _mainChildIndex = -1;            _mainGridMinSize = 50;            _refreshDelegate = EnsureBoundsCorrect;        }        /// <summary>        /// Group layout type.        /// </summary>        public GroupLayoutType layout        {            get { return _layout; }            set            {                if (_layout != value)                {                    _layout = value;                    SetBoundsChangedFlag();                }            }        }        /// <summary>        ///         /// </summary>        public int lineGap        {            get { return _lineGap; }            set            {                if (_lineGap != value)                {                    _lineGap = value;                    SetBoundsChangedFlag(true);                }            }        }        /// <summary>        ///         /// </summary>        public int columnGap        {            get { return _columnGap; }            set            {                if (_columnGap != value)                {                    _columnGap = value;                    SetBoundsChangedFlag(true);                }            }        }        /// <summary>        ///         /// </summary>        public bool excludeInvisibles        {            get { return _excludeInvisibles; }            set            {                if (_excludeInvisibles != value)                {                    _excludeInvisibles = value;                    SetBoundsChangedFlag();                }            }        }        /// <summary>        ///         /// </summary>        public bool autoSizeDisabled        {            get { return _autoSizeDisabled; }            set            {                if (_autoSizeDisabled != value)                {                    _autoSizeDisabled = value;                    SetBoundsChangedFlag();                }            }        }        /// <summary>        ///         /// </summary>        public int mainGridMinSize        {            get { return _mainGridMinSize; }            set            {                if (_mainGridMinSize != value)                {                    _mainGridMinSize = value;                    SetBoundsChangedFlag();                }            }        }        /// <summary>        ///         /// </summary>        public int mainGridIndex        {            get { return _mainGridIndex; }            set            {                if (_mainGridIndex != value)                {                    _mainGridIndex = value;                    SetBoundsChangedFlag();                }            }        }        /// <summary>        /// Update group bounds.        /// 更新组的包围.        /// </summary>        public void SetBoundsChangedFlag(bool positionChangedOnly = false)        {            if (_updating == 0 && parent != null)            {                if (!positionChangedOnly)                    _percentReady = false;                if (!_boundsChanged)                {                    _boundsChanged = true;                    if (_layout != GroupLayoutType.None)                    {                        UpdateContext.OnBegin -= _refreshDelegate;                        UpdateContext.OnBegin += _refreshDelegate;                    }                }            }        }        public void EnsureBoundsCorrect()        {            if (parent == null || !_boundsChanged)                return;            UpdateContext.OnBegin -= _refreshDelegate;            _boundsChanged = false;            if (_autoSizeDisabled)                ResizeChildren(0, 0);            else            {                HandleLayout();                UpdateBounds();            }        }        void UpdateBounds()        {            int cnt = parent.numChildren;            int i;            GObject child;            float ax = int.MaxValue, ay = int.MaxValue;            float ar = int.MinValue, ab = int.MinValue;            float tmp;            bool empty = true;            bool skipInvisibles = _layout != GroupLayoutType.None && _excludeInvisibles;            for (i = 0; i < cnt; i++)            {                child = parent.GetChildAt(i);                if (child.group != this)                    continue;                if (skipInvisibles && !child.internalVisible3)                    continue;                tmp = child.xMin;                if (tmp < ax)                    ax = tmp;                tmp = child.yMin;                if (tmp < ay)                    ay = tmp;                tmp = child.xMin + child.width;                if (tmp > ar)                    ar = tmp;                tmp = child.yMin + child.height;                if (tmp > ab)                    ab = tmp;                empty = false;            }            float w;            float h;            if (!empty)            {                _updating |= 1;                SetXY(ax, ay);                _updating &= 2;                w = ar - ax;                h = ab - ay;            }            else                w = h = 0;            if ((_updating & 2) == 0)            {                _updating |= 2;                SetSize(w, h);                _updating &= 1;            }            else            {                _updating &= 1;                ResizeChildren(_width - w, _height - h);            }        }        void HandleLayout()        {            _updating |= 1;            if (_layout == GroupLayoutType.Horizontal)            {                float curX = this.x;                int cnt = parent.numChildren;                for (int i = 0; i < cnt; i++)                {                    GObject child = parent.GetChildAt(i);                    if (child.group != this)                        continue;                    if (_excludeInvisibles && !child.internalVisible3)                        continue;                    child.xMin = curX;                    if (child.width != 0)                        curX += child.width + _columnGap;                }            }            else if (_layout == GroupLayoutType.Vertical)            {                float curY = this.y;                int cnt = parent.numChildren;                for (int i = 0; i < cnt; i++)                {                    GObject child = parent.GetChildAt(i);                    if (child.group != this)                        continue;                    if (_excludeInvisibles && !child.internalVisible3)                        continue;                    child.yMin = curY;                    if (child.height != 0)                        curY += child.height + _lineGap;                }            }            _updating &= 2;        }        internal void MoveChildren(float dx, float dy)        {            if ((_updating & 1) != 0 || parent == null)                return;            _updating |= 1;            int cnt = parent.numChildren;            int i;            GObject child;            for (i = 0; i < cnt; i++)            {                child = parent.GetChildAt(i);                if (child.group == this)                {                    child.SetXY(child.x + dx, child.y + dy);                }            }            _updating &= 2;        }        internal void ResizeChildren(float dw, float dh)        {            if (_layout == GroupLayoutType.None || (_updating & 2) != 0 || parent == null)                return;            _updating |= 2;            if (_boundsChanged)            {                _boundsChanged = false;                if (!_autoSizeDisabled)                {                    UpdateBounds();                    return;                }            }            int cnt = parent.numChildren;            if (!_percentReady)            {                _percentReady = true;                _numChildren = 0;                _totalSize = 0;                _mainChildIndex = -1;                int j = 0;                for (int i = 0; i < cnt; i++)                {                    GObject child = parent.GetChildAt(i);                    if (child.group != this)                        continue;                    if (!_excludeInvisibles || child.internalVisible3)                    {                        if (j == _mainGridIndex)                            _mainChildIndex = i;                        _numChildren++;                        if (_layout == GroupLayoutType.Horizontal)                            _totalSize += child.width;                        else                            _totalSize += child.height;                    }                    j++;                }                if (_mainChildIndex != -1)                {                    if (_layout == GroupLayoutType.Horizontal)                    {                        GObject child = parent.GetChildAt(_mainChildIndex);                        _totalSize += _mainGridMinSize - child.width;                        child._sizePercentInGroup = _mainGridMinSize / _totalSize;                    }                    else                    {                        GObject child = parent.GetChildAt(_mainChildIndex);                        _totalSize += _mainGridMinSize - child.height;                        child._sizePercentInGroup = _mainGridMinSize / _totalSize;                    }                }                for (int i = 0; i < cnt; i++)                {                    GObject child = parent.GetChildAt(i);                    if (child.group != this)                        continue;                    if (i == _mainChildIndex)                        continue;                    if (_totalSize > 0)                        child._sizePercentInGroup = (_layout == GroupLayoutType.Horizontal ? child.width : child.height) / _totalSize;                    else                        child._sizePercentInGroup = 0;                }            }            float remainSize = 0;            float remainPercent = 1;            bool priorHandled = false;            if (_layout == GroupLayoutType.Horizontal)            {                remainSize = this.width - (_numChildren - 1) * _columnGap;                if (_mainChildIndex != -1 && remainSize >= _totalSize)                {                    GObject child = parent.GetChildAt(_mainChildIndex);                    child.SetSize(remainSize - (_totalSize - _mainGridMinSize), child._rawHeight + dh, true);                    remainSize -= child.width;                    remainPercent -= child._sizePercentInGroup;                    priorHandled = true;                }                float curX = this.x;                for (int i = 0; i < cnt; i++)                {                    GObject child = parent.GetChildAt(i);                    if (child.group != this)                        continue;                    if (_excludeInvisibles && !child.internalVisible3)                    {                        child.SetSize(child._rawWidth, child._rawHeight + dh, true);                        continue;                    }                    if (!priorHandled || i != _mainChildIndex)                    {                        child.SetSize(Mathf.Round(child._sizePercentInGroup / remainPercent * remainSize), child._rawHeight + dh, true);                        remainPercent -= child._sizePercentInGroup;                        remainSize -= child.width;                    }                    child.xMin = curX;                    if (child.width != 0)                        curX += child.width + _columnGap;                }            }            else            {                remainSize = this.height - (_numChildren - 1) * _lineGap;                if (_mainChildIndex != -1 && remainSize >= _totalSize)                {                    GObject child = parent.GetChildAt(_mainChildIndex);                    child.SetSize(child._rawWidth + dw, remainSize - (_totalSize - _mainGridMinSize), true);                    remainSize -= child.height;                    remainPercent -= child._sizePercentInGroup;                    priorHandled = true;                }                float curY = this.y;                for (int i = 0; i < cnt; i++)                {                    GObject child = parent.GetChildAt(i);                    if (child.group != this)                        continue;                    if (_excludeInvisibles && !child.internalVisible3)                    {                        child.SetSize(child._rawWidth + dw, child._rawHeight, true);                        continue;                    }                    if (!priorHandled || i != _mainChildIndex)                    {                        child.SetSize(child._rawWidth + dw, Mathf.Round(child._sizePercentInGroup / remainPercent * remainSize), true);                        remainPercent -= child._sizePercentInGroup;                        remainSize -= child.height;                    }                    child.yMin = curY;                    if (child.height != 0)                        curY += child.height + _lineGap;                }            }            _updating &= 1;        }        override protected void HandleAlphaChanged()        {            base.HandleAlphaChanged();            if (this.underConstruct || parent == null)                return;            int cnt = parent.numChildren;            float a = this.alpha;            for (int i = 0; i < cnt; i++)            {                GObject child = parent.GetChildAt(i);                if (child.group == this)                    child.alpha = a;            }        }        override internal protected void HandleVisibleChanged()        {            if (parent == null)                return;            int cnt = parent.numChildren;            for (int i = 0; i < cnt; i++)            {                GObject child = parent.GetChildAt(i);                if (child.group == this)                    child.HandleVisibleChanged();            }        }        override public void Setup_BeforeAdd(ByteBuffer buffer, int beginPos)        {            base.Setup_BeforeAdd(buffer, beginPos);            buffer.Seek(beginPos, 5);            _layout = (GroupLayoutType)buffer.ReadByte();            _lineGap = buffer.ReadInt();            _columnGap = buffer.ReadInt();            if (buffer.version >= 2)            {                _excludeInvisibles = buffer.ReadBool();                _autoSizeDisabled = buffer.ReadBool();                _mainGridIndex = buffer.ReadShort();            }        }        override public void Setup_AfterAdd(ByteBuffer buffer, int beginPos)        {            base.Setup_AfterAdd(buffer, beginPos);            if (!this.visible)                HandleVisibleChanged();        }    }}
 |