ApplicationContext¶
MessengerContext の派生クラスとして ApplicationContext クラスが定義されています。
このクラスの役割は純粋な MVVM Framework から逸脱しており、MVVM Framework 機能と OpenGLビューの機能とマウスオペレーションに関する機能の3つを統合する役割を担っています。(クラス構成 にあるクラス図を参照して下さい)
ApplicationContext は次の3つで特徴づけられます。
- MessengerContext クラスを継承している
- ISceneGraphContext インターフェイスを実装している
- ICommandContext インターフェイスを実装している
MessengerContext については既に説明済みですので、残りの2つについて説明します。
ISceneGraphContext インターフェイス¶
このインターフェイスは MoNo.Wpf.dll の中に(C#で)次のように定義されています。
namespace MoNo.Wpf
{
public interface ISceneGraphContext
{
/// <summary>
/// このオブジェクトが DataContext としてバインドされている SceneGraph オブジェクトを取得します。
/// </summary>
/// <remarks>
/// このプロパティは MoNo.RAIL フレームワーク側で設定されます。アプリケーション側で値を変更してはいけません。
/// </remarks>
SceneGraph SceneGraph { get; set; }
}
}
コメントにも書かれているように、このインターフェイスをアプリケーション側で使用することはありません。
このインターフェイスは MoNo.RAIL の内部、正確には MoNo.Wpf.GLViewport
コントロールの内部で使用されます。 DataContext
プロパティが ISceneGraphContext
を実装していると、GLViewport
が保持しているシーングラフをそこに設定します。
つまり、ApplicationContext(の派生クラス)が GLViewport の DataContext にバインドされるように設定すれば、GLViewport に設定されたシーングラフが ApplicationContext にも設定される、ということです。
ICommandContext インターフェイス¶
このインターフェイスは MoNo.Framework.FSharp.dll の中に次のように定義されています。
type ICommandContext =
inherit IContRunner
abstract OperationDriver : Ctrl.OperationDriver
abstract ViewContext : Graphics.IViewContext
- IContRunner を継承していますので、継続モナドを実行する機能を持ちます。
- OperationDriver を保持しており、マウスオペレーションに関する機能を持ちます。
- ViewContext へのリンクを持っており、OpenGL ビューとつながっています。
このインターフェイスには次のような拡張メソッドが多数定義されています。 ICommandContext の重要性は上記の定義そのものよりも下記の拡張メソッドにあります。
[<AutoOpen>]
module MoNo.Ctrl.CommandContextExtension
open System.Windows.Forms
open MoNo
type ICommandContext with
member this.ByOperation (operation, getResult) = ...
member this.ByOperation operation = ...
member this.ByMouseOperation operation = ...
member this.GetMouseOperation (filter, button, ?action) =
let operation = MouseOperation (this.ViewContext, filter, button)
action |> Option.iter (fun action -> action operation)
this.ByMouseOperation operation
member this.GetMouseClick (button, ?action) = this.GetMouseOperation (MouseOperations.MouseClick, button, defaultArg action ignore)
member this.GetMouseDown (button, ?action) = this.GetMouseOperation (MouseOperations.MouseDown, button, defaultArg action ignore)
member this.GetMouseUp (button, ?action) = this.GetMouseOperation (MouseOperations.MouseUp, button, defaultArg action ignore)
member this.GetMouseMove (button, ?action) = this.GetMouseOperation (MouseOperations.MouseMove, button, defaultArg action ignore)
member this.GetMouseWheel ?action = this.GetMouseOperation (MouseOperations.MouseWheel, MouseButtons.None, defaultArg action ignore)
member this.GetLButtonClick ?action = this.GetMouseClick (MouseButtons.Left, defaultArg action ignore)
member this.GetRButtonClick ?action = this.GetMouseClick (MouseButtons.Right, defaultArg action ignore)
member this.GetMButtonClick ?action = this.GetMouseClick (MouseButtons.Middle, defaultArg action ignore)
member this.GetLButtonDown ?action = this.GetMouseDown (MouseButtons.Left, defaultArg action ignore)
member this.GetRButtonDown ?action = this.GetMouseDown (MouseButtons.Right, defaultArg action ignore)
member this.GetMButtonDown ?action = this.GetMouseDown (MouseButtons.Middle, defaultArg action ignore)
member this.GetLButtonUp ?action = this.GetMouseUp (MouseButtons.Left, defaultArg action ignore)
member this.GetRButtonUp ?action = this.GetMouseUp (MouseButtons.Right, defaultArg action ignore)
member this.GetMButtonUp ?action = this.GetMouseUp (MouseButtons.Middle, defaultArg action ignore)
これらの拡張メソッドはみな、Cont<'a>
を返します。
つまり cont { ... }
というコンピューテーション式の中で使えるということです。
特にマウスオペレーションに関するメソッドはすべて Cont<(IView * MouseEventArgs)>
を返します。
従って次のようなコンピュテーション式でマウスクリックイベントを取得することができます。
cont {
let! view, e = con.GetLButtonClick()
...
}