117 lines
2.9 KiB
Go
117 lines
2.9 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"log/slog"
|
|
"math/rand"
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/tardisx/streamdeck-plugin"
|
|
"github.com/tardisx/streamdeck-plugin/events"
|
|
"github.com/tardisx/streamdeck-plugin/tools"
|
|
)
|
|
|
|
// keep track of instances we've seen, each one has a different
|
|
// colour
|
|
type clocks struct {
|
|
contextColour map[string]string
|
|
lock sync.Mutex
|
|
}
|
|
|
|
// template for making a clock image in SVG
|
|
const svgClock = `
|
|
<svg width="144" height="144" xmlns="http://www.w3.org/2000/svg">
|
|
<rect width="144" height="144" fill="black"/>
|
|
<text x="72" y="108"
|
|
font-family="Arial, sans-serif"
|
|
font-size="96"
|
|
font-weight="bold"
|
|
fill="%s"
|
|
text-anchor="middle"
|
|
dominant-baseline="central"
|
|
transform="rotate(%d, 72, 72)">
|
|
%02d
|
|
</text>
|
|
</svg>`
|
|
|
|
func main() {
|
|
clocks := clocks{
|
|
contextColour: map[string]string{},
|
|
lock: sync.Mutex{},
|
|
}
|
|
slog.Info("Starting up")
|
|
c := streamdeck.NewWithLogger(slog.Default())
|
|
|
|
slog.Info("Registering handlers")
|
|
c.RegisterHandler(func(e events.ERWillAppear) {
|
|
// clock appeared, give it a random colour
|
|
slog.Info("appearing " + e.Context)
|
|
clocks.lock.Lock()
|
|
defer clocks.lock.Unlock()
|
|
clocks.contextColour[e.Context] = randRGB()
|
|
})
|
|
c.RegisterHandler(func(e events.ERWillDisappear) {
|
|
// Stop updating this clock by simply removing it from our struct.
|
|
// Note that this is not required, and in this case it means that
|
|
// when it gets re-instantiated it will get a new colour.
|
|
// But it is good practice to not spend CPU on updating things that
|
|
// are not currently being displayed.
|
|
slog.Info("disappearing " + e.Context)
|
|
clocks.lock.Lock()
|
|
defer clocks.lock.Unlock()
|
|
delete(clocks.contextColour, e.Context)
|
|
})
|
|
c.RegisterHandler(func(e events.ERKeyDown) {
|
|
// button pressed, change its colour
|
|
slog.Info("keyDown " + e.Context)
|
|
clocks.lock.Lock()
|
|
defer clocks.lock.Unlock()
|
|
clocks.contextColour[e.Context] = randRGB()
|
|
drawClock(c, e.Context, clocks.contextColour[e.Context])
|
|
})
|
|
|
|
slog.Info("Connecting web socket")
|
|
err := c.Connect()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
// update all clocks, continuously
|
|
go func() {
|
|
for {
|
|
clocks.lock.Lock()
|
|
for context, colour := range clocks.contextColour {
|
|
drawClock(c, context, colour)
|
|
}
|
|
clocks.lock.Unlock()
|
|
time.Sleep(time.Second)
|
|
}
|
|
}()
|
|
|
|
slog.Info("waiting for the end")
|
|
c.WaitForPluginExit()
|
|
}
|
|
|
|
func drawClock(c streamdeck.Connection, context string, colour string) {
|
|
// rotation for this minute of the hour
|
|
rot := int(360.0 * (float64(time.Now().Minute()) / 60.0))
|
|
// generate the SVG
|
|
svg := fmt.Sprintf(svgClock, colour, rot, time.Now().Hour())
|
|
|
|
// create the event
|
|
newImage := events.NewESSetImage(
|
|
context,
|
|
tools.SVGToPayload(svg),
|
|
events.EventTargetBoth,
|
|
nil)
|
|
|
|
// send it
|
|
c.Send(newImage)
|
|
}
|
|
|
|
// randRGB creates a random colour
|
|
func randRGB() string {
|
|
return fmt.Sprintf("#%02x%02x%02x", rand.Intn(256), rand.Intn(256), rand.Intn(256))
|
|
}
|