| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282 |
- import { _decorator, Component, Prefab, Node, instantiate, Vec3, UITransform } from 'cc';
- import { ViewItemPro } from './ViewItemPro';
- import { SplitInfo } from '../ExClass';
- const { ccclass, property,menu } = _decorator;
- @ccclass('Generate')
- @menu("新组件/Generate")
- export class Generate extends Component {
- @property(Prefab)
- public pre_item: Prefab | Node = null;
- @property({ tooltip: "第一帧加载个数" })
- public first_add_num = 1;
- @property({ tooltip: "每帧加载个个数" })
- public every_frame_add = 1;
- @property({ tooltip: "每行最多个数" })
- public horizontal_num = 1;
- @property({ tooltip: "是否需要计算子节点位置" })
- public auto_align_child = true;
- @property({ tooltip: "1 高度=item行数*高度\n2:1的基础上宽度=列数*宽度" })
- public change_size_mode = 1;
- @property({ tooltip: "item是否上有脚本" })
- public item_have_script = true;
- @property({ tooltip: "从左往右排" })
- public left_to_right = true;
- @property
- public split_child = false;
- private uitrans = null;
- private m_data: any = null;
- private item_list: Array<any> = [];
- private state: number = 0;
- private have_init = false;
- private first_node: Node = null;
- private need_refresh = false;
- private p: any = null;
- private item_width: number = 0;
- private item_height: number = 0;
- private offset_x: number = 0;
- private offset_y: number = 0;
- private offsets: Array<any> = [];
- private split_infos: Array<SplitInfo> = [];
- private size_override: Array<number> = null;
- protected onLoad() {
- this.uitrans = this.node.getComponent(UITransform);
- this.first_node = null;
- if(!this.pre_item && this.node.children.length > 0){
- this.split_child = false;
- this.pre_item = this.node.children[0];
- if(this.item_have_script){
- this.item_list.push(this.pre_item.getComponent(ViewItemPro));
- }
- else{
- this.item_list.push(this.pre_item.components[0]);
- }
- }
- }
- protected onEnable(): void {
- if(this.need_refresh)this.initData(this.m_data, this.p);
- }
- public setOverrideSize(size:any){
- this.size_override = size;
- this.have_init = false;
- }
- public setPrefab(pre: Prefab) {
- this.pre_item = pre;
- this.first_node = instantiate(pre);
- }
- public initData(data: any, p: any = null) {
- this.m_data = data;
- this.p = p;
- this.need_refresh = !this.enabled;
- if(!this.enabled)return;
- this.initParams();
- this.updateSize();
- if (!data || data.length == 0) {
- this.item_list.forEach((element, index) => {
- element.node.active = false;
- if(this.split_child)this.split_infos[index].setActive(false);
- });
- return;
- }
- if (this.change_size_mode > 0 && this.auto_align_child) {
- this.updateItemsPos();
- }
- let items_len = this.item_list.length;
- let need_add = data.length - items_len;
- if (need_add > 0) {
- let need_add = data.length - items_len;
- need_add = Math.min(need_add, this.first_add_num);
- this.addItems(items_len, items_len + need_add);
- this.updateItems(0, items_len + need_add);
- this.state = 1;
- return;
- }
- else if(need_add < 0){
- for (let i = items_len + need_add; i < items_len; i++){
- this.item_list[i].node.active = false;
- if(this.split_child)this.split_infos[i].setActive(false);
- }
- }
- this.updateItems(0, this.m_data.length);
- }
- private initParams() {
- if (!this.have_init) {
- let node = null;
- if(this.first_node){
- node = this.first_node;
- }
- else{
- if(Node.isNode(this.pre_item)){
- node = this.node.children[0];
- }
- else{
- node = instantiate(this.pre_item);
- }
- this.first_node = node;
- if (this.split_child) {
- this.offsets = SplitInfo.getOffsetByNode(node);
- }
- }
- let trans = node.getComponent(UITransform);
- if(this.size_override){
- this.item_width = this.size_override[0];
- this.item_height = this.size_override[1];
- }
- else{
- this.item_width = trans.width;
- this.item_height = trans.height;
- }
- if(this.left_to_right)this.offset_x = trans.anchorX * this.item_width;
- else this.offset_x = (trans.anchorX - 1) * this.item_width;
- this.offset_y = (1 - trans.anchorY) * this.item_height;
- this.have_init = true;
- }
- }
- private updateSize() {
- let len = 0;
- if(this.m_data)len = this.m_data.length;
- let row = Math.ceil(len / this.horizontal_num);
- if (this.change_size_mode == 2) {
- let col = len > this.horizontal_num ? this.horizontal_num : len;
- this.uitrans.setContentSize(col * this.item_width, row * this.item_height);
- }
- else if (this.change_size_mode == 1) {
- this.uitrans.height = row * this.item_height;
- }
- }
- private addItems(begin: number, end: number) {
- let begin_x = this.left_to_right ? this._getLeftBoundary() : this._getRightBoundary();
- let begin_y = this._getTopBoundary();
- let row = 0, col = 0;
- for (let i = begin; i < end; i++) {
- let node = i == 0 ? this.first_node : instantiate(this.pre_item) as Node;
- if(this.item_have_script)this.item_list.push(node.getComponent(ViewItemPro));
- else this.item_list.push(node.components[0]);
- node.setParent(this.node);
- let flag = this.left_to_right ? 1 : -1;
- let x = 0 , y = 0;
- if (this.auto_align_child) {
- row = Math.floor(i / this.horizontal_num);
- col = i % this.horizontal_num;
- x = begin_x + flag * col * this.item_width + this.offset_x;
- y = begin_y - row * this.item_height - this.offset_y;
- node.toXY(x, y);
- }
- }
- if (this.split_child) {
- let com_node = null;
- let info = null;
- for (let i = begin; i < end; i++) {
- com_node = this.item_list[i].node;
- info = new SplitInfo(com_node);
- this.split_infos.push(info);
- com_node.setSiblingIndex(i);
- info.setSlisByIndex(i);
- info.moveByOffset(this.offsets);
- }
- //console.log(this.node.children)
- }
- }
- private updateItemsPos() {
- if (this.item_list.length == 0) return;
- let begin_x = this.left_to_right ? this._getLeftBoundary() : this._getRightBoundary();
- let begin_y = this._getTopBoundary();
- let row = 0, col = 0;
- let x = 0 , y = 0;
- let flag = this.left_to_right ? 1 : -1;
- for (let i = 0, len = this.item_list.length; i < len; i++) {
- let node = this.item_list[i].node;
- row = Math.floor(i / this.horizontal_num);
- col = i % this.horizontal_num;
- x = begin_x + flag * col * this.item_width + this.offset_x;
- y = begin_y - row * this.item_height - this.offset_y;
- node.toXY(x, y);
- if(this.split_child){
- this.split_infos[i].moveByOffset(this.offsets);
- }
- }
- }
- private updateItems(begin: number, end: number) {
- for (let i = begin; i < end; i++) {
- this.item_list[i].node.active = true;
- if(this.split_child)this.split_infos[i].setActive(true);
- if(this.item_have_script){
- this.item_list[i].reset();
- this.item_list[i].init(this.m_data[i], i, this.p);
- }
- else{
- this.p(this.item_list[i].node, i);
- }
- }
- }
- private _getLeftBoundary() {
- return -this.uitrans.anchorX * this.uitrans.width;
- }
- private _getBottomBoundary() {
- return -this.uitrans.anchorY * this.uitrans.height;
- }
- private _getRightBoundary() {
- return (1 - this.uitrans.anchorX) * this.uitrans.width;
- }
- private _getTopBoundary() {
- return (1 - this.uitrans.anchorY) * this.uitrans.height;
- }
- public getValidCount(){
- return this.m_data.length;
- }
- public getItems() {
- return this.item_list;
- }
- public removeAllItems() {
- if(!this.isValid)return;
- for(let i = 0 ; i < this.item_list.length ; i++){
- this.node.removeChild(this.item_list[i].node);
- }
- this.have_init = false;
- this.item_list.length = 0;
- this.first_node = null;
- }
- public getItemById(index: number) {
- return this.item_list[index];
- }
- public getPosById(index:number){
- let begin_x = this.left_to_right ? this._getLeftBoundary() : this._getRightBoundary();
- let begin_y = this._getTopBoundary();
- let row = Math.floor(index / this.horizontal_num);
- let col = index % this.horizontal_num;
- let flag = this.left_to_right ? 1 : -1;
- let x = begin_x + flag * col * this.item_width + this.offset_x;
- let y = begin_y - row * this.item_height - this.offset_y;
- return [x, y];
- }
- protected update(dt: number) {
- if (this.state == 0) return;
- if (this.item_list.length >= this.m_data.length) {
- this.state = 0;
- //console.log(this.node.children)
- this.node.emit("load_end");
- } else {
- let add = Math.min(this.every_frame_add, this.m_data.length - this.item_list.length);
- let items_len = this.item_list.length;
- this.addItems(items_len, items_len + add);
- this.updateItems(items_len, items_len + add);
- }
- }
- }
|