| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051 | using System;using System.Collections.Generic;using FairyGUI.Utils;using UnityEngine;namespace FairyGUI{    /// <summary>    /// Callback function when an item is needed to update its look.    /// </summary>    /// <param name="index">Item index.</param>    /// <param name="item">Item object.</param>    public delegate void ListItemRenderer(int index, GObject item);    /// <summary>    ///     /// </summary>    /// <param name="index"></param>    /// <returns></returns>    public delegate string ListItemProvider(int index);    /// <summary>    /// GList class.    /// </summary>    public class GList : GComponent    {        /// <summary>        /// Resource url of the default item.        /// </summary>        public string defaultItem;        /// <summary>        /// 如果true,当item不可见时自动折叠,否则依然占位        /// </summary>        public bool foldInvisibleItems = false;        /// <summary>        /// List selection mode        /// </summary>        /// <seealso cref="ListSelectionMode"/>        public ListSelectionMode selectionMode;        /// <summary>        /// Callback function when an item is needed to update its look.        /// </summary>        public ListItemRenderer itemRenderer;        /// <summary>        /// Callback funtion to return item resource url.        /// </summary>        public ListItemProvider itemProvider;        /// <summary>        ///         /// </summary>        public bool scrollItemToViewOnClick;        ListLayoutType _layout;        int _lineCount;        int _columnCount;        int _lineGap;        int _columnGap;        AlignType _align;        VertAlignType _verticalAlign;        bool _autoResizeItem;        Controller _selectionController;        GObjectPool _pool;        int _lastSelectedIndex;        EventListener _onClickItem;        EventListener _onRightClickItem;        //Virtual List support        bool _virtual;        bool _loop;        int _numItems;        int _realNumItems;        int _firstIndex; //the top left index        int _curLineItemCount; //item count in one line        int _curLineItemCount2; //只用在页面模式,表示垂直方向的项目数        Vector2 _itemSize;        int _virtualListChanged; //1-content changed, 2-size changed        uint itemInfoVer; //用来标志item是否在本次处理中已经被重用了        int _miscFlags; //1-event locked, 2-focus events registered        class ItemInfo        {            public Vector2 size;            public GObject obj;            public uint updateFlag;            public bool selected;        }        List<ItemInfo> _virtualItems;        EventCallback1 _itemClickDelegate;        public GList()            : base()        {            _trackBounds = true;            this.opaque = true;            scrollItemToViewOnClick = true;            container = new Container();            rootContainer.AddChild(container);            rootContainer.gameObject.name = "GList";            _pool = new GObjectPool(container.cachedTransform);            _itemClickDelegate = __clickItem;        }        public override void Dispose()        {            _pool.Clear();            if (_virtualListChanged != 0)                Timers.inst.Remove(this.RefreshVirtualList);            _selectionController = null;            scrollItemToViewOnClick = false;            itemRenderer = null;            itemProvider = null;            base.Dispose();        }        /// <summary>        /// Dispatched when a list item being clicked.        /// </summary>        public EventListener onClickItem        {            get { return _onClickItem ?? (_onClickItem = new EventListener(this, "onClickItem")); }        }        /// <summary>        /// Dispatched when a list item being clicked with right button.        /// </summary>        public EventListener onRightClickItem        {            get { return _onRightClickItem ?? (_onRightClickItem = new EventListener(this, "onRightClickItem")); }        }        /// <summary>        /// List layout type.        /// </summary>        public ListLayoutType layout        {            get { return _layout; }            set            {                if (_layout != value)                {                    _layout = value;                    SetBoundsChangedFlag();                    if (_virtual)                        SetVirtualListChangedFlag(true);                }            }        }        /// <summary>        ///         /// </summary>        public int lineCount        {            get { return _lineCount; }            set            {                if (_lineCount != value)                {                    _lineCount = value;                    if (_layout == ListLayoutType.FlowVertical || _layout == ListLayoutType.Pagination)                    {                        SetBoundsChangedFlag();                        if (_virtual)                            SetVirtualListChangedFlag(true);                    }                }            }        }        /// <summary>        ///         /// </summary>        public int columnCount        {            get { return _columnCount; }            set            {                if (_columnCount != value)                {                    _columnCount = value;                    if (_layout == ListLayoutType.FlowHorizontal || _layout == ListLayoutType.Pagination)                    {                        SetBoundsChangedFlag();                        if (_virtual)                            SetVirtualListChangedFlag(true);                    }                }            }        }        /// <summary>        ///         /// </summary>        public int lineGap        {            get { return _lineGap; }            set            {                if (_lineGap != value)                {                    _lineGap = value;                    SetBoundsChangedFlag();                    if (_virtual)                        SetVirtualListChangedFlag(true);                }            }        }        /// <summary>        ///         /// </summary>        public int columnGap        {            get { return _columnGap; }            set            {                if (_columnGap != value)                {                    _columnGap = value;                    SetBoundsChangedFlag();                    if (_virtual)                        SetVirtualListChangedFlag(true);                }            }        }        /// <summary>        ///         /// </summary>        public AlignType align        {            get { return _align; }            set            {                if (_align != value)                {                    _align = value;                    SetBoundsChangedFlag();                    if (_virtual)                        SetVirtualListChangedFlag(true);                }            }        }        /// <summary>        ///         /// </summary>        public VertAlignType verticalAlign        {            get { return _verticalAlign; }            set            {                if (_verticalAlign != value)                {                    _verticalAlign = value;                    SetBoundsChangedFlag();                    if (_virtual)                        SetVirtualListChangedFlag(true);                }            }        }        /// <summary>        /// If the item will resize itself to fit the list width/height.        /// </summary>        public bool autoResizeItem        {            get { return _autoResizeItem; }            set            {                if (_autoResizeItem != value)                {                    _autoResizeItem = value;                    SetBoundsChangedFlag();                    if (_virtual)                        SetVirtualListChangedFlag(true);                }            }        }        /// <summary>        ///         /// </summary>        /// <value></value>        public Vector2 defaultItemSize        {            get { return _itemSize; }            set            {                _itemSize = value;                if (_virtual)                {                    if (_layout == ListLayoutType.SingleColumn || _layout == ListLayoutType.FlowHorizontal)                        this.scrollPane.scrollStep = _itemSize.y;                    else                        this.scrollPane.scrollStep = _itemSize.x;                    SetVirtualListChangedFlag(true);                }            }        }        /// <summary>        ///         /// </summary>        public GObjectPool itemPool        {            get { return _pool; }        }        /// <summary>        ///         /// </summary>        /// <param name="url"></param>        /// <returns></returns>        public GObject GetFromPool(string url)        {            if (string.IsNullOrEmpty(url))                url = defaultItem;            GObject ret = _pool.GetObject(url);            if (ret != null)                ret.visible = true;            return ret;        }        void ReturnToPool(GObject obj)        {            _pool.ReturnObject(obj);        }        /// <summary>        /// Add a item to list, same as GetFromPool+AddChild        /// </summary>        /// <returns>Item object</returns>        public GObject AddItemFromPool()        {            GObject obj = GetFromPool(null);            return AddChild(obj);        }        /// <summary>        /// Add a item to list, same as GetFromPool+AddChild        /// </summary>        /// <param name="url">Item resource url</param>        /// <returns>Item object</returns>        public GObject AddItemFromPool(string url)        {            GObject obj = GetFromPool(url);            return AddChild(obj);        }        /// <summary>        ///         /// </summary>        /// <param name="child"></param>        /// <param name="index"></param>        /// <returns></returns>        override public GObject AddChildAt(GObject child, int index)        {            base.AddChildAt(child, index);            if (child is GButton)            {                GButton button = (GButton)child;                button.selected = false;                button.changeStateOnClick = false;            }            child.onClick.Add(_itemClickDelegate);            child.onRightClick.Add(_itemClickDelegate);            return child;        }        /// <summary>        ///         /// </summary>        /// <param name="index"></param>        /// <param name="dispose"></param>        /// <returns></returns>        override public GObject RemoveChildAt(int index, bool dispose)        {            GObject child = base.RemoveChildAt(index, dispose);            child.onClick.Remove(_itemClickDelegate);            child.onRightClick.Remove(_itemClickDelegate);            return child;        }        /// <summary>        ///         /// </summary>        /// <param name="index"></param>        public void RemoveChildToPoolAt(int index)        {            GObject child = base.RemoveChildAt(index);            ReturnToPool(child);        }        /// <summary>        ///         /// </summary>        /// <param name="child"></param>        public void RemoveChildToPool(GObject child)        {            base.RemoveChild(child);            ReturnToPool(child);        }        /// <summary>        ///         /// </summary>        public void RemoveChildrenToPool()        {            RemoveChildrenToPool(0, -1);        }        /// <summary>        ///         /// </summary>        /// <param name="beginIndex"></param>        /// <param name="endIndex"></param>        public void RemoveChildrenToPool(int beginIndex, int endIndex)        {            if (endIndex < 0 || endIndex >= _children.Count)                endIndex = _children.Count - 1;            for (int i = beginIndex; i <= endIndex; ++i)                RemoveChildToPoolAt(beginIndex);        }        /// <summary>        ///         /// </summary>        public int selectedIndex        {            get            {                if (_virtual)                {                    int cnt = _realNumItems;                    for (int i = 0; i < cnt; i++)                    {                        ItemInfo ii = _virtualItems[i];                        if ((ii.obj is GButton) && ((GButton)ii.obj).selected                            || ii.obj == null && ii.selected)                        {                            if (_loop)                                return i % _numItems;                            else                                return i;                        }                    }                }                else                {                    int cnt = _children.Count;                    for (int i = 0; i < cnt; i++)                    {                        GButton obj = _children[i].asButton;                        if (obj != null && obj.selected)                            return i;                    }                }                return -1;            }            set            {                if (value >= 0 && value < this.numItems)                {                    if (selectionMode != ListSelectionMode.Single)                        ClearSelection();                    AddSelection(value, false);                }                else                    ClearSelection();            }        }        /// <summary>        ///         /// </summary>        public Controller selectionController        {            get { return _selectionController; }            set { _selectionController = value; }        }        /// <summary>        ///         /// </summary>        /// <returns></returns>        public List<int> GetSelection()        {            return GetSelection(null);        }        /// <summary>        ///         /// </summary>        /// <returns></returns>        public List<int> GetSelection(List<int> result)        {            if (result == null)                result = new List<int>();            if (_virtual)            {                int cnt = _realNumItems;                for (int i = 0; i < cnt; i++)                {                    ItemInfo ii = _virtualItems[i];                    if ((ii.obj is GButton) && ((GButton)ii.obj).selected                        || ii.obj == null && ii.selected)                    {                        int j = i;                        if (_loop)                        {                            j = i % _numItems;                            if (result.Contains(j))                                continue;                        }                        result.Add(j);                    }                }            }            else            {                int cnt = _children.Count;                for (int i = 0; i < cnt; i++)                {                    GButton obj = _children[i].asButton;                    if (obj != null && obj.selected)                        result.Add(i);                }            }            return result;        }        /// <summary>        ///         /// </summary>        /// <param name="index"></param>        /// <param name="scrollItToView"></param>        public void AddSelection(int index, bool scrollItToView)        {            if (selectionMode == ListSelectionMode.None)                return;            CheckVirtualList();            if (selectionMode == ListSelectionMode.Single)                ClearSelection();            if (scrollItToView)                ScrollToView(index);            _lastSelectedIndex = index;            GButton obj = null;            if (_virtual)            {                ItemInfo ii = _virtualItems[index];                if (ii.obj != null)                    obj = ii.obj.asButton;                ii.selected = true;            }            else                obj = GetChildAt(index).asButton;            if (obj != null && !obj.selected)            {                obj.selected = true;                UpdateSelectionController(index);            }        }        /// <summary>        ///         /// </summary>        /// <param name="index"></param>        public void RemoveSelection(int index)        {            if (selectionMode == ListSelectionMode.None)                return;            GButton obj = null;            if (_virtual)            {                ItemInfo ii = _virtualItems[index];                if (ii.obj != null)                    obj = ii.obj.asButton;                ii.selected = false;            }            else                obj = GetChildAt(index).asButton;            if (obj != null)                obj.selected = false;        }        /// <summary>        ///         /// </summary>        public void ClearSelection()        {            if (_virtual)            {                int cnt = _realNumItems;                for (int i = 0; i < cnt; i++)                {                    ItemInfo ii = _virtualItems[i];                    if ((ii.obj is GButton))                        ((GButton)ii.obj).selected = false;                    ii.selected = false;                }            }            else            {                int cnt = _children.Count;                for (int i = 0; i < cnt; i++)                {                    GButton obj = _children[i].asButton;                    if (obj != null)                        obj.selected = false;                }            }        }        void ClearSelectionExcept(GObject g)        {            if (_virtual)            {                int cnt = _realNumItems;                for (int i = 0; i < cnt; i++)                {                    ItemInfo ii = _virtualItems[i];                    if (ii.obj != g)                    {                        if ((ii.obj is GButton))                            ((GButton)ii.obj).selected = false;                        ii.selected = false;                    }                }            }            else            {                int cnt = _children.Count;                for (int i = 0; i < cnt; i++)                {                    GButton obj = _children[i].asButton;                    if (obj != null && obj != g)                        obj.selected = false;                }            }        }        /// <summary>        ///         /// </summary>        public void SelectAll()        {            CheckVirtualList();            int last = -1;            if (_virtual)            {                int cnt = _realNumItems;                for (int i = 0; i < cnt; i++)                {                    ItemInfo ii = _virtualItems[i];                    if ((ii.obj is GButton) && !((GButton)ii.obj).selected)                    {                        ((GButton)ii.obj).selected = true;                        last = i;                    }                    ii.selected = true;                }            }            else            {                int cnt = _children.Count;                for (int i = 0; i < cnt; i++)                {                    GButton obj = _children[i].asButton;                    if (obj != null && !obj.selected)                    {                        obj.selected = true;                        last = i;                    }                }            }            if (last != -1)                UpdateSelectionController(last);        }        /// <summary>        ///         /// </summary>        public void SelectNone()        {            ClearSelection();        }        /// <summary>        ///         /// </summary>        public void SelectReverse()        {            CheckVirtualList();            int last = -1;            if (_virtual)            {                int cnt = _realNumItems;                for (int i = 0; i < cnt; i++)                {                    ItemInfo ii = _virtualItems[i];                    if ((ii.obj is GButton))                    {                        ((GButton)ii.obj).selected = !((GButton)ii.obj).selected;                        if (((GButton)ii.obj).selected)                            last = i;                    }                    ii.selected = !ii.selected;                }            }            else            {                int cnt = _children.Count;                for (int i = 0; i < cnt; i++)                {                    GButton obj = _children[i].asButton;                    if (obj != null)                    {                        obj.selected = !obj.selected;                        if (obj.selected)                            last = i;                    }                }            }            if (last != -1)                UpdateSelectionController(last);        }        /// <summary>        ///         /// </summary>        /// <param name="enabled"></param>        public void EnableSelectionFocusEvents(bool enabled)        {            if (((_miscFlags & 2) != 0) == enabled)                return;            if (enabled)            {                _miscFlags |= 2;                this.tabStopChildren = true;                onFocusIn.Add(NotifySelection);                onFocusOut.Add(NotifySelection);            }            else            {                _miscFlags &= 0xFD;                onFocusIn.Remove(NotifySelection);                onFocusOut.Remove(NotifySelection);            }        }        void NotifySelection(EventContext context)        {            string eventType = context.type == "onFocusIn" ? "onListFocusIn" : "onListFocusOut";            int cnt = _children.Count;            for (int i = 0; i < cnt; i++)            {                GButton obj = _children[i].asButton;                if (obj != null && obj.selected)                    obj.DispatchEvent(eventType);            }        }        /// <summary>        ///         /// </summary>        public void EnableArrowKeyNavigation(bool enabled)        {            if (enabled)            {                this.tabStopChildren = true;                onKeyDown.Add(__keydown);            }            else            {                this.tabStopChildren = false;                onKeyDown.Remove(__keydown);            }        }        void __keydown(EventContext context)        {            int index = -1;            switch (context.inputEvent.keyCode)            {                case KeyCode.LeftArrow:                    index = HandleArrowKey(7);                    break;                case KeyCode.RightArrow:                    index = HandleArrowKey(3);                    break;                case KeyCode.UpArrow:                    index = HandleArrowKey(1);                    break;                case KeyCode.DownArrow:                    index = HandleArrowKey(5);                    break;            }            if (index != -1)            {                index = ItemIndexToChildIndex(index);                if (index != -1)                    DispatchItemEvent(GetChildAt(index), context);                context.StopPropagation();            }        }        /// <summary>        ///         /// </summary>        /// <param name="dir"></param>        public int HandleArrowKey(int dir)        {            int curIndex = this.selectedIndex;            if (curIndex == -1)                return -1;            int index = curIndex;            switch (dir)            {                case 1://up                    if (_layout == ListLayoutType.SingleColumn || _layout == ListLayoutType.FlowVertical)                    {                        index--;                    }                    else if (_layout == ListLayoutType.FlowHorizontal || _layout == ListLayoutType.Pagination)                    {                        if (_virtual)                        {                            index -= _curLineItemCount;                        }                        else                        {                            GObject current = _children[index];                            int k = 0;                            int i;                            for (i = index - 1; i >= 0; i--)                            {                                GObject obj = _children[i];                                if (obj.y != current.y)                                {                                    current = obj;                                    break;                                }                                k++;                            }                            for (; i >= 0; i--)                            {                                GObject obj = _children[i];                                if (obj.y != current.y)                                {                                    index = i + k + 1;                                    break;                                }                            }                        }                    }                    break;                case 3://right                    if (_layout == ListLayoutType.SingleRow || _layout == ListLayoutType.FlowHorizontal || _layout == ListLayoutType.Pagination)                    {                        index++;                    }                    else if (_layout == ListLayoutType.FlowVertical)                    {                        if (_virtual)                        {                            index += _curLineItemCount;                        }                        else                        {                            GObject current = _children[index];                            int k = 0;                            int cnt = _children.Count;                            int i;                            for (i = index + 1; i < cnt; i++)                            {                                GObject obj = _children[i];                                if (obj.x != current.x)                                {                                    current = obj;                                    break;                                }                                k++;                            }                            for (; i < cnt; i++)                            {                                GObject obj = _children[i];                                if (obj.x != current.x)                                {                                    index = i - k - 1;                                    break;                                }                            }                        }                    }                    break;                case 5://down                    if (_layout == ListLayoutType.SingleColumn || _layout == ListLayoutType.FlowVertical)                    {                        index++;                    }                    else if (_layout == ListLayoutType.FlowHorizontal || _layout == ListLayoutType.Pagination)                    {                        if (_virtual)                        {                            index += _curLineItemCount;                        }                        else                        {                            GObject current = _children[index];                            int k = 0;                            int cnt = _children.Count;                            int i;                            for (i = index + 1; i < cnt; i++)                            {                                GObject obj = _children[i];                                if (obj.y != current.y)                                {                                    current = obj;                                    break;                                }                                k++;                            }                            for (; i < cnt; i++)                            {                                GObject obj = _children[i];                                if (obj.y != current.y)                                {                                    index = i - k - 1;                                    break;                                }                            }                        }                    }                    break;                case 7://left                    if (_layout == ListLayoutType.SingleRow || _layout == ListLayoutType.FlowHorizontal || _layout == ListLayoutType.Pagination)                    {                        index--;                    }                    else if (_layout == ListLayoutType.FlowVertical)                    {                        if (_virtual)                        {                            index -= _curLineItemCount;                        }                        else                        {                            GObject current = _children[index];                            int k = 0;                            int i;                            for (i = index - 1; i >= 0; i--)                            {                                GObject obj = _children[i];                                if (obj.x != current.x)                                {                                    current = obj;                                    break;                                }                                k++;                            }                            for (; i >= 0; i--)                            {                                GObject obj = _children[i];                                if (obj.x != current.x)                                {                                    index = i + k + 1;                                    break;                                }                            }                        }                    }                    break;            }            if (index != curIndex && index >= 0 && index < this.numItems)            {                ClearSelection();                AddSelection(index, true);                return index;            }            else                return -1;        }        void __clickItem(EventContext context)        {            GObject item = context.sender as GObject;            if ((item is GButton) && selectionMode != ListSelectionMode.None)                SetSelectionOnEvent(item, context.inputEvent);            if (scrollPane != null && scrollItemToViewOnClick)                scrollPane.ScrollToView(item, true);            DispatchItemEvent(item, context);        }        virtual protected void DispatchItemEvent(GObject item, EventContext context)        {            if (context.type == item.onRightClick.type)                DispatchEvent("onRightClickItem", item);            else                DispatchEvent("onClickItem", item);        }        void SetSelectionOnEvent(GObject item, InputEvent evt)        {            bool dontChangeLastIndex = false;            GButton button = (GButton)item;            int index = ChildIndexToItemIndex(GetChildIndex(item));            if (selectionMode == ListSelectionMode.Single)            {                if (!button.selected)                {                    ClearSelectionExcept(button);                    button.selected = true;                }            }            else            {                if (evt.shift)                {                    if (!button.selected)                    {                        if (_lastSelectedIndex != -1)                        {                            int min = Math.Min(_lastSelectedIndex, index);                            int max = Math.Max(_lastSelectedIndex, index);                            max = Math.Min(max, this.numItems - 1);                            if (_virtual)                            {                                for (int i = min; i <= max; i++)                                {                                    ItemInfo ii = _virtualItems[i];                                    if (ii.obj is GButton)                                        ((GButton)ii.obj).selected = true;                                    ii.selected = true;                                }                            }                            else                            {                                for (int i = min; i <= max; i++)                                {                                    GButton obj = GetChildAt(i).asButton;                                    if (obj != null && !obj.selected)                                        obj.selected = true;                                }                            }                            dontChangeLastIndex = true;                        }                        else                        {                            button.selected = true;                        }                    }                }                else if (evt.ctrlOrCmd || selectionMode == ListSelectionMode.Multiple_SingleClick)                {                    button.selected = !button.selected;                }                else                {                    if (!button.selected)                    {                        ClearSelectionExcept(button);                        button.selected = true;                    }                    else if (evt.button == 0)                        ClearSelectionExcept(button);                }            }            if (!dontChangeLastIndex)                _lastSelectedIndex = index;            if (button.selected)                UpdateSelectionController(index);        }        /// <summary>        /// Resize to list size to fit specified item count.         /// If list layout is single column or flow horizontally, the height will change to fit.         /// If list layout is single row or flow vertically, the width will change to fit.        /// </summary>        public void ResizeToFit()        {            ResizeToFit(int.MaxValue, 0);        }        /// <summary>        /// Resize to list size to fit specified item count.         /// If list layout is single column or flow horizontally, the height will change to fit.         /// If list layout is single row or flow vertically, the width will change to fit.        /// </summary>        /// <param name="itemCount">Item count</param>        public void ResizeToFit(int itemCount)        {            ResizeToFit(itemCount, 0);        }        /// <summary>        /// Resize to list size to fit specified item count.         /// If list layout is single column or flow horizontally, the height will change to fit.         /// If list layout is single row or flow vertically, the width will change to fit.        /// </summary>        /// <param name="itemCount">>Item count</param>        /// <param name="minSize">If the result size if smaller than minSize, then use minSize.</param>        public void ResizeToFit(int itemCount, int minSize)        {            EnsureBoundsCorrect();            int curCount = this.numItems;            if (itemCount > curCount)                itemCount = curCount;            if (_virtual)            {                int lineCount = Mathf.CeilToInt((float)itemCount / _curLineItemCount);                if (_layout == ListLayoutType.SingleColumn || _layout == ListLayoutType.FlowHorizontal)                    this.viewHeight = lineCount * _itemSize.y + Math.Max(0, lineCount - 1) * _lineGap;                else                    this.viewWidth = lineCount * _itemSize.x + Math.Max(0, lineCount - 1) * _columnGap;            }            else if (itemCount == 0)            {                if (_layout == ListLayoutType.SingleColumn || _layout == ListLayoutType.FlowHorizontal)                    this.viewHeight = minSize;                else                    this.viewWidth = minSize;            }            else            {                int i = itemCount - 1;                GObject obj = null;                while (i >= 0)                {                    obj = this.GetChildAt(i);                    if (!foldInvisibleItems || obj.visible)                        break;                    i--;                }                if (i < 0)                {                    if (_layout == ListLayoutType.SingleColumn || _layout == ListLayoutType.FlowHorizontal)                        this.viewHeight = minSize;                    else                        this.viewWidth = minSize;                }                else                {                    float size;                    if (_layout == ListLayoutType.SingleColumn || _layout == ListLayoutType.FlowHorizontal)                    {                        size = obj.y + obj.height;                        if (size < minSize)                            size = minSize;                        this.viewHeight = size;                    }                    else                    {                        size = obj.x + obj.width;                        if (size < minSize)                            size = minSize;                        this.viewWidth = size;                    }                }            }        }        /// <summary>        ///         /// </summary>        override protected void HandleSizeChanged()        {            base.HandleSizeChanged();            SetBoundsChangedFlag();            if (_virtual)                SetVirtualListChangedFlag(true);        }        override public void HandleControllerChanged(Controller c)        {            base.HandleControllerChanged(c);            if (_selectionController == c)                this.selectedIndex = c.selectedIndex;        }        void UpdateSelectionController(int index)        {            if (_selectionController != null && !_selectionController.changing                && index < _selectionController.pageCount)            {                Controller c = _selectionController;                _selectionController = null;                c.selectedIndex = index;                _selectionController = c;            }        }        /// <summary>        /// Scroll the list to make an item with certain index visible.        /// </summary>        /// <param name="index">Item index</param>        public void ScrollToView(int index)        {            ScrollToView(index, false);        }        /// <summary>        ///  Scroll the list to make an item with certain index visible.        /// </summary>        /// <param name="index">Item index</param>        /// <param name="ani">True to scroll smoothly, othewise immdediately.</param>        public void ScrollToView(int index, bool ani)        {            ScrollToView(index, ani, false);        }        /// <summary>        ///  Scroll the list to make an item with certain index visible.        /// </summary>        /// <param name="index">Item index</param>        /// <param name="ani">True to scroll smoothly, othewise immdediately.</param>        /// <param name="setFirst">If true, scroll to make the target on the top/left; If false, scroll to make the target any position in view.</param>        public void ScrollToView(int index, bool ani, bool setFirst)        {            if (_virtual)            {                if (_numItems == 0)                    return;                CheckVirtualList();                if (index >= _virtualItems.Count)                    throw new Exception("Invalid child index: " + index + ">" + _virtualItems.Count);                if (_loop)                    index = Mathf.FloorToInt((float)_firstIndex / _numItems) * _numItems + index;                Rect rect;                ItemInfo ii = _virtualItems[index];                if (_layout == ListLayoutType.SingleColumn || _layout == ListLayoutType.FlowHorizontal)                {                    float pos = 0;                    for (int i = _curLineItemCount - 1; i < index; i += _curLineItemCount)                        pos += _virtualItems[i].size.y + _lineGap;                    rect = new Rect(0, pos, _itemSize.x, ii.size.y);                }                else if (_layout == ListLayoutType.SingleRow || _layout == ListLayoutType.FlowVertical)                {                    float pos = 0;                    for (int i = _curLineItemCount - 1; i < index; i += _curLineItemCount)                        pos += _virtualItems[i].size.x + _columnGap;                    rect = new Rect(pos, 0, ii.size.x, _itemSize.y);                }                else                {                    int page = index / (_curLineItemCount * _curLineItemCount2);                    rect = new Rect(page * viewWidth + (index % _curLineItemCount) * (ii.size.x + _columnGap),                        (index / _curLineItemCount) % _curLineItemCount2 * (ii.size.y + _lineGap),                        ii.size.x, ii.size.y);                }                if (this.scrollPane != null)                    scrollPane.ScrollToView(rect, ani, setFirst);                else if (parent != null && parent.scrollPane != null)                    parent.scrollPane.ScrollToView(this.TransformRect(rect, parent), ani, setFirst);            }            else            {                GObject obj = GetChildAt(index);                if (this.scrollPane != null)                    scrollPane.ScrollToView(obj, ani, setFirst);                else if (parent != null && parent.scrollPane != null)                    parent.scrollPane.ScrollToView(obj, ani, setFirst);            }        }        /// <summary>        /// 获取当前点击哪个item        /// </summary>        public GObject touchItem        {            get            {                //find out which item is under finger                //逐层往上知道查到点击了那个item                GObject obj = GRoot.inst.touchTarget;                GObject p = obj.parent;                while (p != null)                {                    if (p == this)                        return obj;                    obj = p;                    p = p.parent;                }                return null;            }        }        /// <summary>        /// Get first child in view.        /// </summary>        /// <returns></returns>        public override int GetFirstChildInView()        {            return ChildIndexToItemIndex(base.GetFirstChildInView());        }        public int ChildIndexToItemIndex(int index)        {            if (!_virtual)                return index;            if (_layout == ListLayoutType.Pagination)            {                for (int i = _firstIndex; i < _realNumItems; i++)                {                    if (_virtualItems[i].obj != null)                    {                        index--;                        if (index < 0)                            return i;                    }                }                return index;            }            else            {                index += _firstIndex;                if (_loop && _numItems > 0)                    index = index % _numItems;                return index;            }        }        public int ItemIndexToChildIndex(int index)        {            if (!_virtual)                return index;            if (_layout == ListLayoutType.Pagination)            {                return GetChildIndex(_virtualItems[index].obj);            }            else            {                if (_loop && _numItems > 0)                {                    int j = _firstIndex % _numItems;                    if (index >= j)                        index = index - j;                    else                        index = _numItems - j + index;                }                else                    index -= _firstIndex;                return index;            }        }        /// <summary>        /// Set the list to be virtual list.        /// 设置列表为虚拟列表模式。在虚拟列表模式下,列表不会为每一条列表数据创建一个实体对象,而是根据视口大小创建最小量的显示对象,然后通过itemRenderer指定的回调函数设置列表数据。        /// 在虚拟模式下,你不能通过AddChild、RemoveChild等方式管理列表,只能通过设置numItems设置列表数据的长度。        /// 如果要刷新列表,可以通过重新设置numItems,或者调用RefreshVirtualList完成。        /// ‘单行’或者‘单列’的列表布局可支持不等高的列表项目。        /// 除了‘页面’的列表布局,其他布局均支持使用不同资源构建列表项目,你可以在itemProvider里返回。如果不提供,默认使用defaultItem。        /// </summary>        public void SetVirtual()        {            SetVirtual(false);        }        public bool isVirtual        {            get { return _virtual; }        }        /// <summary>        /// Set the list to be virtual list, and has loop behavior.        /// </summary>        public void SetVirtualAndLoop()        {            SetVirtual(true);        }        void SetVirtual(bool loop)        {            if (!_virtual)            {                if (this.scrollPane == null)                    Debug.LogError("FairyGUI: Virtual list must be scrollable!");                if (loop)                {                    if (_layout == ListLayoutType.FlowHorizontal || _layout == ListLayoutType.FlowVertical)                        Debug.LogError("FairyGUI: Loop list is not supported for FlowHorizontal or FlowVertical layout!");                    this.scrollPane.bouncebackEffect = false;                }                _virtual = true;                _loop = loop;                _virtualItems = new List<ItemInfo>();                RemoveChildrenToPool();                if (_itemSize.x == 0 || _itemSize.y == 0)                {                    GObject obj = GetFromPool(null);                    if (obj == null)                    {                        Debug.LogError("FairyGUI: Virtual List must have a default list item resource.");                        _itemSize = new Vector2(100, 100);                    }                    else                    {                        _itemSize = obj.size;                        _itemSize.x = Mathf.CeilToInt(_itemSize.x);                        _itemSize.y = Mathf.CeilToInt(_itemSize.y);                        ReturnToPool(obj);                    }                }                if (_layout == ListLayoutType.SingleColumn || _layout == ListLayoutType.FlowHorizontal)                {                    this.scrollPane.scrollStep = _itemSize.y;                    if (_loop)                        this.scrollPane._loop = 2;                }                else                {                    this.scrollPane.scrollStep = _itemSize.x;                    if (_loop)                        this.scrollPane._loop = 1;                }                this.scrollPane.onScroll.AddCapture(__scrolled);                SetVirtualListChangedFlag(true);            }        }        /// <summary>        /// Set the list item count.         /// If the list is not virtual, specified number of items will be created.         /// If the list is virtual, only items in view will be created.        /// </summary>        public int numItems        {            get            {                if (_virtual)                    return _numItems;                else                    return _children.Count;            }            set            {                if (_virtual)                {                    if (itemRenderer == null)                        throw new Exception("FairyGUI: Set itemRenderer first!");                    _numItems = value;                    if (_loop)                        _realNumItems = _numItems * 6;//设置6倍数量,用于循环滚动                    else                        _realNumItems = _numItems;                    //_virtualItems的设计是只增不减的                    int oldCount = _virtualItems.Count;                    if (_realNumItems > oldCount)                    {                        for (int i = oldCount; i < _realNumItems; i++)                        {                            ItemInfo ii = new ItemInfo();                            ii.size = _itemSize;                            _virtualItems.Add(ii);                        }                    }                    else                    {                        for (int i = _realNumItems; i < oldCount; i++)                            _virtualItems[i].selected = false;                    }                    if (_virtualListChanged != 0)                        Timers.inst.Remove(this.RefreshVirtualList);                    //立即刷新                    this.RefreshVirtualList(null);                }                else                {                    int cnt = _children.Count;                    if (value > cnt)                    {                        for (int i = cnt; i < value; i++)                        {                            if (itemProvider == null)                                AddItemFromPool();                            else                                AddItemFromPool(itemProvider(i));                        }                    }                    else                    {                        RemoveChildrenToPool(value, cnt);                    }                    if (itemRenderer != null)                    {                        for (int i = 0; i < value; i++)                            itemRenderer(i, GetChildAt(i));                    }                }            }        }        public void RefreshVirtualList()        {            if (!_virtual)                throw new Exception("FairyGUI: not virtual list");            SetVirtualListChangedFlag(false);        }        void CheckVirtualList()        {            if (_virtualListChanged != 0)            {                this.RefreshVirtualList(null);                Timers.inst.Remove(this.RefreshVirtualList);            }        }        void SetVirtualListChangedFlag(bool layoutChanged)        {            if (layoutChanged)                _virtualListChanged = 2;            else if (_virtualListChanged == 0)                _virtualListChanged = 1;            Timers.inst.CallLater(RefreshVirtualList);        }        void RefreshVirtualList(object param)        {            bool layoutChanged = _virtualListChanged == 2;            _virtualListChanged = 0;            _miscFlags |= 1;            if (layoutChanged)            {                if (_layout == ListLayoutType.SingleColumn || _layout == ListLayoutType.SingleRow)                    _curLineItemCount = 1;                else if (_layout == ListLayoutType.FlowHorizontal)                {                    if (_columnCount > 0)                        _curLineItemCount = _columnCount;                    else                    {                        _curLineItemCount = Mathf.FloorToInt((this.scrollPane.viewWidth + _columnGap) / (_itemSize.x + _columnGap));                        if (_curLineItemCount <= 0)                            _curLineItemCount = 1;                    }                }                else if (_layout == ListLayoutType.FlowVertical)                {                    if (_lineCount > 0)                        _curLineItemCount = _lineCount;                    else                    {                        _curLineItemCount = Mathf.FloorToInt((this.scrollPane.viewHeight + _lineGap) / (_itemSize.y + _lineGap));                        if (_curLineItemCount <= 0)                            _curLineItemCount = 1;                    }                }                else //pagination                {                    if (_columnCount > 0)                        _curLineItemCount = _columnCount;                    else                    {                        _curLineItemCount = Mathf.FloorToInt((this.scrollPane.viewWidth + _columnGap) / (_itemSize.x + _columnGap));                        if (_curLineItemCount <= 0)                            _curLineItemCount = 1;                    }                    if (_lineCount > 0)                        _curLineItemCount2 = _lineCount;                    else                    {                        _curLineItemCount2 = Mathf.FloorToInt((this.scrollPane.viewHeight + _lineGap) / (_itemSize.y + _lineGap));                        if (_curLineItemCount2 <= 0)                            _curLineItemCount2 = 1;                    }                }            }            float ch = 0, cw = 0;            if (_realNumItems > 0)            {                int len = Mathf.CeilToInt((float)_realNumItems / _curLineItemCount) * _curLineItemCount;                int len2 = Math.Min(_curLineItemCount, _realNumItems);                if (_layout == ListLayoutType.SingleColumn || _layout == ListLayoutType.FlowHorizontal)                {                    for (int i = 0; i < len; i += _curLineItemCount)                        ch += _virtualItems[i].size.y + _lineGap;                    if (ch > 0)                        ch -= _lineGap;                    if (_autoResizeItem)                        cw = scrollPane.viewWidth;                    else                    {                        for (int i = 0; i < len2; i++)                            cw += _virtualItems[i].size.x + _columnGap;                        if (cw > 0)                            cw -= _columnGap;                    }                }                else if (_layout == ListLayoutType.SingleRow || _layout == ListLayoutType.FlowVertical)                {                    for (int i = 0; i < len; i += _curLineItemCount)                        cw += _virtualItems[i].size.x + _columnGap;                    if (cw > 0)                        cw -= _columnGap;                    if (_autoResizeItem)                        ch = this.scrollPane.viewHeight;                    else                    {                        for (int i = 0; i < len2; i++)                            ch += _virtualItems[i].size.y + _lineGap;                        if (ch > 0)                            ch -= _lineGap;                    }                }                else                {                    int pageCount = Mathf.CeilToInt((float)len / (_curLineItemCount * _curLineItemCount2));                    cw = pageCount * viewWidth;                    ch = viewHeight;                }            }            HandleAlign(cw, ch);            this.scrollPane.SetContentSize(cw, ch);            _miscFlags &= 0xFE;            HandleScroll(true);        }        void __scrolled(EventContext context)        {            HandleScroll(false);        }        int GetIndexOnPos1(ref float pos, bool forceUpdate)        {            if (_realNumItems < _curLineItemCount)            {                pos = 0;                return 0;            }            if (numChildren > 0 && !forceUpdate)            {                float pos2 = this.GetChildAt(0).y;                if (pos2 + (_lineGap > 0 ? 0 : -_lineGap) > pos)                {                    for (int i = _firstIndex - _curLineItemCount; i >= 0; i -= _curLineItemCount)                    {                        pos2 -= (_virtualItems[i].size.y + _lineGap);                        if (pos2 <= pos)                        {                            pos = pos2;                            return i;                        }                    }                    pos = 0;                    return 0;                }                else                {                    float testGap = _lineGap > 0 ? _lineGap : 0;                    for (int i = _firstIndex; i < _realNumItems; i += _curLineItemCount)                    {                        float pos3 = pos2 + _virtualItems[i].size.y;                        if (pos3 + testGap > pos)                        {                            pos = pos2;                            return i;                        }                        pos2 = pos3 + _lineGap;                    }                    pos = pos2;                    return _realNumItems - _curLineItemCount;                }            }            else            {                float pos2 = 0;                float testGap = _lineGap > 0 ? _lineGap : 0;                for (int i = 0; i < _realNumItems; i += _curLineItemCount)                {                    float pos3 = pos2 + _virtualItems[i].size.y;                    if (pos3 + testGap > pos)                    {                        pos = pos2;                        return i;                    }                    pos2 = pos3 + _lineGap;                }                pos = pos2;                return _realNumItems - _curLineItemCount;            }        }        int GetIndexOnPos2(ref float pos, bool forceUpdate)        {            if (_realNumItems < _curLineItemCount)            {                pos = 0;                return 0;            }            if (numChildren > 0 && !forceUpdate)            {                float pos2 = this.GetChildAt(0).x;                if (pos2 + (_columnGap > 0 ? 0 : -_columnGap) > pos)                {                    for (int i = _firstIndex - _curLineItemCount; i >= 0; i -= _curLineItemCount)                    {                        pos2 -= (_virtualItems[i].size.x + _columnGap);                        if (pos2 <= pos)                        {                            pos = pos2;                            return i;                        }                    }                    pos = 0;                    return 0;                }                else                {                    float testGap = _columnGap > 0 ? _columnGap : 0;                    for (int i = _firstIndex; i < _realNumItems; i += _curLineItemCount)                    {                        float pos3 = pos2 + _virtualItems[i].size.x;                        if (pos3 + testGap > pos)                        {                            pos = pos2;                            return i;                        }                        pos2 = pos3 + _columnGap;                    }                    pos = pos2;                    return _realNumItems - _curLineItemCount;                }            }            else            {                float pos2 = 0;                float testGap = _columnGap > 0 ? _columnGap : 0;                for (int i = 0; i < _realNumItems; i += _curLineItemCount)                {                    float pos3 = pos2 + _virtualItems[i].size.x;                    if (pos3 + testGap > pos)                    {                        pos = pos2;                        return i;                    }                    pos2 = pos3 + _columnGap;                }                pos = pos2;                return _realNumItems - _curLineItemCount;            }        }        int GetIndexOnPos3(ref float pos, bool forceUpdate)        {            if (_realNumItems < _curLineItemCount)            {                pos = 0;                return 0;            }            float viewWidth = this.viewWidth;            int page = Mathf.FloorToInt(pos / viewWidth);            int startIndex = page * (_curLineItemCount * _curLineItemCount2);            float pos2 = page * viewWidth;            float testGap = _columnGap > 0 ? _columnGap : 0;            for (int i = 0; i < _curLineItemCount; i++)            {                float pos3 = pos2 + _virtualItems[startIndex + i].size.x;                if (pos3 + testGap > pos)                {                    pos = pos2;                    return startIndex + i;                }                pos2 = pos3 + _columnGap;            }            pos = pos2;            return startIndex + _curLineItemCount - 1;        }        void HandleScroll(bool forceUpdate)        {            if ((_miscFlags & 1) != 0)                return;            if (_layout == ListLayoutType.SingleColumn || _layout == ListLayoutType.FlowHorizontal)            {                int enterCounter = 0;                while (HandleScroll1(forceUpdate))                {                    //可能会因为ITEM资源改变导致ITEM大小发生改变,所有出现最后一页填不满的情况,这时要反复尝试填满。                    enterCounter++;                    forceUpdate = false;                    if (enterCounter > 20)                    {                        Debug.Log("FairyGUI: list will never be filled as the item renderer function always returns a different size.");                        break;                    }                }                HandleArchOrder1();            }            else if (_layout == ListLayoutType.SingleRow || _layout == ListLayoutType.FlowVertical)            {                int enterCounter = 0;                while (HandleScroll2(forceUpdate))                {                    enterCounter++;                    forceUpdate = false;                    if (enterCounter > 20)                    {                        Debug.Log("FairyGUI: list will never be filled as the item renderer function always returns a different size.");                        break;                    }                }                HandleArchOrder2();            }            else            {                HandleScroll3(forceUpdate);            }            _boundsChanged = false;        }        bool HandleScroll1(bool forceUpdate)        {            float pos = scrollPane.scrollingPosY;            float max = pos + scrollPane.viewHeight;            bool end = max == scrollPane.contentHeight;//这个标志表示当前需要滚动到最末,无论内容变化大小            //寻找当前位置的第一条项目            int newFirstIndex = GetIndexOnPos1(ref pos, forceUpdate);            if (newFirstIndex == _firstIndex && !forceUpdate)                return false;            int oldFirstIndex = _firstIndex;            _firstIndex = newFirstIndex;            int curIndex = newFirstIndex;            bool forward = oldFirstIndex > newFirstIndex;            int childCount = this.numChildren;            int lastIndex = oldFirstIndex + childCount - 1;            int reuseIndex = forward ? lastIndex : oldFirstIndex;            float curX = 0, curY = pos;            bool needRender;            float deltaSize = 0;            float firstItemDeltaSize = 0;            string url = defaultItem;            int partSize = (int)((scrollPane.viewWidth - _columnGap * (_curLineItemCount - 1)) / _curLineItemCount);            itemInfoVer++;            while (curIndex < _realNumItems && (end || curY < max))            {                ItemInfo ii = _virtualItems[curIndex];                if (ii.obj == null || forceUpdate)                {                    if (itemProvider != null)                    {                        url = itemProvider(curIndex % _numItems);                        if (url == null)                            url = defaultItem;                        url = UIPackage.NormalizeURL(url);                    }                    if (ii.obj != null && ii.obj.resourceURL != url)                    {                        if (ii.obj is GButton)                            ii.selected = ((GButton)ii.obj).selected;                        RemoveChildToPool(ii.obj);                        ii.obj = null;                    }                }                if (ii.obj == null)                {                    //搜索最适合的重用item,保证每次刷新需要新建或者重新render的item最少                    if (forward)                    {                        for (int j = reuseIndex; j >= oldFirstIndex; j--)                        {                            ItemInfo ii2 = _virtualItems[j];                            if (ii2.obj != null && ii2.updateFlag != itemInfoVer && ii2.obj.resourceURL == url)                            {                                if (ii2.obj is GButton)                                    ii2.selected = ((GButton)ii2.obj).selected;                                ii.obj = ii2.obj;                                ii2.obj = null;                                if (j == reuseIndex)                                    reuseIndex--;                                break;                            }                        }                    }                    else                    {                        for (int j = reuseIndex; j <= lastIndex; j++)                        {                            ItemInfo ii2 = _virtualItems[j];                            if (ii2.obj != null && ii2.updateFlag != itemInfoVer && ii2.obj.resourceURL == url)                            {                                if (ii2.obj is GButton)                                    ii2.selected = ((GButton)ii2.obj).selected;                                ii.obj = ii2.obj;                                ii2.obj = null;                                if (j == reuseIndex)                                    reuseIndex++;                                break;                            }                        }                    }                    if (ii.obj != null)                    {                        SetChildIndex(ii.obj, forward ? curIndex - newFirstIndex : numChildren);                    }                    else                    {                        ii.obj = _pool.GetObject(url);                        if (forward)                            this.AddChildAt(ii.obj, curIndex - newFirstIndex);                        else                            this.AddChild(ii.obj);                    }                    if (ii.obj is GButton)                        ((GButton)ii.obj).selected = ii.selected;                    needRender = true;                }                else                    needRender = forceUpdate;                if (needRender)                {                    if (_autoResizeItem && (_layout == ListLayoutType.SingleColumn || _columnCount > 0))                        ii.obj.SetSize(partSize, ii.obj.height, true);                    itemRenderer(curIndex % _numItems, ii.obj);                    if (curIndex % _curLineItemCount == 0)                    {                        deltaSize += Mathf.CeilToInt(ii.obj.size.y) - ii.size.y;                        if (curIndex == newFirstIndex && oldFirstIndex > newFirstIndex)                        {                            //当内容向下滚动时,如果新出现的项目大小发生变化,需要做一个位置补偿,才不会导致滚动跳动                            firstItemDeltaSize = Mathf.CeilToInt(ii.obj.size.y) - ii.size.y;                        }                    }                    ii.size.x = Mathf.CeilToInt(ii.obj.size.x);                    ii.size.y = Mathf.CeilToInt(ii.obj.size.y);                }                ii.updateFlag = itemInfoVer;                ii.obj.SetXY(curX, curY);                if (curIndex == newFirstIndex) //要显示多一条才不会穿帮                    max += ii.size.y;                curX += ii.size.x + _columnGap;                if (curIndex % _curLineItemCount == _curLineItemCount - 1)                {                    curX = 0;                    curY += ii.size.y + _lineGap;                }                curIndex++;            }            for (int i = 0; i < childCount; i++)            {                ItemInfo ii = _virtualItems[oldFirstIndex + i];                if (ii.updateFlag != itemInfoVer && ii.obj != null)                {                    if (ii.obj is GButton)                        ii.selected = ((GButton)ii.obj).selected;                    RemoveChildToPool(ii.obj);                    ii.obj = null;                }            }            childCount = _children.Count;            for (int i = 0; i < childCount; i++)            {                GObject obj = _virtualItems[newFirstIndex + i].obj;                if (_children[i] != obj)                    SetChildIndex(obj, i);            }            if (deltaSize != 0 || firstItemDeltaSize != 0)                this.scrollPane.ChangeContentSizeOnScrolling(0, deltaSize, 0, firstItemDeltaSize);            if (curIndex > 0 && this.numChildren > 0 && this.container.y <= 0 && GetChildAt(0).y > -this.container.y)//最后一页没填满!                return true;            else                return false;        }        bool HandleScroll2(bool forceUpdate)        {            float pos = scrollPane.scrollingPosX;            float max = pos + scrollPane.viewWidth;            bool end = pos == scrollPane.contentWidth;//这个标志表示当前需要滚动到最末,无论内容变化大小            //寻找当前位置的第一条项目            int newFirstIndex = GetIndexOnPos2(ref pos, forceUpdate);            if (newFirstIndex == _firstIndex && !forceUpdate)                return false;            int oldFirstIndex = _firstIndex;            _firstIndex = newFirstIndex;            int curIndex = newFirstIndex;            bool forward = oldFirstIndex > newFirstIndex;            int childCount = this.numChildren;            int lastIndex = oldFirstIndex + childCount - 1;            int reuseIndex = forward ? lastIndex : oldFirstIndex;            float curX = pos, curY = 0;            bool needRender;            float deltaSize = 0;            float firstItemDeltaSize = 0;            string url = defaultItem;            int partSize = (int)((scrollPane.viewHeight - _lineGap * (_curLineItemCount - 1)) / _curLineItemCount);            itemInfoVer++;            while (curIndex < _realNumItems && (end || curX < max))            {                ItemInfo ii = _virtualItems[curIndex];                if (ii.obj == null || forceUpdate)                {                    if (itemProvider != null)                    {                        url = itemProvider(curIndex % _numItems);                        if (url == null)                            url = defaultItem;                        url = UIPackage.NormalizeURL(url);                    }                    if (ii.obj != null && ii.obj.resourceURL != url)                    {                        if (ii.obj is GButton)                            ii.selected = ((GButton)ii.obj).selected;                        RemoveChildToPool(ii.obj);                        ii.obj = null;                    }                }                if (ii.obj == null)                {                    if (forward)                    {                        for (int j = reuseIndex; j >= oldFirstIndex; j--)                        {                            ItemInfo ii2 = _virtualItems[j];                            if (ii2.obj != null && ii2.updateFlag != itemInfoVer && ii2.obj.resourceURL == url)                            {                                if (ii2.obj is GButton)                                    ii2.selected = ((GButton)ii2.obj).selected;                                ii.obj = ii2.obj;                                ii2.obj = null;                                if (j == reuseIndex)                                    reuseIndex--;                                break;                            }                        }                    }                    else                    {                        for (int j = reuseIndex; j <= lastIndex; j++)                        {                            ItemInfo ii2 = _virtualItems[j];                            if (ii2.obj != null && ii2.updateFlag != itemInfoVer && ii2.obj.resourceURL == url)                            {                                if (ii2.obj is GButton)                                    ii2.selected = ((GButton)ii2.obj).selected;                                ii.obj = ii2.obj;                                ii2.obj = null;                                if (j == reuseIndex)                                    reuseIndex++;                                break;                            }                        }                    }                    if (ii.obj != null)                    {                        SetChildIndex(ii.obj, forward ? curIndex - newFirstIndex : numChildren);                    }                    else                    {                        ii.obj = _pool.GetObject(url);                        if (forward)                            this.AddChildAt(ii.obj, curIndex - newFirstIndex);                        else                            this.AddChild(ii.obj);                    }                    if (ii.obj is GButton)                        ((GButton)ii.obj).selected = ii.selected;                    needRender = true;                }                else                    needRender = forceUpdate;                if (needRender)                {                    if (_autoResizeItem && (_layout == ListLayoutType.SingleRow || _lineCount > 0))                        ii.obj.SetSize(ii.obj.width, partSize, true);                    itemRenderer(curIndex % _numItems, ii.obj);                    if (curIndex % _curLineItemCount == 0)                    {                        deltaSize += Mathf.CeilToInt(ii.obj.size.x) - ii.size.x;                        if (curIndex == newFirstIndex && oldFirstIndex > newFirstIndex)                        {                            //当内容向下滚动时,如果新出现的一个项目大小发生变化,需要做一个位置补偿,才不会导致滚动跳动                            firstItemDeltaSize = Mathf.CeilToInt(ii.obj.size.x) - ii.size.x;                        }                    }                    ii.size.x = Mathf.CeilToInt(ii.obj.size.x);                    ii.size.y = Mathf.CeilToInt(ii.obj.size.y);                }                ii.updateFlag = itemInfoVer;                ii.obj.SetXY(curX, curY);                if (curIndex == newFirstIndex) //要显示多一条才不会穿帮                    max += ii.size.x;                curY += ii.size.y + _lineGap;                if (curIndex % _curLineItemCount == _curLineItemCount - 1)                {                    curY = 0;                    curX += ii.size.x + _columnGap;                }                curIndex++;            }            for (int i = 0; i < childCount; i++)            {                ItemInfo ii = _virtualItems[oldFirstIndex + i];                if (ii.updateFlag != itemInfoVer && ii.obj != null)                {                    if (ii.obj is GButton)                        ii.selected = ((GButton)ii.obj).selected;                    RemoveChildToPool(ii.obj);                    ii.obj = null;                }            }            childCount = _children.Count;            for (int i = 0; i < childCount; i++)            {                GObject obj = _virtualItems[newFirstIndex + i].obj;                if (_children[i] != obj)                    SetChildIndex(obj, i);            }            if (deltaSize != 0 || firstItemDeltaSize != 0)                this.scrollPane.ChangeContentSizeOnScrolling(deltaSize, 0, firstItemDeltaSize, 0);            if (curIndex > 0 && this.numChildren > 0 && this.container.x <= 0 && GetChildAt(0).x > -this.container.x)//最后一页没填满!                return true;            else                return false;        }        void HandleScroll3(bool forceUpdate)        {            float pos = scrollPane.scrollingPosX;            //寻找当前位置的第一条项目            int newFirstIndex = GetIndexOnPos3(ref pos, forceUpdate);            if (newFirstIndex == _firstIndex && !forceUpdate)                return;            int oldFirstIndex = _firstIndex;            _firstIndex = newFirstIndex;            //分页模式不支持不等高,所以渲染满一页就好了            int reuseIndex = oldFirstIndex;            int virtualItemCount = _virtualItems.Count;            int pageSize = _curLineItemCount * _curLineItemCount2;            int startCol = newFirstIndex % _curLineItemCount;            float viewWidth = this.viewWidth;            int page = (int)(newFirstIndex / pageSize);            int startIndex = page * pageSize;            int lastIndex = startIndex + pageSize * 2; //测试两页            bool needRender;            string url = defaultItem;            int partWidth = (int)((scrollPane.viewWidth - _columnGap * (_curLineItemCount - 1)) / _curLineItemCount);            int partHeight = (int)((scrollPane.viewHeight - _lineGap * (_curLineItemCount2 - 1)) / _curLineItemCount2);            itemInfoVer++;            //先标记这次要用到的项目            for (int i = startIndex; i < lastIndex; i++)            {                if (i >= _realNumItems)                    continue;                int col = i % _curLineItemCount;                if (i - startIndex < pageSize)                {                    if (col < startCol)                        continue;                }                else                {                    if (col > startCol)                        continue;                }                ItemInfo ii = _virtualItems[i];                ii.updateFlag = itemInfoVer;            }            GObject lastObj = null;            int insertIndex = 0;            for (int i = startIndex; i < lastIndex; i++)            {                if (i >= _realNumItems)                    continue;                ItemInfo ii = _virtualItems[i];                if (ii.updateFlag != itemInfoVer)                    continue;                if (ii.obj == null)                {                    //寻找看有没有可重用的                    while (reuseIndex < virtualItemCount)                    {                        ItemInfo ii2 = _virtualItems[reuseIndex];                        if (ii2.obj != null && ii2.updateFlag != itemInfoVer)                        {                            if (ii2.obj is GButton)                                ii2.selected = ((GButton)ii2.obj).selected;                            ii.obj = ii2.obj;                            ii2.obj = null;                            break;                        }                        reuseIndex++;                    }                    if (insertIndex == -1)                        insertIndex = GetChildIndex(lastObj) + 1;                    if (ii.obj == null)                    {                        if (itemProvider != null)                        {                            url = itemProvider(i % _numItems);                            if (url == null)                                url = defaultItem;                            url = UIPackage.NormalizeURL(url);                        }                        ii.obj = _pool.GetObject(url);                        this.AddChildAt(ii.obj, insertIndex);                    }                    else                    {                        insertIndex = SetChildIndexBefore(ii.obj, insertIndex);                    }                    insertIndex++;                    if (ii.obj is GButton)                        ((GButton)ii.obj).selected = ii.selected;                    needRender = true;                }                else                {                    needRender = forceUpdate;                    insertIndex = -1;                    lastObj = ii.obj;                }                if (needRender)                {                    if (_autoResizeItem)                    {                        if (_curLineItemCount == _columnCount && _curLineItemCount2 == _lineCount)                            ii.obj.SetSize(partWidth, partHeight, true);                        else if (_curLineItemCount == _columnCount)                            ii.obj.SetSize(partWidth, ii.obj.height, true);                        else if (_curLineItemCount2 == _lineCount)                            ii.obj.SetSize(ii.obj.width, partHeight, true);                    }                    itemRenderer(i % _numItems, ii.obj);                    ii.size.x = Mathf.CeilToInt(ii.obj.size.x);                    ii.size.y = Mathf.CeilToInt(ii.obj.size.y);                }            }            //排列item            float borderX = (startIndex / pageSize) * viewWidth;            float xx = borderX;            float yy = 0;            float lineHeight = 0;            for (int i = startIndex; i < lastIndex; i++)            {                if (i >= _realNumItems)                    continue;                ItemInfo ii = _virtualItems[i];                if (ii.updateFlag == itemInfoVer)                    ii.obj.SetXY(xx, yy);                if (ii.size.y > lineHeight)                    lineHeight = ii.size.y;                if (i % _curLineItemCount == _curLineItemCount - 1)                {                    xx = borderX;                    yy += lineHeight + _lineGap;                    lineHeight = 0;                    if (i == startIndex + pageSize - 1)                    {                        borderX += viewWidth;                        xx = borderX;                        yy = 0;                    }                }                else                    xx += ii.size.x + _columnGap;            }            //释放未使用的            for (int i = reuseIndex; i < virtualItemCount; i++)            {                ItemInfo ii = _virtualItems[i];                if (ii.updateFlag != itemInfoVer && ii.obj != null)                {                    if (ii.obj is GButton)                        ii.selected = ((GButton)ii.obj).selected;                    RemoveChildToPool(ii.obj);                    ii.obj = null;                }            }        }        void HandleArchOrder1()        {            if (this.childrenRenderOrder == ChildrenRenderOrder.Arch)            {                float mid = this.scrollPane.posY + this.viewHeight / 2;                float minDist = int.MaxValue, dist;                int apexIndex = 0;                int cnt = this.numChildren;                for (int i = 0; i < cnt; i++)                {                    GObject obj = GetChildAt(i);                    if (!foldInvisibleItems || obj.visible)                    {                        dist = Mathf.Abs(mid - obj.y - obj.height / 2);                        if (dist < minDist)                        {                            minDist = dist;                            apexIndex = i;                        }                    }                }                this.apexIndex = apexIndex;            }        }        void HandleArchOrder2()        {            if (this.childrenRenderOrder == ChildrenRenderOrder.Arch)            {                float mid = this.scrollPane.posX + this.viewWidth / 2;                float minDist = int.MaxValue, dist;                int apexIndex = 0;                int cnt = this.numChildren;                for (int i = 0; i < cnt; i++)                {                    GObject obj = GetChildAt(i);                    if (!foldInvisibleItems || obj.visible)                    {                        dist = Mathf.Abs(mid - obj.x - obj.width / 2);                        if (dist < minDist)                        {                            minDist = dist;                            apexIndex = i;                        }                    }                }                this.apexIndex = apexIndex;            }        }        override protected internal void GetSnappingPosition(ref float xValue, ref float yValue)        {            if (_virtual)            {                if (_layout == ListLayoutType.SingleColumn || _layout == ListLayoutType.FlowHorizontal)                {                    float saved = yValue;                    int index = GetIndexOnPos1(ref yValue, false);                    if (index < _virtualItems.Count && saved - yValue > _virtualItems[index].size.y / 2 && index < _realNumItems)                        yValue += _virtualItems[index].size.y + _lineGap;                }                else if (_layout == ListLayoutType.SingleRow || _layout == ListLayoutType.FlowVertical)                {                    float saved = xValue;                    int index = GetIndexOnPos2(ref xValue, false);                    if (index < _virtualItems.Count && saved - xValue > _virtualItems[index].size.x / 2 && index < _realNumItems)                        xValue += _virtualItems[index].size.x + _columnGap;                }                else                {                    float saved = xValue;                    int index = GetIndexOnPos3(ref xValue, false);                    if (index < _virtualItems.Count && saved - xValue > _virtualItems[index].size.x / 2 && index < _realNumItems)                        xValue += _virtualItems[index].size.x + _columnGap;                }            }            else                base.GetSnappingPosition(ref xValue, ref yValue);        }        private void HandleAlign(float contentWidth, float contentHeight)        {            Vector2 newOffset = Vector2.zero;            if (contentHeight < viewHeight)            {                if (_verticalAlign == VertAlignType.Middle)                    newOffset.y = (int)((viewHeight - contentHeight) / 2);                else if (_verticalAlign == VertAlignType.Bottom)                    newOffset.y = viewHeight - contentHeight;            }            if (contentWidth < this.viewWidth)            {                if (_align == AlignType.Center)                    newOffset.x = (int)((viewWidth - contentWidth) / 2);                else if (_align == AlignType.Right)                    newOffset.x = viewWidth - contentWidth;            }            if (newOffset != _alignOffset)            {                _alignOffset = newOffset;                if (scrollPane != null)                    scrollPane.AdjustMaskContainer();                else                    container.SetXY(_margin.left + _alignOffset.x, _margin.top + _alignOffset.y);            }        }        override protected void UpdateBounds()        {            if (_virtual)                return;            int cnt = _children.Count;            int i;            int j = 0;            GObject child;            float curX = 0;            float curY = 0;            float cw, ch;            float maxWidth = 0;            float maxHeight = 0;            float viewWidth = this.viewWidth;            float viewHeight = this.viewHeight;            if (_layout == ListLayoutType.SingleColumn)            {                for (i = 0; i < cnt; i++)                {                    child = GetChildAt(i);                    if (foldInvisibleItems && !child.visible)                        continue;                    if (curY != 0)                        curY += _lineGap;                    child.y = curY;                    if (_autoResizeItem)                        child.SetSize(viewWidth, child.height, true);                    curY += Mathf.CeilToInt(child.height);                    if (child.width > maxWidth)                        maxWidth = child.width;                }                ch = curY;                if (ch <= viewHeight && _autoResizeItem && scrollPane != null && scrollPane._displayInDemand && scrollPane.vtScrollBar != null)                {                    viewWidth += scrollPane.vtScrollBar.width;                    for (i = 0; i < cnt; i++)                    {                        child = GetChildAt(i);                        if (foldInvisibleItems && !child.visible)                            continue;                        child.SetSize(viewWidth, child.height, true);                        if (child.width > maxWidth)                            maxWidth = child.width;                    }                }                cw = Mathf.CeilToInt(maxWidth);            }            else if (_layout == ListLayoutType.SingleRow)            {                for (i = 0; i < cnt; i++)                {                    child = GetChildAt(i);                    if (foldInvisibleItems && !child.visible)                        continue;                    if (curX != 0)                        curX += _columnGap;                    child.x = curX;                    if (_autoResizeItem)                        child.SetSize(child.width, viewHeight, true);                    curX += Mathf.CeilToInt(child.width);                    if (child.height > maxHeight)                        maxHeight = child.height;                }                cw = curX;                if (cw <= viewWidth && _autoResizeItem && scrollPane != null && scrollPane._displayInDemand && scrollPane.hzScrollBar != null)                {                    viewHeight += scrollPane.hzScrollBar.height;                    for (i = 0; i < cnt; i++)                    {                        child = GetChildAt(i);                        if (foldInvisibleItems && !child.visible)                            continue;                        child.SetSize(child.width, viewHeight, true);                        if (child.height > maxHeight)                            maxHeight = child.height;                    }                }                ch = Mathf.CeilToInt(maxHeight);            }            else if (_layout == ListLayoutType.FlowHorizontal)            {                if (_autoResizeItem && _columnCount > 0)                {                    float lineSize = 0;                    int lineStart = 0;                    float remainSize;                    float remainPercent;                    for (i = 0; i < cnt; i++)                    {                        child = GetChildAt(i);                        if (foldInvisibleItems && !child.visible)                            continue;                        lineSize += child.sourceWidth;                        j++;                        if (j == _columnCount || i == cnt - 1)                        {                            remainSize = viewWidth - (j - 1) * _columnGap;                            remainPercent = 1;                            curX = 0;                            for (j = lineStart; j <= i; j++)                            {                                child = GetChildAt(j);                                if (foldInvisibleItems && !child.visible)                                    continue;                                child.SetXY(curX, curY);                                float perc = child.sourceWidth / lineSize;                                child.SetSize(Mathf.Round(perc / remainPercent * remainSize), child.height, true);                                remainSize -= child.width;                                remainPercent -= perc;                                curX += child.width + _columnGap;                                if (child.height > maxHeight)                                    maxHeight = child.height;                            }                            //new line                            curY += Mathf.CeilToInt(maxHeight) + _lineGap;                            maxHeight = 0;                            j = 0;                            lineStart = i + 1;                            lineSize = 0;                        }                    }                    ch = curY + Mathf.CeilToInt(maxHeight);                    cw = viewWidth;                }                else                {                    for (i = 0; i < cnt; i++)                    {                        child = GetChildAt(i);                        if (foldInvisibleItems && !child.visible)                            continue;                        if (curX != 0)                            curX += _columnGap;                        if (_columnCount != 0 && j >= _columnCount                            || _columnCount == 0 && curX + child.width > viewWidth && maxHeight != 0)                        {                            //new line                            curX = 0;                            curY += Mathf.CeilToInt(maxHeight) + _lineGap;                            maxHeight = 0;                            j = 0;                        }                        child.SetXY(curX, curY);                        curX += Mathf.CeilToInt(child.width);                        if (curX > maxWidth)                            maxWidth = curX;                        if (child.height > maxHeight)                            maxHeight = child.height;                        j++;                    }                    ch = curY + Mathf.CeilToInt(maxHeight);                    cw = Mathf.CeilToInt(maxWidth);                }            }            else if (_layout == ListLayoutType.FlowVertical)            {                if (_autoResizeItem && _lineCount > 0)                {                    float lineSize = 0;                    int lineStart = 0;                    float remainSize;                    float remainPercent;                    for (i = 0; i < cnt; i++)                    {                        child = GetChildAt(i);                        if (foldInvisibleItems && !child.visible)                            continue;                        lineSize += child.sourceHeight;                        j++;                        if (j == _lineCount || i == cnt - 1)                        {                            remainSize = viewHeight - (j - 1) * _lineGap;                            remainPercent = 1;                            curY = 0;                            for (j = lineStart; j <= i; j++)                            {                                child = GetChildAt(j);                                if (foldInvisibleItems && !child.visible)                                    continue;                                child.SetXY(curX, curY);                                float perc = child.sourceHeight / lineSize;                                child.SetSize(child.width, Mathf.Round(perc / remainPercent * remainSize), true);                                remainSize -= child.height;                                remainPercent -= perc;                                curY += child.height + _lineGap;                                if (child.width > maxWidth)                                    maxWidth = child.width;                            }                            //new line                            curX += Mathf.CeilToInt(maxWidth) + _columnGap;                            maxWidth = 0;                            j = 0;                            lineStart = i + 1;                            lineSize = 0;                        }                    }                    cw = curX + Mathf.CeilToInt(maxWidth);                    ch = viewHeight;                }                else                {                    for (i = 0; i < cnt; i++)                    {                        child = GetChildAt(i);                        if (foldInvisibleItems && !child.visible)                            continue;                        if (curY != 0)                            curY += _lineGap;                        if (_lineCount != 0 && j >= _lineCount                            || _lineCount == 0 && curY + child.height > viewHeight && maxWidth != 0)                        {                            curY = 0;                            curX += Mathf.CeilToInt(maxWidth) + _columnGap;                            maxWidth = 0;                            j = 0;                        }                        child.SetXY(curX, curY);                        curY += child.height;                        if (curY > maxHeight)                            maxHeight = curY;                        if (child.width > maxWidth)                            maxWidth = child.width;                        j++;                    }                    cw = curX + Mathf.CeilToInt(maxWidth);                    ch = Mathf.CeilToInt(maxHeight);                }            }            else //pagination            {                int page = 0;                int k = 0;                float eachHeight = 0;                if (_autoResizeItem && _lineCount > 0)                    eachHeight = Mathf.Floor((viewHeight - (_lineCount - 1) * _lineGap) / _lineCount);                if (_autoResizeItem && _columnCount > 0)                {                    float lineSize = 0;                    int lineStart = 0;                    float remainSize;                    float remainPercent;                    for (i = 0; i < cnt; i++)                    {                        child = GetChildAt(i);                        if (foldInvisibleItems && !child.visible)                            continue;                        if (j == 0 && (_lineCount != 0 && k >= _lineCount                            || _lineCount == 0 && curY + (_lineCount > 0 ? eachHeight : child.height) > viewHeight))                        {                            //new page                            page++;                            curY = 0;                            k = 0;                        }                        lineSize += child.sourceWidth;                        j++;                        if (j == _columnCount || i == cnt - 1)                        {                            remainSize = viewWidth - (j - 1) * _columnGap;                            remainPercent = 1;                            curX = 0;                            for (j = lineStart; j <= i; j++)                            {                                child = GetChildAt(j);                                if (foldInvisibleItems && !child.visible)                                    continue;                                child.SetXY(page * viewWidth + curX, curY);                                float perc = child.sourceWidth / lineSize;                                child.SetSize(Mathf.Round(perc / remainPercent * remainSize), _lineCount > 0 ? eachHeight : child.height, true);                                remainSize -= child.width;                                remainPercent -= perc;                                curX += child.width + _columnGap;                                if (child.height > maxHeight)                                    maxHeight = child.height;                            }                            //new line                            curY += Mathf.CeilToInt(maxHeight) + _lineGap;                            maxHeight = 0;                            j = 0;                            lineStart = i + 1;                            lineSize = 0;                            k++;                        }                    }                }                else                {                    for (i = 0; i < cnt; i++)                    {                        child = GetChildAt(i);                        if (foldInvisibleItems && !child.visible)                            continue;                        if (curX != 0)                            curX += _columnGap;                        if (_autoResizeItem && _lineCount > 0)                            child.SetSize(child.width, eachHeight, true);                        if (_columnCount != 0 && j >= _columnCount                            || _columnCount == 0 && curX + child.width > viewWidth && maxHeight != 0)                        {                            curX = 0;                            curY += maxHeight + _lineGap;                            maxHeight = 0;                            j = 0;                            k++;                            if (_lineCount != 0 && k >= _lineCount                                || _lineCount == 0 && curY + child.height > viewHeight && maxWidth != 0)//new page                            {                                page++;                                curY = 0;                                k = 0;                            }                        }                        child.SetXY(page * viewWidth + curX, curY);                        curX += Mathf.CeilToInt(child.width);                        if (curX > maxWidth)                            maxWidth = curX;                        if (child.height > maxHeight)                            maxHeight = child.height;                        j++;                    }                }                ch = page > 0 ? viewHeight : (curY + Mathf.CeilToInt(maxHeight));                cw = (page + 1) * viewWidth;            }            HandleAlign(cw, ch);            SetBounds(0, 0, cw, ch);            InvalidateBatchingState(true);        }        override public void Setup_BeforeAdd(ByteBuffer buffer, int beginPos)        {            base.Setup_BeforeAdd(buffer, beginPos);            buffer.Seek(beginPos, 5);            _layout = (ListLayoutType)buffer.ReadByte();            selectionMode = (ListSelectionMode)buffer.ReadByte();            _align = (AlignType)buffer.ReadByte();            _verticalAlign = (VertAlignType)buffer.ReadByte();            _lineGap = buffer.ReadShort();            _columnGap = buffer.ReadShort();            _lineCount = buffer.ReadShort();            _columnCount = buffer.ReadShort();            _autoResizeItem = buffer.ReadBool();            _childrenRenderOrder = (ChildrenRenderOrder)buffer.ReadByte();            _apexIndex = buffer.ReadShort();            if (buffer.ReadBool())            {                _margin.top = buffer.ReadInt();                _margin.bottom = buffer.ReadInt();                _margin.left = buffer.ReadInt();                _margin.right = buffer.ReadInt();            }            OverflowType overflow = (OverflowType)buffer.ReadByte();            if (overflow == OverflowType.Scroll)            {                int savedPos = buffer.position;                buffer.Seek(beginPos, 7);                SetupScroll(buffer);                buffer.position = savedPos;            }            else                SetupOverflow(overflow);            if (buffer.ReadBool())            {                int i1 = buffer.ReadInt();                int i2 = buffer.ReadInt();                this.clipSoftness = new Vector2(i1, i2);            }            if (buffer.version >= 2)            {                scrollItemToViewOnClick = buffer.ReadBool();                foldInvisibleItems = buffer.ReadBool();            }            buffer.Seek(beginPos, 8);            defaultItem = buffer.ReadS();            ReadItems(buffer);        }        virtual protected void ReadItems(ByteBuffer buffer)        {            int itemCount = buffer.ReadShort();            for (int i = 0; i < itemCount; i++)            {                int nextPos = buffer.ReadShort();                nextPos += buffer.position;                string str = buffer.ReadS();                if (str == null)                {                    str = defaultItem;                    if (string.IsNullOrEmpty(str))                    {                        buffer.position = nextPos;                        continue;                    }                }                GObject obj = GetFromPool(str);                if (obj != null)                {                    AddChild(obj);                    SetupItem(buffer, obj);                }                buffer.position = nextPos;            }        }        protected void SetupItem(ByteBuffer buffer, GObject obj)        {            string str;            str = buffer.ReadS();            if (str != null)                obj.text = str;            str = buffer.ReadS();            if (str != null && (obj is GButton))                (obj as GButton).selectedTitle = str;            str = buffer.ReadS();            if (str != null)                obj.icon = str;            str = buffer.ReadS();            if (str != null && (obj is GButton))                (obj as GButton).selectedIcon = str;            str = buffer.ReadS();            if (str != null)                obj.name = str;            if (obj is GComponent)            {                int cnt = buffer.ReadShort();                for (int i = 0; i < cnt; i++)                {                    Controller cc = ((GComponent)obj).GetController(buffer.ReadS());                    str = buffer.ReadS();                    if (cc != null)                        cc.selectedPageId = str;                }                if (buffer.version >= 2)                {                    cnt = buffer.ReadShort();                    for (int i = 0; i < cnt; i++)                    {                        string target = buffer.ReadS();                        int propertyId = buffer.ReadShort();                        string value = buffer.ReadS();                        GObject obj2 = ((GComponent)obj).GetChildByPath(target);                        if (obj2 != null)                        {                            if (propertyId == 0)                                obj2.text = value;                            else if (propertyId == 1)                                obj2.icon = value;                        }                    }                }            }        }        override public void Setup_AfterAdd(ByteBuffer buffer, int beginPos)        {            base.Setup_AfterAdd(buffer, beginPos);            buffer.Seek(beginPos, 6);            int i = buffer.ReadShort();            if (i != -1)                _selectionController = parent.GetControllerAt(i);        }    }}
 |