@nsshunt/stsui 1.11.46 → 1.11.48

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/dist/index.cjs CHANGED
@@ -1,559 +1,495 @@
1
- "use strict";
2
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const EventEmitter = require("node:events");
4
- const blessed = require("blessed");
5
- class MenuBar {
6
- listb = null;
7
- // options := { screen: <blessed screen>, top: <bool>, menuitems: [ { text: <string>, key: <string>, cb: <call back func> } ] }
8
- constructor(screen, options) {
9
- const compoptions = {
10
- parent: screen,
11
- left: 0,
12
- right: 0,
13
- height: 1,
14
- width: "shrink",
15
- mouse: true,
16
- keys: true,
17
- autoCommandKeys: true,
18
- scrollable: true,
19
- style: {
20
- fg: "yellow",
21
- bg: "blue",
22
- item: {
23
- hover: {
24
- fg: "white",
25
- bg: "green"
26
- }
27
- },
28
- selected: {
29
- fg: "black",
30
- bg: "yellow"
31
- }
32
- }
33
- };
34
- if (options.top === true) {
35
- compoptions.top = 0;
36
- } else {
37
- compoptions.bottom = 0;
38
- }
39
- compoptions.commands = {};
40
- options.menuitems.forEach((menuItem) => {
41
- if (compoptions.commands) {
42
- compoptions.commands[menuItem.text] = {
43
- keys: [menuItem.key],
44
- callback: menuItem.cb
45
- };
46
- }
47
- });
48
- this.listb = blessed.listbar(compoptions);
49
- }
50
- get listbar() {
51
- return this.listb;
52
- }
53
- }
54
- class STSUIFrame extends EventEmitter {
55
- //export class STSUIFrame {
56
- uiBoxes = {};
57
- // { box: <<blessed box>>, boxHeader: <<blessed box>> }
58
- screen = null;
59
- #cursor = 0;
60
- // panel index with the complete model data.
61
- #renderPanelFn = null;
62
- screenHeaderText = "...";
63
- minRows = 1;
64
- minCols = 1;
65
- minWidth = 40;
66
- minHeight = 7;
67
- #cursorInfo = null;
68
- sortInfo = null;
69
- // Current sort mode UI box control
70
- screenHeader = null;
71
- uidata;
72
- /**
73
- *
74
- * @param {*} data The screen layout data. Schema: { title: <str>,
75
- * grid: { rows: <int>, cols: <int> },
76
- * panels: [ { id: <str>, pos: { row: <int>, col: <int>, rowSpan: <int>, colSpan: <int> },
77
- * template: <handlebars func>, widgets: { [ { <prop_name>: <blessed widget> } ] } } ] }
78
- */
79
- constructor(data, renderPanelFn = null) {
80
- super();
81
- this.uidata = data;
82
- this.#renderPanelFn = renderPanelFn;
83
- this.SetupUI();
84
- }
85
- get blessed() {
86
- return blessed;
87
- }
88
- /**
89
- *
90
- * @param {number} position The index (0 based) for the panel item to be calculated
91
- * @returns object with top, left, width and height correctly set
92
- */
93
- #CalcBoxPos = (panel) => {
94
- if (!this.screen) return null;
95
- if (!panel.pos) return null;
96
- let screenHeight = this.screen.height;
97
- if (this.uidata.menu !== null) {
98
- screenHeight -= this.uidata.menu.length;
99
- }
100
- const screenWidth = this.screen.width;
101
- const rows = this.uidata.grid.rows;
102
- const cols = this.uidata.grid.cols;
103
- const pos = panel.pos;
104
- const colWidth = Math.floor(screenWidth / cols);
105
- const rowHeight = Math.floor(screenHeight / rows);
106
- let topoffset = 0;
107
- if (this.uidata.menu !== null) {
108
- for (const [, value] of Object.entries(this.uidata.menu)) {
109
- if (value.top === true) {
110
- topoffset = 1;
111
- break;
112
- }
113
- }
114
- }
115
- const boxPos = {
116
- top: pos.row * rowHeight + topoffset,
117
- left: pos.col * colWidth,
118
- width: colWidth * pos.colSpan,
119
- height: rowHeight * pos.rowSpan
120
- };
121
- if (pos.col + pos.colSpan === cols) {
122
- boxPos.width = screenWidth - pos.col * colWidth;
123
- }
124
- if (pos.row + pos.rowSpan === rows) {
125
- boxPos.height = screenHeight - pos.row * rowHeight;
126
- }
127
- return boxPos;
128
- };
129
- #UpdateUIBoxPos = (panel, uiBox) => {
130
- const pos = this.#CalcBoxPos(panel);
131
- if (!pos) {
132
- return;
133
- }
134
- uiBox.box.top = pos.top;
135
- uiBox.box.left = pos.left;
136
- uiBox.box.width = pos.width;
137
- uiBox.box.height = pos.height;
138
- uiBox.boxHeader.top = pos.top;
139
- uiBox.boxHeader.left = pos.left + 2;
140
- if (typeof panel.widgets !== "undefined" && panel.widgets !== null) {
141
- for (const [, value] of Object.entries(panel.widgets)) {
142
- if (value.widget === "log") {
143
- const widget = uiBox.box.get(value.widget);
144
- if (widget.position.top >= uiBox.box.height - 4) {
145
- widget.position.top = uiBox.box.height - 4;
146
- } else {
147
- if (value.options.top) {
148
- widget.position.top = value.options.top;
149
- }
150
- }
151
- }
152
- }
153
- }
154
- };
155
- /**
156
- * ReSize the grid layout
157
- */
158
- #ReSize = () => {
159
- for (const [, value] of Object.entries(this.uiBoxes)) {
160
- this.#UpdateUIBoxPos(value.box.get("panel"), value);
161
- }
162
- };
163
- #UpdatePanelPosition = (panel, row, col, uiBox) => {
164
- panel.pos = { row, col, rowSpan: 1, colSpan: 1 };
165
- this.#UpdateUIBoxPos(panel, uiBox);
166
- uiBox.boxHeader.setContent(panel.panelHeader);
167
- };
168
- /*
169
- ClickEx(panel: any) {
170
- //@@ override in sub-class
171
- }
172
- */
173
- CreateWidget = (widgetName, widgetoptions) => {
174
- const widget = blessed[widgetName].call(this, widgetoptions);
175
- return widget;
176
- };
177
- CreateWidgetEx(widgetName, widgetoptions) {
178
- const widget = blessed[widgetName].call(this, widgetoptions);
179
- return widget;
180
- }
181
- SetupWidgets = (box, panel, parent, blessedWidgets) => {
182
- for (const [blessedWidgetKey, blessedWidgetDetails] of Object.entries(blessedWidgets)) {
183
- const widgetoptions = { ...blessedWidgetDetails.options };
184
- if (box) {
185
- if (widgetoptions.top && widgetoptions.top >= box.height - 3) {
186
- widgetoptions.top = box.height - 4;
187
- }
188
- }
189
- const widget = blessed[blessedWidgetDetails.widget].call(this, widgetoptions);
190
- widget.set("id", blessedWidgetDetails.id);
191
- parent.append(widget);
192
- parent.set(blessedWidgetDetails.widget, widget);
193
- parent.set(`__blessedWidgetKey__${blessedWidgetKey}`, widget);
194
- if (blessedWidgetDetails.events) {
195
- for (const [eventName, eventDetails] of Object.entries(blessedWidgetDetails.events)) {
196
- widget.on(eventName, () => {
197
- eventDetails.cb(panel, widget, parent);
198
- });
199
- }
200
- }
201
- this.emit("widgetsetup", box, panel, widget);
202
- if (blessedWidgetDetails.children) {
203
- this.SetupWidgets(null, panel, widget, blessedWidgetDetails.children);
204
- }
205
- }
206
- };
207
- /**
208
- *
209
- * Setup all panels
210
- */
211
- #SetupPanels() {
212
- if (!this.screen) {
213
- return;
214
- }
215
- const panelKeys = Object.keys(this.uidata.panels);
216
- const uiBoxIds = Object.keys(this.uiBoxes);
217
- for (let i = 0; i < uiBoxIds.length; i++) {
218
- if (typeof this.uidata.panels[uiBoxIds[i]] === "undefined") {
219
- let uiBox = this.uiBoxes[uiBoxIds[i]];
220
- if (typeof uiBox !== "undefined") {
221
- this.emit("preremovebox", uiBox.box, uiBox.box.get("panel"));
222
- this.screen.remove(uiBox.boxHeader);
223
- this.screen.remove(uiBox.box);
224
- uiBox = null;
225
- delete this.uiBoxes[uiBoxIds[i]];
226
- }
227
- }
228
- }
229
- const touched = {};
230
- for (let i = 0; i < this.uidata.grid.cols * this.uidata.grid.rows; i++) {
231
- const gridPos = this.#cursor + i;
232
- const col = i % this.uidata.grid.cols;
233
- const row = Math.floor(i / this.uidata.grid.cols);
234
- const panel = this.uidata.panels[panelKeys[gridPos]];
235
- if (typeof panel !== "undefined") {
236
- if (typeof this.uiBoxes[panel.id] === "undefined") {
237
- panel.pos = { row, col, rowSpan: 1, colSpan: 1 };
238
- const calculatedBoxPos = this.#CalcBoxPos(panel);
239
- if (!calculatedBoxPos) {
240
- return;
241
- }
242
- const { top, left, width, height } = this.#CalcBoxPos(panel);
243
- const box = blessed.box({
244
- parent: this.screen,
245
- top,
246
- left,
247
- width,
248
- height,
249
- style: {
250
- bg: "#101010",
251
- fg: "white"
252
- },
253
- border: {
254
- type: "line"
255
- },
256
- keys: false,
257
- // Do not allow default key handling for this box
258
- tags: true
259
- // Allow style in-line tags such as bolt, italics, etc.
260
- });
261
- const boxHeader = blessed.box({
262
- parent: this.screen,
263
- top,
264
- left: left + 2,
265
- width: "shrink",
266
- height: 1,
267
- style: {
268
- bg: "gray",
269
- fg: "white"
270
- },
271
- keys: false,
272
- // Do not allow default key handling for this box
273
- mouse: false,
274
- content: panel.panelHeader,
275
- tags: true
276
- // Allow style in-line tags such as bold, italics, etc.
277
- });
278
- this.uiBoxes[panel.id] = { box, boxHeader };
279
- boxHeader.setIndex(-1);
280
- box.on("click", () => {
281
- this.emit("click", box.get("panel"));
282
- });
283
- box.on("destroy", () => {
284
- this.emit("destroy", box, panel);
285
- });
286
- box.on("remove", () => {
287
- this.emit("remove", box, panel);
288
- });
289
- box.on("detach", () => {
290
- this.emit("detach", box, panel);
291
- });
292
- box.set("panel", panel);
293
- this.uiBoxes[panel.id].box = box;
294
- this.emit("boxsetup", box, panel);
295
- if (typeof panel.widgets !== "undefined" && panel.widgets !== null) {
296
- this.SetupWidgets(box, panel, box, panel.widgets);
297
- this.emit("widgetsetupcomplete", box, panel, panel.widgets);
298
- }
299
- touched[panel.id] = true;
300
- } else {
301
- this.#UpdatePanelPosition(panel, row, col, this.uiBoxes[panel.id]);
302
- touched[panel.id] = true;
303
- }
304
- if (this.#renderPanelFn) {
305
- this.#renderPanelFn(this.uiBoxes[panel.id].box, panel);
306
- }
307
- }
308
- }
309
- for (const [key] of Object.entries(this.uiBoxes)) {
310
- const box = this.uiBoxes[key].box;
311
- const panel = box.get("panel");
312
- if (typeof touched[key] === "undefined") {
313
- box.hide();
314
- this.uiBoxes[key].boxHeader.hide();
315
- this.emit("boxhide", this.uiBoxes[key].box, panel, panel.widgets);
316
- } else {
317
- box.show();
318
- this.uiBoxes[key].boxHeader.show();
319
- this.emit("boxshow", this.uiBoxes[key].box, panel, panel.widgets);
320
- }
321
- }
322
- }
323
- get gridData() {
324
- return this.uidata;
325
- }
326
- set gridData(gridData) {
327
- this.uidata = gridData;
328
- this.#SetupPanels();
329
- this.UpdateCursorInfo();
330
- this.Render();
331
- }
332
- get gridDataPanels() {
333
- return this.uidata.panels;
334
- }
335
- set gridDataPanels(gridDataPanels) {
336
- this.uidata.panels = gridDataPanels;
337
- this.#SetupPanels();
338
- this.UpdateCursorInfo();
339
- this.Render();
340
- }
341
- /*
342
- ExitEx() {
343
- //@@ override in sub-class
344
- }
345
-
346
- EscapeEx() {
347
- //@@ override in sub-class
348
- }
349
- */
350
- // https://www.npmjs.com/package/blessed
351
- // data:= { title: <str>,
352
- // grid: { rows: <int>, cols: <int> },
353
- // menu: [ { top: <bool>, menuitems: [ { text: <string>, key: <string>, cb: <func> } ] } ]
354
- // panels: [ { id: <str>, pos: { row: <int>, col: <int>, rowSpan: <int>, colSpan: <int> }, template: <str> } ] }
355
- /**
356
- *
357
- * @param {*} data UI Data
358
- */
359
- SetupUI = () => {
360
- this.DestroyUI();
361
- if (this.screen === null) {
362
- this.screen = blessed.screen({
363
- smartCSR: true
364
- });
365
- }
366
- if (!this.screen) {
367
- return;
368
- }
369
- const data = this.uidata;
370
- this.screen.title = data.title;
371
- this.screen.on("resize", () => {
372
- this.#ReSize();
373
- this.Render();
374
- });
375
- if (data.menu !== null) {
376
- for (let i = 0; i < data.menu.length; i++) {
377
- new MenuBar(this.screen, data.menu[i]);
378
- }
379
- }
380
- this.screen.key(["C-c"], () => {
381
- this.DestroyUI();
382
- this.emit("exit");
383
- });
384
- this.screen.key(["escape"], () => {
385
- this.emit("escape");
386
- });
387
- this.#SetupPanels();
388
- this.#cursorInfo = blessed.box({
389
- parent: this.screen,
390
- bottom: 0,
391
- right: 0,
392
- width: "shrink",
393
- height: 1,
394
- style: {
395
- bg: "gray",
396
- fg: "white"
397
- },
398
- keys: false,
399
- // Do not allow default key handling for this box
400
- mouse: false,
401
- content: "",
402
- tags: true
403
- // Allow style in-line tags such as bolt, italics, etc.
404
- });
405
- this.sortInfo = blessed.box({
406
- parent: this.screen,
407
- top: 0,
408
- right: 0,
409
- width: "shrink",
410
- height: 1,
411
- style: {
412
- bg: "gray",
413
- fg: "white"
414
- },
415
- keys: false,
416
- // Do not allow default key handling for this box
417
- mouse: false,
418
- content: "",
419
- tags: true
420
- // Allow style in-line tags such as bolt, italics, etc.
421
- });
422
- this.screenHeader = blessed.box({
423
- parent: this.screen,
424
- top: 0,
425
- left: "center",
426
- width: "shrink",
427
- height: 1,
428
- style: {
429
- bg: "gray",
430
- fg: "white"
431
- },
432
- keys: false,
433
- // Do not allow default key handling for this box
434
- mouse: false,
435
- content: `[ ... ]`,
436
- tags: true
437
- // Allow style in-line tags such as bolt, italics, etc.
438
- });
439
- this.UpdateCursorInfo();
440
- this.UpdateSortInfo("Default");
441
- this.UpdateScreenHeader(this.screenHeaderText);
442
- this.Render();
443
- };
444
- UpdateCursorInfo = () => {
445
- if (this.#cursorInfo) {
446
- this.#cursorInfo.setContent(`Cursor: ${this.#cursor} / ${this.TotalPanelNumber}`);
447
- }
448
- };
449
- UpdateSortInfo = (sortMode) => {
450
- if (this.sortInfo) {
451
- this.sortInfo.setContent(`Sort: ${sortMode}`);
452
- }
453
- };
454
- UpdateScreenHeader = (screenHeaderText) => {
455
- this.screenHeaderText = screenHeaderText;
456
- if (this.screenHeader) {
457
- this.screenHeader.setContent(`[ ${screenHeaderText} ]`);
458
- }
459
- };
460
- get rows() {
461
- return this.uidata.grid.rows;
462
- }
463
- get cols() {
464
- return this.uidata.grid.cols;
465
- }
466
- IncRows = () => {
467
- if (this.screen && this.screen.height / (this.uidata.grid.rows + 1) > this.minHeight) {
468
- this.uidata.grid.rows++;
469
- this.CheckCursor();
470
- this.#UpdateUI();
471
- }
472
- };
473
- DecRows = () => {
474
- if (this.uidata.grid.rows > this.minRows) {
475
- this.uidata.grid.rows--;
476
- this.CheckCursor();
477
- this.#UpdateUI();
478
- }
479
- };
480
- IncCols = () => {
481
- if (this.screen && this.screen.width / (this.uidata.grid.cols + 1) > this.minWidth) {
482
- this.uidata.grid.cols++;
483
- this.CheckCursor();
484
- this.#UpdateUI();
485
- }
486
- };
487
- DecCols = () => {
488
- if (this.uidata.grid.cols > this.minCols) {
489
- this.uidata.grid.cols--;
490
- this.CheckCursor();
491
- this.#UpdateUI();
492
- }
493
- };
494
- get ScreenCells() {
495
- return this.uidata.grid.cols * this.uidata.grid.rows;
496
- }
497
- get TotalPanelNumber() {
498
- return Object.keys(this.uidata.panels).length;
499
- }
500
- CheckCursor = () => {
501
- if (this.#cursor > this.TotalPanelNumber - this.ScreenCells) {
502
- this.#cursor = this.TotalPanelNumber - this.ScreenCells;
503
- if (this.#cursor < 0) {
504
- this.#cursor = 0;
505
- }
506
- }
507
- this.UpdateCursorInfo();
508
- };
509
- NextPage = () => {
510
- const endpos = this.TotalPanelNumber - this.ScreenCells;
511
- if (this.#cursor < endpos) {
512
- this.#cursor += this.ScreenCells;
513
- if (this.#cursor > endpos) {
514
- this.#cursor = endpos;
515
- }
516
- this.#UpdateUI();
517
- }
518
- };
519
- PrevPage = () => {
520
- if (this.#cursor > 0) {
521
- this.#cursor -= this.ScreenCells;
522
- if (this.#cursor < 0) {
523
- this.#cursor = 0;
524
- }
525
- this.#UpdateUI();
526
- }
527
- };
528
- #UpdateUI() {
529
- this.SetupUI();
530
- }
531
- Exit = () => {
532
- this.DestroyUI();
533
- this.emit("exit");
534
- };
535
- /**
536
- *
537
- */
538
- DestroyUI = () => {
539
- if (this.screen !== null) {
540
- this.uiBoxes = {};
541
- this.screen.destroy();
542
- this.screen = null;
543
- }
544
- };
545
- /**
546
- * Render the screen.
547
- */
548
- Render = () => {
549
- if (this.screen) {
550
- this.screen.render();
551
- }
552
- };
553
- get mainScreen() {
554
- return this.screen;
555
- }
556
- }
2
+ //#region \0rolldown/runtime.js
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
+ key = keys[i];
12
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
13
+ get: ((k) => from[k]).bind(null, key),
14
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
15
+ });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
20
+ value: mod,
21
+ enumerable: true
22
+ }) : target, mod));
23
+ //#endregion
24
+ let node_events = require("node:events");
25
+ node_events = __toESM(node_events);
26
+ let blessed = require("blessed");
27
+ blessed = __toESM(blessed);
28
+ //#region src/menubar.ts
29
+ var MenuBar = class {
30
+ listb = null;
31
+ constructor(screen, options) {
32
+ const compoptions = {
33
+ parent: screen,
34
+ left: 0,
35
+ right: 0,
36
+ height: 1,
37
+ width: "shrink",
38
+ mouse: true,
39
+ keys: true,
40
+ autoCommandKeys: true,
41
+ scrollable: true,
42
+ style: {
43
+ fg: "yellow",
44
+ bg: "blue",
45
+ item: { hover: {
46
+ fg: "white",
47
+ bg: "green"
48
+ } },
49
+ selected: {
50
+ fg: "black",
51
+ bg: "yellow"
52
+ }
53
+ }
54
+ };
55
+ if (options.top === true) compoptions.top = 0;
56
+ else compoptions.bottom = 0;
57
+ compoptions.commands = {};
58
+ options.menuitems.forEach((menuItem) => {
59
+ if (compoptions.commands) compoptions.commands[menuItem.text] = {
60
+ keys: [menuItem.key],
61
+ callback: menuItem.cb
62
+ };
63
+ });
64
+ this.listb = blessed.default.listbar(compoptions);
65
+ }
66
+ get listbar() {
67
+ return this.listb;
68
+ }
69
+ };
70
+ //#endregion
71
+ //#region src/stsuiframe.ts
72
+ var STSUIFrame = class extends node_events.default {
73
+ uiBoxes = {};
74
+ screen = null;
75
+ #cursor = 0;
76
+ #renderPanelFn = null;
77
+ screenHeaderText = "...";
78
+ minRows = 1;
79
+ minCols = 1;
80
+ minWidth = 40;
81
+ minHeight = 7;
82
+ #cursorInfo = null;
83
+ sortInfo = null;
84
+ screenHeader = null;
85
+ uidata;
86
+ /**
87
+ *
88
+ * @param {*} data The screen layout data. Schema: { title: <str>,
89
+ * grid: { rows: <int>, cols: <int> },
90
+ * panels: [ { id: <str>, pos: { row: <int>, col: <int>, rowSpan: <int>, colSpan: <int> },
91
+ * template: <handlebars func>, widgets: { [ { <prop_name>: <blessed widget> } ] } } ] }
92
+ */
93
+ constructor(data, renderPanelFn = null) {
94
+ super();
95
+ this.uidata = data;
96
+ this.#renderPanelFn = renderPanelFn;
97
+ this.SetupUI();
98
+ }
99
+ get blessed() {
100
+ return blessed.default;
101
+ }
102
+ /**
103
+ *
104
+ * @param {number} position The index (0 based) for the panel item to be calculated
105
+ * @returns object with top, left, width and height correctly set
106
+ */
107
+ #CalcBoxPos = (panel) => {
108
+ if (!this.screen) return null;
109
+ if (!panel.pos) return null;
110
+ let screenHeight = this.screen.height;
111
+ if (this.uidata.menu !== null) screenHeight -= this.uidata.menu.length;
112
+ const screenWidth = this.screen.width;
113
+ const rows = this.uidata.grid.rows;
114
+ const cols = this.uidata.grid.cols;
115
+ const pos = panel.pos;
116
+ const colWidth = Math.floor(screenWidth / cols);
117
+ const rowHeight = Math.floor(screenHeight / rows);
118
+ let topoffset = 0;
119
+ if (this.uidata.menu !== null) {
120
+ for (const [, value] of Object.entries(this.uidata.menu)) if (value.top === true) {
121
+ topoffset = 1;
122
+ break;
123
+ }
124
+ }
125
+ const boxPos = {
126
+ top: pos.row * rowHeight + topoffset,
127
+ left: pos.col * colWidth,
128
+ width: colWidth * pos.colSpan,
129
+ height: rowHeight * pos.rowSpan
130
+ };
131
+ if (pos.col + pos.colSpan === cols) boxPos.width = screenWidth - pos.col * colWidth;
132
+ if (pos.row + pos.rowSpan === rows) boxPos.height = screenHeight - pos.row * rowHeight;
133
+ return boxPos;
134
+ };
135
+ #UpdateUIBoxPos = (panel, uiBox) => {
136
+ const pos = this.#CalcBoxPos(panel);
137
+ if (!pos) return;
138
+ uiBox.box.top = pos.top;
139
+ uiBox.box.left = pos.left;
140
+ uiBox.box.width = pos.width;
141
+ uiBox.box.height = pos.height;
142
+ uiBox.boxHeader.top = pos.top;
143
+ uiBox.boxHeader.left = pos.left + 2;
144
+ if (typeof panel.widgets !== "undefined" && panel.widgets !== null) {
145
+ for (const [, value] of Object.entries(panel.widgets)) if (value.widget === "log") {
146
+ const widget = uiBox.box.get(value.widget);
147
+ if (widget.position.top >= uiBox.box.height - 4) widget.position.top = uiBox.box.height - 4;
148
+ else if (value.options.top) widget.position.top = value.options.top;
149
+ }
150
+ }
151
+ };
152
+ /**
153
+ * ReSize the grid layout
154
+ */
155
+ #ReSize = () => {
156
+ for (const [, value] of Object.entries(this.uiBoxes)) this.#UpdateUIBoxPos(value.box.get("panel"), value);
157
+ };
158
+ #UpdatePanelPosition = (panel, row, col, uiBox) => {
159
+ panel.pos = {
160
+ row,
161
+ col,
162
+ rowSpan: 1,
163
+ colSpan: 1
164
+ };
165
+ this.#UpdateUIBoxPos(panel, uiBox);
166
+ uiBox.boxHeader.setContent(panel.panelHeader);
167
+ };
168
+ CreateWidget = (widgetName, widgetoptions) => {
169
+ return blessed.default[widgetName].call(this, widgetoptions);
170
+ };
171
+ CreateWidgetEx(widgetName, widgetoptions) {
172
+ return blessed.default[widgetName].call(this, widgetoptions);
173
+ }
174
+ SetupWidgets = (box, panel, parent, blessedWidgets) => {
175
+ for (const [blessedWidgetKey, blessedWidgetDetails] of Object.entries(blessedWidgets)) {
176
+ const widgetoptions = { ...blessedWidgetDetails.options };
177
+ if (box) {
178
+ if (widgetoptions.top && widgetoptions.top >= box.height - 3) widgetoptions.top = box.height - 4;
179
+ }
180
+ const widget = blessed.default[blessedWidgetDetails.widget].call(this, widgetoptions);
181
+ widget.set("id", blessedWidgetDetails.id);
182
+ parent.append(widget);
183
+ parent.set(blessedWidgetDetails.widget, widget);
184
+ parent.set(`__blessedWidgetKey__${blessedWidgetKey}`, widget);
185
+ if (blessedWidgetDetails.events) for (const [eventName, eventDetails] of Object.entries(blessedWidgetDetails.events)) widget.on(eventName, () => {
186
+ eventDetails.cb(panel, widget, parent);
187
+ });
188
+ this.emit("widgetsetup", box, panel, widget);
189
+ if (blessedWidgetDetails.children) this.SetupWidgets(null, panel, widget, blessedWidgetDetails.children);
190
+ }
191
+ };
192
+ /**
193
+ *
194
+ * Setup all panels
195
+ */
196
+ #SetupPanels() {
197
+ if (!this.screen) return;
198
+ const panelKeys = Object.keys(this.uidata.panels);
199
+ const uiBoxIds = Object.keys(this.uiBoxes);
200
+ for (let i = 0; i < uiBoxIds.length; i++) if (typeof this.uidata.panels[uiBoxIds[i]] === "undefined") {
201
+ let uiBox = this.uiBoxes[uiBoxIds[i]];
202
+ if (typeof uiBox !== "undefined") {
203
+ this.emit("preremovebox", uiBox.box, uiBox.box.get("panel"));
204
+ this.screen.remove(uiBox.boxHeader);
205
+ this.screen.remove(uiBox.box);
206
+ uiBox = null;
207
+ delete this.uiBoxes[uiBoxIds[i]];
208
+ }
209
+ }
210
+ const touched = {};
211
+ for (let i = 0; i < this.uidata.grid.cols * this.uidata.grid.rows; i++) {
212
+ const gridPos = this.#cursor + i;
213
+ const col = i % this.uidata.grid.cols;
214
+ const row = Math.floor(i / this.uidata.grid.cols);
215
+ const panel = this.uidata.panels[panelKeys[gridPos]];
216
+ if (typeof panel !== "undefined") {
217
+ if (typeof this.uiBoxes[panel.id] === "undefined") {
218
+ panel.pos = {
219
+ row,
220
+ col,
221
+ rowSpan: 1,
222
+ colSpan: 1
223
+ };
224
+ if (!this.#CalcBoxPos(panel)) return;
225
+ const { top, left, width, height } = this.#CalcBoxPos(panel);
226
+ const box = blessed.default.box({
227
+ parent: this.screen,
228
+ top,
229
+ left,
230
+ width,
231
+ height,
232
+ style: {
233
+ bg: "#101010",
234
+ fg: "white"
235
+ },
236
+ border: { type: "line" },
237
+ keys: false,
238
+ tags: true
239
+ });
240
+ const boxHeader = blessed.default.box({
241
+ parent: this.screen,
242
+ top,
243
+ left: left + 2,
244
+ width: "shrink",
245
+ height: 1,
246
+ style: {
247
+ bg: "gray",
248
+ fg: "white"
249
+ },
250
+ keys: false,
251
+ mouse: false,
252
+ content: panel.panelHeader,
253
+ tags: true
254
+ });
255
+ this.uiBoxes[panel.id] = {
256
+ box,
257
+ boxHeader
258
+ };
259
+ boxHeader.setIndex(-1);
260
+ box.on("click", () => {
261
+ this.emit("click", box.get("panel"));
262
+ });
263
+ box.on("destroy", () => {
264
+ this.emit("destroy", box, panel);
265
+ });
266
+ box.on("remove", () => {
267
+ this.emit("remove", box, panel);
268
+ });
269
+ box.on("detach", () => {
270
+ this.emit("detach", box, panel);
271
+ });
272
+ box.set("panel", panel);
273
+ this.uiBoxes[panel.id].box = box;
274
+ this.emit("boxsetup", box, panel);
275
+ if (typeof panel.widgets !== "undefined" && panel.widgets !== null) {
276
+ this.SetupWidgets(box, panel, box, panel.widgets);
277
+ this.emit("widgetsetupcomplete", box, panel, panel.widgets);
278
+ }
279
+ touched[panel.id] = true;
280
+ } else {
281
+ this.#UpdatePanelPosition(panel, row, col, this.uiBoxes[panel.id]);
282
+ touched[panel.id] = true;
283
+ }
284
+ if (this.#renderPanelFn) this.#renderPanelFn(this.uiBoxes[panel.id].box, panel);
285
+ }
286
+ }
287
+ for (const [key] of Object.entries(this.uiBoxes)) {
288
+ const box = this.uiBoxes[key].box;
289
+ const panel = box.get("panel");
290
+ if (typeof touched[key] === "undefined") {
291
+ box.hide();
292
+ this.uiBoxes[key].boxHeader.hide();
293
+ this.emit("boxhide", this.uiBoxes[key].box, panel, panel.widgets);
294
+ } else {
295
+ box.show();
296
+ this.uiBoxes[key].boxHeader.show();
297
+ this.emit("boxshow", this.uiBoxes[key].box, panel, panel.widgets);
298
+ }
299
+ }
300
+ }
301
+ get gridData() {
302
+ return this.uidata;
303
+ }
304
+ set gridData(gridData) {
305
+ this.uidata = gridData;
306
+ this.#SetupPanels();
307
+ this.UpdateCursorInfo();
308
+ this.Render();
309
+ }
310
+ get gridDataPanels() {
311
+ return this.uidata.panels;
312
+ }
313
+ set gridDataPanels(gridDataPanels) {
314
+ this.uidata.panels = gridDataPanels;
315
+ this.#SetupPanels();
316
+ this.UpdateCursorInfo();
317
+ this.Render();
318
+ }
319
+ /**
320
+ *
321
+ * @param {*} data UI Data
322
+ */
323
+ SetupUI = () => {
324
+ this.DestroyUI();
325
+ if (this.screen === null) this.screen = blessed.default.screen({ smartCSR: true });
326
+ if (!this.screen) return;
327
+ const data = this.uidata;
328
+ this.screen.title = data.title;
329
+ this.screen.on("resize", () => {
330
+ this.#ReSize();
331
+ this.Render();
332
+ });
333
+ if (data.menu !== null) for (let i = 0; i < data.menu.length; i++) new MenuBar(this.screen, data.menu[i]);
334
+ this.screen.key(["C-c"], () => {
335
+ this.DestroyUI();
336
+ this.emit("exit");
337
+ });
338
+ this.screen.key(["escape"], () => {
339
+ this.emit("escape");
340
+ });
341
+ this.#SetupPanels();
342
+ this.#cursorInfo = blessed.default.box({
343
+ parent: this.screen,
344
+ bottom: 0,
345
+ right: 0,
346
+ width: "shrink",
347
+ height: 1,
348
+ style: {
349
+ bg: "gray",
350
+ fg: "white"
351
+ },
352
+ keys: false,
353
+ mouse: false,
354
+ content: "",
355
+ tags: true
356
+ });
357
+ this.sortInfo = blessed.default.box({
358
+ parent: this.screen,
359
+ top: 0,
360
+ right: 0,
361
+ width: "shrink",
362
+ height: 1,
363
+ style: {
364
+ bg: "gray",
365
+ fg: "white"
366
+ },
367
+ keys: false,
368
+ mouse: false,
369
+ content: "",
370
+ tags: true
371
+ });
372
+ this.screenHeader = blessed.default.box({
373
+ parent: this.screen,
374
+ top: 0,
375
+ left: "center",
376
+ width: "shrink",
377
+ height: 1,
378
+ style: {
379
+ bg: "gray",
380
+ fg: "white"
381
+ },
382
+ keys: false,
383
+ mouse: false,
384
+ content: `[ ... ]`,
385
+ tags: true
386
+ });
387
+ this.UpdateCursorInfo();
388
+ this.UpdateSortInfo("Default");
389
+ this.UpdateScreenHeader(this.screenHeaderText);
390
+ this.Render();
391
+ };
392
+ UpdateCursorInfo = () => {
393
+ if (this.#cursorInfo) this.#cursorInfo.setContent(`Cursor: ${this.#cursor} / ${this.TotalPanelNumber}`);
394
+ };
395
+ UpdateSortInfo = (sortMode) => {
396
+ if (this.sortInfo) this.sortInfo.setContent(`Sort: ${sortMode}`);
397
+ };
398
+ UpdateScreenHeader = (screenHeaderText) => {
399
+ this.screenHeaderText = screenHeaderText;
400
+ if (this.screenHeader) this.screenHeader.setContent(`[ ${screenHeaderText} ]`);
401
+ };
402
+ get rows() {
403
+ return this.uidata.grid.rows;
404
+ }
405
+ get cols() {
406
+ return this.uidata.grid.cols;
407
+ }
408
+ IncRows = () => {
409
+ if (this.screen && this.screen.height / (this.uidata.grid.rows + 1) > this.minHeight) {
410
+ this.uidata.grid.rows++;
411
+ this.CheckCursor();
412
+ this.#UpdateUI();
413
+ }
414
+ };
415
+ DecRows = () => {
416
+ if (this.uidata.grid.rows > this.minRows) {
417
+ this.uidata.grid.rows--;
418
+ this.CheckCursor();
419
+ this.#UpdateUI();
420
+ }
421
+ };
422
+ IncCols = () => {
423
+ if (this.screen && this.screen.width / (this.uidata.grid.cols + 1) > this.minWidth) {
424
+ this.uidata.grid.cols++;
425
+ this.CheckCursor();
426
+ this.#UpdateUI();
427
+ }
428
+ };
429
+ DecCols = () => {
430
+ if (this.uidata.grid.cols > this.minCols) {
431
+ this.uidata.grid.cols--;
432
+ this.CheckCursor();
433
+ this.#UpdateUI();
434
+ }
435
+ };
436
+ get ScreenCells() {
437
+ return this.uidata.grid.cols * this.uidata.grid.rows;
438
+ }
439
+ get TotalPanelNumber() {
440
+ return Object.keys(this.uidata.panels).length;
441
+ }
442
+ CheckCursor = () => {
443
+ if (this.#cursor > this.TotalPanelNumber - this.ScreenCells) {
444
+ this.#cursor = this.TotalPanelNumber - this.ScreenCells;
445
+ if (this.#cursor < 0) this.#cursor = 0;
446
+ }
447
+ this.UpdateCursorInfo();
448
+ };
449
+ NextPage = () => {
450
+ const endpos = this.TotalPanelNumber - this.ScreenCells;
451
+ if (this.#cursor < endpos) {
452
+ this.#cursor += this.ScreenCells;
453
+ if (this.#cursor > endpos) this.#cursor = endpos;
454
+ this.#UpdateUI();
455
+ }
456
+ };
457
+ PrevPage = () => {
458
+ if (this.#cursor > 0) {
459
+ this.#cursor -= this.ScreenCells;
460
+ if (this.#cursor < 0) this.#cursor = 0;
461
+ this.#UpdateUI();
462
+ }
463
+ };
464
+ #UpdateUI() {
465
+ this.SetupUI();
466
+ }
467
+ Exit = () => {
468
+ this.DestroyUI();
469
+ this.emit("exit");
470
+ };
471
+ /**
472
+ *
473
+ */
474
+ DestroyUI = () => {
475
+ if (this.screen !== null) {
476
+ this.uiBoxes = {};
477
+ this.screen.destroy();
478
+ this.screen = null;
479
+ }
480
+ };
481
+ /**
482
+ * Render the screen.
483
+ */
484
+ Render = () => {
485
+ if (this.screen) this.screen.render();
486
+ };
487
+ get mainScreen() {
488
+ return this.screen;
489
+ }
490
+ };
491
+ //#endregion
557
492
  exports.MenuBar = MenuBar;
558
493
  exports.STSUIFrame = STSUIFrame;
559
- //# sourceMappingURL=index.cjs.map
494
+
495
+ //# sourceMappingURL=index.cjs.map