mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-01 15:45:38 +00:00
bd1ef92dc4
In a discussion with Raph Levien, the author of our compute renderer implementation, it became clear to me that it's not at all certain that complex strokes will ever be efficiently supported by a GPU renderer. At the same time, the machinery for converting a complex stroke to a GPU-friendly outline has a significant maintenance cost. Further, it is surprising to users that complex strokes are significantly slower and allocate memory. This change removes support for complex strokes, leaving only round-capped, round-joined strokes supported by the compute renderer. The default renderer still converts all strokes to outline, but it also caches the result. This is an API change. The complex stroke conversion code has been moved to the external gioui.org/x/stroke package, with a similar API. Updats gio#282 (Inkeliz brought up the allocation issue) Signed-off-by: Elias Naur <mail@eliasnaur.com>
81 lines
1.6 KiB
Go
81 lines
1.6 KiB
Go
// SPDX-License-Identifier: Unlicense OR MIT
|
|
|
|
package material
|
|
|
|
import (
|
|
"image"
|
|
"image/color"
|
|
"math"
|
|
"time"
|
|
|
|
"gioui.org/f32"
|
|
"gioui.org/layout"
|
|
"gioui.org/op"
|
|
"gioui.org/op/clip"
|
|
"gioui.org/op/paint"
|
|
"gioui.org/unit"
|
|
)
|
|
|
|
type LoaderStyle struct {
|
|
Color color.NRGBA
|
|
}
|
|
|
|
func Loader(th *Theme) LoaderStyle {
|
|
return LoaderStyle{
|
|
Color: th.Palette.ContrastBg,
|
|
}
|
|
}
|
|
|
|
func (l LoaderStyle) Layout(gtx layout.Context) layout.Dimensions {
|
|
diam := gtx.Constraints.Min.X
|
|
if minY := gtx.Constraints.Min.Y; minY > diam {
|
|
diam = minY
|
|
}
|
|
if diam == 0 {
|
|
diam = gtx.Px(unit.Dp(24))
|
|
}
|
|
sz := gtx.Constraints.Constrain(image.Pt(diam, diam))
|
|
radius := float32(sz.X) * .5
|
|
defer op.Offset(f32.Pt(radius, radius)).Push(gtx.Ops).Pop()
|
|
|
|
dt := float32((time.Duration(gtx.Now.UnixNano()) % (time.Second)).Seconds())
|
|
startAngle := dt * math.Pi * 2
|
|
endAngle := startAngle + math.Pi*1.5
|
|
|
|
defer clipLoader(gtx.Ops, startAngle, endAngle, radius).Push(gtx.Ops).Pop()
|
|
paint.ColorOp{
|
|
Color: l.Color,
|
|
}.Add(gtx.Ops)
|
|
defer op.Offset(f32.Pt(-radius, -radius)).Push(gtx.Ops).Pop()
|
|
paint.PaintOp{}.Add(gtx.Ops)
|
|
op.InvalidateOp{}.Add(gtx.Ops)
|
|
return layout.Dimensions{
|
|
Size: sz,
|
|
}
|
|
}
|
|
|
|
func clipLoader(ops *op.Ops, startAngle, endAngle, radius float32) clip.Op {
|
|
const thickness = .25
|
|
|
|
var (
|
|
width = radius * thickness
|
|
delta = endAngle - startAngle
|
|
|
|
vy, vx = math.Sincos(float64(startAngle))
|
|
|
|
inner = radius * (1. - thickness*.5)
|
|
pen = f32.Pt(float32(vx), float32(vy)).Mul(inner)
|
|
center = f32.Pt(0, 0).Sub(pen)
|
|
|
|
p clip.Path
|
|
)
|
|
|
|
p.Begin(ops)
|
|
p.Move(pen)
|
|
p.Arc(center, center, delta)
|
|
return clip.Stroke{
|
|
Path: p.End(),
|
|
Width: width,
|
|
}.Op()
|
|
}
|