From b9f2e0fb41c008c222d50f8ab754aa1ad76dd18f Mon Sep 17 00:00:00 2001 From: Egon Elbre Date: Sat, 13 Mar 2021 14:46:46 +0200 Subject: [PATCH] widget/material: use clip.Circle to draw circles Signed-off-by: Egon Elbre --- widget/material/checkable.go | 22 ++++++-------------- widget/material/slider.go | 15 ++++++-------- widget/material/switch.go | 40 ++++++++++++++++-------------------- 3 files changed, 30 insertions(+), 47 deletions(-) diff --git a/widget/material/checkable.go b/widget/material/checkable.go index 8fca34e6..38c0563f 100644 --- a/widget/material/checkable.go +++ b/widget/material/checkable.go @@ -5,7 +5,6 @@ package material import ( "image" "image/color" - "math" "gioui.org/f32" "gioui.org/internal/f32color" @@ -52,10 +51,12 @@ func (c *checkable) layout(gtx layout.Context, checked, hovered bool) layout.Dim background := f32color.MulAlpha(c.IconColor, 70) - var p clip.Path - p.Begin(gtx.Ops) - addCircle(&p, float32(size)/2) - paint.FillShape(gtx.Ops, background, clip.Outline{Path: p.End()}.Op()) + radius := float32(size) / 2 + paint.FillShape(gtx.Ops, background, + clip.Circle{ + Center: f32.Point{X: radius, Y: radius}, + Radius: radius, + }.Op(gtx.Ops)) return dims }), @@ -85,14 +86,3 @@ func (c *checkable) layout(gtx layout.Context, checked, hovered bool) layout.Dim pointer.Rect(image.Rectangle{Max: dims.Size}).Add(gtx.Ops) return dims } - -// addCircle adds the outline of a circle to a path. -func addCircle(p *clip.Path, r float32) { - // https://pomax.github.io/bezierinfo/#circles_cubic. - const c = 4 * (math.Sqrt2 - 1) / 3 // 4*(sqrt(2)-1)/3 - p.Move(f32.Point{X: 2 * r, Y: 2*r - r}) - p.Cube(f32.Point{X: 0, Y: r * c}, f32.Point{X: -r + r*c, Y: r}, f32.Point{X: -r, Y: r}) - p.Cube(f32.Point{X: -r * c, Y: 0}, f32.Point{X: -r, Y: -r + r*c}, f32.Point{X: -r, Y: -r}) - p.Cube(f32.Point{X: 0, Y: -r * c}, f32.Point{X: r - r*c, Y: -r}, f32.Point{X: r, Y: -r}) - p.Cube(f32.Point{X: r * c, Y: 0}, f32.Point{X: r, Y: r - r*c}, f32.Point{X: r, Y: r}) -} diff --git a/widget/material/slider.go b/widget/material/slider.go index 6617fbca..b65bb2b4 100644 --- a/widget/material/slider.go +++ b/widget/material/slider.go @@ -6,6 +6,7 @@ import ( "image" "image/color" + "gioui.org/f32" "gioui.org/internal/f32color" "gioui.org/layout" "gioui.org/op" @@ -83,16 +84,12 @@ func (s SliderStyle) Layout(gtx layout.Context) layout.Dimensions { st.Load() // Draw thumb. - st = op.Save(gtx.Ops) pt := axis.Convert(image.Pt(thumbPos, sizeCross/2)) - rpt := image.Pt(thumbRadius, thumbRadius) - thumb := image.Rectangle{ - Min: pt.Sub(rpt), - Max: pt.Add(rpt), - } - clip.UniformRRect(layout.FRect(thumb), float32(thumbRadius)).Add(gtx.Ops) - paint.Fill(gtx.Ops, color) - st.Load() + paint.FillShape(gtx.Ops, color, + clip.Circle{ + Center: f32.Point{X: float32(pt.X), Y: float32(pt.Y)}, + Radius: float32(thumbRadius), + }.Op(gtx.Ops)) return layout.Dimensions{Size: size} } diff --git a/widget/material/switch.go b/widget/material/switch.go index 99f75a25..a9c4ff4b 100644 --- a/widget/material/switch.go +++ b/widget/material/switch.go @@ -88,30 +88,34 @@ func (s SwitchStyle) Layout(gtx layout.Context) layout.Dimensions { op.Offset(f32.Point{X: float32(off)}).Add(gtx.Ops) } + thumbRadius := float32(thumbSize) / 2 + // Draw hover. if s.Switch.Hovered() { - var p clip.Path - r := 1.7 * float32(thumbSize) / 2 - p.Begin(gtx.Ops) - //p.Move(f32.Pt(-float32(thumbSize)/2, -float32(thumbSize)/2)) - p.Move(f32.Pt(-r+float32(thumbSize)/2, -r+float32(thumbSize)/2)) - addCircle(&p, r) + r := 1.7 * thumbRadius background := f32color.MulAlpha(s.Color.Enabled, 70) - paint.FillShape(gtx.Ops, background, clip.Outline{Path: p.End()}.Op()) + paint.FillShape(gtx.Ops, background, + clip.Circle{ + Center: f32.Point{X: thumbRadius, Y: thumbRadius}, + Radius: r, + }.Op(gtx.Ops)) } // Draw thumb shadow, a translucent disc slightly larger than the // thumb itself. - shadowStack := op.Save(gtx.Ops) - shadowSize := float32(2) // Center shadow horizontally and slightly adjust its Y. - op.Offset(f32.Point{X: -shadowSize / 2, Y: -.75}).Add(gtx.Ops) - drawDisc(gtx.Ops, float32(thumbSize)+shadowSize, argb(0x55000000)) - shadowStack.Load() + paint.FillShape(gtx.Ops, argb(0x55000000), + clip.Circle{ + Center: f32.Point{X: thumbRadius, Y: thumbRadius + .25}, + Radius: thumbRadius + 1, + }.Op(gtx.Ops)) // Draw thumb. - drawDisc(gtx.Ops, float32(thumbSize), col) - stack.Load() + paint.FillShape(gtx.Ops, col, + clip.Circle{ + Center: f32.Point{X: thumbRadius, Y: thumbRadius}, + Radius: thumbRadius, + }.Op(gtx.Ops)) // Set up click area. stack = op.Save(gtx.Ops) @@ -130,11 +134,3 @@ func (s SwitchStyle) Layout(gtx layout.Context) layout.Dimensions { dims := image.Point{X: trackWidth, Y: thumbSize} return layout.Dimensions{Size: dims} } - -func drawDisc(ops *op.Ops, sz float32, col color.NRGBA) { - defer op.Save(ops).Load() - rr := sz / 2 - clip.UniformRRect(f32.Rectangle{Max: f32.Pt(sz, sz)}, rr).Add(ops) - paint.ColorOp{Color: col}.Add(ops) - paint.PaintOp{}.Add(ops) -}