x4js 2.0.34 → 2.1.0-manual
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -21
- package/package.json +39 -26
- package/src/components/base.scss +25 -89
- package/src/components/boxes/boxes.module.scss +54 -54
- package/src/components/boxes/boxes.ts +513 -513
- package/src/components/breadcrumb/breadcrumb.scss +56 -56
- package/src/components/breadcrumb/breadcrumb.ts +93 -93
- package/src/components/btngroup/btngroup.module.scss +40 -40
- package/src/components/btngroup/btngroup.ts +152 -152
- package/src/components/button/button.module.scss +172 -172
- package/src/components/button/button.ts +232 -232
- package/src/components/calendar/calendar.module.scss +162 -162
- package/src/components/calendar/calendar.ts +326 -326
- package/src/components/canvas/canvas.module.scss +24 -24
- package/src/components/canvas/canvas.ts +195 -195
- package/src/components/canvas/canvas_ex.ts +275 -275
- package/src/components/checkbox/check.svg +3 -3
- package/src/components/checkbox/checkbox.module.scss +141 -141
- package/src/components/checkbox/checkbox.ts +139 -139
- package/src/components/colorinput/colorinput.module.scss +64 -64
- package/src/components/colorinput/colorinput.ts +90 -90
- package/src/components/colorpicker/colorpicker.module.scss +132 -132
- package/src/components/colorpicker/colorpicker.ts +481 -481
- package/src/components/combobox/combobox.module.scss +145 -145
- package/src/components/combobox/combobox.ts +282 -282
- package/src/components/combobox/updown.svg +3 -3
- package/src/components/components.ts +45 -44
- package/src/components/dialog/dialog.module.scss +103 -105
- package/src/components/dialog/dialog.ts +233 -233
- package/src/components/filedrop/filedrop.module.scss +69 -69
- package/src/components/filedrop/filedrop.ts +130 -130
- package/src/components/form/form.module.scss +38 -38
- package/src/components/form/form.ts +172 -172
- package/src/components/gridview/gridview.module.scss +323 -337
- package/src/components/gridview/gridview.ts +1276 -1315
- package/src/components/header/header.module.scss +40 -40
- package/src/components/header/header.ts +141 -141
- package/src/components/icon/icon.module.scss +32 -32
- package/src/components/icon/icon.ts +165 -165
- package/src/components/image/image.module.scss +27 -27
- package/src/components/image/image.ts +168 -168
- package/src/components/input/input.module.scss +74 -74
- package/src/components/input/input.ts +537 -537
- package/src/components/keyboard/keyboard.module.scss +136 -136
- package/src/components/keyboard/keyboard.ts +549 -549
- package/src/components/label/label.module.scss +90 -91
- package/src/components/label/label.ts +101 -101
- package/src/components/link/link.module.scss +44 -44
- package/src/components/link/link.ts +87 -87
- package/src/components/listbox/listbox.module.scss +179 -179
- package/src/components/listbox/listbox.ts +596 -596
- package/src/components/menu/menu.module.scss +128 -128
- package/src/components/menu/menu.ts +174 -174
- package/src/components/messages/messages.module.scss +92 -146
- package/src/components/messages/messages.ts +237 -303
- package/src/components/normalize.scss +391 -391
- package/src/components/notification/notification.module.scss +83 -83
- package/src/components/notification/notification.ts +107 -107
- package/src/components/panel/panel.module.scss +66 -71
- package/src/components/panel/panel.ts +57 -57
- package/src/components/popup/popup.module.scss +51 -51
- package/src/components/popup/popup.ts +457 -457
- package/src/components/progress/progress.module.scss +56 -56
- package/src/components/progress/progress.ts +43 -43
- package/src/components/propgrid/progrid.module.scss +111 -111
- package/src/components/propgrid/propgrid.ts +300 -300
- package/src/components/propgrid/updown.svg +3 -3
- package/src/components/radio/radio.module.scss +163 -163
- package/src/components/radio/radio.svg +3 -3
- package/src/components/radio/radio.ts +141 -141
- package/src/components/rating/rating.module.scss +22 -22
- package/src/components/rating/rating.ts +131 -131
- package/src/components/select/select.module.scss +8 -8
- package/src/components/select/select.ts +134 -134
- package/src/components/shared.scss +141 -71
- package/src/components/sizers/sizer.module.scss +90 -107
- package/src/components/sizers/sizer.ts +131 -134
- package/src/components/slider/slider.module.scss +117 -117
- package/src/components/slider/slider.ts +197 -197
- package/src/components/spreadsheet/spreadsheet.module.scss +307 -307
- package/src/components/spreadsheet/spreadsheet.ts +1223 -1223
- package/src/components/switch/switch.module.scss +126 -126
- package/src/components/switch/switch.ts +61 -61
- package/src/components/tabs/tabs.module.scss +46 -67
- package/src/components/tabs/tabs.ts +229 -234
- package/src/components/textarea/textarea.module.scss +63 -63
- package/src/components/textarea/textarea.ts +131 -131
- package/src/components/textedit/textedit.module.scss +115 -115
- package/src/components/textedit/textedit.ts +122 -122
- package/src/components/themes.scss +90 -90
- package/src/components/tickline/tickline.module.scss +25 -25
- package/src/components/tickline/tickline.ts +81 -81
- package/src/components/tooltips/tooltips.scss +71 -71
- package/src/components/tooltips/tooltips.ts +120 -120
- package/src/components/treeview/treeview.module.scss +192 -192
- package/src/components/treeview/treeview.ts +484 -484
- package/src/components/viewport/viewport.module.scss +31 -31
- package/src/components/viewport/viewport.ts +41 -41
- package/src/core/component.ts +1299 -1299
- package/src/core/core_application.ts +361 -361
- package/src/core/core_colors.ts +512 -512
- package/src/core/core_data.ts +1297 -1297
- package/src/core/core_dom.ts +481 -481
- package/src/core/core_dragdrop.ts +225 -225
- package/src/core/core_element.ts +221 -221
- package/src/core/core_events.ts +214 -214
- package/src/core/core_i18n.ts +395 -395
- package/src/core/core_pdf.ts +454 -454
- package/src/core/core_react.ts +78 -78
- package/src/core/core_router.ts +296 -296
- package/src/core/core_state.ts +62 -62
- package/src/core/core_styles.ts +213 -213
- package/src/core/core_svg.ts +1042 -1042
- package/src/core/core_tools.ts +996 -996
- package/src/types/scss.d.ts +4 -4
- package/src/types/x4react.d.ts +8 -8
- package/src/x4.scss +19 -19
- package/src/x4.ts +36 -36
- package/src/x4tsx.d.ts +26 -26
- package/.vscode/launch.json +0 -14
- package/.vscode/settings.json +0 -2
- package/demo/assets/house-light.svg +0 -1
- package/demo/assets/radio.svg +0 -4
- package/demo/index.html +0 -12
- package/demo/main.scss +0 -23
- package/demo/main.ts +0 -324
- package/demo/package.json +0 -26
- package/demo/scss.d.ts +0 -4
- package/demo/svg.d.ts +0 -1
- package/demo/tsconfig.json +0 -14
- package/src/components/gridview/folder-open.svg +0 -1
- package/src/components/messages/spinner.svg +0 -1
- package/src/x4.d.ts +0 -10
- package/tsconfig.json +0 -11
|
@@ -1,300 +1,300 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ___ ___ __
|
|
3
|
-
* \ \/ / / _
|
|
4
|
-
* \ / /_| |_
|
|
5
|
-
* / \____ _|
|
|
6
|
-
* /__/\__\ |_|
|
|
7
|
-
*
|
|
8
|
-
* @file propgrid.ts
|
|
9
|
-
* @author Etienne Cochard
|
|
10
|
-
*
|
|
11
|
-
* @copyright (c) 2024 R-libre ingenierie
|
|
12
|
-
*
|
|
13
|
-
* Use of this source code is governed by an MIT-style license
|
|
14
|
-
* that can be found in the LICENSE file or at https://opensource.org/licenses/MIT.
|
|
15
|
-
**/
|
|
16
|
-
|
|
17
|
-
import { Select } from "../select/select"
|
|
18
|
-
import { Button } from "../button/button"
|
|
19
|
-
import { Component, ComponentProps, EvChange, EvFocus } from "../../core/component"
|
|
20
|
-
import { HBox, VBox } from "../boxes/boxes"
|
|
21
|
-
import { Input, InputProps } from "../input/input"
|
|
22
|
-
import { ListItem } from "../listbox/listbox"
|
|
23
|
-
import { Label, SimpleText } from "../label/label"
|
|
24
|
-
import { class_ns, isFunction } from '../../core/core_tools';
|
|
25
|
-
import { Icon } from '../components'
|
|
26
|
-
|
|
27
|
-
import "./progrid.module.scss"
|
|
28
|
-
import updown_icon from "./updown.svg"
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
type IValue = boolean | number | string;
|
|
32
|
-
type IValueCB = ( name: string) => IValue;
|
|
33
|
-
|
|
34
|
-
export interface PropertyValue {
|
|
35
|
-
type: 'boolean' | 'number' | 'string' | 'password' | 'options' | 'label' | 'button';
|
|
36
|
-
title?: string;
|
|
37
|
-
desc?: string;
|
|
38
|
-
name?: string;
|
|
39
|
-
value: IValue | IValueCB;
|
|
40
|
-
options?: ListItem[];
|
|
41
|
-
callback: ( name: string, value: any ) => void;
|
|
42
|
-
step?: number; // for numbers
|
|
43
|
-
live?: boolean; // for live update
|
|
44
|
-
cls?: string;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export interface PropertyGroup {
|
|
48
|
-
title: string;
|
|
49
|
-
desc?: string;
|
|
50
|
-
icon?: string;
|
|
51
|
-
cls?: string;
|
|
52
|
-
collapsible?: boolean;
|
|
53
|
-
|
|
54
|
-
items: PropertyValue[];
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export interface PropertyProps extends ComponentProps {
|
|
58
|
-
groups: PropertyGroup[];
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
@class_ns( "x4" )
|
|
62
|
-
export class PropertyGrid extends VBox {
|
|
63
|
-
|
|
64
|
-
private root: Component;
|
|
65
|
-
private groups: PropertyGroup[];
|
|
66
|
-
|
|
67
|
-
constructor(props: PropertyProps) {
|
|
68
|
-
super(props);
|
|
69
|
-
|
|
70
|
-
this.root = new Component({ cls: "root" });
|
|
71
|
-
this.setContent( this.root );
|
|
72
|
-
|
|
73
|
-
if( props.groups ) {
|
|
74
|
-
this.setItems( props.groups );
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
*
|
|
80
|
-
*/
|
|
81
|
-
|
|
82
|
-
setItems( _grps: PropertyGroup[] ) {
|
|
83
|
-
|
|
84
|
-
this.groups = _grps.filter( x => !!x );
|
|
85
|
-
//this.groups.sort( (a,b) => {return a.title>b.title ? 1 : 0} );
|
|
86
|
-
|
|
87
|
-
let items: Component[] = [];
|
|
88
|
-
|
|
89
|
-
for( const g of this.groups ) {
|
|
90
|
-
items.push( this.makeGroupHeader(g) );
|
|
91
|
-
g.items.forEach( i => {
|
|
92
|
-
if( i ) {
|
|
93
|
-
items.push( this.makePropertyRow(i) );
|
|
94
|
-
}
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
this.root.setContent( items );
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Gets the html of a group header row
|
|
103
|
-
* @param {string} displayName - The group display name
|
|
104
|
-
* @param {boolean} isCollapsible - Whether the group should support expand/collapse
|
|
105
|
-
*/
|
|
106
|
-
|
|
107
|
-
makeGroupHeader( g: PropertyGroup ) {
|
|
108
|
-
|
|
109
|
-
const toggle = (e: Component) => {
|
|
110
|
-
|
|
111
|
-
let visible: boolean;
|
|
112
|
-
if (!e.hasClass("collapsed")) {
|
|
113
|
-
e.addClass("collapsed");
|
|
114
|
-
visible = false;
|
|
115
|
-
}
|
|
116
|
-
else {
|
|
117
|
-
e.removeClass("collapsed");
|
|
118
|
-
visible = true;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
let p = e.nextElement();
|
|
122
|
-
while (p && p.hasClass("row")) {
|
|
123
|
-
p.show(visible);
|
|
124
|
-
p = p.nextElement();
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
let cls = "group";
|
|
129
|
-
if( g.cls ) {
|
|
130
|
-
cls += ' '+g.cls;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
const tr = new HBox({
|
|
134
|
-
cls,
|
|
135
|
-
content: [
|
|
136
|
-
g.icon ? new Icon({ id: "icon", iconId: g.icon }) : null,
|
|
137
|
-
new VBox( { content: [
|
|
138
|
-
new SimpleText({ cls: "title", text: g.title }),
|
|
139
|
-
g.desc ? new SimpleText({ cls: "desc", text: g.desc }) : null,
|
|
140
|
-
]}),
|
|
141
|
-
g.collapsible? new Button({ icon: updown_icon, click: (e) => toggle(tr) }) : null,
|
|
142
|
-
]
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
tr.setClass("collapsible", g.collapsible );
|
|
146
|
-
return tr;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
*
|
|
151
|
-
*/
|
|
152
|
-
|
|
153
|
-
makePropertyRow( item: PropertyValue ) {
|
|
154
|
-
|
|
155
|
-
let use_hdr = true;
|
|
156
|
-
|
|
157
|
-
// If boolean create checkbox
|
|
158
|
-
let editor: Component;
|
|
159
|
-
let value = isFunction(item.value) ? item.value( item.name ) : item.value;
|
|
160
|
-
item.value = value;
|
|
161
|
-
|
|
162
|
-
if (item.type === 'boolean') {
|
|
163
|
-
editor = new Input({
|
|
164
|
-
type: "checkbox",
|
|
165
|
-
id: item.name,
|
|
166
|
-
name: item.name,
|
|
167
|
-
checked: value as boolean,
|
|
168
|
-
dom_events: {
|
|
169
|
-
change: ( e: Event ) => {
|
|
170
|
-
item.callback?.( item.name, (editor.dom as HTMLInputElement).checked );
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
}
|
|
176
|
-
else if (item.type === 'options') {
|
|
177
|
-
editor = new Select( {
|
|
178
|
-
value: value as string,
|
|
179
|
-
id: item.name,
|
|
180
|
-
items: item.options,
|
|
181
|
-
name: item.name,
|
|
182
|
-
change: ( e: EvChange ) => {
|
|
183
|
-
item.callback?.( item.name, e.value );
|
|
184
|
-
}
|
|
185
|
-
});
|
|
186
|
-
}
|
|
187
|
-
else if (item.type === 'password') {
|
|
188
|
-
editor = new Input({
|
|
189
|
-
type: 'password',
|
|
190
|
-
id: item.name,
|
|
191
|
-
name: item.name,
|
|
192
|
-
value: value as string,
|
|
193
|
-
focus: ( e: EvFocus ) => {
|
|
194
|
-
if( e.focus_out ) {
|
|
195
|
-
item.callback?.( item.name, (editor as Input).getValue() );
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
});
|
|
199
|
-
}
|
|
200
|
-
else if (item.type === 'number') {
|
|
201
|
-
editor = new Input({
|
|
202
|
-
type: 'number',
|
|
203
|
-
id: item.name,
|
|
204
|
-
name: item.name,
|
|
205
|
-
value: value as string,
|
|
206
|
-
step: item.step,
|
|
207
|
-
focus: ( e: EvFocus ) => {
|
|
208
|
-
if( e.focus_out ) {
|
|
209
|
-
item.callback?.( item.name, (editor as Input).getNumValue() );
|
|
210
|
-
}
|
|
211
|
-
},
|
|
212
|
-
change: ( ) => {
|
|
213
|
-
if( item.live ) {
|
|
214
|
-
item.callback?.( item.name, (editor as Input).getNumValue() );
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
});
|
|
218
|
-
}
|
|
219
|
-
else if (item.type === 'label') {
|
|
220
|
-
editor = new Label({
|
|
221
|
-
id: item.name,
|
|
222
|
-
text: value as string,
|
|
223
|
-
});
|
|
224
|
-
}
|
|
225
|
-
else if (item.type === 'button') {
|
|
226
|
-
use_hdr = false;
|
|
227
|
-
editor = new Button({
|
|
228
|
-
id: item.name,
|
|
229
|
-
label: value as string,
|
|
230
|
-
click: ( ) => {
|
|
231
|
-
item.callback?.( item.name, '' );
|
|
232
|
-
}
|
|
233
|
-
});
|
|
234
|
-
}
|
|
235
|
-
else {
|
|
236
|
-
editor = new Input({
|
|
237
|
-
type: 'text',
|
|
238
|
-
id: item.name,
|
|
239
|
-
name: item.name,
|
|
240
|
-
value: value as string,
|
|
241
|
-
focus: ( e: EvFocus ) => {
|
|
242
|
-
if( e.focus_out ) {
|
|
243
|
-
item.callback?.( item.name, (editor as Input).getValue() );
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
});
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
let cls = 'row';
|
|
250
|
-
if( item.cls ) {
|
|
251
|
-
cls += ' ' + item.cls;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
return new HBox({
|
|
255
|
-
cls,
|
|
256
|
-
content: [
|
|
257
|
-
use_hdr ? new Component({ cls: 'cell hdr', content: item.title ?? item.name, tooltip: item.desc }) : null,
|
|
258
|
-
new Component({ cls: 'cell', tag: "label", attrs: { "labelFor": item.name }, content: editor })
|
|
259
|
-
]
|
|
260
|
-
});
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
/**
|
|
264
|
-
*
|
|
265
|
-
*/
|
|
266
|
-
|
|
267
|
-
setPropValue( name: string, value: any ) {
|
|
268
|
-
const all = this.groups.flatMap( x => [ ...x.items ] ) ;
|
|
269
|
-
const item = all.find( x => x.name==name );
|
|
270
|
-
if( !item ) {
|
|
271
|
-
return;
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
if (item.type === 'boolean') {
|
|
275
|
-
const editor = this.root.query<Input>( '#'+item.name );
|
|
276
|
-
if( editor ) {
|
|
277
|
-
editor.setCheck( value as boolean );
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
else if (item.type === 'options') {
|
|
281
|
-
const editor = this.root.query<Select>( '#'+item.name );
|
|
282
|
-
if( editor ) {
|
|
283
|
-
editor.setValue( value as string );
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
else if (item.type === 'number') {
|
|
287
|
-
const editor = this.root.query<Input>( '#'+item.name );
|
|
288
|
-
if( editor ) {
|
|
289
|
-
editor.setNumValue( value as number, -2 );
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
else {
|
|
293
|
-
const editor = this.root.query<Input>( '#'+item.name );
|
|
294
|
-
if( editor ) {
|
|
295
|
-
editor.setValue( value as string );
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
|
|
1
|
+
/**
|
|
2
|
+
* ___ ___ __
|
|
3
|
+
* \ \/ / / _
|
|
4
|
+
* \ / /_| |_
|
|
5
|
+
* / \____ _|
|
|
6
|
+
* /__/\__\ |_|
|
|
7
|
+
*
|
|
8
|
+
* @file propgrid.ts
|
|
9
|
+
* @author Etienne Cochard
|
|
10
|
+
*
|
|
11
|
+
* @copyright (c) 2024 R-libre ingenierie
|
|
12
|
+
*
|
|
13
|
+
* Use of this source code is governed by an MIT-style license
|
|
14
|
+
* that can be found in the LICENSE file or at https://opensource.org/licenses/MIT.
|
|
15
|
+
**/
|
|
16
|
+
|
|
17
|
+
import { Select } from "../select/select"
|
|
18
|
+
import { Button } from "../button/button"
|
|
19
|
+
import { Component, ComponentProps, EvChange, EvFocus } from "../../core/component"
|
|
20
|
+
import { HBox, VBox } from "../boxes/boxes"
|
|
21
|
+
import { Input, InputProps } from "../input/input"
|
|
22
|
+
import { ListItem } from "../listbox/listbox"
|
|
23
|
+
import { Label, SimpleText } from "../label/label"
|
|
24
|
+
import { class_ns, isFunction } from '../../core/core_tools';
|
|
25
|
+
import { Icon } from '../components'
|
|
26
|
+
|
|
27
|
+
import "./progrid.module.scss"
|
|
28
|
+
import updown_icon from "./updown.svg"
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
type IValue = boolean | number | string;
|
|
32
|
+
type IValueCB = ( name: string) => IValue;
|
|
33
|
+
|
|
34
|
+
export interface PropertyValue {
|
|
35
|
+
type: 'boolean' | 'number' | 'string' | 'password' | 'options' | 'label' | 'button';
|
|
36
|
+
title?: string;
|
|
37
|
+
desc?: string;
|
|
38
|
+
name?: string;
|
|
39
|
+
value: IValue | IValueCB;
|
|
40
|
+
options?: ListItem[];
|
|
41
|
+
callback: ( name: string, value: any ) => void;
|
|
42
|
+
step?: number; // for numbers
|
|
43
|
+
live?: boolean; // for live update
|
|
44
|
+
cls?: string;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface PropertyGroup {
|
|
48
|
+
title: string;
|
|
49
|
+
desc?: string;
|
|
50
|
+
icon?: string;
|
|
51
|
+
cls?: string;
|
|
52
|
+
collapsible?: boolean;
|
|
53
|
+
|
|
54
|
+
items: PropertyValue[];
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface PropertyProps extends ComponentProps {
|
|
58
|
+
groups: PropertyGroup[];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
@class_ns( "x4" )
|
|
62
|
+
export class PropertyGrid extends VBox {
|
|
63
|
+
|
|
64
|
+
private root: Component;
|
|
65
|
+
private groups: PropertyGroup[];
|
|
66
|
+
|
|
67
|
+
constructor(props: PropertyProps) {
|
|
68
|
+
super(props);
|
|
69
|
+
|
|
70
|
+
this.root = new Component({ cls: "root" });
|
|
71
|
+
this.setContent( this.root );
|
|
72
|
+
|
|
73
|
+
if( props.groups ) {
|
|
74
|
+
this.setItems( props.groups );
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
*
|
|
80
|
+
*/
|
|
81
|
+
|
|
82
|
+
setItems( _grps: PropertyGroup[] ) {
|
|
83
|
+
|
|
84
|
+
this.groups = _grps.filter( x => !!x );
|
|
85
|
+
//this.groups.sort( (a,b) => {return a.title>b.title ? 1 : 0} );
|
|
86
|
+
|
|
87
|
+
let items: Component[] = [];
|
|
88
|
+
|
|
89
|
+
for( const g of this.groups ) {
|
|
90
|
+
items.push( this.makeGroupHeader(g) );
|
|
91
|
+
g.items.forEach( i => {
|
|
92
|
+
if( i ) {
|
|
93
|
+
items.push( this.makePropertyRow(i) );
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
this.root.setContent( items );
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Gets the html of a group header row
|
|
103
|
+
* @param {string} displayName - The group display name
|
|
104
|
+
* @param {boolean} isCollapsible - Whether the group should support expand/collapse
|
|
105
|
+
*/
|
|
106
|
+
|
|
107
|
+
makeGroupHeader( g: PropertyGroup ) {
|
|
108
|
+
|
|
109
|
+
const toggle = (e: Component) => {
|
|
110
|
+
|
|
111
|
+
let visible: boolean;
|
|
112
|
+
if (!e.hasClass("collapsed")) {
|
|
113
|
+
e.addClass("collapsed");
|
|
114
|
+
visible = false;
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
e.removeClass("collapsed");
|
|
118
|
+
visible = true;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
let p = e.nextElement();
|
|
122
|
+
while (p && p.hasClass("row")) {
|
|
123
|
+
p.show(visible);
|
|
124
|
+
p = p.nextElement();
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
let cls = "group";
|
|
129
|
+
if( g.cls ) {
|
|
130
|
+
cls += ' '+g.cls;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const tr = new HBox({
|
|
134
|
+
cls,
|
|
135
|
+
content: [
|
|
136
|
+
g.icon ? new Icon({ id: "icon", iconId: g.icon }) : null,
|
|
137
|
+
new VBox( { content: [
|
|
138
|
+
new SimpleText({ cls: "title", text: g.title }),
|
|
139
|
+
g.desc ? new SimpleText({ cls: "desc", text: g.desc }) : null,
|
|
140
|
+
]}),
|
|
141
|
+
g.collapsible? new Button({ icon: updown_icon, click: (e) => toggle(tr) }) : null,
|
|
142
|
+
]
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
tr.setClass("collapsible", g.collapsible );
|
|
146
|
+
return tr;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
*
|
|
151
|
+
*/
|
|
152
|
+
|
|
153
|
+
makePropertyRow( item: PropertyValue ) {
|
|
154
|
+
|
|
155
|
+
let use_hdr = true;
|
|
156
|
+
|
|
157
|
+
// If boolean create checkbox
|
|
158
|
+
let editor: Component;
|
|
159
|
+
let value = isFunction(item.value) ? item.value( item.name ) : item.value;
|
|
160
|
+
item.value = value;
|
|
161
|
+
|
|
162
|
+
if (item.type === 'boolean') {
|
|
163
|
+
editor = new Input({
|
|
164
|
+
type: "checkbox",
|
|
165
|
+
id: item.name,
|
|
166
|
+
name: item.name,
|
|
167
|
+
checked: value as boolean,
|
|
168
|
+
dom_events: {
|
|
169
|
+
change: ( e: Event ) => {
|
|
170
|
+
item.callback?.( item.name, (editor.dom as HTMLInputElement).checked );
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
}
|
|
176
|
+
else if (item.type === 'options') {
|
|
177
|
+
editor = new Select( {
|
|
178
|
+
value: value as string,
|
|
179
|
+
id: item.name,
|
|
180
|
+
items: item.options,
|
|
181
|
+
name: item.name,
|
|
182
|
+
change: ( e: EvChange ) => {
|
|
183
|
+
item.callback?.( item.name, e.value );
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
else if (item.type === 'password') {
|
|
188
|
+
editor = new Input({
|
|
189
|
+
type: 'password',
|
|
190
|
+
id: item.name,
|
|
191
|
+
name: item.name,
|
|
192
|
+
value: value as string,
|
|
193
|
+
focus: ( e: EvFocus ) => {
|
|
194
|
+
if( e.focus_out ) {
|
|
195
|
+
item.callback?.( item.name, (editor as Input).getValue() );
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
else if (item.type === 'number') {
|
|
201
|
+
editor = new Input({
|
|
202
|
+
type: 'number',
|
|
203
|
+
id: item.name,
|
|
204
|
+
name: item.name,
|
|
205
|
+
value: value as string,
|
|
206
|
+
step: item.step,
|
|
207
|
+
focus: ( e: EvFocus ) => {
|
|
208
|
+
if( e.focus_out ) {
|
|
209
|
+
item.callback?.( item.name, (editor as Input).getNumValue() );
|
|
210
|
+
}
|
|
211
|
+
},
|
|
212
|
+
change: ( ) => {
|
|
213
|
+
if( item.live ) {
|
|
214
|
+
item.callback?.( item.name, (editor as Input).getNumValue() );
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
else if (item.type === 'label') {
|
|
220
|
+
editor = new Label({
|
|
221
|
+
id: item.name,
|
|
222
|
+
text: value as string,
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
else if (item.type === 'button') {
|
|
226
|
+
use_hdr = false;
|
|
227
|
+
editor = new Button({
|
|
228
|
+
id: item.name,
|
|
229
|
+
label: value as string,
|
|
230
|
+
click: ( ) => {
|
|
231
|
+
item.callback?.( item.name, '' );
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
editor = new Input({
|
|
237
|
+
type: 'text',
|
|
238
|
+
id: item.name,
|
|
239
|
+
name: item.name,
|
|
240
|
+
value: value as string,
|
|
241
|
+
focus: ( e: EvFocus ) => {
|
|
242
|
+
if( e.focus_out ) {
|
|
243
|
+
item.callback?.( item.name, (editor as Input).getValue() );
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
let cls = 'row';
|
|
250
|
+
if( item.cls ) {
|
|
251
|
+
cls += ' ' + item.cls;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
return new HBox({
|
|
255
|
+
cls,
|
|
256
|
+
content: [
|
|
257
|
+
use_hdr ? new Component({ cls: 'cell hdr', content: item.title ?? item.name, tooltip: item.desc }) : null,
|
|
258
|
+
new Component({ cls: 'cell', tag: "label", attrs: { "labelFor": item.name }, content: editor })
|
|
259
|
+
]
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
*
|
|
265
|
+
*/
|
|
266
|
+
|
|
267
|
+
setPropValue( name: string, value: any ) {
|
|
268
|
+
const all = this.groups.flatMap( x => [ ...x.items ] ) ;
|
|
269
|
+
const item = all.find( x => x.name==name );
|
|
270
|
+
if( !item ) {
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
if (item.type === 'boolean') {
|
|
275
|
+
const editor = this.root.query<Input>( '#'+item.name );
|
|
276
|
+
if( editor ) {
|
|
277
|
+
editor.setCheck( value as boolean );
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
else if (item.type === 'options') {
|
|
281
|
+
const editor = this.root.query<Select>( '#'+item.name );
|
|
282
|
+
if( editor ) {
|
|
283
|
+
editor.setValue( value as string );
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
else if (item.type === 'number') {
|
|
287
|
+
const editor = this.root.query<Input>( '#'+item.name );
|
|
288
|
+
if( editor ) {
|
|
289
|
+
editor.setNumValue( value as number, -2 );
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
else {
|
|
293
|
+
const editor = this.root.query<Input>( '#'+item.name );
|
|
294
|
+
if( editor ) {
|
|
295
|
+
editor.setValue( value as string );
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<svg viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
-
<path class="fa-primary" d="M4.93179 5.43179C4.75605 5.60753 4.75605 5.89245 4.93179 6.06819C5.10753 6.24392 5.39245 6.24392 5.56819 6.06819L7.49999 4.13638L9.43179 6.06819C9.60753 6.24392 9.89245 6.24392 10.0682 6.06819C10.2439 5.89245 10.2439 5.60753 10.0682 5.43179L7.81819 3.18179C7.73379 3.0974 7.61933 3.04999 7.49999 3.04999C7.38064 3.04999 7.26618 3.0974 7.18179 3.18179L4.93179 5.43179ZM10.0682 9.56819C10.2439 9.39245 10.2439 9.10753 10.0682 8.93179C9.89245 8.75606 9.60753 8.75606 9.43179 8.93179L7.49999 10.8636L5.56819 8.93179C5.39245 8.75606 5.10753 8.75606 4.93179 8.93179C4.75605 9.10753 4.75605 9.39245 4.93179 9.56819L7.18179 11.8182C7.35753 11.9939 7.64245 11.9939 7.81819 11.8182L10.0682 9.56819Z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd">
|
|
3
|
-
</path>
|
|
1
|
+
<svg viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path class="fa-primary" d="M4.93179 5.43179C4.75605 5.60753 4.75605 5.89245 4.93179 6.06819C5.10753 6.24392 5.39245 6.24392 5.56819 6.06819L7.49999 4.13638L9.43179 6.06819C9.60753 6.24392 9.89245 6.24392 10.0682 6.06819C10.2439 5.89245 10.2439 5.60753 10.0682 5.43179L7.81819 3.18179C7.73379 3.0974 7.61933 3.04999 7.49999 3.04999C7.38064 3.04999 7.26618 3.0974 7.18179 3.18179L4.93179 5.43179ZM10.0682 9.56819C10.2439 9.39245 10.2439 9.10753 10.0682 8.93179C9.89245 8.75606 9.60753 8.75606 9.43179 8.93179L7.49999 10.8636L5.56819 8.93179C5.39245 8.75606 5.10753 8.75606 4.93179 8.93179C4.75605 9.10753 4.75605 9.39245 4.93179 9.56819L7.18179 11.8182C7.35753 11.9939 7.64245 11.9939 7.81819 11.8182L10.0682 9.56819Z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd">
|
|
3
|
+
</path>
|
|
4
4
|
</svg>
|