mirror of
https://github.com/VickScarlet/lifeRestart.git
synced 2026-08-28 09:16:47 +08:00
update: toolchan
This commit is contained in:
+245
-208
@@ -1,360 +1,397 @@
|
||||
import Views from './themes/views.js';
|
||||
import Views from './views.js'
|
||||
export default class UIManager {
|
||||
constructor(stage) {
|
||||
UIManager.#views = Views;
|
||||
UIManager.#views = Views
|
||||
|
||||
if(!stage) {
|
||||
stage = Laya.stage;
|
||||
if (!stage) {
|
||||
stage = Laya.stage
|
||||
}
|
||||
this.#stage = stage;
|
||||
this.#stage = stage
|
||||
|
||||
stage.addChild(this.#viewLayer);
|
||||
this.#viewLayer.zOrder = 1;
|
||||
stage.addChild(this.#dialogLayer);
|
||||
this.#dialogLayer.zOrder = 2;
|
||||
stage.addChild(this.#popupLayer);
|
||||
this.#popupLayer.zOrder = 3;
|
||||
stage.addChild(this.#viewLayer)
|
||||
this.#viewLayer.zOrder = 1
|
||||
stage.addChild(this.#dialogLayer)
|
||||
this.#dialogLayer.zOrder = 2
|
||||
stage.addChild(this.#popupLayer)
|
||||
this.#popupLayer.zOrder = 3
|
||||
this.#viewLayer.top =
|
||||
this.#viewLayer.bottom =
|
||||
this.#viewLayer.left =
|
||||
this.#viewLayer.right =
|
||||
this.#dialogLayer.top =
|
||||
this.#dialogLayer.bottom =
|
||||
this.#dialogLayer.left =
|
||||
this.#dialogLayer.right =
|
||||
this.#popupLayer.top =
|
||||
this.#popupLayer.bottom =
|
||||
this.#popupLayer.left =
|
||||
this.#popupLayer.right =
|
||||
this.#dialogMask.top =
|
||||
this.#dialogMask.bottom =
|
||||
this.#dialogMask.left =
|
||||
this.#dialogMask.right = 0;
|
||||
this.#dialogMask.graphics.drawRect(0, 0, 5000, 5000, '#000000');
|
||||
this.#dialogMask.alpha = 0.4;
|
||||
this.#dialogMask.on(Laya.Event.CLICK, this, ()=>{
|
||||
this.#dialogStack[this.#dialogStack.length - 1]?.close?.();
|
||||
this.#viewLayer.bottom =
|
||||
this.#viewLayer.left =
|
||||
this.#viewLayer.right =
|
||||
this.#dialogLayer.top =
|
||||
this.#dialogLayer.bottom =
|
||||
this.#dialogLayer.left =
|
||||
this.#dialogLayer.right =
|
||||
this.#popupLayer.top =
|
||||
this.#popupLayer.bottom =
|
||||
this.#popupLayer.left =
|
||||
this.#popupLayer.right =
|
||||
this.#dialogMask.top =
|
||||
this.#dialogMask.bottom =
|
||||
this.#dialogMask.left =
|
||||
this.#dialogMask.right =
|
||||
0
|
||||
this.#dialogMask.graphics.drawRect(0, 0, 5000, 5000, '#000000')
|
||||
this.#dialogMask.alpha = 0.4
|
||||
this.#dialogMask.on(Laya.Event.CLICK, this, () => {
|
||||
this.#dialogStack[this.#dialogStack.length - 1]?.close?.()
|
||||
})
|
||||
}
|
||||
|
||||
static #instance = {};
|
||||
static #views;
|
||||
#stage;
|
||||
#loading;
|
||||
#currentView;
|
||||
#viewLayer = new Laya.Panel();
|
||||
#dialogLayer = new Laya.Panel();
|
||||
#popupLayer = new Laya.Panel();
|
||||
#dialogMask = new Laya.Sprite();
|
||||
#viewMap = new Map();
|
||||
#class = new Map();
|
||||
#dialogStack = [];
|
||||
static #instance = {}
|
||||
static #views
|
||||
#stage
|
||||
#loading
|
||||
#currentView
|
||||
#viewLayer = new Laya.Panel()
|
||||
#dialogLayer = new Laya.Panel()
|
||||
#popupLayer = new Laya.Panel()
|
||||
#dialogMask = new Laya.Sprite()
|
||||
#viewMap = new Map()
|
||||
#class = new Map()
|
||||
#dialogStack = []
|
||||
|
||||
static get inst() {
|
||||
return this.getInstance();
|
||||
return this.getInstance()
|
||||
}
|
||||
static getInstance(name="default") {
|
||||
return this.#instance[name] || (this.#instance[name] = new UIManager());
|
||||
static getInstance(name = 'default') {
|
||||
return this.#instance[name] || (this.#instance[name] = new UIManager())
|
||||
}
|
||||
|
||||
static get pages() {
|
||||
return this.#views.pages;
|
||||
return this.#views.pages
|
||||
}
|
||||
|
||||
static get popups() {
|
||||
return this.#views.popups;
|
||||
return this.#views.popups
|
||||
}
|
||||
|
||||
static theme(theme, prop) {
|
||||
return this.#views.themes[theme][prop];
|
||||
return this.#views.themes[theme][prop]
|
||||
}
|
||||
|
||||
async setLoading(loading) {
|
||||
const className = this.#pages[loading];
|
||||
const view = await this.getView(className, null, null, loading);
|
||||
view.top = view.bottom = view.left = view.right = 0;
|
||||
view.zOrder = 4;
|
||||
this.#loading = view;
|
||||
const className = this.#pages[loading]
|
||||
const view = await this.getView(className, null, null, loading)
|
||||
view.top = view.bottom = view.left = view.right = 0
|
||||
view.zOrder = 4
|
||||
this.#loading = view
|
||||
}
|
||||
|
||||
async switchView(viewName, args, actions) {
|
||||
const className = this.#pages[viewName];
|
||||
const className = this.#pages[viewName]
|
||||
// get view instance
|
||||
const view = await this.getView(className, args, actions?.load, viewName, 'pages');
|
||||
const view = await this.getView(
|
||||
className,
|
||||
args,
|
||||
actions?.load,
|
||||
viewName,
|
||||
'pages'
|
||||
)
|
||||
|
||||
view.top = view.bottom = view.left = view.right = 0;
|
||||
view.top = view.bottom = view.left = view.right = 0
|
||||
// close current view
|
||||
this.clearAllDialog();
|
||||
await this.#currentView?.__close?.(view);
|
||||
await this.#currentView?.close?.(view);
|
||||
this.#viewLayer.removeChildren();
|
||||
this.clearAllDialog()
|
||||
await this.#currentView?.__close?.(view)
|
||||
await this.#currentView?.close?.(view)
|
||||
this.#viewLayer.removeChildren()
|
||||
|
||||
// open new view
|
||||
await view.init?.(args);
|
||||
await view.init?.(args)
|
||||
|
||||
this.#currentView = view;
|
||||
this.#viewLayer.addChild(view);
|
||||
this.#currentView = view
|
||||
this.#viewLayer.addChild(view)
|
||||
|
||||
view.__close = actions?.close;
|
||||
await actions?.open?.(view);
|
||||
await view.show?.();
|
||||
view.__close = actions?.close
|
||||
await actions?.open?.(view)
|
||||
await view.show?.()
|
||||
}
|
||||
|
||||
async getView(className, args, preload, viewName, type) {
|
||||
// check if view is already loaded
|
||||
let view = await this.#viewMap.get(className);
|
||||
let view = await this.#viewMap.get(className)
|
||||
|
||||
let timeout;
|
||||
if(this.#loading) {
|
||||
let timeout
|
||||
if (this.#loading) {
|
||||
timeout = setTimeout(
|
||||
()=>this.#stage.addChild(this.#loading),
|
||||
() => this.#stage.addChild(this.#loading),
|
||||
3000
|
||||
);
|
||||
)
|
||||
}
|
||||
const onProgress = this.#loading?.onProgress;
|
||||
const onProgress = this.#loading?.onProgress
|
||||
|
||||
if(!view) {
|
||||
if (!view) {
|
||||
// load view
|
||||
const ViewClass = await this.loadView(className);
|
||||
const resourceList = await ViewClass.load?.(args);
|
||||
const scanedResourceList = this.#loading? this.scanResource(ViewClass.uiView): [];
|
||||
if(preload) {
|
||||
preload = [].concat(preload).concat(scanedResourceList);
|
||||
const ViewClass = await this.loadView(className)
|
||||
const resourceList = await ViewClass.load?.(args)
|
||||
const scanedResourceList = this.#loading
|
||||
? this.scanResource(ViewClass.uiView)
|
||||
: []
|
||||
if (preload) {
|
||||
preload = [].concat(preload).concat(scanedResourceList)
|
||||
} else {
|
||||
preload = scanedResourceList;
|
||||
preload = scanedResourceList
|
||||
}
|
||||
await this.loadRes(resourceList, preload, onProgress);
|
||||
await this.loadRes(resourceList, preload, onProgress)
|
||||
|
||||
// create view
|
||||
view = new ViewClass();
|
||||
view = new ViewClass()
|
||||
// add view to map
|
||||
this.#viewMap.set(className, view);
|
||||
this.#viewMap.set(className, view)
|
||||
} else {
|
||||
// load resource
|
||||
const resourceList = await view.constructor.load?.(args);
|
||||
await this.loadRes(resourceList, preload, onProgress);
|
||||
const resourceList = await view.constructor.load?.(args)
|
||||
await this.loadRes(resourceList, preload, onProgress)
|
||||
}
|
||||
if(timeout) clearTimeout(timeout);
|
||||
this.#loading?.removeSelf();
|
||||
if (timeout) clearTimeout(timeout)
|
||||
this.#loading?.removeSelf()
|
||||
|
||||
this.#config(view, viewName, type);
|
||||
this.#config(view, viewName, type)
|
||||
// return view
|
||||
return view;
|
||||
return view
|
||||
}
|
||||
|
||||
async loadView(className) {
|
||||
// load view
|
||||
if(this.#class.has(className)) return this.#class.get(className);
|
||||
const c = (await import(`./themes/${className}.js`)).default;
|
||||
this.#class.set(className, c);
|
||||
return c;
|
||||
if (this.#class.has(className)) return this.#class.get(className)
|
||||
const views = import.meta.glob('./themes/**/*.js')
|
||||
const view = (await views[`./themes/${className}.js`]()).default
|
||||
this.#class.set(className, view)
|
||||
return view
|
||||
}
|
||||
|
||||
async loadRes(resourceList, preload, onProgress) {
|
||||
const cnt = (resourceList?.length || 0)
|
||||
+(preload?.length || 0);
|
||||
if(resourceList && resourceList.length) {
|
||||
const s = resourceList.length / cnt;
|
||||
await Laya.promises.loader.load(resourceList, Laya.Handler.create(null, prg=>onProgress?.(prg*s)));
|
||||
const cnt = (resourceList?.length || 0) + (preload?.length || 0)
|
||||
if (resourceList && resourceList.length) {
|
||||
const s = resourceList.length / cnt
|
||||
await Laya.promises.loader.load(
|
||||
resourceList,
|
||||
Laya.Handler.create(null, prg => onProgress?.(prg * s))
|
||||
)
|
||||
}
|
||||
if(preload && preload.length) {
|
||||
const s = 1 - preload.length / cnt;
|
||||
const l = preload.length / cnt;
|
||||
await Laya.promises.loader.load(preload, Laya.Handler.create(null, prg=>onProgress?.(prg*l+s)));
|
||||
if (preload && preload.length) {
|
||||
const s = 1 - preload.length / cnt
|
||||
const l = preload.length / cnt
|
||||
await Laya.promises.loader.load(
|
||||
preload,
|
||||
Laya.Handler.create(null, prg => onProgress?.(prg * l + s))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#showDialogStack() {
|
||||
if(this.#dialogStack.length == 0) {
|
||||
this.#dialogLayer.visible = false;
|
||||
return;
|
||||
if (this.#dialogStack.length == 0) {
|
||||
this.#dialogLayer.visible = false
|
||||
return
|
||||
}
|
||||
this.#dialogLayer.visible = true;
|
||||
this.#dialogStack.forEach((dialog, i)=>{
|
||||
this.#dialogLayer.addChild(dialog);
|
||||
dialog.zOrder = i;
|
||||
this.#dialogLayer.visible = true
|
||||
this.#dialogStack.forEach((dialog, i) => {
|
||||
this.#dialogLayer.addChild(dialog)
|
||||
dialog.zOrder = i
|
||||
})
|
||||
this.#dialogLayer.addChild(this.#dialogMask);
|
||||
const l = this.#dialogStack.length;
|
||||
this.#dialogMask.zOrder = l -1;
|
||||
this.#dialogStack[l -1].zOrder = l;
|
||||
this.#dialogLayer.addChild(this.#dialogMask)
|
||||
const l = this.#dialogStack.length
|
||||
this.#dialogMask.zOrder = l - 1
|
||||
this.#dialogStack[l - 1].zOrder = l
|
||||
}
|
||||
|
||||
async showDialog(dialogName, args, actions) {
|
||||
const className = this.#pages[dialogName];
|
||||
const dialog = await this.getView(className, args, actions?.load, dialogName, 'pages');
|
||||
const className = this.#pages[dialogName]
|
||||
const dialog = await this.getView(
|
||||
className,
|
||||
args,
|
||||
actions?.load,
|
||||
dialogName,
|
||||
'pages'
|
||||
)
|
||||
|
||||
const index = this.#dialogStack.indexOf(dialog);
|
||||
if(index != -1) {
|
||||
this.#dialogStack.splice(index, 1);
|
||||
const index = this.#dialogStack.indexOf(dialog)
|
||||
if (index != -1) {
|
||||
this.#dialogStack.splice(index, 1)
|
||||
}
|
||||
this.#dialogStack.push(dialog);
|
||||
dialog.init?.(args);
|
||||
dialog.centerX = dialog.centerY = 0;
|
||||
this.#showDialogStack();
|
||||
this.#dialogStack.push(dialog)
|
||||
dialog.init?.(args)
|
||||
dialog.centerX = dialog.centerY = 0
|
||||
this.#showDialogStack()
|
||||
|
||||
const open = actions?.open || (async () => {
|
||||
dialog.scaleX = 0;
|
||||
dialog.scaleY = 0;
|
||||
await Laya.promises.Tween.to(dialog, { scaleX: 1, scaleY: 1 }, 300, Laya.Ease.backOut);
|
||||
});
|
||||
await open(dialog);
|
||||
dialog.mouseThrough = true;
|
||||
dialog.mouseEnabled = true;
|
||||
dialog.close = async ()=>{
|
||||
if(actions?.close) {
|
||||
await actions.close();
|
||||
const open =
|
||||
actions?.open ||
|
||||
(async () => {
|
||||
dialog.scaleX = 0
|
||||
dialog.scaleY = 0
|
||||
await Laya.promises.Tween.to(
|
||||
dialog,
|
||||
{ scaleX: 1, scaleY: 1 },
|
||||
300,
|
||||
Laya.Ease.backOut
|
||||
)
|
||||
})
|
||||
await open(dialog)
|
||||
dialog.mouseThrough = true
|
||||
dialog.mouseEnabled = true
|
||||
dialog.close = async () => {
|
||||
if (actions?.close) {
|
||||
await actions.close()
|
||||
} else {
|
||||
await Laya.promises.Tween.to(dialog, { scaleX: 0, scaleY: 0 }, 300, Laya.Ease.strongIn);
|
||||
await Laya.promises.Tween.to(
|
||||
dialog,
|
||||
{ scaleX: 0, scaleY: 0 },
|
||||
300,
|
||||
Laya.Ease.strongIn
|
||||
)
|
||||
}
|
||||
const index = this.#dialogStack.indexOf(dialog);
|
||||
if(index != -1) {
|
||||
this.#dialogStack.splice(index, 1);
|
||||
const index = this.#dialogStack.indexOf(dialog)
|
||||
if (index != -1) {
|
||||
this.#dialogStack.splice(index, 1)
|
||||
}
|
||||
this.#showDialogStack();
|
||||
this.#showDialogStack()
|
||||
}
|
||||
|
||||
this.#dialogLayer.addChild(dialog);
|
||||
this.#dialogLayer.addChild(dialog)
|
||||
}
|
||||
|
||||
async popup(type, args) {
|
||||
const className = this.#popups[type];
|
||||
const popup = await this.getView(className, args, null, type, 'popups');
|
||||
this.#popupLayer.addChild(popup);
|
||||
await popup.popup(args, this.#popupLayer);
|
||||
this.#popupLayer.removeChild(popup);
|
||||
const className = this.#popups[type]
|
||||
const popup = await this.getView(className, args, null, type, 'popups')
|
||||
this.#popupLayer.addChild(popup)
|
||||
await popup.popup(args, this.#popupLayer)
|
||||
this.#popupLayer.removeChild(popup)
|
||||
}
|
||||
|
||||
clearAllDialog() {
|
||||
this.#dialogStack = [];
|
||||
this.#showDialogStack();
|
||||
this.#dialogStack = []
|
||||
this.#showDialogStack()
|
||||
}
|
||||
|
||||
#config(view, key, type) {
|
||||
const config = this.#configs?.[type]?.[key];
|
||||
if(!config) return;
|
||||
if(view.config && view.config(config)) return;
|
||||
const config = this.#configs?.[type]?.[key]
|
||||
if (!config) return
|
||||
if (view.config && view.config(config)) return
|
||||
const applyConfig = (target, config) => {
|
||||
if(!target) return;
|
||||
if(typeof config == 'string') {
|
||||
config = this.#configs?.class?.[config];
|
||||
if (!target) return
|
||||
if (typeof config == 'string') {
|
||||
config = this.#configs?.class?.[config]
|
||||
}
|
||||
$_.deepMapSet(target, config);
|
||||
};
|
||||
$_.deepMapSet(target, config)
|
||||
}
|
||||
|
||||
if(config.names)
|
||||
for(const name in config.names)
|
||||
this.#deepGetChildsByName(view, name)
|
||||
.forEach(child => applyConfig(child, config.names[name]));
|
||||
|
||||
if(config.vars)
|
||||
for(const key in config.vars)
|
||||
applyConfig(view[key], config.vars[key]);
|
||||
if (config.names)
|
||||
for (const name in config.names)
|
||||
this.#deepGetChildsByName(view, name).forEach(child =>
|
||||
applyConfig(child, config.names[name])
|
||||
)
|
||||
|
||||
if (config.vars)
|
||||
for (const key in config.vars)
|
||||
applyConfig(view[key], config.vars[key])
|
||||
}
|
||||
|
||||
#deepGetChildsByName(parent, name) {
|
||||
const list = [];
|
||||
if(!parent || !parent._childs) return list;
|
||||
const list = []
|
||||
if (!parent || !parent._childs) return list
|
||||
|
||||
for(const child of parent._childs) {
|
||||
if(child.name == name) list.push(child);
|
||||
if(child._childs) list.push(...this.#deepGetChildsByName(child, name));
|
||||
for (const child of parent._childs) {
|
||||
if (child.name == name) list.push(child)
|
||||
if (child._childs)
|
||||
list.push(...this.#deepGetChildsByName(child, name))
|
||||
}
|
||||
return list;
|
||||
return list
|
||||
}
|
||||
|
||||
#cutPath(path) {
|
||||
path = ''+path;
|
||||
let index = path.length;
|
||||
path = '' + path
|
||||
let index = path.length
|
||||
do {
|
||||
index --;
|
||||
if(path[index] == '.') {
|
||||
break;
|
||||
index--
|
||||
if (path[index] == '.') {
|
||||
break
|
||||
}
|
||||
} while (index>0)
|
||||
return [
|
||||
path.substring(0, index),
|
||||
path.substring(index, path.length)
|
||||
];
|
||||
} while (index > 0)
|
||||
return [path.substring(0, index), path.substring(index, path.length)]
|
||||
}
|
||||
|
||||
#subSkin(skin, type) {
|
||||
if(!skin || !skin.replace(/\s/g, '')) return [];
|
||||
if (!skin || !skin.replace(/\s/g, '')) return []
|
||||
switch (type) {
|
||||
case 'ProgressBar':
|
||||
return [ skin, ...this.#progressBarSkin(skin) ];
|
||||
return [skin, ...this.#progressBarSkin(skin)]
|
||||
case 'ScrollBar':
|
||||
return [ skin, ...this.#scrollBarSkin(skin) ];
|
||||
return [skin, ...this.#scrollBarSkin(skin)]
|
||||
default:
|
||||
return [skin]
|
||||
}
|
||||
}
|
||||
|
||||
#progressBarSkin(skin) {
|
||||
if(!skin.replace(/\s/g, '')) return [];
|
||||
let p = this.#cutPath(skin);
|
||||
return [`${p[0]}$bar${p[1]}`];
|
||||
if (!skin.replace(/\s/g, '')) return []
|
||||
let p = this.#cutPath(skin)
|
||||
return [`${p[0]}$bar${p[1]}`]
|
||||
}
|
||||
|
||||
#scrollBarSkin(skin) {
|
||||
if(!skin.replace(/\s/g, '')) return [];
|
||||
let p = this.#cutPath(skin);
|
||||
if (!skin.replace(/\s/g, '')) return []
|
||||
let p = this.#cutPath(skin)
|
||||
return [
|
||||
`${p[0]}$bar${p[1]}`,
|
||||
`${p[0]}$up${p[1]}`,
|
||||
`${p[0]}$down${p[1]}`
|
||||
];
|
||||
`${p[0]}$down${p[1]}`,
|
||||
]
|
||||
}
|
||||
|
||||
scanResource(uiView) {
|
||||
if(!uiView) return [];
|
||||
const resourceList = [];
|
||||
if (!uiView) return []
|
||||
const resourceList = []
|
||||
|
||||
resourceList.push(...this.#subSkin(uiView.props?.skin, uiView.type));
|
||||
resourceList.push(...this.#subSkin(uiView.props?.hScrollBarSkin, 'ScrollBar'));
|
||||
resourceList.push(...this.#subSkin(uiView.props?.vScrollBarSkin, 'ScrollBar'));
|
||||
resourceList.push(...this.#subSkin(uiView.props?.skin, uiView.type))
|
||||
resourceList.push(
|
||||
...this.#subSkin(uiView.props?.hScrollBarSkin, 'ScrollBar')
|
||||
)
|
||||
resourceList.push(
|
||||
...this.#subSkin(uiView.props?.vScrollBarSkin, 'ScrollBar')
|
||||
)
|
||||
|
||||
uiView.child?.forEach(child => {
|
||||
resourceList.push(...this.scanResource(child));
|
||||
});
|
||||
resourceList.push(...this.scanResource(child))
|
||||
})
|
||||
|
||||
return resourceList;
|
||||
return resourceList
|
||||
}
|
||||
|
||||
get currentView() {
|
||||
return this.#currentView;
|
||||
return this.#currentView
|
||||
}
|
||||
|
||||
get currentDialog() {
|
||||
return this.#dialogStack[this.#dialogStack.length -1];
|
||||
return this.#dialogStack[this.#dialogStack.length - 1]
|
||||
}
|
||||
|
||||
get theme() {
|
||||
return localStorage.getItem('theme');
|
||||
return localStorage.getItem('theme')
|
||||
}
|
||||
set theme(value) {
|
||||
localStorage.setItem('theme', value);
|
||||
this.#stage.bgColor = this.#configs.bgColor;
|
||||
document?.querySelector?.('meta[name="theme-color"]')?.setAttribute?.('content', this.#configs.bgColor);
|
||||
localStorage.setItem('theme', value)
|
||||
this.#stage.bgColor = this.#configs.bgColor
|
||||
document
|
||||
?.querySelector?.('meta[name="theme-color"]')
|
||||
?.setAttribute?.('content', this.#configs.bgColor)
|
||||
}
|
||||
|
||||
get #pages() {
|
||||
return UIManager.theme(this.theme, 'pages');
|
||||
return UIManager.theme(this.theme, 'pages')
|
||||
}
|
||||
get #popups() {
|
||||
return UIManager.theme(this.theme, 'popups');
|
||||
return UIManager.theme(this.theme, 'popups')
|
||||
}
|
||||
get #configs() {
|
||||
return UIManager.theme(this.theme, 'configs');
|
||||
return UIManager.theme(this.theme, 'configs')
|
||||
}
|
||||
get common() {
|
||||
return this.#configs.common;
|
||||
return this.#configs.common
|
||||
}
|
||||
gradeColor(grade) {
|
||||
return this.common.grade[grade];
|
||||
return this.common.grade[grade]
|
||||
}
|
||||
gradeFilter(grade) {
|
||||
return this.common.filter[grade];
|
||||
return this.common.filter[grade]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user