Advertisement
Guest User

curveditor

a guest
Oct 14th, 2015
102
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
D 6.30 KB | None | 0 0
  1. #load "LWCs.fsx"
  2.  
  3. open System.Windows.Forms
  4. open System.Drawing
  5. open LWCs
  6.  
  7. let f = new Form(Text="Curve editor", TopMost=true)
  8. f.Show()
  9.  
  10. let scrollTimer = new Timer(Interval=30)
  11.  
  12. type IumButton() as this =
  13.   inherit LWC()
  14.  
  15.   let clickevt = new Event<System.EventArgs>()
  16.   let clickevt1 = new Event<System.EventArgs>()
  17.  
  18.   do this.Size <- SizeF(32.f, 32.f)
  19.  
  20.   let mutable text = ""
  21.  
  22.   member this.Click = clickevt.Publish
  23.   member this.Click1 = clickevt1.Publish
  24.  
  25.   member this.Text
  26.     with get() = text
  27.     and set(v) = text <- v; this.Invalidate()
  28.  
  29.   override this.OnMouseMove e = ()
  30.   override this.OnMouseDown e = clickevt.Trigger(new System.EventArgs())
  31.   override this.OnMouseUp e = clickevt1.Trigger(new System.EventArgs())
  32.  
  33.   override this.OnPaint e =
  34.     let g = e.Graphics
  35.     g.FillRectangle(Brushes.Yellow,0,0,300,300)
  36.     g.FillEllipse(Brushes.Red, new Rectangle(0,0,int(this.Size.Width),int(this.Size.Height)))
  37.     let sz = g.MeasureString(text, this.Parent.Font)
  38.     g.DrawString(text, this.Parent.Font, Brushes.White, PointF((this.Size.Width - sz.Width) / 2.f, (this.Size.Height - sz.Height) / 2.f))
  39.  
  40. type NavBut=
  41. | Up = 0
  42. | Right = 2
  43. | Left = 1
  44. | Down = 3
  45.  
  46.  
  47. // Lightweight controls: astrazione programmativa che imita i controlli grafici
  48. type Editor() as this =
  49.   inherit LWContainer()
  50.     do
  51.       this.SetStyle(ControlStyles.DoubleBuffer,true)
  52.       this.SetStyle(ControlStyles.AllPaintingInWmPaint,true)
  53.       this.SetStyle(ControlStyles.UserPaint,true)
  54.   let pts = [| PointF(); PointF(20.f, 20.f); PointF(50.f, 50.f); PointF(50.f, 100.f) |]
  55.  
  56.   let buttons = [|
  57.     new IumButton(Text="U",Location=PointF(32.f,0.f));
  58.     new IumButton(Text="L",Location=PointF(0.f,32.f));
  59.     new IumButton(Text="R",Location=PointF(64.f,32.f));
  60.     new IumButton(Text="D",Location=PointF(32.f,64.f));
  61.   |]
  62.  
  63.   let button (k:NavBut)=
  64.     buttons.[int(k)]
  65.  
  66.  
  67.   let handleSize = 5.f
  68.  
  69.   let mutable selected = None
  70.   let mutable offsetDrag = PointF()
  71.  
  72.   let mutable tension = 1.f
  73.  
  74.   let mutable w2v = new Drawing2D.Matrix()
  75.   let mutable v2w = new Drawing2D.Matrix()
  76.  
  77.   let translateW (tx, ty) =
  78.     w2v.Translate(tx, ty)
  79.     v2w.Translate(-tx, -ty, Drawing2D.MatrixOrder.Append)
  80.  
  81.   let rotateW a =
  82.     w2v.Rotate a
  83.     v2w.Rotate(-a, Drawing2D.MatrixOrder.Append)
  84.  
  85.   let rotateAtW p a =
  86.     w2v.RotateAt(a, p)
  87.     v2w.RotateAt(-a, p, Drawing2D.MatrixOrder.Append)
  88.  
  89.   let scaleW (sx, sy) =
  90.     w2v.Scale(sx, sy)
  91.     v2w.Scale(1.f/sx, 1.f/sy, Drawing2D.MatrixOrder.Append)
  92.  
  93.   let transformP (m:Drawing2D.Matrix) (p:Point) =
  94.     let a = [| PointF(single p.X, single p.Y) |]
  95.     m.TransformPoints(a)
  96.     a.[0]
  97.  
  98.   let handleHitTest (p:PointF) (h:PointF) =
  99.     let x = p.X - h.X
  100.     let y = p.Y - h.Y
  101.     x * x + y * y < handleSize * handleSize
  102.  
  103.  
  104.   do buttons |> Seq.iter (fun b->
  105.     b.Parent <- this
  106.     this.LWControls.Add(b)
  107.     )
  108.   let mutable bUp = false
  109.   do
  110.     (button NavBut.Up).Click.Add(fun _ ->
  111.         this.Cursor <- Cursors.Hand
  112.         SendKeys.Send("{W}")
  113.     )    
  114.     (button NavBut.Down).Click.Add(fun _ ->
  115.         SendKeys.Send("{S}")
  116.     )
  117.     (button NavBut.Left).Click.Add(fun _ ->
  118.         SendKeys.Send("{A}")
  119.     )
  120.     (button NavBut.Right).Click.Add(fun _ ->
  121.         SendKeys.Send("{D}")
  122.     )    
  123.  
  124.   let scrollBy dir =
  125.     match dir with
  126.     | NavBut.Up -> (0.f,-10.f)
  127.     | NavBut.Down -> (0.f,10.f)
  128.     | NavBut.Left -> (10.f,0.f)
  129.     | NavBut.Right -> (-10.f,0.f)
  130.  
  131.   member this.V2W = v2w
  132.  
  133.   member this.Tension
  134.     with get () = tension
  135.     and set (v) = tension <- v; this.Invalidate()
  136.  
  137.   override this.OnMouseDown e =
  138.     let l = transformP v2w e.Location
  139.     let ht = handleHitTest l
  140.     selected <- pts |> Array.tryFindIndex ht
  141.     match selected with
  142.     | Some(idx) ->
  143.       let p = pts.[idx]
  144.       offsetDrag <- PointF(p.X - l.X, p.Y - l.Y)
  145.     | None -> ()
  146.     base.OnMouseDown(e)
  147.  
  148.   override this.OnMouseUp e =
  149.     selected <- None
  150.  
  151.   override this.OnMouseMove e =
  152.     let l = transformP v2w e.Location
  153.     buttons |> Array.iter (fun b -> b.OnMouseMove e)
  154.     match selected with
  155.     | Some idx ->
  156.       pts.[idx] <- PointF(l.X + offsetDrag.X, l.Y + offsetDrag.Y)
  157.       this.Invalidate()
  158.     | None -> ()
  159.  
  160.   override this.OnPaint e =
  161.     let g = e.Graphics
  162.     g.SmoothingMode <- Drawing2D.SmoothingMode.HighQuality
  163.     let drawHandle (p:PointF) =
  164.       let w = 5.f
  165.       g.DrawEllipse(Pens.Black, p.X - w, p.Y - w, 2.f * w, 2.f * w)
  166.     let ctx = g.Save()
  167.     g.Transform <- w2v
  168.     g.DrawBezier(Pens.Black, pts.[0], pts.[1], pts.[2], pts.[3])
  169.     g.DrawLine(Pens.Red, pts.[0], pts.[1])
  170.     g.DrawLine(Pens.Red, pts.[2], pts.[3])
  171.     g.DrawCurve(Pens.Blue, pts, tension)
  172.     // let (|>) x f = f x
  173.     pts |> Array.iter drawHandle
  174.     g.Restore(ctx)
  175.     base.OnPaint(e)
  176.  
  177.  
  178.  
  179.   override this.OnKeyDown e =
  180.     let translate (x, y) =
  181.       let t = [| PointF(0.f, 0.f); PointF(x, y) |]
  182.       v2w.TransformPoints(t)
  183.       translateW(t.[1].X - t.[0].X, t.[1].Y - t.[0].Y)
  184.  
  185.     match e.KeyCode with
  186.     | Keys.W ->
  187.       translate(0.f,-10.f)
  188.       this.Invalidate()
  189.     | Keys.D ->
  190.       translate(10.f,0.f)
  191.       this.Invalidate()
  192.     | Keys.A ->
  193.       translate(-10.f,0.f)
  194.       this.Invalidate()
  195.     | Keys.S ->
  196.       translate(0.f,10.f)
  197.       this.Invalidate()
  198.     | Keys.Q ->
  199.       let p = transformP v2w (Point(this.Width / 2, this.Height / 2))
  200.       rotateAtW p 10.f
  201.       this.Invalidate()
  202.     | Keys.E ->
  203.       let p = transformP v2w (Point(this.Width / 2, this.Height / 2))
  204.       rotateAtW p -10.f
  205.       this.Invalidate()
  206.     | Keys.Z ->
  207.       let p = transformP v2w (Point(this.Width / 2, this.Height / 2))
  208.       scaleW(1.1f, 1.1f)
  209.       let p1 = transformP v2w (Point(this.Width / 2, this.Height / 2))
  210.       translateW(p1.X - p.X, p1.Y - p.Y)
  211.       this.Invalidate()
  212.     | Keys.X ->
  213.       let p = transformP v2w (Point(this.Width / 2, this.Height / 2))
  214.       scaleW(1.f/1.1f, 1.f / 1.1f)
  215.       let p1 = transformP v2w (Point(this.Width / 2, this.Height / 2))
  216.       translateW(p1.X - p.X, p1.Y - p.Y)
  217.       this.Invalidate()
  218.     | _ -> ()
  219.  
  220.  
  221.  
  222.  
  223. let e = new Editor(Dock=DockStyle.Fill)
  224. f.Controls.Add(e)
  225. e.Focus()
  226.  
  227. // <NoInMidTerm>
  228. //let b = new Button(Text="OK")
  229. //e.Controls.Add(b)
  230. // </NoInMidTerm>
  231.  
  232. e.Tension <- 1.f
  233.  
  234. //e.MouseDown.Add(fun _ -> printfn "Ahi!")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement