Merge main
No files matched your search
@@ -37,6 +37,7 @@ testdata/snapshots/ <os>/<name>-<light|dark>.png
|
|||||||
- Focus: `internal.Ring(e, k.Focus, radius)` for the 2 DIP ring with 2 DIP gap.
|
- Focus: `internal.Ring(e, k.Focus, radius)` for the 2 DIP ring with 2 DIP gap.
|
||||||
- State marks (checked, selected, progress) use `OnAccent` on `Accent`, or `AccentText`, never `Accent` alone on dark surfaces (2.44:1).
|
- State marks (checked, selected, progress) use `OnAccent` on `Accent`, or `AccentText`, never `Accent` alone on dark surfaces (2.44:1).
|
||||||
- Ornament color only for dividers, corners, panel titles. No gradients, glow, glass or texture.
|
- Ornament color only for dividers, corners, panel titles. No gradients, glow, glass or texture.
|
||||||
|
- Animated paths: pass coordinates through `internal.Snap(p, v)`. MyGo caches path masks by quarter-pixel keys (ui/path.go); unsnapped motion reuses near-miss masks and breaks snapshots.
|
||||||
- Durations: `mujica.Motion(c, theme.StateDuration)`; popups use `theme.PopupDuration`.
|
- Durations: `mujica.Motion(c, theme.StateDuration)`; popups use `theme.PopupDuration`.
|
||||||
- Disabled blocks input before handling it (`Disabled(true)`); MyGo dims disabled elements, do not add opacity.
|
- Disabled blocks input before handling it (`Disabled(true)`); MyGo dims disabled elements, do not add opacity.
|
||||||
- Copy shown by a component comes from `msg(c, key)`; business copy comes from the caller.
|
- Copy shown by a component comes from `msg(c, key)`; business copy comes from the caller.
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
package internal
|
package internal
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"math"
|
||||||
|
|
||||||
"github.com/egoist/mygo/ui"
|
"github.com/egoist/mygo/ui"
|
||||||
|
|
||||||
"mujicaui/theme"
|
"mujicaui/theme"
|
||||||
@@ -33,3 +35,9 @@ func Diamond(cx, cy, s float32) *ui.Path {
|
|||||||
p.Close()
|
p.Close()
|
||||||
return &p
|
return &p
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Snap rounds v to MyGo's quarter-device-pixel path cache grid.
|
||||||
|
func Snap(p *ui.Painter, v float32) float32 {
|
||||||
|
g := 4 * p.Scale()
|
||||||
|
return float32(math.Round(float64(v*g))) / g
|
||||||
|
}
|
||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
|
|
||||||
"github.com/egoist/mygo/ui"
|
"github.com/egoist/mygo/ui"
|
||||||
|
|
||||||
|
"mujicaui/internal"
|
||||||
"mujicaui/theme"
|
"mujicaui/theme"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -112,21 +113,21 @@ func progressRing(c *ui.Context, k theme.Tokens, u float32, acc float64, name, c
|
|||||||
}
|
}
|
||||||
stroke := max(3, d/10)
|
stroke := max(3, d/10)
|
||||||
ring.Draw(func(p *ui.Painter, r ui.Rect) {
|
ring.Draw(func(p *ui.Painter, r ui.Rect) {
|
||||||
cx, cy, rad := r.X+r.W/2, r.Y+r.H/2, (r.W-stroke)/2
|
cx, cy, rad := internal.Snap(p, r.X+r.W/2), internal.Snap(p, r.Y+r.H/2), internal.Snap(p, (r.W-stroke)/2)
|
||||||
var track ui.Path
|
var track ui.Path
|
||||||
track.Circle(cx, cy, rad)
|
track.Circle(cx, cy, rad)
|
||||||
p.StrokePath(&track, stroke, k.Border)
|
p.StrokePath(&track, stroke, k.Border)
|
||||||
switch {
|
switch {
|
||||||
case !opts.Indeterminate:
|
case !opts.Indeterminate:
|
||||||
if shown > 0 {
|
if shown > 0 {
|
||||||
p.StrokePath(progressArc(cx, cy, rad, 0, shown), stroke, k.AccentText)
|
p.StrokePath(progressArc(p, cx, cy, rad, 0, shown), stroke, k.AccentText)
|
||||||
}
|
}
|
||||||
case still:
|
case still:
|
||||||
p.StrokePath(&track, stroke, k.AccentText.Alpha(0.4))
|
p.StrokePath(&track, stroke, k.AccentText.Alpha(0.4))
|
||||||
default:
|
default:
|
||||||
p.AnimationFrame()
|
p.AnimationFrame()
|
||||||
start := float32(p.Now().UnixMilli()%1200) / 1200
|
start := float32(p.Now().UnixMilli()%1200) / 1200
|
||||||
p.StrokePath(progressArc(cx, cy, rad, start, start+0.25), stroke, k.AccentText)
|
p.StrokePath(progressArc(p, cx, cy, rad, start, start+0.25), stroke, k.AccentText)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
if caption != "" && d >= 44 && !opts.Indeterminate {
|
if caption != "" && d >= 44 && !opts.Indeterminate {
|
||||||
@@ -150,7 +151,7 @@ func progressRing(c *ui.Context, k theme.Tokens, u float32, acc float64, name, c
|
|||||||
}
|
}
|
||||||
|
|
||||||
// progressArc is the arc from turn a to turn b, clockwise from twelve o'clock.
|
// progressArc is the arc from turn a to turn b, clockwise from twelve o'clock.
|
||||||
func progressArc(cx, cy, r float32, a, b float32) *ui.Path {
|
func progressArc(pt *ui.Painter, cx, cy, r float32, a, b float32) *ui.Path {
|
||||||
var p ui.Path
|
var p ui.Path
|
||||||
n := max(2, int(math.Ceil(float64((b-a)*64))))
|
n := max(2, int(math.Ceil(float64((b-a)*64))))
|
||||||
for i := 0; i <= n; i++ {
|
for i := 0; i <= n; i++ {
|
||||||
@@ -158,9 +159,9 @@ func progressArc(cx, cy, r float32, a, b float32) *ui.Path {
|
|||||||
x := cx + r*float32(math.Sin(2*math.Pi*t))
|
x := cx + r*float32(math.Sin(2*math.Pi*t))
|
||||||
y := cy - r*float32(math.Cos(2*math.Pi*t))
|
y := cy - r*float32(math.Cos(2*math.Pi*t))
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
p.MoveTo(x, y)
|
p.MoveTo(internal.Snap(pt, x), internal.Snap(pt, y))
|
||||||
} else {
|
} else {
|
||||||
p.LineTo(x, y)
|
p.LineTo(internal.Snap(pt, x), internal.Snap(pt, y))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return &p
|
return &p
|
||||||
|
|||||||
@@ -58,11 +58,8 @@ func spinnerMark(c *ui.Context, label string, size float32, color ui.Color, stil
|
|||||||
a := 2 * math.Pi * (turn + float64(i)/4)
|
a := 2 * math.Pi * (turn + float64(i)/4)
|
||||||
x := cx + rad*float32(math.Cos(a))
|
x := cx + rad*float32(math.Cos(a))
|
||||||
y := cy + rad*float32(math.Sin(a))
|
y := cy + rad*float32(math.Sin(a))
|
||||||
// Device-pixel centers keep cached shapes rendering alike.
|
|
||||||
s := p.Scale()
|
|
||||||
x, y = float32(math.Round(float64(x*s)))/s, float32(math.Round(float64(y*s)))/s
|
|
||||||
alpha := 1 - float32(i)*0.22
|
alpha := 1 - float32(i)*0.22
|
||||||
p.FillPath(internal.Diamond(x, y, r.W*0.3), color.Alpha(alpha))
|
p.FillPath(internal.Diamond(internal.Snap(p, x), internal.Snap(p, y), internal.Snap(p, r.W*0.3)), color.Alpha(alpha))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 9.6 KiB After Width: | Height: | Size: 9.7 KiB |
|
Before Width: | Height: | Size: 8.4 KiB After Width: | Height: | Size: 8.6 KiB |
|
Before Width: | Height: | Size: 8.2 KiB After Width: | Height: | Size: 8.3 KiB |
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.4 KiB |
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 7.9 KiB After Width: | Height: | Size: 7.9 KiB |
|
Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 7.6 KiB |