swing-ui 0.1.25 → 1.0.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.
Files changed (116) hide show
  1. package/LICENSE +5 -4
  2. package/README.md +144 -7
  3. package/SwingUI.js +2611 -0
  4. package/classes/Arc.js +185 -0
  5. package/classes/Button.js +55 -0
  6. package/classes/CheckBox.js +33 -0
  7. package/classes/CheckBoxMenuItem.js +24 -0
  8. package/classes/ComboBox.js +329 -0
  9. package/classes/ComponentContainer.js +828 -0
  10. package/classes/ContextMenu.js +141 -0
  11. package/classes/DocumentEditor.js +168 -0
  12. package/classes/Ellipse.js +76 -0
  13. package/classes/InternalWindow.js +397 -0
  14. package/classes/InternalWindowContainer.js +93 -0
  15. package/classes/Label.js +52 -0
  16. package/classes/Line.js +105 -0
  17. package/classes/List.js +452 -0
  18. package/classes/MediaPlayer.js +504 -0
  19. package/classes/Menu.js +74 -0
  20. package/classes/MenuBar.js +56 -0
  21. package/classes/MenuItem.js +92 -0
  22. package/classes/Panel.js +50 -0
  23. package/classes/PasswordField.js +47 -0
  24. package/classes/Polygon.js +236 -0
  25. package/classes/Polyline.js +240 -0
  26. package/classes/ProgressBar.js +62 -0
  27. package/classes/RadioButton.js +110 -0
  28. package/classes/RadioButtonMenuItem.js +106 -0
  29. package/classes/Rectangle.js +199 -0
  30. package/classes/ScrollPane.js +53 -0
  31. package/classes/ScrollableComponent.js +141 -0
  32. package/classes/Separator.js +24 -0
  33. package/classes/Shape.js +584 -0
  34. package/classes/ShapeContainer.js +231 -0
  35. package/classes/Slider.js +172 -0
  36. package/classes/Spinner.js +172 -0
  37. package/classes/SplitView.js +82 -0
  38. package/classes/Stroke.js +115 -0
  39. package/classes/Table.js +982 -0
  40. package/classes/Tabs.js +228 -0
  41. package/classes/TextArea.js +125 -0
  42. package/classes/TextComponent.js +207 -0
  43. package/classes/TextField.js +128 -0
  44. package/classes/TextShape.js +123 -0
  45. package/classes/ToggleButton.js +147 -0
  46. package/classes/ToolBar.js +120 -0
  47. package/classes/TrayIcon.js +54 -0
  48. package/classes/Tree.js +569 -0
  49. package/classes/UIComponent.js +2113 -0
  50. package/classes/Window.js +609 -0
  51. package/enums.js +298 -0
  52. package/fonts.conf +32 -0
  53. package/functions.js +254 -0
  54. package/icon.png +0 -0
  55. package/index.js +109 -4
  56. package/jar/gui-11.jar +0 -0
  57. package/jar/lib/flatlaf.jar +0 -0
  58. package/jar/lib/jna.jar +0 -0
  59. package/package.json +58 -33
  60. package/typedefs.js +973 -0
  61. package/types/SwingUI.d.ts +727 -0
  62. package/types/classes/Arc.d.ts +111 -0
  63. package/types/classes/Button.d.ts +38 -0
  64. package/types/classes/CheckBox.d.ts +22 -0
  65. package/types/classes/CheckBoxMenuItem.d.ts +18 -0
  66. package/types/classes/ComboBox.d.ts +172 -0
  67. package/types/classes/ComponentContainer.d.ts +131 -0
  68. package/types/classes/ContextMenu.d.ts +74 -0
  69. package/types/classes/DocumentEditor.d.ts +95 -0
  70. package/types/classes/Ellipse.d.ts +34 -0
  71. package/types/classes/InternalWindow.d.ts +163 -0
  72. package/types/classes/InternalWindowContainer.d.ts +36 -0
  73. package/types/classes/Label.d.ts +33 -0
  74. package/types/classes/Line.d.ts +48 -0
  75. package/types/classes/List.d.ts +223 -0
  76. package/types/classes/MediaPlayer.d.ts +381 -0
  77. package/types/classes/Menu.d.ts +43 -0
  78. package/types/classes/MenuBar.d.ts +26 -0
  79. package/types/classes/MenuItem.d.ts +57 -0
  80. package/types/classes/Panel.d.ts +28 -0
  81. package/types/classes/PasswordField.d.ts +22 -0
  82. package/types/classes/Polygon.d.ts +93 -0
  83. package/types/classes/Polyline.d.ts +96 -0
  84. package/types/classes/ProgressBar.d.ts +36 -0
  85. package/types/classes/RadioButton.d.ts +70 -0
  86. package/types/classes/RadioButtonMenuItem.d.ts +71 -0
  87. package/types/classes/Rectangle.d.ts +82 -0
  88. package/types/classes/ScrollPane.d.ts +23 -0
  89. package/types/classes/ScrollableComponent.d.ts +81 -0
  90. package/types/classes/Separator.d.ts +14 -0
  91. package/types/classes/Shape.d.ts +223 -0
  92. package/types/classes/ShapeContainer.d.ts +92 -0
  93. package/types/classes/Slider.d.ts +107 -0
  94. package/types/classes/Spinner.d.ts +129 -0
  95. package/types/classes/SplitView.d.ts +47 -0
  96. package/types/classes/Stroke.d.ts +99 -0
  97. package/types/classes/Table.d.ts +652 -0
  98. package/types/classes/Tabs.d.ts +118 -0
  99. package/types/classes/TextArea.d.ts +45 -0
  100. package/types/classes/TextComponent.d.ts +136 -0
  101. package/types/classes/TextField.d.ts +94 -0
  102. package/types/classes/TextShape.d.ts +73 -0
  103. package/types/classes/ToggleButton.d.ts +84 -0
  104. package/types/classes/ToolBar.d.ts +82 -0
  105. package/types/classes/TrayIcon.d.ts +43 -0
  106. package/types/classes/Tree.d.ts +354 -0
  107. package/types/classes/UIComponent.d.ts +945 -0
  108. package/types/classes/Window.d.ts +334 -0
  109. package/types/enums.d.ts +437 -0
  110. package/types/functions.d.ts +109 -0
  111. package/types/index.d.ts +188 -0
  112. package/types/typedefs.d.ts +1626 -0
  113. package/ui-process-manager.js +317 -0
  114. package/video-devices-linux.sh +72 -0
  115. package/video-devices-mac.sh +33 -0
  116. package/CHANGES.md +0 -3
