UIMgr.ts 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. import { UIController } from './UIController';
  2. import { ModuleContext } from '../Base/ModuleContext';
  3. const { ccclass, property } = cc._decorator;
  4. class UIUpdater extends cc.Component {
  5. update() {
  6. UIController.updateAll();
  7. }
  8. }
  9. /**
  10. * @en the `User Interface Manager`, handles some stuffs like the ui loads,ui layers,resizing etc.
  11. * @zh UI管理器,处理UI加载,层级,窗口变化等
  12. *
  13. * */
  14. export class UIMgr {
  15. private static _inst: UIMgr;
  16. public static get inst(): UIMgr {
  17. if (this._inst == null) {
  18. this._inst = new UIMgr();
  19. }
  20. return this._inst;
  21. }
  22. private _uiCanvas: cc.Node;
  23. private _uiRoot: cc.Node;
  24. private createFullScreenNode() {
  25. let canvas = this._uiCanvas;
  26. let node = new cc.Node();
  27. node.group = this._uiCanvas.group;
  28. node.width = canvas.width;
  29. node.height = canvas.height;
  30. let widget = node.addComponent(cc.Widget);
  31. widget.isAlignBottom = true;
  32. widget.isAlignTop = true;
  33. widget.isAlignLeft = true;
  34. widget.isAlignRight = true;
  35. widget.left = 0;
  36. widget.right = 0;
  37. widget.top = 0;
  38. widget.bottom = 0;
  39. return node;
  40. }
  41. /**
  42. * @en setup this UIMgr,`don't call more than once`.
  43. * @zh 初始化UIMgr,`不要多次调用`
  44. * */
  45. public setup(uiCanvas: cc.Node | cc.Prefab, maxLayers: number, layerNames?: Array<string>) {
  46. if (this._uiCanvas) {
  47. return;
  48. }
  49. if (!uiCanvas) {
  50. cc.error('uiCanvas must be a cc.Node or cc.Prefab');
  51. return;
  52. }
  53. if (uiCanvas instanceof cc.Node) {
  54. this._uiCanvas = uiCanvas;
  55. }
  56. else {
  57. this._uiCanvas = cc.instantiate(uiCanvas);
  58. cc.director.getScene().addChild(this._uiCanvas);
  59. }
  60. this._uiCanvas.name = '$tgxUICanvas$';
  61. cc.game.addPersistRootNode(this._uiCanvas);
  62. if (!this._uiCanvas.getComponent(UIUpdater)) {
  63. this._uiCanvas.addComponent(UIUpdater);
  64. }
  65. layerNames ||= [];
  66. this._uiRoot = this.createFullScreenNode();
  67. this._uiRoot.name = 'ui_root'
  68. this._uiCanvas.addChild(this._uiRoot);
  69. //create layers
  70. for (let i = 0; i < maxLayers; ++i) {
  71. let layerNode = this.createFullScreenNode();
  72. layerNode.name = 'ui_layer_' + (layerNames[i] ? layerNames[i] : i);
  73. this._uiRoot.addChild(layerNode);
  74. }
  75. }
  76. public getLayerNode(layerIndex: number): cc.Node {
  77. return this._uiRoot.children[layerIndex] || this._uiRoot;
  78. }
  79. public hideAll() {
  80. UIController.hideAll();
  81. }
  82. public getUI<T extends UIController>(uiCls): T {
  83. let allControllers = (UIController as any)._controllers;
  84. for (let i = 0; i < allControllers.length; ++i) {
  85. let c = allControllers[i];
  86. if (c instanceof uiCls) {
  87. return c;
  88. }
  89. }
  90. return null;
  91. }
  92. public isShowing(uiCls: any): boolean {
  93. let allControllers = (UIController as any)._controllers;
  94. for (let i = 0; i < allControllers.length; ++i) {
  95. if (allControllers[i] instanceof uiCls) {
  96. return true;
  97. }
  98. }
  99. return false;
  100. }
  101. /***
  102. * @en show ui by the given parameters.
  103. * @zh 显示UI
  104. * @param uiCls the class, must inherits from the class `UIController`.
  105. * @param cb will be called after ui created.
  106. * @param thisArg the this argument for param `cb`.
  107. * @returns the instance of `uiCls`
  108. * */
  109. public showUI(uiCls: any, cb?: Function, thisArg?: any): any {
  110. let bundleName = ModuleContext.getClassModule(uiCls);
  111. if (bundleName) {
  112. let bundle = cc.assetManager.getBundle(bundleName);
  113. if (!bundle) {
  114. cc.assetManager.loadBundle(bundleName, null, (err, loadedBundle) => {
  115. if (err) {
  116. console.log(err);
  117. }
  118. else {
  119. this.showUI(uiCls, cb, thisArg);
  120. }
  121. });
  122. return;
  123. }
  124. }
  125. let ui = ModuleContext.createFromModule(uiCls) as UIController;
  126. let resArr = ui.getRes() || [];
  127. if (typeof (ui.prefab) == 'string') {
  128. resArr.push(ui.prefab as never);
  129. }
  130. let fnLoadAndCreateFromBundle = (bundle: cc.AssetManager.Bundle) => {
  131. bundle.load(resArr, (err, data) => {
  132. if (err) {
  133. console.log(err);
  134. }
  135. let node: cc.Node = null;
  136. let prefab: cc.Prefab = ui.prefab as cc.Prefab;
  137. if (typeof (ui.prefab) == 'string') {
  138. prefab = bundle.get(ui.prefab) as cc.Prefab;
  139. }
  140. if (prefab) {
  141. node = cc.instantiate(prefab);
  142. }
  143. else {
  144. //special for empty ui
  145. node = this.createFullScreenNode();
  146. }
  147. let parent = UIMgr.inst.getLayerNode(ui.layer);
  148. parent.addChild(node);
  149. ui.setup(node);
  150. if (cb) {
  151. cb.apply(thisArg, [ui]);
  152. }
  153. });
  154. return ui;
  155. }
  156. bundleName = bundleName || 'resources';
  157. let bundle = cc.assetManager.getBundle(bundleName);
  158. return fnLoadAndCreateFromBundle(bundle);
  159. }
  160. }