-
Notifications
You must be signed in to change notification settings - Fork 23
/
Copy pathstreamdeck.go
120 lines (104 loc) · 3.39 KB
/
streamdeck.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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
package streamdeck
import "image"
// ButtonDisplay is the interface to satisfy for displaying on a button
type ButtonDisplay interface {
GetImageForButton(int) image.Image
GetButtonIndex() int
SetButtonIndex(int)
RegisterUpdateHandler(func(Button))
Pressed()
}
// ButtonActionHandler is the interface to satisfy for handling a button being pressed, generally via an `actionhandler`
type ButtonActionHandler interface {
Pressed(Button)
}
// Button is the interface to satisfy for being a button; currently this is a direct proxy for the `ButtonDisplay` interface as there isn't a requirement to handle being pressed
type Button interface {
ButtonDisplay
}
// ButtonDecorator represents a way to modify the button image, for example to add a highlight or an "on/off" hint
type ButtonDecorator interface {
Apply(image.Image, int) image.Image
}
// StreamDeck is the main struct to represent a StreamDeck device, and internally contains the reference to a `Device`
type StreamDeck struct {
dev *Device
buttons map[int]Button
decorators map[int]ButtonDecorator
}
// 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.
func New() (*StreamDeck, error) {
sd := &StreamDeck{}
d, err := Open()
if err != nil {
return nil, err
}
sd.dev = d
sd.buttons = make(map[int]Button)
sd.decorators = make(map[int]ButtonDecorator)
sd.dev.ButtonPress(sd.pressHandler)
return sd, nil
}
// GetName returns the name of the type of Streamdeck
func (sd *StreamDeck) GetName() string {
return sd.dev.deviceType.name
}
// AddButton adds a `Button` object to the StreamDeck at the specified index
func (sd *StreamDeck) AddButton(btnIndex int, b Button) {
b.RegisterUpdateHandler(sd.ButtonUpdateHandler)
b.SetButtonIndex(btnIndex)
sd.buttons[btnIndex] = b
sd.updateButton(b)
}
// SetDecorator imposes a ButtonDecorator onto a given button
func (sd *StreamDeck) SetDecorator(btnIndex int, d ButtonDecorator) {
sd.decorators[btnIndex] = d
// If there's a button there, update it
btn, ok := sd.buttons[btnIndex]
if ok {
sd.updateButton(btn)
}
}
// UnsetDecorator removes a ButtonDecorator from a given button
func (sd *StreamDeck) UnsetDecorator(btnIndex int) {
delete(sd.decorators, btnIndex)
// If there's a button there, update it
btn, ok := sd.buttons[btnIndex]
if ok {
sd.updateButton(btn)
}
}
// ButtonUpdateHandler allows a user of this library to signal when something external has changed, such that this button should be update
func (sd *StreamDeck) ButtonUpdateHandler(b Button) {
sd.buttons[b.GetButtonIndex()] = b
sd.updateButton(b)
}
// GetButtonByIndex returns a button for the given index
func (sd *StreamDeck) GetButtonIndex(btnIndex int) Button {
b, ok := sd.buttons[btnIndex]
if !ok {
return nil
}
return b
}
func (sd *StreamDeck) pressHandler(btnIndex int, d *Device, err error) {
if err != nil {
panic(err)
}
b := sd.buttons[btnIndex]
if b != nil {
sd.buttons[btnIndex].Pressed()
}
}
func (sd *StreamDeck) updateButton(b Button) error {
img := b.GetImageForButton(sd.dev.deviceType.imageSize.X)
decorator, ok := sd.decorators[b.GetButtonIndex()]
if ok {
img = decorator.Apply(img, sd.dev.deviceType.imageSize.X)
}
e := sd.dev.WriteRawImageToButton(b.GetButtonIndex(), img)
return e
}
func (sd *StreamDeck) SetBrightness(brightness int) {
sd.dev.SetBrightness(brightness)
}