アイコンエディタにアンドゥ機能を追加します。なんらかの編集が加えられたらパネル上の色情報をBitmapにして保存しておきます。アンドゥとリドゥボタンが押されたら保存しておいたBitmap情報から復元するという方法でやってみることにします。

まずはアンドゥバッファとこれを管理するためのクラスを示します。

Undobufクラスには編集前の情報と編集後の情報を保存しておきます。

Undobufを管理するUndoBufsクラスにはUndo、Redoのためのバッファ、実際にUndo、Redoが要求されたときの処理、そもそもUndoとRedoが可能かどうかを調べるメソッドを用意しています。

Undo、Redoが要求されたときはイベントを発生させて、イベントハンドラのなかで実際の処理をおこないます。

あとは簡単・・・と思ったら結構落とし穴がありました。

マウスがクリックされたら編集前のデータを保存しているのですが、範囲選択がされているときにこれをおこなうと範囲選択用の色まで保存されてしまうので、新しくつくったClearSelectionForSaveUndobufメソッドでいったん解除しています。

そのあとSaveOldBitmapで編集前のデータを保存しています。保存が終わったらRestoreSelectionAfterSaveUndobufで範囲選択の状態に戻しています。

SaveOldBitmapメソッドとClearSelectionForSaveUndobufメソッド、RestoreSelectionAfterSaveUndobufメソッドは以下のような内容になっています。

ドラッグがおわったらデータが変更されているか調べて、変更されていた場合はUndobufを追加しています。

InsertUndobufメソッドは以下のようになっています。

データが変更されているかどうかはafterBitmapとoldBitmapを比較すればいいのですが、

ではダメです。afterBitmapとoldBitmapのデータが同じでもオブジェクト的には違うからです。そこで以下のようにBitmap.GetPixelメソッドで調べています。

それからUndobufを追加するのはパネルがクリックされたときだけではありません。[文字を入力する]ボタンがクリックされたときも必要です。

また新しいファイルが読み込まれたときはアンドゥバッファはクリアしなければなりません。

あとはUndo、Redoボタンがおされたときの処理を書きます。

これでUndoBufsクラスのなかでイベントが発生するので、そのときの処理を書きます。

これでUndo、Redoの処理もできるようになりました。