VSLab update and measure units sample

by cisterni 30. October 2008 23:29

Ok, it is some time since the last update of VSLab, but today I decided to update the installer and commit several changes I did to improve stability and support for events. I finally managed to go through the whole Viewlet definition and fully document supported and unsupported events inherited from UserControl. I also managed to fix several bugs in this respect.

 This is term period and in the Graphical interfaces courses I'm teaching using F# (interactively). Today to discuss animations I've implemented a simple application with balls moving around and quickly converted into a viewlet! The nice thing about this application is the use of unit measures in a graphical application to estimate velocity (<px/s>). Once you run the viewlet you can create a new ball by simply clicking in the client area and drag the initial velocity vector. Here is a screenshot:

 

and here it is the code:

#light

open System.Drawing

open System.Windows.Forms [<Measure>] type px

[<Measure>] type s

open VSLab

let ballsz = new SizeF(25.0f, 25.0f)

type Ball(ipx: float<px>, ipy:float<px>, ivx:float<px/s>, ivy:float<px/s>) =

  let mutable vx = ivx

  let mutable vy = ivy

  let mutable px = ipx

  let mutable py = ipy

  let sz = ballsz

  member x.Update(interval:float<s>) =

    px <- px + vx * interval

    py <- py + vy * interval

  member x.Size

    with get() = sz

  member x.Position     with get() = (px, py)

 

  member x.CenterPosition

    with get() = ((px + 1.0<px> * (float (sz.Width / 2.0f))), (py + 1.0<px> * (float (sz.Height / 2.0f))))

 

  member x.Velocity

    with get() = (vx, vy)

    and set (v:float<px/s>*float<px/s>) =

      vx <- fst v

      vy <- snd v

type SampleViewlet() as x =

  inherit Viewlet()

  let balls = new ResizeArray<Ball>()

  let framerate = 0.02<s>

  let t = new Timer()

  let mutable newball:Option<Ball> = None

  let mutable mousepos = (0, 0)

 

  do

    t.Interval <- int(framerate * 1000.0)

    t.Tick.Add(fun _ ->

    balls |> ResizeArray.iter (fun b ->

      b.Update(framerate)

      let px, py = b.Position

      let pxi = (int px)

      let pyi = (int py)      let mutable vx, vy = b.Velocity

 

      if (pxi < 0 || pxi > x.ClientSize.Width - (int b.Size.Width)) then

        vx <- vx * -1.0

      if (pyi < 0 || pyi > x.ClientSize.Height - (int b.Size.Height)) then

        vy <- vy * -1.0

 

      b.Velocity <- (vx, vy)

      )

 

      x.Invalidate()

    )

    t.Start()

    x.Text <- "Animate!"

  override x.OnMouseDown e =

    mousepos <- (e.X, e.Y)

    let px = 1.0<px>*((float e.X) - ((float ballsz.Width) / 2.0))

    let py = 1.0<px>*((float e.Y) - ((float ballsz.Height) / 2.0))

    let b = new Ball(px, py, 0.0<px/s>, 0.0<px/s>)

    balls.Add(b)

    newball <- Some(b)

  override x.OnMouseMove e =

    if newball.IsSome then

      mousepos <- (e.X, e.Y)

  override x.OnMouseUp e =

    if newball.IsSome then

      let px, py = newball.Value.Position

      let vx = (float (fst mousepos - (int px)))*1.0<px/s>

      let vy = (float (snd mousepos - (int py)))*1.0<px/s>

      newball.Value.Velocity <- (vx, vy)

      newball <- None

  override x.OnPaint e =    let g = e.Graphics

    g.SmoothingMode <- Drawing2D.SmoothingMode.AntiAlias

    balls |> ResizeArray.iter (fun b ->

    let px, py = b.Position

    g.FillEllipse(Brushes.Blue, (single px), (single py), ballsz.Width, ballsz.Height))

    if newball.IsSome then

      let px, py = newball.Value.CenterPosition

      let ipx = (int px)

      let ipy = (int py)

      let mx, my = mousepos

      use p = new Pen(Color.Black)

      p.EndCap <- Drawing2D.LineCap.ArrowAnchor

      g.DrawLine(p, ipx, ipy, mx, my)

 

  override x.OnViewletVisibilityChange e =

  t.Enabled <- e

let v = new SampleViewlet()

v.Show()

v.Close()

Currently rated 5.0 by 2 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

General | Viewlets

Powered by BlogEngine.NET 1.4.0.0
Theme by Mads Kristensen

VSLab blog

VSLab is a Visual Studio extension designed to support Visual Studio interaction from F# interactive. It is a Microsoft product developed at University of Pisa, by a team lead by Antonio Cisternino.

Resources

Recent comments

Comment RSS

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in  anyway.

© Copyright 2008