Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #load "textEdLwc.fsx"
- open System.Windows.Forms
- open System.Drawing
- open TextEdLwc
- // Riprendo il bottone implementato a lezione
- type PIButton() =
- inherit LWControl()
- let mutable text = ""
- member this.SetText str =
- text <- str
- str
- member this.Text
- with get() = text
- and set(v) = text <- v
- override this.OnPaint e =
- let parent = this.Parent
- let g = e.Graphics
- let r = RectangleF(this.Position, this.Size) |> RectF2Rect
- g.DrawRectangle(Pens.Red, r)
- let ssz = g.MeasureString(text, parent.Font)
- let p = this.Position
- let sz = this.Size
- let sx, sy = p.X + (sz.Width - ssz.Width) / 2.f, p.Y + (sz.Height - ssz.Height) / 2.f
- g.DrawString(text, parent.Font, Brushes.Red, PointF(sx, sy))
- // Istanzio la lista di font
- let FontArray = ResizeArray<Font>()
- FontArray.Add(new Font(FontFamily.GenericSansSerif, 16.0f))
- FontArray.Add(new Font(FontFamily.GenericSerif, 16.0f))
- let mutable curFontIndex = 0
- let transformPoint (m:Drawing2D.Matrix) (p:PointF) =
- let pts = [| p |]
- m.TransformPoints(pts)
- pts.[0]
- // Funzione per trovare il font della dimensione adatta
- let FindFont (g : Graphics) (str : string) (box : SizeF) (preferredfont : Font) =
- let stringsize = g.MeasureString(str, preferredfont)
- let scaleRatio = min (box.Height / stringsize.Height) (box.Width / stringsize.Width)
- let scalefontsize = scaleRatio * preferredfont.Size
- new Font(preferredfont.FontFamily, float32 scalefontsize)
- type PIGlyph(lf:Font) =
- inherit LWControl()
- let mutable letter = 'A'
- let mutable letterSize = 12.0f
- let mutable drag = None
- let letterfont = lf
- member this.Drag
- with get() = drag
- and set(v) = drag <- v
- member this.Lettera
- with get() = letter
- and set(v) = letter <- v
- member this.LetterSize
- with get() = letterSize
- and set(v) = letterSize <- v
- override this.OnPaint e =
- let parent = this.Parent
- let g = e.Graphics
- let t = g.Transform
- let r = RectangleF(this.Position, this.Size) |> RectF2Rect
- // Creo la nuova vista
- let newt = g.Transform
- newt.RotateAt(-this.Angle, PointF(this.Position.X + this.Size.Width /2.f, this.Position.Y + this.Size.Height /2.f))
- g.Transform <- newt
- g.DrawRectangle(Pens.DarkGreen, r)
- let fittingfont = FindFont g (string letter) this.Size letterfont
- let ssz = g.MeasureString(string letter, fittingfont)
- let p = this.Position
- let sz = this.Size
- let sx, sy = p.X + (sz.Width - ssz.Width) / 2.f, p.Y + (sz.Height - ssz.Height) / 2.f
- g.DrawString(string letter, fittingfont, Brushes.Black, PointF(sx, sy))
- // Ripristino le coordinate
- g.Transform <- t
- override this.HitTest p e=
- let prodottoScalare (p1 : PointF) (p2 : PointF) =
- p1.X * p2.X + p1.Y * p2.Y
- let gradiARadianti (a: float) =
- a * System.Math.PI / float 180
- let puntoRuotato (p : PointF) (c : PointF) (ang : float32) =
- let a = float32 (gradiARadianti (float ang))
- let xr = (cos a) * (p.X - c.X) - (sin a) * (p.Y - c.Y) + c.X
- let yr = (sin a) * (p.X - c.X) + (cos a) * (p.Y - c.Y) + c.Y
- PointF(xr, yr)
- let differenzaVettoriale (p1 : PointF) (p2 : PointF) =
- PointF(p2.X - p1.X, p2.Y - p1.Y)
- // Trovo i vertici del rettangolo dritto:
- let A, B, C, D = this.Position, this.Position + SizeF(this.Size.Width, 0.f), this.Position + this.Size, this.Position + SizeF(0.f, this.Size.Height)
- // Trovo i vertici ruotati
- let c = this.Position + SizeF(this.Size.Width/2.f, this.Size.Height/2.f)
- let A1, B1, C1, D1 = (puntoRuotato A c -this.Angle), (puntoRuotato B c -this.Angle), (puntoRuotato C c -this.Angle), (puntoRuotato D c -this.Angle)
- let M = PointF(float32 p.X, float32 p.Y)
- // Calcolo i vettori necessari
- let AM, AB, AD = differenzaVettoriale A1 M, differenzaVettoriale A1 B1, differenzaVettoriale A1 D1
- // Calcolo i prodotti scalari
- let AMAB, ABAB, AMAD, ADAD = (prodottoScalare AM AB), (prodottoScalare AB AB), (prodottoScalare AM AD), (prodottoScalare AD AD)
- // Controllo la posizione
- 0.f < AMAB && AMAB < ABAB && 0.f < AMAD && AMAD < ADAD
- (* // METODO BASATO SUI TRIANGOLI
- let gradiARadianti (a: float) =
- a * System.Math.PI / float 180
- let puntoRuotato (p : PointF) (c : PointF) (ang : float32) =
- let a = float32 (gradiARadianti (float ang))
- let xr = (cos a) * (p.X - c.X) - (sin a) * (p.Y - c.Y) + c.X
- let yr = (sin a) * (p.X - c.X) + (cos a) * (p.Y - c.Y) + c.Y
- PointF(xr, yr)
- let sign (p1: PointF) (p2: PointF) (p3: PointF) =
- (p1.X - p3.X) * (p2.Y - p3.Y) - (p2.X - p3.X) * (p1.Y - p3.Y)
- let puntoInTriangolo (pt: PointF) (v1: PointF) (v2: PointF) (v3: PointF) =
- let b1 = ((sign pt v1 v2) < 0.0f)
- let b2 = ((sign pt v2 v3) < 0.0f)
- let b3 = ((sign pt v3 v1) < 0.0f)
- b1 = b2 && b2 = b3
- // Calcolo i vertici del rettangolo ruotato
- // Vertici originali
- let A, B, C, D = this.Position, this.Position + SizeF(this.Size.Width, 0.f), this.Position + this.Size, this.Position + SizeF(0.f, this.Size.Height)
- let c = this.Position + SizeF(this.Size.Width/2.f, this.Size.Height/2.f)
- // Vertici ruotati
- let A1, B1, C1, D1 = (puntoRuotato A c -this.Angle), (puntoRuotato B c -this.Angle), (puntoRuotato C c -this.Angle), (puntoRuotato D c -this.Angle)
- let M = PointF(float32 e.X, float32 e.Y)
- // Controllo se il punto cade in uno de due triangoli
- (puntoInTriangolo M A1 B1 C1) || (puntoInTriangolo M A1 D1 C1)
- *)
- override this.OnMouseDown e =
- let parent = this.Parent
- match parent with
- | :? LWContainer as par ->
- let mp = transformPoint par.Transformations.V2W (PointF(single(e.X), single(e.Y)))
- drag <- Some (mp.X - this.Position.X, mp.Y - this.Position.Y)
- | _ -> ()
- override this.OnMouseMove e =
- let parent = this.Parent
- match parent with
- | :? LWContainer as par ->
- let mp = transformPoint par.Transformations.V2W (PointF(single(e.X), single(e.Y)))
- match drag with
- | Some (dx, dy) ->
- this.Position <- PointF(mp.X - dx, mp.Y - dy)
- this.Parent.Invalidate()
- | None -> ()
- | _ -> ()
- override this.OnMouseUp e =
- drag <- None
- // Creo la form contenente i controlli
- let fin = new Form()
- // Implemento il container
- let container = new LWContainer(Dock=DockStyle.Fill)
- fin.Controls.Add(container)
- let addLwc2Container (container:LWContainer) (contr:LWControl) =
- contr.Parent <- container
- container.LWControls.Add(contr)
- // Dichiarazioni per il calcolo della posizione dei controlli
- let buttonPadding = 2
- let buttonSide = 30
- let btnNumberToPosition num =
- let xpos = buttonPadding + (num % 3)*(buttonSide + buttonPadding)
- let ypos = buttonPadding + (num / 3)*(buttonSide + buttonPadding)
- PointF(float32 xpos, float32 ypos)
- let squaredBtnSize side =
- SizeF(float32 side, float32 side)
- let mutable letteraSelezionata : string = "A"
- let startScrolling dir _ =
- container.ScrollDir <- dir
- container.ScrollTimer.Start()
- let startRotating dir _ =
- container.RotateDir <- dir
- container.RotateTimer.Start()
- let startScaling dir _ =
- container.ScaleDir <- dir
- container.ScaleTimer.Start()
- let fontUp (display : PIButton ) _ =
- curFontIndex <- (curFontIndex + 1) % FontArray.Count
- display.Text <- string curFontIndex
- container.Invalidate()
- let fontDown (display : PIButton ) _ =
- curFontIndex <- (curFontIndex - 1)
- if curFontIndex < 0 then curFontIndex <- FontArray.Count - 1
- display.Text <- string curFontIndex
- container.Invalidate()
- // Implementazione dell'array di glifi
- let GlyphArray = new ResizeArray<PIGlyph>()
- let defaultLetterSize = SizeF(100.f, 100.f)
- let nuovaLettera pos =
- let ltr = PIGlyph(FontArray.[curFontIndex], Position=pos, Size=defaultLetterSize, Lettera=letteraSelezionata.[0], CoordinateType=World)
- ltr.Parent <- container
- addLwc2Container container ltr
- GlyphArray.Add(ltr)
- container.Invalidate()
- pos
- let rimuoviLettera (ltr:LWControl) :unit =
- match ltr with
- | :? PIGlyph as l ->
- ignore (GlyphArray.Remove(l))
- ignore (container.LWControls.Remove(ltr))
- | _ -> ()
- let letterScale = 1.1f
- let letterRotation = 5
- let animationTimer = new Timer(Interval=10)
- do
- animationTimer.Tick.Add(fun _ ->
- for gl in GlyphArray do
- gl.Angle <- (gl.Angle + float32 letterRotation) % float32 360
- container.Invalidate()
- )
- // Istanzio i pulsanti per i controlli vista
- let upButton = PIButton(Position=(btnNumberToPosition 1), Size=squaredBtnSize buttonSide, Text="↑", CoordinateType=View)
- upButton.MouseDown.Add(startScrolling ScrollUp)
- addLwc2Container container upButton
- let downButton = PIButton(Position=(btnNumberToPosition 7), Size=squaredBtnSize buttonSide, Text="↓", CoordinateType=View)
- downButton.MouseDown.Add(startScrolling ScrollDown)
- addLwc2Container container downButton
- let leftButton = PIButton(Position=(btnNumberToPosition 3), Size=squaredBtnSize buttonSide, Text="←", CoordinateType=View)
- leftButton.MouseDown.Add(startScrolling ScrollLeft)
- addLwc2Container container leftButton
- let rightButton = PIButton(Position=(btnNumberToPosition 5), Size=squaredBtnSize buttonSide, Text="→", CoordinateType=View)
- rightButton.MouseDown.Add(startScrolling ScrollRight)
- addLwc2Container container rightButton
- let rotateRightButton = PIButton(Position=(btnNumberToPosition 2), Size=squaredBtnSize buttonSide, Text="R", CoordinateType=View)
- rotateRightButton.MouseDown.Add(startRotating RotateRight)
- addLwc2Container container rotateRightButton
- let rotateLeftButton = PIButton(Position=(btnNumberToPosition 0), Size=squaredBtnSize buttonSide, Text="L", CoordinateType=View)
- rotateLeftButton.MouseDown.Add(startRotating RotateLeft)
- addLwc2Container container rotateLeftButton
- let scaleUpButton = PIButton(Position=(btnNumberToPosition 8), Size=squaredBtnSize buttonSide, Text="+", CoordinateType=View)
- scaleUpButton.MouseDown.Add(startScaling ScaleUp)
- addLwc2Container container scaleUpButton
- let scaleDownButton = PIButton(Position=(btnNumberToPosition 6), Size=squaredBtnSize buttonSide, Text="-", CoordinateType=View)
- scaleDownButton.MouseDown.Add(startScaling ScaleDown)
- addLwc2Container container scaleDownButton
- // Istanzio il quadrato per il display della lettera corrente
- let currentLetterDisplay = PIButton(Position=(btnNumberToPosition 4), Size=squaredBtnSize buttonSide, Text="A", CoordinateType=View)
- addLwc2Container container currentLetterDisplay
- // Istanzio i pulsanti per il controllo delle lettere
- let biggerLetterButton = PIButton(Position=(btnNumberToPosition 12), Size=squaredBtnSize buttonSide, Text="S↑", CoordinateType=View)
- biggerLetterButton.MouseDown.Add(fun _ ->
- let control = container.SelectedControl
- match control with
- | :? PIGlyph as ltr ->
- ltr.Size <- SizeF(letterScale * ltr.Size.Width, letterScale * ltr.Size.Height)
- container.Invalidate()
- | _ -> ()
- )
- addLwc2Container container biggerLetterButton
- let smallerLetterButton = PIButton(Position=(btnNumberToPosition 13), Size=squaredBtnSize buttonSide, Text="S↓", CoordinateType=View)
- smallerLetterButton.MouseDown.Add(fun _ ->
- let control = container.SelectedControl
- match control with
- | :? PIGlyph as ltr ->
- ltr.Size <- SizeF((1.f/letterScale) * ltr.Size.Width, (1.f/letterScale) * ltr.Size.Height)
- container.Invalidate()
- | _ -> ()
- )
- addLwc2Container container smallerLetterButton
- let rotateLeftLetterButton = PIButton(Position=(btnNumberToPosition 15), Size=squaredBtnSize buttonSide, Text="R←", CoordinateType=View)
- rotateLeftLetterButton.MouseDown.Add(fun _ ->
- let control = container.SelectedControl
- match control with
- | :? PIGlyph as ltr ->
- ltr.Angle <- (ltr.Angle + float32 letterRotation) % float32 360
- container.Invalidate()
- | _ -> ()
- )
- addLwc2Container container rotateLeftLetterButton
- let rotateRightLetterButton = PIButton(Position=(btnNumberToPosition 16), Size=squaredBtnSize buttonSide, Text="R→", CoordinateType=View)
- rotateRightLetterButton.MouseDown.Add(fun _ ->
- let control = container.SelectedControl
- match control with
- | :? PIGlyph as ltr ->
- ltr.Angle <- (ltr.Angle - float32 letterRotation)
- if ltr.Angle < 0.f then ltr.Angle <- ltr.Angle + 360.f
- container.Invalidate()
- | _ -> ()
- )
- addLwc2Container container rotateRightLetterButton
- let animateButton = PIButton(Position=(btnNumberToPosition 17), Size=squaredBtnSize buttonSide, Text="Anim", CoordinateType=View)
- animateButton.MouseDown.Add(fun _ ->
- if animationTimer.Enabled then animationTimer.Stop()
- else animationTimer.Start()
- )
- addLwc2Container container animateButton
- let deleteLetterButton = PIButton(Position=(btnNumberToPosition 14), Size=squaredBtnSize buttonSide, Text="Del", CoordinateType=View)
- deleteLetterButton.MouseDown.Add(fun _ ->
- let control = container.SelectedControl
- match control with
- | :? PIGlyph as ltr ->
- rimuoviLettera control
- container.SelectedControl <- LWControl()
- container.Invalidate()
- | _ -> ()
- )
- addLwc2Container container deleteLetterButton
- // Istanzio il pannello dei font
- let currentFontDisplay = PIButton(Position=(btnNumberToPosition 23), Size=squaredBtnSize buttonSide, Text="0", CoordinateType=View)
- addLwc2Container container currentFontDisplay
- let nextFontButton = PIButton(Position=(btnNumberToPosition 21), Size=squaredBtnSize buttonSide, Text="Fo↑", CoordinateType=View)
- nextFontButton.MouseDown.Add(fontUp currentFontDisplay)
- addLwc2Container container nextFontButton
- let prevFontButton = PIButton(Position=(btnNumberToPosition 22), Size=squaredBtnSize buttonSide, Text="Fo↓", CoordinateType=View)
- prevFontButton.MouseDown.Add(fontDown currentFontDisplay)
- addLwc2Container container prevFontButton
- let aggiornaLettera lett =
- letteraSelezionata <- lett
- currentLetterDisplay.Text <- lett
- lett
- container.UpdateLastLetter <- aggiornaLettera
- container.AddNewLetter <- nuovaLettera
- fin.Text <- "Editor Caratteri - Manini Nicolas"
- fin.Show()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement