Add text rendering for Stream Deck buttons with toggle demo
This commit is contained in:
@@ -3,7 +3,6 @@ package main
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"image/color"
|
"image/color"
|
||||||
"math/rand/v2"
|
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"syscall"
|
"syscall"
|
||||||
@@ -11,6 +10,42 @@ import (
|
|||||||
"qrun/lib/streamdeck"
|
"qrun/lib/streamdeck"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var palette = []color.RGBA{
|
||||||
|
{220, 50, 50, 255},
|
||||||
|
{50, 180, 50, 255},
|
||||||
|
{50, 100, 220, 255},
|
||||||
|
{220, 160, 30, 255},
|
||||||
|
{180, 50, 180, 255},
|
||||||
|
{50, 180, 180, 255},
|
||||||
|
{220, 120, 50, 255},
|
||||||
|
{100, 100, 200, 255},
|
||||||
|
}
|
||||||
|
|
||||||
|
func labelForKey(key int) string {
|
||||||
|
row := key / streamdeck.KeyCols()
|
||||||
|
col := key % streamdeck.KeyCols()
|
||||||
|
switch row {
|
||||||
|
case 0:
|
||||||
|
return fmt.Sprintf("Ch %d\nSelect", col+1)
|
||||||
|
case 1:
|
||||||
|
return fmt.Sprintf("Ch %d\nMute", col+1)
|
||||||
|
case 2:
|
||||||
|
return fmt.Sprintf("Ch %d\nSolo", col+1)
|
||||||
|
case 3:
|
||||||
|
return fmt.Sprintf("Ch %d\nRec", col+1)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("Key %d", key)
|
||||||
|
}
|
||||||
|
|
||||||
|
func drawKey(dev *streamdeck.Device, key int, bg color.RGBA) {
|
||||||
|
dim := color.RGBA{bg.R / 3, bg.G / 3, bg.B / 3, 255}
|
||||||
|
dev.SetKeyText(key, dim, color.White, labelForKey(key))
|
||||||
|
}
|
||||||
|
|
||||||
|
func drawKeyActive(dev *streamdeck.Device, key int, bg color.RGBA) {
|
||||||
|
dev.SetKeyText(key, bg, color.White, labelForKey(key))
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
dev, err := streamdeck.Open()
|
dev, err := streamdeck.Open()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -24,12 +59,12 @@ func main() {
|
|||||||
dev.SetBrightness(80)
|
dev.SetBrightness(80)
|
||||||
|
|
||||||
for i := 0; i < streamdeck.KeyCount(); i++ {
|
for i := 0; i < streamdeck.KeyCount(); i++ {
|
||||||
r := uint8(rand.IntN(256))
|
col := i % streamdeck.KeyCols()
|
||||||
g := uint8(rand.IntN(256))
|
drawKey(dev, i, palette[col])
|
||||||
b := uint8(rand.IntN(256))
|
|
||||||
dev.SetKeyColor(i, color.RGBA{r, g, b, 255})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
active := make([]bool, streamdeck.KeyCount())
|
||||||
|
|
||||||
keys := make(chan streamdeck.KeyEvent, 64)
|
keys := make(chan streamdeck.KeyEvent, 64)
|
||||||
go func() {
|
go func() {
|
||||||
if err := dev.ReadKeys(keys); err != nil {
|
if err := dev.ReadKeys(keys); err != nil {
|
||||||
@@ -43,15 +78,17 @@ func main() {
|
|||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case ev := <-keys:
|
case ev := <-keys:
|
||||||
if ev.Pressed {
|
if !ev.Pressed {
|
||||||
fmt.Printf("Key %d pressed\n", ev.Key)
|
continue
|
||||||
r := uint8(rand.IntN(256))
|
|
||||||
g := uint8(rand.IntN(256))
|
|
||||||
b := uint8(rand.IntN(256))
|
|
||||||
dev.SetKeyColor(ev.Key, color.RGBA{r, g, b, 255})
|
|
||||||
} else {
|
|
||||||
fmt.Printf("Key %d released\n", ev.Key)
|
|
||||||
}
|
}
|
||||||
|
col := ev.Key % streamdeck.KeyCols()
|
||||||
|
active[ev.Key] = !active[ev.Key]
|
||||||
|
if active[ev.Key] {
|
||||||
|
drawKeyActive(dev, ev.Key, palette[col])
|
||||||
|
} else {
|
||||||
|
drawKey(dev, ev.Key, palette[col])
|
||||||
|
}
|
||||||
|
fmt.Printf("Key %d toggled %v\n", ev.Key, active[ev.Key])
|
||||||
case <-sig:
|
case <-sig:
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
return
|
return
|
||||||
|
|||||||
45
lib/streamdeck/text.go
Normal file
45
lib/streamdeck/text.go
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
package streamdeck
|
||||||
|
|
||||||
|
import (
|
||||||
|
"image"
|
||||||
|
"image/color"
|
||||||
|
"image/draw"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"golang.org/x/image/font"
|
||||||
|
"golang.org/x/image/font/basicfont"
|
||||||
|
"golang.org/x/image/math/fixed"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TextImage(bg color.Color, fg color.Color, lines ...string) image.Image {
|
||||||
|
img := image.NewRGBA(image.Rect(0, 0, keySize, keySize))
|
||||||
|
draw.Draw(img, img.Bounds(), &image.Uniform{bg}, image.Point{}, draw.Src)
|
||||||
|
|
||||||
|
face := basicfont.Face7x13
|
||||||
|
metrics := face.Metrics()
|
||||||
|
lineHeight := metrics.Height.Ceil()
|
||||||
|
|
||||||
|
totalHeight := lineHeight * len(lines)
|
||||||
|
startY := (keySize-totalHeight)/2 + metrics.Ascent.Ceil()
|
||||||
|
|
||||||
|
for i, line := range lines {
|
||||||
|
width := font.MeasureString(face, line).Ceil()
|
||||||
|
x := (keySize - width) / 2
|
||||||
|
y := startY + i*lineHeight
|
||||||
|
|
||||||
|
d := &font.Drawer{
|
||||||
|
Dst: img,
|
||||||
|
Src: &image.Uniform{fg},
|
||||||
|
Face: face,
|
||||||
|
Dot: fixed.P(x, y),
|
||||||
|
}
|
||||||
|
d.DrawString(line)
|
||||||
|
}
|
||||||
|
|
||||||
|
return img
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Device) SetKeyText(key int, bg color.Color, fg color.Color, text string) error {
|
||||||
|
lines := strings.Split(text, "\n")
|
||||||
|
return d.SetKeyImage(key, TextImage(bg, fg, lines...))
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user