x4js 2.2.72 → 2.2.74

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "x4js",
3
- "version": "2.2.72",
3
+ "version": "2.2.74",
4
4
  "type": "module",
5
5
  "main": "src/x4.ts",
6
6
  "module": "src/x4.ts",
@@ -424,7 +424,7 @@ export class GridBox<P extends GridBoxProps=GridBoxProps,E extends ComponentEven
424
424
  */
425
425
 
426
426
  setRowCount( n: number ) {
427
- this.setStyleValue( "gridTemplateRows", `repeat(${n})` );
427
+ this.setStyleValue( "gridTemplateRows", `repeat(${n},1fr)` );
428
428
  }
429
429
 
430
430
  /**
@@ -433,7 +433,7 @@ export class GridBox<P extends GridBoxProps=GridBoxProps,E extends ComponentEven
433
433
  */
434
434
 
435
435
  setColCount( n: number ) {
436
- this.setStyleValue( "gridTemplateColumns", `repeat(${n})` );
436
+ this.setStyleValue( "gridTemplateColumns", `repeat(${n},1fr)` );
437
437
  }
438
438
 
439
439
  /**
@@ -442,7 +442,7 @@ export class GridBox<P extends GridBoxProps=GridBoxProps,E extends ComponentEven
442
442
  */
443
443
 
444
444
  setTemplate( t: string[] ) {
445
- this.setAttribute( "grid-template-area", t.map( x => '"' + x + '"' ).join(" ") );
445
+ this.setAttribute( "grid-template-areas", t.map( x => '"' + x + '"' ).join(" ") );
446
446
  }
447
447
 
448
448
  /**
@@ -93,11 +93,11 @@ export class Canvas extends Component<CanvasProps, CanvasEventMap> {
93
93
  * redraw the canvas (force a paint)
94
94
  */
95
95
 
96
- private $update_rep = 0;
96
+ #update_rep = 0;
97
97
  public redraw(wait?: number) {
98
98
 
99
99
  if (wait !== undefined) {
100
- if( ++this.$update_rep>=20 ) {
100
+ if( ++this.#update_rep>=20 ) {
101
101
  this.clearTimeout( 'update' );
102
102
  this._paint( );
103
103
  }
@@ -115,67 +115,63 @@ export class Canvas extends Component<CanvasProps, CanvasEventMap> {
115
115
  *
116
116
  */
117
117
 
118
+ #pixel_ratio = -1 // can change when moving to another screen
118
119
  private _paint() {
119
- this.$update_rep = 0;
120
+ this.#update_rep = 0;
120
121
 
121
- let dom = this.dom;
122
- if (!this.isVisible() ) {
122
+ if (!this.isVisible()) {
123
123
  return;
124
124
  }
125
125
 
126
- //const canvas = this.m_canvas.dom as HTMLCanvasElement;
126
+ const dom = this.dom;
127
127
  const w = dom.clientWidth;
128
128
  const h = dom.clientHeight;
129
129
 
130
+ if (!w || !h) {
131
+ return;
132
+ }
133
+
130
134
  const ctx = this.getContext();
131
- if (w != this.m_iwidth || h != this.m_iheight) {
132
- // adjustment for HDPI
133
- let devicePixelRatio = window.devicePixelRatio || 1;
134
- let backingStoreRatio = (<any>ctx).webkitBackingStorePixelRatio ||
135
- (<any>ctx).mozBackingStorePixelRatio ||
136
- (<any>ctx).msBackingStorePixelRatio ||
137
- (<any>ctx).oBackingStorePixelRatio ||
138
- (<any>ctx).backingStorePixelRatio || 1;
139
-
140
- let canvas = this.canvas;
141
-
142
- if ( this.m_scale != 1.0 ) { //devicePixelRatio !== backingStoreRatio || this.m_scale != 1.0) {
143
- let ratio = 1; //devicePixelRatio / backingStoreRatio,
144
- const rw = w * ratio;
145
- const rh = h * ratio;
146
-
147
- canvas.setAttribute('width', '' + rw);
148
- canvas.setAttribute('height', '' + rh);
149
- canvas.setStyleValue('width', w);
150
- canvas.setStyleValue('height', h);
151
-
152
- ratio *= this.m_scale;
153
- ctx.scale(ratio, ratio);
154
- }
155
- else {
156
- canvas.setAttribute('width', '' + w);
157
- canvas.setAttribute('height', '' + h);
158
- canvas.setStyleValue('width', w);
159
- canvas.setStyleValue('height', h);
160
- ctx.scale(1, 1);
161
- }
135
+ const ratio = window.devicePixelRatio || 1;
136
+
137
+ if (
138
+ w !== this.m_iwidth ||
139
+ h !== this.m_iheight ||
140
+ ratio !== this.#pixel_ratio
141
+ ) {
142
+ const canvas = this.canvas;
143
+
144
+ // CSS size stays in logical pixels, while the backing buffer
145
+ // uses the physical screen resolution.
146
+ canvas.setAttribute('width', '' + Math.round(w * ratio));
147
+ canvas.setAttribute('height', '' + Math.round(h * ratio));
148
+ canvas.setStyleValue('width', w);
149
+ canvas.setStyleValue('height', h);
162
150
 
163
151
  this.m_iwidth = w;
164
152
  this.m_iheight = h;
153
+ this.#pixel_ratio = ratio;
165
154
  }
166
155
 
167
- if (w && h) {
168
- let cc = createPainter(ctx, w, h);
169
- if (this.props.clear) {
170
-
171
- cc.clearRect(0,0,w/this.m_scale,h/this.m_scale);
172
- }
156
+ // setTransform avoids accumulating transformations between paints.
157
+ const scale = ratio * this.m_scale;
158
+ ctx.setTransform(scale, 0, 0, scale, 0, 0);
173
159
 
174
- cc.save();
175
- cc.translate(-0.5, -0.5);
176
- this.paint(cc);
177
- cc.restore();
160
+ const cc = createPainter(ctx, w, h);
161
+
162
+ if (this.props.clear) {
163
+ cc.clearRect(
164
+ 0,
165
+ 0,
166
+ w / this.m_scale,
167
+ h / this.m_scale
168
+ );
178
169
  }
170
+
171
+ cc.save();
172
+ cc.translate(-0.5, -0.5);
173
+ this.paint(cc);
174
+ cc.restore();
179
175
  }
180
176
 
181
177
  protected paint(ctx: CanvasEx ) {
@@ -157,7 +157,7 @@ export class Form<P extends FormProps = FormProps> extends Box<P> {
157
157
 
158
158
  for( let name in result ) {
159
159
  if( new_values[name] != result[name] ) {
160
- const x = this.query( `input[${name}"]` );
160
+ const x = this.query( `input[name="${name}"]` );
161
161
  const ifx = x.queryInterface( "form-element" ) as IFormElement;
162
162
  ifx.setRawValue( new_values[name] );
163
163
  }
@@ -391,15 +391,15 @@ export class Gridview<P extends GridviewProps = GridviewProps, E extends Gridvie
391
391
  }
392
392
  }
393
393
 
394
+ /*
394
395
  setColumns( columns: GridColumn[] ) {
395
396
  this._columns = columns.map(x => x);
397
+
396
398
  if( this.dom ) {
397
-
398
399
  this._updateFlexs( );
399
400
 
400
401
  // Rebuild headers
401
402
  if (this._fheader) {
402
- /*
403
403
  const newFixedHeader = this._buildColHeader(true);
404
404
  this._fheader.setContent(newFixedHeader.getChildren());
405
405
  // On doit remplacer _fheader dans le DOM ou mettre à jour son contenu
@@ -444,14 +444,13 @@ export class Gridview<P extends GridviewProps = GridviewProps, E extends Gridvie
444
444
  }
445
445
 
446
446
  this.setContent(content);
447
- */
448
- console.assert( false, "TODO" );
449
447
  }
450
448
 
451
449
  this._computeFullSize( );
452
450
  this._update( true );
453
451
  }
454
452
  }
453
+ */
455
454
 
456
455
  getView( ): DataView {
457
456
  return this._dataview;
@@ -862,7 +861,7 @@ export class Gridview<P extends GridviewProps = GridviewProps, E extends Gridvie
862
861
  continue;
863
862
  }
864
863
 
865
- const content = this._renderCell(rec, cdata.id, [cdata.type] );
864
+ const content = this._renderCell(rec, cdata, [cdata.type] );
866
865
 
867
866
  let align = "start";
868
867
  switch (cdata.align) {
@@ -38,7 +38,7 @@ export interface PropertyValue {
38
38
  name?: string;
39
39
  value: IValue | IValueCB;
40
40
  options?: ListItem[];
41
- callback: ( name: string, value: any ) => void;
41
+ callback?: ( name: string, value: any ) => void;
42
42
  live?: boolean; // for live update
43
43
  cls?: string;
44
44
  step?: number; // for numbers
@@ -347,6 +347,12 @@ export class PropertyGrid extends VBox {
347
347
  editor.setNumValue( value as number, -2 );
348
348
  }
349
349
  }
350
+ else if (item.type === 'label') {
351
+ const label = this.root.query<Label>( '#'+item.name );
352
+ if( label ) {
353
+ label.setText( value );
354
+ }
355
+ }
350
356
  else {
351
357
  const editor = this.root.query<Input>( '#'+item.name );
352
358
  if( editor ) {
@@ -5,7 +5,7 @@ import { Component, ComponentProps } from '../../core/component';
5
5
  import "./tickline.module.scss"
6
6
  import { class_ns } from '../../core/core_tools';
7
7
 
8
- interface TickLineProps extends ComponentProps {
8
+ export interface TickLineProps extends ComponentProps {
9
9
  values: number[];
10
10
  min?: number;
11
11
  max?: number;
@@ -45,7 +45,8 @@ export class TickLine extends Component<TickLineProps> {
45
45
  const vals = props.values;
46
46
  const padding = 4;
47
47
 
48
- if( !vals.length ) {
48
+ if( (props.type=='bars' && vals.length==0) ||
49
+ (props.type=='line' && vals.length<2) ) {
49
50
  this.clearContent( );
50
51
  return;
51
52
  }
@@ -52,7 +52,7 @@ export interface TreeItem extends ListItem {
52
52
  open?: boolean;
53
53
  }
54
54
 
55
- interface TreeviewProps extends Omit<ComponentProps,"content"> {
55
+ export interface TreeviewProps extends Omit<ComponentProps,"content"> {
56
56
  items: TreeItem[];
57
57
  footer?: Component;
58
58
  emptyMsg?: string;
@@ -61,7 +61,7 @@ interface TreeviewProps extends Omit<ComponentProps,"content"> {
61
61
  click?: EventCallback<EvClick>;
62
62
  }
63
63
 
64
- interface TreeviewEvents extends ComponentEvents {
64
+ export interface TreeviewEvents extends ComponentEvents {
65
65
  selectionChange?: EvSelectionChange;
66
66
  dblClick?: EvDblClick;
67
67
  click?: EvClick;
@@ -315,7 +315,7 @@ export class DataModel<T = any> {
315
315
 
316
316
  fields.forEach( (fi) => {
317
317
  if( fi.required && !this.getField(fi.name,record) ) {
318
- if( errs ) {
318
+ if( !errs ) {
319
319
  errs = [];
320
320
  }
321
321
 
@@ -260,6 +260,7 @@ export class CoreElement<E extends EventMap = EventMap> {
260
260
  cleanUp( ) {
261
261
  this.clearTimeouts( );
262
262
  this.#cleanup?.forEach( x => x() );
263
+ this.#cleanup.length = 0;
263
264
  }
264
265
 
265
266
  // :: EVENTS ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
@@ -26,8 +26,6 @@
26
26
  translations: any;
27
27
  }
28
28
 
29
- const sym_lang = Symbol( "i18n" );
30
-
31
29
  let languages: Record<string,Language> = {
32
30
  };
33
31
 
@@ -211,7 +209,46 @@ function _findBaseTrans( base: any ) {
211
209
  return undefined;
212
210
  }
213
211
 
214
- export let _tr: Partial<typeof fr> = {};
212
+ /**
213
+ * current language state
214
+ */
215
+
216
+ const current = {
217
+ name: "",
218
+ translations: {} as any,
219
+ };
220
+
221
+ /**
222
+ * stable translation object: forwards every access to the current language,
223
+ * so references to _tr stay valid after selectLanguage
224
+ */
225
+
226
+ const tr_handler: ProxyHandler<any> = {
227
+ get( _target, prop ) {
228
+ return current.translations[prop];
229
+ },
230
+
231
+ has( _target, prop ) {
232
+ return prop in current.translations;
233
+ },
234
+
235
+ ownKeys( ) {
236
+ return Reflect.ownKeys( current.translations );
237
+ },
238
+
239
+ getOwnPropertyDescriptor( _target, prop ) {
240
+ const value = current.translations[prop];
241
+
242
+ if( value === undefined ) {
243
+ return undefined;
244
+ }
245
+
246
+ return { value, enumerable: true, configurable: true };
247
+ },
248
+ };
249
+
250
+ export const _tr: Partial<typeof fr> = new Proxy( {}, tr_handler );
251
+
215
252
 
216
253
  /**
217
254
  * select the given language as current
@@ -224,8 +261,9 @@ export function selectLanguage( name: string ) {
224
261
  return;
225
262
  }
226
263
 
227
- _tr = languages[name].translations;
228
- (_tr as any)[sym_lang] = name;
264
+ current.name = name;
265
+ current.translations = languages[name].translations;
266
+
229
267
  return _tr;
230
268
  }
231
269
 
@@ -234,7 +272,7 @@ export function selectLanguage( name: string ) {
234
272
  */
235
273
 
236
274
  export function getCurrentLanguage( ): string {
237
- return (_tr as any)[sym_lang];
275
+ return current.name;
238
276
  }
239
277
 
240
278
  /**
@@ -359,8 +397,8 @@ let en = {
359
397
  day_short: [ 'sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat' ],
360
398
  day_long: [ 'sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday' ],
361
399
 
362
- month_short: [ 'jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jui', 'aug', 'sep', 'oct', 'nov', 'dec' ],
363
- month_long: [ 'january', 'february', 'march', 'april', 'mau', 'june', 'jully', 'august', 'september', 'october', 'november', 'december' ],
400
+ month_short: [ 'jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec' ],
401
+ month_long: [ 'january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december' ],
364
402
 
365
403
  property: 'Property',
366
404
  value: 'Value',