anchor.diff:    /// Constructor
     ShaderEditor(int _w, int _h, String l) : super(_w, _h, l) {
       color = fl.WHITE;
  +    final width = _w;
       final height = _h;
       final half = (_w / 2).round();
       final pad = 10;
   
  +    // Create canvas.
       canvas = new Gl2DCanvas(0, 0, half, height);
   
  -    editor = new fl.TextEditor(half + pad, pad, w - half - pad, height - pad);
  +    // Create button.
  +    button = new fl.Button(half, 0, width - half, 40, 'Recompile!');
  +    button.box = fl.FLAT_BOX;
  +    button.labelsize = 20;
  +    button.color = fl.DARK2;
  +    button.callback = (w, _) {
  +      update();
  +    };
  +
  +    // Create editor.
  +    editor = new fl.TextEditor(half + pad, button.h + pad, width - half - pad,
  +        height - button.h - pad);
       editor.box = fl.FLAT_BOX;
       editor.cursorStyle = fl.TextDisplay.SIMPLE_CURSOR;
       editor.cursorColor = fl.rgbColor(64);
  
positive.code:   /// Fragment shader editor
    fl.TextEditor editor;
  
    /// Text buffer for the editor
    fl.TextBuffer buffer;
  
  
negative.code: 
    void draw() {
      if (!valid()) {
        final width = w;
        final height = h;
  
        // Set viewport.
        glViewport(0, 0, width, height);
  
        // Update vertices.
        updateVertexData([
          // Top-left triangle
          -width, -height, -width, height, width, height,
  
          // Bottom-right triangle
          width, -height, -width, -height, width, height
        ]);
  
        // Compute new matrix.
        double far = 10.0;
        double near = 0.1;
        matrix[0] = 1.0 / width;
        matrix[5] = 1.0 / height;
        matrix[10] = -2.0 / (far - near);
        matrix[11] = (far + near) / (far - near);
      }
  