88 lines
2.2 KiB
Go
88 lines
2.2 KiB
Go
package mujica
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/egoist/mygo/ui"
|
|
|
|
"mujicaui/internal"
|
|
"mujicaui/theme"
|
|
)
|
|
|
|
// Presence is a person's availability. The zero value is offline.
|
|
type Presence int
|
|
|
|
const (
|
|
PresenceOffline Presence = iota
|
|
PresenceOnline
|
|
PresenceAway
|
|
PresenceBusy
|
|
)
|
|
|
|
func (p Presence) key() string {
|
|
switch p {
|
|
case PresenceOffline:
|
|
return "online_status.offline"
|
|
case PresenceOnline:
|
|
return "online_status.online"
|
|
case PresenceAway:
|
|
return "online_status.away"
|
|
case PresenceBusy:
|
|
return "online_status.busy"
|
|
}
|
|
panic(fmt.Sprintf("mujica: unknown Presence %d", int(p)))
|
|
}
|
|
|
|
// OnlineStatusOptions configure an OnlineStatus.
|
|
type OnlineStatusOptions struct {
|
|
// HideText keeps the shape, accessible name and tooltip.
|
|
HideText bool
|
|
// Size is the shape's diameter; zero means 10.
|
|
Size float32
|
|
}
|
|
|
|
// OnlineStatus shows presence as a distinct shape plus its name.
|
|
func OnlineStatus(c *ui.Context, p Presence, opts OnlineStatusOptions) *ui.Element {
|
|
name := msg(c, p.key())
|
|
if opts.Size < 0 {
|
|
panic("mujica: OnlineStatus Size must not be negative")
|
|
}
|
|
size := opts.Size
|
|
if size == 0 {
|
|
size = 10
|
|
}
|
|
k := Tokens(c)
|
|
row := ui.Row(c).Gap(Density(c).Unit() * 1.5).AlignItems(ui.Center).Shrink(0).Role(ui.RoleStatus).Label(name)
|
|
if opts.HideText {
|
|
row.Tooltip(name)
|
|
}
|
|
row.Children(func() {
|
|
ui.Box(c).Size(size, size).Shrink(0).Draw(func(p2 *ui.Painter, r ui.Rect) { presencePaint(p2, k, p, r) })
|
|
if !opts.HideText {
|
|
ui.Text(c, name).FontSize(FontSize(c, theme.CaptionSize)).TextColor(k.TextMuted).SingleLine()
|
|
}
|
|
})
|
|
return row
|
|
}
|
|
|
|
func presencePaint(p *ui.Painter, k theme.Tokens, s Presence, r ui.Rect) {
|
|
cx, cy := internal.Snap(p, r.X+r.W/2), internal.Snap(p, r.Y+r.H/2)
|
|
rad := r.W / 2
|
|
var disc ui.Path
|
|
disc.Circle(cx, cy, rad)
|
|
switch s {
|
|
case PresenceOnline:
|
|
p.FillPath(&disc, k.Success)
|
|
case PresenceAway:
|
|
p.FillPath(&disc, k.Warning)
|
|
var bite ui.Path
|
|
bite.Circle(cx-rad*0.45, cy-rad*0.45, rad*0.62)
|
|
p.FillPath(&bite, k.Surface)
|
|
case PresenceBusy:
|
|
p.FillPath(&disc, k.Danger)
|
|
p.Fill(ui.Rect{X: cx - rad*0.6, Y: cy - max(1, rad*0.18), W: rad * 1.2, H: max(2, rad*0.36)}, k.Surface, 0)
|
|
default:
|
|
p.StrokePath(&disc, max(1.5, rad*0.3), k.TextMuted)
|
|
}
|
|
}
|