Advertisement
ptrelford

GraphicsWindow with Xwt

Jul 7th, 2015
506
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
F# 21.82 KB | None | 0 0
  1. open Xwt
  2. open Xwt.Drawing
  3. open System
  4. open System.Net
  5. open System.Threading
  6.  
  7. type Pen = Pen of color:Color * width:float
  8. type Font = Font of size:float * isBold:bool
  9. type Line = Line of x1:float * y1:float * x2:float * y2:float
  10. type Rect = Rect of width:float * height:float
  11. type Triangle = Triangle of x1:float * y1:float * x2:float * y2:float * x3:float * y3:float
  12. type Ellipse = Ellipse of width:float * height:float
  13.  
  14. type Shape =
  15.    | LineShape of line:Line * pen:Pen  
  16.    | RectShape of rect:Rect * pen:Pen * fill:Color
  17.    | TriangleShape of triangle:Triangle * pen:Pen * fill:Color
  18.    | EllipseShape of Ellipse * pen:Pen * fill:Color
  19.    | ImageShape of image:Image
  20.    | TextShape of textRef:string ref * font:Font * color:Color
  21.  
  22. type Drawing =
  23.    | DrawLine of line:Line * pen:Pen
  24.    | DrawRect of rect:Rect * pen:Pen
  25.    | DrawTriangle of triangle:Triangle * pen:Pen
  26.    | DrawEllipse of ellipse:Ellipse * pen:Pen
  27.    | DrawImage of image:Image ref * x:float * y:float
  28.    | DrawText of x:float * y:float * text:string * font:Font * color:Color
  29.    | DrawBoundText of x:float * y:float * width:float * text:string * font:Font * color:Color
  30.    | FillRect of rectangle:Rect * fill:Color
  31.    | FillTriangle of triangle:Triangle * fill:Color
  32.    | FillEllipse of ellipse:Ellipse * fill:Color
  33.    | DrawShape of name:string * shape:Shape
  34.  
  35. let drawEllipse (ctx:Context) (x,y,w,h) =
  36.    let kappa = 0.5522848
  37.    let ox = (w/2.0) * kappa
  38.    let oy = (h/2.0) * kappa
  39.    let xe = x + w
  40.    let ye = y + h
  41.    let xm = x + w / 2.0
  42.    let ym = y + h / 2.0
  43.    ctx.MoveTo(x,ym)
  44.    ctx.CurveTo(x, ym - oy, xm - ox, y, xm, y)
  45.    ctx.CurveTo(xm + ox, y, xe, ym - oy, xe, ym)
  46.    ctx.CurveTo(xe, ym + oy, xm + ox, ye, xm, ye)
  47.    ctx.CurveTo(xm - ox, ye, x, ym + oy, x, ym)
  48.  
  49. let drawTriangle (ctx:Context) (Triangle(x1,y1,x2,y2,x3,y3)) =
  50.    ctx.MoveTo(x1,y1)
  51.    ctx.LineTo(x2,y2)
  52.    ctx.LineTo(x3,y3)
  53.    ctx.LineTo(x1,y1)
  54.  
  55. let penStroke (ctx:Context) (Pen(color,width)) =
  56.    ctx.SetColor(color)
  57.    ctx.SetLineWidth(width)
  58.    ctx.Stroke()
  59.  
  60. let fill (ctx:Context) (color:Color) =
  61.    ctx.SetColor(color)  
  62.    ctx.Fill()
  63.  
  64. type DrawingInfo = {
  65.    Drawing:Drawing;
  66.    mutable Offset:Point;
  67.    mutable Opacity:float option
  68.    mutable IsVisible:bool }
  69.  
  70. let draw (ctx:Context) (info:DrawingInfo) =
  71.    let x,y = info.Offset.X, info.Offset.Y
  72.    let withOpacity (color:Color) =
  73.       match info.Opacity with
  74.       | Some opacity -> color.WithAlpha(color.Alpha * opacity)
  75.       | None -> color
  76.    match info.Drawing with
  77.    | DrawLine(Line(x1,y1,x2,y2),pen) ->
  78.       ctx.MoveTo(x1,y1)
  79.       ctx.LineTo(x2,y2)
  80.       penStroke ctx pen
  81.    | DrawRect(Rect(w,h),pen) ->
  82.       ctx.Rectangle(x,y,w,h)
  83.       penStroke ctx pen
  84.    | DrawTriangle(triangle,pen) ->
  85.       drawTriangle ctx triangle
  86.       penStroke ctx pen
  87.    | DrawEllipse(Ellipse(w,h),pen) ->
  88.       drawEllipse ctx (x,y,w,h)
  89.       penStroke ctx pen
  90.    | DrawImage(image,x,y) ->
  91.       if !image <> null then
  92.          ctx.DrawImage(!image,x,y)
  93.    | DrawText(x,y,text,Font(size,isBold),color) ->
  94.       let layout = new TextLayout(Text=text)
  95.       layout.Font <- layout.Font.WithSize(size)
  96.       if isBold then layout.Font <- layout.Font.WithWeight(FontWeight.Bold)      
  97.       ctx.SetColor(color)
  98.       ctx.DrawTextLayout(layout,x,y)
  99.    | DrawBoundText(x,y,width,text,Font(size,isBold),color) ->
  100.       let layout = new TextLayout(Text=text)
  101.       layout.Font <- layout.Font.WithSize(size)
  102.       layout.Width <- width
  103.       if isBold then layout.Font <- layout.Font.WithWeight(FontWeight.Bold)      
  104.       ctx.SetColor(color)
  105.       ctx.DrawTextLayout(layout,x,y)
  106.    | FillRect(Rect(w,h),fillColor) ->
  107.       ctx.Rectangle(x,y,w,h)
  108.       fill ctx fillColor
  109.    | FillTriangle(triangle,fillColor) ->
  110.       drawTriangle ctx triangle
  111.       fill ctx fillColor
  112.    | FillEllipse(Ellipse(w,h),fillColor) ->
  113.       drawEllipse ctx (x,y,w,h)
  114.       fill ctx fillColor
  115.    | DrawShape(_,LineShape(Line(x1,y1,x2,y2),pen)) ->
  116.       ctx.MoveTo(x+x1,y+y1)
  117.       ctx.LineTo(x+x2,y+y2)
  118.       penStroke ctx pen
  119.    | DrawShape(_,RectShape(Rect(w,h),pen,fillColor)) ->
  120.       ctx.Rectangle(x,y,w,h)
  121.       fill ctx fillColor
  122.       ctx.Rectangle(x,y,w,h)
  123.       penStroke ctx pen
  124.    | DrawShape(_,TriangleShape(triangle,pen,fillColor)) ->
  125.       drawTriangle ctx triangle
  126.       fill ctx (withOpacity fillColor)
  127.       drawTriangle ctx triangle
  128.       penStroke ctx pen
  129.    | DrawShape(_,EllipseShape(Ellipse(w,h),pen,fillColor)) ->
  130.       drawEllipse ctx (x,y,w,h)      
  131.       fill ctx (withOpacity fillColor)
  132.       drawEllipse ctx (x,y,w,h)
  133.       penStroke ctx pen
  134.    | DrawShape(_,TextShape(textRef,Font(size,isBold),color)) ->
  135.       let layout = new TextLayout()
  136.       layout.Text <- !textRef
  137.       layout.Font <- layout.Font.WithSize(size)
  138.       if isBold then layout.Font <- layout.Font.WithWeight(FontWeight.Bold)      
  139.       ctx.SetColor(color)
  140.       ctx.DrawTextLayout(layout,x,y)
  141.    | DrawShape(name,shape) ->
  142.       failwith "Not implemented"
  143.      
  144. let loadImageAsync (url:string) = async {
  145.    let request = HttpWebRequest.Create(url)
  146.    use! response = request.AsyncGetResponse()
  147.    use stream = response.GetResponseStream()
  148.    return Image.FromStream(stream)
  149.    }
  150.  
  151. [<AllowNullLiteral>]
  152. type DrawingCanvas () =
  153.    inherit Canvas ()
  154.    let drawings = ResizeArray<DrawingInfo>()
  155.    let onShape shapeName f =
  156.       drawings
  157.       |> Seq.tryPick (function
  158.          | { Drawing=DrawShape(name,_) } as info when name = shapeName -> Some info
  159.          | _ -> None
  160.       )
  161.       |> Option.iter f      
  162.    member canvas.AddDrawing(drawing) =
  163.       { Drawing=drawing; Offset=Point(); Opacity=None; IsVisible=true }
  164.       |> drawings.Add
  165.       canvas.QueueDraw()
  166.    member canvas.AddDrawingAt(drawing, offset:Point) =
  167.       { Drawing=drawing; Offset=offset; Opacity=None; IsVisible=true }
  168.       |> drawings.Add
  169.       canvas.QueueDraw()
  170.    member canvas.MoveShape(shape, offset:Point) =
  171.       onShape shape (fun info -> info.Offset <- offset; canvas.QueueDraw())
  172.    member canvas.SetShapeOpacity(shape, opacity) =
  173.       onShape shape (fun info -> info.Opacity <- Some opacity; canvas.QueueDraw())
  174.    member canvas.SetShapeVisibility(shape, isVisible) =
  175.       onShape shape (fun info -> info.IsVisible <- isVisible; canvas.QueueDraw())
  176.    member canvas.RemoveShape(shape) =
  177.       drawings |> Seq.tryFindIndex (function
  178.          | { DrawingInfo.Drawing=DrawShape(shapeName,_) } -> shapeName = shape
  179.          | _ -> false
  180.       )
  181.       |> function Some index -> drawings.RemoveAt(index) | None -> ()
  182.    member canvas.Invalidate() =
  183.       canvas.QueueDraw()
  184.    override this.OnDraw(ctx, rect) =
  185.       base.OnDraw(ctx, rect)      
  186.       for drawing in drawings do
  187.          if drawing.IsVisible then draw ctx drawing
  188.  
  189. type internal MyApp () =
  190.    let mutable mainWindow : Window = null
  191.    let mutable mainCanvas : DrawingCanvas = null
  192.    let mutable keyUp = Action<string>(ignore)
  193.    let mutable keyDown = Action<string>(ignore)
  194.    let mutable mouseDown = fun () -> ()
  195.    let mutable mouseUp = fun () -> ()
  196.    let mutable mouseMove = fun () -> ()
  197.    let mutable mouseX = 0.0
  198.    let mutable mouseY = 0.0
  199.    let mutable isLeftButtonDown = false
  200.    let runApp onRun =      
  201.       Application.Initialize (ToolkitType.Gtk)      
  202.       mainWindow <- new Window(Title="App", Padding = WidgetSpacing(), Width=800., Height=600.)          
  203.       mainCanvas <- new DrawingCanvas(BackgroundColor=Colors.White)
  204.       mainCanvas.KeyPressed.Add(fun args -> keyDown.Invoke(args.Key.ToString()))
  205.       mainCanvas.KeyReleased.Add(fun args -> keyUp.Invoke(args.Key.ToString()))
  206.       mainCanvas.ButtonPressed.Add(fun args ->
  207.          mouseX <- args.X
  208.          mouseY <- args.Y
  209.          if args.Button = PointerButton.Left then isLeftButtonDown <-true
  210.          mouseDown()
  211.       )
  212.       mainCanvas.ButtonReleased.Add(fun args ->
  213.          mouseX <- args.X
  214.          mouseY <- args.Y
  215.          if args.Button = PointerButton.Left then isLeftButtonDown <- false
  216.          mouseUp()
  217.       )
  218.       mainCanvas.MouseMoved.Add(fun args ->
  219.          mouseX <- args.X
  220.          mouseY <- args.Y
  221.          mouseMove()
  222.       )
  223.       mainWindow.Content <- mainCanvas
  224.       mainCanvas.CanGetFocus <- true
  225.       mainCanvas.SetFocus()            
  226.       mainWindow.Show()
  227.       mainWindow.Closed.Add(fun e -> Application.Exit())
  228.       let onRun = unbox<unit->unit> onRun
  229.       onRun ()        
  230.       Application.Run()  
  231.    let startAppThread () =
  232.       use isInitialized = new AutoResetEvent(false)
  233.       let thread = Thread(ParameterizedThreadStart runApp)
  234.       thread.SetApartmentState(ApartmentState.STA)
  235.       thread.Start(fun () -> isInitialized.Set() |> ignore)
  236.       isInitialized.WaitOne() |> ignore      
  237.    do startAppThread()
  238.    member app.Window = mainWindow
  239.    member app.Canvas = mainCanvas
  240.    member app.Invoke action = Application.Invoke action
  241.    member app.KeyUp with set action = keyUp <- action
  242.    member app.KeyDown with set action = keyDown <- action
  243.    member app.MouseDown with set action = mouseDown <- action
  244.    member app.MouseUp with set action = mouseUp <- action
  245.    member app.MouseMove with set action = mouseMove <- action
  246.    member app.MouseX with get() = mouseX
  247.    member app.MouseY with get() = mouseY
  248.    member app.IsLeftButtonDown with get() = isLeftButtonDown
  249.  
  250. [<Sealed>]
  251. type internal My private () =
  252.    static let app = lazy (MyApp())
  253.    static member App = app.Value
  254.          
  255. let addDrawing drawing =
  256.    My.App.Invoke (fun () -> My.App.Canvas.AddDrawing(drawing))
  257. let addDrawingAt drawing (x,y) =
  258.    My.App.Invoke (fun () -> My.App.Canvas.AddDrawingAt(drawing,Point(x,y)))
  259.  
  260. [<Sealed>]
  261. type GraphicsWindow private () =
  262.    static let mutable lastKey : string = null
  263.    static let mutable backgroundColor = Colors.White
  264.    static let mutable width = 640.0
  265.    static let mutable height = 480.0
  266.    static let pen () = Pen(GraphicsWindow.PenColor,GraphicsWindow.PenWidth)
  267.    static let brush () = GraphicsWindow.BrushColor
  268.    static let font () = Font(GraphicsWindow.FontSize,GraphicsWindow.FontBold)
  269.    static let draw drawing = addDrawing drawing      
  270.    static let drawAt (x,y) drawing = addDrawingAt drawing (x,y)
  271.    static member Title
  272.       with set title =
  273.          My.App.Invoke (fun () -> My.App.Window.Title <- title)
  274.    static member BackgroundColor
  275.       with get () = backgroundColor
  276.       and set color =
  277.          backgroundColor <- color
  278.          My.App.Invoke (fun () -> My.App.Canvas.BackgroundColor <- color)
  279.    static member Width
  280.       with get () = width
  281.       and set newWidth =
  282.          width <- newWidth
  283.          My.App.Invoke (fun () -> My.App.Window.Width <- newWidth)
  284.    static member Height
  285.       with get () = height
  286.       and set newHeight =
  287.          height <- newHeight
  288.          My.App.Invoke (fun () -> My.App.Window.Height <- newHeight)
  289.    static member val PenColor = Colors.Black with get, set
  290.    static member val PenWidth = 2.0 with get, set
  291.    static member val BrushColor = Colors.Purple with get,set
  292.    static member val FontSize = 12.0 with get,set
  293.    static member val FontBold = false with get,set
  294.    static member DrawLine(x1,y1,x2,y2) =
  295.       DrawLine(Line(x1,y1,x2,y2),pen()) |> draw
  296.    static member DrawRectangle(x,y,width,height) =
  297.       DrawRect(Rect(width,height),pen()) |> drawAt (x,y)
  298.    static member DrawTriangle(x1,y1,x2,y2,x3,y3) =
  299.       DrawTriangle(Triangle(x1,y1,x2,y2,x3,y3),pen()) |> draw
  300.    static member DrawEllipse(x,y,width,height) =
  301.       DrawEllipse(Ellipse(width,height),pen()) |> drawAt (x,y)
  302.    static member DrawImage(imageName,x,y) =
  303.       let imageRef = ref null
  304.       async {
  305.          let! image = loadImageAsync imageName
  306.          imageRef := image
  307.          My.App.Invoke(fun () -> My.App.Canvas.Invalidate())
  308.       } |> Async.Start
  309.       DrawImage(imageRef,x,y) |> draw
  310.    static member DrawText(x,y,text) =
  311.       DrawText(x,y,text,font(),brush()) |> draw
  312.    static member DrawBoundText(x,y,width,text) =
  313.       DrawBoundText(x,y,width,text,font(),brush()) |> draw
  314.    static member FillRectangle(x,y,width,height) =
  315.       FillRect(Rect(width,height),brush()) |> drawAt (x,y)
  316.    static member FillTriangle(x1,y1,x2,y2,x3,y3) =
  317.       FillTriangle(Triangle(x1,y1,x2,y2,x3,y3),brush()) |> draw
  318.    static member FillEllipse(x,y,width,height) =
  319.       FillEllipse(Ellipse(width,height),brush()) |> drawAt (x,y)
  320.    static member LastKey with get() : string = lastKey
  321.    static member KeyUp
  322.       with set (action:unit -> unit) =
  323.          My.App.Invoke (fun () ->
  324.             My.App.KeyUp <- (fun key -> lastKey <- key; action())
  325.          )
  326.    static member KeyDown
  327.       with set (action:unit -> unit) =
  328.          My.App.Invoke (fun () ->
  329.              My.App.KeyDown <- (fun key -> lastKey <- key; action())
  330.          )
  331.    static member MouseX with get() = My.App.MouseX
  332.    static member MouseY with get() = My.App.MouseY
  333.    static member MouseDown
  334.       with set (action:unit -> unit) = My.App.MouseDown <- action  
  335.    static member MouseUp
  336.       with set (action:unit -> unit) = My.App.MouseUp <- action      
  337.    static member MouseMove
  338.       with set (action:unit -> unit) = My.App.MouseMove <- action
  339.    static member GetColorFromRGB(r,g,b) =
  340.       Color.FromBytes(byte r,byte g,byte b)
  341.    static member Show() = ()
  342.    static member Hide() = ()  
  343.  
  344. [<Sealed>]
  345. type Mouse private () =
  346.    static member IsLeftButtonDown = My.App.IsLeftButtonDown
  347.    static member X = My.App.MouseX
  348.    static member Y = My.App.MouseY
  349.  
  350. open System.Collections.Generic
  351.  
  352. type ShapeInfo = { Shape:Shape; mutable Offset:Point; mutable Opacity:float }
  353.  
  354. [<Sealed>]
  355. type Shapes private () =
  356.    static let pen () = Pen(GraphicsWindow.PenColor,GraphicsWindow.PenWidth)
  357.    static let brush () = GraphicsWindow.BrushColor
  358.    static let font () = Font(GraphicsWindow.FontSize,GraphicsWindow.FontBold)
  359.    static let shapes = Dictionary<string,ShapeInfo>()
  360.    static let addShape name shape =
  361.       let info = { Shape=shape; Offset=Point(); Opacity=1.0 }
  362.       shapes.Add(name,info)
  363.       addDrawing (DrawShape(name,shape))
  364.    static let onShape shapeName action =
  365.       match shapes.TryGetValue(shapeName) with
  366.       | true, info -> action info
  367.       | false, _ -> ()
  368.    static let genName name = name + Guid.NewGuid().ToString()
  369.    static member Remove(shapeName) =
  370.       My.App.Invoke (fun () -> My.App.Canvas.RemoveShape(shapeName))
  371.    static member AddLine(x1,y1,x2,y2) =
  372.       let name = genName "Line"
  373.       LineShape(Line(x1,y1,x2,y2),pen()) |> addShape name
  374.       name
  375.    static member AddRectangle(width,height) =
  376.       let name = genName "Rectangle"
  377.       RectShape(Rect(width,height),pen(),brush()) |> addShape name
  378.       name
  379.    static member AddTriangle(x1,y1,x2,y2,x3,y3) =
  380.       let name = genName "Triangle"
  381.       TriangleShape(Triangle(x1,y1,x2,y2,x3,y3),pen(),brush()) |> addShape name
  382.       name
  383.    static member AddEllipse(width,height) =
  384.       let name = genName "Ellipse"
  385.       EllipseShape(Ellipse(width,height),pen(),brush()) |> addShape name
  386.       name
  387.    static member AddImage(imageName) =
  388.       let name = genName "Image"
  389.       ImageShape(imageName) |> addShape name
  390.       name
  391.    static member AddText(text) =
  392.       let name = genName "Text"
  393.       TextShape(ref text, font(), brush()) |> addShape name
  394.       name
  395.    static member HideShape(shapeName) =      
  396.       My.App.Invoke (fun () -> My.App.Canvas.SetShapeVisibility(shapeName,false))      
  397.    static member ShowShape(shapeName) =
  398.       My.App.Invoke (fun () -> My.App.Canvas.SetShapeVisibility(shapeName,true))      
  399.    static member Move(shapeName,x,y) =
  400.       onShape shapeName (fun info ->
  401.          info.Offset <- Point(x,y)
  402.          My.App.Invoke (fun () -> My.App.Canvas.MoveShape(shapeName,info.Offset))
  403.       )
  404.    static member GetLeft(shapeName) =      
  405.       match shapes.TryGetValue(shapeName) with
  406.       | true, info -> info.Offset.X
  407.       | false, _ -> 0.0
  408.    static member GetTop(shapeName) =
  409.       match shapes.TryGetValue(shapeName) with
  410.       | true, info -> info.Offset.Y
  411.       | false, _ -> 0.0
  412.    static member SetOpacity(shapeName, opacity) =
  413.       onShape shapeName (fun info ->
  414.          info.Opacity <- opacity
  415.          My.App.Invoke (fun () -> My.App.Canvas.SetShapeOpacity(shapeName,opacity))
  416.       )
  417.    static member GetOpacity(shapeName) =
  418.       match shapes.TryGetValue(shapeName) with
  419.       | true, info -> info.Opacity
  420.       | false, _ -> 1.0
  421.    static member SetText(shapeName, text) =
  422.       failwith "Not implemented"
  423.  
  424. [<Sealed>]
  425. type Turtle private () =
  426.    static let mutable angle = 0.0
  427.    static let mutable _x = 0.0
  428.    static let mutable _y = 0.0
  429.    static let mutable isPenUp = false
  430.    static member Angle
  431.       with get () = angle
  432.       and set value = angle <- value
  433.    static member X
  434.       with get () = _x
  435.       and set value = _x <- value
  436.    static member Y
  437.       with get () = _y
  438.       and set value = _y <- value
  439.    static member Turn(amount:float) =
  440.       angle <- angle + amount
  441.    static member Move(distance:float) =
  442.       let r = angle * Math.PI / 180.0
  443.       let x' = _x + distance * cos r
  444.      let y' = _y + distance * sin r
  445.       if not isPenUp then
  446.          GraphicsWindow.DrawLine(_x,_y,x',y')
  447.       _x <- x'
  448.      _y <- y'
  449.    static member MoveTo(x:float,y:float) =
  450.       _x <- x; _y = y
  451.    static member PenUp() =
  452.       isPenUp <- true
  453.    static member PenDown() =
  454.       isPenUp <- false
  455.  
  456. [<Sealed>]
  457. type Program private () =
  458.    static member Delay(ms:int) = Thread.Sleep(ms)
  459.  
  460. module Math =
  461.    let private rand = System.Random()
  462.    let GetRadians (deg:float) = deg * Math.PI / 180.
  463.    let GetRandomNumber(n) = rand.Next(n)
  464.  
  465. type Clock private () =
  466.    static member Hour = DateTime.Now.Hour |> float
  467.    static member Minute = DateTime.Now.Minute |> float
  468.    static member Second = DateTime.Now.Second |> float
  469. (*
  470. // [snippet:Turtle sample]
  471. GraphicsWindow.PenColor <- Colors.Purple
  472. Turtle.X <- 150.0
  473. Turtle.Y <- 150.0
  474. for i in 0..5..200 do
  475.    Turtle.Move(float i)
  476.    Turtle.Turn(90.0)
  477. // [/snippet]
  478.  
  479. // [snippet:Random circles sample]
  480. let rand = Random()
  481. let colors = [Colors.Red; Colors.Green; Colors.Blue; Colors.Yellow]
  482. GraphicsWindow.BackgroundColor <- Colors.Black
  483. for i = 1 to 1200 do
  484.    GraphicsWindow.BrushColor <- colors.[rand.Next(colors.Length)]
  485.    GraphicsWindow.FillEllipse(rand.NextDouble()*800., rand.NextDouble()*600., 30., 30.)
  486. // [/snippet]
  487.  
  488. // [snippet:Paint program sample]
  489. let onKeyDown () =
  490.    match GraphicsWindow.LastKey with
  491.    | "K1" -> GraphicsWindow.PenColor <- Colors.Red
  492.    | "K2" -> GraphicsWindow.PenColor <- Colors.Blue
  493.    | "K3" -> GraphicsWindow.PenColor <- Colors.LightGreen
  494.    | s -> System.Diagnostics.Debug.WriteLine(s)
  495.  
  496. let mutable prevX = 0.0
  497. let mutable prevY = 0.0
  498.  
  499. let onMouseDown () =
  500.    prevX <- GraphicsWindow.MouseX
  501.    prevY <- GraphicsWindow.MouseY
  502.    
  503. let onMouseMove () =
  504.    let x = GraphicsWindow.MouseX
  505.    let y = GraphicsWindow.MouseY
  506.    if Mouse.IsLeftButtonDown then
  507.       GraphicsWindow.DrawLine(prevX, prevY, x, y)
  508.    prevX <- x
  509.    prevY <- y
  510.  
  511. GraphicsWindow.BackgroundColor <- Colors.Black
  512. GraphicsWindow.PenColor <- Colors.White
  513. GraphicsWindow.MouseDown <- onMouseDown
  514. GraphicsWindow.MouseMove <- onMouseMove
  515. GraphicsWindow.KeyDown <- onKeyDown
  516. // [/snippet]
  517. *)
  518. // [snippet:Clock sample]
  519. let GW = GraphicsWindow.Width
  520. let GH = GraphicsWindow.Height
  521. let Radius = 200.0
  522. let MidX = GW/2.0
  523. let MidY = GW/2.0
  524.  
  525. let initWindow () =
  526.    GraphicsWindow.Show()
  527.    GraphicsWindow.Title <- "Analog Clock"
  528.    GraphicsWindow.BackgroundColor <- Colors.Black
  529.    GraphicsWindow.BrushColor <- Colors.BurlyWood
  530.    GraphicsWindow.DrawEllipse(MidX-Radius-15.,MidY-Radius-5.,Radius*2.+30.,Radius*2.+20.)
  531.    GraphicsWindow.FillEllipse(MidX-Radius-15.,MidY-Radius-5.,Radius*2.+30.,Radius*2.+20.)
  532.    for angle in 1.0..180.0 do
  533.      let X = MidX+(Radius+15.)*Math.Cos(Math.GetRadians(angle))
  534.      let Y1 = MidY+Radius*Math.Sin(Math.GetRadians(angle))+15.
  535.      let Y2 = MidY+(Radius+15.)*Math.Sin(Math.GetRadians(-angle))+10.
  536.      let Blue = Math.GetRandomNumber(40)+30
  537.      GraphicsWindow.PenWidth <- Math.GetRandomNumber(5) |> float
  538.      GraphicsWindow.PenColor <- GraphicsWindow.GetColorFromRGB(Blue+100+Math.GetRandomNumber(10),Blue+60+Math.GetRandomNumber(20),Blue)
  539.      Shapes.AddLine(X,Y1,X,Y2) |> ignore
  540.    GraphicsWindow.BrushColor <- Colors.White
  541.    let ClockNum = Dictionary<_,_>()
  542.    for i in 1. .. 12. do
  543.      let Radians = Math.GetRadians(-i * 30. + 90.)
  544.      ClockNum.[i] <- Shapes.AddText(i.ToString())
  545.      Shapes.Move(ClockNum.[i],MidX-4.+Radius*Math.Cos(Radians),MidY-4.-Radius*Math.Sin(Radians))  
  546.    
  547. let mutable HourHand = ""
  548. let mutable MinuteHand = ""
  549. let mutable SecondHand = ""
  550. let mutable Hour = 0.
  551. let mutable Minute = 0.
  552. let mutable Second = 0.
  553. let initHands () =
  554.    if (Clock.Hour + Clock.Minute/60. + Clock.Second/3600. <> Hour) then
  555.      Shapes.Remove(HourHand)
  556.      Hour <- Clock.Hour + Clock.Minute/60. + Clock.Second/3600.
  557.      GraphicsWindow.PenColor <- Colors.Black
  558.      GraphicsWindow.PenWidth <- 3.
  559.      HourHand <- Shapes.AddLine(MidX,MidY,MidX+Radius/2.*Math.Cos(Math.GetRadians(Hour*30.-90.)),MidY+Radius/2.*Math.Sin(Math.GetRadians(Hour*30.-90.)))  
  560.    if Clock.Minute <> Minute then
  561.      Shapes.Remove(MinuteHand)
  562.      Minute <- Clock.Minute + Clock.Second/60.
  563.      GraphicsWindow.PenColor <- Colors.Blue
  564.      GraphicsWindow.PenWidth <- 2.
  565.      MinuteHand <- Shapes.AddLine(MidX,MidY,MidX+Radius/1.2*Math.Cos(Math.GetRadians(Minute*6.-90.)),MidY+Radius/1.2*Math.Sin(Math.GetRadians(Minute*6.-90.)))  
  566.    if Clock.Second <> Second then
  567.      Shapes.Remove(SecondHand)
  568.      Second <- Clock.Second
  569.      GraphicsWindow.PenColor <- Colors.Red
  570.      GraphicsWindow.PenWidth <- 1.
  571.      SecondHand <- Shapes.AddLine(MidX,MidY,MidX+Radius*Math.Cos(Math.GetRadians(Second*6.-90.)),MidY+Radius*Math.Sin(Math.GetRadians(Second*6.-90.)))
  572.    
  573. initWindow()
  574. while true do
  575.    initHands()
  576.    //Sound.PlayClick()
  577.    Program.Delay(1000)
  578. // [/snippet]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement