canvasframework 0.3.26 → 0.3.28
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/components/AndroidDatePickerDialog.js +14 -6
- package/components/Camera.js +247 -15
- package/components/DatePicker.js +87 -53
- package/components/TimePicker.js +842 -351
- package/core/CanvasFramework.js +2 -0
- package/core/UIBuilder.js +2 -0
- package/index.js +1 -0
- package/package.json +1 -1
|
@@ -31,21 +31,29 @@ class AndroidDatePickerDialog extends Component {
|
|
|
31
31
|
height: framework.height,
|
|
32
32
|
visible: false
|
|
33
33
|
});
|
|
34
|
-
|
|
34
|
+
|
|
35
35
|
this.selectedDate = options.selectedDate || new Date();
|
|
36
36
|
this.onChange = options.onChange;
|
|
37
37
|
this.currentMonth = this.selectedDate.getMonth();
|
|
38
38
|
this.currentYear = this.selectedDate.getFullYear();
|
|
39
39
|
this.hoveredDay = null;
|
|
40
|
-
|
|
40
|
+
|
|
41
|
+
// Options de personnalisation
|
|
42
|
+
this.headerBgColor = options.headerBgColor || '#6200EE';
|
|
43
|
+
this.selectedColor = options.selectedColor || '#6200EE';
|
|
44
|
+
this.buttonColor = options.buttonColor || '#6200EE';
|
|
45
|
+
this.todayColor = options.todayColor || '#6200EE';
|
|
46
|
+
this.textColor = options.textColor || '#000000';
|
|
47
|
+
this.dayNamesColor = options.dayNamesColor || '#666666';
|
|
48
|
+
|
|
41
49
|
this.dialogWidth = Math.min(320, framework.width - 40);
|
|
42
50
|
this.dialogHeight = 420;
|
|
43
51
|
this.headerHeight = 100;
|
|
44
52
|
this.daySize = (this.dialogWidth - 40) / 7;
|
|
45
|
-
|
|
53
|
+
|
|
46
54
|
this.opacity = 0;
|
|
47
55
|
this.isVisible = false;
|
|
48
|
-
|
|
56
|
+
|
|
49
57
|
this.onPress = this.handlePress.bind(this);
|
|
50
58
|
}
|
|
51
59
|
|
|
@@ -183,7 +191,7 @@ class AndroidDatePickerDialog extends Component {
|
|
|
183
191
|
const selectedMonth = monthNames[this.selectedDate.getMonth()];
|
|
184
192
|
const selectedDayNum = this.selectedDate.getDate();
|
|
185
193
|
|
|
186
|
-
ctx.fillStyle = '#
|
|
194
|
+
ctx.fillStyle = '#000000';
|
|
187
195
|
ctx.font = 'bold 32px Roboto, sans-serif';
|
|
188
196
|
ctx.textBaseline = 'middle';
|
|
189
197
|
ctx.fillText(`${selectedDay}, ${selectedMonth} ${selectedDayNum}`,
|
|
@@ -263,7 +271,7 @@ class AndroidDatePickerDialog extends Component {
|
|
|
263
271
|
}
|
|
264
272
|
|
|
265
273
|
// Numéro
|
|
266
|
-
ctx.fillStyle = isSelected ? '#FFFFFF' : '#
|
|
274
|
+
ctx.fillStyle = isSelected ? '#FFFFFF' : '#212121';
|
|
267
275
|
ctx.font = '14px Roboto, sans-serif';
|
|
268
276
|
ctx.textAlign = 'center';
|
|
269
277
|
ctx.textBaseline = 'middle';
|
package/components/Camera.js
CHANGED
|
@@ -280,6 +280,218 @@ class Camera extends Component {
|
|
|
280
280
|
}
|
|
281
281
|
}
|
|
282
282
|
|
|
283
|
+
drawContainIcon(ctx, x, y, size) {
|
|
284
|
+
// Icône "contain" : rectangle avec flèches vers l'intérieur
|
|
285
|
+
const pad = size * 0.2;
|
|
286
|
+
ctx.strokeStyle = '#000';
|
|
287
|
+
ctx.lineWidth = 2;
|
|
288
|
+
|
|
289
|
+
// Rectangle extérieur
|
|
290
|
+
ctx.strokeRect(x + pad, y + pad, size - pad * 2, size - pad * 2);
|
|
291
|
+
|
|
292
|
+
// Flèches pointant vers l'intérieur
|
|
293
|
+
const arrowSize = size * 0.15;
|
|
294
|
+
ctx.fillStyle = '#000';
|
|
295
|
+
|
|
296
|
+
// Flèche haut
|
|
297
|
+
ctx.beginPath();
|
|
298
|
+
ctx.moveTo(x + size/2, y + pad - 2);
|
|
299
|
+
ctx.lineTo(x + size/2 - arrowSize, y + pad + arrowSize);
|
|
300
|
+
ctx.lineTo(x + size/2 + arrowSize, y + pad + arrowSize);
|
|
301
|
+
ctx.fill();
|
|
302
|
+
|
|
303
|
+
// Flèche bas
|
|
304
|
+
ctx.beginPath();
|
|
305
|
+
ctx.moveTo(x + size/2, y + size - pad + 2);
|
|
306
|
+
ctx.lineTo(x + size/2 - arrowSize, y + size - pad - arrowSize);
|
|
307
|
+
ctx.lineTo(x + size/2 + arrowSize, y + size - pad - arrowSize);
|
|
308
|
+
ctx.fill();
|
|
309
|
+
|
|
310
|
+
// Flèche gauche
|
|
311
|
+
ctx.beginPath();
|
|
312
|
+
ctx.moveTo(x + pad - 2, y + size/2);
|
|
313
|
+
ctx.lineTo(x + pad + arrowSize, y + size/2 - arrowSize);
|
|
314
|
+
ctx.lineTo(x + pad + arrowSize, y + size/2 + arrowSize);
|
|
315
|
+
ctx.fill();
|
|
316
|
+
|
|
317
|
+
// Flèche droite
|
|
318
|
+
ctx.beginPath();
|
|
319
|
+
ctx.moveTo(x + size - pad + 2, y + size/2);
|
|
320
|
+
ctx.lineTo(x + size - pad - arrowSize, y + size/2 - arrowSize);
|
|
321
|
+
ctx.lineTo(x + size - pad - arrowSize, y + size/2 + arrowSize);
|
|
322
|
+
ctx.fill();
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
drawCoverIcon(ctx, x, y, size) {
|
|
326
|
+
// Icône "cover" : rectangle avec flèches vers l'extérieur
|
|
327
|
+
const pad = size * 0.2;
|
|
328
|
+
ctx.strokeStyle = '#000';
|
|
329
|
+
ctx.lineWidth = 2;
|
|
330
|
+
|
|
331
|
+
// Rectangle intérieur
|
|
332
|
+
ctx.strokeRect(x + pad, y + pad, size - pad * 2, size - pad * 2);
|
|
333
|
+
|
|
334
|
+
// Flèches pointant vers l'extérieur
|
|
335
|
+
const arrowSize = size * 0.15;
|
|
336
|
+
ctx.fillStyle = '#000';
|
|
337
|
+
|
|
338
|
+
// Flèche haut
|
|
339
|
+
ctx.beginPath();
|
|
340
|
+
ctx.moveTo(x + size/2, y + 2);
|
|
341
|
+
ctx.lineTo(x + size/2 - arrowSize, y + arrowSize + 2);
|
|
342
|
+
ctx.lineTo(x + size/2 + arrowSize, y + arrowSize + 2);
|
|
343
|
+
ctx.fill();
|
|
344
|
+
|
|
345
|
+
// Flèche bas
|
|
346
|
+
ctx.beginPath();
|
|
347
|
+
ctx.moveTo(x + size/2, y + size - 2);
|
|
348
|
+
ctx.lineTo(x + size/2 - arrowSize, y + size - arrowSize - 2);
|
|
349
|
+
ctx.lineTo(x + size/2 + arrowSize, y + size - arrowSize - 2);
|
|
350
|
+
ctx.fill();
|
|
351
|
+
|
|
352
|
+
// Flèche gauche
|
|
353
|
+
ctx.beginPath();
|
|
354
|
+
ctx.moveTo(x + 2, y + size/2);
|
|
355
|
+
ctx.lineTo(x + arrowSize + 2, y + size/2 - arrowSize);
|
|
356
|
+
ctx.lineTo(x + arrowSize + 2, y + size/2 + arrowSize);
|
|
357
|
+
ctx.fill();
|
|
358
|
+
|
|
359
|
+
// Flèche droite
|
|
360
|
+
ctx.beginPath();
|
|
361
|
+
ctx.moveTo(x + size - 2, y + size/2);
|
|
362
|
+
ctx.lineTo(x + size - arrowSize - 2, y + size/2 - arrowSize);
|
|
363
|
+
ctx.lineTo(x + size - arrowSize - 2, y + size/2 + arrowSize);
|
|
364
|
+
ctx.fill();
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
drawContainIcon(ctx, x, y, size) {
|
|
368
|
+
// Icône "contain" : rectangle avec flèches vers l'intérieur
|
|
369
|
+
const pad = size * 0.2;
|
|
370
|
+
ctx.strokeStyle = '#000';
|
|
371
|
+
ctx.lineWidth = 2;
|
|
372
|
+
|
|
373
|
+
// Rectangle extérieur
|
|
374
|
+
ctx.strokeRect(x + pad, y + pad, size - pad * 2, size - pad * 2);
|
|
375
|
+
|
|
376
|
+
// Flèches pointant vers l'intérieur
|
|
377
|
+
const arrowSize = size * 0.15;
|
|
378
|
+
ctx.fillStyle = '#000';
|
|
379
|
+
|
|
380
|
+
// Flèche haut
|
|
381
|
+
ctx.beginPath();
|
|
382
|
+
ctx.moveTo(x + size/2, y + pad - 2);
|
|
383
|
+
ctx.lineTo(x + size/2 - arrowSize, y + pad + arrowSize);
|
|
384
|
+
ctx.lineTo(x + size/2 + arrowSize, y + pad + arrowSize);
|
|
385
|
+
ctx.fill();
|
|
386
|
+
|
|
387
|
+
// Flèche bas
|
|
388
|
+
ctx.beginPath();
|
|
389
|
+
ctx.moveTo(x + size/2, y + size - pad + 2);
|
|
390
|
+
ctx.lineTo(x + size/2 - arrowSize, y + size - pad - arrowSize);
|
|
391
|
+
ctx.lineTo(x + size/2 + arrowSize, y + size - pad - arrowSize);
|
|
392
|
+
ctx.fill();
|
|
393
|
+
|
|
394
|
+
// Flèche gauche
|
|
395
|
+
ctx.beginPath();
|
|
396
|
+
ctx.moveTo(x + pad - 2, y + size/2);
|
|
397
|
+
ctx.lineTo(x + pad + arrowSize, y + size/2 - arrowSize);
|
|
398
|
+
ctx.lineTo(x + pad + arrowSize, y + size/2 + arrowSize);
|
|
399
|
+
ctx.fill();
|
|
400
|
+
|
|
401
|
+
// Flèche droite
|
|
402
|
+
ctx.beginPath();
|
|
403
|
+
ctx.moveTo(x + size - pad + 2, y + size/2);
|
|
404
|
+
ctx.lineTo(x + size - pad - arrowSize, y + size/2 - arrowSize);
|
|
405
|
+
ctx.lineTo(x + size - pad - arrowSize, y + size/2 + arrowSize);
|
|
406
|
+
ctx.fill();
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
drawCoverIcon(ctx, x, y, size) {
|
|
410
|
+
// Icône "cover" : rectangle avec flèches vers l'extérieur
|
|
411
|
+
const pad = size * 0.2;
|
|
412
|
+
ctx.strokeStyle = '#000';
|
|
413
|
+
ctx.lineWidth = 2;
|
|
414
|
+
|
|
415
|
+
// Rectangle intérieur
|
|
416
|
+
ctx.strokeRect(x + pad, y + pad, size - pad * 2, size - pad * 2);
|
|
417
|
+
|
|
418
|
+
// Flèches pointant vers l'extérieur
|
|
419
|
+
const arrowSize = size * 0.15;
|
|
420
|
+
ctx.fillStyle = '#000';
|
|
421
|
+
|
|
422
|
+
// Flèche haut
|
|
423
|
+
ctx.beginPath();
|
|
424
|
+
ctx.moveTo(x + size/2, y + 2);
|
|
425
|
+
ctx.lineTo(x + size/2 - arrowSize, y + arrowSize + 2);
|
|
426
|
+
ctx.lineTo(x + size/2 + arrowSize, y + arrowSize + 2);
|
|
427
|
+
ctx.fill();
|
|
428
|
+
|
|
429
|
+
// Flèche bas
|
|
430
|
+
ctx.beginPath();
|
|
431
|
+
ctx.moveTo(x + size/2, y + size - 2);
|
|
432
|
+
ctx.lineTo(x + size/2 - arrowSize, y + size - arrowSize - 2);
|
|
433
|
+
ctx.lineTo(x + size/2 + arrowSize, y + size - arrowSize - 2);
|
|
434
|
+
ctx.fill();
|
|
435
|
+
|
|
436
|
+
// Flèche gauche
|
|
437
|
+
ctx.beginPath();
|
|
438
|
+
ctx.moveTo(x + 2, y + size/2);
|
|
439
|
+
ctx.lineTo(x + arrowSize + 2, y + size/2 - arrowSize);
|
|
440
|
+
ctx.lineTo(x + arrowSize + 2, y + size/2 + arrowSize);
|
|
441
|
+
ctx.fill();
|
|
442
|
+
|
|
443
|
+
// Flèche droite
|
|
444
|
+
ctx.beginPath();
|
|
445
|
+
ctx.moveTo(x + size - 2, y + size/2);
|
|
446
|
+
ctx.lineTo(x + size - arrowSize - 2, y + size/2 - arrowSize);
|
|
447
|
+
ctx.lineTo(x + size - arrowSize - 2, y + size/2 + arrowSize);
|
|
448
|
+
ctx.fill();
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
drawSwitchCameraIcon(ctx, x, y, size) {
|
|
452
|
+
// Icône de switch caméra : deux caméras avec flèche circulaire
|
|
453
|
+
const centerX = x + size / 2;
|
|
454
|
+
const centerY = y + size / 2;
|
|
455
|
+
const radius = size * 0.35;
|
|
456
|
+
|
|
457
|
+
ctx.strokeStyle = '#ffffff';
|
|
458
|
+
ctx.lineWidth = 3;
|
|
459
|
+
ctx.lineCap = 'round';
|
|
460
|
+
|
|
461
|
+
// Arc circulaire (flèche de rotation)
|
|
462
|
+
ctx.beginPath();
|
|
463
|
+
ctx.arc(centerX, centerY, radius, -Math.PI * 0.7, Math.PI * 0.7);
|
|
464
|
+
ctx.stroke();
|
|
465
|
+
|
|
466
|
+
// Flèche en haut à droite
|
|
467
|
+
const arrowSize = size * 0.15;
|
|
468
|
+
const arrowAngle = Math.PI * 0.7;
|
|
469
|
+
const arrowX = centerX + radius * Math.cos(arrowAngle);
|
|
470
|
+
const arrowY = centerY + radius * Math.sin(arrowAngle);
|
|
471
|
+
|
|
472
|
+
ctx.fillStyle = '#ffffff';
|
|
473
|
+
ctx.beginPath();
|
|
474
|
+
ctx.moveTo(arrowX, arrowY);
|
|
475
|
+
ctx.lineTo(arrowX - arrowSize, arrowY - arrowSize * 0.5);
|
|
476
|
+
ctx.lineTo(arrowX - arrowSize * 0.5, arrowY + arrowSize);
|
|
477
|
+
ctx.fill();
|
|
478
|
+
|
|
479
|
+
// Mini caméra au centre
|
|
480
|
+
const camWidth = size * 0.25;
|
|
481
|
+
const camHeight = size * 0.18;
|
|
482
|
+
const camX = centerX - camWidth / 2;
|
|
483
|
+
const camY = centerY - camHeight / 2;
|
|
484
|
+
|
|
485
|
+
ctx.fillStyle = '#ffffff';
|
|
486
|
+
ctx.fillRect(camX, camY, camWidth, camHeight);
|
|
487
|
+
|
|
488
|
+
// Objectif
|
|
489
|
+
ctx.fillStyle = '#000';
|
|
490
|
+
ctx.beginPath();
|
|
491
|
+
ctx.arc(centerX, centerY, size * 0.08, 0, Math.PI * 2);
|
|
492
|
+
ctx.fill();
|
|
493
|
+
}
|
|
494
|
+
|
|
283
495
|
draw(ctx) {
|
|
284
496
|
ctx.save();
|
|
285
497
|
|
|
@@ -340,7 +552,9 @@ class Camera extends Component {
|
|
|
340
552
|
// Mini preview dernière photo (bas droite, 3s)
|
|
341
553
|
if (this.previewPhoto) {
|
|
342
554
|
const previewSize = 80;
|
|
343
|
-
|
|
555
|
+
const img = new Image();
|
|
556
|
+
img.src = this.previewPhoto;
|
|
557
|
+
ctx.drawImage(img, this.x + this.width - previewSize - 10, this.y + this.height - previewSize - 10, previewSize, previewSize);
|
|
344
558
|
ctx.strokeStyle = '#fff';
|
|
345
559
|
ctx.lineWidth = 2;
|
|
346
560
|
ctx.strokeRect(this.x + this.width - previewSize - 10, this.y + this.height - previewSize - 10, previewSize, previewSize);
|
|
@@ -363,10 +577,19 @@ class Camera extends Component {
|
|
|
363
577
|
ctx.arc(this.x + this.width/2, this.y + this.height - 50, this.captureButtonRadius + 10, 0, Math.PI * 2);
|
|
364
578
|
ctx.stroke();
|
|
365
579
|
|
|
366
|
-
// Switch caméra
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
580
|
+
// Switch caméra avec icône
|
|
581
|
+
const switchBtnX = this.x + 20;
|
|
582
|
+
const switchBtnY = this.y + 20;
|
|
583
|
+
const switchBtnSize = 50;
|
|
584
|
+
|
|
585
|
+
// Fond semi-transparent
|
|
586
|
+
ctx.fillStyle = 'rgba(0,0,0,0.5)';
|
|
587
|
+
ctx.beginPath();
|
|
588
|
+
ctx.arc(switchBtnX + switchBtnSize/2, switchBtnY + switchBtnSize/2, switchBtnSize/2, 0, Math.PI * 2);
|
|
589
|
+
ctx.fill();
|
|
590
|
+
|
|
591
|
+
// Icône
|
|
592
|
+
this.drawSwitchCameraIcon(ctx, switchBtnX, switchBtnY, switchBtnSize);
|
|
370
593
|
|
|
371
594
|
// Torch
|
|
372
595
|
if (this.torchSupported) {
|
|
@@ -374,16 +597,25 @@ class Camera extends Component {
|
|
|
374
597
|
ctx.fillText('⚡', this.x + this.width - 50, this.y + 45);
|
|
375
598
|
}
|
|
376
599
|
|
|
377
|
-
// Bouton switch mode
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
ctx.
|
|
383
|
-
ctx.
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
600
|
+
// Bouton switch mode avec icône
|
|
601
|
+
const btnX = this.x + this.width - 80;
|
|
602
|
+
const btnY = this.y + 20;
|
|
603
|
+
|
|
604
|
+
// Fond du bouton
|
|
605
|
+
ctx.fillStyle = 'rgba(255,255,255,0.9)';
|
|
606
|
+
ctx.fillRect(btnX, btnY, this.modeButtonSize, this.modeButtonSize);
|
|
607
|
+
|
|
608
|
+
// Bordure
|
|
609
|
+
ctx.strokeStyle = '#000';
|
|
610
|
+
ctx.lineWidth = 2;
|
|
611
|
+
ctx.strokeRect(btnX, btnY, this.modeButtonSize, this.modeButtonSize);
|
|
612
|
+
|
|
613
|
+
// Dessiner l'icône appropriée
|
|
614
|
+
if (this.fitMode === 'contain') {
|
|
615
|
+
this.drawContainIcon(ctx, btnX, btnY, this.modeButtonSize);
|
|
616
|
+
} else {
|
|
617
|
+
this.drawCoverIcon(ctx, btnX, btnY, this.modeButtonSize);
|
|
618
|
+
}
|
|
387
619
|
|
|
388
620
|
ctx.restore();
|
|
389
621
|
}
|
package/components/DatePicker.js
CHANGED
|
@@ -35,19 +35,29 @@ class DatePicker extends Component {
|
|
|
35
35
|
this.onChange = options.onChange;
|
|
36
36
|
this.platform = framework.platform;
|
|
37
37
|
this.label = options.label || 'Sélectionner une date';
|
|
38
|
-
|
|
39
|
-
//
|
|
38
|
+
|
|
39
|
+
// Options de personnalisation
|
|
40
|
+
this.headerBgColor = options.headerBgColor || '#6200EE'; // Android dialog header
|
|
41
|
+
this.inputBgColor = options.inputBgColor || null;
|
|
42
|
+
this.inputTextColor = options.inputTextColor || null;
|
|
43
|
+
this.inputBorderColor = options.inputBorderColor || null;
|
|
44
|
+
this.labelColor = options.labelColor || null;
|
|
45
|
+
this.inputHeight = options.inputHeight || 50;
|
|
46
|
+
this.inputRadius = options.inputRadius || (this.platform === 'cupertino' ? 10 : 0);
|
|
47
|
+
this.fontSize = options.fontSize || null;
|
|
48
|
+
this.selectedColor = options.selectedColor || '#6200EE'; // Android selected items
|
|
49
|
+
this.buttonColor = options.buttonColor || '#6200EE'; // Android buttons
|
|
50
|
+
|
|
51
|
+
// Dimensions
|
|
40
52
|
if (this.platform === 'cupertino') {
|
|
41
53
|
this.width = options.width || framework.width - 40;
|
|
42
|
-
this.height = 50;
|
|
43
54
|
this.pickerModal = null;
|
|
44
|
-
this.onClick = this.openPicker.bind(this);
|
|
45
55
|
} else {
|
|
46
|
-
// Pour Android: afficher directement le modal
|
|
47
56
|
this.width = options.width || Math.min(320, framework.width - 40);
|
|
48
|
-
this.height = 50;
|
|
49
|
-
this.onClick = this.openPicker.bind(this);
|
|
50
57
|
}
|
|
58
|
+
|
|
59
|
+
this.height = this.inputHeight;
|
|
60
|
+
this.onClick = this.openPicker.bind(this);
|
|
51
61
|
}
|
|
52
62
|
|
|
53
63
|
/**
|
|
@@ -69,7 +79,6 @@ class DatePicker extends Component {
|
|
|
69
79
|
|
|
70
80
|
|
|
71
81
|
openIOSPicker() {
|
|
72
|
-
// Créer un modal avec le picker iOS
|
|
73
82
|
const modal = new Modal(this.framework, {
|
|
74
83
|
title: '',
|
|
75
84
|
width: this.framework.width,
|
|
@@ -78,8 +87,7 @@ class DatePicker extends Component {
|
|
|
78
87
|
closeOnOverlayClick: true,
|
|
79
88
|
bgColor: '#F9F9F9'
|
|
80
89
|
});
|
|
81
|
-
|
|
82
|
-
// Créer le picker de date iOS style
|
|
90
|
+
|
|
83
91
|
const picker = new IOSDatePickerWheel(this.framework, {
|
|
84
92
|
x: 0,
|
|
85
93
|
y: 20,
|
|
@@ -89,22 +97,23 @@ class DatePicker extends Component {
|
|
|
89
97
|
this.selectedDate = date;
|
|
90
98
|
if (this.onChange) this.onChange(date);
|
|
91
99
|
}
|
|
100
|
+
// Ajoutez ici d'autres options si IOSDatePickerWheel en supporte
|
|
92
101
|
});
|
|
93
102
|
modal.add(picker);
|
|
94
|
-
|
|
95
|
-
// Bouton Valider
|
|
103
|
+
|
|
96
104
|
const btnOK = new Button(this.framework, {
|
|
97
105
|
x: (this.framework.width - 200) / 2,
|
|
98
106
|
y: 230,
|
|
99
107
|
width: 200,
|
|
100
108
|
height: 44,
|
|
101
109
|
text: 'Valider',
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
110
|
+
// Personnalisation du bouton si nécessaire
|
|
111
|
+
bgColor: this.buttonColor,
|
|
112
|
+
textColor: '#FFFFFF',
|
|
113
|
+
onClick: () => modal.hide()
|
|
105
114
|
});
|
|
106
115
|
modal.add(btnOK);
|
|
107
|
-
|
|
116
|
+
|
|
108
117
|
this.framework.add(modal);
|
|
109
118
|
modal.show();
|
|
110
119
|
this.pickerModal = modal;
|
|
@@ -115,15 +124,18 @@ class DatePicker extends Component {
|
|
|
115
124
|
* @private
|
|
116
125
|
*/
|
|
117
126
|
openAndroidDialog() {
|
|
118
|
-
// Créer un dialog Material Design avec calendrier
|
|
119
127
|
const dialog = new AndroidDatePickerDialog(this.framework, {
|
|
120
128
|
selectedDate: this.selectedDate,
|
|
121
129
|
onChange: (date) => {
|
|
122
130
|
this.selectedDate = date;
|
|
123
131
|
if (this.onChange) this.onChange(date);
|
|
124
|
-
}
|
|
132
|
+
},
|
|
133
|
+
// Transmettre toutes les options de couleur
|
|
134
|
+
headerBgColor: this.headerBgColor,
|
|
135
|
+
selectedColor: this.selectedColor,
|
|
136
|
+
buttonColor: this.buttonColor
|
|
125
137
|
});
|
|
126
|
-
|
|
138
|
+
|
|
127
139
|
this.framework.add(dialog);
|
|
128
140
|
dialog.show();
|
|
129
141
|
}
|
|
@@ -134,34 +146,39 @@ class DatePicker extends Component {
|
|
|
134
146
|
*/
|
|
135
147
|
draw(ctx) {
|
|
136
148
|
if (this.platform === 'cupertino') {
|
|
137
|
-
//
|
|
149
|
+
// Styles Cupertino
|
|
150
|
+
const bgColor = this.inputBgColor || '#FFFFFF';
|
|
151
|
+
const textColor = this.inputTextColor || '#000000';
|
|
152
|
+
const labelColor = this.labelColor || '#8E8E93';
|
|
153
|
+
const borderColor = this.inputBorderColor || '#C7C7CC';
|
|
154
|
+
const fontSize = this.fontSize || 16;
|
|
155
|
+
|
|
138
156
|
ctx.save();
|
|
139
|
-
|
|
157
|
+
|
|
140
158
|
// Background
|
|
141
|
-
ctx.fillStyle =
|
|
142
|
-
ctx.
|
|
143
|
-
this.roundRect(ctx, this.x, this.y, this.width, this.height, 10);
|
|
159
|
+
ctx.fillStyle = bgColor;
|
|
160
|
+
this.roundRect(ctx, this.x, this.y, this.width, this.height, this.inputRadius);
|
|
144
161
|
ctx.fill();
|
|
145
|
-
|
|
146
|
-
//
|
|
147
|
-
ctx.strokeStyle =
|
|
162
|
+
|
|
163
|
+
// Border
|
|
164
|
+
ctx.strokeStyle = borderColor;
|
|
148
165
|
ctx.lineWidth = 1;
|
|
149
166
|
ctx.stroke();
|
|
150
|
-
|
|
167
|
+
|
|
151
168
|
// Label
|
|
152
|
-
ctx.fillStyle =
|
|
169
|
+
ctx.fillStyle = labelColor;
|
|
153
170
|
ctx.font = '14px -apple-system, sans-serif';
|
|
154
171
|
ctx.textAlign = 'left';
|
|
155
172
|
ctx.textBaseline = 'middle';
|
|
156
173
|
ctx.fillText(this.label, this.x + 15, this.y + this.height / 2 - 10);
|
|
157
|
-
|
|
158
|
-
//
|
|
159
|
-
ctx.fillStyle =
|
|
160
|
-
ctx.font =
|
|
174
|
+
|
|
175
|
+
// Selected date
|
|
176
|
+
ctx.fillStyle = textColor;
|
|
177
|
+
ctx.font = `${fontSize}px -apple-system, sans-serif`;
|
|
161
178
|
ctx.fillText(this.formatDate(this.selectedDate), this.x + 15, this.y + this.height / 2 + 10);
|
|
162
|
-
|
|
179
|
+
|
|
163
180
|
// Chevron
|
|
164
|
-
ctx.strokeStyle =
|
|
181
|
+
ctx.strokeStyle = borderColor;
|
|
165
182
|
ctx.lineWidth = 2;
|
|
166
183
|
ctx.lineCap = 'round';
|
|
167
184
|
ctx.beginPath();
|
|
@@ -169,23 +186,40 @@ class DatePicker extends Component {
|
|
|
169
186
|
ctx.lineTo(this.x + this.width - 20, this.y + this.height / 2);
|
|
170
187
|
ctx.lineTo(this.x + this.width - 15, this.y + this.height / 2 - 5);
|
|
171
188
|
ctx.stroke();
|
|
172
|
-
|
|
189
|
+
|
|
173
190
|
ctx.restore();
|
|
174
191
|
} else {
|
|
175
|
-
//
|
|
192
|
+
// Styles Material
|
|
193
|
+
const bgColor = this.inputBgColor || (this.pressed ? '#F5F5F5' : '#FFFFFF');
|
|
194
|
+
const textColor = this.inputTextColor || '#000000';
|
|
195
|
+
const labelColor = this.labelColor || '#666666';
|
|
196
|
+
const borderColor = this.inputBorderColor || '#E0E0E0';
|
|
197
|
+
const fontSize = this.fontSize || 16;
|
|
198
|
+
const iconColor = labelColor;
|
|
199
|
+
|
|
176
200
|
ctx.save();
|
|
177
|
-
|
|
201
|
+
|
|
178
202
|
// Background
|
|
179
|
-
ctx.fillStyle =
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
203
|
+
ctx.fillStyle = bgColor;
|
|
204
|
+
if (this.inputRadius > 0) {
|
|
205
|
+
this.roundRect(ctx, this.x, this.y, this.width, this.height, this.inputRadius);
|
|
206
|
+
ctx.fill();
|
|
207
|
+
} else {
|
|
208
|
+
ctx.fillRect(this.x, this.y, this.width, this.height);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Border
|
|
212
|
+
ctx.strokeStyle = borderColor;
|
|
184
213
|
ctx.lineWidth = 1;
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
214
|
+
if (this.inputRadius > 0) {
|
|
215
|
+
this.roundRect(ctx, this.x, this.y, this.width, this.height, this.inputRadius);
|
|
216
|
+
ctx.stroke();
|
|
217
|
+
} else {
|
|
218
|
+
ctx.strokeRect(this.x, this.y, this.width, this.height);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// Calendar icon
|
|
222
|
+
ctx.strokeStyle = iconColor;
|
|
189
223
|
ctx.lineWidth = 2;
|
|
190
224
|
ctx.strokeRect(this.x + 15, this.y + 15, 20, 20);
|
|
191
225
|
ctx.beginPath();
|
|
@@ -194,20 +228,20 @@ class DatePicker extends Component {
|
|
|
194
228
|
ctx.moveTo(this.x + 32, this.y + 12);
|
|
195
229
|
ctx.lineTo(this.x + 32, this.y + 18);
|
|
196
230
|
ctx.stroke();
|
|
197
|
-
|
|
231
|
+
|
|
198
232
|
// Label
|
|
199
|
-
ctx.fillStyle =
|
|
233
|
+
ctx.fillStyle = labelColor;
|
|
200
234
|
ctx.font = '12px Roboto, sans-serif';
|
|
201
235
|
ctx.textAlign = 'left';
|
|
202
236
|
ctx.textBaseline = 'top';
|
|
203
237
|
ctx.fillText(this.label, this.x + 45, this.y + 8);
|
|
204
|
-
|
|
238
|
+
|
|
205
239
|
// Date
|
|
206
|
-
ctx.fillStyle =
|
|
207
|
-
ctx.font =
|
|
240
|
+
ctx.fillStyle = textColor;
|
|
241
|
+
ctx.font = `${fontSize}px Roboto, sans-serif`;
|
|
208
242
|
ctx.textBaseline = 'bottom';
|
|
209
243
|
ctx.fillText(this.formatDate(this.selectedDate), this.x + 45, this.y + this.height - 8);
|
|
210
|
-
|
|
244
|
+
|
|
211
245
|
ctx.restore();
|
|
212
246
|
}
|
|
213
247
|
}
|