Skip to content

Commit b5a5e8f

Browse files
committed
Merge branch 'button-decorator'
2 parents 168202d + 199de65 commit b5a5e8f

File tree

4 files changed

+126
-2
lines changed

4 files changed

+126
-2
lines changed

decorators/border.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package decorators
2+
3+
import (
4+
"image"
5+
"image/color"
6+
)
7+
8+
type Border struct {
9+
width int
10+
colour color.Color
11+
}
12+
13+
func NewBorder(width int, colour color.Color) *Border {
14+
b := &Border{width: width, colour: colour}
15+
return b
16+
}
17+
18+
func (b *Border) Apply(img image.Image) image.Image {
19+
newimg := img.(*image.RGBA)
20+
// TODO base the 96 on the image bounds
21+
for i := 0; i < b.width; i++ {
22+
rect(i, i, 96-i, 96-i, newimg, b.colour)
23+
}
24+
return newimg
25+
}
26+
27+
// Utility functions from https://stackoverflow.com/questions/28992396/draw-a-rectangle-in-golang
28+
29+
func hLine(x1, y, x2 int, img *image.RGBA, colour color.Color) {
30+
for ; x1 <= x2; x1++ {
31+
img.Set(x1, y, colour)
32+
}
33+
}
34+
35+
func vLine(x, y1, y2 int, img *image.RGBA, colour color.Color) {
36+
for ; y1 <= y2; y1++ {
37+
img.Set(x, y1, colour)
38+
}
39+
}
40+
41+
func rect(x1, y1, x2, y2 int, img *image.RGBA, colour color.Color) {
42+
hLine(x1, y1, x2, img, colour)
43+
hLine(x1, y2, x2, img, colour)
44+
vLine(x1, y1, y2, img, colour)
45+
vLine(x2, y1, y2, img, colour)
46+
}

examples/client.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
streamdeck "github.com/magicmonkey/go-streamdeck"
88
"github.com/magicmonkey/go-streamdeck/actionhandlers"
99
"github.com/magicmonkey/go-streamdeck/buttons"
10+
"github.com/magicmonkey/go-streamdeck/decorators"
1011
)
1112

1213
func main() {
@@ -40,6 +41,16 @@ func main() {
4041
multiActionButton.SetActionHandler(thisActionHandler)
4142
sd.AddButton(27, multiActionButton)
4243

44+
decoratedButton := buttons.NewTextButton("ABC")
45+
sd.AddButton(19, decoratedButton)
46+
47+
time.Sleep(2 * time.Second)
48+
decorator1 := decorators.NewBorder(10, color.RGBA{0, 255, 0, 255})
49+
sd.SetDecorator(19, decorator1)
50+
time.Sleep(2 * time.Second)
51+
decorator2 := decorators.NewBorder(5, color.RGBA{255, 0, 0, 255})
52+
sd.SetDecorator(19, decorator2)
53+
4354
time.Sleep(2 * time.Second)
4455

4556
myButton.SetText("Bye!")

examples/client2.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package main
2+
3+
import (
4+
"image/color"
5+
"strconv"
6+
"sync"
7+
8+
streamdeck "github.com/magicmonkey/go-streamdeck"
9+
"github.com/magicmonkey/go-streamdeck/actionhandlers"
10+
"github.com/magicmonkey/go-streamdeck/buttons"
11+
"github.com/magicmonkey/go-streamdeck/decorators"
12+
)
13+
14+
func main() {
15+
var current int
16+
17+
sd, err := streamdeck.New()
18+
if err != nil {
19+
panic(err)
20+
}
21+
22+
btns := make([]*buttons.TextButton, 32)
23+
for i := 0; i < 32; i++ {
24+
btns[i] = buttons.NewTextButton(strconv.Itoa(i))
25+
sd.AddButton(i, btns[i])
26+
}
27+
28+
greenBorder := decorators.NewBorder(10, color.RGBA{0, 255, 0, 255})
29+
30+
redBorder := decorators.NewBorder(5, color.RGBA{255, 0, 0, 255})
31+
for i := 0; i < 32; i++ {
32+
sd.SetDecorator(i, redBorder)
33+
}
34+
35+
for i := 0; i < 32; i++ {
36+
h := actionhandlers.NewCustomAction(func(btn streamdeck.Button) {
37+
sd.SetDecorator(current, redBorder)
38+
sd.SetDecorator(btn.GetButtonIndex(), greenBorder)
39+
current = btn.GetButtonIndex()
40+
})
41+
btns[i].SetActionHandler(h)
42+
}
43+
44+
var wg sync.WaitGroup
45+
wg.Add(1)
46+
wg.Wait()
47+
48+
}

streamdeck.go

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,15 @@ type Button interface {
2121
ButtonDisplay
2222
}
2323

24+
type ButtonDecorator interface {
25+
Apply(image.Image) image.Image
26+
}
27+
2428
// StreamDeck is the main struct to represent a StreamDeck device, and internally contains the reference to a `Device`
2529
type StreamDeck struct {
26-
dev *Device
27-
buttons map[int]Button
30+
dev *Device
31+
buttons map[int]Button
32+
decorators map[int]ButtonDecorator
2833
}
2934

3035
// New will return a new instance of a `StreamDeck`, and is the main entry point for the higher-level interface. It will return an error if there is no StreamDeck plugged in.
@@ -36,6 +41,7 @@ func New() (*StreamDeck, error) {
3641
}
3742
sd.dev = d
3843
sd.buttons = make(map[int]Button)
44+
sd.decorators = make(map[int]ButtonDecorator)
3945
sd.dev.ButtonPress(sd.pressHandler)
4046
return sd, nil
4147
}
@@ -48,6 +54,15 @@ func (sd *StreamDeck) AddButton(btnIndex int, b Button) {
4854
sd.updateButton(b)
4955
}
5056

57+
func (sd *StreamDeck) SetDecorator(btnIndex int, d ButtonDecorator) {
58+
sd.decorators[btnIndex] = d
59+
// If there's a button there, update it
60+
btn, ok := sd.buttons[btnIndex]
61+
if ok {
62+
sd.updateButton(btn)
63+
}
64+
}
65+
5166
// ButtonUpdateHandler allows a user of this library to signal when something external has changed, such that this button should be update
5267
func (sd *StreamDeck) ButtonUpdateHandler(b Button) {
5368
sd.buttons[b.GetButtonIndex()] = b
@@ -66,6 +81,10 @@ func (sd *StreamDeck) pressHandler(btnIndex int, d *Device, err error) {
6681

6782
func (sd *StreamDeck) updateButton(b Button) error {
6883
img := b.GetImageForButton()
84+
decorator, ok := sd.decorators[b.GetButtonIndex()]
85+
if ok {
86+
img = decorator.Apply(img)
87+
}
6988
e := sd.dev.WriteRawImageToButton(b.GetButtonIndex(), img)
7089
return e
7190
}

0 commit comments

Comments
 (0)