import { Debug } from "../Common/Debug" ; import { Item } from "./Item" ; const { ccclass , property } = cc . _decorator ; @ ccclass export abstract class ItemList < T > extends cc . Component { @ property refreshTime : number = 0 ; @ property ( cc . Node ) contentParent : cc . Node = null ; _itemList : Item < T > [ ] = new Array ( ) ; _idleItemCache : Item < T > [ ] = new Array ( ) ; _selectedSlot : number = 0 ; _isDestroyItemOnDisable : boolean = false ; update ( dt ) { if ( this . refreshTime < this . dataUpdateTime ( ) ) { this . refreshTime = this . dataUpdateTime ( ) ; this . refreshContent ( ) ; } this . onUpdate ( dt ) ; } onDisable ( ) { if ( this . _isDestroyItemOnDisable == false ) { return ; } for ( let i = 0 ; i < this . _itemList . length ; i ++ ) { if ( this . _itemList [ i ] . node != null ) { this . _itemList [ i ] . node . destroy ( ) ; } } this . _itemList = [ ] ; for ( let i = 0 ; i < this . _idleItemCache . length ; i ++ ) { if ( this . _idleItemCache [ i ] . node != null ) { this . _idleItemCache [ i ] . node . destroy ( ) ; } } this . _idleItemCache = [ ] ; this . refreshTime = 0 ; } setRefreshTime ( time ) { this . refreshTime = time ; } refreshContent ( ) { this . beforeRefresh ( ) ; let slotCount = this . slotCount ( ) ; let dataCount = this . dataCount ( ) ; if ( slotCount < dataCount ) { slotCount = dataCount ; } if ( this . _itemList . length > slotCount ) { for ( let i = 0 , n = this . _itemList . length - slotCount ; i < n && this . _itemList . length > 0 ; i ++ ) { let item = this . _itemList [ this . _itemList . length - 1 ] ; this . _itemList . splice ( this . _itemList . length - 1 , 1 ) ; item . reset ( 0 ) ; this . setItemIdle ( item ) ; } } for ( let i = 0 ; i < slotCount ; i ++ ) { let item = null ; if ( i < this . _itemList . length ) { item = this . _itemList [ i ] ; } else { item = this . getMyItem ( ) ; if ( item != null ) { if ( item . node . parent !== this . contentParent ) { this . contentParent . addChild ( item . node ) ; } this . _itemList . push ( item ) ; } } if ( i < dataCount ) { let data = this . getData ( i ) ; if ( item != null ) { item . bindData ( i , data ) ; item . node . setSiblingIndex ( i ) ; } } else { if ( item != null ) { item . reset ( i ) ; } } } for ( let i = 0 ; i < this . _itemList . length ; i ++ ) { let item = this . _itemList [ i ] ; let selected = i == this . _selectedSlot ; item . select ( selected ) ; if ( selected ) { this . onItemSelected ( item ) ; } } this . afterRefresh ( ) ; } getItem ( index ) { if ( index < 0 || index >= this . _itemList . length ) { return null ; } return this . _itemList [ index ] ; } getItemCount ( ) { return this . _itemList . length ; } getMyItem ( ) { if ( this . _idleItemCache . length > 0 ) { let item = this . _idleItemCache . shift ( ) ; if ( item && ! item . node . activeInHierarchy ) { item . node . active = true ; } return item ; } else { let item = this . createItem ( ) ; if ( item != null ) { let btn = item . getClickButton ( ) ; if ( btn != null ) { let self = this ; btn . node . on ( 'click' , function ( event ) { self . select ( item ) ; } ) ; } } return item ; } } setItemIdle ( item ) { if ( item == null ) { return ; } ; if ( item . node . activeInHierarchy ) { item . node . active = false ; } this . _idleItemCache . push ( item ) ; } select ( item ) { this . _selectedSlot = this . _itemList . indexOf ( item ) ; this . refreshSelectState ( ) ; this . onItemSelected ( item ) ; } selectEmpty ( ) { this . _selectedSlot = - 1 ; } DestroyItemOnDisable ( ) { this . _isDestroyItemOnDisable = true ; } setSelectSlot ( slot ) { if ( slot < 0 || slot >= this . _itemList . length ) { return ; } this . _selectedSlot = slot ; } refreshSelectState ( ) { for ( let i = 0 ; i < this . _itemList . length ; i ++ ) { this . _itemList [ i ] . select ( i === this . _selectedSlot ) ; } } beforeRefresh ( ) { } afterRefresh ( ) { } onUpdate ( dt ) { } abstract slotCount ( ) ; abstract createItem ( ) ; abstract dataUpdateTime ( ) ; abstract dataCount ( ) ; abstract getData ( index ) ; abstract onItemSelected ( item ) ; }