オープンソースの ActionScript 向け IDE。開発環境は .NET Framework で、SharpDevelop を使って開発することができます。
- 本拠地 - http://www.flashdevelop.org/community/
- svn リポジトリ - http://svn1.cvsdude.com/osflash/flashdevelop/
複数ペインを持ったエディタを作る際の参考にするため、ソースコードを解読してます。
VS で言うところのソリューションエクスプローラに当たるのが ProjectManager。
ProjectManager でファイルをダブルクリックし、編集画面が開かれる過程。
ProjectManager.Controls.TreeView.ProjectTreeView の DefWndProc() がウィンドウメッセージを処理します。ここで、ダブルクリックされると DoubleClick イベントが呼び出されます。DoubleClick の挙動は、ProjectManager.PluginMain.TreeDoubleClick() で定義されています。ここから色々たらいまわしにされて、ProjectManager.PluginMain.OpenFile() にたどり着きます。ダブルクリックされたファイルの条件が合えば、MainForm.OpenEditableDocument() が呼び出され、ファイルが開かれます。MainForm は PluginMain のスタティックプロパティで、IMainForm 型です。実際に参照する値は、PluginBase.MainForm で、この値は PluginBase の Initialize() の引数として渡されます。PluginBase は非常に小さなクラスで、全てのメンバ(IMainForm, IProject, Initialize() )がスタティックです。
IMainForm が何かと言うと、文字通りメインフォームのインタフェースなのですが、興味深いことに、あくまで実装を伴わないインタフェースであり、その名前空間は PluginCore です。FlashDevelop.MainForm は、この IMainForm を実装します。つまり PluginCore ありきで FlashDevelop ができているわけです。
ここらで、なぜこれを調べていたかの理由について書きます。理想論で言えば、下位に位置するもの(今回は ProjectTreeView)は、上位に位置するもの(IMainForm)に依存しないべきです。ProjectTreeView が IMainForm に依存した実装になってしまうことで、そのクラスは IMainForm がなくなると使えなくなります。例えば、他のプロジェクトなどで ProjectTreeView を使うためには修正が要るということです。ProjectTreeView が上位のオブジェクトに何かを伝えたければ、コールバックなどの仕組みを使うのが一般的です。しかし、FlashDevelop のケースではそうではありませんでした。インタフェースという間接的な形であれ、上位のクラスについての情報を下位のクラスが持つという構造になっていました。これが現実なのかなぁというのが正直な感想です。実際、このようにしてしまったほうが生産性も上がるし、実行効率もいいと思います。
現実的なケースとして、ブラウザを考えます。ブラウザ全体の子要素として、メインとなるブラウザ部分(ビューと呼びます)や、メニューバー、ツールバー、アドレスバーなどがあります。ビューでリンクをクリックすると、アドレスバーに表示されるアドレスは変わり、ツールバーの「戻る」ボタンが押せるようになります。この処理はどのように実装されるべきでしょうか。先ほどの理想論では、ブラウザがビューに設定したコールバック関数が呼び出され、その中でアドレスバーのアドレスの変更などが行われます。
// 初期化時
view.AddEventListener(PAGE_CHANGED, OnPageChanged);
void OnPageChanged(const string& url) {
addressBar.SetURL(url);
toolbar.GetButton(GO_BACK).SetEnable(true);
}
といった感じで。方や妥協案では、ビュー側でこの処理を行います。どっちがいいか、設計思想しだいですね。