Advertisement
Guest User

Untitled

a guest
May 6th, 2014
176
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
F# 4.46 KB | None | 0 0
  1. namespace FSharpSandbox.iOS
  2.  
  3. open System
  4. open System.Drawing
  5.  
  6. open MonoTouch.UIKit
  7. open MonoTouch.Foundation
  8. open Microsoft.FSharp.Quotations
  9.  
  10. type EventHandler<'Model> =
  11.    | Sync of ('Model -> 'Model)
  12.    | Async of ('Model -> Async<'Model>)
  13.    | Seq of EventHandler<'Model> seq
  14.  
  15. type IController<'Event, 'Model> =
  16.     abstract member InitModel : unit -> 'Model
  17.    abstract member Handle : ('Event -> EventHandler<'Model>)
  18.  
  19. [<Preserve (AllMembers = true)>]
  20. type TestModel = { FirstName: string; LastName: string; ClickCount: int; ClickEnabled: bool }
  21.  
  22. module TestModelModule =
  23.    let fullName model = model.FirstName + " " + model.LastName
  24.  
  25.    let enableClick model = { model with ClickEnabled = true }
  26.  
  27.    let disableClick model = { model with ClickEnabled = false }
  28.  
  29.    let click model = { model with ClickCount = model.ClickCount + 1 }
  30.  
  31.    let clickAsync model = async {
  32.        do! Async.Sleep 1000
  33.        return click model |> enableClick }
  34.  
  35. type TestModelEvent =
  36.    | Clicked
  37.  
  38. type TestController () =
  39.    interface IController<TestModelEvent, TestModel> with
  40.  
  41.        member this.InitModel () = { FirstName = ""; LastName = ""; ClickCount = 0; ClickEnabled = true }
  42.  
  43.        member this.Handle = function
  44.            //| Clicked -> Sync TestModelModule.click
  45.            | Clicked -> seq {
  46.                yield Sync TestModelModule.disableClick
  47.                yield Async TestModelModule.clickAsync } |> Seq
  48.  
  49. [<Register ("FSharpSandbox_iOSViewController")>]
  50. [<Preserve (AllMembers = true)>]
  51. type FSharpSandbox_iOSViewController () =
  52.    inherit UIViewController ()
  53.  
  54.    let controller = TestController () :> IController<TestModelEvent, TestModel>
  55.    let mutable model = controller.InitModel ()
  56.    let mutable prevModel = model
  57.  
  58.    let click (args: EventArgs) = Clicked
  59.        
  60.    let uiButtonEnabledBinding (button: UIButton) f = fun x -> button.Enabled <- f x
  61.    let uiButtonTitleBinding (button: UIButton) f = fun x -> button.SetTitle (f x)
  62.  
  63.    // Release any cached data, images, etc that aren't in use.
  64.     override this.DidReceiveMemoryWarning () =
  65.         base.DidReceiveMemoryWarning ()
  66.  
  67.     // Perform any additional setup after loading the view, typically from a nib.
  68.     override this.ViewDidLoad () =
  69.         base.ViewDidLoad ()
  70.  
  71.         this.View.BackgroundColor <- UIColor.White
  72.  
  73.         let btn = UIButton.FromType UIButtonType.System
  74.         let txtv = new UITextView (RectangleF (16.f, 16.f, 64.f, 32.f))
  75.  
  76.         btn.Frame <- RectangleF (96.f, 96.f, 196.f, 32.f)
  77.         btn.SetTitle ("Click", UIControlState.Normal)
  78.  
  79.         this.View.AddSubview btn
  80.         this.View.AddSubview txtv
  81.  
  82.         let btnEnabledBinding = uiButtonEnabledBinding btn (fun x -> x.ClickEnabled)
  83.         let btnTitleBinding = uiButtonTitleBinding btn (fun x -> sprintf "Clicked %i times!" x.ClickCount, UIControlState.Normal)
  84.  
  85.         let getPropertyValues model =
  86.             let typ = model.GetType()
  87.             typ.GetProperties()
  88.             |> Array.map (fun x -> (x.Name, x.GetValue model))
  89.  
  90.         let check prevModel model =
  91.             let prevValues = getPropertyValues prevModel
  92.             let values = getPropertyValues model
  93.  
  94.             prevValues
  95.             |> Array.iter2 (fun (name, value1) (_, value2) ->
  96.                 if value1 <> value2 && name = "ClickCount" then btnTitleBinding model
  97.                 if value1 <> value2 && name = "ClickEnabled" then btnEnabledBinding model
  98.             ) values
  99.  
  100.         let rec eventHandler = function
  101.             | Sync eh ->
  102.                 prevModel <- model
  103.                 model <- eh model
  104.                 check prevModel model
  105.             | Async eh ->
  106.                 prevModel <- model
  107.                 Async.StartWithContinuations (
  108.                     computation = eh model,
  109.                     continuation = (fun x ->
  110.                         model <- x
  111.                         check prevModel x),
  112.                     exceptionContinuation = ignore,
  113.                     cancellationContinuation = ignore)
  114.             | Seq xs -> xs |> Seq.iter eventHandler      
  115.                
  116.         let handle x = controller.Handle x |> eventHandler    
  117.  
  118.         btn.TouchUpInside
  119.         |> Observable.map click
  120.         |> Observable.subscribe handle
  121.         |> ignore
  122.  
  123.     // Return true for supported orientations
  124.     override this.ShouldAutorotateToInterfaceOrientation (orientation) =
  125.         orientation <> UIInterfaceOrientation.PortraitUpsideDown
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement