S.F. Page

Programming,Music,etc...

ポケミク・シーケンサーを作る(5)

相変わらずのペースだが、ぼちぼちと実装を進めている。マウスでノート挿入する機能を実装してみているところである。何しろあまりUIを真剣に作りこんだことがないのでいろいろ躓きながら手戻りしながらである。少しずつしか進歩しない。

Undo/Redoもできるようにするのは結構面倒である。過去に作りかけたアプリたちによってUndo/Redoの基本的な実装は心得ている。とりあえず作ったUndo/Redo管理オブジェクトは以下である。

function UndoManager()
{
  this.buffer = [];
  this.index = -1;
}

UndoManager.prototype =
{
  clear: function ()
  {
    this.buffer.length = 0;
    this.index = -1;
    $(this).trigger('cleared');
  },
  exec: function (command)
  {
    command.exec();
    if (this.index > 0 && this.index != (this.buffer.length - 1))
    {
      this.buffer.length = this.index + 1;
    }
    this.buffer.push(command);
    ++this.index;
    $(this).trigger('executed');
  },
  redo: function ()
  {
    if (this.index < this.buffer.length)
    {
      var command = this.buffer[this.index];
      command.redo();
      ++this.index;
      $(this).trigger('redid');
      if (this.index >= this.buffer.length)
      {
        --this.index;
        $(this).trigger('redoEmpty');
      }

    } 
  },
  undo: function ()
  {
    if (this.buffer.length > 0 && this.index >= 0)
    {
      var command = this.buffer[this.index];
      command.undo();
      --this.index;
      $(this).trigger('undid');
      if (this.index < 0)
      {
        this.index = 0;
        $(this).trigger('undoEmpty');
      } 
    }
  }
}

var undoManager = new UndoManager();

Undoさせたい機能はコマンドパターンで実装する。exec(),undo(),redo()メソッドを持つオブジェクトを定義してそれをこのUndoManagerに渡して実行させる。イベントを発生させているのはそれによりUndo/RedoのUIを変化させるためである。ノート挿入機能で一応動くことが確認できたのであとはコマンドを実装していくだけである。