13

Editor

Objective
  • Responder
    • Editor

Cliquez dans le champ de saisie de la couleur. Choisissez une couleur. Appuyez sur Entrée ou cliquez en dehors du sélecteur pour valider la couleur choisie. La plaque change de couleur.

Le bouton Défaire est activé.

Choisissez une autre couleur. Entrez directement une valeur, e.g. #CB6.

Cliquez sur le bouton Défaire.

La couleur précédente est affichée.

Le bouton Refaire est activé.

Cliquez sur le bouton Refaire pour revenir à la dernière couleur sélectionnée.

Rechargez la page. La couleur de la plaque est sauvegardée.

Dans la console du navigateur, verrouillez toute l'interface en bloquant l'éditeur :

editor.disable()

Déverrouillez l'interface :

editor.enable()

Affichez la valeur du modèle :

model.get()

Changez la valeur du modèle :

model.set({ color: "#E02" })

L'interface se met à jour. Vérifiez que la valeur du modèle est normalisée :

model.get()
Object { color: "#ee0022" }

Désactivez la synchronisation automatique :

model.disableSync()

Sélectionnez une autre couleur. Rechargez la page. La modification n'est pas enregistrée.

  1. function Editor(model, view, inspectors, panel = false) {
  2.     Responder.call(this);
  3.  
  4.     model.addListener(this);
  5.  
  6.     this._model = model;
  7.  
  8.     if (view)
  9.         view.addListener(this);
  10.  
  11.     this._view = view;
  12.  
  13.     for (let p in inspectors)
  14.         inspectors[p].addNextResponder(this);
  15.  
  16.     this._inspectors = inspectors;
  17.  
  18.     if (panel) {
  19.         panel.addNextResponder(this);
  20.         model.enableUndo();
  21.     }
  22.  
  23.     this._panel = panel;
  24. }
  25.  
  26. Editor.prototype = Object.create(Responder.prototype);
  27.  
  28. Object.defineProperty(Editor.prototype, 'constructor', { value: Editor, enumerable: false, writable: true });
  29.  
  30. Editor.prototype.modelSet = function(sender) {
  31.     let options = sender.get();
  32.  
  33.     if (this._view)
  34.         this._view.set(options);
  35.  
  36.     let inspectors = this._inspectors;
  37.  
  38.     for (let p in inspectors)
  39.         inspectors[p].set(options[p]);
  40. };
  41.  
  42. Editor.prototype.modelValueChanged = function(sender, prop, val) {
  43.     if (this._view)
  44.         this._view.setValue(prop, val);
  45.  
  46.     this._inspectors[prop].set(val);
  47. };
  48.  
  49. Editor.prototype.modelUndoChanged = function(sender) {
  50.     if (this._panel) {
  51.         if (this._model.canUndo())
  52.             this._panel.enableUndo();
  53.         else
  54.             this._panel.disableUndo();
  55.  
  56.         if (this._model.canRedo())
  57.             this._panel.enableRedo();
  58.         else
  59.             this._panel.disableRedo();
  60.     }
  61. };
  62.  
  63. Editor.prototype.undo = function(sender) {
  64.     this._model.undo();
  65.  
  66.     return true;
  67. };
  68.  
  69. Editor.prototype.redo = function(sender) {
  70.     this._model.redo();
  71.  
  72.     return true;
  73. };
  74.  
  75. Editor.prototype.inspectorValueChanged = function(sender) {
  76.     let inspectors = this._inspectors;
  77.  
  78.     for (let p in inspectors) {
  79.         if (inspectors[p] === sender) {
  80.             this._model.setValue(p, sender.get());
  81.             break;
  82.         }
  83.     }
  84.  
  85.     return true;
  86. };
  87.  
  88. Editor.prototype.disable = function() {
  89.     let inspectors = this._inspectors;
  90.  
  91.     for (let p in inspectors)
  92.         inspectors[p].disable();
  93.  
  94.     if (this._panel)
  95.         this._panel.disable();
  96.  
  97.     return this;
  98. };
  99.  
  100. Editor.prototype.enable = function() {
  101.     let inspectors = this._inspectors;
  102.  
  103.     for (let p in inspectors)
  104.         inspectors[p].enable();
  105.  
  106.     if (this._panel) {
  107.         if (this._model.canUndo())
  108.             this._panel.enableUndo();
  109.         if (this._model.canRedo())
  110.             this._panel.enableRedo();
  111.     }
  112.  
  113.     return this;
  114. };
Test
  1. <?php $text='Objective.js'; ?>
  2. <?php $font='Slackey'; ?>
  3. <?php $fontSize=24; ?>
  1. <?php $color='#cccccc'; ?>
  1. <?php head('font', $font); ?>
  1. <?php head('javascript', 'jquery.minicolors'); ?>
  2. <?php head('stylesheet', 'jquery.minicolors', 'screen'); ?>
  1. <?php $id=uniqid('id'); ?>
  1. .test_display {
  2.     width: 240px;
  3.     height: 135px;
  4.     display: flex;
  5.     margin-bottom: 10px;
  6.     border-radius: 3px;
  7. }
  1. <div id="<?php echo $id; ?>" class="noprint">
  2. <div class="test_display">
  3. <canvas width="240" height="135"></canvas>
  4. </div>
  5. <div class="ojs">
  6. <div>
  7. <div class="control_panel">
  8. <button type="submit" class="ojs_button narrow" disabled><i class="fas fa-undo"></i></button>
  9. <button type="submit" class="ojs_button narrow" disabled><i class="fas fa-redo"></i></button>
  10. </div>
  11. <span class="color_panel"></span>
  12. </div>
  13. </div>
  14. </div>
  1. <?php head('javascript', '/objectivejs/Objective.js'); ?>
  2. <?php head('javascript', '/objectivejs/Validator.js'); ?>
  3. <?php head('javascript', '/objectivejs/Responder.js'); ?>
  4. <?php head('javascript', '/objectivejs/View.js'); ?>
  5. <?php head('javascript', '/objectivejs/Inspector.js'); ?>
  6. <?php head('javascript', '/objectivejs/ColorInspector.js'); ?>
  7. <?php head('javascript', '/objectivejs/Model.js'); ?>
  8. <?php head('javascript', '/objectivejs/Undo.js'); ?>
  9. <?php head('javascript', '/objectivejs/Panel.js'); ?>
  10. <?php head('javascript', '/objectivejs/UndoPanel.js'); ?>
  11. <?php head('javascript', '/objectivejs/Editor.js'); ?>
  12. <?php head('javascript', '/objectivejs/ModelStorageDelegate.js'); ?>
  1. function ColorModel(name) {
  2.     Model.call(this, name);
  3.  
  4.     this._value = {
  5.         color:  ColorModel.defaultColor
  6.     };
  7. }
  8.  
  9. ColorModel.prototype = Object.create(Model.prototype);
  10.  
  11. Object.defineProperty(ColorModel.prototype, 'constructor', { value: ColorModel, enumerable: false, writable: true });
  1. ColorModel.defaultColor = '<?php echo $color; ?>';
  1. ColorModel.prototype.validateValue = function(prop, val) {
  2.     if (prop == 'color')
  3.         return Validator.validateColor(val);
  4.  
  5.     return false;
  6. }
  7.  
  8. ColorModel.prototype.normalizeValue = function(prop, val) {
  9.     if (prop == 'color')
  10.         val = Validator.normalizeColor(val);
  11.  
  12.     return val;
  13. }
  1. function ColorView() {
  2.     View.call(this);
  3.  
  4.     this._color = ColorModel.defaultColor;
  5.  
  6.     this._canvas = null;
  7. }
  8.  
  9. ColorView.prototype = Object.create(View.prototype);
  10.  
  11. Object.defineProperty(ColorView.prototype, 'constructor', { value: ColorView, enumerable: false, writable: true });
  1. ColorView.prototype.set = function(options) {
  2.     const {color} = options;
  3.  
  4.     this.setColor(color);
  5.  
  6.     return this;
  7. }
  1. ColorView.prototype.setValue = function(prop, val) {
  2.     if (prop == 'color')
  3.         this.setColor(val);
  4.  
  5.     return this;
  6. }
  1. ColorView.prototype.setColor = function(color) {
  2.     if (this._color != color) {
  3.         this._color = color;
  4.  
  5.         if (this._widget)
  6.             this._widget.style.backgroundColor = color;
  7.     }
  8.  
  9.     return this;
  10. }
  1. ColorView.prototype.resetWidget = function() {
  2.     if (this._widget)
  3.         this._widget.style.backgroundColor = this._color;
  4.  
  5.     return this;
  6. }
  1. ColorView.prototype.setWidget = function(w) {
  2.     const canvas = w.querySelector('canvas');
  3.  
  4.     if (canvas === null)
  5.         throw new TypeError();
  6.  
  7.     this._canvas = canvas;
  8.  
  9.     View.prototype.setWidget.call(this, w);
  10.  
  11.     return this;
  12. }
  1. ColorView.prototype.drawWidget = function(font, fontSize, text) {
  2.     if (this._canvas) {
  3.         let canvas = this._canvas;
  4.         let ctx = canvas.getContext('2d');
  5.  
  6.         ctx.font = `bold ${fontSize}px "${font}"`;
  7.  
  8.         ctx.fillStyle = 'white';
  9.         ctx.textAlign = 'center';
  10.         ctx.textBaseline = 'middle';
  11.         ctx.fillText('', canvas.width / 2, canvas.height / 2);
  12.         ctx.beginPath();
  13.         ctx.arc(20, 20, 10, 0, 2 * Math.PI);
  14.         ctx.fill();
  15.         ctx.beginPath();
  16.         ctx.arc(canvas.width-20, 20, 10, 0, 2 * Math.PI);
  17.         ctx.fill();
  18.         ctx.beginPath();
  19.         ctx.arc(canvas.width-20, canvas.height-20, 10, 0, 2 * Math.PI);
  20.         ctx.fill();
  21.         ctx.beginPath();
  22.         ctx.arc(20, canvas.height-20, 10, 0, 2 * Math.PI);
  23.         ctx.fill();
  24.  
  25.         document.fonts.ready.then(() => {
  26.             ctx.fillText(text, canvas.width / 2, canvas.height / 2);
  27.         });
  28.     }
  29.  
  30.     return this;
  31. }
  1. const model = new ColorModel('color');
  2.  
  3. const container = document.querySelector('#<?php echo $id; ?>');
  4.  
  5. const panel = new UndoPanel();
  6.  
  7. panel.setManagedWidget(container.querySelector('.control_panel')).resetWidget();
  8.  
  9. const view = new ColorView();
  10.  
  11. view.setWidget(container.querySelector('.test_display')).resetWidget();
  12.  
  13. view.drawWidget('<?php echo $font; ?>', <?php echo $fontSize; ?>, '<?php echo $text; ?>');
  14.  
  15. const colorInspector = new ColorInspector(model.getValue('color'));
  16.  
  17. colorInspector.createManagedWidget(container.querySelector('.color_panel'));
  18.  
  19. const inspectors = {
  20.     color:  colorInspector
  21. }
  22.  
  23. const editor = new Editor(model, view, inspectors, panel);
  24.  
  25. model.setDelegate(new ModelStorageDelegate());
  26. model.readIn();
  27. model.enableSync();
VOIR AUSSI

Model, Responder, ColorInspector, ClipEditor, Architecture d'un éditeur

Commentaires

Votre commentaire :
[p] [b] [i] [u] [s] [quote] [pre] [br] [code] [url] [email] strip aide 2000

Entrez un maximum de 2000 caractères.
Améliorez la présentation de votre texte avec les balises de formatage suivantes :
[p]paragraphe[/p], [b]gras[/b], [i]italique[/i], [u]souligné[/u], [s]barré[/s], [quote]citation[/quote], [pre]tel quel[/pre], [br]à la ligne,
[url]http://www.izend.org[/url], [url=http://www.izend.org]site[/url], [email]izend@izend.org[/email], [email=izend@izend.org]izend[/email],
[code]commande[/code], [code=langage]code source en c, java, php, html, javascript, xml, css, sql, bash, dos, make, etc.[/code].