This repository has been archived by the owner on Apr 5, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 29
/
presence.go
100 lines (81 loc) · 2.15 KB
/
presence.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
package avatar
import (
"math"
"github.com/diamondburned/arikawa/v2/gateway"
"github.com/diamondburned/gotk4/pkg/cairo"
"github.com/diamondburned/gotk4/pkg/gtk/v3"
)
const (
statusSizeBorder = 0.35
statusSizeMaxRadius = 9.0
)
// WithStatus is the user avatar with the activity status dot.
type WithStatus struct {
*Image
status gateway.Status
size int
}
// NewWithStatus creates a new image with status.
func NewWithStatus(size int) *WithStatus {
return NewFromImageWithStatus(New(size), size)
}
// NewFromImageWithStatus creates a new image with status from a custom image.
func NewFromImageWithStatus(image *Image, size int) *WithStatus {
s := &WithStatus{
Image: image,
status: "",
size: size,
}
image.ConnectAfter("draw", s.draw)
return s
}
// SetStatus sets the status indicator.
func (s *WithStatus) SetStatus(status gateway.Status) {
s.status = status
gtk.BaseWidget(s.Image).QueueDraw()
}
func (s *WithStatus) draw(w gtk.Widgetter, cc *cairo.Context) {
var color uint32
switch s.status {
case gateway.OnlineStatus:
color = 0x43B581
case gateway.DoNotDisturbStatus:
color = 0xF04747
case gateway.IdleStatus:
color = 0xFAA61A
case gateway.OfflineStatus, gateway.InvisibleStatus:
color = 0x747F8D
default:
return
}
alloc := gtk.BaseWidget(w).Allocation()
width := float64(alloc.Width())
height := float64(alloc.Height())
indicatorDiameter := math.Pow(float64(s.size), 0.75)
indicatorRadius := math.Min(indicatorDiameter/2, statusSizeMaxRadius)
borderThickness := indicatorRadius * statusSizeBorder
borderStart := indicatorRadius - borderThickness
centerPointX := width - indicatorRadius
centerPointY := height - indicatorRadius
cc.Arc(centerPointX, centerPointY, indicatorRadius, 0, 2*math.Pi)
cc.Clip()
cc.Paint()
// Draw the indicator.
cc.SetSourceRGB(hexRGB(color))
cc.Arc(centerPointX, centerPointY, borderStart, 0, 2*math.Pi)
cc.Fill()
cc.SetSourceRGBA(1, 1, 1, 0)
cc.Paint()
return
}
const (
maskR = 0xFF0000
maskG = 0x00FF00
maskB = 0x0000FF
)
func hexRGB(hex uint32) (r, g, b float64) {
r = float64((hex&maskR)>>16) / 0xFF
g = float64((hex&maskG)>>8) / 0xFF
b = float64((hex&maskB)>>0) / 0xFF
return
}