package/classes/Arc.js ADDED
@@ -0,0 +1,185 @@
1
+
2
+ import {Shape} from "./Shape.js";
3
+
4
+ /**
5
+ * An `Arc` shape that extends the {@link Shape} class.
6
+ *
7
+ * An Arc is a portion of a circle defined by its center coordinates, width (horizontal diameter), height (vertical diameter), starting angle, and extent (the angular span of the arc) in degrees.
8
+ *
9
+ * @class
10
+ * @global
11
+ * @see Shape
12
+ */
13
+ export class Arc extends Shape
14
+ {
15
+ /**
16
+ * Enum for arc drawing types: Pie and Chord.
17
+ *
18
+ * @readonly
19
+ * @enum {number}
20
+ * @property {number} Chord - Draws the arc as a straight chord between the start and end points.
21
+ * @property {number} Pie - Draws the arc as a pie shape (arc connected to the center).
22
+ * @example
23
+ * Arc.Type.Pie
24
+ */
25
+ static Type = Object.freeze({Chord: 1, Pie: 2});
26
+
27
+ _size = {width: 100, height: 100};
28
+ _hole_size = {width: 0, height: 0};
29
+ _start_angle = 0;
30
+ _extent = 360;
31
+ _arc_type = Arc.Type.Chord;
32
+
33
+ /**
34
+ * Creates an instance of Arc shape.
35
+ *
36
+ * @param {Stroke} [stroke] - A border of the shape.
37
+ * @param {string} [background] - Color, gradient, or image background, similar to CSS. Use an empty string to remove the background.
38
+ * @param {number} [opacity] - Opacity of the shape (0 to 1).
39
+ * @param {number} [x] - Horizontal position from the left edge.
40
+ * @param {number} [y] - Vertical position from the top edge.
41
+ * @param {number} [width] - Width of the arc (horizontal diameter).
42
+ * @param {number} [height] - Height of the arc (vertical diameter). If omitted, height will be same as width.
43
+ * @param {number} [startAngle] - Starting angle of the arc (0 to 360 degrees).
44
+ * @param {number} [sweepAngle] - How much the arc is open (0 to 360 degrees).
45
+ * @param {Arc.Type} [type] = Arc type. One of: `Arc.Type.Chord`, `Arc.Type.Pie`.
46
+ */
47
+ constructor(stroke = undefined, background = undefined, opacity = 1, x = 0, y = 0, width = 100, height = undefined, startAngle = 0, sweepAngle = 360, type = Arc.Type.Chord)
48
+ {
49
+ super(undefined, stroke, background, opacity, x, y);
50
+ this._type = "arc";
51
+ this._size = {width: width, height: height != null ? height : width};
52
+ this._start_angle = startAngle;
53
+ this._extent = Math.max(0, Math.min(360, parseFloat(sweepAngle)));
54
+ this._arc_type = Math.max(Arc.Type.Chord, Math.min(Arc.Type.Pie, parseInt(type)));
55
+ }
56
+
57
+ /**
58
+ * Sets or gets the size of the arc (horizontal and vertical diameter).
59
+ *
60
+ * @param {number|{width:number, height:number}} width - Width of the arc (horizontal diameter), or a size object (e.g., {width:300,height:300}).
61
+ * @param {number} [height] - Height of the arc (vertical diameter).
62
+ * @returns {{width:number, height:number}|Arc} If called without parameters, current size is returned; otherwise this Arc object is returned.
63
+ */
64
+ size()
65
+ {
66
+ if(arguments.length > 0)
67
+ {
68
+ this._size = (arguments.length > 1) ? {width: arguments[0], height: arguments[1]} : arguments[0];
69
+
70
+ if(typeof this._size !== "object") this._size = {width: this._size, height: this._size};
71
+ this.update("min");
72
+ return this;
73
+ }
74
+ else
75
+ {
76
+ return {width: this._size.width, height: this._size.height};
77
+ }
78
+ }
79
+
80
+ /**
81
+ * Sets or gets the size of the hollow space inside the arc. The hole make it look more like a donut.
82
+ *
83
+ * @param {number|{width:number, height:number}} width - Width of the hole (horizontal diameter), or a size object (e.g., {width:50,height:50}).
84
+ * @param {number} [height] - Height of the hole (vertical diameter).
85
+ * @returns {{width:number, height:number}|Arc} If called without parameters, current hole size is returned; otherwise this Arc object is returned.
86
+ */
87
+ holeSize()
88
+ {
89
+ if(arguments.length > 0)
90
+ {
91
+ this._hole_size = (arguments.length > 1) ? {width: arguments[0], height: arguments[1]} : arguments[0];
92
+
93
+ if(typeof this._hole_size !== "object") this._hole_size = {width: this._hole_size, height: this._hole_size};
94
+ this.update("min");
95
+ return this;
96
+ }
97
+ else
98
+ {
99
+ return {width: this._size.width, height: this._size.height};
100
+ }
101
+ }
102
+
103
+ /**
104
+ * Sets or gets the type of the arc to Arc.Type.Chord or Arc.Type.Pie
105
+ *
106
+ * @param {Arc.Type} [type] - One of the type values: Arc.Type.Pie, Arc.Type.Chord
107
+ * @returns {Arc.Type|Arc} If called without parameters, current type is returned; otherwise this Arc object is returned.
108
+ */
109
+ type()
110
+ {
111
+ if(arguments.length > 0)
112
+ {
113
+ this._arc_type = arguments[0];
114
+
115
+ this.update("min");
116
+ return this;
117
+ }
118
+ else
119
+ {
120
+ return this._arc_type;
121
+ }
122
+ }
123
+
124
+ /**
125
+ * Gets or sets the starting angle of the arc.
126
+ *
127
+ * The starting angle defines where the arc begins, measured in degrees
128
+ * from the positive x-axis in a clockwise direction.
129
+ *
130
+ * @param {number} [angle] - Sets the start angle (0 to 360 degrees).
131
+ * @returns {number|Arc} Returns the current start angle if no parameter is given, otherwise returns the Arc instance for chaining.
132
+ */
133
+ startAngle()
134
+ {
135
+ if(arguments.length > 0)
136
+ {
137
+ this._start_angle = parseFloat(arguments[0]) % 360;
138
+ if(this._start_angle < 0) this._start_angle = 360 + this._start_angle;
139
+ this.update("min");
140
+ return this;
141
+ }
142
+
143
+ return this._start_angle;
144
+ }
145
+
146
+ /**
147
+ * Sets or gets how much the arc is open in degrees, between 0 and 360.
148
+ *
149
+ * @param {number} [sweepAngle] - Sweep angle of the opening starting from the start angle (0 and 360).
150
+ * @returns {number|Arc} If called without parameters, current value is returned; otherwise this Arc object is returned.
151
+ */
152
+ sweepAngle()
153
+ {
154
+ if(arguments.length > 0)
155
+ {
156
+ this._extent = Math.max(0, Math.min(360, parseFloat(arguments[0])));
157
+ this.update("min");
158
+ return this;
159
+ }
160
+
161
+ return this._extent;
162
+ }
163
+
164
+ /**
165
+ * Returns a JSON object that contains this shape properties. It may be converted back to this shape.
166
+ *
167
+ * @param {string} [include="all"] - Specified what to include. "all" is default. Valid values are: "all", "stroke", "background", "points", "basic".
168
+ * @return {object} Returns an object containing this shape's properties.
169
+ */
170
+ toObject(include = "all")
171
+ {
172
+ let obj = super.toObject(include);
173
+
174
+ if(this._type === "arc")
175
+ {
176
+ obj.size = this._size;
177
+ obj.hole_size = this._hole_size;
178
+ obj.start_angle = this._start_angle;
179
+ obj.extent = this._extent;
180
+ obj.arc_type = this._arc_type;
181
+ }
182
+
183
+ return obj;
184
+ }
185
+ }
@@ -0,0 +1,55 @@
1
+
2
+ import {UIComponent} from "./UIComponent.js";
3
+
4
+ /**
5
+ * Button UI component that extends UIComponent class.
6
+ * For more methods for this component check UIComponent class.
7
+ * @class
8
+ * @global
9
+ */
10
+ export class Button extends UIComponent
11
+ {
12
+ /**
13
+ * Button constructor.
14
+ *
15
+ * @param {string} [text] - Button text
16
+ * @example
17
+ * this.button1 = new Button().text("Click Me");
18
+ * this.button2 = new Button("Click Me");
19
+ */
20
+ constructor()
21
+ {
22
+ super("Button", (new.target === Button), ...arguments);
23
+
24
+ this.finalize(Button);
25
+ }
26
+
27
+ /**
28
+ * Sets or gets an action command. This command is specified in event object for onAction(e => {alert(e.command);}) event handler.
29
+ * Default value of action command for a Button is it's initial text.
30
+ *
31
+ * @param {string} [command] (Optional)
32
+ * @return {string|Button} If called without arguments, returns `number` value, otherwise returns `this` Button instance.
33
+ * @example
34
+ * const button = new Button("Activate").addTo(window).center();
35
+ * button.command("Activate Motor 1");
36
+ * button.onAction(e => {
37
+ * alert(e.command); // shows a dialog window with a message "Activate Motor 1" when button is clicked.
38
+ * });
39
+ */
40
+ command(...args)
41
+ {
42
+ if(args.length > 0 && typeof args[0] !== "string") args[0] = String(args[0]); // enforce string type
43
+ return this.property("actionCommand", args);
44
+ }
45
+
46
+ /**
47
+ * Returns current size of an icon, or `null` when no icon has been set or icon failed to load.
48
+ * @readonly
49
+ * @type {Size|null}
50
+ */
51
+ get iconSize()
52
+ {
53
+ return this.property("iconSize", []);
54
+ }
55
+ }
@@ -0,0 +1,33 @@
1
+
2
+ import {UIComponent} from "./UIComponent.js";
3
+
4
+ /**
5
+ * Check box UI component that extends UIComponent class.
6
+ * For more methods for this component check UIComponent class.
7
+ * @class
8
+ * @global
9
+ */
10
+ export class CheckBox extends UIComponent
11
+ {
12
+ /**
13
+ * CheckBox constructor.
14
+ *
15
+ * @param {string} [text] - Text displayed next to the checkbox
16
+ */
17
+ constructor()
18
+ {
19
+ super("CheckBox", (new.target === CheckBox), ...arguments);
20
+ this.finalize(CheckBox);
21
+ }
22
+
23
+ /**
24
+ * Sets or gets the selection state of the checkbox.
25
+ *
26
+ * @param {boolean} [selected] - `true` to select, `false` to deselect the checkbox.
27
+ * @return {boolean|CheckBox} If called without arguments, returns `boolean` value, otherwise returns `this` CheckBox instance.
28
+ */
29
+ selected()
30
+ {
31
+ return this.property("selected", arguments);
32
+ }
33
+ }
@@ -0,0 +1,24 @@
1
+
2
+ import {MenuItem} from "./MenuItem.js";
3
+
4
+ /**
5
+ * Check box menu item UI component that extends MenuItem class.
6
+ * For more methods for this component check MenuItem and UIComponent class.
7
+ * @class
8
+ * @global
9
+ * @see MenuItem
10
+ * @extends MenuItem
11
+ */
12
+ export class CheckBoxMenuItem extends MenuItem
13
+ {
14
+ /**
15
+ * Sets or gets boolean indicating whether this component is be selected.
16
+ *
17
+ * @param {boolean} selected - `true` to select, `false` to deselect.
18
+ * @return {CheckBoxMenuItem|boolean} Returns `this` CheckBoxMenuItem instance if argument is provided, otherwise returns `boolean` value.
19
+ */
20
+ selected()
21
+ {
22
+ return this.property("selected", arguments);
23
+ }
24
+ }
@@ -0,0 +1,329 @@
1
+
2
+ import {TextComponent} from "./TextComponent.js";
3
+
4
+ /**
5
+ * ComboBox UI component that extends UIComponent class.
6
+ * Check examples below and become familiar with a {@link ListItem} object format.
7
+ * @class
8
+ * @global
9
+ * @see ListItem
10
+ * @example
11
+ *
12
+ * // ListItem object format:
13
+ * ListItem {
14
+ * text: string, // Item text (required only for a new item).
15
+ * id: string|number, // Value that can be used by software logic to identify this item
16
+ * value: string|number, // Additional value to be stored in the item for later use.
17
+ * icon: string, // Absolute or relative path to icon image, base64 encoded image string, or `null` to remove icon.
18
+ * color: string, // Item text color as a 6 character hex encoded color string (e.g. #665500)
19
+ * background: string, // Item background color as a 6 character hex encoded color string (e.g. #665500)
20
+ * tooltip: string, // Tooltip text to show when pointer hover the item. (in List and Tree components only)
21
+ * font: Font // Object{name: string, size: number, bold: boolean, ...}. See complete list of font properties in example of font() method.
22
+ * }
23
+ */
24
+ export class ComboBox extends TextComponent
25
+ {
26
+ /**
27
+ * ComboBox constructor.
28
+ * Accepts an optional Array parameter: strings ["Item 1","Item 2", ...], numbers [1, 2, 3, ...], item objects [{text:"Item 1"}, {text:"Item 2"}, ...], or a mixture of them.
29
+ *
30
+ * @param {Array<string|number|ListItem>} [items] - Items as an Array of objects, strings or numbers. Can be a mix of these types. For item Object's format check out add() method example .
31
+ * @see ListItem
32
+ * @example
33
+ * // Creating combo box, then adding each item separately.
34
+ * const combo1 = new ComboBox().add("Item 1").add(45).add({text: "Item 2", font:{bolt:true}});
35
+ *
36
+ * // Creating combo box, then adding items as an array.
37
+ * const combo2 = new ComboBox().items([
38
+ * "Item 1",
39
+ * 45,
40
+ * {text: "Item 3", font:{bolt:true}}
41
+ * ]);
42
+ *
43
+ * // Creating combo box with items as a string and object. Items can be a mix of strings and objects.
44
+ * const combo3 = new ComboBox([
45
+ * "Item 1",
46
+ * 45,
47
+ * {text: "Item 3", font:{bolt:true}}
48
+ * ]);
49
+ */
50
+ constructor(...args) // accepts an optional parameter, array of string for list items
51
+ {
52
+ super("ComboBox", (new.target === ComboBox), ...args);
53
+ this.finalize(ComboBox, TextComponent);
54
+ }
55
+
56
+ /**
57
+ * Adds a list item at the end of the list, or inserts the item at specified index.
58
+ *
59
+ * @param {string|number|ListItem} item - List item as a string, number or a {@link ListItem} formatted object.
60
+ * @param {number} [index=undefined] - Integer position at which to add the item.
61
+ * @returns {number} Returns an index of the added item, or -1 if the item was not added.
62
+ * @see ListItem
63
+ * @example
64
+ * const i = combo1.add({text: "New Item", ...more optional properties}); // Adding item as object
65
+ * const i = combo1.add("New Item"); // Adding item as string
66
+ * const i = combo1.add(45); // Adding item as number
67
+ */
68
+ add(item, index = undefined)
69
+ {
70
+ // make sure that value is an object
71
+ if(typeof item !== "object") item = {id: item, text: String(item)};
72
+
73
+ if(index > -1) item.index = parseInt(index);
74
+ return ui.sendToGUI({control: this.id, get: "add", data: {item: item, index: index}}, r => r.value);
75
+ }
76
+
77
+ /**
78
+ * If index argument is specified, N amount of items starting form specified index will be removed.
79
+ * If called without parameters, this component will be removed from it's parent. See examples below.
80
+ *
81
+ * @param {number} [index=undefined] - Index of the item to remove. If not provided, the component will be removed from its parent.
82
+ * @returns {ComboBox} Returns `this` ComboBox instance for method chaining.
83
+ * @example
84
+ * combo.remove(); // removes the component from it's parent container
85
+ * combo1.remove(4); // removes list item at index 4
86
+ */
87
+ remove()
88
+ {
89
+ if(arguments.length > 0 && typeof arguments[0] !== "boolean")
90
+ {
91
+ // remove item at specified index
92
+ ui.sendToGUI({control: this.id, set: "removeItem", value: parseInt(arguments[0])});
93
+
94
+ return this;
95
+ }
96
+
97
+ // remove this element from it's parent (as usual)
98
+ return super.remove();
99
+ }
100
+
101
+ /**
102
+ * Gets the amount of items in the list.
103
+ * @readonly
104
+ * @type {number}
105
+ */
106
+ get length()
107
+ {
108
+ return ui.sendToGUI({control: this.id, get: "length"});
109
+ }
110
+
111
+ /**
112
+ * Gets, sets or updates an item at a specified index. Check usage examples below.
113
+ *
114
+ * @param {number} index - Index of the list item
115
+ * @param {ListItem} [item] - ListItem formatted object. See {@link ListItem} documentation.
116
+ * @param {boolean} [update=false] - `true` to update specified item properties with provided item properties, `false` to replace the item with new one. Default is `false`.
117
+ * @returns {ComboBox|ListItem} If item argument is passed, then `this` ComboBox instance is returned, otherwise item at specified index is returned. If index is out of range, `undefined` is returned.
118
+ * @see ListItem
119
+ * @example
120
+ * const item = combo1.item(3); // gets the item at index 3
121
+ * combo1.item(3, {text: "New text", value:"new value"}); // replaces item at index 3
122
+ * combo1.item(3, {background: "#FF7777"}, true); // changes item's background color at index 3
123
+ */
124
+ item(index)
125
+ {
126
+ if(typeof index !== "number") index = parseInt(i);
127
+ if(!Number.isSafeInteger(index) || index < 0) throw new Error(`Invalid "index" argument passed to List.item(i). A positive number is expected, but received a ${typeof arguments[0]}: ${arguments[0]}.`);
128
+
129
+ if(arguments.length > 1)
130
+ {
131
+ let item = arguments[1];
132
+
133
+ // make sure that value is an object
134
+ if(typeof item !== "object") item = {id: item, text: String(value)};
135
+
136
+ item.index = index;
137
+ item.update = (arguments.length > 2 && arguments[2] === true);
138
+
139
+ ui.sendToGUI({control: this.id, set: "item", value: item});
140
+ return this;
141
+ }
142
+ else
143
+ {
144
+ return ui.sendToGUI({control: this.id, get: "item", data: parseInt(index)});
145
+ }
146
+ }
147
+
148
+ /**
149
+ * Gets a selected item. Returns a selected item as a ListItem formatted object, or `null` if no item is selected.
150
+ *
151
+ * @readonly
152
+ * @type {ListItem|null}
153
+ */
154
+ get selectedItem()
155
+ {
156
+ return this.property("selectedItem", arguments) ?? null;
157
+ }
158
+
159
+ /**
160
+ * Sets or gets an index of a selected item. Can be used to make an item at certain index to be selected.
161
+ *
162
+ * @param {number} [index] - Index of an item to select. Set -1 to make no item be selected.
163
+ * @returns {ComboBox|number} If index is specified, then `this` component instance is returned, otherwise currently selected index is returned.
164
+ */
165
+ selectedIndex(...args)
166
+ {
167
+ if(args.length > 0) args[0] = parseInt(args[0]);
168
+ return this.property("index", args);
169
+ }
170
+
171
+ /**
172
+ * Selects and item that has a specified value, or gets a value of currently selected item.
173
+ *
174
+ * @param {string|number|null} [value] - Value of an item to be selected. Set `null` to make no item selected.
175
+ * @returns {ComboBox|number|string|null} If a `value` is specified, then `this` ComboBox instance is returned, otherwise a value of selected item is returned, or `null` if no item is selected.
176
+ */
177
+ selectedValue(...args)
178
+ {
179
+ return this.property("value", args);
180
+ }
181
+
182
+ /**
183
+ * Selects a first item whose `id` property matches provided `id`, or gets an `id` property of currently selected item.
184
+ *
185
+ * @param {string|number} [id] - ID of an item to be selected.
186
+ * @returns {ComboBox|number|string|null} If `id` parameter is specified, then `this` ComboBox instance is returned, otherwise an `id` of selected item is returned, or `null` if no item is selected.
187
+ */
188
+ selectedID(...args)
189
+ {
190
+ return this.property("id", args);
191
+ }
192
+
193
+ /**
194
+ *
195
+ * Sets or gets an array of list items. When setting, all existing items in the list will be removed before new ones are added.
196
+ *
197
+ * @param {Array<string|number|ListItem>} [items] - Items as an Array of objects, strings or numbers. Can be a mix of these types. For item Object's format check out add() method example .
198
+ * @returns {ComboBox|Array<ListItem>} When getting, an Array is returned, otherwise `this` component instance is returned.
199
+ */
200
+ items()
201
+ {
202
+ return this.property("items", arguments);
203
+ }
204
+
205
+ /**
206
+ * Removes all items.
207
+ * @return {ComboBox} Returns `this` component instance.
208
+ */
209
+ clear()
210
+ {
211
+ ui.sendToGUI({control: this.id, set: "clear"});
212
+ return this;
213
+ }
214
+
215
+ /**
216
+ * Shows or hides the popup list, or get a boolean whether the popup is visible.
217
+ *
218
+ * @param {bool} [visible] - `true` to show, `false` to hide.
219
+ * @return {ComboBox|boolean} Returns `this` component instance if argument is passed, otherwise returns `boolean` value indication if the popup list is currently visible.
220
+ */
221
+ open(...args)
222
+ {
223
+ if(args.length > 0) args[0] = (args[0] === true); // validate boolean input value
224
+ return this.property("open", args);
225
+ }
226
+
227
+ /**
228
+ * Registers, unregisters and gets a list of handler functions for the popup list events (when the popup becomes visible and hidden).
229
+ *
230
+ * @param {function(PopupEvent):any} [callback] - Handler function receiving {@link PopupEvent} object. Pass `null` to unregister all handler callbacks.
231
+ * @param {boolean} [remove] - Set to `true` to unregister the handler function.
232
+ * @return {function[]|ComboBox} Returns an array of registered handler functions if arguments are omitted, otherwise returns `this` component instance.
233
+ * @see PopupEvent
234
+ * @example
235
+ * // event Object format:
236
+ * const e = {
237
+ * target: object, // The component that triggered the event.
238
+ * type: string, // `show`, `hide`, `cancel`.
239
+ * x: number, // Component's X position
240
+ * y: number, // Component's Y position
241
+ * interactive: boolean, // Indicates if the popup was triggered by user's interaction (not programmatically).
242
+ * };
243
+ */
244
+ onPopupEvents(callback, ...args)
245
+ {
246
+ return this.event("onPopupEvents", callback, args[0] ?? false);
247
+ }
248
+
249
+ /**
250
+ * Sets or gets the maximum number of items to show in a popup list without having to scroll.
251
+ *
252
+ * @param {number} size - Defines the maximum amount of items that should be visible in the popup list without having to scroll.
253
+ * @return {ComboBox|number} Returns `number` value if argument is omitted, otherwise returns `this` component instance.
254
+ */
255
+ popupSize(...args)
256
+ {
257
+ if(args.length > 0) args[0] = parseInt(args[0]); // validate int input value
258
+ return this.property("popupSize", args);
259
+ }
260
+
261
+ /**
262
+ * Gets or sets a padding for each item in the list. See example below.
263
+ *
264
+ * @param {number|string} padding - Number for same padding on all sides, string to specify padding for each side "top right bottom left"
265
+ * @return {string|List} Returns `this` component instance if at least one argument is provided, otherwise returns current padding.
266
+ * @example
267
+ * combobox.itemPadding(3); // defines same padding for top, right, bottom and left.
268
+ * combobox.itemPadding("5 0 5 3"); // defines padding for each side separately, top=5, right=0, bottom=5 and left=3.
269
+ * const padding = combobox.itemPadding(); // gets the padding object
270
+ */
271
+ itemPadding(...args)
272
+ {
273
+ if(args.length === 0)
274
+ {
275
+ const padding = this.property("itemPadding", []);
276
+ return `${padding.top ?? 0} ${padding.right ?? 0} ${padding.bottom ?? 0} ${padding.left ?? 0}`;
277
+ }
278
+ else
279
+ {
280
+ let padding;
281
+
282
+ if(typeof args[0] === "string")
283
+ {
284
+ const nums = args[0].match(/\d+/g)?.map(Number).slice(0, 4) || [];
285
+ padding = {top: nums[0] ?? 0, right: nums[1] ?? 0, bottom: nums[2] ?? 0, left: nums[3] ?? 0};
286
+ }
287
+ else
288
+ {
289
+ args[0] = parseInt(args[0]);
290
+ padding = {top: args[0], right: args[0], bottom: args[0], left: args[0]};
291
+ }
292
+
293
+ return this.property("itemPadding", [padding]);
294
+ }
295
+ }
296
+
297
+ /**
298
+ * Finds first item whose text matches the string argument. If item is {text: "First Item", value: "item1"}, it should be found by passing value "First Item".
299
+ *
300
+ * @param {string} value - Search by this text
301
+ * @return {ListItem[]} Returns an array of found items. Each found item will have an `index` property fo convenience.
302
+ */
303
+ findByText(value)
304
+ {
305
+ return ui.sendToGUI({control: this.id, get: "findBy", data: {by: "text", q: value}});
306
+ }
307
+
308
+ /**
309
+ * Finds first item whose value matches the argument. If item is {text: "First Item", value: "item1", id: 1}, it should be found by passing value "item1".
310
+ *
311
+ * @param {string|number} value - Search by this text or number
312
+ * @return {ListItem[]} Returns an array of found items. Each found item will have an `index` property fo convenience.
313
+ */
314
+ findByValue(value)
315
+ {
316
+ return ui.sendToGUI({control: this.id, get: "findBy", data: {by: "value", q: value}});
317
+ }
318
+
319
+ /**
320
+ * Finds first item whose ID matches the argument. If item is {text: "First Item", value: "item1", id: 1}, it should be found by passing value 1.
321
+ *
322
+ * @param {string|number} value - Search by this text or number
323
+ * @return {ListItem[]} Returns an array of found items. Each found item will have an `index` property fo convenience.
324
+ */
325
+ findByID(value)
326
+ {
327
+ return ui.sendToGUI({control: this.id, get: "findBy", data: {by: "id", q: value}});
328
+ }
329
+ }