From 83f460de65b4aa8ab4a17e3168b162e2f98d30cd Mon Sep 17 00:00:00 2001 From: unanmed <1319491857@qq.com> Date: Thu, 3 Apr 2025 15:22:25 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20@motajs/system=20=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/api/motajs-system-action/Hotkey.md | 311 ++++++++++++++++++++++ docs/api/motajs-system-action/Keyboard.md | 221 +++++++++++++++ docs/api/motajs-system-ui/GameUI.md | 97 +++++++ docs/api/motajs-system-ui/UIController.md | 284 ++++++++++++++++++++ docs/api/motajs-system-ui/UIInstance.md | 121 +++++++++ docs/api/motajs-system/index.md | 24 +- packages/system-action/src/hotkey.ts | 35 +-- packages/system-ui/src/controller.ts | 7 +- packages/system-ui/src/shared.ts | 7 + 9 files changed, 1089 insertions(+), 18 deletions(-) create mode 100644 docs/api/motajs-system-action/Hotkey.md create mode 100644 docs/api/motajs-system-action/Keyboard.md create mode 100644 docs/api/motajs-system-ui/GameUI.md create mode 100644 docs/api/motajs-system-ui/UIController.md create mode 100644 docs/api/motajs-system-ui/UIInstance.md diff --git a/docs/api/motajs-system-action/Hotkey.md b/docs/api/motajs-system-action/Hotkey.md new file mode 100644 index 0000000..60f600d --- /dev/null +++ b/docs/api/motajs-system-action/Hotkey.md @@ -0,0 +1,311 @@ +# Hotkey API 文档 + +本文档由 `DeepSeek R1` 模型生成并微调。 + +```mermaid +graph LR + Hotkey --> EventEmitter + + click EventEmitter "https://nodejs.org/api/events.html#class-eventemitter" +``` + +## 类描述 + +`Hotkey` 是按键系统的核心类,用于管理按键绑定、辅助键状态、按键分组及事件触发逻辑。继承自 `EventEmitter`,支持自定义事件监听。主要用于实现复杂的快捷键系统。 + +--- + +## 属性说明 + +| 属性名 | 类型 | 描述 | +| -------------- | ---------------------------- | -------------------------------------------- | +| `id` | `string` | 控制器的唯一标识符 | +| `name` | `string` | 控制器的显示名称 | +| `data` | `Record` | 存储所有已注册的按键配置 | +| `keyMap` | `Map` | 按键代码到配置的映射(支持多键绑定同一操作) | +| `enabled` | `boolean` | 当前控制器是否启用(默认 `false`) | +| `list`(静态) | `Hotkey[]` | 静态属性,存储所有已创建的控制器实例 | + +--- + +## 构造方法 + +```typescript +function constructor(id: string, name: string): Hotkey; +``` + +- **参数** + - `id`: 控制器的唯一标识符 + - `name`: 控制器的显示名称 + +**示例** + +```typescript +const editorHotkey = new Hotkey('editor', '编辑器快捷键'); +``` + +--- + +## 方法说明 + +### `register` + +```typescript +function register(data: RegisterHotkeyData): this; +``` + +注册一个按键配置。 + +- **参数** + ```typescript + interface RegisterHotkeyData { + id: string; // 按键唯一标识(可含数字后缀,如 "copy_1") + name: string; // 显示名称(如 "复制") + defaults: KeyCode; // 默认按键代码 + ctrl?: boolean; // 是否默认需要 Ctrl 辅助键 + shift?: boolean; // 是否默认需要 Shift 辅助键 + alt?: boolean; // 是否默认需要 Alt 辅助键 + } + ``` + +**示例** + +```typescript +editorHotkey.register({ + id: 'copy', + name: '复制', + defaults: KeyCode.KeyC, + ctrl: true +}); +``` + +--- + +### `realize` + +```typescript +function realize(id: string, func: HotkeyFunc, config?: HotkeyEmitConfig): this; +``` + +为按键绑定触发逻辑。 + +- **参数** + - `id`: 目标按键 ID(无需后缀) + - `func`: 触发时执行的函数 + - `config`: 触发类型配置(节流/超时等) + +**示例** + +```typescript +editorHotkey.realize( + 'copy', + (id, key, ev) => { + console.log('执行复制操作'); + }, + { type: 'down-throttle', throttle: 500 } +); +``` + +--- + +### `group` + +```typescript +function group(id: string, name: string, keys?: RegisterHotkeyData[]): this; +``` + +创建按键分组,后续注册的按键自动加入该组。 + +- **参数** + - `id`: 分组唯一标识 + - `name`: 分组显示名称 + - `keys`: 可选,预注册的按键列表 + +--- + +### `set` + +```typescript +function set(id: string, key: KeyCode, assist: number, emit?: boolean): void; +``` + +动态修改按键绑定。 + +- **参数** + - `id`: 目标按键 ID + - `key`: 新按键代码 + - `assist`: 辅助键状态(二进制位:Ctrl=1<<0, Shift=1<<1, Alt=1<<2) + - `emit`: 是否触发 `set` 事件(默认 `true`) + +--- + +### `when` + +```typescript +function when(fn: () => boolean): this; +``` + +为当前作用域的按键绑定添加触发条件。 + +- **参数** + - `fn`: 条件函数,返回 `true` 时允许触发按键逻辑 + +**示例** + +```typescript +// 仅在游戏处于运行状态时允许触发 +controller.when(() => gameState === 'running'); +``` + +--- + +### `enable` + +```typescript +function enable(): void; +``` + +### `disable` + +```typescript +function disable(): void; +``` + +启用/禁用整个按键控制器(禁用后所有按键事件将被忽略)。 + +**示例** + +```typescript +// 暂停游戏时禁用按键 +controller.disable(); +``` + +--- + +### `use` + +```typescript +function use(symbol: symbol): void; +``` + +切换当前作用域,后续 `realize` 方法绑定的逻辑将关联到该作用域。 + +- **参数** + - `symbol`: 唯一作用域标识符 + +--- + +### `dispose` + +```typescript +function dispose(symbol?: symbol): void; +``` + +释放指定作用域及其绑定的所有按键逻辑。 + +- **参数** + - `symbol`(可选): 要释放的作用域(默认释放当前作用域) + +**示例** + +```typescript +const scope = Symbol(); +controller.use(scope); +// ...绑定操作... +controller.dispose(scope); // 释放该作用域 +``` + +--- + +### `emitKey` + +```typescript +function emitKey( + key: KeyCode, + assist: number, + type: KeyEventType, + ev: KeyboardEvent +): boolean; +``` + +手动触发按键事件(可用于模拟按键操作)。 + +- **参数** + - `key`: 按键代码 + - `assist`: 辅助键状态(二进制位:Ctrl=1<<0, Shift=1<<1, Alt=1<<2) + - `type`: 事件类型(`'up'` 或 `'down'`) + - `ev`: 原始键盘事件对象 +- **返回值** + `true` 表示事件被成功处理,`false` 表示无匹配逻辑 + +**示例** + +```typescript +// 模拟触发 Ctrl+S 保存操作 +controller.emitKey( + KeyCode.KeyS, + 1 << 0, // Ctrl 激活 + 'down', + new KeyboardEvent('keydown') +); +``` + +--- + +## 静态方法说明 + +### `Hotkey.get` + +```typescript +function get(id: string): Hotkey | undefined; +``` + +**静态方法**:根据 ID 获取控制器实例。 + +--- + +## 事件说明 + +| 事件名 | 参数类型 | 触发时机 | +| --------- | --------------------------------------------------- | ---------------- | +| `set` | `[id: string, key: KeyCode, assist: number]` | 按键绑定被修改时 | +| `emit` | `[key: KeyCode, assist: number, type: KeyEmitType]` | 按键被触发时 | +| `press` | `[key: KeyCode]` | 按键被按下时 | +| `release` | `[key: KeyCode]` | 按键被释放时 | + +**事件监听示例** + +```typescript +editorHotkey.on('emit', (key, assist) => { + console.log(`按键 ${KeyCode[key]} 触发,辅助键状态:${assist}`); +}); +``` + +--- + +## 总使用示例 + +::: code-group + +```typescript [注册] +import { gameKey } from '@motajs/system-action'; + +gameKey.register({ + id: 'jump', + name: '跳跃', + defaults: KeyCode.Space +}); +``` + +```typescript [实现] +import { useKey } from '@motajs/render-vue'; + +const [gameKey] = useKey(); + +// 绑定跳跃逻辑 +gameKey.realize('jump', () => { + player.jump(); +}); +``` + +::: diff --git a/docs/api/motajs-system-action/Keyboard.md b/docs/api/motajs-system-action/Keyboard.md new file mode 100644 index 0000000..f3929fa --- /dev/null +++ b/docs/api/motajs-system-action/Keyboard.md @@ -0,0 +1,221 @@ +# Keyboard API 文档 + +本文档由 `DeepSeek R1` 模型生成并微调。 + +```mermaid +graph LR + Keyboard --> EventEmitter +``` + +## 类描述 + +`Keyboard` 是虚拟键盘的核心类,用于管理动态按键布局、处理按键事件及辅助键状态。继承自 `EventEmitter`,支持自定义事件监听。 + +--- + +## 属性说明 + +| 属性名 | 类型 | 描述 | +| -------------- | ---------------- | ----------------------------------------------------------- | +| `id` | `string` | 键盘的唯一标识符 | +| `keys` | `KeyboardItem[]` | 当前键盘包含的按键列表(响应式数组) | +| `assist` | `number` | 辅助键状态(二进制位表示:Ctrl=1<<0, Shift=1<<1, Alt=1<<2) | +| `fontSize` | `number` | 按键文本字体大小(默认 18) | +| `list`(静态) | `Keyboard[]` | 静态属性,存储所有已创建的键盘实例 | + +**KeyboardItem 结构**: + +```typescript +interface KeyboardItem { + key: KeyCode; // 按键代码 + text?: string; // 显示文本(可选) + x: number; // X 坐标 + y: number; // Y 坐标 + width: number; // 宽度 + height: number; // 高度 +} +``` + +--- + +## 构造方法 + +```typescript +function constructor(id: string): Keyboard; +``` + +- **参数** + - `id`: 键盘的唯一标识符 + +**示例** + +```typescript +const numpad = new Keyboard('numpad'); +``` + +--- + +## 方法说明 + +### `add` + +```typescript +function add(item: KeyboardItem): Keyboard; +``` + +### `remove` + +```typescript +function remove(item: KeyboardItem): Keyboard; +``` + +添加/移除按键,返回当前实例以便链式调用。 + +**示例** + +```typescript +// 添加数字键 1 +numpad.add({ + key: KeyCode.Digit1, + text: '1', + x: 0, + y: 0, + width: 60, + height: 60 +}); + +// 移除按键 +numpad.remove(existingKey); +``` + +--- + +### `extend` + +```typescript +function extend( + keyboard: Keyboard, + offsetX?: number, + offsetY?: number +): Keyboard; +``` + +继承其他键盘的按键布局并添加偏移量。 + +**示例** + +```typescript +const extendedKB = new Keyboard('extended'); +extendedKB.extend(numpad, 100, 0); // 向右偏移 100px +``` + +--- + +### `emitKey` + +```typescript +function emitKey(key: KeyboardItem, index: number): void; +``` + +模拟触发按键事件(自动处理辅助键状态)。 + +--- + +### `createScope` + +```typescript +function createScope(): symbol; +``` + +### `disposeScope` + +```typescript +function disposeScope(): void; +``` + +管理事件监听作用域: + +- `createScope`: 创建新作用域(返回唯一标识符) +- `disposeScope`: 释放当前作用域 + +--- + +### `withAssist` + +```typescript +function withAssist(assist: number): symbol; +``` + +创建预设辅助键状态的作用域(如 `Ctrl+Shift`)。 + +--- + +### `Keyboard.get` + +```typescript +function get(id: string): Keyboard | undefined; +``` + +**静态方法**:根据 ID 获取键盘实例。 + +--- + +## 事件说明 + +| 事件名 | 参数类型 | 触发时机 | +| -------------- | ------------------------- | ------------------ | +| `add` | `KeyboardItem` | 新增按键时 | +| `remove` | `KeyboardItem` | 移除按键时 | +| `extend` | `Keyboard` | 继承其他键盘布局时 | +| `emit` | `item, assist, index, ev` | 触发按键时 | +| `scopeCreate` | `symbol` | 创建作用域时 | +| `scopeDispose` | `symbol` | 释放作用域时 | + +**事件监听示例** + +```typescript +numpad.on('emit', (item, assist) => { + console.log(`按键 ${item.key} 触发,辅助键状态:${assist}`); +}); +``` + +--- + +## 总使用示例 + +```typescript +import { KeyCode } from '@motajs/client-base'; +import { Keyboard } from '@motajs/system-action'; + +// 创建数字键盘 +const numpad = new Keyboard('numpad'); + +// 添加基础按键 +numpad + .add({ key: KeyCode.Digit1, x: 0, y: 0, width: 60, height: 60 }) + .add({ key: KeyCode.Digit2, x: 60, y: 0, width: 60, height: 60 }); + +// 添加功能键(带辅助状态) +const ctrlScope = numpad.withAssist(1 << 0); // Ctrl 激活 +numpad.add({ + key: KeyCode.KeyC, + text: '复制', + x: 120, + y: 0, + width: 120, + height: 60 +}); + +// 监听复制键 +numpad.on('emit', item => { + if (item.key === KeyCode.KeyC) { + console.log('执行复制操作'); + } +}); + +// 触发按键 +numpad.emitKey(numpad.keys[0], 0); // 模拟按下数字 1 + +// 获取键盘实例 +const foundKB = Keyboard.get('numpad'); +``` diff --git a/docs/api/motajs-system-ui/GameUI.md b/docs/api/motajs-system-ui/GameUI.md new file mode 100644 index 0000000..c8dae21 --- /dev/null +++ b/docs/api/motajs-system-ui/GameUI.md @@ -0,0 +1,97 @@ +# GameUI API 文档 + +本文档由 `DeepSeek R1` 模型生成并微调。 + +```mermaid +graph LR + GameUI --> IGameUI +``` + +_实现 `IGameUI` 接口_ + +## 接口描述 + +`IGameUI` 是 UI 系统的核心接口,定义了 UI 实例的基础结构和静态操作方法。 + +--- + +## 属性说明 + +| 属性名 | 类型 | 描述 | +| -------------- | ---------------------------------- | ------------------------------------------------------------------- | +| `name` | `string` | 只读,UI 的唯一标识名称 | +| `component` | `C extends UIComponent` | 只读,关联的 Vue 组件实例 | +| `list`(静态) | `Map>` | 静态属性,存储所有已注册的 UI 实例,键为 `name`,值为 `GameUI` 实例 | + +--- + +## 构造方法 + +### `consturctor` + +```typescript +function constructor(name: string, component: C): GameUI; +``` + +- **参数** + - `name`: UI 的唯一标识名称 + - `component`: 关联的 Vue 组件实例 + +**示例** + +```typescript +import { defineComponent } from 'vue'; + +export const MyComponent = defineComponent(...); + +// 创建 UI 实例并自动注册到静态列表 +export const MyUI = new GameUI('my-ui', MyComponent); +``` + +--- + +## 方法说明 + +### `GameUI.get` + +```typescript +function get(id: string): GameUI | null; +``` + +**静态方法**:根据 UI 名称从静态列表获取实例。 + +- **参数** + - `id`: UI 的唯一标识名称 +- **返回值** + 匹配的 `GameUI` 实例,未找到时返回 `null` + +**示例** + +```typescript +// 获取名为 "home" 的 UI 实例 +const ui = GameUI.get('my-ui'); +if (ui) { + console.log(ui.component); // 输出关联的 Vue 组件 +} +``` + +--- + +## 总使用示例 + +```tsx +import { defineComponent } from 'vue'; +import { GameUI } from '@motajs/system-ui'; + +// 定义组件 +export const MyCom = defineComponent(() => { + return () => ( + + + + ); +}); + +// 定义 UI 实例 +export const MyUI = new GameUI('my-ui', MyCom); +``` diff --git a/docs/api/motajs-system-ui/UIController.md b/docs/api/motajs-system-ui/UIController.md new file mode 100644 index 0000000..e781db1 --- /dev/null +++ b/docs/api/motajs-system-ui/UIController.md @@ -0,0 +1,284 @@ +# UIController API 文档 + +本文档由 `DeepSeek R1` 模型生成并微调。 + +```mermaid +graph LR + UIController --> EventEmitter + + click EventEmitter "https://nodejs.org/api/events.html#class-eventemitter" +``` + +## 类描述 + +`UIController` 是 UI 控制系统的核心类,负责管理 UI 实例的显示栈、背景控制以及多种显示模式。继承自 `EventEmitter`,支持事件监听。想要编写 UI 请参考[深度指南](../../guide/ui.md)。 + +--- + +## 属性说明 + +| 属性名 | 类型 | 描述 | +| --------------------- | ---------------------------- | --------------------------------------------------------------- | +| `stack` | `IUIInstance[]` (响应式数组) | 当前管理的 UI 实例栈 | +| `mode` | `UIMode` | UI 显示模式,默认为 `LastOnlyStack` | +| `background` | `IGameUI` | 背景 UI 的配置实例 | +| `backIns` | `ShallowRef` | 背景 UI 实例的响应式引用 | +| `showBack` | `ComputedRef` | 当前是否显示背景(用户设置与系统状态共同决定) | +| `active`(只读) | `boolean` | 系统是否显示背景 UI(等价于 `sysShowBack.value`) | +| `controllers`(静态) | `Map` | 静态属性,存储所有已创建的控制器实例,键为 `id`,值为控制器实例 | + +--- + +## 构造方法 + +### `constructor` + +```typescript +function constructor(id: string): UIController; +``` + +- **参数** + - `id`: 控制器的唯一标识符(若重复会触发警告日志) + +**示例** + +```typescript +const mainController = new UIController('main'); +``` + +--- + +## 方法说明 + +### `render` + +```typescript +function render(): VNode; +``` + +渲染 UI 容器组件(用于 Vue 挂载)。 + +**示例** + +```tsx +import { defineComponent } from 'vue'; +import { UIController } from '@motajs/system-ui'; + +export const myController = new UIController('my-controller'); + +export const MyCom = defineComponent(() => { + return () => {myController.render()}; +}); +``` + +--- + +### `setBackground` + +```typescript +function setBackground( + back: IGameUI, + vBind: UIProps +): void; +``` + +设置背景 UI 并初始化其实例。 + +- **参数** + - `back`: 背景 UI 配置实例 + - `vBind`: 传递给背景组件的 Props 对象 + +**示例** + +```typescript +import { BackgroundUI } from './background'; + +// 显示背景组件,并传入参数 theme='dark' +mainController.setBackground(BackgroundUI, { theme: 'dark' }); +``` + +--- + +### `hideBackground` + +```typescript +function hideBackground(): void; +``` + +隐藏背景 UI (不影响系统状态)。 + +--- + +### `showBackground` + +```typescript +function showBackground(): void; +``` + +显示背景 UI(不影响系统状态)。 + +--- + +### `keep` + +```typescript +function keep(): IKeepController; +``` + +维持背景显示(防闪烁),返回控制器对象: + +```typescript +interface IKeepController { + safelyUnload(): void; // 安全卸载(仅在栈为空时关闭) + unload(): void; // 强制立即卸载 +} +``` + +**示例** + +```typescript +const keeper = mainController.keep(); +// 执行某些操作后... +keeper.safelyUnload(); +``` + +--- + +### `open` + +```typescript +function open( + ui: IGameUI, + vBind: UIProps, + alwaysShow?: boolean +): IUIInstance; +``` + +打开一个新 UI 实例并加入栈中。 + +- **参数** + - `ui`: UI 配置实例 + - `vBind`: 组件 Props + - `alwaysShow`: 是否强制显示(默认 `false`) +- **返回值** + 打开的 UI 实例,可以用于关闭等操作 + +**示例** + +```typescript +import { MyUI } from './myUI'; + +const instance = mainController.open(MyUI, { param: 80 }); +``` + +--- + +### `close` + +```typescript +function close(ui: IUIInstance): void; +``` + +关闭指定 UI 实例(根据当前模式可能影响其他实例)。 + +--- + +### `closeAll` + +```typescript +function closeAll(ui?: IGameUI): void; +``` + +关闭所有或指定类型的所有 UI 实例。 + +- **参数** + - `ui`(可选): 指定要关闭的 UI 类型,不填时表示关闭所有 UI + +--- + +### `lastOnly` + +```typescript +function lastOnly(stack?: boolean): void; +``` + +切换显示模式:仅显示最后一个 UI(可设置为栈模式) + +--- + +### `showAll` + +```typescript +function showAll(stack?: boolean): void; +``` + +切换显示模式:显示所有非隐藏 UI(可设置为栈模式) + +--- + +### `showCustom` + +```typescript +function showCustom(config: IUICustomConfig): void; +``` + +切换显示模式:使用自定义模式(需实现 `IUICustomConfig`),参考[指南](../../guide/ui-system.md#自定义显示模式) + +--- + +### `UIController.getController` + +```typescript +function getController(id: string): UIController | null; +``` + +**静态方法**:根据 ID 获取控制器实例。 + +**示例** + +```typescript +const ctrl = UIController.getController('main'); +``` + +--- + +## 事件说明 + +| 事件名 | 参数类型 | 触发时机 | +| ------- | ------------------------------- | ------------------ | +| `open` | `ui: IGameUI, ins: IUIInstance` | 新 UI 实例被打开时 | +| `close` | `ins: IUIInstance` | UI 实例被关闭时 | + +**事件监听示例** + +```typescript +mainController.on('open', (ui, ins) => { + console.log(`Opened UI: ${ui.name}`); +}); +``` + +--- + +## 总使用示例 + +```typescript +import { BackgroundUI, DialogUI } from './myUI'; +import { mainController } from '@user/client-modules'; + +// 事件监听 +mainController.on('close', ins => { + console.log('UI closed:', ins.ui.name); +}); + +// 设置背景 +mainController.setBackground(BackgroundUI, { color: '#333' }); + +// 打开 UI +const dialogIns = mainController.open(DialogUI, { title: '提示' }); + +// 切换显示模式,仅显示最后一个,启用栈模式 +mainController.lastOnly(true); + +// 关闭 UI +mainController.close(dialogIns); +``` diff --git a/docs/api/motajs-system-ui/UIInstance.md b/docs/api/motajs-system-ui/UIInstance.md new file mode 100644 index 0000000..53c7890 --- /dev/null +++ b/docs/api/motajs-system-ui/UIInstance.md @@ -0,0 +1,121 @@ +# UIInstance API 文档 + +本文档由 `DeepSeek R1` 模型生成并微调。 + +```mermaid +graph LR + UIInstance --> IUIInstance +``` + +_实现 `IUIInstance` 接口_ + +## 类描述 + +`UIInstance` 表示通过 `GameUI` 模板创建的具体 UI 实例,用于管理单个 UI 实例的状态和数据绑定。实现了 `IUIInstance` 接口。 + +--- + +## 属性说明 + +| 属性名 | 类型 | 描述 | +| ------------ | ------------ | -------------------------------------------------------- | +| `key` | `number` | 只读,实例的唯一标识(用于 Vue 的 `key` 属性) | +| `ui` | `IGameUI` | 只读,关联的 UI 配置实例(即创建该实例的 `GameUI` 模板) | +| `vBind` | `UIProps` | 只读,传递给 UI 组件的响应式 Props 对象 | +| `hidden` | `boolean` | 当前实例是否处于隐藏状态 | +| `alwaysShow` | `boolean` | 是否强制保持显示(不受显示模式影响) | + +--- + +## 构造方法 + +```typescript +function constructor( + ui: IGameUI, + vBind: UIProps, + alwaysShow: boolean = false +): UIInstance; +``` + +- **参数** + - `ui`: 关联的 `GameUI` 配置实例 + - `vBind`: 初始化的组件 Props 对象 + - `alwaysShow`: 是否强制保持显示(默认 `false`) + +**注意事项**:一般不需要手动创建 `UIInstance` 实例,请使用 [`UIController.open`](./UIController.md#open) 打开 UI 并创建实例。 + +--- + +## 方法说明 + +### `setVBind` + +```typescript +function setVBind(data: Partial>, merge?: boolean): void; +``` + +更新组件的响应式 Props。 + +- **参数** + - `data`: 需要更新的数据(部分 Props) + - `merge`: 是否与现有数据合并(默认 `true`),若为 `false` 则完全覆盖 + +**示例** + +```typescript +// 合并更新音量值 +instance.setVBind({ volume: 60 }); + +// 覆盖所有 Props +instance.setVBind({ theme: 'dark' }, false); +``` + +--- + +### `hide` + +```typescript +function hide(): void; +``` + +控制实例的显示状态(直接操作 `hidden` 属性)。 + +**示例** + +```typescript +instance.hide(); // 隐藏 UI +setTimeout(() => instance.show(), 1000); // 1 秒后显示 +``` + +--- + +### `show` + +```typescript +function show(): void; +``` + +控制实例的显示状态(直接操作 `hidden` 属性)。 + +**示例** + +```typescript +instance.show(); // 隐藏 UI +setTimeout(() => instance.show(), 1000); // 1 秒后显示 +``` + +--- + +## 总使用示例 + +```typescript +import { myController, MyUI } from './myUI'; + +const myIns = myController.open(MyUI, { title: '警告' }); + +// 动态更新 props +myIns.setVBind({ title: '错误' }); + +// 设置显示状态 +myIns.show(); +``` diff --git a/docs/api/motajs-system/index.md b/docs/api/motajs-system/index.md index 01a8fb3..73ffadf 100644 --- a/docs/api/motajs-system/index.md +++ b/docs/api/motajs-system/index.md @@ -1,3 +1,25 @@ # @motajs/system -目录: +包含两个模块: + +- [Action](../motajs-system-action/index.md) +- [UI](../motajs-system-ui/index.md) + +## 引入示例 + +```ts +import { Action, UI } from '@motajs/system'; + +Action.gameKey.register(...); +const myController = new UI.UIController('my-controller'); +``` + +等效于: + +```ts +import { gameKey } from '@motajs/system-action'; +import { UIController } from '@motajs/system-ui'; + +gameKey.register(...); +const myController = new UIController('my-controller'); +``` diff --git a/packages/system-action/src/hotkey.ts b/packages/system-action/src/hotkey.ts index 2105d0f..52722b8 100644 --- a/packages/system-action/src/hotkey.ts +++ b/packages/system-action/src/hotkey.ts @@ -113,7 +113,7 @@ export class Hotkey extends EventEmitter { * 注册一个按键,id可以包含数字后缀,可以显示为同一个按键操作拥有多个按键可以触发 * @param data 要注册的按键信息 */ - register(data: RegisterHotkeyData) { + register(data: RegisterHotkeyData): this { const d: HotkeyData = { ...data, ctrl: !!data.ctrl, @@ -140,7 +140,7 @@ export class Hotkey extends EventEmitter { * @param func 按键按下时执行的函数 * @param config 按键的配置信息 */ - realize(id: string, func: HotkeyFunc, config?: HotkeyEmitConfig) { + realize(id: string, func: HotkeyFunc, config?: HotkeyEmitConfig): this { const toSet = Object.values(this.data).filter(v => { const split = v.id.split('_'); const last = !isNaN(Number(split.at(-1))); @@ -176,7 +176,7 @@ export class Hotkey extends EventEmitter { * 使用一个symbol作为当前作用域,之后调用{@link realize}所实现的按键功能将会添加至此作用域 * @param symbol 当前作用域的symbol */ - use(symbol: symbol) { + use(symbol: symbol): void { spliceBy(this.scopeStack, symbol); this.scopeStack.push(symbol); this.scope = symbol; @@ -187,7 +187,7 @@ export class Hotkey extends EventEmitter { * 释放一个作用域,释放后作用域将退回至删除的作用域的上一级 * @param symbol 要释放的作用域的symbol */ - dispose(symbol: symbol = this.scopeStack.at(-1) ?? Symbol()) { + dispose(symbol: symbol = this.scopeStack.at(-1) ?? Symbol()): void { for (const key of Object.values(this.data)) { key.emits.delete(symbol); } @@ -202,7 +202,7 @@ export class Hotkey extends EventEmitter { * @param assist 辅助按键,三位二进制数据,从低到高依次为`ctrl` `shift` `alt` * @param emit 是否触发set事件,当且仅当从fromJSON方法调用时为false */ - set(id: string, key: KeyCode, assist: number, emit: boolean = true) { + set(id: string, key: KeyCode, assist: number, emit: boolean = true): void { const { ctrl, shift, alt } = unwarpBinary(assist); const data = this.data[id]; if (!data) return; @@ -269,7 +269,7 @@ export class Hotkey extends EventEmitter { * 检查按键按下情况,如果没有按下则添加 * @param keyCode 按下的按键 */ - private checkPress(keyCode: KeyCode) { + private checkPress(keyCode: KeyCode): void { if (this.pressed.has(keyCode)) return; this.pressed.add(keyCode); this.pressTime.set(keyCode, Date.now()); @@ -280,7 +280,7 @@ export class Hotkey extends EventEmitter { * 当按键松开时,移除相应的按下配置 * @param keyCode 松开的按键 */ - private checkPressEnd(keyCode: KeyCode) { + private checkPressEnd(keyCode: KeyCode): void { if (!this.pressed.has(keyCode)) return; this.pressed.delete(keyCode); this.pressTime.delete(keyCode); @@ -327,6 +327,7 @@ export class Hotkey extends EventEmitter { } return false; } + return false; } /** @@ -334,7 +335,7 @@ export class Hotkey extends EventEmitter { * @param id 组的id * @param name 组的名称 */ - group(id: string, name: string, keys?: RegisterHotkeyData[]) { + group(id: string, name: string, keys?: RegisterHotkeyData[]): this { this.grouping = id; this.groupName[id] = name; this.groups[id] ??= []; @@ -345,14 +346,14 @@ export class Hotkey extends EventEmitter { /** * 启用这个按键控制器 */ - enable() { + enable(): void { this.enabled = true; } /** * 禁用这个按键控制器 */ - disable() { + disable(): void { this.enabled = false; } @@ -360,12 +361,12 @@ export class Hotkey extends EventEmitter { * 在当前作用域下,满足什么条件时触发按键 * @param fn 条件函数 */ - when(fn: () => boolean) { + when(fn: () => boolean): this { this.conditionMap.set(this.scope, fn); return this; } - toJSON() { + toJSON(): string { const res: Record = {}; for (const [key, data] of Object.entries(this.data)) { res[key] = { @@ -376,7 +377,7 @@ export class Hotkey extends EventEmitter { return JSON.stringify(res); } - fromJSON(data: string) { + fromJSON(data: string): void { const json: Record = JSON.parse(data); for (const [key, data] of Object.entries(json)) { this.set(key, data.key, data.assist, false); @@ -393,7 +394,7 @@ export class Hotkey extends EventEmitter { * 根据id获取hotkey实例 * @param id 要获取的hotkey实例的id */ - static get(id: string) { + static get(id: string): Hotkey | undefined { return this.list.find(v => v.id === id); } } @@ -406,7 +407,7 @@ export function unwarpBinary(bin: number): AssistHoykey { }; } -export function checkAssist(bin: number, key: KeyCode) { +export function checkAssist(bin: number, key: KeyCode): boolean { return ( isAssist(key) && !!( @@ -416,7 +417,9 @@ export function checkAssist(bin: number, key: KeyCode) { ); } -export function isAssist(key: KeyCode) { +export function isAssist( + key: KeyCode +): key is KeyCode.Ctrl | KeyCode.Shift | KeyCode.Alt { return key === KeyCode.Ctrl || key === KeyCode.Shift || key === KeyCode.Alt; } diff --git a/packages/system-ui/src/controller.ts b/packages/system-ui/src/controller.ts index 2764dd0..d9ef07c 100644 --- a/packages/system-ui/src/controller.ts +++ b/packages/system-ui/src/controller.ts @@ -74,7 +74,10 @@ export interface IUICustomConfig { update(stack: IUIInstance[]): void; } -interface UIControllerEvent {} +interface UIControllerEvent { + open: [ui: IGameUI, ins: IUIInstance]; + close: [ui: IUIInstance]; +} export class UIController extends EventEmitter @@ -190,6 +193,7 @@ export class UIController break; } this.sysShowBack.value = true; + this.emit('open', ui, ins); return ins; } @@ -230,6 +234,7 @@ export class UIController this.sysShowBack.value = false; } this.keepBack = false; + this.emit('close', ui); } closeAll(ui?: IGameUI): void { diff --git a/packages/system-ui/src/shared.ts b/packages/system-ui/src/shared.ts index 7cf714b..0d62494 100644 --- a/packages/system-ui/src/shared.ts +++ b/packages/system-ui/src/shared.ts @@ -114,6 +114,13 @@ export interface IUIInstance { /** 是否永远保持开启 */ readonly alwaysShow: boolean; + /** + * 设置这个 UI 实例的响应式数据的值 + * @param data 要设置的值 + * @param merge 是将传入的值与原先的值合并(true),还是将当前值覆盖掉原先的值(false),默认合并 + */ + setVBind(data: Partial>, merge?: boolean): void; + /** * 隐藏这个 ui */