swing-ui 1.0.1 → 1.0.4
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.md +1 -1
- package/classes/ComponentContainer.js +109 -81
- package/classes/Panel.js +1 -1
- package/classes/UIComponent.js +44 -3
- package/classes/Window.js +1 -1
- package/enums.js +1 -1
- package/icon.png +0 -0
- package/jar/gui-11.jar +0 -0
- package/package.json +2 -2
- package/types/classes/UIComponent.d.ts +24 -3
- package/types/enums.d.ts +1 -1
package/README.md
CHANGED
|
@@ -77,7 +77,7 @@ class HelloApp extends Window {
|
|
|
77
77
|
super("swing-ui Demo");
|
|
78
78
|
this.innerSize(360, 160).position(200, 200).closeOperation(Window.CloseOperation.Exit);
|
|
79
79
|
|
|
80
|
-
new Label("What's your name?").position(20, 20).addTo(this);
|
|
80
|
+
new Label("What's your name?").position(20, 20).size(300, 25).addTo(this);
|
|
81
81
|
const name = new TextField("type name here").size(300, 28).position(20, 45).addTo(this);
|
|
82
82
|
|
|
83
83
|
new Button("Greet me").position(20, 85).addTo(this)
|
|
@@ -111,8 +111,13 @@ export class ComponentContainer extends UIComponent
|
|
|
111
111
|
|
|
112
112
|
if(this.#descriptorObject == null)
|
|
113
113
|
{
|
|
114
|
-
this.
|
|
115
|
-
this.
|
|
114
|
+
this._applyUIDefinition = undefined;
|
|
115
|
+
this._applyComponentPropertiesV1_0 = undefined;
|
|
116
|
+
this._buildComponentResources = undefined;
|
|
117
|
+
|
|
118
|
+
delete this._applyUIDefinition;
|
|
119
|
+
delete this._applyComponentPropertiesV1_0;
|
|
120
|
+
delete this._buildComponentResources;
|
|
116
121
|
}
|
|
117
122
|
}
|
|
118
123
|
|
|
@@ -446,7 +451,7 @@ export class ComponentContainer extends UIComponent
|
|
|
446
451
|
* @private
|
|
447
452
|
* @ignore
|
|
448
453
|
*/
|
|
449
|
-
|
|
454
|
+
_applyUIDefinition(class_name)
|
|
450
455
|
{
|
|
451
456
|
// Apply UI to this component
|
|
452
457
|
if(this.#descriptorObject != null)
|
|
@@ -473,12 +478,12 @@ export class ComponentContainer extends UIComponent
|
|
|
473
478
|
try
|
|
474
479
|
{
|
|
475
480
|
common.validateComponent(this.#descriptorObject.component);
|
|
481
|
+
this._buildComponentResources(this, this.#descriptorObject, common); // contextMenus, menuBar, trayIcons
|
|
482
|
+
this._applyComponentPropertiesV1_0(this, this.#descriptorObject.component, common);
|
|
476
483
|
}catch(ex)
|
|
477
484
|
{
|
|
478
485
|
error(`${ex.name}: ${ex.message}`, false);
|
|
479
486
|
}
|
|
480
|
-
|
|
481
|
-
this.applyComponentPropertiesV1_0(this, this.#descriptorObject.component, common);
|
|
482
487
|
}
|
|
483
488
|
else
|
|
484
489
|
{
|
|
@@ -502,15 +507,108 @@ export class ComponentContainer extends UIComponent
|
|
|
502
507
|
}
|
|
503
508
|
|
|
504
509
|
// delete these functions to make sure they can't be called again
|
|
505
|
-
this.
|
|
506
|
-
this.
|
|
507
|
-
this.
|
|
510
|
+
this._buildComponentResources = undefined;
|
|
511
|
+
this._applyComponentPropertiesV1_0 = undefined;
|
|
512
|
+
this._applyUIDefinition = undefined;
|
|
513
|
+
|
|
514
|
+
delete this._buildComponentResources;
|
|
515
|
+
delete this._applyComponentPropertiesV1_0;
|
|
516
|
+
delete this._applyUIDefinition;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
/**
|
|
520
|
+
* @private
|
|
521
|
+
*/
|
|
522
|
+
_buildComponentResources(component, desc, common)
|
|
523
|
+
{
|
|
524
|
+
//region For backward compatibility
|
|
525
|
+
if("contextMenus" in desc.component)
|
|
526
|
+
{
|
|
527
|
+
desc.contextMenus = desc.component.contextMenus;
|
|
528
|
+
delete desc.component.contextMenus;
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
if("trayIcons" in desc.component)
|
|
532
|
+
{
|
|
533
|
+
desc.trayIcons = desc.component.trayIcons;
|
|
534
|
+
delete desc.component.trayIcons;
|
|
535
|
+
}
|
|
536
|
+
//endregion
|
|
537
|
+
|
|
538
|
+
// load context menus
|
|
539
|
+
if("contextMenus" in desc)
|
|
540
|
+
{
|
|
541
|
+
if(Array.isArray(desc.contextMenus))
|
|
542
|
+
{
|
|
543
|
+
desc.contextMenus.forEach(json_child =>
|
|
544
|
+
{
|
|
545
|
+
try
|
|
546
|
+
{
|
|
547
|
+
common.validateComponent(json_child);
|
|
548
|
+
|
|
549
|
+
this[json_child.ref] = new globalThis[json_child.type]();
|
|
550
|
+
this._applyComponentPropertiesV1_0(this[json_child.ref], json_child, common);
|
|
551
|
+
}catch(ex)
|
|
552
|
+
{
|
|
553
|
+
error(`Failed to load a context menu. ${ex.name}: ${ex.message}`, false);
|
|
554
|
+
}
|
|
555
|
+
});
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
delete desc.contextMenus;
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
if(desc.component.type === "Window")
|
|
562
|
+
{
|
|
563
|
+
// load main menu bar
|
|
564
|
+
if("menuBar" in desc.component)
|
|
565
|
+
{
|
|
566
|
+
try
|
|
567
|
+
{
|
|
568
|
+
common.validateComponent(desc.component.menuBar);
|
|
569
|
+
|
|
570
|
+
const bar = new globalThis[desc.component.menuBar.type]();
|
|
571
|
+
this._applyComponentPropertiesV1_0(bar, desc.component.menuBar, common);
|
|
572
|
+
component.menuBar(bar);
|
|
573
|
+
delete desc.component.menuBar;
|
|
574
|
+
}catch(ex)
|
|
575
|
+
{
|
|
576
|
+
error(`Failed to load a menu bar. ${ex.name}: ${ex.message}`, false);
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
// load tray icons
|
|
581
|
+
if("trayIcons" in desc)
|
|
582
|
+
{
|
|
583
|
+
if(Array.isArray(desc.trayIcons))
|
|
584
|
+
{
|
|
585
|
+
desc.trayIcons.forEach(json_child =>
|
|
586
|
+
{
|
|
587
|
+
try
|
|
588
|
+
{
|
|
589
|
+
common.validateComponent(json_child);
|
|
590
|
+
}catch(ex)
|
|
591
|
+
{
|
|
592
|
+
error(`Failed to load a tray icon. ${ex.name}: ${ex.message}`, false);
|
|
593
|
+
return;
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
const trayIcon = new globalThis[json_child.type]();
|
|
597
|
+
this.onDispose(e => {if(!trayIcon.destroyed) trayIcon.destroy();}); // destroy the tray icon when window gets disposed
|
|
598
|
+
this[json_child.ref] = trayIcon;
|
|
599
|
+
this._applyComponentPropertiesV1_0(trayIcon, json_child, common);
|
|
600
|
+
});
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
delete desc.trayIcons;
|
|
604
|
+
}
|
|
605
|
+
}
|
|
508
606
|
}
|
|
509
607
|
|
|
510
608
|
/**
|
|
511
609
|
* @private
|
|
512
610
|
*/
|
|
513
|
-
|
|
611
|
+
_applyComponentPropertiesV1_0(component, properties, common)
|
|
514
612
|
{
|
|
515
613
|
const ref = properties.ref;
|
|
516
614
|
delete properties.ref;
|
|
@@ -605,76 +703,6 @@ export class ComponentContainer extends UIComponent
|
|
|
605
703
|
}
|
|
606
704
|
}
|
|
607
705
|
|
|
608
|
-
// load context menus
|
|
609
|
-
if("contextMenus" in properties)
|
|
610
|
-
{
|
|
611
|
-
if(Array.isArray(properties.contextMenus))
|
|
612
|
-
{
|
|
613
|
-
properties.contextMenus.forEach(json_child =>
|
|
614
|
-
{
|
|
615
|
-
try
|
|
616
|
-
{
|
|
617
|
-
common.validateComponent(json_child);
|
|
618
|
-
}catch(ex)
|
|
619
|
-
{
|
|
620
|
-
error(`Failed to load a context menu. ${ex.name}: ${ex.message}`, false);
|
|
621
|
-
return;
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
this[json_child.ref] = new globalThis[json_child.type]();
|
|
625
|
-
this.applyComponentPropertiesV1_0(this[json_child.ref], json_child, common);
|
|
626
|
-
});
|
|
627
|
-
}
|
|
628
|
-
|
|
629
|
-
delete properties.contextMenus;
|
|
630
|
-
}
|
|
631
|
-
|
|
632
|
-
if(component instanceof Window)
|
|
633
|
-
{
|
|
634
|
-
// load main menu bar
|
|
635
|
-
if("menuBar" in properties)
|
|
636
|
-
{
|
|
637
|
-
try
|
|
638
|
-
{
|
|
639
|
-
common.validateComponent(properties.menuBar);
|
|
640
|
-
}catch(ex)
|
|
641
|
-
{
|
|
642
|
-
error(`Failed to load a menu bar. ${ex.name}: ${ex.message}`, false);
|
|
643
|
-
}
|
|
644
|
-
|
|
645
|
-
const bar = new globalThis[properties.menuBar.type]();
|
|
646
|
-
this.applyComponentPropertiesV1_0(bar, properties.menuBar, common);
|
|
647
|
-
component.menuBar(bar);
|
|
648
|
-
delete properties.menuBar;
|
|
649
|
-
}
|
|
650
|
-
|
|
651
|
-
// load tray icons
|
|
652
|
-
if("trayIcons" in properties)
|
|
653
|
-
{
|
|
654
|
-
if(Array.isArray(properties.trayIcons))
|
|
655
|
-
{
|
|
656
|
-
properties.trayIcons.forEach(json_child =>
|
|
657
|
-
{
|
|
658
|
-
try
|
|
659
|
-
{
|
|
660
|
-
common.validateComponent(json_child);
|
|
661
|
-
}catch(ex)
|
|
662
|
-
{
|
|
663
|
-
error(`Failed to load a tray icon. ${ex.name}: ${ex.message}`, false);
|
|
664
|
-
return;
|
|
665
|
-
}
|
|
666
|
-
|
|
667
|
-
const trayIcon = new globalThis[json_child.type]();
|
|
668
|
-
component.onDispose(e => {if(!trayIcon.destroyed) trayIcon.destroy();}); // destroy the tray icon when window gets disposed
|
|
669
|
-
this[json_child.ref] = trayIcon;
|
|
670
|
-
this.applyComponentPropertiesV1_0(trayIcon, json_child, common);
|
|
671
|
-
});
|
|
672
|
-
}
|
|
673
|
-
|
|
674
|
-
delete properties.trayIcons;
|
|
675
|
-
}
|
|
676
|
-
}
|
|
677
|
-
|
|
678
706
|
// apply properties
|
|
679
707
|
for(const prop of Object.keys(properties))
|
|
680
708
|
{
|
|
@@ -748,7 +776,7 @@ export class ComponentContainer extends UIComponent
|
|
|
748
776
|
|
|
749
777
|
const child_ref = json_child.ref;
|
|
750
778
|
this[child_ref] = new globalThis[json_child.type]();
|
|
751
|
-
this.
|
|
779
|
+
this._applyComponentPropertiesV1_0(this[child_ref], json_child, common);
|
|
752
780
|
component.addChild(this[child_ref]);
|
|
753
781
|
});
|
|
754
782
|
}
|
|
@@ -803,7 +831,7 @@ export class ComponentContainer extends UIComponent
|
|
|
803
831
|
{
|
|
804
832
|
try
|
|
805
833
|
{
|
|
806
|
-
component[event](new Function('e', func.substring(11).trim()).bind(
|
|
834
|
+
component[event](new Function('e', func.substring(11).trim()).bind(component));
|
|
807
835
|
}catch(ex)
|
|
808
836
|
{
|
|
809
837
|
component[event]((...args) =>
|
package/classes/Panel.js
CHANGED
|
@@ -32,7 +32,7 @@ class Panel extends ShapeContainer
|
|
|
32
32
|
//this.finalize(Panel, ShapeContainer);
|
|
33
33
|
|
|
34
34
|
// load UI definition file
|
|
35
|
-
if(new.target !== Panel && this.
|
|
35
|
+
if(new.target !== Panel && this._applyUIDefinition != null) this._applyUIDefinition(new.target.name); // must be called AFTER super()
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
/**
|
package/classes/UIComponent.js
CHANGED
|
@@ -251,9 +251,9 @@ class UIComponent
|
|
|
251
251
|
}
|
|
252
252
|
|
|
253
253
|
/**
|
|
254
|
-
* Gets a parent
|
|
254
|
+
* Gets a parent container component. If this component wasn't added to any container component, then `null` is returned.
|
|
255
255
|
* @readonly
|
|
256
|
-
* @type {
|
|
256
|
+
* @type {UIComponent|null}
|
|
257
257
|
*/
|
|
258
258
|
get parent()
|
|
259
259
|
{
|
|
@@ -263,6 +263,47 @@ class UIComponent
|
|
|
263
263
|
return UIComponent.get(this.parent_id);
|
|
264
264
|
}
|
|
265
265
|
|
|
266
|
+
/**
|
|
267
|
+
* Gets a previous sibling component. If this component wasn't added to any container component, then `null` is returned.
|
|
268
|
+
* @readonly
|
|
269
|
+
* @type {UIComponent|null}
|
|
270
|
+
* @since 1.0.3
|
|
271
|
+
*/
|
|
272
|
+
get previousSibling()
|
|
273
|
+
{
|
|
274
|
+
if(this.parent == null) return null;
|
|
275
|
+
let i = this.parent.childIndex(this);
|
|
276
|
+
if(i === 0) return null;
|
|
277
|
+
return this.parent.child(i - 1);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Gets a next sibling component. If this component wasn't added to any container component, then `null` is returned.
|
|
282
|
+
* @readonly
|
|
283
|
+
* @type {UIComponent|null}
|
|
284
|
+
* @since 1.0.3
|
|
285
|
+
*/
|
|
286
|
+
get nextSibling()
|
|
287
|
+
{
|
|
288
|
+
if(this.parent == null) return null;
|
|
289
|
+
let i = this.parent.childIndex(this);
|
|
290
|
+
return this.parent.child(i + 1);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Gets an array of sibling components.
|
|
295
|
+
* @readonly
|
|
296
|
+
* @type {UIComponent[]}
|
|
297
|
+
* @since 1.0.3
|
|
298
|
+
*/
|
|
299
|
+
get siblings()
|
|
300
|
+
{
|
|
301
|
+
if(this.parent == null) return [];
|
|
302
|
+
const _siblings = this.parent.children;
|
|
303
|
+
_siblings.splice(_siblings.indexOf(this), 1);
|
|
304
|
+
return _siblings;
|
|
305
|
+
}
|
|
306
|
+
|
|
266
307
|
/**
|
|
267
308
|
* Gets a Window component containing this component. Returns `null` if no Window contain this component.
|
|
268
309
|
* @readonly
|
|
@@ -404,7 +445,7 @@ class UIComponent
|
|
|
404
445
|
|
|
405
446
|
/**
|
|
406
447
|
* Checks if this component is inside specified ancestor component (at any level, not just direct child).
|
|
407
|
-
* @param {
|
|
448
|
+
* @param {UIComponent} ancestor - Ancestor component to test against
|
|
408
449
|
* @return {boolean}
|
|
409
450
|
* @see ComponentContainer#contains
|
|
410
451
|
*/
|
package/classes/Window.js
CHANGED
|
@@ -129,7 +129,7 @@ class Window extends ShapeContainer
|
|
|
129
129
|
//this.finalize(ShapeContainer, Window);
|
|
130
130
|
|
|
131
131
|
// load UI definition file
|
|
132
|
-
if(new.target !== Window && this.
|
|
132
|
+
if(new.target !== Window && this._applyUIDefinition != null) this._applyUIDefinition(new.target.name); // must be called AFTER super()
|
|
133
133
|
}
|
|
134
134
|
|
|
135
135
|
/**
|
package/enums.js
CHANGED
|
@@ -160,7 +160,7 @@ export const SelectionMode = Object.freeze({Single: 0, Range: 1, Multiple: 2});
|
|
|
160
160
|
* textarea.font({name: FontFamily.SansSerif});
|
|
161
161
|
*
|
|
162
162
|
* @example <h2>Setting Text shape font:</h2>
|
|
163
|
-
* let text = new
|
|
163
|
+
* let text = new TextShape("Hello World", {name: FontFamily.Fantasy, size: 30});
|
|
164
164
|
*/
|
|
165
165
|
export const FontFamily = Object.freeze({Serif: "serif", SansSerif: "sans-serif", Monospaced: "monospace", Cursive: "cursive", System: "system-ui", Fantasy: "fantasy"});
|
|
166
166
|
|
package/icon.png
CHANGED
|
Binary file
|
package/jar/gui-11.jar
CHANGED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "swing-ui",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "Graphic User Interface for
|
|
3
|
+
"version": "1.0.4",
|
|
4
|
+
"description": "Cross-platform Graphic User Interface for Node.js, Bun and Deno 2+",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"docs": "jsdoc -c docs-files/jsdoc.json",
|
|
@@ -89,11 +89,32 @@ export class UIComponent {
|
|
|
89
89
|
*/
|
|
90
90
|
readonly get id(): number;
|
|
91
91
|
/**
|
|
92
|
-
* Gets a parent
|
|
92
|
+
* Gets a parent container component. If this component wasn't added to any container component, then `null` is returned.
|
|
93
93
|
* @readonly
|
|
94
|
-
* @type {
|
|
94
|
+
* @type {UIComponent|null}
|
|
95
95
|
*/
|
|
96
|
-
readonly get parent():
|
|
96
|
+
readonly get parent(): UIComponent | null;
|
|
97
|
+
/**
|
|
98
|
+
* Gets a previous sibling component. If this component wasn't added to any container component, then `null` is returned.
|
|
99
|
+
* @readonly
|
|
100
|
+
* @type {UIComponent|null}
|
|
101
|
+
* @since 1.0.3
|
|
102
|
+
*/
|
|
103
|
+
readonly get previousSibling(): UIComponent | null;
|
|
104
|
+
/**
|
|
105
|
+
* Gets a next sibling component. If this component wasn't added to any container component, then `null` is returned.
|
|
106
|
+
* @readonly
|
|
107
|
+
* @type {UIComponent|null}
|
|
108
|
+
* @since 1.0.3
|
|
109
|
+
*/
|
|
110
|
+
readonly get nextSibling(): UIComponent | null;
|
|
111
|
+
/**
|
|
112
|
+
* Gets an array of sibling components.
|
|
113
|
+
* @readonly
|
|
114
|
+
* @type {UIComponent[]}
|
|
115
|
+
* @since 1.0.3
|
|
116
|
+
*/
|
|
117
|
+
readonly get siblings(): UIComponent[];
|
|
97
118
|
/**
|
|
98
119
|
* Gets a Window component containing this component. Returns `null` if no Window contain this component.
|
|
99
120
|
* @readonly
|
package/types/enums.d.ts
CHANGED
|
@@ -225,7 +225,7 @@ export type FontFamily = string;
|
|
|
225
225
|
* textarea.font({name: FontFamily.SansSerif});
|
|
226
226
|
*
|
|
227
227
|
* @example <h2>Setting Text shape font:</h2>
|
|
228
|
-
* let text = new
|
|
228
|
+
* let text = new TextShape("Hello World", {name: FontFamily.Fantasy, size: 30});
|
|
229
229
|
*/
|
|
230
230
|
export const FontFamily: Readonly<{
|
|
231
231
|
Serif: "serif";
|