【お知らせ】プログラミング記事の投稿はQiitaに移行しました。

対話的操作

n7shi2009-06-09


F# InteractiveからWPFの図形を操作してみました。LOGO気分でWPFの操作を覚えられるかもしれません。

WPFを読み込みます。

#r "PresentationCore.dll";;
#r "PresentationFramework.dll";;
#r "WindowsBase.dll";;
open System.Windows;;
open System.Windows.Controls;;
open System.Windows.Shapes;;
open System.Windows.Media;;

ウィンドウを開きます。

let w = new Window(Title = "Test", Width = 256.0, Height = 256.0);;
w.Show();;

図形を置くためのCanvasを用意します。

let canvas = new Canvas();;
w.Content <- canvas;;

四角形を置きます。

let r = new Rectangle(Width = 40.0, Height = 40.0);;
Canvas.SetLeft(r, 20.0);;
Canvas.SetTop(r, 60.0);;
r.Stroke <- new SolidColorBrush(Colors.Black);;
r.Fill <- new SolidColorBrush(Colors.Yellow);;
canvas.Children.Add(r);;

文字を置きます。

let tb = new TextBlock(Text = "abcdefg", FontSize = 24.0);;
canvas.Children.Add(tb);;

移動がCanvas経由で面倒なため関数にします。

let move = fun sh x y ->
    Canvas.SetLeft(sh, x)
    Canvas.SetTop(sh, y)
;;
move tb 20.0 30.0;;

マウスで移動できるようにします。

let mutable elem : UIElement = null;;
let mutable click = new Point();;
let mutable orig = new Point();;
let down = fun (el : UIElement) (e : Input.MouseButtonEventArgs) ->
    elem <- el
    orig <- new Point(Canvas.GetLeft(el), Canvas.GetTop(el))
    click <- e.GetPosition(canvas)
    canvas.CaptureMouse() |> ignore
;;
r.MouseDown.Add(down r);;
tb.MouseDown.Add(down tb);;
canvas.MouseMove.Add(fun e ->
    if elem <> null then
        let p = e.GetPosition(canvas)
        move elem (orig.X + p.X - click.X) (orig.Y + p.Y - click.Y)
);;
canvas.MouseUp.Add(fun _ ->
    elem <- null
    canvas.ReleaseMouseCapture()
);;

対話的に進めながら、ちゃんとイベントループが回っているのが良いです。副作用ばかりですが、MouseDownに部分適用した関数を渡している部分は関数型っぽいでしょうか。