swing-ui 0.1.25 → 1.0.3

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 +2154 -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 +966 -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
@@ -0,0 +1,609 @@
1
+ import {ShapeContainer} from "./ShapeContainer.js";
2
+
3
+ /**
4
+ * Window UI component that extends ShapesContainer class which extends UIComponent.
5
+ * For more methods for this component check ShapesContainer and UIComponent classes.
6
+ *
7
+ * @glass
8
+ * @global
9
+ * @example <h2>To create a new custom window class (recommended way for main window):</h2>
10
+ * class MyWindow extends Window
11
+ * {
12
+ * constructor()
13
+ * {
14
+ * super("My New Application"); //
15
+ * }
16
+ * }
17
+ *
18
+ * // appWindow1 will be accessible globally.
19
+ * globalThis.appWindow1 = new MyWindow();
20
+ */
21
+ class Window extends ShapeContainer
22
+ {
23
+ _shapes = [];
24
+ temp_token = undefined;
25
+
26
+ #owner = null; // used only for modal window
27
+ #prop = {
28
+ closeOperation: Window.CloseOperation.Exit,
29
+ innerOffset: null
30
+ };
31
+
32
+ /**
33
+ * Represents the behavior when a close button is clicked or close() method is called.
34
+ * Applies to {@link Window} and {@link InternalWindow} components.
35
+ *
36
+ * @readonly
37
+ * @enum {number}
38
+ * @property {number} Nothing - Do nothing; the close button has no effect. WindowEvent with type "closing" still gets emitted to report intent to close.
39
+ * @property {number} Hide - Hide the window instead of closing it.
40
+ * @property {number} Dispose - Release window resources and remove it from display. Emits 2 WindowEvent events, with type "closing" and with "close".
41
+ * @property {number} Exit - Terminate the entire application. Emits 2 WindowEvent events, with type "closing" and with "close".
42
+ * @see Window
43
+ * @see InternalWindow
44
+ * @example
45
+ * window.closeOperation(Window.CloseOperation.Exit); // setting most common window close operation
46
+ */
47
+ static CloseOperation = Object.freeze({Nothing: 0, Hide: 1, Dispose: 2, Exit: 3});
48
+
49
+ /**
50
+ * Represents the display state of a {@link Window}. Pass one of these values to {@link Window#state} to get or set the Window's current state.
51
+ *
52
+ * @readonly
53
+ * @enum {number}
54
+ * @property {number} Normal - The window is in its default, restored state (not minimized or maximized).
55
+ * @property {number} Minimized - The window is collapsed to the taskbar or dock.
56
+ * @property {number} Maximized - The window is expanded to fill the entire application area on the screen.
57
+ * @property {number} MaximizedHorizontally - The window is maximized horizontally but not vertically. Doesn't apply to {@link InternalWindow} component.
58
+ * @property {number} MaximizedVertically - The window is maximized vertically but not horizontally. Doesn't apply to {@link InternalWindow} component.
59
+ * @see Window#state
60
+ * @see Window#minimize
61
+ * @see Window#maximize
62
+ * @see InternalWindow#state
63
+ * @example <h2>Checking and setting Window state</h2>
64
+ * if(window.state() === Window.State.Minimized)
65
+ * {
66
+ * window.state(Window.State.Normal);
67
+ * }
68
+ */
69
+ static State = Object.freeze({
70
+ Normal: 0,
71
+ Minimized: 1,
72
+ Maximized: 2,
73
+ MaximizedHorizontally: 3,
74
+ MaximizedVertically: 4
75
+ });
76
+
77
+ /**
78
+ * Represents the type of the window. Used when creating or modifying a window's appearance or behavior.
79
+ *
80
+ * @readonly
81
+ * @enum {number}
82
+ * @property {number} Normal - A standard, resizable window with borders, title bar and a taskbar button.
83
+ * @property {number} Borderless - A window with a task bar button, but without border and title bar.
84
+ * @property {number} Utility - A smaller utility window without a taskbar button, typically used for tools or palettes.
85
+ * @property {number} Popup - A popup window, usually without a title bar, borders and taskbar button.
86
+ * @see Window#type
87
+ * @example
88
+ * let window = ne Window("New window", parent_window, Window.Type.Utility);
89
+ */
90
+ static Type = Object.freeze({Normal: 0, Borderless: 1, Utility: 2, Popup: 3});
91
+
92
+ /**
93
+ * Window component constructor.
94
+ *
95
+ * @param {string} [text] - Text displayed in Window title bar and in task bar button.
96
+ * @param {Window} [owner_window=null] - Enables modal mode. This new Window will always be on top of the owner Window until it is closed.
97
+ * @param {Window.Type} [windowType=Window.Type.Normal] - Type of the Window.
98
+ * @see Window.Type
99
+ * @see Window.CloseOperation
100
+ * @example <h2>3 ways to create a new Window:</h2>
101
+ * new Window() // without title text D789
102
+ * new Window("Window Title Text") // width title text
103
+ * new Window("Window Title Text", owner_window, Window.Type.Utility) // for modal window
104
+ */
105
+ constructor(...args)
106
+ {
107
+ if(args.length > 1 && args[1] != null && !(args[1] instanceof Window))
108
+ {
109
+ throw new Error(`Passed owner of the Windows must be also a Window. Received ${typeof args[1]}`);
110
+ }
111
+
112
+ const arg = {};
113
+
114
+ if(args.length > 0 && typeof args[0] === "string") arg.text = args[0];
115
+ if(arg.text === undefined) delete arg.text;
116
+
117
+ if(args[1] != null && args[1] instanceof Window) arg.owner = args[1].id; // set owner Window if provided, making this window modal
118
+ if(args.length > 2) arg.type = args[2];
119
+
120
+ super("Frame", (new.target === Window), ...(Object.keys(arg).length > 0 ? [arg] : []));
121
+
122
+ if("owner" in arg) this.#owner = args[1];
123
+
124
+ // callback to clear innerOffset cache on UI change
125
+ const clearOffset = e => {this.#prop.innerOffset = null;};
126
+ ui.onUIChange(clearOffset); // register callback
127
+ this.onDispose(e => {ui.onUIChange(clearOffset, true);}); // unregister callback
128
+
129
+ //this.finalize(ShapeContainer, Window);
130
+
131
+ // load UI definition file
132
+ if(new.target !== Window && this.applyUIDefinition != null) this.applyUIDefinition(new.target.name); // must be called AFTER super()
133
+ }
134
+
135
+ /**
136
+ * Returns Window component that is set as an owner of this Window, or `null` if owner Window was not set.
137
+ *
138
+ * @readonly
139
+ * @type {Window|null}
140
+ */
141
+ get owner()
142
+ {
143
+ return this.#owner;
144
+ }
145
+
146
+ /**
147
+ * Gets the current Window type.
148
+ *
149
+ * @readonly
150
+ * @type {Window.Type}
151
+ * @see Window#Type
152
+ */
153
+ get type()
154
+ {
155
+ return this.property("type", []);
156
+ }
157
+
158
+ /**
159
+ * Returns the size of the screen that the Window occupies. If the Window is not on any screen, then returns default screen's size. If the Window was never displayed on a screen, then `null` is returned.
160
+ *
161
+ * @readonly
162
+ * @type {Size}
163
+ */
164
+ get screenSize()
165
+ {
166
+ return this.property("screenSize");
167
+ }
168
+
169
+ /**
170
+ * Returns an offset of each side of content pane of the Window relative to Window's edges. See example below:
171
+ *
172
+ * @readonly
173
+ * @type {Object}
174
+ * @example
175
+ * // Returned object format:
176
+ * {
177
+ * top: number,
178
+ * right: number,
179
+ * bottom: number,
180
+ * left: number
181
+ * }
182
+ */
183
+ get innerOffset()
184
+ {
185
+ if(this.#prop.innerOffset == null) this.#prop.innerOffset = this.property("innerOffset", []);
186
+ return this.#prop.innerOffset;
187
+ }
188
+
189
+ /**
190
+ * Sets or gets the operation to perform when a Window close button is clicked by a user or a close() method is called on this Window.
191
+ *
192
+ * @param {Window.CloseOperation} [operation] - One of Window.CloseOperation enum values. Default is Window.CloseOperation.Close.
193
+ * @return {Window|Window.CloseOperation} Returns `this` component if argument is provided, otherwise returns value.
194
+ */
195
+ closeOperation(...args)
196
+ {
197
+ if(args.length === 0) return this.#prop.closeOperation;
198
+
199
+ this.#prop.closeOperation = args[0];
200
+ return this.property("closeOperation", args);
201
+ }
202
+
203
+ /**
204
+ * Gets, registers or unregisters an event handler for when the state of the Window changes between normal, minimized, maximized.
205
+ *
206
+ * @param {function(WindowStateEvent): any} [callback] - The event handler function receiving {@link WindowStateEvent} event object.
207
+ * @param {boolean} [remove=false] - Set to `true` to unregister the event handler.
208
+ * @returns {this}
209
+ * @see Window#State
210
+ * @example
211
+ * // Example event object:
212
+ * const e = {
213
+ * target: Window, // The component that triggered the event.
214
+ * type: string, // `change`
215
+ * oldValue: Window.State, // Previous state
216
+ * newValue: Window.State, // New state
217
+ * interactive: boolean // Indicates if the state was changed by user's interaction with window
218
+ * };
219
+ */
220
+ onStateChange(...args)
221
+ {
222
+ if(args.length === 0) return this.event("onStateChange");
223
+ return this.event("onStateChange", args[0], args[1] ?? false);
224
+ }
225
+
226
+ /**
227
+ * Gets, registers or unregisters an event handler for window events, such as activate, deactivate, closed, etc.
228
+ *
229
+ * @param {function(WindowEvent): any} [callback] - The event handler function receiving {@link WindowEvent} event object.
230
+ * @param {boolean} [remove=false] - Set to `true` to unregister the event handler.
231
+ * @returns {this}
232
+ *
233
+ * @example
234
+ * // Example event object:
235
+ * const e = {
236
+ * target: Window, // The component that triggered the event.
237
+ * type: string, // `activate`, `deactivate`, `minimize`, `restore`, `closing`, `close`, `show`
238
+ * interactive: boolean // Indicates if triggered by user's interaction with window
239
+ * };
240
+ */
241
+ onWindowEvents(...args)
242
+ {
243
+ if(args.length === 0) return this.event("onWindowEvents");
244
+ return this.event("onWindowEvents", args[0], args[1] ?? false);
245
+ }
246
+
247
+ /**
248
+ * Performs previously specified close operation on this Window.
249
+ * To specify what operation should be performed use closeOperation(Window.CloseOperation.[Nothing|Exit|Hide|Dispose])
250
+ *
251
+ * @return {Window} Returns this window component
252
+ */
253
+ close()
254
+ {
255
+ switch(this.#prop.closeOperation)
256
+ {
257
+ case Window.CloseOperation.Dispose:
258
+ {
259
+ this.emit("onWindowEvents", {type: "closing", interactive: false});
260
+ this.emit("onWindowEvents", {type: "close", interactive: false});
261
+
262
+ ui.sendToGUI({control: this.id, set: "close"});
263
+
264
+ this.destroy();
265
+ break;
266
+ }
267
+ case Window.CloseOperation.Hide:
268
+ {
269
+ this.hide();
270
+ break;
271
+ }
272
+ case Window.CloseOperation.Exit:
273
+ {
274
+ this.emit("onWindowEvents", {type: "closing", interactive: false});
275
+ this.emit("onWindowEvents", {type: "close", interactive: false});
276
+ this.emit("onDispose", {type: "dispose"});
277
+ ui.sendToGUI({control: this.id, set: "close"});
278
+ ui.exit(0);
279
+ break;
280
+ }
281
+ case Window.CloseOperation.Nothing:
282
+ {
283
+ ui.sendToGUI({control: this.id, set: "close"});
284
+ break;
285
+ }
286
+ }
287
+
288
+ return this;
289
+ }
290
+
291
+ /**
292
+ * Shows a dialog window asking user to confirm your message. User has an option to press OK or Cancel, which result in returned values `true` or `false` respectively.
293
+ *
294
+ * @param {string} message - Message to show in dialog window.
295
+ * @return {boolean} Returns `boolean` indicating if user confirmed the message or not.
296
+ */
297
+ confirm(message)
298
+ {
299
+ return ui.sendToGUI({control: this.id, get: "showConfirmDialog", data: message});
300
+ }
301
+
302
+ /**
303
+ * Opens file/directory chooser dialog window. Check example for all possible options.
304
+ *
305
+ * @param {FileChooserOptions} options - JSON Object with valid options. See example for full list of options.
306
+ * @returns {string|string[]|null} Returns `string` path if `multiple` option is `false`, `string[]` if `multiple` option is `true`, or `null` if file chooser was closed without making a selection.
307
+ * @example
308
+ * window.chooseFile({
309
+ * directory: false, // `true` for Directory selection, `false` for Files.
310
+ * save: true, // `true` for `Save` dialog box, `false` for `Open`.
311
+ * multiple: false, // [true|false] to be able to select multiple files/folders.
312
+ * hidden:false, // [true|false] to show hidden files.
313
+ * filter:"Documents:doc,docx,txt,rtf|Music:mp3,m4a,ogg,wma|Images:gif,jpg,jpeg,bmp,webp", // File extension can have multiple "." characters, such as "file.d.ts".
314
+ * path:"Initial-Path/file.ext" // Default path to open in the dialog window.
315
+ * });
316
+ * @see FileChooserOptions
317
+ */
318
+ chooseFile(options)
319
+ {
320
+ return ui.sendToGUI({control: this.id, get: "showFileChooser", data: options}, null, true);
321
+ }
322
+
323
+ /**
324
+ * Opens color chooser dialog window.
325
+ *
326
+ * @param {string} [title] - Dialog window title text
327
+ * @param {string} [initial_color] - Default color to show in dialog window before a new one is chosen.
328
+ * @returns {string|null} Returns a string of a chosen color.
329
+ */
330
+ chooseColor(title = "Choose Color", initial_color = "#000000")
331
+ {
332
+ return ui.sendToGUI({
333
+ control: this.id,
334
+ get: "showColorPicker",
335
+ data: {title: title, default: initial_color}
336
+ }, null, true);
337
+ }
338
+
339
+ /**
340
+ * Opens font chooser dialog window.
341
+ *
342
+ * @param {string} [title] - Dialog window title text
343
+ * @param {Object} [initial_font] - Pre-fills dialog window with specified font properties.
344
+ * @returns {Object|null} Returns a new chosen font object or `null` if font was not selected.
345
+ */
346
+ chooseFont(title = "Choose Font", initial_font = {})
347
+ {
348
+ return ui.sendToGUI({control: this.id, get: "showFontChooser", data: {title: title, font: initial_font}});
349
+ }
350
+
351
+ /**
352
+ * Sets or get a window state. Use one of these enum values: Window.State.[Normal|Minimized|Maximized|MaximizedHorizontally|MaximizedVertically]
353
+ *
354
+ * @param {Window.State} [state] - Setting new window state
355
+ * @returns {Window.State|Window} Returns `this` Window if argument is provided, otherwise returns current state.
356
+ * @see Window#State
357
+ * @example
358
+ * window.state(Window.State.Maximized);
359
+ * if(window.state() === Window.State.Maximized) console.log("It works!");
360
+ */
361
+ state()
362
+ {
363
+ if(arguments.length > 0) arguments[0] = parseInt(arguments[0]);
364
+ return this.property("state", arguments);
365
+ }
366
+
367
+ /**
368
+ * Convenience method to minimize the Window by setting Window state to Window.State.Minimized.
369
+ *
370
+ * @return {Window} Returns `this` Window.
371
+ * @see Window#State
372
+ * @see Window#state
373
+ * @see Window#maximize
374
+ */
375
+ minimize()
376
+ {
377
+ return this.state(Window.State.Minimized);
378
+ }
379
+
380
+ /**
381
+ * Convenience method to maximize the Window by setting Window state to Window.State.Maximized.
382
+ *
383
+ * @return {Window} Returns `this` Window.
384
+ * @see Window#State
385
+ * @see Window#state
386
+ * @see Window#minimize
387
+ */
388
+ maximize()
389
+ {
390
+ return this.state(Window.State.Maximized);
391
+ }
392
+
393
+ /**
394
+ * Sets or returns the index or the screen that the Window is on.
395
+ *
396
+ * @args {number} [index] - Index of the screen where to move this Window. To get a list of screens with indexes use ui.screens().
397
+ * @return {Window|number} Returns `this` Window if argument is provided, otherwise returns index of the screen this Window is on.
398
+ */
399
+ screen()
400
+ {
401
+ return this.property("screen", arguments);
402
+ }
403
+
404
+ /**
405
+ * Sets or gets a default button in this window form. On some systems like Windows OS default button has a different look than other buttons.
406
+ *
407
+ * @param {Button} button - The button that should be default on this Window. Only last assigned button gets to be default.
408
+ * @return {Button|undefined}
409
+ */
410
+ defaultButton(...args)
411
+ {
412
+ if(args.length > 0)
413
+ {
414
+ if(!(args[0] instanceof Button)) throw new Error("Default button of a Window must be of type Button. " + (typeof args[0]) + " was given.");
415
+ return this.property("defaultButton", [args[0].id]);
416
+ }
417
+ else
418
+ {
419
+ const id = this.property("defaultButton", []);
420
+ const btn = UIComponent.get(id);
421
+ return btn instanceof Button ? btn : undefined;
422
+ }
423
+ }
424
+
425
+ /**
426
+ * Sets or gets a size of content container of this Window (doesn't include the size of the window borders and a menu bar like size() function does).
427
+ *
428
+ * @param {number|Size} [width_or_size] - Width integer or a Size object as a sole parameter.
429
+ * @param {number} [height] - Integer height value (required if the first argument is a numeric width).
430
+ * @return {Size|Window} Returns `this` Window if called with parameters, otherwise returns the inner size.
431
+ * @see Size
432
+ */
433
+ innerSize(...args)
434
+ {
435
+ if(args.length > 0)
436
+ {
437
+ if(args[0] == null) return this;
438
+
439
+ let size = undefined;
440
+
441
+ if(typeof args[0] === "object")
442
+ {
443
+ if(!("width" in args[0]) || !("height" in args[0])) return this;
444
+ size = {width: Number.parseInt(args[0].width), height: Number.parseInt(args[0].height)}
445
+ }
446
+ else if(args.length > 1)
447
+ {
448
+ size = {width: Number.parseInt(args[0]), height: Number.parseInt(args[1])};
449
+ }
450
+ else return this;
451
+
452
+ if(size.width < 0 || size.height < 0) return this;
453
+
454
+ const offset = this.innerOffset;
455
+ this.#prop.size = {width: size.width + offset.left + offset.right, height: size.height + offset.top + offset.bottom};
456
+
457
+ return this.property("innerSize", [size]);
458
+ }
459
+
460
+ return this.property("innerSize", []);
461
+ }
462
+
463
+ /**
464
+ * Indicates the minimum size the content container of the Window it can be resized to. It overrides previously set minSize() value.
465
+ *
466
+ * @param {number|Size} width_or_size - Width, or a Size formatted object as a sole parameter.
467
+ * @param {number} height - Height of the component.
468
+ * @returns {Size|Window|null} If called without parameters, current minimum inner Size is returned or `null` if it wasn't previously set; otherwise returns `this` component instance for chaining.
469
+ * @see Window#maxInnerSize
470
+ * @see UIComponent#minSize
471
+ * @see Size
472
+ */
473
+ minInnerSize(...args)
474
+ {
475
+ if(args.length > 0)
476
+ {
477
+ let s = (typeof args[0] === "object") ? args[0] : {width: args[0], height: args[1]};
478
+
479
+ // add offset
480
+ const offset = this.innerOffset;
481
+ s.x += offset.left + offset.right;
482
+ s.y += offset.top + offset.bottom;
483
+
484
+ return this.minSize(s);
485
+ }
486
+ else
487
+ {
488
+ let s = this.minSize();
489
+
490
+ if(s == null) return null;
491
+
492
+ // subtract offset
493
+ const offset = this.innerOffset;
494
+ s.x -= (offset.left + offset.right);
495
+ s.y -= (offset.top + offset.bottom);
496
+
497
+ return s;
498
+ }
499
+ }
500
+
501
+ /**
502
+ * Indicates the maximum size the content container of the Window it can be resized to. It overrides previously set maxSize() value.
503
+ *
504
+ * @param {number|Size} width_or_size - Width, or a Size formatted object as a sole parameter.
505
+ * @param {number} height - Height of the component.
506
+ * @returns {Size|Window|null} If called without parameters, current maximum inner Size is returned or `null` if it wasn't previously set; otherwise returns `this` component instance for chaining.
507
+ * @see Window#minInnerSize
508
+ * @see UIComponent#maxSize
509
+ * @see Size
510
+ */
511
+ maxInnerSize(...args)
512
+ {
513
+ if(args.length > 0)
514
+ {
515
+ let s = (typeof args[0] === "object") ? args[0] : {width: args[0], height: args[1]};
516
+
517
+ // add offset
518
+ const offset = this.innerOffset;
519
+ s.x += offset.left + offset.right;
520
+ s.y += offset.top + offset.bottom;
521
+
522
+ return this.maxSize(s);
523
+ }
524
+ else
525
+ {
526
+ let s = this.maxSize();
527
+
528
+ if(s == null) return null;
529
+
530
+ // subtract offset
531
+ const offset = this.innerOffset;
532
+ s.x -= (offset.left + offset.right);
533
+ s.y -= (offset.top + offset.bottom);
534
+
535
+ return s;
536
+ }
537
+ }
538
+
539
+ /**
540
+ * Sets or gets whether window should always stay on top of other windows.
541
+ *
542
+ * @param {boolean} [value] - Set Window to be on top or not
543
+ * @return {Window|boolean} Returns `this` Window if arguments are supplied, otherwise returns `boolean` value.
544
+ */
545
+ alwaysOnTop(...args)
546
+ {
547
+ return this.property("alwaysOnTop", args.length > 0 ? [args[0] === true] : []);
548
+ }
549
+
550
+ /**
551
+ * Sets or gets the main menu bar for the top of the Window. On macOS, this menu bar appears in the system's top menu bar.
552
+ *
553
+ * @param {MenuBar} [bar] - The `MenuBar` to set as the primary menu bar.
554
+ * @returns {Window|MenuBar|null} Returns the `Window` instance when setting a menu bar; otherwise, returns the currently set `MenuBar`, or `null` if none is set.
555
+ */
556
+ menuBar(...args)
557
+ {
558
+ if(args.length === 0) return this.#prop.menuBar ?? null;
559
+
560
+ let menuBar = args[0];
561
+
562
+ if(menuBar == null) // remove context menu
563
+ {
564
+ if(this.#prop.menuBar != null)
565
+ {
566
+ this.#prop.menuBar = null;
567
+ this.#prop.innerOffset = null; // reset offset because it changed
568
+ return this.property("menuBar", [null]);
569
+ }
570
+ return this;
571
+ }
572
+ else if(menuBar instanceof globalThis.MenuBar) // add context menu. // can't use !(menu instanceof MenuBar) because MenuBar imports this class, thus would create circular import.
573
+ {
574
+ this.#prop.menuBar = menuBar;
575
+ this.#prop.innerOffset = null; // reset offset because it changed
576
+ return this.property("menuBar", [menuBar.id]);
577
+ }
578
+ else
579
+ {
580
+ error(ui._msg[11]);
581
+ return this;
582
+ }
583
+ }
584
+
585
+ /**
586
+ * Sets of get whether the window may be resized by end user.
587
+ *
588
+ * @param {boolean} [value] - Enables/disables resizing
589
+ * @return {Window|boolean} Returns `this` Window if argument is supplied, otherwise returns `boolean` value.
590
+ */
591
+ resizable(...args)
592
+ {
593
+ return this.property("resizable", args);
594
+ }
595
+
596
+ /**
597
+ * Sets or gets component opacity float value between 0 and 1 inclusive. Opacity can be set only to Windo with types {@link Window.Type.Borderless} or {@link Window.Type.Popup}.
598
+ *
599
+ * @param {number} [opacity] - A number between 0 and 1 inclusive.
600
+ * @return {number|this} If `opacity` argument is provided, `this` component is returned, otherwise opacity `number` is returned.
601
+ */
602
+ opacity(...args)
603
+ {
604
+ return this.property("opacity", args);
605
+ }
606
+
607
+ }
608
+
609
+ export {Window};