/******************************************************************************* * * Nx UI相关方法 * * * * 2021.12.10 ******************************************************************************/ const NxObject = require( "nx.object" ); var nxGUI = cc.Class( { extends: NxObject, name: "nxGUI", // 初始化 initialize: function( _args ) { // USPER if( !this._super( _args ) ) { return false; } // 全局服务开启 nx.gui = this; return true; }, // 销毁 uninitialize: function() { // 全局服务关闭 nx.gui = null; // USPER return this._super(); }, // 子节点查找 // _names为cc.find参数格式 若_names空,则为_refnode find: function( _refnode, _names ) { if( !_refnode || !_refnode.isValid ) { return null; } if( _refnode instanceof cc.Component ) { _refnode = _refnode.node; } if( typeof _names != "string" || _names === "" ) { return _refnode; } return cc.find( _names, _refnode ); }, // 获取子节点组件 getComponent: function( _refnode, _names, _cmpName, _create = false ) { var node = this.find( _refnode, _names ); if( !node ) { return null; } let cmp = node.getComponent( _cmpName ); if( !cmp && _create ) { cmp = node.addComponent( _cmpName ); } return cmp; }, // 节点是否可见 isActive: function( _refnode, _names ) { var node = this.find( _refnode, _names ); return node ? node.active : false; }, // 节点有效 setActive: function( _refnode, _names, _active ) { var node = this.find( _refnode, _names ); if( node ) { node.active = !!_active; } return node; }, // 节点透明度 setOpacity: function( _refnode, _names, _opacity ) { var node = this.find( _refnode, _names ); if( node ) { node.opacity = _opacity; } return node; }, // 设置是否有效 setEnable: function( _refnode, _name, _enable ) { // 按钮 var btn = this.getComponent( _refnode, _name, cc.Button ); if( btn ) { btn.enabled = _enable; return btn.node; } return null; }, // 位置设定 setPosition: function( _refnode, _names, _pos ) { const node = this.find( _refnode, _names ); if( node ) { node.setPosition( _pos ); } return node; }, // 是否屏幕内可见 // _ofs[上,下,左,右] isInFrameView: function( _refnode, _names, _ofs ) { const node = this.find( _refnode, _names ); if( !node ) { return false; } _ofs = _ofs || [ 0, 0, 0, 0 ]; var range = cc.view.getVisibleSize(); var pos = node.convertToWorldSpaceAR( cc.Vec2.ZERO ); var top = pos.y - node.height / 2; var bottom = pos.y + node.height / 2; var left = pos.x + node.width / 2; var right = pos.x - node.height / 2; return top <= ( range.height - _ofs[ 0 ] ) && bottom >= _ofs[ 1 ] && left >= _ofs[ 2 ] && right <= ( range.width - _ofs[ 3 ] ); }, // 设置文本 setString: function( _refnode, _names, _text ) { var cmp = this.getComponent( _refnode, _names, cc.Label ); if( !cmp ) { cmp = this.getComponent( _refnode, _names, cc.RichText ); if( !cmp ) { cmp = this.getComponent( _refnode, _names, cc.EditBox ); } } if( cmp ) { _text += ""; cmp.string = _text || ""; } return cmp; }, // 设置富文本 setStringRich: function( _refnode, _names, _text ) { var cmp = this.getComponent( _refnode, _names, cc.RichText ); if( cmp ) { _text += ""; cmp.string = _text == null ? "" : _text; } return cmp; }, // 设置颜色 setColor: function( _refnode, _names, _color ) { const node = this.find( _refnode, _names ); if( node ) { node.color = _color; } return node; }, // 设置样式 setCSS: function( _refnode, _names, _cssKey ) { let cmp = this.getComponent( _refnode, _names, "nx.vb.theme" ); if( cmp ) { cmp.setCSS( _cssKey ); } return cmp; }, // 设置描边色 setOutlineColor: function( _refnode, _names, _color ) { const cmp = this.getComponent( _refnode, _names, cc.LabelOutline ); if( cmp ) { cmp.color = _color; } return cmp; }, // 精灵褪色 fadeSpriteColor: function( _refnode, _names, _isfade ) { const cmp = this.getComponent( _refnode, _names, cc.Sprite ); if( !cmp ) { return null; } cmp.setState( _isfade ? 1 : 0 ); return cmp; }, // 节点全色设置 setColorDeep: function( _refnode, _names, _color ) { var _setclr = function( _nd, _color ) { if( !_nd ) { return; } _nd.color = _color; var children = _nd.children; for( var i = 0; i < children.length; ++i ) { _setclr( children[ i ], _color ); } }; var node = this.find( _refnode, _names ); if( node ) { _setclr( node, _color ); } }, // 设置WEB图片 setWebImage: function( _refnode, _names, _url, _ext = ".jpg" ) { const cmp = this.getComponent( _refnode, _names, cc.Sprite ); if( !cmp ) { return null; } cc.loader.load( _url, ( _err, _tex ) => { if( _err ) { nx.warn( "[远程]loadRemote加载失败:", _err.errorMessage || _err ); return; } nx.dt.trycatch( () => { if( cmp ) { cmp.spriteFrame = new cc.SpriteFrame( _tex, new cc.Rect( 0, 0, _tex.width, _tex.height ), false, cc.Vec2.ZERO, new cc.Size( _tex.width, _tex.height ) ); } } ); } ); return cmp; }, // 设置精灵 setSpriteFrame: function( _refnode, _names, _sfkey, _cb = nx.dt.fnEmpty ) { const sprite = this.getComponent( _refnode, _names, "nx.fx.sprite", true ); if( !sprite ) { nx.warn( "[GUI]设置精灵失败,不是有效组件:%s", _names ); return null; } sprite.setSpriteFrame( _sfkey, _cb ); return this.getComponent( sprite, "", cc.Sprite ); }, // 设置合图精灵 setAtlasFrame: function( _refnode, _names, _sfkey, _opacity = false ) { const cmp = this.getComponent( _refnode, _names, cc.Sprite ); if( !cmp ) { return null; } // 直接设置返回 if( typeof _sfkey != "string" ) { cmp.spriteFrame = _sfkey; return cmp; } // 频繁设置 if( cmp.loading ) { nx.warn( "[GUI]设置合图频繁:" ); nx.warn( "\t\t进行中:", nx.dt.enjson( cmp.loading ) ); nx.warn( "\t\t顶替为:", nx.dt.enjson( { names: _names, rkey: _sfkey } ) ); cmp.loading = null; } // 记录 cmp.loading = { names: _names, rkey: _sfkey, }; if( _opacity ) { cmp.node.opacity = op; } nx.res.loadAtlasFrame( _sfkey, function( _error, _sframe ) { // 记录还原 cmp.loading = null; if( _opacity ) { cmp.node.opacity = op; } cmp.spriteFrame = _sframe; } ); return cmp; }, // 设置子图 setLocAtlas: function( _refnode, _names, _key ) { const cmp = this.getComponent( _refnode, _names, "xLocalAtlas" ); if( !cmp ) { nx.warn( "子图设定失败,错误的组件:" + _key ); return null; } cmp.set( _key ); return cmp; }, // 设置本地文本 setLocText: function( _refnode, _names, _key ) { const cmp = this.getComponent( _refnode, _names, "xLocalText" ); if( !cmp ) { nx.warn( "文本设定失败,错误的组件:" + _key ); return null; } cmp.set( _key ); return cmp; }, // 按钮锁&解锁 setLocked: function( _refnode, _names, _locked ) { var cmp = this.getComponent( _refnode, _names, "nx.fx.button" ); if( !cmp ) { cmp = this.getComponent( _refnode, _names, "nx.fx.button.wnd" ); if( !cmp ) { nx.warn( "按钮锁&解锁,错误的组件:" + _locked ); return null; } } cmp.lock( !!_locked ); return cmp; }, setCdTxt: function( _node, _names, _sec, _endCall ) { let cmp = nx.gui.getComponent( _node, _names, "nx.fx.cd", true ); if( !cmp ) { nx.warn( "计时组件不存在:" + _names ); return; } cmp.setSecs( _sec, _endCall ); return cmp; }, // 子节点全隐藏 hideAllChildren: function( _refnode, _names ) { const parent = this.find( _refnode, _names ); if( parent ) { for( let i = 0; i < parent.childrenCount; i++ ) { this.setActive( parent.children[ i ], null, false ); } } return parent; }, // 清空子节点 cleanAllChildren: function( _refnode, _names ) { const parent = this.find( _refnode, _names ); if( parent ) { let chd = parent.children; if( chd.length > 0 ){ for(let i = 0; i < chd.length; i++ ){ if( chd[i] ){ chd[i].destroy(); } } } } return parent; }, // 子节点批量补全 gocChildren: function( _refnode, _names, _count, _prefab, _justHide = true ) { const parent = this.find( _refnode, _names ); if( !parent ) { nx.error( "子节点补全失败,无效父节点!" ); return; } // 需要补全 if( _count >= parent.childrenCount ) { _prefab = _prefab || parent.children[ 0 ]; if( !_prefab ) { nx.error( "子节点补全失败,无效模板!" ); return; } // 实例化缺少数量的节点 const cloneCount = _count - parent.childrenCount; for( let i = 0; i < cloneCount; i++ ) { parent.addChild( cc.instantiate( _prefab ) ); } if( _justHide ) { parent.children.forEach( _node => { if( !_node.active ) { _node.active = true; } } ); } return; } // 统计多余的个数 if( _justHide ) { for( let i in parent.children ) { let node = parent.children[ i ]; node.active = ( i < _count ); } } else { const nodes = []; const count = parent.childrenCount - _count; for( let i = 1; i <= count; ++i ) { let idx = parent.children.length - i; nodes.push( parent.children[ idx ] ); } nodes.forEach( _nd => { _nd.removeFromParent( true ); } ); } }, // 执行某方法 doSth: function( _refnode, _names, _func, _data ) { const node = this.find( _refnode, _names ); if( node && nx.dt.fnGood( _func ) ) { _func( node, _data ); } return node; }, // 对齐方式 // Key: center, lt, ld, rt, rd setAligment: function( _refnod, _names, _key, _p1 = 0, _p2 = 0 ) { let widget = nx.gui.getComponent( _refnod, _names, cc.Widget ); if( !widget ) { nx.error( "[GUI]对齐失败,找不到Widget组件!" ); return; } switch( _key ) { case "lt": { widget.isAlignLeft = true; widget.isAlignTop = true; widget.isAlignBottom = false; widget.isAlignRight = false; widget.left = _p1 || 0; widget.top = _p2 || 0; } break; case "ld": { widget.isAlignLeft = true; widget.isAlignTop = false; widget.isAlignBottom = true; widget.isAlignRight = false; widget.left = _p1 || 0; widget.bottom = _p2 || 0; } break; case "rt": { widget.isAlignLeft = false; widget.isAlignTop = true; widget.isAlignBottom = false; widget.isAlignRight = true; widget.right = _p1 || 0; widget.top = _p2 || 0; } break; case "rd": { widget.isAlignLeft = false; widget.isAlignTop = false; widget.isAlignBottom = true; widget.isAlignRight = true; widget.right = _p1 || 0; widget.bottom = _p2 || 0; } break; default: { widget.isAlignVerticalCenter = true; widget.isAlignHorizontalCenter = true; widget.horizontalCenter = _p1 || 0; widget.verticalCenter = _p2 || 0; } break; } widget.updateAlignment(); return widget; }, // 按钮无效化 // 背景褪色,子节点调整透明度 btnFadeColorAndAlphaChildren: function( _refnode, _names, _isfade ) { var nd = this.find( _refnode, _names ); nd.color = _isfade ? cc.Color.GRAY : cc.Color.WHITE; // 子节点调整透明度 var children = nd.children; for( var i = 0; i < children.length; ++i ) { if( children[ i ].name !== "bg" ) { children[ i ].opacity = _isfade ? 100 : 255; } } }, // 按钮锁定(用于QA模式,避免重复触发) lockButton: function( _refnode, _names, _uifunc ) { const cmp = this.getComponent( _refnode, _names, "xButton" ); if( cmp ) { cmp.setInteract( false, _uifunc || this.btnFadeColorAndAlphaChildren.bind( this ) ); } return cmp; }, // 按钮解锁(用于QA模式,避免重复触发) unlockButton: function( _refnode, _names, _uifunc ) { const cmp = this.getComponent( _refnode, _names, "xButton" ); if( cmp ) { cmp.setInteract( true, _uifunc || this.btnFadeColorAndAlphaChildren.bind( this ) ); } return cmp; }, // 视图绑定-文本 vbindText: function( _refnode, _names, _target, _key, _fmt ) { const cmp = this.getComponent( _refnode, _names, "nx.vb.text" ); if( cmp ) { cmp.setTarget( _target, _key, _fmt ); } return cmp; }, // 视图绑定-富文本 vbindRichText: function( _refnode, _names, _target, _key, _fmt ) { const cmp = this.getComponent( _refnode, _names, "nx.vb.richText" ); if( cmp ) { cmp.setTarget( _target, _key, _fmt ); } return cmp; }, // 视图绑定-图片 vbindImage: function( _refnode, _names, _target, _key ) { const cmp = this.getComponent( _refnode, _names, "nx.vb.sprite" ); if( cmp ) { cmp.setTarget( _target, _key ); } return cmp; }, // 视图绑定-进度条 vbindProgress: function( _refnode, _names, _target, _key1, _key2 ) { const cmp = this.getComponent( _refnode, _names, "nx.vb.progress" ); if( cmp ) { cmp.setTarget( _target, _key1, _key2 ); } return cmp; }, // 视图绑定-显示控制 vbindVisible: function( _refnode, _names, _target, _key ) { const cmp = this.getComponent( _refnode, _names, "nx.vb.visible" ); if( cmp ) { cmp.setTarget( _target, _key ); } return cmp; }, // 设置合图精灵 setAtlasFrame: function( _refnode, _names, _sfkey ) { const cmp = this.getComponent( _refnode, _names, cc.Sprite ); if( !cmp ) { return null; } if( typeof _sfkey == "string" ) { nx.res.loadAtlasFrame( _sfkey, function( _error, _sframe ) { cmp.spriteFrame = _sframe; } ); } else { cmp.spriteFrame = _sfkey; } return cmp; }, // 设置帧动画 setFrameAnimation: function( _refnode, _names, _rkey, _cb, _loop = true, _speed = 0 ) { let cmp = this.getComponent( _refnode, _names, "nx.fx.animFrames", true ); if( !cmp ) { nx.error( "[GUI]找不到帧动画播放组件!" ); return null; } // 播放 cmp.isLoop = _loop; if( _speed > 0 ) { cmp.speed = _speed; } cmp.load2Play( _rkey, _cb ); return cmp; }, // 播放DragonBones骨骼动画 playDragonDones: function( _refnode, _names, _rkey, _action, _cb, _loop = true ) { let cmp = this.getComponent( _refnode, _names, "nx.fx.dragonBones", true ); if( !cmp ) { nx.error( "[GUI]找不到DragonBones组件!" ); return null; } // 播放 cmp.play( _rkey, _action, _cb, _loop ); return cmp; }, // 播放Spine骨骼动画 playSpine: function( _refnode, _names, _rkey, _action, _cb, _loop = true ) { let cmp = this.getComponent( _refnode, _names, "nx.fx.spine", true ); if( !cmp ) { nx.error( "[GUI]找不到Spine组件!" ); return null; } // 播放 cmp.play( _rkey, _action, _cb, _loop ); return cmp; }, } ); // 模块导出 module.exports = nxGUI;