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,62 @@
1
+ import {UIComponent} from "./UIComponent.js";
2
+
3
+ /**
4
+ * Progress bar component is used to show progress visually, from 0% to 100%. Valid value range is from 0 to 100.
5
+ * For simplicity the ProgressBar does not have min() and max() properties. Min is always 0, max is always 100.
6
+ * Using multiple of these components in vertical position can be used to show audio spectrum analyzer.
7
+ * @class
8
+ * @global
9
+ */
10
+ export class ProgressBar extends UIComponent
11
+ {
12
+ /**
13
+ * ProgressBar constructor. Creates an instance of ProgressBar UI component.
14
+ * @param {number} [value] - Numeric value between 0 and 100.
15
+ */
16
+ constructor(...args)
17
+ {
18
+ if(args.length > 0)
19
+ {
20
+ super("ProgressBar", (new.target === ProgressBar), args[0]);
21
+ }
22
+ else
23
+ {
24
+ super("ProgressBar", (new.target === ProgressBar));
25
+ }
26
+
27
+ this.finalize(ProgressBar);
28
+ }
29
+
30
+ /**
31
+ * Sets or get a numeric value as percent of process (value between 0 and 100).
32
+ *
33
+ * @param {number} [value] - Numeric value between 0 and 100 that represents percent of progress.
34
+ * @return {number|ProgressBar} Returns `this` instance of ProgressBar when setting a value, otherwise returns current value.
35
+ */
36
+ value(...args)
37
+ {
38
+ return this.property("value", args);
39
+ }
40
+
41
+ /**
42
+ * Sets or get an orientation of the progress bar as horizontal or vertical.
43
+ *
44
+ * @param {Orientation} orientation - Orientation of progress bar. Default is horizontal.
45
+ * @return {Orientation|ProgressBar} Returns `this` component instance when setting value, otherwise returns current value.
46
+ */
47
+ orientation(...args)
48
+ {
49
+ return this.property("orientation", args);
50
+ }
51
+
52
+ /**
53
+ * Sets or gets wether the state of the progress is indeterminate.
54
+ *
55
+ * @param {boolean} is_indeterminate Sets a boolean stating if the state of progress is indeterminate. Omit to get the current state.
56
+ * @return {boolean|ProgressBar} Returns `this` component instance when setting value, otherwise returns current value.
57
+ */
58
+ indeterminate(...args)
59
+ {
60
+ return this.property("indeterminate", args.length > 0 ? [args[0] === true] : []);
61
+ }
62
+ }
@@ -0,0 +1,110 @@
1
+
2
+ import {UIComponent} from "./UIComponent.js";
3
+
4
+ /**
5
+ * RadioButton is a component used to select of multiple option by clicking on it.
6
+ * Multiple RadioButton components must be grouped for selection to work.
7
+ * To group them pick one main RadioButton and group other RadioButton components with it.
8
+ * For example if you have three RadioButton components, you must group second component with first one, then third component with any component that is already grouped (first or second).
9
+ * Then to detect selection changes add onChange(e => {console.log(e.value);}) to only one of the grouped RadioButton components, and e.value will be the value of currently selected RadioButton.
10
+ * @class
11
+ * @global
12
+ * @example
13
+ * // Example how to group RadioButton components and detect when selected value of a group changes.
14
+ *
15
+ * var mainForm = new Window("Demo").size(500, 300).show();
16
+ *
17
+ * // create first RadioButton and sets group value change handler function
18
+ * mainForm.radio1 = new RadioButton("Option 1").addTo(mainForm).position(10, 10).onChange(e => {console.log(e.value);});
19
+ *
20
+ * // create second RadioButton and group it with first one
21
+ * mainForm.radio2 = new RadioButton("Option 2").addTo(mainForm).position(10, 30).group(mainForm.radio1);
22
+ *
23
+ * // create third RadioButton and group it with first one
24
+ * mainForm.radio3 = new RadioButton("Option 3").addTo(mainForm).position(10, 50).group(mainForm.radio1);
25
+ *
26
+ * // now when user clicks on any of these radio buttons a new selected value will be logged in console.
27
+ */
28
+ export class RadioButton extends UIComponent
29
+ {
30
+ /**
31
+ * RadioButton constructor. Creates an instance of RadioButton UI component.
32
+ * @param {string} [text] - Text of the radio button component.
33
+ */
34
+ constructor(...args)
35
+ {
36
+ super("RadioButton", (new.target === RadioButton), ...args);
37
+ this.finalize(RadioButton);
38
+ }
39
+
40
+ /**
41
+ * Sets or gets boolean indicating whether this component is selected.
42
+ * @param {boolean} [selected] - `true` to select, `false` to deselect.
43
+ * @return {RadioButtonMenuItem|boolean} Returns `this` CheckBoxMenuItem instance if argument is provided, otherwise returns `boolean` value.
44
+ */
45
+ selected()
46
+ {
47
+ return this.property("selected", arguments.length > 0 ? [arguments[0] === true] : []);
48
+ }
49
+
50
+ /**
51
+ * Sets or gets a value of this component.
52
+ * @param {*} [value] - Value to be held by this component
53
+ * @return {RadioButton|*} If setting a value, then an instance of `this` component is returned, otherwise current value is returned.
54
+ */
55
+ value()
56
+ {
57
+ return this.property("value", arguments);
58
+ }
59
+
60
+ /**
61
+ * Gets or sets the selected value within this radio button group.
62
+ *
63
+ * If a value is provided, selects the radio button within the group that matches the given value (including this one).
64
+ *
65
+ * @param {number|string} [value] - Value to select within the group.
66
+ * @return {RadioButton|number|string|null} If value is provided, an instance of `this` object is returned. If no argument is provided, a value of the currently selected ToggleButton within the group is returned, or `null`, if no button is selected or selected button doesn't have a value.
67
+ */
68
+ selectedValue()
69
+ {
70
+ return this.property("selectedValue", arguments);
71
+ }
72
+
73
+ /**
74
+ * Adds this RadioButton to the group of another RadioButton while abandoning current group, or removes it from its current group and creates its own group when you pass `null`.
75
+ *
76
+ * - Call without parameters to get an Array of all components in its group.
77
+ * - Pass another RadioButton to join its group.
78
+ * - Pass `null` to leave the current group (if any) and create its own group.
79
+ *
80
+ * @param {RadioButton|null} [component] - A RadioButton to join, or `null` to leave the current group. Omit to get the RadioButton components of the same group.
81
+ * @returns {RadioButton|RadioButton[]} This RadioButton, for chaining when called with parameter, otherwise an Array of all RadioButton components in its group.
82
+ */
83
+ group(...args)
84
+ {
85
+ if(args.length > 0)
86
+ {
87
+ if(args[0] !== null && !(args[0] instanceof this.constructor)) throw new Error(`Invalid value passed to ${this.constructor.name}.group(). ${this.constructor.name} component or NULL is expected.`);
88
+ return this.property("group", [args[0] !== null ? args[0].id : null]);
89
+ }
90
+ else
91
+ {
92
+ let _items = this.property("group", []);
93
+
94
+ for(let i in _items) _items[i] = UIComponent.get(_items[i]);
95
+
96
+ return _items;
97
+ }
98
+ }
99
+
100
+ /**
101
+ * Deselect all ToggleButton elements grouped with this element.
102
+ *
103
+ * @return {ToggleButton} Returns `this` component instance.
104
+ */
105
+ clearSelection()
106
+ {
107
+ ui.sendToGUI({control: this.id, set: "clearSelection"});
108
+ return this;
109
+ }
110
+ }
@@ -0,0 +1,106 @@
1
+
2
+ import {MenuItem} from "./MenuItem.js";
3
+
4
+ /**
5
+ * Radio button menu item UI component that extends MenuItem class.
6
+ *
7
+ * RadioButton is a component used to select of multiple option by clicking on it.
8
+ * Multiple RadioButton components must be grouped for selection to work as expected.
9
+ * To group them pick one main RadioButtonMenuItem and group other RadioButtonMenuItem with it.
10
+ * For example if you have three RadioButtonMenuItem components that you want to group, you must group second component with first one, then third component with any component that is already grouped (first or second).
11
+ * Then to detect selection changes add onChange(e => {console.log(e.value);}) to only one of the grouped RadioButton components, and e.value will be the value of currently selected RadioButton.
12
+ * See example below.
13
+ *
14
+ * @class
15
+ * @global
16
+ * @see MenuItem
17
+ * @extends MenuItem
18
+ * @example
19
+ * // Example how to group RadioButton components and detect when selected value of a group changes.
20
+ *
21
+ * var fileMenu = new Menu("Options").addTo(menuBar);
22
+ *
23
+ * // create first RadioButtonMenuItem and sets group value change handler function
24
+ * mainForm.radio1 = new RadioButtonMenuItem("Option 1").addTo(fileMenu).onChange(e => {console.log(e.value);});
25
+ *
26
+ * // create second RadioButtonMenuItem and group it with first one
27
+ * mainForm.radio2 = new RadioButtonMenuItem("Option 2").addTo(fileMenu).group(mainForm.radio1);
28
+ *
29
+ * // create third RadioButtonMenuItem and group it with first one
30
+ * mainForm.radio3 = new RadioButtonMenuItem("Option 3").addTo(fileMenu).group(mainForm.radio1);
31
+ *
32
+ * // now when user clicks on any of these radio buttons a new selected value will be logged in console.
33
+ */
34
+ export class RadioButtonMenuItem extends MenuItem
35
+ {
36
+ /**
37
+ * Sets or gets boolean indicating whether this component is selected.
38
+ * @param {boolean} [selected] - `true` to select, `false` to deselect.
39
+ * @return {RadioButtonMenuItem|boolean} Returns `this` CheckBoxMenuItem instance if argument is provided, otherwise returns `boolean` value.
40
+ */
41
+ selected()
42
+ {
43
+ return this.property("selected", arguments.length > 0 ? [arguments[0] === true] : []);
44
+ }
45
+
46
+ /**
47
+ * Sets or gets a value of this component.
48
+ * @param {*} [value] - Value to be held by this component
49
+ * @return {RadioButtonMenuItem|*} If setting a value, then an instance of `this` component is returned, otherwise current value is returned.
50
+ */
51
+ value()
52
+ {
53
+ return this.property("value", arguments);
54
+ }
55
+
56
+ /**
57
+ * Gets or sets the selected value within this radio button group.
58
+ *
59
+ * If a value is provided, selects the radio button within the group that matches the given value (including this one).
60
+ *
61
+ * @param {number|string} [value] - Value to select within the group.
62
+ * @return {RadioButtonMenuItem|number|string|null} If value is provided, an instance of `this` object is returned. If no argument is provided, a value of the currently selected radio button in the group is returned, or `null`, if no button is selected or selected button doesn't have a value.
63
+ */
64
+ selectedValue()
65
+ {
66
+ return this.property("selectedValue", arguments);
67
+ }
68
+
69
+ /**
70
+ * Adds this RadioButtonMenuItem to the group of another RadioButtonMenuItem while abandoning current group, or removes it from its current group and creates its own when you pass `null`.
71
+ *
72
+ * - Call without parameters to get an Array of all components in its group.
73
+ * - Pass another RadioButtonMenuItem to join its group.
74
+ * - Pass `null` to leave the current group (if any) and create its own group.
75
+ *
76
+ * @param {RadioButtonMenuItem|null} [component] - A RadioButtonMenuItem to join, or `null` to leave the current group. Omit to get the grouped RadioButtonMenuItem components.
77
+ * @returns {RadioButtonMenuItem|RadioButtonMenuItem[]} This RadioButtonMenuItem, for chaining when called with parameter, otherwise an Array of all RadioButtonMenuItem components in its group.
78
+ */
79
+ group(...args)
80
+ {
81
+ if(args.length > 0)
82
+ {
83
+ if(args[0] !== null && !(args[0] instanceof this.constructor)) throw new Error(`Invalid value passed to ${this.constructor.name}.group(). ${this.constructor.name} component or NULL is expected.`);
84
+ return this.property("group", [args[0] !== null ? args[0].id : null]);
85
+ }
86
+ else
87
+ {
88
+ let _items = this.property("group", []);
89
+
90
+ for(let i in _items) _items[i] = UIComponent.get(_items[i]);
91
+
92
+ return _items;
93
+ }
94
+ }
95
+
96
+ /**
97
+ * Deselect all RadioButtonMenuItem elements grouped with this element.
98
+ *
99
+ * @return {RadioButtonMenuItem} Returns `this` component instance.
100
+ */
101
+ clearSelection()
102
+ {
103
+ ui.sendToGUI({control: this.id, set: "clearSelection"});
104
+ return this;
105
+ }
106
+ }
@@ -0,0 +1,199 @@
1
+
2
+ import {Shape} from "./Shape.js";
3
+
4
+ /**
5
+ * Rectangle shape can draw a rectangles (if width and height are different) and a square (when width and height are same.
6
+ *
7
+ * Rectangle class extends {@link Shape} class.
8
+ *
9
+ * @class
10
+ * @global
11
+ * @see Shape
12
+ */
13
+ export class Rectangle extends Shape
14
+ {
15
+ _points = [];
16
+ _arc_size = undefined;
17
+ _corner_radius = undefined;
18
+ _size = {width: 0, height: 0};
19
+
20
+ /**
21
+ * Creates an instance of Rectangle shape.
22
+ *
23
+ * @param {Stroke} [stroke=undefined] - A border of the shape.
24
+ * @param {string} [background=undefined] - Color, gradient, or image background, similar to CSS. Use an empty string to remove the background.
25
+ * @param {number} [opacity=1] - Opacity of the shape (0 to 1).
26
+ * @param {number} [x=0] - Horizontal position from the left edge.
27
+ * @param {number} [y=0] - Vertical position from the top edge.
28
+ * @param {number} [width=100] - Width of the ellipse (horizontal diameter).
29
+ * @param {number} [height=undefined] - Height of the ellipse (vertical diameter). If omitted, height will be same as width.
30
+ */
31
+ constructor(stroke = undefined, background = undefined, opacity = 1, x = 0, y = 0, width = 100, height = undefined)
32
+ {
33
+ super(undefined, stroke, background, opacity, x, y);
34
+ this._type = "rectangle";
35
+ if(width == null) width = 100;
36
+ this._size = {width: width, height: height != null ? height : width};
37
+ }
38
+
39
+ /**
40
+ * Sets or gets the size of the `Rectangle`.
41
+ *
42
+ * @param {number|Size} width - Width of the Rectangle, or a `Size` object (e.g., {width:300,height:300}).
43
+ * @param {number} [height] - Height of the Rectangle.
44
+ * @returns {Size|Rectangle} If called without parameters, current size is returned; otherwise this Rectangle object is returned.
45
+ * @see Size
46
+ */
47
+ size(...args)
48
+ {
49
+ if(args.length > 0)
50
+ {
51
+ let new_size = {};
52
+
53
+ if(typeof args[0] === "object")
54
+ {
55
+ if(args[0].constructor === Object)
56
+ {
57
+ new_size = {width: args[0].width, height: args[0].height};
58
+ }
59
+ else
60
+ {
61
+ throw new Error(`Invalid object type passed as an argument to Rectangle.size(). Standard Size formatted Object is expected, but ${args[0].constructor.name} was passed.`);
62
+ }
63
+ }
64
+ else
65
+ {
66
+ new_size = {width: args[0], height: args[1]};
67
+ }
68
+
69
+ if(!("width" in new_size && "height" in new_size)) throw new Error(`Invalid argument passed to Rectangle.size(). Width and height are expected.`);
70
+
71
+ this._size = new_size;
72
+
73
+ if(typeof this._size !== "object") this._size = {width: this._size, height: this._size}; // If size is one number, set i to height and width
74
+ this.update("size");
75
+ return this;
76
+ }
77
+ else
78
+ {
79
+ return {width: this._size.width, height: this._size.height};
80
+ }
81
+ }
82
+
83
+ /**
84
+ * Sets corner radius if only one argument passed, or arc width and height if two arguments or size object supplied. The arc size is applied to all corners.
85
+ *
86
+ * This a way to create all rounded corners with arc of same or different width and height. If you want to specify corner radius for specific corners, use {@link Rectangle#cornerRadius} method: cornerRadius(...).
87
+ *
88
+ * @param {number|{width:number, height:number}} width - Width of the corner arc, or a size object (e.g., {width:300,height:300}).
89
+ * @param {number} [height] - Height of the corner arc.
90
+ * @return {{width:number, height:number}|Rectangle} If called without parameters, current arc size is returned; otherwise this Rectangle object is returned.
91
+ * @see Rectangle#cornerRadius
92
+ * @example <h2>Valid ways to set arc size:</h2>
93
+ * rectangle.cornerArc(radius);
94
+ * rectangle.cornerArc(width,height);
95
+ * rectangle.cornerArc({width:5,height:10});
96
+ */
97
+ cornerArc()
98
+ {
99
+ if(arguments.length > 0)
100
+ {
101
+ this._arc_size = (arguments.length > 1) ? {width: arguments[0], height: arguments[1]} : arguments[0];
102
+
103
+ if(typeof this._arc_size !== "object") this._arc_size = {width: this._arc_size, height: this._arc_size};
104
+
105
+ if(this._corner_radius != null)
106
+ {
107
+ this._corner_radius = undefined;
108
+ this.update("corner_radius");
109
+ }
110
+
111
+ this.update("arc_size");
112
+ return this;
113
+ }
114
+ else
115
+ {
116
+ return {...this._arc_size};
117
+ }
118
+ }
119
+
120
+ /**
121
+ * Sets or gets a corner radius for each corner separately or for all corners at once.
122
+ *
123
+ * This method sets same width and height of the arc. If you need to set arc with different width and height, you can use {@link Rectangle#cornerArc} method: cornerArc(...).
124
+ *
125
+ * @param {number|string|object|undefined} topLeft_or_all - Radius for top-left corner, a `string` radii for all corners (e.g., "15 15 0 0"), or an `object` containing each corner in the same format as this method returns. If this is the only passed parameter, it will be used for all corners.
126
+ * @param {number|undefined} topRight - Radius for top-right corner. If omitted, it defaults to topLeft corner.
127
+ * @param {number|undefined} bottomRight - Radius for bottom-right corner. If omitted, it defaults to topRight corner.
128
+ * @param {number|undefined} bottomLeft - Radius for bottom-left corner. If omitted, it defaults to bottomRight corner.
129
+ * @return {{tl:number, tr:number, br:number, bl:number}|Rectangle} If called without parameters or `topLeft` is `undefined`, current corner radius object is returned. If called with arguments, this Rectangle shape is returned for chaining.
130
+ * @see Rectangle#cornerArc
131
+ *
132
+ * @example <h2>3 ways to set radius for each corner separately:</h2>
133
+ * rectangle.cornerRadius(10, 10, 0, 0); // as separate parameters
134
+ * rectangle.cornerRadius("10 10 0 0"); // in a string (CSS style)
135
+ * rectangle.cornerRadius({tl:10, tr:10, br:0, bl:0}); // In same object format as this method returns
136
+ *
137
+ * @example <h2>Setting radius for all corners at once:</h2>
138
+ * rectangle.cornerRadius(10);
139
+ */
140
+ cornerRadius(topLeft = undefined, topRight = undefined, bottomRight = undefined, bottomLeft = undefined)
141
+ {
142
+ // getter
143
+ if(topLeft == null) return this._corner_radius != null ? {...this._corner_radius} : undefined;
144
+
145
+ // setter
146
+ if(typeof topLeft === "string")
147
+ {
148
+ let _r = topLeft.replace(/[^\d\s]+/g, "").split(/\s+/);
149
+
150
+ topLeft = parseInt(_r[0] ?? 0);
151
+ topRight = parseInt(_r[1] ?? topRight);
152
+ bottomRight = parseInt(_r[2] ?? bottomRight);
153
+ bottomLeft = parseInt(_r[3] ?? bottomLeft);
154
+ }
155
+ else if(typeof topLeft === "object")
156
+ {
157
+ const obj = topLeft;
158
+ topLeft = obj.tl ?? 0;
159
+ topRight = obj.tr ?? topRight;
160
+ bottomRight = obj.br ?? bottomRight;
161
+ bottomLeft = obj.bl ?? bottomLeft;
162
+ }
163
+
164
+ if(topRight == null) topRight = topLeft;
165
+ if(bottomRight == null) bottomRight = topRight;
166
+ if(bottomLeft == null) bottomLeft = bottomRight;
167
+
168
+ this._corner_radius = {tl: topLeft, tr: topRight, br: bottomRight, bl: bottomLeft};
169
+
170
+ if(this._arc_size != null)
171
+ {
172
+ this._arc_size = undefined;
173
+ this.update("arc_size");
174
+ }
175
+
176
+ this.update("corner_radius");
177
+ return this;
178
+ }
179
+
180
+ /**
181
+ * Returns a JSON object that contains this shape properties. It may be converted back to this shape.
182
+ *
183
+ * @param {string} [include="all"] - Specified what to include. "all" is default. Valid values are: "all", "stroke", "background", "points", "basic".
184
+ * @return {object} Returns an object containing this shape's properties.
185
+ */
186
+ toObject(what = "all")
187
+ {
188
+ let shape = super.toObject(what);
189
+
190
+ if(this._type === "rectangle")
191
+ {
192
+ if("all|size".indexOf(what) >= 0) shape.size = this._size;
193
+ if("all|arc_size".indexOf(what) >= 0) shape.arc_size = this._arc_size;
194
+ if("all|corner_radius".indexOf(what) >= 0) shape.corner_radius = this._corner_radius;
195
+ }
196
+
197
+ return shape;
198
+ }
199
+ }
@@ -0,0 +1,53 @@
1
+
2
+ import {ComponentContainer} from "./ComponentContainer.js";
3
+ import {ScrollableComponent} from "./ScrollableComponent.js";
4
+
5
+ /**
6
+ * ScrollPane is a UI component used to display content that may not fit within the visible area, such as large images, scrollable lists, or lengthy forms.
7
+ *
8
+ * To use it, place another component (e.g., a Panel) inside the ScrollPane, and then add your scrollable items to that inner component.
9
+ * ScrollPane itself only provides scroll bars for scrolling and can contain only one child component at a time. Adding a second child component removes existing one.
10
+ *
11
+ * NOTE: DO NOT add components like List, Table, Tree, TextArea, InternalWindowContainer, or DocumentEditor directly to a ScrollPane, because these components already have built-in scroll bars.
12
+ *
13
+ * Extends {@link ComponentContainer} and {@link ScrollableComponent}, which extends {@link UIComponent}.
14
+ *
15
+ * @class
16
+ * @global
17
+ */
18
+ class ScrollPane extends ComponentContainer
19
+ {
20
+ /**
21
+ * ScrollPane constructor. Creates an instance of ScrollPane UI component.
22
+ *@param {string} [text] - Text associated with this ScrollPane. It will be used, for example, for a tab name when this ScrollPane is added to Tabs component.
23
+ */
24
+ constructor()
25
+ {
26
+ if(arguments.length > 0)
27
+ {
28
+ super("ScrollPane", (new.target === ScrollPane), arguments[0]);
29
+ }
30
+ else
31
+ {
32
+ super("ScrollPane", (new.target === ScrollPane));
33
+ }
34
+
35
+ this.finalize(ScrollPane, ComponentContainer);
36
+ }
37
+
38
+ /**
39
+ * Adds a child component to this container component.
40
+ *
41
+ * @param {Object} component - UI Component that can be a child of this component.
42
+ * @returns {this} Returns an instance of `this` component.
43
+ */
44
+ addChild(component, ...data)
45
+ {
46
+ if(this.childCount > 0) this.child(0)?.remove(); // remove previous child
47
+ return super.addChild(component, []);
48
+ }
49
+ }
50
+
51
+ ComponentContainer.implementClass(ScrollPane, ScrollableComponent);
52
+
53
+ export {ScrollPane};
@@ -0,0 +1,141 @@
1
+
2
+ import {UIComponent} from "./UIComponent.js";
3
+
4
+ /**
5
+ * ScrollableComponent is not a standalone component. ScrollableComponent extends UIComponent and serves a purpose to implement text editor related methods and properties.
6
+ *
7
+ * ScrollableComponent is extended by {@link TextArea}, {@link DocumentEditor}, {@link List}, {@link Table}, {@link Tree}, {@link InternalWindowContainer} and {@link ScrollPane}.
8
+ * @class
9
+ * @global
10
+ */
11
+ export class ScrollableComponent extends UIComponent
12
+ {
13
+ /**
14
+ * ScrollableComponent constructor.
15
+ * @internal
16
+ * @ignore
17
+ */
18
+ constructor(...args)
19
+ {
20
+ super(...args);
21
+ }
22
+
23
+ /**
24
+ * Sets or gets scroll bars visibility for horizontal and vertical scroll bars.
25
+ *
26
+ * @param {boolean|null|Scrollbars} [horizontal_or_both] - `true` = visible, `false` = hidden, `null` = auto. Also can be an Object of one or both values.
27
+ * @param {boolean|null} [vertical] - `true` = visible, `false` = hidden, `null` = auto. When first argument is provided but this one is omitted, then this will match the first argument.
28
+ * @return {this|Scrollbars} Returns `this` component if at least one argument is provided, otherwise returns current state of both scroll bars: {h:boolean|null, v: boolean|null}.
29
+ * @example
30
+ * textarea.scrollbars(true); // makes both scroll bars always visible
31
+ * textarea.scrollbars(false, null); // makes horizontal scroll bar hidden, but vertical will become visible as needed
32
+ * textarea.scrollbars({horizontal: false, vertical: null}); // makes horizontal scroll bar hidden, but vertical will become visible as needed
33
+ */
34
+ scrollbars(...args)
35
+ {
36
+ let arg = {};
37
+
38
+ if(args.length === 1)
39
+ {
40
+ if(args[0] != null && typeof args[0] === "object")
41
+ {
42
+ if("horizontal" in args[0]) arg.h = args[0].horizontal == null ? null : (args[0].horizontal === true);
43
+ if("vertical" in args[0]) arg.v = args[0].vertical == null ? null : (args[0].vertical === true);
44
+ }
45
+ else
46
+ {
47
+ arg.h = args[0] == null ? null : (args[0] === true);
48
+ arg.v = arg.h;
49
+ }
50
+ }
51
+ else if(args.length === 2)
52
+ {
53
+ arg.h = args[0] == null ? null : (args[0] === true);
54
+ arg.v = args[1] == null ? null : (args[1] === true);
55
+ }
56
+
57
+ return this.property("scrollbars", Object.keys(arg).length > 0 ? [arg] : []);
58
+ }
59
+
60
+ /**
61
+ * Sets and gets horizontal (X) and vertical (y) scroll positions. Applies only to components that have scroll bars, such as TextField, List, Table, DocumentEditor, Tree, ScrollPane, and InternalWindowContainer.
62
+ *
63
+ * @param {number} [x=undefined] - Set integer number to set horizontal position, or `undefined` to not set horizontal position. Omit this argument to get scroll position.
64
+ * @param {number} [y=undefined] - Set integer number to set vertical position, or `undefined` to not set vertical position.
65
+ * @return {this|Object} Returns horizontal and vertical scroll positions as an Object{x:number, y:number} if no arguments are passed, otherwise returns `this` component instance.
66
+ * @example
67
+ * const position = textarea.scrollPosition(); // Gets horizontal and vertical scroll positions as an Object{x:number, y:number}
68
+ * textarea.scrollPosition(40, 20); // sets horizontal and vertical scroll positions
69
+ * textarea.scrollPosition(null, 20); // sets only vertical scroll position
70
+ * textarea.scrollPosition(40, null); // sets only horizontal scroll position
71
+ * textarea.scrollPosition(40); // sets only horizontal scroll position
72
+ */
73
+ scrollPosition(x = undefined, y = undefined)
74
+ {
75
+ if(arguments.length > 0)
76
+ {
77
+ return this.property("scrollPosition", [{x: x ?? undefined, y: y ?? undefined}]);
78
+ }
79
+ else
80
+ {
81
+ return this.property("scrollPosition");
82
+ }
83
+ }
84
+
85
+ /**
86
+ * Gets the size of scroll bars (horizontal and vertical). Setting is not supported yet.
87
+ *
88
+ * @returns {number[]|this} Returns a size Object {x:number, y:number} when arguments are omitted, otherwise `this` component instance.
89
+ */
90
+ scrollBarSize(...args)
91
+ {
92
+ return this.property("scrollBarSize", args); // if return value is NULL, then return empty array
93
+ }
94
+
95
+ /**
96
+ * Sets or get scroll increment of a scrollable component.
97
+ *
98
+ * @param {number} pixels - How many pixels the page is scrolled in one step of scrolling with up/down keys or mouse wheel.
99
+ * @return {this|number} Returns `this` component if argument is provided, otherwise returns `number` value.
100
+ */
101
+ scrollIncrement(...args)
102
+ {
103
+ if(args.length > 0) args[0] = Math.max(1, parseInt(args[0]));
104
+ return this.property("scrollIncrement", args);
105
+ }
106
+
107
+ /**
108
+ * Sets or gets whether scrolling should be smooth (animated). Applies only to scrollable components.
109
+ *
110
+ * @param {boolean} enable - Enables or disables smooth scrolling
111
+ * @return {this|number} Returns `this` component if argument is provided, otherwise returns `boolean` value.
112
+ */
113
+ smoothScrolling(...args)
114
+ {
115
+ if(args.length > 0) args[0] = (args[0] === true);
116
+ return this.property("smoothScrolling", args);
117
+ }
118
+
119
+ /**
120
+ * Gets, registers or unregisters an event handler function for scrolling of vertical and/or horizontal scroll bars. Applicable only to components with scroll bars.
121
+ *
122
+ * @param {function(ScrollEvent): any} [callback=undefined] - The event handler function that receives a {@link ScrollEvent} object. Pass `null` to unregister all handler functions.
123
+ * @param {boolean} [remove=false] - Set to `true` to unregister the event handler.
124
+ * @returns {this|function[]} An array of handler functions if no arguments are passed, otherwise `this` component for method chaining.
125
+ * @see ScrollEvent
126
+ * @example
127
+ * // Example event object:
128
+ * const e = {
129
+ * target: object, // The component that triggered the event.
130
+ * type: string, // `horizontal`, `vertical`.
131
+ * x: number, // New value of horizontal scroll position
132
+ * y: number, // New value of vertical scroll position
133
+ * maxX: number, // Maximum value of horizontal scroll position
134
+ * maxY: number // Maximum value of vertical scroll position
135
+ * };
136
+ */
137
+ onScroll(...args)
138
+ {
139
+ return this.event("onScroll", args[0], args[1] ?? false);
140
+ }
141
+ }