docs: @motajs/system 文档

This commit is contained in:
unanmed 2025-04-03 15:22:25 +08:00
parent 0df879298e
commit 83f460de65
9 changed files with 1089 additions and 18 deletions

View File

@ -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<string, HotkeyData>` | 存储所有已注册的按键配置 |
| `keyMap` | `Map<KeyCode, HotkeyData[]>` | 按键代码到配置的映射(支持多键绑定同一操作) |
| `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();
});
```
:::

View File

@ -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');
```

View File

@ -0,0 +1,97 @@
# GameUI API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
```mermaid
graph LR
GameUI --> IGameUI
```
_实现 `IGameUI` 接口_
## 接口描述
`IGameUI<C>` 是 UI 系统的核心接口,定义了 UI 实例的基础结构和静态操作方法。
---
## 属性说明
| 属性名 | 类型 | 描述 |
| -------------- | ---------------------------------- | ------------------------------------------------------------------- |
| `name` | `string` | 只读UI 的唯一标识名称 |
| `component` | `C extends UIComponent` | 只读,关联的 Vue 组件实例 |
| `list`(静态) | `Map<string, GameUI<UIComponent>>` | 静态属性,存储所有已注册的 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<T extends UIComponent>(id: string): GameUI<T> | null;
```
**静态方法**:根据 UI 名称从静态列表获取实例。
- **参数**
- `id`: UI 的唯一标识名称
- **返回值**
匹配的 `GameUI` 实例,未找到时返回 `null`
**示例**
```typescript
// 获取名为 "home" 的 UI 实例
const ui = GameUI.get<MyComponent>('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 () => (
<container>
<text text="自定义组件 UI" />
</container>
);
});
// 定义 UI 实例
export const MyUI = new GameUI('my-ui', MyCom);
```

View File

@ -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<IUIInstance>` | 背景 UI 实例的响应式引用 |
| `showBack` | `ComputedRef<boolean>` | 当前是否显示背景(用户设置与系统状态共同决定) |
| `active`(只读) | `boolean` | 系统是否显示背景 UI等价于 `sysShowBack.value` |
| `controllers`(静态) | `Map<string, UIController>` | 静态属性,存储所有已创建的控制器实例,键为 `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 () => <container>{myController.render()}</container>;
});
```
---
### `setBackground`
```typescript
function setBackground<T extends UIComponent>(
back: IGameUI<T>,
vBind: UIProps<T>
): 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<T extends UIComponent>(
ui: IGameUI<T>,
vBind: UIProps<T>,
alwaysShow?: boolean
): IUIInstance<T>;
```
打开一个新 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);
```

View File

@ -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<C>` | 只读,关联的 UI 配置实例(即创建该实例的 `GameUI` 模板) |
| `vBind` | `UIProps<C>` | 只读,传递给 UI 组件的响应式 Props 对象 |
| `hidden` | `boolean` | 当前实例是否处于隐藏状态 |
| `alwaysShow` | `boolean` | 是否强制保持显示(不受显示模式影响) |
---
## 构造方法
```typescript
function constructor(
ui: IGameUI<C>,
vBind: UIProps<C>,
alwaysShow: boolean = false
): UIInstance;
```
- **参数**
- `ui`: 关联的 `GameUI` 配置实例
- `vBind`: 初始化的组件 Props 对象
- `alwaysShow`: 是否强制保持显示(默认 `false`
**注意事项**:一般不需要手动创建 `UIInstance` 实例,请使用 [`UIController.open`](./UIController.md#open) 打开 UI 并创建实例。
---
## 方法说明
### `setVBind`
```typescript
function setVBind(data: Partial<Props<C>>, 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();
```

View File

@ -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');
```

View File

@ -113,7 +113,7 @@ export class Hotkey extends EventEmitter<HotkeyEvent> {
* 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<HotkeyEvent> {
* @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<HotkeyEvent> {
* 使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<HotkeyEvent> {
* 退
* @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<HotkeyEvent> {
* @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<HotkeyEvent> {
*
* @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<HotkeyEvent> {
*
* @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<HotkeyEvent> {
}
return false;
}
return false;
}
/**
@ -334,7 +335,7 @@ export class Hotkey extends EventEmitter<HotkeyEvent> {
* @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<HotkeyEvent> {
/**
*
*/
enable() {
enable(): void {
this.enabled = true;
}
/**
*
*/
disable() {
disable(): void {
this.enabled = false;
}
@ -360,12 +361,12 @@ export class Hotkey extends EventEmitter<HotkeyEvent> {
*
* @param fn
*/
when(fn: () => boolean) {
when(fn: () => boolean): this {
this.conditionMap.set(this.scope, fn);
return this;
}
toJSON() {
toJSON(): string {
const res: Record<string, HotkeyJSON> = {};
for (const [key, data] of Object.entries(this.data)) {
res[key] = {
@ -376,7 +377,7 @@ export class Hotkey extends EventEmitter<HotkeyEvent> {
return JSON.stringify(res);
}
fromJSON(data: string) {
fromJSON(data: string): void {
const json: Record<string, HotkeyJSON> = 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<HotkeyEvent> {
* 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;
}

View File

@ -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<UIControllerEvent>
@ -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 {

View File

@ -114,6 +114,13 @@ export interface IUIInstance<C extends UIComponent = UIComponent> {
/** 是否永远保持开启 */
readonly alwaysShow: boolean;
/**
* UI
* @param data
* @param merge truefalse
*/
setVBind(data: Partial<Props<C>>, merge?: boolean): void;
/**
* ui
*/