Advertisement
Guest User

Untitled

a guest
Nov 6th, 2016
304
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
F# 22.25 KB | None | 0 0
  1. open System.Windows.Forms
  2. open System.Drawing
  3.  
  4. // Lightweight controls: astrazione programmativa che imita i controlli grafici
  5. type LWC() =
  6.   let mutable parent : Control = null
  7.   let mutable location = PointF()
  8.   let mutable size = SizeF()
  9.  
  10.   let mouseDown = Event<MouseEventArgs>()
  11.   let mouseMove = Event<MouseEventArgs>()
  12.   let mouseUp = Event<MouseEventArgs>()
  13.  
  14.   member val MouseEventHandled = false with get, set
  15.  
  16.   member this.MouseDown with get() = mouseDown.Publish
  17.   member this.MouseMove with get() = mouseMove.Publish
  18.   member this.MouseUp with get() = mouseUp.Publish
  19.  
  20.   abstract OnMouseDown : MouseEventArgs -> unit
  21.   default this.OnMouseDown e = mouseDown.Trigger(e)
  22.  
  23.   abstract OnMouseMove : MouseEventArgs -> unit
  24.   default this.OnMouseMove e = mouseMove.Trigger(e)
  25.  
  26.   abstract OnMouseUp : MouseEventArgs -> unit
  27.   default this.OnMouseUp e = mouseUp.Trigger(e)
  28.  
  29.   abstract OnPaint : PaintEventArgs -> unit
  30.   default this.OnPaint _ = ()
  31.  
  32.   abstract HitTest : PointF -> bool
  33.   default this.HitTest p =
  34.     (RectangleF(PointF(), size)).Contains(p)
  35.  
  36.   member this.Invalidate() =
  37.     if parent <> null then parent.Invalidate()
  38.  
  39.   member this.Location
  40.     with get() = location
  41.     and set(v) = location <- v; this.Invalidate()
  42.  
  43.   member this.Size
  44.     with get() = size
  45.     and set(v) = size <- v; this.Invalidate()
  46.  
  47.   member this.Parent
  48.     with get() = parent
  49.     and set(v) = parent <- v
  50.  
  51. type LWContainer() =
  52.   inherit UserControl()
  53.  
  54.   let controls = ResizeArray<LWC>()
  55.  
  56.   let cloneMouseEvent (c:LWC) (e:MouseEventArgs) =
  57.     new MouseEventArgs(e.Button, e.Clicks, e.X - int(c.Location.X), e.Y - int(c.Location.Y), e.Delta)
  58.  
  59.   let correlate (e:MouseEventArgs) (f:LWC->MouseEventArgs->unit) =
  60.     let mutable found = false
  61.     for i in { (controls.Count - 1) .. -1 .. 0 } do
  62.       if not found then
  63.         let c = controls.[i]
  64.         if c.HitTest(PointF(single(e.X) - c.Location.X, single(e.Y) - c.Location.Y)) then
  65.           found <- true
  66.           f c (cloneMouseEvent c e)
  67.  
  68.   let mutable captured : LWC option = None
  69.  
  70.   member this.LWControls = controls
  71.   member val LWMouseEventHandled = false with get, set
  72.  
  73.   override this.OnMouseDown e =
  74.     this.LWMouseEventHandled <- false
  75.     correlate e (fun c ev -> captured <- Some(c); c.OnMouseDown(ev); this.LWMouseEventHandled <- c.MouseEventHandled; c.MouseEventHandled <- false)
  76.     base.OnMouseDown e
  77.  
  78.   override this.OnMouseUp e =
  79.     this.LWMouseEventHandled <- false
  80.     correlate e (fun c ev -> c.OnMouseUp(ev); this.LWMouseEventHandled <- c.MouseEventHandled; c.MouseEventHandled <- false)
  81.     match captured with
  82.     | Some c -> c.OnMouseUp(cloneMouseEvent c e); captured <- None
  83.     | None  -> ()
  84.     base.OnMouseUp e
  85.  
  86.   override this.OnMouseMove e =
  87.     this.LWMouseEventHandled <- false
  88.     correlate e (fun c ev -> c.OnMouseMove(ev); this.LWMouseEventHandled <- c.MouseEventHandled; c.MouseEventHandled <- false)
  89.     match captured with
  90.     | Some c -> c.OnMouseMove(cloneMouseEvent c e)
  91.     | None  -> ()
  92.     base.OnMouseMove e
  93.  
  94.   override this.OnPaint e =
  95.     controls |> Seq.iter (fun c ->
  96.       let s = e.Graphics.Save()
  97.       e.Graphics.TranslateTransform(c.Location.X, c.Location.Y)
  98.       e.Graphics.Clip <- new Region(RectangleF(0.f, 0.f, c.Size.Width + 1.f, c.Size.Height + 1.f))
  99.       let r = e.Graphics.ClipBounds
  100.       let evt = new PaintEventArgs(e.Graphics, new Rectangle(int(r.Left), int(r.Top), int(r.Width), int(r.Height)))
  101.       c.OnPaint evt
  102.       e.Graphics.Restore(s)
  103.     )
  104.     base.OnPaint(e)
  105.  
  106. open System.Drawing
  107.  
  108. let computeCollision (me) (other) =
  109.     let mutable (meRec:Rectangle, meDir:Size, mePrec:Point) = me
  110.     let mutable (otherRec:Rectangle, otherDir:Size, otherPrec:Point) = other
  111.  
  112.     if Region(meRec).IsVisible(otherRec) then
  113.         let deltaDir = Size(-meDir.Width, -meDir.Height)
  114.  
  115.         meRec.Location <- mePrec + Size(meDir.Width, -meDir.Height)
  116.         if Region(meRec).IsVisible otherRec then
  117.             meRec.Location <- mePrec + Size(-meDir.Width, meDir.Height)
  118.  
  119.         ()
  120.        
  121.  
  122. let a1 = new ResizeArray<Rectangle * Size * Point>()
  123. let a2 = new ResizeArray<Rectangle * Size * Point>()
  124.  
  125.  
  126. let a3 = a1
  127.             |> Seq.append a2
  128.             |> Seq.toArray
  129.  
  130. for me in a1 do
  131.     for other in a3 do
  132.         if me <> other then
  133.             computeCollision me other
  134.                
  135.      
  136.     ()
  137.  
  138.  
  139. open System.Windows.Forms
  140. open System.Drawing
  141.  
  142.  
  143. let f = new Form(Text="Midterm exercise 3", TopMost=true)
  144. f.Show()
  145.  
  146. type RoundButton() =
  147.   inherit LWC()
  148.  
  149.   member val Text : string = "" with get, set //alloca una var locale che si chiama Text e genera due membri uno get e uno set
  150.  
  151.   //disegna il bottone
  152.   override this.OnPaint e =
  153.     let g = e.Graphics
  154.     g.DrawEllipse(Pens.Black, 0.f, 0.f, this.Size.Width, this.Size.Height)// disegno in tutta la mia area sta a chi mi chiama definire quale è
  155.     let r = g.MeasureString(this.Text, this.Parent.Font)// per sapere la dimensione del test per disegnarlo al centro del bottone. Il font è nel controllo, quindi invoco il parent. Tutti i controlli hanno un font. Restituisce un rettangolo r che è la label.
  156.     let x, y = (this.Size.Width - r.Width) / 2.f, (this.Size.Height - r.Height) / 2.f
  157.     g.DrawString(this.Text, this.Parent.Font, Brushes.Black, PointF(x, y))// scrive
  158.  
  159. type RectButton() =
  160.   inherit LWC()
  161.  
  162.   member val Text : string = "" with get, set //alloca una var locale che si chiama Text e genera due membri uno get e uno set
  163.  
  164.   override this.OnPaint e =
  165.     let g = e.Graphics
  166.     g.DrawRectangle(Pens.Black, 0.f, 0.f, this.Size.Width, this.Size.Height)
  167.     let r = g.MeasureString(this.Text, this.Parent.Font)// per sapere la dimensione del test per disegnarlo al centro del bottone. Il font è nel controllo, quindi invoco il parent. Tutti i controlli hanno un font. Restituisce un rettangolo r che è la label.
  168.     let x, y = (this.Size.Width - r.Width) / 2.f, (this.Size.Height - r.Height) / 2.f
  169.     g.DrawString(this.Text, this.Parent.Font, Brushes.Black, PointF(x, y))// scrive
  170.  
  171.  
  172. type VWCoordinates() =
  173.   let mutable wv = new Drawing2D.Matrix()
  174.   let mutable vw = new Drawing2D.Matrix()
  175.  
  176.   member this.WV with get() = wv and set(v) = wv <- v
  177.   member this.VW with get() = vw and set(v) = vw <- v
  178.  
  179.   member this.Clone() =
  180.     let ret = VWCoordinates()
  181.     ret.WV <- wv.Clone()
  182.     ret.VW <- vw.Clone()
  183.     ret
  184.  
  185.   member this.Multiply(m:VWCoordinates, ?order:Drawing2D.MatrixOrder) =
  186.     let wo = match order with Some(Drawing2D.MatrixOrder.Append) -> Drawing2D.MatrixOrder.Append | _ -> Drawing2D.MatrixOrder.Prepend
  187.     let vo = match order with Some(Drawing2D.MatrixOrder.Prepend) -> Drawing2D.MatrixOrder.Prepend | _ -> Drawing2D.MatrixOrder.Append
  188.     wv.Multiply(m.WV, wo)
  189.     vw.Multiply(m.VW, vo)
  190.  
  191.   member this.Rotate(a:single) =
  192.     wv.Rotate(a)
  193.     vw.Rotate(-a, Drawing2D.MatrixOrder.Append)
  194.  
  195.   member this.RotateAt(a:single, p:PointF) =
  196.     wv.RotateAt(a, p)
  197.     vw.RotateAt(-a, p, Drawing2D.MatrixOrder.Append)
  198.  
  199.   member this.Translate(tx:single, ty:single) =
  200.     wv.Translate(tx, ty)
  201.     vw.Translate(-tx, -ty, Drawing2D.MatrixOrder.Append)
  202.  
  203.   member this.Scale(sx:single, sy:single) =
  204.     wv.Scale(sx, sy)
  205.     vw.Scale(1.f / sx, 1.f / sy, Drawing2D.MatrixOrder.Append)
  206.  
  207.   member this.TransformPointVW (p:Point) =
  208.     let toPointF (p:Point) = PointF(single p.X, single p.Y)
  209.     let a = [| p |> toPointF |]
  210.     this.VW.TransformPoints(a)
  211.     a.[0]
  212.   member this.FTransformPointVW(p:PointF) =
  213.     let a = [| p |]
  214.     this.VW.TransformPoints(a)
  215.     a.[0]
  216.  
  217.   member this.ScaleAtV(sx:single, sy: single, cv:Point) =
  218.       let cw = cv |> this.TransformPointVW
  219.       this.Scale(sx, sy)
  220.       let cwp = cv |> this.TransformPointVW
  221.       this.Translate(cwp.X - cw.X, cwp.Y - cw.Y)
  222. //fine classe Coordinate Vista Mondo.
  223.  
  224. ///PALLINE RIMBALZINE ///////////////////////////////////////////////////////////////////////////////
  225. type BouncingBall() =
  226.   let mutable location = PointF()
  227.   let mutable speed = SizeF(10.f,10.f) // px/s
  228.   let mutable lastT = System.DateTime.Now
  229. //  let mutable mass = 1.f
  230.   let mutable size = SizeF(1.f,1.f)// la size del rettangolo che contiene la pallina
  231.   let mutable precLocation = PointF()
  232.  
  233. //  let matrix = VWCoordinates()
  234. //  let transformPointVW p = matrix.TransformPointVW(p)
  235.  
  236.   member this.Location with get() = location and set(v) = location <- v
  237.   member this.Speed with get() = speed and set(v) = speed <- v
  238.   member this.Size with get() = size and set(v) = size <- v
  239.   member this.Bounds = new RectangleF(location, size)
  240.   member this.CenterLocation with get() = PointF(location.X + size.Width / 2.f, location.Y + size.Height / 2.f)
  241.  
  242.   member this.Region with get() = new Region(this.Bounds)
  243.   member this.PrecPos with get() = precLocation and set(v) = precLocation <- v
  244.  
  245. //  member this.Mass with get() = mass and set(v) = mass <- v
  246.  
  247.   member this.UpdateSpeed(balls:BouncingBall seq, rectangles:RectangleF seq) = //aggiorna le velocità a restituisce una coppia, NB Speed è una size fatta da una componente x e una y
  248.     let vb (b:BouncingBall, r:RectangleF) (vx : single, vy : single) =
  249.       let ct, cb = this.CenterLocation, b.CenterLocation
  250. //      let cr = PointF(r.Location.X + r.Size.Width / 2.f, r.Location.Y + r.Size.Height / 2.f) // centro dei rettangoli
  251.       let cx, cy = cb.X - ct.X, cb.Y - ct.Y
  252.       let sp = cx*vx + cy*vy
  253.       let cr, vr = sqrt(cx*cx + cy*cy), sqrt(vx*vx+vy*vy)
  254.       let cosa = sp / (cr*vr)
  255.       let sina = sqrt(1.f - cosa*cosa)
  256.       let vtb, votb = - vr * cosa, vr * sina
  257.       let beta = atan2 cy  cx
  258.       let pi = single(System.Math.PI)
  259.       let vtbx, vtby = vtb * cos(beta), vtb * sin(beta)
  260.       let votbx, votby = votb * cos(pi / 2.f - beta), votb * sin(pi / 2.f - beta)
  261.       (votbx + vtbx, votby + vtby)
  262.    
  263.     for b in balls do     // per ogni pallina che non è sè stessa e che collide, aggiorna la velocità
  264.         for r in rectangles do
  265.           if b <> this && (this.CollideWithBalls(b) || this.CollideWithRect(this, r)) then
  266.             let vx, vy = vb (b, r) (speed.Width, speed.Height)
  267.             speed <- SizeF(vx, vy)
  268.  
  269.   member this.UpdatePosition() =   //aggiorna la posizione e il tempo al quale è stata aggiornata
  270.     let t = System.DateTime.Now
  271.     let dt = t - lastT
  272.     let vx = speed.Width / 1000.f
  273.     let vy = speed.Height / 1000.f
  274.     let dx = vx * single(dt.TotalMilliseconds)
  275.     let dy = vy * single(dt.TotalMilliseconds)
  276. //    let rnd = new System.Random()
  277.     precLocation <- location
  278.     location <- PointF(location.X + dx, location.Y + dy)
  279.     //location <- PointF(location.X + single(rnd.NextDouble()) * dx, location.Y + single(rnd.NextDouble()) * dy)
  280.     //location <- PointF(single(rnd.NextDouble()) * 50.f, single(rnd.NextDouble()) * 50.f)
  281.     lastT <- t
  282.  
  283.   member this.CollideWithBalls (b:BouncingBall) =
  284.     let sqdist (p1:PointF) (p2:PointF) =
  285.       let dx, dy = p1.X - p2.X, p1.Y - p2.Y
  286.       dx * dx + dy * dy
  287.     let c1, c2 = this.CenterLocation, b.CenterLocation
  288.     let d1, d2 = this.Size.Width / 2.f, b.Size.Width / 2.f
  289.     sqdist c1 c2 <= (d1 + d2)*(d1 + d2)
  290.  
  291.   //collision con rettangoli
  292.   member this.CollideWithRect (b:BouncingBall, r: RectangleF) =
  293.     let sqdist (p1:PointF) (p2:PointF) =
  294.       let dx, dy = p1.X - p2.X, p1.Y - p2.Y
  295.       dx * dx + dy * dy
  296.     let cball = b.CenterLocation
  297.     let crect = PointF(r.Location.X + r.Size.Width / 2.f, r.Location.Y + r.Size.Height / 2.f)
  298.     let rwidth, bwidht = r.Size.Width / 2.f, b.Size.Width / 2.f
  299.     //caso ovvio che la pallina entri dentro il rettangolo
  300.     sqdist cball crect <= rwidth*rwidth
  301.  
  302. ////////////FINE CLASSE PALLINE RIMBALZINE
  303.  
  304. //Dichiarazione del mio sistema di coordinate
  305. type CollisionTester() as this =
  306.   inherit LWContainer()
  307.  
  308.   let balls = new ResizeArray<BouncingBall>()
  309.   let rectangles = ResizeArray<RectangleF>()
  310.  
  311.  
  312. //  do balls.Add(new BouncingBall(Location=PointF(20.f, 30.f), Speed=SizeF(30.f, 30.f))) // do serve per dichiarare uno statement, in questo caso aggiunge una pallina al buffer
  313. //  let updateBalls() =
  314. //    balls |> Seq.iter (fun b ->
  315. //      b.UpdatePosition() // Per la collision detection
  316. //      b.UpdateSpeed(balls, rectangles)
  317. //      if b.Location.X < 0.f || b.Location.X + b.Size.Width > single(this.Width) then
  318. //        b.Speed <- SizeF(- b.Speed.Width, b.Speed.Height)
  319. //      if b.Location.Y < 0.f || b.Location.Y + b.Size.Height > single(this.Height) then
  320. //        b.Speed <- SizeF(b.Speed.Width, - b.Speed.Height)
  321. //    )
  322.  
  323.   let computeExit (me:BouncingBall) (other:RectangleF) =
  324.     if me.CenterLocation.X > other.Left && me.CenterLocation.X < other.Right then
  325.         if abs (me.CenterLocation.Y - other.Bottom) < abs (me.CenterLocation.Y - other.Top) then
  326.             me.Location <- PointF(me.Location.X, me.Location.Y + abs(me.Location.Y - other.Bottom) + 2.f)
  327.             me.PrecPos <- me.Location
  328.         else
  329.             me.Location <- PointF(me.Location.X, me.Location.Y - abs(me.Location.Y - other.Top) - 2.f)
  330.             me.PrecPos <- me.Location
  331.  
  332.     else if me.CenterLocation.Y > other.Top && me.CenterLocation.Y < other.Bottom then
  333.         if abs (me.CenterLocation.X - other.Left) < abs (me.CenterLocation.X - other.Right) then
  334.             me.Location <- PointF(me.Location.X - abs(me.Location.X - other.Left) - 2.0f, me.Location.Y)
  335.             me.PrecPos <- me.Location
  336.         else
  337.             me.Location <- PointF(me.Location.X + abs(me.Location.X - other.Right) + 2.f, me.Location.Y)
  338.             me.PrecPos <- me.Location
  339.  
  340.    
  341.  
  342.   let computeCollisionRect (me:BouncingBall) (other:RectangleF) =
  343.         if me.Region.IsVisible other then
  344.             computeExit me other
  345.             me.Location <- me.PrecPos + SizeF(me.Speed.Width, -me.Speed.Height)
  346.             me.Speed <- SizeF(me.Speed.Width, -me.Speed.Height)
  347.  
  348.             if me.Region.IsVisible other then
  349.                 me.Speed <- SizeF(-me.Speed.Width, me.Speed.Height)
  350.  
  351.             me.Location <- me.PrecPos
  352.  
  353.   let computeCollisionBall (me:BouncingBall) (other:BouncingBall) =
  354.         if me.Region.IsVisible other.Bounds then
  355.             me.Location <- me.PrecPos + SizeF(me.Speed.Width, -me.Speed.Height)
  356.             me.Speed <- SizeF(me.Speed.Width, -me.Speed.Height)
  357.  
  358.             if me.Region.IsVisible other.Bounds then
  359.                 me.Speed <- SizeF(-me.Speed.Width, me.Speed.Height)
  360.  
  361.             me.Location <- me.PrecPos
  362.  
  363.   let updateBalls() =
  364.     for me in balls do
  365.         me.UpdatePosition()
  366.         for other in balls do
  367.             if me <> other then computeCollisionBall me other
  368.         for other in rectangles do
  369.             computeCollisionRect me other
  370.  
  371.     ()
  372. //inizio dell'animazione
  373.   let t = new Timer(Interval=10)
  374.   do
  375.     t.Tick.Add(fun _  ->
  376.       updateBalls()
  377.       this.Invalidate()
  378.     )
  379.     t.Start()
  380.  //fine dell'animazione
  381.   let mutable bip : BouncingBall option = None
  382.   let mutable mousePos = PointF()
  383.  
  384.   //Dichiaro come costruire rettangoli e punti  
  385.   let toRectangle (r:RectangleF) = Rectangle(int r.X, int r.Y, int r.Width, int r.Height)
  386.   let toPointF (p:Point) = PointF(single p.X, single p.Y)
  387.  
  388.   let mkRectangleF(p1:PointF, p2:PointF) =
  389.     let x1, y1 = min p1.X p2.X, min p1.Y p2.Y
  390.     let x2, y2 = max p1.X p2.X, max p1.Y p2.Y
  391.     RectangleF(x1, y1, x2 - x1, y2 - y1)
  392.  
  393.   let mutable dragStart = None
  394.   let mutable position = PointF()
  395.  
  396.   //creo i bottoni
  397.   let up = RoundButton(Text="Up",Parent=this,Location=PointF(50.f, 0.f), Size=SizeF(35.f, 35.f))
  398.   let left = RoundButton(Text="Left",Parent=this,Location=PointF(0.f, 50.f), Size=SizeF(35.f, 35.f))
  399.   let right = RoundButton(Text="Right",Parent=this,Location=PointF(100.f, 50.f), Size=SizeF(35.f, 35.f))
  400.   let down = RoundButton(Text="Down",Parent=this,Location=PointF(50.f, 100.f), Size=SizeF(35.f, 35.f))
  401.   let rotateLeft = RoundButton(Text="RtLeft",Parent=this,Location=PointF(20.f, 150.f), Size=SizeF(40.f, 40.f))
  402.   let rotateRight = RoundButton(Text="RtRight",Parent=this,Location=PointF(70.f, 150.f), Size=SizeF(40.f, 40.f))
  403.   let zoomIn = RoundButton(Text="+",Parent=this,Location=PointF(45.f, 60.f), Size=SizeF(20.f, 20.f))
  404.   let zoomOut = RoundButton(Text="-",Parent=this,Location=PointF(70.f, 60.f), Size=SizeF(20.f, 20.f))
  405.   let createRect = RectButton(Text="Create Rect", Parent=this,Location=PointF(20.f, 200.f), Size=SizeF(90.f, 40.f))
  406.   let createCirc = RectButton(Text="Create Circ", Parent=this,Location=PointF(20.f, 260.f), Size=SizeF(90.f, 40.f))
  407.   let selectionTool = RectButton(Text="Selection Tool",Parent=this,Location=PointF(20.f, 340.f), Size=SizeF(90.f, 40.f))
  408.  
  409.  
  410.   let mutable rectornot : bool = true
  411.   let mutable circornot : bool = false
  412.   let mutable selectornot : bool = false
  413.  
  414.   let mat = VWCoordinates()
  415.   let transformPointVW p = mat.TransformPointVW(p)
  416.   // definisco i comportamenti dei bottoni
  417.   do
  418.     this.SetStyle(ControlStyles.AllPaintingInWmPaint ||| ControlStyles.OptimizedDoubleBuffer, true)//get rid of flickering
  419.  
  420.     this.LWControls.AddRange([| up; left; right; down; rotateLeft; rotateRight; zoomIn; zoomOut; createRect; createCirc; selectionTool |])
  421.     up.MouseDown.Add(fun _ -> mat.Translate(0.f, 10.f); up.MouseEventHandled <- true; this.Invalidate())
  422.     left.MouseDown.Add(fun _ -> mat.Translate(10.f, 0.f); up.MouseEventHandled <- true; this.Invalidate())
  423.     right.MouseDown.Add(fun _ -> mat.Translate(-10.f, 0.f); up.MouseEventHandled <- true; this.Invalidate())
  424.     down.MouseDown.Add(fun _ -> mat.Translate(0.f, -10.f); up.MouseEventHandled <- true; this.Invalidate())
  425.     rotateLeft.MouseDown.Add(fun _ -> mat.RotateAt(5.f, Point((this.Width / 2), (this.Height / 2)) |> transformPointVW); this.Invalidate())
  426.     rotateRight.MouseDown.Add(fun _ -> mat.RotateAt(-5.f, Point((this.Width / 2), (this.Height / 2)) |> transformPointVW); this.Invalidate())
  427.     zoomIn.MouseDown.Add(fun _ -> mat.ScaleAtV(1.1f, 1.1f, Point(this.Width / 2, this.Height / 2)); this.Invalidate())
  428.     zoomOut.MouseDown.Add(fun _ -> mat.ScaleAtV(1.f / 1.1f, 1.f / 1.1f, Point(this.Width / 2, this.Height / 2)); this.Invalidate())
  429.     createRect.MouseDown.Add(fun _ ->
  430.        match rectornot with
  431.         | true -> ()
  432.         | false -> circornot <- false; selectornot <- false; rectornot <- true
  433.        createRect.MouseEventHandled <- true; this.Invalidate())
  434.     createCirc.MouseDown.Add(fun _ ->
  435.        match circornot with
  436.         | true -> ()
  437.         | false -> rectornot <- false; selectornot <- false; circornot <- true
  438.        createCirc.MouseEventHandled <- true; this.Invalidate())
  439.     selectionTool.MouseDown.Add(fun _ ->
  440.        match selectornot with
  441.         | true -> ()
  442.         | false -> rectornot <- false; circornot <- false; selectornot <- true
  443.        selectionTool.MouseEventHandled <- true; this.Invalidate())
  444.  
  445.   // timer per aumeto massa
  446.   let updateMass() =
  447.     match bip with
  448.         | Some(b) -> b.Size <- SizeF(b.Size.Width*1.1f, b.Size.Height*1.1f)
  449.         | _ -> ()
  450.   let masstimer = new Timer(Interval=30)
  451.  
  452.   let mutable count = 0
  453.   do
  454.     masstimer.Tick.Add(fun _  ->
  455.       updateMass()
  456.       this.Invalidate()
  457.     )
  458.     masstimer.Start()
  459. //  let y = Screen.PrimaryScreen.Bounds.Bottom - this.Height;
  460.  
  461. // disegno un puntatore che mi indica il centro della vista
  462.   override this.OnPaint e =
  463.     let g = e.Graphics
  464.     let initTransform = g.Transform
  465. //    let currentTransform = g.Transform
  466.     g.DrawLine(Pens.Black, this.Width / 2 - 10, this.Height / 2, this.Width / 2 + 10, this.Height / 2)
  467.     g.DrawLine(Pens.Black, this.Width / 2, this.Height / 2 - 10, this.Width / 2, this.Height / 2 + 10)
  468.  
  469.     g.Transform <- mat.WV
  470.     for r in rectangles do
  471.       g.DrawRectangle(Pens.Black, r |> toRectangle)
  472.  
  473.     if dragStart.IsSome then
  474.       let r = mkRectangleF(dragStart.Value |> mat.FTransformPointVW, position) |> toRectangle
  475.       g.DrawRectangle(Pens.Red, r)
  476.    
  477.    
  478.     // palline //////////////////////////////////
  479.     let paintball (b : BouncingBall) =
  480.       let r = b.Bounds
  481.       g.FillEllipse(Brushes.Blue, r)
  482.       g.DrawEllipse(Pens.DarkBlue, r)
  483.  
  484.     balls |> Seq.iter paintball
  485.    
  486. //    g.Transform <- initTransform
  487.  
  488.     // sto disegnando una pallina
  489.     match bip with
  490.     | Some b ->
  491.       use p = new Pen(Brushes.Black)
  492.       p.EndCap <- Drawing2D.LineCap.ArrowAnchor
  493.       g.DrawLine(p, PointF(b.Location.X + b.Size.Width / 2.f, b.Location.Y + b.Size.Height / 2.f), mousePos|> mat.FTransformPointVW)
  494.       paintball b
  495.     | None -> ()
  496.        
  497.     g.Transform <- initTransform
  498.     base.OnPaint(e)
  499.  
  500.   override this.OnMouseDown e =
  501.     base.OnMouseDown e
  502.     if not(this.LWMouseEventHandled) then
  503.       if rectornot then dragStart <- Some(e.Location |> mat.TransformPointVW)
  504.       else if circornot then
  505.             let b = BouncingBall()
  506.             mousePos <- e.Location |> mat.TransformPointVW
  507.             b.Location <- PointF(single(e.X) - b.Size.Width / 2.f, single(e.Y) - b.Size.Height / 2.f) |> mat.FTransformPointVW
  508.             bip <- Some(b)
  509.             this.Invalidate()
  510.        else ()//fai select
  511.  
  512.  
  513.   override this.OnMouseMove e =
  514.     base.OnMouseMove e
  515.     count <- count+1
  516.     if not(this.LWMouseEventHandled) then
  517.       if rectornot && dragStart.IsSome then position <- e.Location |> mat.TransformPointVW; this.Invalidate()
  518.       else if circornot then
  519.         match bip with
  520.             | Some b ->
  521.               mousePos <- PointF(single(e.X), single(e.Y))
  522.               if(count%5 = 0) then
  523.                 this.Invalidate()
  524.             | None -> ()
  525.       else ()//fai select
  526.  
  527.   override this.OnMouseUp e =
  528.     base.OnMouseUp e
  529.     if not(this.LWMouseEventHandled)  then
  530.       if rectornot && dragStart.IsSome then
  531.           position <- e.Location |> mat.TransformPointVW
  532.           rectangles.Add(mkRectangleF(dragStart.Value, position))
  533.           dragStart <- None
  534.           this.Invalidate()
  535.       else if circornot then
  536.           match bip with
  537.             | Some b ->
  538.               let x0, y0 = b.Location.X + b.Size.Width / 2.f, b.Location.Y + b.Size.Height / 2.f
  539.               let x1,y1  = PointF(single(e.X), single(e.Y)) |> mat.FTransformPointVW |> (fun p -> (p.X, p.Y))
  540.               b.Speed <- SizeF((x1 - x0) / 2.f, (y1 - y0) / 2.f)
  541.               balls.Add(b)
  542.               bip <- None
  543.               this.Invalidate()
  544.             | None -> ()
  545.       else ()//fai select
  546.  
  547. let c = new CollisionTester(Dock=DockStyle.Fill)
  548. f.Controls.Add(c)
  549.  
  550. c.Focus()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement