Monday, November 15, 2010

More F# Findings

I spend quite a bit of time reading other F# related content mainly from experts of the field.
It's definitely a great way to learn, but sometimes I get really annoyed when people put out some really great F# code only to visualize it with a sad presentation framework like Windows Forms. People... it's 2010 soon to be 2011! We need to start educating everyone on better presentation. I've decided to side track the MATLAB series and just start posting some random findings of mine through playing around in scripts with WPF and Silverlight. The hope is that someone will see something and get something out of it. If not, then at least I can contribute to more F# with WPF and Silverlight content out in the inner webs.

This first discovery is Silverlight related. I'm working on a side project and came across a need to draw a path. So I turned to the following article and decided to re-think and re-do it in F#.

Special thanks to Tomas Petricek for the Utils module logic to lookup Xaml elements in F#.

( Utils.fs )

module Utils
open System.Windows.Controls

let (?) (this : Control) (prop : string) : 'T =
  this.FindName(prop) :?> 'T

( Main.fs )
namespace DrawingAPath

open Utils
open System
open System.Windows
open System.Windows.Controls
open System.Windows.Ink
open System.Windows.Input
open System.Windows.Media

type MainView() as this = 
    inherit UserControl()
    let uri = new System.Uri("/DrawingAPath;component/MainView.xaml", UriKind.Relative)
    do Application.LoadComponent(this, uri)

    let mutable s = new Stroke()
    let inkP: InkPresenter = this?inkP
    let pv: ListBox = this?PointsViewer

    let AddPoints (pX: float, pY: float, device: StylusDevice) = 
    let DefineInkStroke (ev: MouseButtonEventArgs) = 
        inkP.CaptureMouse() |> ignore
        s = new Stroke() |> ignore
        s.DrawingAttributes.Color = Colors.White |> ignore

    let DisplayPointsForPath (ev: MouseButtonEventArgs) =
        let points =
                |> sp -> String.Format("X: {0} Y:{0}",sp.X,sp.Y))
        pv.ItemsSource <- points
        s <- null

      inkP.MouseLeftButtonDown.Add(fun ev -> DefineInkStroke ev)
      inkP.MouseLeftButtonUp.Add(fun ev -> DisplayPointsForPath ev )            
          |> me -> 
                let pos = me.GetPosition(this?LayoutRoot)
                pos.X, pos.Y, me.StylusDevice)

          |> Event.filter( fun (pX , pY, sd) -> 
                                pX > 0.0 && pX < 300.0 && pY > 0.0 && pY < 195.0)
          |> Event.add(AddPoints)

No comments:

Post a Comment