mirror of
				https://github.com/unanmed/HumanBreak.git
				synced 2025-11-04 15:12:58 +08:00 
			
		
		
		
	Compare commits
	
		
			No commits in common. "0cc76bd475da262d2214982ae1c5d7836068bd5d" and "109e77d6a2205c378f88a08f0fb2115c169ea6f4" have entirely different histories.
		
	
	
		
			0cc76bd475
			...
			109e77d6a2
		
	
		
@ -1,9 +1,9 @@
 | 
				
			|||||||
import { defineComponent, VNode } from 'vue';
 | 
					import { computed, defineComponent, VNode } from 'vue';
 | 
				
			||||||
import { IUIMountable } from './shared';
 | 
					import { IUIMountable, UIComponent } from './shared';
 | 
				
			||||||
import { SetupComponentOptions } from '@/module';
 | 
					import { SetupComponentOptions } from '@/module';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface UIContainerProps {
 | 
					export interface UIContainerProps {
 | 
				
			||||||
    controller: IUIMountable;
 | 
					    controller: IUIMountable<UIComponent>;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const containerConfig = {
 | 
					const containerConfig = {
 | 
				
			||||||
@ -13,29 +13,18 @@ const containerConfig = {
 | 
				
			|||||||
export const UIContainer = defineComponent<UIContainerProps>(props => {
 | 
					export const UIContainer = defineComponent<UIContainerProps>(props => {
 | 
				
			||||||
    const data = props.controller;
 | 
					    const data = props.controller;
 | 
				
			||||||
    const back = data.backIns;
 | 
					    const back = data.backIns;
 | 
				
			||||||
 | 
					    const show = computed(() => data.stack.filter(v => !v.hidden));
 | 
				
			||||||
    return (): VNode[] => {
 | 
					    return (): VNode[] => {
 | 
				
			||||||
        const elements: VNode[] = [];
 | 
					        const elements: VNode[] = [];
 | 
				
			||||||
        const b = back.value;
 | 
					        const b = back.value;
 | 
				
			||||||
        if (b && data.showBack.value && !b.hidden) {
 | 
					        if (b && data.showBack.value && !b.hidden) {
 | 
				
			||||||
            elements.push(
 | 
					            elements.push(
 | 
				
			||||||
                <b.ui.component
 | 
					                <b.ui.component {...b.vBind} key={b.key}></b.ui.component>
 | 
				
			||||||
                    {...b.vBind}
 | 
					 | 
				
			||||||
                    controller={data}
 | 
					 | 
				
			||||||
                    instance={b}
 | 
					 | 
				
			||||||
                    key={b.key}
 | 
					 | 
				
			||||||
                    hidden={b.hidden}
 | 
					 | 
				
			||||||
                ></b.ui.component>
 | 
					 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return elements.concat(
 | 
					        return elements.concat(
 | 
				
			||||||
            data.stack.map(v => (
 | 
					            show.value.map(v => (
 | 
				
			||||||
                <v.ui.component
 | 
					                <v.ui.component {...v.vBind} key={v.key}></v.ui.component>
 | 
				
			||||||
                    {...v.vBind}
 | 
					 | 
				
			||||||
                    key={v.key}
 | 
					 | 
				
			||||||
                    controller={data}
 | 
					 | 
				
			||||||
                    instance={v}
 | 
					 | 
				
			||||||
                    hidden={v.hidden}
 | 
					 | 
				
			||||||
                ></v.ui.component>
 | 
					 | 
				
			||||||
            ))
 | 
					            ))
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
				
			|||||||
@ -5,9 +5,9 @@ import {
 | 
				
			|||||||
    IKeepController,
 | 
					    IKeepController,
 | 
				
			||||||
    IUIInstance,
 | 
					    IUIInstance,
 | 
				
			||||||
    IUIMountable,
 | 
					    IUIMountable,
 | 
				
			||||||
    UIComponent,
 | 
					    UIComponent
 | 
				
			||||||
    UIProps
 | 
					 | 
				
			||||||
} from './shared';
 | 
					} from './shared';
 | 
				
			||||||
 | 
					import { Props } from '@/core/render';
 | 
				
			||||||
import { UIInstance } from './instance';
 | 
					import { UIInstance } from './instance';
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
    computed,
 | 
					    computed,
 | 
				
			||||||
@ -35,13 +35,13 @@ export const enum UIMode {
 | 
				
			|||||||
    Custom
 | 
					    Custom
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface IUICustomConfig {
 | 
					export interface IUICustomConfig<C extends UIComponent> {
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 打开一个新的 UI
 | 
					     * 打开一个新的 UI
 | 
				
			||||||
     * @param ins 要打开的 UI 实例
 | 
					     * @param ins 要打开的 UI 实例
 | 
				
			||||||
     * @param stack 当前的 UI 栈,还未将 UI 实例加入栈中
 | 
					     * @param stack 当前的 UI 栈,还未将 UI 实例加入栈中
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    open(ins: IUIInstance, stack: IUIInstance[]): void;
 | 
					    open(ins: IUIInstance<C>, stack: IUIInstance<C>[]): void;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 关闭一个 UI
 | 
					     * 关闭一个 UI
 | 
				
			||||||
@ -49,7 +49,7 @@ export interface IUICustomConfig {
 | 
				
			|||||||
     * @param stack 当前的 UI 栈,还未将 UI 实例移除
 | 
					     * @param stack 当前的 UI 栈,还未将 UI 实例移除
 | 
				
			||||||
     * @param index 这个 UI 实例在 UI 栈中的索引
 | 
					     * @param index 这个 UI 实例在 UI 栈中的索引
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    close(ins: IUIInstance, stack: IUIInstance[], index: number): void;
 | 
					    close(ins: IUIInstance<C>, stack: IUIInstance<C>[], index: number): void;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 隐藏一个 UI
 | 
					     * 隐藏一个 UI
 | 
				
			||||||
@ -57,7 +57,7 @@ export interface IUICustomConfig {
 | 
				
			|||||||
     * @param stack 当前的 UI 栈
 | 
					     * @param stack 当前的 UI 栈
 | 
				
			||||||
     * @param index 这个 UI 实例在 UI 栈中的索引
 | 
					     * @param index 这个 UI 实例在 UI 栈中的索引
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    hide(ins: IUIInstance, stack: IUIInstance[], index: number): void;
 | 
					    hide(ins: IUIInstance<C>, stack: IUIInstance<C>[], index: number): void;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 显示一个 UI
 | 
					     * 显示一个 UI
 | 
				
			||||||
@ -65,32 +65,32 @@ export interface IUICustomConfig {
 | 
				
			|||||||
     * @param stack 当前的 UI 栈
 | 
					     * @param stack 当前的 UI 栈
 | 
				
			||||||
     * @param index 这个 UI 实例在 UI 栈中的索引
 | 
					     * @param index 这个 UI 实例在 UI 栈中的索引
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    show(ins: IUIInstance, stack: IUIInstance[], index: number): void;
 | 
					    show(ins: IUIInstance<C>, stack: IUIInstance<C>[], index: number): void;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 更新所有 UI 的显示,一般会在显示模式更改时调用
 | 
					     * 更新所有 UI 的显示,一般会在显示模式更改时调用
 | 
				
			||||||
     * @param stack 当前的 UI 栈
 | 
					     * @param stack 当前的 UI 栈
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    update(stack: IUIInstance[]): void;
 | 
					    update(stack: IUIInstance<C>[]): void;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
interface UIControllerEvent {}
 | 
					interface UIControllerEvent {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export class UIController
 | 
					export class UIController<C extends UIComponent = UIComponent>
 | 
				
			||||||
    extends EventEmitter<UIControllerEvent>
 | 
					    extends EventEmitter<UIControllerEvent>
 | 
				
			||||||
    implements IUIMountable
 | 
					    implements IUIMountable<C>
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    static controllers: Map<string, UIController> = new Map();
 | 
					    static controllers: Map<string, UIController> = new Map();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /** 当前的 ui 栈 */
 | 
					    /** 当前的 ui 栈 */
 | 
				
			||||||
    readonly stack: IUIInstance[] = reactive([]);
 | 
					    readonly stack: IUIInstance<C>[] = reactive([]);
 | 
				
			||||||
    /** UI 显示方式 */
 | 
					    /** UI 显示方式 */
 | 
				
			||||||
    mode: UIMode = UIMode.LastOnlyStack;
 | 
					    mode: UIMode = UIMode.LastOnlyStack;
 | 
				
			||||||
    /** 这个 UI 实例的背景,当这个 UI 处于显示模式时,会显示背景 */
 | 
					    /** 这个 UI 实例的背景,当这个 UI 处于显示模式时,会显示背景 */
 | 
				
			||||||
    background?: IGameUI;
 | 
					    background?: IGameUI<C>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /** 背景 UI 实例 */
 | 
					    /** 背景 UI 实例 */
 | 
				
			||||||
    readonly backIns: ShallowRef<IUIInstance | null> = shallowRef(null);
 | 
					    readonly backIns: ShallowRef<IUIInstance<C> | null> = shallowRef(null);
 | 
				
			||||||
    /** 当前是否显示背景 UI */
 | 
					    /** 当前是否显示背景 UI */
 | 
				
			||||||
    readonly showBack: ComputedRef<boolean> = computed(
 | 
					    readonly showBack: ComputedRef<boolean> = computed(
 | 
				
			||||||
        () => this.userShowBack.value && this.sysShowBack.value
 | 
					        () => this.userShowBack.value && this.sysShowBack.value
 | 
				
			||||||
@ -102,7 +102,7 @@ export class UIController
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /** 自定义显示模式下的配置信息 */
 | 
					    /** 自定义显示模式下的配置信息 */
 | 
				
			||||||
    private config?: IUICustomConfig;
 | 
					    private config?: IUICustomConfig<C>;
 | 
				
			||||||
    /** 是否维持背景 UI */
 | 
					    /** 是否维持背景 UI */
 | 
				
			||||||
    private keepBack: boolean = false;
 | 
					    private keepBack: boolean = false;
 | 
				
			||||||
    /** 用户是否显示背景 UI */
 | 
					    /** 用户是否显示背景 UI */
 | 
				
			||||||
@ -134,7 +134,7 @@ export class UIController
 | 
				
			|||||||
     * 设置背景 UI
 | 
					     * 设置背景 UI
 | 
				
			||||||
     * @param back 这个 UI 控制器的背景 UI
 | 
					     * @param back 这个 UI 控制器的背景 UI
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    setBackground(back: IGameUI) {
 | 
					    setBackground(back: IGameUI<C>) {
 | 
				
			||||||
        this.background = back;
 | 
					        this.background = back;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -171,12 +171,13 @@ export class UIController
 | 
				
			|||||||
        };
 | 
					        };
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    open<T extends UIComponent>(
 | 
					    /**
 | 
				
			||||||
        ui: IGameUI<T>,
 | 
					     * 打开一个 ui
 | 
				
			||||||
        vBind: UIProps<T>,
 | 
					     * @param ui 要打开的 ui
 | 
				
			||||||
        alwaysShow: boolean = false
 | 
					     * @param vBind 传递给这个 ui 的响应式数据
 | 
				
			||||||
    ): IUIInstance<T> {
 | 
					     */
 | 
				
			||||||
        const ins = new UIInstance(ui, vBind, alwaysShow);
 | 
					    open(ui: IGameUI<C>, vBind: Props<C>) {
 | 
				
			||||||
 | 
					        const ins = new UIInstance(ui, vBind);
 | 
				
			||||||
        switch (this.mode) {
 | 
					        switch (this.mode) {
 | 
				
			||||||
            case UIMode.LastOnly:
 | 
					            case UIMode.LastOnly:
 | 
				
			||||||
            case UIMode.LastOnlyStack:
 | 
					            case UIMode.LastOnlyStack:
 | 
				
			||||||
@ -195,7 +196,11 @@ export class UIController
 | 
				
			|||||||
        return ins;
 | 
					        return ins;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    close(ui: IUIInstance) {
 | 
					    /**
 | 
				
			||||||
 | 
					     * 关闭一个 ui
 | 
				
			||||||
 | 
					     * @param ui 要关闭的 ui 实例
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    close(ui: UIInstance<C>) {
 | 
				
			||||||
        const index = this.stack.indexOf(ui);
 | 
					        const index = this.stack.indexOf(ui);
 | 
				
			||||||
        if (index === -1) return;
 | 
					        if (index === -1) return;
 | 
				
			||||||
        switch (this.mode) {
 | 
					        switch (this.mode) {
 | 
				
			||||||
@ -234,16 +239,7 @@ export class UIController
 | 
				
			|||||||
        this.keepBack = false;
 | 
					        this.keepBack = false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    closeAll(ui?: IGameUI): void {
 | 
					    hide(ins: IUIInstance<C>): void {
 | 
				
			||||||
        if (!ui) {
 | 
					 | 
				
			||||||
            this.stack.splice(0);
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            const list = this.stack.filter(v => v.ui === ui);
 | 
					 | 
				
			||||||
            list.forEach(v => this.close(v));
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    hide(ins: IUIInstance): void {
 | 
					 | 
				
			||||||
        const index = this.stack.indexOf(ins);
 | 
					        const index = this.stack.indexOf(ins);
 | 
				
			||||||
        if (index === -1) return;
 | 
					        if (index === -1) return;
 | 
				
			||||||
        if (this.mode === UIMode.Custom) {
 | 
					        if (this.mode === UIMode.Custom) {
 | 
				
			||||||
@ -253,7 +249,7 @@ export class UIController
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    show(ins: IUIInstance): void {
 | 
					    show(ins: IUIInstance<C>): void {
 | 
				
			||||||
        const index = this.stack.indexOf(ins);
 | 
					        const index = this.stack.indexOf(ins);
 | 
				
			||||||
        if (index === -1) return;
 | 
					        if (index === -1) return;
 | 
				
			||||||
        if (this.mode === UIMode.Custom) {
 | 
					        if (this.mode === UIMode.Custom) {
 | 
				
			||||||
@ -294,7 +290,7 @@ export class UIController
 | 
				
			|||||||
     * 使用自定义的显示模式
 | 
					     * 使用自定义的显示模式
 | 
				
			||||||
     * @param config 自定义显示模式的配置
 | 
					     * @param config 自定义显示模式的配置
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    showCustom(config: IUICustomConfig) {
 | 
					    showCustom(config: IUICustomConfig<C>) {
 | 
				
			||||||
        this.mode = UIMode.Custom;
 | 
					        this.mode = UIMode.Custom;
 | 
				
			||||||
        this.config = config;
 | 
					        this.config = config;
 | 
				
			||||||
        config.update(this.stack);
 | 
					        config.update(this.stack);
 | 
				
			||||||
@ -304,8 +300,10 @@ export class UIController
 | 
				
			|||||||
     * 获取一个元素上的 ui 控制器
 | 
					     * 获取一个元素上的 ui 控制器
 | 
				
			||||||
     * @param id 要获取的 ui 控制器的唯一标识符
 | 
					     * @param id 要获取的 ui 控制器的唯一标识符
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    static getController(id: string): UIController | null {
 | 
					    static getController<T extends UIComponent>(
 | 
				
			||||||
        const res = this.controllers.get(id);
 | 
					        id: string
 | 
				
			||||||
 | 
					    ): UIController<T> | null {
 | 
				
			||||||
 | 
					        const res = this.controllers.get(id) as UIController<T>;
 | 
				
			||||||
        return res ?? null;
 | 
					        return res ?? null;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
import { Props } from '@/core/render';
 | 
					import { Props } from '@/core/render';
 | 
				
			||||||
import { IGameUI, IUIInstance, UIComponent, UIProps } from './shared';
 | 
					import { IGameUI, IUIInstance, UIComponent } from './shared';
 | 
				
			||||||
import EventEmitter from 'eventemitter3';
 | 
					import EventEmitter from 'eventemitter3';
 | 
				
			||||||
import { markRaw, mergeProps } from 'vue';
 | 
					import { markRaw, mergeProps } from 'vue';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -21,8 +21,7 @@ export class UIInstance<C extends UIComponent>
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    constructor(
 | 
					    constructor(
 | 
				
			||||||
        ui: IGameUI<C>,
 | 
					        ui: IGameUI<C>,
 | 
				
			||||||
        public vBind: UIProps<C>,
 | 
					        public vBind: Props<C>
 | 
				
			||||||
        public readonly alwaysShow: boolean = false
 | 
					 | 
				
			||||||
    ) {
 | 
					    ) {
 | 
				
			||||||
        super();
 | 
					        super();
 | 
				
			||||||
        this.ui = markRaw(ui);
 | 
					        this.ui = markRaw(ui);
 | 
				
			||||||
@ -31,13 +30,13 @@ export class UIInstance<C extends UIComponent>
 | 
				
			|||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 设置这个 UI 实例的响应式数据的值
 | 
					     * 设置这个 UI 实例的响应式数据的值
 | 
				
			||||||
     * @param data 要设置的值
 | 
					     * @param data 要设置的值
 | 
				
			||||||
     * @param merge 是将传入的值与原先的值合并(true),还是将当前值覆盖掉原先的值(false),默认合并
 | 
					     * @param merge 是将传入的值与原先的值合并(true),还是将当前值覆盖掉原先的值(false)
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    setVBind(data: Partial<Props<C>>, merge: boolean = true) {
 | 
					    setVBind(data: Props<C>, merge: boolean = true) {
 | 
				
			||||||
        if (merge) {
 | 
					        if (merge) {
 | 
				
			||||||
            this.vBind = mergeProps(this.vBind, data) as UIProps<C>;
 | 
					            this.vBind = mergeProps(this.vBind, data) as Props<C>;
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            this.vBind = data as UIProps<C>;
 | 
					            this.vBind = data;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -3,17 +3,7 @@ import { DefineComponent, DefineSetupFnComponent, Ref, ShallowRef } from 'vue';
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
export type UIComponent = DefineSetupFnComponent<any> | DefineComponent;
 | 
					export type UIComponent = DefineSetupFnComponent<any> | DefineComponent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface UIComponentProps<T extends UIComponent = UIComponent> {
 | 
					export interface IGameUI<C extends UIComponent> {
 | 
				
			||||||
    controller: IUIMountable;
 | 
					 | 
				
			||||||
    instance: IUIInstance<T>;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export type UIProps<C extends UIComponent = UIComponent> = Omit<
 | 
					 | 
				
			||||||
    Props<C>,
 | 
					 | 
				
			||||||
    keyof UIComponentProps<C>
 | 
					 | 
				
			||||||
>;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export interface IGameUI<C extends UIComponent = UIComponent> {
 | 
					 | 
				
			||||||
    /** 这个 UI 的名称 */
 | 
					    /** 这个 UI 的名称 */
 | 
				
			||||||
    readonly name: string;
 | 
					    readonly name: string;
 | 
				
			||||||
    /** 这个 UI 的组件 */
 | 
					    /** 这个 UI 的组件 */
 | 
				
			||||||
@ -32,11 +22,11 @@ export interface IKeepController {
 | 
				
			|||||||
    unload(): void;
 | 
					    unload(): void;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface IUIMountable {
 | 
					export interface IUIMountable<C extends UIComponent> {
 | 
				
			||||||
    /** 当前的 UI 栈 */
 | 
					    /** 当前的 UI 栈 */
 | 
				
			||||||
    readonly stack: IUIInstance<UIComponent>[];
 | 
					    readonly stack: IUIInstance<C>[];
 | 
				
			||||||
    /** 当前的背景 UI */
 | 
					    /** 当前的背景 UI */
 | 
				
			||||||
    readonly backIns: ShallowRef<IUIInstance<UIComponent> | null>;
 | 
					    readonly backIns: ShallowRef<IUIInstance<C> | null>;
 | 
				
			||||||
    /** 当前是否显示背景 UI */
 | 
					    /** 当前是否显示背景 UI */
 | 
				
			||||||
    readonly showBack: Ref<boolean>;
 | 
					    readonly showBack: Ref<boolean>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -44,46 +34,13 @@ export interface IUIMountable {
 | 
				
			|||||||
     * 隐藏一个 UI
 | 
					     * 隐藏一个 UI
 | 
				
			||||||
     * @param ins 要隐藏的 UI 实例
 | 
					     * @param ins 要隐藏的 UI 实例
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    hide(ins: IUIInstance<UIComponent>): void;
 | 
					    hide(ins: IUIInstance<C>): void;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 显示一个 UI
 | 
					     * 显示一个 UI
 | 
				
			||||||
     * @param ins 要显示的 UI 实例
 | 
					     * @param ins 要显示的 UI 实例
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    show(ins: IUIInstance<UIComponent>): void;
 | 
					    show(ins: IUIInstance<C>): void;
 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * 隐藏背景 UI
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    hideBackground(): void;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * 显示背景 UI
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    showBackground(): void;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * 打开一个 ui
 | 
					 | 
				
			||||||
     * @param ui 要打开的 ui
 | 
					 | 
				
			||||||
     * @param vBind 传递给这个 ui 的响应式数据
 | 
					 | 
				
			||||||
     * @param alwaysShow 这个 ui 是否保持开启,对于需要叠加显示的 ui 非常有用
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    open<T extends UIComponent>(
 | 
					 | 
				
			||||||
        ui: IGameUI<T>,
 | 
					 | 
				
			||||||
        vBind: UIProps<T>,
 | 
					 | 
				
			||||||
        alwaysShow?: boolean
 | 
					 | 
				
			||||||
    ): IUIInstance<T>;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * 关闭一个 ui
 | 
					 | 
				
			||||||
     * @param ui 要关闭的 ui 实例
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    close(ui: IUIInstance<UIComponent>): void;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * 关闭所有或指定类型的所有 UI
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    closeAll(ui?: IGameUI<UIComponent>): void;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 维持背景,直到下次所有 UI 都被关闭
 | 
					     * 维持背景,直到下次所有 UI 都被关闭
 | 
				
			||||||
@ -91,17 +48,15 @@ export interface IUIMountable {
 | 
				
			|||||||
    keep(): IKeepController;
 | 
					    keep(): IKeepController;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface IUIInstance<C extends UIComponent = UIComponent> {
 | 
					export interface IUIInstance<C extends UIComponent> {
 | 
				
			||||||
    /** 这个 ui 实例的唯一 key,用于 vue */
 | 
					    /** 这个 ui 实例的唯一 key,用于 vue */
 | 
				
			||||||
    readonly key: number;
 | 
					    readonly key: number;
 | 
				
			||||||
    /** 这个 ui 实例的 ui 信息 */
 | 
					    /** 这个 ui 实例的 ui 信息 */
 | 
				
			||||||
    readonly ui: IGameUI<C>;
 | 
					    readonly ui: IGameUI<C>;
 | 
				
			||||||
    /** 传递给这个 ui 实例的响应式数据 */
 | 
					    /** 传递给这个 ui 实例的响应式数据 */
 | 
				
			||||||
    readonly vBind: UIProps<C>;
 | 
					    readonly vBind: Props<C>;
 | 
				
			||||||
    /** 当前元素是否被隐藏 */
 | 
					    /** 当前元素是否被隐藏 */
 | 
				
			||||||
    readonly hidden: boolean;
 | 
					    readonly hidden: boolean;
 | 
				
			||||||
    /** 是否永远保持开启 */
 | 
					 | 
				
			||||||
    readonly alwaysShow: boolean;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 隐藏这个 ui
 | 
					     * 隐藏这个 ui
 | 
				
			||||||
 | 
				
			|||||||
@ -5,7 +5,6 @@ import { TextContent, TextContentExpose, TextContentProps } from './textbox';
 | 
				
			|||||||
import { SetupComponentOptions } from './types';
 | 
					import { SetupComponentOptions } from './types';
 | 
				
			||||||
import { TextAlign } from './textboxTyper';
 | 
					import { TextAlign } from './textboxTyper';
 | 
				
			||||||
import { Page, PageExpose } from './page';
 | 
					import { Page, PageExpose } from './page';
 | 
				
			||||||
import { GameUI, IUIMountable } from '@/core/system';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface ConfirmBoxProps extends DefaultProps, TextContentProps {
 | 
					export interface ConfirmBoxProps extends DefaultProps, TextContentProps {
 | 
				
			||||||
    text: string;
 | 
					    text: string;
 | 
				
			||||||
@ -67,11 +66,11 @@ const confirmBoxProps = {
 | 
				
			|||||||
 *   color="#333"
 | 
					 *   color="#333"
 | 
				
			||||||
 *   border="gold"
 | 
					 *   border="gold"
 | 
				
			||||||
 *   // 设置选项的字体
 | 
					 *   // 设置选项的字体
 | 
				
			||||||
 *   selFont={new Font('Verdana', 16)}
 | 
					 *   selFont="16px Verdana"
 | 
				
			||||||
 *   // 设置选项的文本颜色
 | 
					 *   // 设置选项的文本颜色
 | 
				
			||||||
 *   selFill="#d48"
 | 
					 *   selFill="#d48"
 | 
				
			||||||
 *   // 完全继承 TextContent 的参数,因此可以填写 font 参数指定文本字体
 | 
					 *   // 完全继承 TextContent 的参数,因此可以填写 fontFamily 参数指定文本字体
 | 
				
			||||||
 *   font={new Font('arial')}
 | 
					 *   fontFamily="Arial"
 | 
				
			||||||
 *   onYes={onYes}
 | 
					 *   onYes={onYes}
 | 
				
			||||||
 *   onNo={onNo}
 | 
					 *   onNo={onNo}
 | 
				
			||||||
 * />
 | 
					 * />
 | 
				
			||||||
@ -192,11 +191,8 @@ export const ConfirmBox = defineComponent<
 | 
				
			|||||||
    );
 | 
					    );
 | 
				
			||||||
}, confirmBoxProps);
 | 
					}, confirmBoxProps);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type ChoiceKey = string | number | symbol;
 | 
					 | 
				
			||||||
export type ChoiceItem = [key: ChoiceKey, text: string];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export interface ChoicesProps extends DefaultProps, TextContentProps {
 | 
					export interface ChoicesProps extends DefaultProps, TextContentProps {
 | 
				
			||||||
    choices: ChoiceItem[];
 | 
					    choices: [key: string | number | symbol, text: string][];
 | 
				
			||||||
    loc: ElementLocator;
 | 
					    loc: ElementLocator;
 | 
				
			||||||
    width: number;
 | 
					    width: number;
 | 
				
			||||||
    maxHeight?: number;
 | 
					    maxHeight?: number;
 | 
				
			||||||
@ -210,11 +206,12 @@ export interface ChoicesProps extends DefaultProps, TextContentProps {
 | 
				
			|||||||
    titleFont?: Font;
 | 
					    titleFont?: Font;
 | 
				
			||||||
    titleFill?: CanvasStyle;
 | 
					    titleFill?: CanvasStyle;
 | 
				
			||||||
    pad?: number;
 | 
					    pad?: number;
 | 
				
			||||||
 | 
					    defaultChoice?: string | number | symbol;
 | 
				
			||||||
    interval?: number;
 | 
					    interval?: number;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type ChoicesEmits = {
 | 
					export type ChoicesEmits = {
 | 
				
			||||||
    choose: (key: ChoiceKey) => void;
 | 
					    choice: (key: string | number | symbol) => void;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const choicesProps = {
 | 
					const choicesProps = {
 | 
				
			||||||
@ -233,49 +230,16 @@ const choicesProps = {
 | 
				
			|||||||
        'titleFont',
 | 
					        'titleFont',
 | 
				
			||||||
        'titleFill',
 | 
					        'titleFill',
 | 
				
			||||||
        'pad',
 | 
					        'pad',
 | 
				
			||||||
 | 
					        'defaultChoice',
 | 
				
			||||||
        'interval'
 | 
					        'interval'
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
    emits: ['choose']
 | 
					    emits: ['choice']
 | 
				
			||||||
} satisfies SetupComponentOptions<
 | 
					} satisfies SetupComponentOptions<
 | 
				
			||||||
    ChoicesProps,
 | 
					    ChoicesProps,
 | 
				
			||||||
    ChoicesEmits,
 | 
					    ChoicesEmits,
 | 
				
			||||||
    keyof ChoicesEmits
 | 
					    keyof ChoicesEmits
 | 
				
			||||||
>;
 | 
					>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * 选项框组件,用于在多个选项中选择一个,例如样板的系统设置就由它实现。
 | 
					 | 
				
			||||||
 * 参数参考 {@link ChoicesProps},事件参考 {@link ChoicesEmits}。用例如下:
 | 
					 | 
				
			||||||
 * ```tsx
 | 
					 | 
				
			||||||
 * <Choices
 | 
					 | 
				
			||||||
 *   // 选项数组,每一项是一个二元素数组,第一项表示这个选项的 id,在选中时会以此作为参数传递给事件
 | 
					 | 
				
			||||||
 *   // 第二项表示这一项的内容,即展示给玩家看的内容
 | 
					 | 
				
			||||||
 *   choices={[[0, '选项1'], [100, '选项2']]}
 | 
					 | 
				
			||||||
 *   // 选项框会自动计算宽度和高度,因此不需要手动指定,即使手动指定也无效
 | 
					 | 
				
			||||||
 *   loc={[240, 240, void 0, void 0, 0.5, 0.5]}
 | 
					 | 
				
			||||||
 *   text="请选择一项"
 | 
					 | 
				
			||||||
 *   title="选项"
 | 
					 | 
				
			||||||
 *   // 使用 winskin 图片作为背景
 | 
					 | 
				
			||||||
 *   winskin="winskin.png"
 | 
					 | 
				
			||||||
 *   // 使用颜色作为背景和边框,如果设置了 winskin,那么此参数无效
 | 
					 | 
				
			||||||
 *   color="#333"
 | 
					 | 
				
			||||||
 *   border="gold"
 | 
					 | 
				
			||||||
 *   // 调整每两个选项之间的间隔
 | 
					 | 
				
			||||||
 *   interval={12}
 | 
					 | 
				
			||||||
 *   // 设置选项的字体
 | 
					 | 
				
			||||||
 *   selFont={new Font('Verdana', 16)}
 | 
					 | 
				
			||||||
 *   // 设置选项的文本颜色
 | 
					 | 
				
			||||||
 *   selFill="#d48"
 | 
					 | 
				
			||||||
 *   // 设置标题的字体
 | 
					 | 
				
			||||||
 *   titleFont={new Font('Verdana', 16)}
 | 
					 | 
				
			||||||
 *   // 设置标题的文本颜色
 | 
					 | 
				
			||||||
 *   selFill="gold"
 | 
					 | 
				
			||||||
 *   // 完全继承 TextContent 的参数,因此可以填写 font 参数指定文本字体
 | 
					 | 
				
			||||||
 *   font={new Font('arial')}
 | 
					 | 
				
			||||||
 *   // 当选择某一项时触发
 | 
					 | 
				
			||||||
 *   onChoice={(choice) => console.log(choice)}
 | 
					 | 
				
			||||||
 * />
 | 
					 | 
				
			||||||
 * ```
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
export const Choices = defineComponent<
 | 
					export const Choices = defineComponent<
 | 
				
			||||||
    ChoicesProps,
 | 
					    ChoicesProps,
 | 
				
			||||||
    ChoicesEmits,
 | 
					    ChoicesEmits,
 | 
				
			||||||
@ -460,7 +424,7 @@ export const Choices = defineComponent<
 | 
				
			|||||||
    key.realize('confirm', () => {
 | 
					    key.realize('confirm', () => {
 | 
				
			||||||
        const page = pageCom.value?.now() ?? 1;
 | 
					        const page = pageCom.value?.now() ?? 1;
 | 
				
			||||||
        const index = page * choiceCountPerPage.value + selected.value;
 | 
					        const index = page * choiceCountPerPage.value + selected.value;
 | 
				
			||||||
        emit('choose', props.choices[index][0]);
 | 
					        emit('choice', props.choices[index][0]);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return () => (
 | 
					    return () => (
 | 
				
			||||||
@ -515,7 +479,7 @@ export const Choices = defineComponent<
 | 
				
			|||||||
                                font={props.selFont}
 | 
					                                font={props.selFont}
 | 
				
			||||||
                                cursor="pointer"
 | 
					                                cursor="pointer"
 | 
				
			||||||
                                zIndex={5}
 | 
					                                zIndex={5}
 | 
				
			||||||
                                onClick={() => emit('choose', v[0])}
 | 
					                                onClick={() => emit('choice', v[0])}
 | 
				
			||||||
                                onSetText={(_, width, height) =>
 | 
					                                onSetText={(_, width, height) =>
 | 
				
			||||||
                                    updateChoiceSize(i, width, height)
 | 
					                                    updateChoiceSize(i, width, height)
 | 
				
			||||||
                                }
 | 
					                                }
 | 
				
			||||||
@ -528,78 +492,3 @@ export const Choices = defineComponent<
 | 
				
			|||||||
        </container>
 | 
					        </container>
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
}, choicesProps);
 | 
					}, choicesProps);
 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * 弹出一个确认框,然后将确认结果返回
 | 
					 | 
				
			||||||
 * @param controller UI 控制器
 | 
					 | 
				
			||||||
 * @param text 确认文本内容
 | 
					 | 
				
			||||||
 * @param loc 确认框的位置
 | 
					 | 
				
			||||||
 * @param width 确认框的宽度
 | 
					 | 
				
			||||||
 * @param props 额外的 props
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
export function getConfirm(
 | 
					 | 
				
			||||||
    controller: IUIMountable,
 | 
					 | 
				
			||||||
    text: string,
 | 
					 | 
				
			||||||
    loc: ElementLocator,
 | 
					 | 
				
			||||||
    width: number,
 | 
					 | 
				
			||||||
    props?: Partial<ConfirmBoxProps>
 | 
					 | 
				
			||||||
) {
 | 
					 | 
				
			||||||
    return new Promise<boolean>(res => {
 | 
					 | 
				
			||||||
        const instance = controller.open(
 | 
					 | 
				
			||||||
            ConfirmBoxUI,
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                ...(props ?? {}),
 | 
					 | 
				
			||||||
                loc,
 | 
					 | 
				
			||||||
                text,
 | 
					 | 
				
			||||||
                width,
 | 
					 | 
				
			||||||
                onYes: () => {
 | 
					 | 
				
			||||||
                    controller.close(instance);
 | 
					 | 
				
			||||||
                    res(true);
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                onNo: () => {
 | 
					 | 
				
			||||||
                    controller.close(instance);
 | 
					 | 
				
			||||||
                    res(false);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            true
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * 弹出一个选择框,然后将选择结果返回
 | 
					 | 
				
			||||||
 * @param controller UI 控制器
 | 
					 | 
				
			||||||
 * @param choices 选择框的选项
 | 
					 | 
				
			||||||
 * @param loc 选择框的位置
 | 
					 | 
				
			||||||
 * @param width 选择框的宽度
 | 
					 | 
				
			||||||
 * @param props 额外的 props
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
export function getChoice<T extends ChoiceKey = ChoiceKey>(
 | 
					 | 
				
			||||||
    controller: IUIMountable,
 | 
					 | 
				
			||||||
    choices: ChoiceItem[],
 | 
					 | 
				
			||||||
    loc: ElementLocator,
 | 
					 | 
				
			||||||
    width: number,
 | 
					 | 
				
			||||||
    props?: Partial<ChoicesProps>
 | 
					 | 
				
			||||||
) {
 | 
					 | 
				
			||||||
    return new Promise<T>(res => {
 | 
					 | 
				
			||||||
        const instance = controller.open(
 | 
					 | 
				
			||||||
            ChoicesUI,
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                ...(props ?? {}),
 | 
					 | 
				
			||||||
                choices,
 | 
					 | 
				
			||||||
                loc,
 | 
					 | 
				
			||||||
                width,
 | 
					 | 
				
			||||||
                onChoose: key => {
 | 
					 | 
				
			||||||
                    controller.close(instance);
 | 
					 | 
				
			||||||
                    res(key as T);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            true
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/** @see {@link ConfirmBox} */
 | 
					 | 
				
			||||||
export const ConfirmBoxUI = new GameUI('confirm-box', ConfirmBox);
 | 
					 | 
				
			||||||
/** @see {@link Choices} */
 | 
					 | 
				
			||||||
export const ChoicesUI = new GameUI('choices', Choices);
 | 
					 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user