| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- import { Button, Canvas, Component, EventHandler, EventTouch, Node, SpriteFrame, _decorator, warn } from "cc";
- // import GlobalDC from "../common/data.global.center";
- const { ccclass, property } = _decorator;
- @ccclass
- export class UI extends Component {
- /** 获取节点深度 */
- public static getDepth(node: Node) {
- let d: number;
- if (node.getComponent(Canvas)) d = 0;
- else d = this.getDepth(node.parent) + 1;
- return d;
- }
- /** 节点层级深度 */
- protected get depth() {
- return UI.getDepth(this.node);
- }
- /** 组件名称 */
- get comp_name() {
- let reg = new RegExp('(?<=<)(?<comp_name>[\\w, \\W]+)(?=>)', 'g');
- return reg.exec(this.name).groups.comp_name;
- }
- /** 给按钮绑定点击事件 */
- private __ButtonBindCall() {
- this.__handle = mtec.cc.creatEventHandle({
- target: this.node,
- component: this.comp_name,
- handler: '__ClickButton',
- });
- this.node.getComponentsInChildren(Button)
- .filter(btn => {
- let pass = false;
- // 如果btn的事件列表是空的,则直接无脑把自己的中继事件放进去
- if (btn.clickEvents.length === 0) pass = true;
- else {
- // 分别收集手动绑定事件和自动绑定事件
- let [hand_event, auto_event] = [[], []] as EventHandler[][];
- btn.clickEvents.forEach(hdl => {
- if (hdl.handler === '__ClickButton') auto_event.push(hdl);
- else hand_event.push(hdl);
- });
- // 如果脚本中初始化了按钮事件,并且按钮事件列表中没有其它初始化事件,则直接添加
- if (auto_event.length === 0 && this._click_event_[btn.node.name]) pass = true;
- // 如果存在其它初始化事件,则以组件的深度优先(即距离按钮最近的组件为准)覆盖,相同深度则以当前为准覆盖
- else if (auto_event.length > 0) {
- let power = this.depth;
- if (this._click_event_[btn.node.name]) power += 10000;
- let el = auto_event.map(h => {
- let comp = h.target.getComponent(UI);
- let p = comp.depth;
- if (comp._click_event_[btn.node.name]) p += 10000;
- return { h, p };
- }).sort((a, b) => a.p - b.p).pop();
- if (el.p <= power) pass = true;
- else auto_event.splice(auto_event.indexOf(el.h), 1);
- auto_event.forEach(h => btn.clickEvents.splice(btn.clickEvents.indexOf(h), 1));
- }
- }
- return pass;
- }).forEach(btn => {
- btn.clickEvents.push(this.__handle);
- this.__btn_map__.set(btn.node.name, btn);
- });
- }
- /** 按钮点击事件中继 */
- protected __ClickButton(event: EventTouch) {
- let node = event.currentTarget as Node;
- let btn = node.getComponent(Button);
- let call = Reflect.get(this._click_event_, node.name);
- if (node.name in this._click_event_) {
- Reflect.apply(call, this, [btn]);
- // 发送点击事件,只对初始化的按钮发送事件
- // GlobalDC.Trigger.CLICK = {
- // component: this.comp_name,
- // button: node.name
- // };
- } else this.ClickBtn(btn);
- }
- /** 没有被初始化的按钮 */
- protected ClickBtn(btn: Button) {
- btn.interactable
- warn(`<${this.comp_name}> 按钮[${btn.node.name}]未被初始化`);
- }
- /** ui交互控制 */
- protected interactable(able: boolean) {
- this.__btn_map__.forEach(btn => btn.interactable = able);
- }
- /** 初始化组件基本逻辑 */
- private __init() {
- if (!this._click_event_.__common) this._click_event_.__common = (() => { }).bind(this);
- this.__ButtonBindCall();
- if (this.sframe.length > 0) {
- this.sframe.forEach(frame => this.smap.set(frame.name, frame));
- this.sframe = undefined;
- }
- if (this.initAfterOnLoad) this.initAfterOnLoad();
- }
- /** 组件事件对象 */
- protected _click_event_: { [name: string]: (this: UI, button: Button) => void } = {};
- /** 组件上的按钮通用回调 */
- protected __handle: EventHandler = null;
- protected __btn_map__: Map<string, Button> = new Map();
- /** ui常用贴图映射 */
- protected smap: Map<string, SpriteFrame> = new Map();
- /** 在加载后的一些自定义初始化 */
- protected initAfterOnLoad(): void {
- };
- @property([SpriteFrame])
- /** ui常用贴图 */
- private sframe: SpriteFrame[] = [];
- protected onLoad() {
- this.__init();
- }
- }
|