nexfep 0.5.5 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README-CN.md +144 -78
- package/README.md +143 -77
- package/frontend/index.d.ts +19 -19
- package/package.json +14 -8
- package/src/Application.d.ts +7 -4
- package/src/Application.js +4 -3
- package/src/Icon.d.ts +19 -0
- package/src/Icon.js +36 -0
- package/src/Logger.d.ts +1 -0
- package/src/Logger.js +5 -14
- package/src/SingleInstance.d.ts +2 -2
- package/src/SingleInstance.js +2 -2
- package/src/Tray.d.ts +4 -3
- package/src/Tray.js +3 -3
- package/src/WindowManager.d.ts +18 -2
- package/src/WindowManager.js +68 -28
package/README-CN.md
CHANGED
|
@@ -41,7 +41,10 @@ import { Application } from "nexfep";
|
|
|
41
41
|
|
|
42
42
|
const app = new Application();
|
|
43
43
|
|
|
44
|
-
const window = await app.windows.createWindow(
|
|
44
|
+
const window = await app.windows.createWindow({
|
|
45
|
+
visible: true,
|
|
46
|
+
decoration: false,
|
|
47
|
+
});
|
|
45
48
|
|
|
46
49
|
await window.loadHTML("<h1 nexfep-area-drag>Hello Nexfep!</h1>");
|
|
47
50
|
```
|
|
@@ -81,11 +84,37 @@ const app = new Application({ LogFilePath: "./app.log" });
|
|
|
81
84
|
- `createLocker(appName)` — 创建应用实例锁,防止多个实例运行
|
|
82
85
|
- `exit()` — 退出应用
|
|
83
86
|
|
|
87
|
+
### Icon
|
|
88
|
+
|
|
89
|
+
`Icon` 用于表示图片资源,可被用作窗口图标、托盘图标等。
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
import { Icon } from "nexfep";
|
|
93
|
+
|
|
94
|
+
// 从文件路径创建
|
|
95
|
+
const icon = Icon.from("./icon.png");
|
|
96
|
+
|
|
97
|
+
// 从 Buffer 或 Uint8Array 创建
|
|
98
|
+
const icon = Icon.from(buffer);
|
|
99
|
+
const icon = Icon.from(uint8Array);
|
|
100
|
+
|
|
101
|
+
// 从包含 data/width/height 的对象创建
|
|
102
|
+
const icon = Icon.from({ data: buffer, width: 64, height: 64 });
|
|
103
|
+
const icon = Icon.from({ data: uint8Array, width: 64, height: 64 });
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
**静态方法**
|
|
107
|
+
|
|
108
|
+
| 方法 | 参数 | 返回值 | 说明 |
|
|
109
|
+
| ------------------ | ----------------------------------------------------------------------------------------- | ------ | ---------------- |
|
|
110
|
+
| `Icon.from(input)` | `string` \| `Buffer` \| `Uint8Array` \| `{ data: Uint8Array \| Buffer, width?, height? }` | `Icon` | 创建一个图标实例 |
|
|
111
|
+
|
|
84
112
|
### Logger
|
|
85
113
|
|
|
86
114
|
Logger 支持文件输出和彩色控制台输出,可通过 `app.logger` 访问。
|
|
87
115
|
|
|
88
116
|
```typescript
|
|
117
|
+
app.logger.clear();
|
|
89
118
|
app.logger.log("Hello World");
|
|
90
119
|
app.logger.error("发生错误");
|
|
91
120
|
app.logger.warn("警告信息");
|
|
@@ -95,13 +124,14 @@ app.logger.debug("调试信息");
|
|
|
95
124
|
|
|
96
125
|
**方法**
|
|
97
126
|
|
|
98
|
-
| 方法 | 说明
|
|
99
|
-
| ---------------- |
|
|
100
|
-
| `
|
|
101
|
-
| `
|
|
102
|
-
| `
|
|
103
|
-
| `
|
|
104
|
-
| `
|
|
127
|
+
| 方法 | 说明 |
|
|
128
|
+
| ---------------- | ------------------------------------------------- |
|
|
129
|
+
| `clear()` | 清空日志文件(仅在设置了`LogFilePath`参数时生效) |
|
|
130
|
+
| `log(message)` | 记录日志 |
|
|
131
|
+
| `error(message)` | 记录错误日志(红色) |
|
|
132
|
+
| `warn(message)` | 记录警告日志(黄色) |
|
|
133
|
+
| `info(message)` | 记录提示日志(蓝色) |
|
|
134
|
+
| `debug(message)` | 记录调试日志(灰色) |
|
|
105
135
|
|
|
106
136
|
每个方法接受字符串或字符串数组作为参数。
|
|
107
137
|
|
|
@@ -118,15 +148,22 @@ const locker = app.createLocker("my-app");
|
|
|
118
148
|
try {
|
|
119
149
|
// 尝试获取应用实例锁
|
|
120
150
|
await locker.lock();
|
|
151
|
+
// 也可以带参数获取锁,例如:
|
|
152
|
+
// await locker.lock(process.argv[2]);
|
|
121
153
|
} catch {
|
|
122
154
|
// 应用实例已存在,退出应用
|
|
123
155
|
app.exit();
|
|
124
156
|
}
|
|
125
|
-
//
|
|
126
|
-
locker.whenLost(() => {
|
|
157
|
+
// 你可以在其它实例抢锁时聚焦当前实例
|
|
158
|
+
locker.whenLost((data) => {
|
|
127
159
|
if (!win.isFocused()) {
|
|
128
160
|
win.focus();
|
|
129
161
|
}
|
|
162
|
+
// 如果对方实例在获取锁时传递了参数,你可以使用它来执行特定操作
|
|
163
|
+
// 若没有传递,data 字段将会是 null
|
|
164
|
+
if (data) {
|
|
165
|
+
console.log("传递了参数:", data);
|
|
166
|
+
}
|
|
130
167
|
});
|
|
131
168
|
// 释放锁
|
|
132
169
|
locker.unlock();
|
|
@@ -136,7 +173,7 @@ locker.unlock();
|
|
|
136
173
|
|
|
137
174
|
| 方法 | 描述 |
|
|
138
175
|
| -------------------- | ------------------------ |
|
|
139
|
-
| `lock()`
|
|
176
|
+
| `lock(data?)` | 尝试获取应用实例锁 |
|
|
140
177
|
| `whenLost(callback)` | 当其它实例抢锁时执行回调 |
|
|
141
178
|
| `unlock()` | 释放锁 |
|
|
142
179
|
|
|
@@ -145,16 +182,14 @@ locker.unlock();
|
|
|
145
182
|
通过 `app.createTray()` 创建和管理系统托盘图标及右键菜单。
|
|
146
183
|
|
|
147
184
|
```typescript
|
|
148
|
-
import {
|
|
185
|
+
import { Icon } from "nexfep";
|
|
186
|
+
|
|
187
|
+
const icon = Icon.from("./icon.png");
|
|
149
188
|
|
|
150
189
|
const tray = app.createTray({
|
|
151
190
|
id: "my-tray",
|
|
152
191
|
tooltip: "我的应用",
|
|
153
|
-
icon:
|
|
154
|
-
data: readFileSync("./icon.png"),
|
|
155
|
-
width: 32,
|
|
156
|
-
height: 32,
|
|
157
|
-
},
|
|
192
|
+
icon: icon, // Icon 实例
|
|
158
193
|
menuItems: [
|
|
159
194
|
{ id: "show", label: "显示窗口" },
|
|
160
195
|
{ id: "quit", label: "退出" },
|
|
@@ -162,29 +197,19 @@ const tray = app.createTray({
|
|
|
162
197
|
});
|
|
163
198
|
```
|
|
164
199
|
|
|
165
|
-
`icon` 字段接受 `TrayIconImage` 对象:
|
|
166
|
-
|
|
167
|
-
```typescript
|
|
168
|
-
interface TrayIconImage {
|
|
169
|
-
data: Buffer; // 图片二进制数据
|
|
170
|
-
width?: number; // 可选宽度
|
|
171
|
-
height?: number; // 可选高度
|
|
172
|
-
}
|
|
173
|
-
```
|
|
174
|
-
|
|
175
200
|
**方法**
|
|
176
201
|
|
|
177
|
-
| 方法
|
|
178
|
-
|
|
|
179
|
-
| `addMenuItem(item)`
|
|
180
|
-
| `removeMenuItem(id)`
|
|
181
|
-
| `setMenuItems(items)`
|
|
182
|
-
| `setIcon(icon
|
|
183
|
-
| `setTooltip(tooltip)`
|
|
184
|
-
| `on(event, callback)`
|
|
185
|
-
| `show()`
|
|
186
|
-
| `hide()`
|
|
187
|
-
| `destroy()`
|
|
202
|
+
| 方法 | 描述 |
|
|
203
|
+
| --------------------- | ------------------------------ |
|
|
204
|
+
| `addMenuItem(item)` | 添加菜单项 |
|
|
205
|
+
| `removeMenuItem(id)` | 按 ID 删除菜单项 |
|
|
206
|
+
| `setMenuItems(items)` | 替换所有菜单项 |
|
|
207
|
+
| `setIcon(icon)` | 更改托盘图标,接受 `Icon` 实例 |
|
|
208
|
+
| `setTooltip(tooltip)` | 更改悬停提示文本 |
|
|
209
|
+
| `on(event, callback)` | 监听托盘事件(如 `'click'`) |
|
|
210
|
+
| `show()` | 显示托盘图标 |
|
|
211
|
+
| `hide()` | 隐藏托盘图标 |
|
|
212
|
+
| `destroy()` | 销毁托盘图标 |
|
|
188
213
|
|
|
189
214
|
```typescript
|
|
190
215
|
tray.on("click", () => {
|
|
@@ -199,13 +224,14 @@ tray.setTooltip("Nexfep 应用");
|
|
|
199
224
|
通过 `app.utils.notify()` 发送桌面通知。
|
|
200
225
|
|
|
201
226
|
```typescript
|
|
202
|
-
const notification = app.utils.notify("标题", "通知内容");
|
|
227
|
+
const notification = app.utils.notify("标题", { body: "通知内容" });
|
|
203
228
|
```
|
|
204
229
|
|
|
205
230
|
**参数**
|
|
206
231
|
|
|
207
232
|
- `title` — 通知标题
|
|
208
|
-
- `
|
|
233
|
+
- `options`(可选)— 配置对象
|
|
234
|
+
- `body` — 通知正文
|
|
209
235
|
|
|
210
236
|
### 窗口池
|
|
211
237
|
|
|
@@ -218,13 +244,38 @@ const pool = app.windows;
|
|
|
218
244
|
### 窗口创建
|
|
219
245
|
|
|
220
246
|
```typescript
|
|
221
|
-
|
|
247
|
+
// 不传参数使用全部默认值
|
|
248
|
+
const win = await pool.createWindow();
|
|
249
|
+
|
|
250
|
+
// 传入部分参数
|
|
251
|
+
const win = await pool.createWindow({
|
|
252
|
+
visible: true,
|
|
253
|
+
title: "我的应用",
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
// 全部参数
|
|
257
|
+
const win = await pool.createWindow({
|
|
258
|
+
visible: true, // 是否立即显示,默认 true
|
|
259
|
+
decoration: true, // 是否使用系统装饰,默认 true
|
|
260
|
+
title: "我的应用", // 窗口标题,默认 "Nexfep Window"
|
|
261
|
+
icon: iconInstance, // 窗口图标,Icon 实例,可选
|
|
262
|
+
resizable: true, // 是否可调整大小,默认 true
|
|
263
|
+
width: 800, // 窗口宽度,默认 800
|
|
264
|
+
height: 600, // 窗口高度,默认 600
|
|
265
|
+
});
|
|
222
266
|
```
|
|
223
267
|
|
|
224
268
|
**参数说明**
|
|
225
269
|
|
|
226
|
-
|
|
227
|
-
|
|
270
|
+
| 选项 | 类型 | 默认值 | 说明 |
|
|
271
|
+
| ------------ | --------- | ----------------- | ------------------------------------------------------------------- |
|
|
272
|
+
| `visible` | `boolean` | `true` | 是否立即显示窗口 |
|
|
273
|
+
| `decoration` | `boolean` | `true` | 是否使用系统窗口装饰。设为 `false` 时,窗口无边框,需要自定义标题栏 |
|
|
274
|
+
| `title` | `string` | `"Nexfep Window"` | 窗口标题 |
|
|
275
|
+
| `icon` | `Icon` | 无 | 窗口图标 |
|
|
276
|
+
| `resizable` | `boolean` | `true` | 窗口是否可调整大小 |
|
|
277
|
+
| `width` | `number` | `800` | 窗口宽度(像素) |
|
|
278
|
+
| `height` | `number` | `600` | 窗口高度(像素) |
|
|
228
279
|
|
|
229
280
|
### 窗口操作
|
|
230
281
|
|
|
@@ -360,6 +411,12 @@ window.addEventListener("user-login", (event) => {
|
|
|
360
411
|
});
|
|
361
412
|
```
|
|
362
413
|
|
|
414
|
+
特别地,主进程可以通过 `pool.broadcast` 向所有打开的窗口发送事件,参数与页面中的 `window.broadcast` 相同:
|
|
415
|
+
|
|
416
|
+
```typescript
|
|
417
|
+
pool.broadcast("user-login", { userId: 123 });
|
|
418
|
+
```
|
|
419
|
+
|
|
363
420
|
#### 定向发送
|
|
364
421
|
|
|
365
422
|
通过 `window.tell` 向指定 ID 的窗口发送消息:
|
|
@@ -388,6 +445,12 @@ window.addEventListener("custom-message", (event) => {
|
|
|
388
445
|
console.log("当前窗口 ID:", window.id);
|
|
389
446
|
```
|
|
390
447
|
|
|
448
|
+
主进程也可通过 `win.tell` 向该窗口发送消息:
|
|
449
|
+
|
|
450
|
+
```typescript
|
|
451
|
+
win.tell("custom-message", { text: `你好,窗口 ${win.id}` });
|
|
452
|
+
```
|
|
453
|
+
|
|
391
454
|
### 自定义消息
|
|
392
455
|
|
|
393
456
|
#### 发送消息
|
|
@@ -586,44 +649,47 @@ nexfep build -u 7
|
|
|
586
649
|
|
|
587
650
|
### WindowPool
|
|
588
651
|
|
|
589
|
-
| 方法/属性
|
|
590
|
-
|
|
|
591
|
-
| `createWindow(
|
|
592
|
-
| `handle(event, callback)`
|
|
593
|
-
| `unhandle(event, callback)`
|
|
594
|
-
| `global`
|
|
595
|
-
| `closeWindow(window)`
|
|
596
|
-
| `onCustomMessage`
|
|
652
|
+
| 方法/属性 | 参数 | 返回值 | 说明 |
|
|
653
|
+
| --------------------------- | ----------------------------------------------- | ----------------- | ------------------------ |
|
|
654
|
+
| `createWindow(options?)` | 可选参数,见上文窗口创建参数说明 | Promise\<Window> | 创建并获取一个窗口 |
|
|
655
|
+
| `handle(event, callback)` | `event`: string, `callback`: (data: any) => any | 无 | 监听指定事件 |
|
|
656
|
+
| `unhandle(event, callback)` | `event`: string, `callback`: (data: any) => any | 无 | 取消监听指定事件 |
|
|
657
|
+
| `global` | / | Map\<string, any> | 全局变量 Map |
|
|
658
|
+
| `closeWindow(window)` | `window`: Window | Promise\<void> | 关闭指定窗口并回收至池中 |
|
|
659
|
+
| `onCustomMessage` | `(window: Window, data: string) => void` | 无 | 自定义消息回调函数 |
|
|
597
660
|
|
|
598
661
|
### Window
|
|
599
662
|
|
|
600
|
-
| 方法/属性
|
|
601
|
-
|
|
|
602
|
-
| `loadURL(url)`
|
|
603
|
-
| `loadHTML(html)`
|
|
604
|
-
| `show()`
|
|
605
|
-
| `hide()`
|
|
606
|
-
| `maximize()`
|
|
607
|
-
| `unMaximize()`
|
|
608
|
-
| `minimize()`
|
|
609
|
-
| `unMinimize()`
|
|
610
|
-
| `close()`
|
|
611
|
-
| `setTitle(title)`
|
|
612
|
-
| `setDecorated(isDecorated)`
|
|
613
|
-
| `
|
|
614
|
-
| `
|
|
615
|
-
| `
|
|
616
|
-
| `
|
|
617
|
-
| `
|
|
618
|
-
| `
|
|
619
|
-
| `
|
|
620
|
-
| `
|
|
621
|
-
| `
|
|
622
|
-
| `
|
|
623
|
-
| `
|
|
624
|
-
| `
|
|
625
|
-
| `
|
|
626
|
-
| `
|
|
663
|
+
| 方法/属性 | 参数 | 返回值 | 说明 |
|
|
664
|
+
| --------------------------------------- | ----------------------------------------------------------------- | --------------------------------- | ------------------------------------------------------------- |
|
|
665
|
+
| `loadURL(url)` | `url`: string — 要加载的网页地址 | Promise\<void> | 加载指定 URL |
|
|
666
|
+
| `loadHTML(html)` | `html`: string — HTML 字符串 | Promise\<void> | 加载指定 HTML 内容 |
|
|
667
|
+
| `show()` | 无 | void | 显示窗口 |
|
|
668
|
+
| `hide()` | 无 | void | 隐藏窗口 |
|
|
669
|
+
| `maximize()` | 无 | void | 最大化窗口 |
|
|
670
|
+
| `unMaximize()` | 无 | void | 还原窗口(取消最大化) |
|
|
671
|
+
| `minimize()` | 无 | void | 最小化窗口 |
|
|
672
|
+
| `unMinimize()` | 无 | void | 还原窗口(取消最小化) |
|
|
673
|
+
| `close()` | 无 | void | 关闭窗口并回收至池中 |
|
|
674
|
+
| `setTitle(title)` | `title`: string | void | 设置窗口标题 |
|
|
675
|
+
| `setDecorated(isDecorated)` | `isDecorated`: boolean | void | 设置窗口是否带边框和标题栏 |
|
|
676
|
+
| `setResizable(resizable)` | `resizable`: boolean | void | 设置窗口是否可调整大小 |
|
|
677
|
+
| `setLevel(level)` | `level`: `-1` \| `0` \| `1` | void | 设置窗口层级:-1=置底,0=正常,1=置顶 |
|
|
678
|
+
| `setFullScreen(isFullScreen, options?)` | `isFullScreen`: `boolean`, `options?`: `{ borderless?: boolean }` | void | 设置全屏模式。`borderless: true` 为无边框全屏,否则为独占全屏 |
|
|
679
|
+
| `setIcon(icon)` | `icon`: `Icon` | void | 设置窗口图标 |
|
|
680
|
+
| `setSize(width, height)` | `width`: number, `height`: number | void | 设置窗口尺寸(像素) |
|
|
681
|
+
| `getSize()` | 无 | { width: number, height: number } | 获取窗口尺寸(像素) |
|
|
682
|
+
| `setPosition(x, y)` | `x`: number, `y`: number | void | 设置窗口位置(像素) |
|
|
683
|
+
| `getPosition()` | 无 | { x: number, y: number } | 获取窗口位置(像素) |
|
|
684
|
+
| `focus()` | 无 | void | 窗口获取焦点 |
|
|
685
|
+
| `isFocused()` | 无 | boolean | 是否有焦点 |
|
|
686
|
+
| `isMaximized()` | 无 | boolean | 是否最大化 |
|
|
687
|
+
| `isMinimized()` | 无 | boolean | 是否最小化 |
|
|
688
|
+
| `toggleMaximize()` | 无 | void | 切换最大化状态 |
|
|
689
|
+
| `toggleMinimize()` | 无 | void | 切换最小化状态 |
|
|
690
|
+
| `openDevTools()` | 无 | void | 打开开发者工具 |
|
|
691
|
+
| `closeDevTools()` | 无 | void | 关闭开发者工具 |
|
|
692
|
+
| `id` | 无 | number | 窗口唯一标识,自增编号 |
|
|
627
693
|
|
|
628
694
|
## 开发
|
|
629
695
|
|