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
@@ -0,0 +1,504 @@
1
+
2
+ import {UIComponent} from "./UIComponent.js";
3
+
4
+ /**
5
+ * Media player is an audio and video player component capable of playing video & audio files, video & audio live streams, video & audio from URL, and from audio & video capture devices, like microphone, web cam and other video capture devices.
6
+ * It's done with the help of pre-installed FFMPEG, so FFMPEG is required to be installed for this to work. FFMPEG is a free open-source software.
7
+ * @class
8
+ * @global
9
+ * @example <h2>Examples of formats of commonly used objects with media player:</h2>
10
+ *
11
+ * VideoDevice {
12
+ * [name]: string, // Name of the video input device.
13
+ * id: string, // ID if the video input device.
14
+ * [formats]: VideoFormat[],// Available video formats (present only when getting video input devices)
15
+ * [format]: VideoFormat // Chosen video format to use (required when setting a video input device).
16
+ * }
17
+ *
18
+ * VideoFormat {
19
+ * size: string, // Video frame size in pixels
20
+ * pixel_format: string // Frame image encoding coming out of the device (e.g.: "yuyv422")
21
+ * [fps]: number // (required only when setting a video input device)
22
+ * [min_fps]: number, // Minimum available frame rate. For example 7.5 fps.
23
+ * [max_fps]: number, // Maximum available frame rate. For example 30 fps.
24
+ * }
25
+ *
26
+ * AudioDevice {
27
+ * [name]: string, // Name of audio device.
28
+ * id: string, // ID of audio device. (required when setting an audio device).
29
+ * [formats]: AudioFormats[], // Available audio formats (present only when getting audio devices).
30
+ * [format]: AudioFormat, // Audio format to use (required when setting an audio device).
31
+ * }
32
+ *
33
+ * AudioFormat {
34
+ * channels: number, // Audio channels available
35
+ * bits: number, // Bits per sample
36
+ * [rate]: number, // Sample rate in Hz. It's only used for audio input device formats (not output). Set it when setting an audio output device.
37
+ * [encoding]: string // Audio encoding (e.g.: PCM_UNSIGNED, PCM_SIGNED). (Only available in audio output device formats).
38
+ * }
39
+ */
40
+ export class MediaPlayer extends UIComponent
41
+ {
42
+ /**
43
+ * Enum for media player states.
44
+ *
45
+ * @readonly
46
+ * @enum {number}
47
+ * @property {number} NoMedia - No media loaded.
48
+ * @property {number} Stopped - Media is stopped.
49
+ * @property {number} Playing - Media is playing.
50
+ * @see MediaPlayer#state
51
+ * @example
52
+ * if(player.state === MediaPlayer.State.Playing)
53
+ * {
54
+ * console.log("Player is playing");
55
+ * }
56
+ */
57
+ static State = Object.freeze({NoMedia: 0, Stopped: 1, Playing: 2});
58
+
59
+ /**
60
+ * Enum for video interpolation methods. Used to smooth resized video and reduce pixelation.
61
+ *
62
+ * @readonly
63
+ * @enum {number}
64
+ * @property {number} None - No interpolation applied.
65
+ * @property {number} ByGUI - Interpolation performed by the GUI.
66
+ * @property {number} ByFFMPEG - Interpolation performed by FFMPEG.
67
+ * @example
68
+ * player.interpolation(MediaPlayer.Interpolation.ByFFMPEG);
69
+ */
70
+ static Interpolation = Object.freeze({None: 0, ByGUI: 1, ByFFMPEG: 2});
71
+
72
+ /**
73
+ * Enum for subtitle background styles. Used to enhance subtitle readability over video. Background color can be changed by {@link MediaPlayer#subtitleBackground}
74
+ *
75
+ * @readonly
76
+ * @enum {number}
77
+ * @property {number} None - Subtitles not visible (only sent as a player event).
78
+ * @property {number} Plain - Visible but without a background.
79
+ * @property {number} Shadow - Subtitle has a shadow background. (Default)
80
+ * @property {number} Box - Subtitle is placed inside a solid box.
81
+ * @property {number} RoundBox - Subtitle is placed inside a solid box with rounded corners.
82
+ * @see MediaPlayer#subtitleStyle
83
+ * @see MediaPlayer#subtitleBackground
84
+ * @example
85
+ * player.subtitleStyle(MediaPlayer.SubtitleStyle.Box);
86
+ */
87
+ static SubtitleStyle = Object.freeze({None: 0, Plain: 1, Shadow: 2, Box: 3, RoundBox: 4});
88
+
89
+ #SourceType = {File: 0, URL: 1, InputDevice: 2};
90
+ #source = null; // {type: SourceType, ...}
91
+
92
+ /**
93
+ * Initializes the MediaPlayer UI component.
94
+ * @see VideoDevice
95
+ * @see AudioDevice
96
+ * @see VideoFormat
97
+ * @see AudioFormat
98
+ */
99
+ constructor()
100
+ {
101
+ super("MediaPlayer", (new.target === MediaPlayer));
102
+
103
+ this.finalize(MediaPlayer);
104
+ }
105
+
106
+ /**
107
+ * Sets the path to ffmpeg executable file, preferably absolute path. Default is `ffmpeg`, and it requires the path to ffmpeg to be added to `Path` environment variable.
108
+ * When setting path, `boolean` is returned whether path is valid and accepted.
109
+ * When getting value, `string` of previously specified or default value is returned.
110
+ *
111
+ * @param {string} [path] - Path to the executable FFMPEG file. Default path is "ffmpeg".
112
+ * @return {boolean|string} Returns `string` path when getting, or `boolean` when setting. `boolean` indicates if specified path was accepted (if it exists).
113
+ */
114
+ static ffmpegPath(...args)
115
+ {
116
+ const req = {system: "ffmpegPath"};
117
+ if(args.length > 0) req.value = args[0];
118
+ return ui.sendToGUI(req, (r) => {return r.value;});
119
+ }
120
+
121
+ /**
122
+ * Sets a path of a local media file as a new media source. Resets player and overrides previously set source.
123
+ *
124
+ * @param {string} path - Path to media file.
125
+ * @param {number} [videoStream] - If the media file has more than one video stream, specify which one to use. Default is 0. For audio-only files this is ignored.
126
+ * @param {number} [audioStream] - If the media file has more than one audio stream (such as multiple languages), specify which one to use. Default is 0. For media without audio stream this is ignored.
127
+ * @param {number|string|null} [subtitleStream=null] - Index of a subtitle stream or a subtitles file path. Default is `null` for no subtitles.
128
+ * @return {MediaPlayer} Returns `this` component instance.
129
+ */
130
+ setFile(path, videoStream = 0, audioStream = 0, subtitleStream = null)
131
+ {
132
+ this.#source = {
133
+ type: this.#SourceType.File,
134
+ path: path,
135
+ videoStream: videoStream,
136
+ audioStream: audioStream,
137
+ subtitleStream: subtitleStream
138
+ };
139
+
140
+ return this.property("source", [this.#source]);
141
+ }
142
+
143
+ /**
144
+ * Sets URL of the media source. Resets player and overrides previously set source.
145
+ *
146
+ * @param {string} url - URL of media.
147
+ * @param {number} [videoStream] - If the media has more than one video stream, specify which one to use. Default is 0. For audio-only files this is ignored.
148
+ * @param {number} [audioStream] - If the media has more than one audio stream (such as multiple languages), specify which one to use. Default is 0. For media without audio stream this is ignored.
149
+ * @param {number|null} [subtitleStream=null] - Index of a subtitle stream. There may be multiple streams in case of multiple languages. Default is NULL for no subtitles.
150
+ * @param {string|null} [format] - Recommended to set for live video streams, such as web cam stream. This value is set as "-input_format" option for FFMPEG command. For example: mjpeg, rtsp, flv, mpegts, hls, http, https, srt or icecast.
151
+ * @param {boolean} [lowLatency] - Set to TRUE to use ffmpeg options for low latency for live video streams (ffmpeg options such as low buffering).
152
+ * @return {MediaPlayer} Returns `this` component instance.
153
+ */
154
+ setURL(url, videoStream = 0, audioStream = 0, subtitleStream = null, format = null, lowLatency = false)
155
+ {
156
+ this.#source = {
157
+ type: this.#SourceType.URL,
158
+ url: url,
159
+ videoStream: videoStream,
160
+ audioStream: audioStream,
161
+ subtitleStream: subtitleStream,
162
+ format: format,
163
+ lowLatency: lowLatency
164
+ };
165
+
166
+ return this.property("source", [this.#source]);
167
+ }
168
+
169
+ /**
170
+ * Sets video device and audio device to use as video and audio source. Resets player and overrides previously set source.
171
+ * To get a list of available devices and their details getters {@link MediaPlayer#videoInputDevices} and {@link MediaPlayer#audioInputDevices} can be used.
172
+ *
173
+ * @param {VideoDevice|null} videoDevice - Video device object (camera or video capture card). Set to `null` to omit video device.
174
+ * @param {AudioDevice|null} [audioDevice=undefined] - Audio device object (microphone, audio capture card or system audio). Omit or set to `null` to omit audio device.
175
+ * @return {MediaPlayer} Returns `this` component instance.
176
+ */
177
+ setInputDevice(videoDevice, audioDevice = undefined)
178
+ {
179
+ this.#source = {type: this.#SourceType.InputDevice};
180
+ if(videoDevice != null) this.#source.video = videoDevice;
181
+ if(audioDevice != null) this.#source.audio = audioDevice;
182
+
183
+ return this.property("source", [this.#source]);
184
+ }
185
+
186
+ /**
187
+ * Sets or gets current playing time in seconds. Decimal points are allowed (e.g. player.seek(165.43); ).
188
+ *
189
+ * @param {number} [seconds] - Sets seek time in seconds. Two decimal points allowed for more precision.
190
+ * @return {MediaPlayer} Returns `this` component instance.
191
+ */
192
+ seek(...args)
193
+ {
194
+ if(this.#source == null) return "Media source not set";
195
+
196
+ return this.property("seek", args);
197
+ }
198
+
199
+ /**
200
+ * Makes the media player start media playback (assuming that media was previously specified using setFile(), setURL() or setInputDevice() functions).
201
+ *
202
+ * @return {MediaPlayer} Returns `this` component instance.
203
+ */
204
+ play()
205
+ {
206
+ return this.property("control", ["play"]);
207
+ }
208
+
209
+ /**
210
+ * Makes media player pause the playback.
211
+ *
212
+ * @return {MediaPlayer} Returns `this` component instance.
213
+ */
214
+ pause()
215
+ {
216
+ return this.property("control", ["pause"]);
217
+ }
218
+
219
+ /**
220
+ * Makes media player stop the playback. Seek time resets to 0, so play() function would start the playback from beginning.
221
+ *
222
+ * @return {MediaPlayer} Returns `this` component instance.
223
+ */
224
+ stop()
225
+ {
226
+ return this.property("control", ["stop"]);
227
+ }
228
+
229
+ /**
230
+ * Sets or get whether video frame should be resized to fit the media player component.
231
+ *
232
+ * @param {boolean} [fit] - `true` to resize video to fit player component, `false` to use actual resolution of the video.
233
+ * @returns {boolean|MediaPlayer} Returns `this` component instance if setting, `boolean` if getting.
234
+ */
235
+ fit(...args)
236
+ {
237
+ return this.property("fit", args.length > 0 ? [args[0] === true] : []);
238
+ }
239
+
240
+ /**
241
+ * Sets or get hardware acceleration setting for ffmpeg video decoding.
242
+ * To get a list of supported hardware acceleration options use `hardwareAccelerations` getter property.
243
+ *
244
+ * @param {string} [hwaccel] - `-hwaccel` option value for FFMPEG. Default is "auto". `null` or "none" to disable hardware acceleration.
245
+ * @returns {string|MediaPlayer} Returns `this` component instance if setting, `string` if getting.
246
+ */
247
+ hardwareAcceleration(...args)
248
+ {
249
+ return this.property("hardwareAcceleration", args);
250
+ }
251
+
252
+ /**
253
+ * Gets a list of supported hardware acceleration options that can be used by FFMPEG on this system.
254
+ * Returns an array of supported hardware accelerations that can be used to decode a video by FFMPEG.
255
+ * @readonly
256
+ * @type {string[]}
257
+ */
258
+ get hardwareAccelerations()
259
+ {
260
+ return this.property("hardwareAccelerations", []);
261
+ }
262
+
263
+ /**
264
+ * Gets an array of enabled video input devices (such as WebCam or video capture device) with an array of accepted video formats (size and frame rate).
265
+ * Returns an array of objects that contain information about each video input device recognized by FFMPEG.
266
+ * NOTE: On linux it is recommended to have `v4l2-utils` installed for fast video devices lookup, otherwise alternative method take a lot longer to complete and may return less video formats and FPS options.
267
+ *
268
+ * @readonly
269
+ * @type {VideoDevice[]}
270
+ * @see VideoDevice
271
+ */
272
+ get videoInputDevices()
273
+ {
274
+ return ui.sendToGUI({control: this.id, get: "inputDevices", data: "video"});
275
+ }
276
+
277
+ /**
278
+ * Gets an array of enabled audio input devices (such as microphone, system sound) with an array of accepted audio formats (sample rate, bit depth, and amount of channels).
279
+ * Returns an array of objects that contain information about each audio input device recognized by FFMPEG.
280
+ *
281
+ * @readonly
282
+ * @type {AudioDevice[]}
283
+ * @see AudioDevice
284
+ */
285
+ get audioInputDevices()
286
+ {
287
+ return ui.sendToGUI({control: this.id, get: "inputDevices", data: "audio"});
288
+ }
289
+
290
+ /**
291
+ * Gets a list of output audio devices (such as speaker, bluetooth headphones, etc.) and their accepted audio formats.
292
+ * These devices may be specified to be used while playing video or audio.
293
+ * Returns an array of objects that contain information about each audio output device recognized by FFMPEG.
294
+ *
295
+ * @readonly
296
+ * @type {AudioDevice[]}
297
+ * @see AudioDevice
298
+ */
299
+ get audioOutputDevices()
300
+ {
301
+ return ui.sendToGUI({control: this.id, get: "outputDevices", data: "audio"});
302
+ }
303
+
304
+ /**
305
+ * Sets or gets a current audio output device. To obtain a list of devices you can use "audioOutputDevices" getter property (e.g. player.audioOutputDevices), which returns a list of devices with their ID and formats.
306
+ * Device name or ID may be passed, but name is preferred, because when devices are added or removed, their ID may change, because it's just an index of the list of devices (enumerator), but names are unique.
307
+ *
308
+ * @param {string} [name] - Audio output device name (or ID) obtained from {@link AudioDevice} object using `{@link MediaPlayer#audioOutputDevices}` getter.
309
+ * @return {MediaPlayer|string} Returns `this` component instance when setting, otherwise current audio output device info as an `object`.
310
+ * @see AudioDevice
311
+ * @see MediaPlayer#audioOutputDevice
312
+ * @example <h2>Getting a list of devices and setting first one:</h2>
313
+ * const player = new MediaPlayer();
314
+ * const _devices = player.audioOutputDevices;
315
+ *
316
+ * player.audioOutputDevice(_devices[0].name);
317
+ *
318
+ */
319
+ audioOutputDevice(...args)
320
+ {
321
+ return this.property("audioOutputDevice", args);
322
+ }
323
+
324
+ /**
325
+ * Registers, unregisters, and gets an Array of event handlers for the MediaPlayer.
326
+ *
327
+ * @param {function(PlayerEvent):any} [callback] - Handler function receiving {@link PlayerEvent} object. Pass `null` to unregister all handler callbacks.
328
+ * @param {boolean} [remove] - Set to `true` to unregister the handler function.
329
+ * @return {MediaPlayer|function[]} Returns `this` component instance if adding or removing the handler, otherwise returns an array of added handler functions.
330
+ * @see PlayerEvent
331
+ * @see Media
332
+ * @see VideoStream
333
+ * @see AudioStream
334
+ * @see SubtitleStream
335
+ * @example
336
+ * // Example of PlayerEvent object
337
+ * PlayerEvent {
338
+ * type: string, // One of: `loadstart`, `loadedmetadata`, `seeking`, `timeupdate`, `play`, `stop`.
339
+ * mediaType: string, // The type of media that is set to play in the player. One of: `File`, `InputDevice`, `URL`.
340
+ * media: Media, // A Media formatted object that contains details about loaded media.
341
+ * currentTime: number, // Current play time.
342
+ * duration: number, // Duration of the media in seconds. When event type is `timeupdate`.
343
+ * reason: string, // Reason for stopping: `Pause`, `EndOfMediaFile`
344
+ * }
345
+ *
346
+ * // Example of a VideoStream object
347
+ * VideoStream {
348
+ * sampleWidth: number,
349
+ * sampleHeight: number,
350
+ * width: number,
351
+ * height: number,
352
+ * pixelAspectRatio: string,
353
+ * displayAspectRatio: string,
354
+ * frameRate: number,
355
+ * codec: string,
356
+ * pixelFormat: string,
357
+ * progressive: boolean,
358
+ * default: boolean
359
+ * }
360
+ *
361
+ * // Example of a AudioStream object
362
+ * AudioStream {
363
+ * sampleRate: number,
364
+ * channels: number,
365
+ * bitDepth: number,
366
+ * codec: string,
367
+ * default: boolean
368
+ * }
369
+ *
370
+ * // Example of a SubtitleStream object
371
+ * SubtitleStream {
372
+ * language: string,
373
+ * codec: string,
374
+ * default: boolean
375
+ * }
376
+ */
377
+ onPlayerEvents(callback, ...args)
378
+ {
379
+ return this.event("onPlayerEvents", callback, args[0] ?? false);
380
+ }
381
+
382
+ /**
383
+ * Gets the current state of the media player component. The returned value corresponds to {@link MediaPlayer#State}.
384
+ *
385
+ * @readonly
386
+ * @see MediaPlayer#State
387
+ * @type {MediaPlayer.State}
388
+ */
389
+ get state()
390
+ {
391
+ return this.property("state", []);
392
+ }
393
+
394
+ /**
395
+ * Sets or gets the method how smoothing is done when video is resized.
396
+ * `ByGUI` means that video frames are smoothed out while drawing on the player component in GUI.
397
+ * `ByFFMPEG` means that ffmpeg will resize video to the size of the component before sending it to GUI. When component is resized while video is playing, the video will have to stop and then start again at the same position.
398
+ * `None` means that video will not be smoothed, and when it's resized, it will look pixelated.
399
+ *
400
+ * @param {MediaPlayer.Interpolation} [interpolation] - Specifies a method of smoothing video when it's displayed in not it's original size. Options: MediaPlayer.Interpolation.[None|ByGUI|ByFFMPEG]
401
+ * @return {MediaPlayer.Interpolation|MediaPlayer} When setting value an instance of `this` object is returned, otherwise a current value is returned.
402
+ */
403
+ interpolation(...args)
404
+ {
405
+ return this.property("interpolation", args.length > 0 ? [args[0]] : []);
406
+ }
407
+
408
+ /**
409
+ * Sets or gets whether to show visualizer for audio-only streams (when no video stream is present, such as when playing music).
410
+ *
411
+ * @param {boolean} enable - Use or not use visualizer for audio-only streams.
412
+ * @return {boolean|MediaPlayer} When setting value an instance of `this` object is returned, otherwise a current value is returned.
413
+ */
414
+ visualizer(...args)
415
+ {
416
+ return this.property("visualizer", args);
417
+ }
418
+
419
+ /**
420
+ * Sets or get value if media should be looping. Valid values are `true`, `false`, or a positive integer how many times it should be looped.
421
+ * The stream continues even though video or audio repeats, after first iteration current time stops updating because it would show time of the
422
+ * total playback, not the current media time. If you need correct media progress time, implement your own loop by starting video again when it stops.
423
+ *
424
+ * @param {boolean|number} [loop] - Loop or not to loop `boolean`, or a `number` how many times to loop.
425
+ * @return {boolean|number|MediaPlayer} When setting a value, an instance of `this` object is returned; otherwise a current value is returned.
426
+ */
427
+ loop(...args)
428
+ {
429
+ if(args.length > 0)
430
+ {
431
+ if(typeof args[0] === "boolean") // convert boolean to int
432
+ {
433
+ args[0] = args[0] ? -1 : 0;
434
+ }
435
+ else // validate int
436
+ {
437
+ args[0] = Math.max(-1, args[0]);
438
+ }
439
+ }
440
+
441
+ return this.property("loop", args);
442
+ }
443
+
444
+ /**
445
+ * Sets or gets the mute state of the media player audio. If muted, it will produce silence instead of provided sound.
446
+ * Its only used if audio stream is present.
447
+ *
448
+ * @param {boolean} mute - `true` to mute, `false` to unmute.
449
+ * @return {boolean|MediaPlayer} When setting value an instance of `this` object is returned, otherwise a current value is returned.
450
+ */
451
+ mute(...args)
452
+ {
453
+ return this.property("mute", args);
454
+ }
455
+
456
+ /**
457
+ * Sets or gets the background color of subtitles text. The background is used for improved readability when video colors are similar to colors of subtitles text.
458
+ *
459
+ * @param {String} [color] - Color string (e.g.: "#000000" or "00000000"). Supports alpha channel for setting transparency.
460
+ * @return {String|MediaPlayer} If called without parameters, the instance of the MediaPlayer component is returned, otherwise current value is returned.
461
+ * @see MediaPlayer#subtitleStyle
462
+ */
463
+ subtitleBackground(...args)
464
+ {
465
+ return this.property("subtitleBackground", args);
466
+ }
467
+
468
+ /**
469
+ * Sets or gets the style of the subtitles. When `None`, subtitles are not visible. The background is used for improved readability when video colors are similar to colors of subtitles text.
470
+ *
471
+ * @param {MediaPlayer.SubtitleStyle} [style] - Style of the subtitle, or `None` to make it not visible. It's still sent as a `PlayerEvent`.
472
+ * @return {MediaPlayer.SubtitleStyle|MediaPlayer} If called without parameters, the instance of the MediaPlayer component is returned, otherwise current value is returned.
473
+ * @see MediaPlayer#SubtitleStyle
474
+ * @see MediaPlayer#subtitleBackground
475
+ * @see PlayerEvent
476
+ */
477
+ subtitleStyle(...args)
478
+ {
479
+ return this.property("subtitleStyle", args);
480
+ }
481
+
482
+ /**
483
+ * Sets video filters to be applied to the video video by FFMPEG. If one of preset filters is not enough, feel free to set a `custom` filter (any ffmpeg video filter that is compatible with -vf option).
484
+ *
485
+ * @param {VideoFilters|null} filters - A VideoFilters object. Check out `VideoFilters` type definition for details. Set to `null` to clear previously set video filters.
486
+ * @returns {MediaPlayer} Returns this MediaPlayer instance for chaining.
487
+ * @see VideoFilters
488
+ */
489
+ videoFilters(filters)
490
+ {
491
+ return this.property("videoFilters", [filters]);
492
+ }
493
+
494
+ /**
495
+ * Sets or gets component opacity float value between 0 and 1 inclusive.
496
+ *
497
+ * @param {number} [opacity] - A number between 0 and 1 inclusive.
498
+ * @return {number|this} If `opacity` argument is provided, `this` component is returned, otherwise opacity `number` is returned.
499
+ */
500
+ opacity(...args)
501
+ {
502
+ return this.property("opacity", args);
503
+ }
504
+ }
@@ -0,0 +1,74 @@
1
+
2
+ import {ComponentContainer} from "./ComponentContainer.js";
3
+ import {MenuItem} from "./MenuItem.js";
4
+
5
+ /**
6
+ * Menu UI component is used to create menus in a menu bar or create a submenu in context menu. It extends MenuItem class.
7
+ * Menu object can be added to MenuBar, ContextMenu, or another Menu object to create a submenu.
8
+ * @class
9
+ * @global
10
+ * @extends MenuItem
11
+ */
12
+ class Menu extends ComponentContainer
13
+ {
14
+ /**
15
+ * Menu constructor. Creates an instance of Menu UI component.
16
+ * @param {string} [text] - Text of the Menu component.
17
+ */
18
+ constructor(...args)
19
+ {
20
+ super("Menu", (new.target === Menu), ...args);
21
+ this.finalize(Menu, ComponentContainer);
22
+ }
23
+
24
+ /**
25
+ * Registers, unregisters and gets a list of handler functions for the menu popup events (when the menu becomes expended and collapsed).
26
+ *
27
+ * @param {function(PopupEvent):any|null} [callback] - Event handler function that receives a {@link PopupEvent} as an argument. Pass `null` to unregister all registered callbacks.
28
+ * @param {boolean} [remove] - Set to `true` to unregister the handler function.
29
+ * @return {function[]|ComboBox} Returns an array of registered handler functions if arguments are omitted, otherwise returns `this` component instance.
30
+ * @see PopupEvent
31
+ * @example
32
+ * mainForm.mainMenuBar = new MenuBar();
33
+ * let handler = function(e){console.log(e);}
34
+ * mainForm.fileMenu = new Menu("File").addTo(mainForm.mainMenuBar).onPopupEvents(handler);
35
+ *
36
+ * // event Object format:
37
+ * const e = {
38
+ * target: object, // The component that triggered the event.
39
+ * type: string, // `show`, `hide`, `cancel`.
40
+ * invoker: Object // UI Component that invoked the popup, or `null` if it was invoked programmatically.
41
+ * x: number, // X position relative to invoker. Only present when invoker is not `null`.
42
+ * y: number, // Y position relative to invoker. Only present when invoker is not `null`.
43
+ * screenX: number, // X position relative to default screen.
44
+ * screenY: number, // Y position relative to default screen.
45
+ * interactive: boolean, // Indicates if the popup was triggered by user's interaction (not programmatically).
46
+ * };
47
+ */
48
+ onPopupEvents(callback, ...args)
49
+ {
50
+ return this.event("onPopupEvents", callback, args[0] ?? false);
51
+ }
52
+
53
+ /**
54
+ * Adds a child component to this container component. Overrides UIComponent.addChild() to validate components being added.
55
+ *
56
+ * @param {Object} component - UI Component that can be a child of this component.
57
+ * @param {...any} [data_or_index] - Argument to pass index at which to insert the child. By default component is added to the end.
58
+ * @returns {this}
59
+ */
60
+ addChild(component, ...data)
61
+ {
62
+ if(!(component instanceof UIComponent) || !(component instanceof Menu || component instanceof MenuItem || component instanceof RadioButtonMenuItem || component instanceof CheckBoxMenuItem || component instanceof Separator))
63
+ {
64
+ throw new Error(component.constructor.name + " cannot be added to Menu");
65
+ }
66
+
67
+ return super.addChild(component, ...data);
68
+ }
69
+ }
70
+
71
+ ComponentContainer.implementClass(Menu, MenuItem);
72
+
73
+ export {Menu};
74
+
@@ -0,0 +1,56 @@
1
+
2
+ import {ComponentContainer} from "./ComponentContainer.js";
3
+
4
+ /**
5
+ * MenuBar UI component is used to create a menu bar at the top of the application. It extends UIComponent class.
6
+ *
7
+ * Menu bar can be added to Window in two ways, by setting the MenuBar as the Window's main menu bar using window.menuBar(menuBar) method, or adding the MenuBar object as any other UI component using menuBar.addTo(window) or window.addChild(menuBar).
8
+ *
9
+ * Using window.menuBar(menuBar) automatically positions and resizes the menu bar to Window's width and in MacOS it uses it as the main menu bar shows at the top menu bar of the operating system.
10
+ *
11
+ * Adding the menu bar as a regular UI component to Window will keep the menu inside the Window and you will have to resize it by setting the desired width (and optionally height).
12
+ *
13
+ * Only Menu objects can be added to MenuBar.
14
+ *
15
+ * Extends {@link ComponentContainer}, which extends {@link UIComponent}.
16
+ * @class
17
+ * @global
18
+ */
19
+ export class MenuBar extends ComponentContainer
20
+ {
21
+ /**
22
+ * Constructor of MenuBar UI component.
23
+ *
24
+ * @param {string} [text] - Text displayed in the menu
25
+ */
26
+ constructor()
27
+ {
28
+ if(arguments.length > 0)
29
+ {
30
+ super("MenuBar", (new.target === MenuBar), arguments[0]);
31
+ }
32
+ else
33
+ {
34
+ super("MenuBar", (new.target === MenuBar));
35
+ }
36
+
37
+ this.finalize(MenuBar, ComponentContainer);
38
+ }
39
+
40
+ /**
41
+ * Adds a child menu component to this menu bar. Overrides UIComponent.addChild() to validate components being added.
42
+ *
43
+ * @param {Object} component - UI Component that can be a child of this component.
44
+ * @param {...any} [index] - Argument to pass index at which to insert the child. By default component is added to the end.
45
+ * @returns {this} Returns an instance of `this` component.
46
+ */
47
+ addChild(component, ...data)
48
+ {
49
+ if(!(component instanceof Menu))
50
+ {
51
+ throw new Error(component.constructor.name + " cannot be added to MenuBar.");
52
+ }
53
+
54
+ return super.addChild(component, ...data);
55
+ }
56
+ }