x4js 2.3.24 → 2.3.25
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/aicontext.md +60 -10
- package/aiguide.md +64 -15
- package/package.json +1 -1
- package/src/components/assets/icons.ts +2 -0
- package/src/components/button/button.ts +5 -0
- package/src/components/dialog/dialog.ts +6 -0
- package/src/components/form/form.module.scss +2 -1
- package/src/components/form/form.ts +3 -0
- package/src/components/listbox/listbox.module.scss +59 -2
- package/src/components/listbox/listbox.ts +131 -21
- package/src/components/messages/messages.module.scss +70 -2
- package/src/components/messages/messages.ts +117 -23
- package/src/components/notification/notification.ts +3 -4
- package/src/components/popup/popup.ts +15 -0
- package/src/components/propgrid/propgrid.ts +30 -36
- package/src/components/tooltips/tooltips.ts +9 -0
- package/src/core/core_application.ts +7 -2
- package/src/core/core_events.ts +14 -2
- package/src/core/core_i18n.ts +28 -0
|
@@ -90,6 +90,9 @@ export class PropertyGrid extends VBox {
|
|
|
90
90
|
private root: Component;
|
|
91
91
|
private groups: PropertyGroup[];
|
|
92
92
|
|
|
93
|
+
// the editor of each property, by its name: no id, a name is not unique in a page
|
|
94
|
+
private editors = new Map<string, Component>( );
|
|
95
|
+
|
|
93
96
|
constructor(props: PropertyProps) {
|
|
94
97
|
super(props);
|
|
95
98
|
|
|
@@ -118,6 +121,8 @@ export class PropertyGrid extends VBox {
|
|
|
118
121
|
|
|
119
122
|
setItems( _grps: PropertyGroup[] ) {
|
|
120
123
|
|
|
124
|
+
this.editors.clear( );
|
|
125
|
+
|
|
121
126
|
if( !_grps || _grps.length==0 ) {
|
|
122
127
|
this.root.clearContent( );
|
|
123
128
|
return;
|
|
@@ -218,7 +223,6 @@ export class PropertyGrid extends VBox {
|
|
|
218
223
|
if (item.type === 'boolean') {
|
|
219
224
|
editor = new Input({
|
|
220
225
|
type: "checkbox",
|
|
221
|
-
id: item.name,
|
|
222
226
|
//name: item.name,
|
|
223
227
|
checked: value as boolean,
|
|
224
228
|
dom_events: {
|
|
@@ -232,7 +236,6 @@ export class PropertyGrid extends VBox {
|
|
|
232
236
|
else if (item.type === 'options') {
|
|
233
237
|
editor = new Select( {
|
|
234
238
|
value: value as ListboxID,
|
|
235
|
-
id: item.name,
|
|
236
239
|
items: item.options,
|
|
237
240
|
//name: item.name,
|
|
238
241
|
change: ( e: EvChange ) => {
|
|
@@ -243,20 +246,23 @@ export class PropertyGrid extends VBox {
|
|
|
243
246
|
else if (item.type === 'password') {
|
|
244
247
|
editor = new Input({
|
|
245
248
|
type: 'password',
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
value: String(value),
|
|
249
|
+
//name: item.name,
|
|
250
|
+
value: String(value),
|
|
249
251
|
focus: ( e: EvFocus ) => {
|
|
250
252
|
if( e.focus_out ) {
|
|
251
253
|
item.callback?.( item.name, (editor as Input).getValue() );
|
|
252
254
|
}
|
|
255
|
+
},
|
|
256
|
+
change: ( ) => {
|
|
257
|
+
if( item.live ) {
|
|
258
|
+
item.callback?.( item.name, (editor as Input).getValue() );
|
|
259
|
+
}
|
|
253
260
|
}
|
|
254
261
|
});
|
|
255
262
|
}
|
|
256
263
|
else if (item.type === 'number') {
|
|
257
264
|
editor = new Input({
|
|
258
265
|
type: 'number',
|
|
259
|
-
id: item.name,
|
|
260
266
|
//name: item.name,
|
|
261
267
|
value: String(value),
|
|
262
268
|
step: item.step,
|
|
@@ -276,7 +282,6 @@ export class PropertyGrid extends VBox {
|
|
|
276
282
|
}
|
|
277
283
|
else if (item.type === 'color') {
|
|
278
284
|
editor = new ColorInput({
|
|
279
|
-
id: item.name,
|
|
280
285
|
color: value as string,
|
|
281
286
|
format: "hex",
|
|
282
287
|
picker: true,
|
|
@@ -289,14 +294,12 @@ export class PropertyGrid extends VBox {
|
|
|
289
294
|
}
|
|
290
295
|
else if (item.type === 'label') {
|
|
291
296
|
editor = new Label({
|
|
292
|
-
id: item.name,
|
|
293
297
|
text: value as string,
|
|
294
298
|
});
|
|
295
299
|
}
|
|
296
300
|
else if (item.type === 'button') {
|
|
297
301
|
use_hdr = false;
|
|
298
302
|
editor = new Button({
|
|
299
|
-
id: item.name,
|
|
300
303
|
cls: "button",
|
|
301
304
|
label: value as string,
|
|
302
305
|
click: ( ) => {
|
|
@@ -307,7 +310,6 @@ export class PropertyGrid extends VBox {
|
|
|
307
310
|
else {
|
|
308
311
|
editor = new Input({
|
|
309
312
|
type: 'text',
|
|
310
|
-
id: item.name,
|
|
311
313
|
//name: item.name,
|
|
312
314
|
value: value as string,
|
|
313
315
|
focus: ( e: EvFocus ) => {
|
|
@@ -315,8 +317,17 @@ export class PropertyGrid extends VBox {
|
|
|
315
317
|
item.callback?.( item.name, (editor as Input).getValue() );
|
|
316
318
|
}
|
|
317
319
|
},
|
|
320
|
+
change: ( ) => {
|
|
321
|
+
if( item.live ) {
|
|
322
|
+
item.callback?.( item.name, (editor as Input).getValue() );
|
|
323
|
+
}
|
|
324
|
+
}
|
|
318
325
|
})
|
|
319
326
|
}
|
|
327
|
+
|
|
328
|
+
if( item.name ) {
|
|
329
|
+
this.editors.set( item.name, editor );
|
|
330
|
+
}
|
|
320
331
|
|
|
321
332
|
let cls = 'row';
|
|
322
333
|
if( item.cls ) {
|
|
@@ -340,7 +351,7 @@ export class PropertyGrid extends VBox {
|
|
|
340
351
|
cls,
|
|
341
352
|
content: [
|
|
342
353
|
use_hdr ? new Component({ cls: 'cell hdr', content: item.title ?? item.name, tooltip: item.desc }) : null,
|
|
343
|
-
new HBox({ cls: 'cell', tag: "label",
|
|
354
|
+
new HBox({ cls: 'cell', tag: "label", content }),
|
|
344
355
|
]
|
|
345
356
|
});
|
|
346
357
|
}
|
|
@@ -352,45 +363,28 @@ export class PropertyGrid extends VBox {
|
|
|
352
363
|
setPropValue( name: string, value: any ) {
|
|
353
364
|
const all = this.groups.flatMap( x => [ ...x.items ] ) ;
|
|
354
365
|
const item = all.find( x => x.name==name );
|
|
355
|
-
|
|
366
|
+
const editor = this.editors.get( name );
|
|
367
|
+
if( !item || !editor ) {
|
|
356
368
|
return;
|
|
357
369
|
}
|
|
358
370
|
|
|
359
371
|
if (item.type === 'boolean') {
|
|
360
|
-
|
|
361
|
-
if( editor ) {
|
|
362
|
-
editor.setCheck( value as boolean );
|
|
363
|
-
}
|
|
372
|
+
(editor as Input).setCheck( value as boolean );
|
|
364
373
|
}
|
|
365
374
|
else if (item.type === 'options') {
|
|
366
|
-
|
|
367
|
-
if( editor ) {
|
|
368
|
-
editor.setValue( value as string );
|
|
369
|
-
}
|
|
375
|
+
(editor as Select).setValue( value as string );
|
|
370
376
|
}
|
|
371
377
|
else if (item.type === 'number') {
|
|
372
|
-
|
|
373
|
-
if( editor ) {
|
|
374
|
-
editor.setNumValue( value as number, -2 );
|
|
375
|
-
}
|
|
378
|
+
(editor as Input).setNumValue( value as number, -2 );
|
|
376
379
|
}
|
|
377
380
|
else if (item.type === 'color') {
|
|
378
|
-
|
|
379
|
-
if( editor ) {
|
|
380
|
-
editor.setColor( value as string );
|
|
381
|
-
}
|
|
381
|
+
(editor as ColorInput).setColor( value as string );
|
|
382
382
|
}
|
|
383
383
|
else if (item.type === 'label') {
|
|
384
|
-
|
|
385
|
-
if( label ) {
|
|
386
|
-
label.setText( value );
|
|
387
|
-
}
|
|
384
|
+
(editor as Label).setText( value );
|
|
388
385
|
}
|
|
389
386
|
else {
|
|
390
|
-
|
|
391
|
-
if( editor ) {
|
|
392
|
-
editor.setValue( value as string );
|
|
393
|
-
}
|
|
387
|
+
(editor as Input).setValue( value as string );
|
|
394
388
|
}
|
|
395
389
|
}
|
|
396
390
|
|
|
@@ -32,6 +32,15 @@ let mouse_pos: Point = {x:0, y:0 };
|
|
|
32
32
|
|
|
33
33
|
const timer = new Timer( );
|
|
34
34
|
|
|
35
|
+
/**
|
|
36
|
+
* the tooltips are shown once this is called: the text of the attribute "tooltip" (the prop
|
|
37
|
+
* tooltip of a component), or the one getTip( ) of a "tip-handler" gives.
|
|
38
|
+
* This text is shown as html: a text that comes from a user is escaped by the application,
|
|
39
|
+
* with sanitizeHtml( text ).
|
|
40
|
+
* @example
|
|
41
|
+
* new Button( { label: "Open", tooltip: `Open <b>${sanitizeHtml( file.name )}</b>` } );
|
|
42
|
+
*/
|
|
43
|
+
|
|
35
44
|
export function initTooltips( ) {
|
|
36
45
|
|
|
37
46
|
document.addEventListener( "mouseenter", ( ev: MouseEvent ) => {
|
|
@@ -255,7 +255,11 @@ export class Application<E extends ApplicationEvents = ApplicationEvents> extend
|
|
|
255
255
|
private _setupKeyboard( ) {
|
|
256
256
|
|
|
257
257
|
document.addEventListener( "keydown", (ev) => {
|
|
258
|
-
|
|
258
|
+
// Enter in a text of several lines is a new line, not the next field
|
|
259
|
+
const target = ev.target as HTMLElement;
|
|
260
|
+
const multiline = target.tagName==="TEXTAREA" || target.isContentEditable;
|
|
261
|
+
|
|
262
|
+
if( ev.key=="Tab" || ( ev.key=="Enter" && !multiline ) ) {
|
|
259
263
|
if( this.focusNext( !ev.shiftKey ) ) {
|
|
260
264
|
ev.preventDefault( );
|
|
261
265
|
}
|
|
@@ -263,7 +267,8 @@ export class Application<E extends ApplicationEvents = ApplicationEvents> extend
|
|
|
263
267
|
|
|
264
268
|
// The focus is nowhere: the shortcuts of the view the user worked in last.
|
|
265
269
|
// (when it is in a view, the view has seen the key before us)
|
|
266
|
-
|
|
270
|
+
// (a view hidden, in a tab not shown: its shortcuts sleep)
|
|
271
|
+
if( ev.target===document.body && this._active?.owner.isVisible( ) && this._active.shortcuts.handle( ev ) ) {
|
|
267
272
|
return;
|
|
268
273
|
}
|
|
269
274
|
|
package/src/core/core_events.ts
CHANGED
|
@@ -159,6 +159,8 @@ export class EventSource<E extends EventMap = EventMap > {
|
|
|
159
159
|
|
|
160
160
|
/**
|
|
161
161
|
* Dispatches an event with a given name and payload to all registered listeners.
|
|
162
|
+
* A listener that throws: its error goes to console.error, the next listeners are
|
|
163
|
+
* called, and fire returns normally.
|
|
162
164
|
* @param name - The name of the event to fire (must be a key in `E`).
|
|
163
165
|
* @param evx - The event payload (event object) to pass to the listeners.
|
|
164
166
|
*/
|
|
@@ -192,14 +194,24 @@ export class EventSource<E extends EventMap = EventMap > {
|
|
|
192
194
|
ev.stopPropagation = stopPropagation;
|
|
193
195
|
}
|
|
194
196
|
|
|
197
|
+
// a listener that throws stops neither the others nor the one that fires
|
|
198
|
+
const call = ( listener: EventCallback ) => {
|
|
199
|
+
try {
|
|
200
|
+
listener( ev );
|
|
201
|
+
}
|
|
202
|
+
catch( e ) {
|
|
203
|
+
console.error( e );
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
|
|
195
207
|
// small optimisation
|
|
196
208
|
if (listeners.length == 1) {
|
|
197
|
-
listeners[0]
|
|
209
|
+
call( listeners[0] );
|
|
198
210
|
}
|
|
199
211
|
else {
|
|
200
212
|
const temp = listeners.slice();
|
|
201
213
|
for (let i = 0, n = temp.length; i < n; i++) {
|
|
202
|
-
temp[i]
|
|
214
|
+
call( temp[i] );
|
|
203
215
|
if (ev.propagationStopped) {
|
|
204
216
|
break;
|
|
205
217
|
}
|
package/src/core/core_i18n.ts
CHANGED
|
@@ -336,6 +336,13 @@ let fr = {
|
|
|
336
336
|
search: 'Rechercher un paramètre',
|
|
337
337
|
nomatch: 'Aucun paramètre trouvé',
|
|
338
338
|
},
|
|
339
|
+
|
|
340
|
+
progression: {
|
|
341
|
+
error: '{0} erreur',
|
|
342
|
+
errors: '{0} erreurs',
|
|
343
|
+
warning: '{0} avertissement',
|
|
344
|
+
warnings: '{0} avertissements',
|
|
345
|
+
},
|
|
339
346
|
}
|
|
340
347
|
};
|
|
341
348
|
|
|
@@ -406,6 +413,13 @@ let en = {
|
|
|
406
413
|
search: 'Search settings',
|
|
407
414
|
nomatch: 'No setting found',
|
|
408
415
|
},
|
|
416
|
+
|
|
417
|
+
progression: {
|
|
418
|
+
error: '{0} error',
|
|
419
|
+
errors: '{0} errors',
|
|
420
|
+
warning: '{0} warning',
|
|
421
|
+
warnings: '{0} warnings',
|
|
422
|
+
},
|
|
409
423
|
}
|
|
410
424
|
};
|
|
411
425
|
|
|
@@ -476,6 +490,13 @@ let es = {
|
|
|
476
490
|
search: 'Buscar un ajuste',
|
|
477
491
|
nomatch: 'Ningún ajuste encontrado',
|
|
478
492
|
},
|
|
493
|
+
|
|
494
|
+
progression: {
|
|
495
|
+
error: '{0} error',
|
|
496
|
+
errors: '{0} errores',
|
|
497
|
+
warning: '{0} advertencia',
|
|
498
|
+
warnings: '{0} advertencias',
|
|
499
|
+
},
|
|
479
500
|
}
|
|
480
501
|
};
|
|
481
502
|
|
|
@@ -546,6 +567,13 @@ let de = {
|
|
|
546
567
|
search: 'Einstellungen durchsuchen',
|
|
547
568
|
nomatch: 'Keine Einstellung gefunden',
|
|
548
569
|
},
|
|
570
|
+
|
|
571
|
+
progression: {
|
|
572
|
+
error: '{0} Fehler',
|
|
573
|
+
errors: '{0} Fehler',
|
|
574
|
+
warning: '{0} Warnung',
|
|
575
|
+
warnings: '{0} Warnungen',
|
|
576
|
+
},
|
|
549
577
|
}
|
|
550
578
|
};
|
|
551
579
|
|