func drawMoon(canvas gxui.Canvas, center math.Point, radius float32) { c := 40 p := make(gxui.Polygon, c*2) for i := 0; i < c; i++ { frac := float32(i) / float32(c) α := math.Lerpf(math.Pi*1.2, math.Pi*-0.2, frac) p[i] = gxui.PolygonVertex{ Position: math.Point{ X: center.X + int(radius*math.Sinf(α)), Y: center.Y + int(radius*math.Cosf(α)), }, RoundedRadius: 0, } } for i := 0; i < c; i++ { frac := float32(i) / float32(c) α := math.Lerpf(math.Pi*-0.2, math.Pi*1.2, frac) r := math.Lerpf(radius, radius*0.5, math.Sinf(frac*math.Pi)) p[i+c] = gxui.PolygonVertex{ Position: math.Point{ X: center.X + int(r*math.Sinf(α)), Y: center.Y + int(r*math.Cosf(α)), }, RoundedRadius: 0, } } canvas.DrawPolygon(p, gxui.CreatePen(3, gxui.Gray80), gxui.CreateBrush(gxui.Gray40)) }
func drawStar(canvas gxui.Canvas, center math.Point, radius, rotation float32, points int) { p := make(gxui.Polygon, points*2) for i := 0; i < points*2; i++ { frac := float32(i) / float32(points*2) α := frac*math.TwoPi + rotation r := []float32{radius, radius / 2}[i&1] p[i] = gxui.PolygonVertex{ Position: math.Point{ X: center.X + int(r*math.Cosf(α)), Y: center.Y + int(r*math.Sinf(α)), }, RoundedRadius: []float32{0, 50}[i&1], } } canvas.DrawPolygon(p, gxui.CreatePen(3, gxui.Red), gxui.CreateBrush(gxui.Yellow)) }
func (o *BubbleOverlay) Paint(c gxui.Canvas) { if !o.IsVisible() { return } for _, child := range o.outer.Children() { b := child.Bounds().Expand(o.outer.Padding()) t := o.targetPoint a := o.arrowWidth / 2 var p gxui.Polygon switch { case t.X < b.Min.X: /* A-----------------B G | F | E | D-----------------C */ p = gxui.Polygon{ /*A*/ {Position: b.TL(), RoundedRadius: 5}, /*B*/ {Position: b.TR(), RoundedRadius: 5}, /*C*/ {Position: b.BR(), RoundedRadius: 5}, /*D*/ {Position: b.BL(), RoundedRadius: 5}, /*E*/ {Position: math.Point{X: b.Min.X, Y: math.Clamp(t.Y+a, b.Min.Y+a, b.Max.Y)}, RoundedRadius: 0}, /*F*/ {Position: t, RoundedRadius: 0}, /*G*/ {Position: math.Point{X: b.Min.X, Y: math.Clamp(t.Y-a, b.Min.Y, b.Max.Y-a)}, RoundedRadius: 0}, } // fmt.Printf("A: %+v\n", p) case t.X > b.Max.X: /* A-----------------B | C | D | E G-----------------F */ p = gxui.Polygon{ /*A*/ {Position: b.TL(), RoundedRadius: 5}, /*B*/ {Position: b.TR(), RoundedRadius: 5}, /*C*/ {Position: math.Point{X: b.Max.X, Y: math.Clamp(t.Y-a, b.Min.Y, b.Max.Y-a)}, RoundedRadius: 0}, /*D*/ {Position: t, RoundedRadius: 0}, /*E*/ {Position: math.Point{X: b.Max.X, Y: math.Clamp(t.Y+a, b.Min.Y+a, b.Max.Y)}, RoundedRadius: 0}, /*F*/ {Position: b.BR(), RoundedRadius: 5}, /*G*/ {Position: b.BL(), RoundedRadius: 5}, } // fmt.Printf("B: %+v\n", p) case t.Y < b.Min.Y: /* C / \ A-----------B D-E | | | | G-----------------F */ p = gxui.Polygon{ /*A*/ {Position: b.TL(), RoundedRadius: 5}, /*B*/ {Position: math.Point{X: math.Clamp(t.X-a, b.Min.X, b.Max.X-a), Y: b.Min.Y}, RoundedRadius: 0}, /*C*/ {Position: t, RoundedRadius: 0}, /*D*/ {Position: math.Point{X: math.Clamp(t.X+a, b.Min.X+a, b.Max.X), Y: b.Min.Y}, RoundedRadius: 0}, /*E*/ {Position: b.TR(), RoundedRadius: 5}, /*F*/ {Position: b.BR(), RoundedRadius: 5}, /*G*/ {Position: b.BL(), RoundedRadius: 5}, } // fmt.Printf("C: %+v\n", p) default: /* A-----------------B | | | | G-----------F D-C \ / E */ p = gxui.Polygon{ /*A*/ {Position: b.TL(), RoundedRadius: 5}, /*B*/ {Position: b.TR(), RoundedRadius: 5}, /*C*/ {Position: b.BR(), RoundedRadius: 5}, /*D*/ {Position: math.Point{X: math.Clamp(t.X+a, b.Min.X+a, b.Max.X), Y: b.Max.Y}, RoundedRadius: 0}, /*E*/ {Position: t, RoundedRadius: 0}, /*F*/ {Position: math.Point{X: math.Clamp(t.X-a, b.Min.X, b.Max.X-a), Y: b.Max.Y}, RoundedRadius: 0}, /*G*/ {Position: b.BL(), RoundedRadius: 5}, } // fmt.Printf("D: %+v\n", p) } c.DrawPolygon(p, o.pen, o.brush) } o.PaintChildren.Paint(c) }