Skip to content

Commit 15f1097

Browse files
committed
Merge branch 'master' of github:magicmonkey/go-streamdeck
2 parents 55a34f2 + 41305be commit 15f1097

File tree

9 files changed

+137
-17
lines changed

9 files changed

+137
-17
lines changed

CONTRIBUTING.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Contributing to Go-Streamdeck
2+
3+
All issues, pull requests and other feedback are very welcome in this project. Please do take the time to read the information below, and get involved!
4+
5+
- [Use Go-Streamdeck From Source](#use-go-streamdeck-from-source)
6+
- [Share Issues, Bugs and Feature Requests](#share-issues-bugs-and-feature-requests)
7+
- [Submit a Patch or Pull Request](#submit-a-patch-or-pull-request)
8+
- [Try the Examples](#try-the-examples)
9+
- [Usage in Other Projects](#usage-in-other-projects)
10+
11+
## Use Go-Streamdeck From Source
12+
13+
To use the `master` branch, another branch, or a branch in your own fork, you can use the `replace` syntax in your `go.mod` file. For more information and an example try this [excellent blog post from Pam Selle](https://thewebivore.com/using-replace-in-go-mod-to-point-to-your-local-module/).
14+
15+
## Share Issues, Bugs and Feature Requests
16+
17+
Go ahead and open an issue, choosing whether you are making a bug report, or a feature request. If it's both, or neither, just pick one! The only difference is the template you are prompted to complete. It's fine to ask questions and support queries by opening an issue on this repository too.
18+
19+
## Submit a Patch or Pull Request
20+
21+
You will need to fork the repository to offer patches. Please make sure your master branch is up to date, then start a new branch, named for the feature/bugfix it contains.
22+
23+
For large changes, please open an issue for discussion so that we know we are not duplicating work or working on a feature that won't be accepted at the end of the process.
24+
25+
## Try the Examples
26+
27+
The `examples/` directory has a series of examples that may be useful in your own applications. Try these out to see the various features in action.
28+
29+
Please open an issue to update us for which operating systems and StreamDeck combinations are working well for you!
30+
31+
## Usage in Other Projects
32+
33+
You are very welcome to use this project within the terms of the license. We would love to have you in our showcase, please open a pull request to update the `README.md` file with a link to your project.

README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@ A Go interface to an Elgato Streamdeck (currently works with the 32-button XL on
66

77
_Designed for and tested with Ubuntu, Go 1.13+ and a Streamdeck XL. Images are the wrong size for other streamdecks; bug reports and patches are welcome!_
88

9+
- [Installation](#installation)
10+
- [Usage](#usage)
11+
* [Example high-level usage](#example-high-level-usage)
12+
* [Example low-level usage](#example-low-level-usage)
13+
- [Showcase](#showcase)
14+
- [Contributions](#contributions)
15+
916
## Installation
1017

1118
Either include the library in your project or install it with the following command:
@@ -109,6 +116,14 @@ func main() {
109116

110117
The program runs for 20 seconds and then exits.
111118

119+
## Showcase
120+
121+
Projects using this library (pull request to add yours!)
122+
123+
* [Streamdeck tricks](https://github.com/lornajane/streamdeck-tricks)
124+
112125
## Contributions
113126

114127
This is a very new project but all feedback, comments, questions and patches are more than welcome. Please get in touch by opening an issue, it would be good to hear who is using the project and how things are going.
128+
129+
For more, see [CONTRIBUTING.md](CONTRIBUTING.md).

buttons/colour.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@ import (
88
streamdeck "github.com/magicmonkey/go-streamdeck"
99
)
1010

11+
// ColourButton represents a button which is a solid block of a single colour
1112
type ColourButton struct {
1213
colour color.Color
1314
updateHandler func(streamdeck.Button)
1415
btnIndex int
1516
actionHandler streamdeck.ButtonActionHandler
1617
}
1718

19+
// GetImageForButton is the interface implemention to get the button's image as an image.Image
1820
func (btn *ColourButton) GetImageForButton() image.Image {
1921
ButtonSize := 96
2022
img := image.NewRGBA(image.Rect(0, 0, ButtonSize, ButtonSize))
@@ -23,33 +25,43 @@ func (btn *ColourButton) GetImageForButton() image.Image {
2325
return img
2426
}
2527

28+
// SetButtonIndex is the interface implemention to set which button on the Streamdeck this is
2629
func (btn *ColourButton) SetButtonIndex(btnIndex int) {
2730
btn.btnIndex = btnIndex
2831
}
2932

33+
// GetButtonIndex is the interface implemention to get which button on the Streamdeck this is
3034
func (btn *ColourButton) GetButtonIndex() int {
3135
return btn.btnIndex
3236
}
3337

38+
// SetColour allows the colour for the button to be changed on the fly
3439
func (btn *ColourButton) SetColour(colour color.Color) {
3540
btn.colour = colour
3641
btn.updateHandler(btn)
3742
}
3843

44+
// RegisterUpdateHandler is the interface implemention to let the engine give this button a callback to
45+
// use to request that the button image is updated on the Streamdeck.
3946
func (btn *ColourButton) RegisterUpdateHandler(f func(streamdeck.Button)) {
4047
btn.updateHandler = f
4148
}
4249

50+
// SetActionHandler allows a ButtonActionHandler implementation to be
51+
// set on this button, so that something can happen when the button is pressed.
4352
func (btn *ColourButton) SetActionHandler(a streamdeck.ButtonActionHandler) {
4453
btn.actionHandler = a
4554
}
4655

56+
// Pressed is the interface implementation for letting the engine notify that the button has been
57+
// pressed. This hands-off to the specified ButtonActionHandler if it has been set.
4758
func (btn *ColourButton) Pressed() {
4859
if btn.actionHandler != nil {
4960
btn.actionHandler.Pressed(btn)
5061
}
5162
}
5263

64+
// NewColourButton creates a new ColourButton of the specified colour
5365
func NewColourButton(colour color.Color) *ColourButton {
5466
btn := &ColourButton{colour: colour}
5567
return btn

buttons/imagefile.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import (
88
streamdeck "github.com/magicmonkey/go-streamdeck"
99
)
1010

11+
// ImageFileButton represents a button with an image on it, where the image is loaded
12+
// from a file.
1113
type ImageFileButton struct {
1214
filePath string
1315
img image.Image
@@ -16,21 +18,25 @@ type ImageFileButton struct {
1618
actionHandler streamdeck.ButtonActionHandler
1719
}
1820

21+
// GetImageForButton is the interface implemention to get the button's image as an image.Image
1922
func (btn *ImageFileButton) GetImageForButton() image.Image {
2023
// TODO base the 96 on the image bounds
2124
newimg := image.NewRGBA(image.Rect(0, 0, 96, 96))
2225
draw.Draw(newimg, newimg.Bounds(), btn.img, image.Point{0, 0}, draw.Src)
2326
return newimg
2427
}
2528

29+
// SetButtonIndex is the interface implemention to set which button on the Streamdeck this is
2630
func (btn *ImageFileButton) SetButtonIndex(btnIndex int) {
2731
btn.btnIndex = btnIndex
2832
}
2933

34+
// GetButtonIndex is the interface implemention to get which button on the Streamdeck this is
3035
func (btn *ImageFileButton) GetButtonIndex() int {
3136
return btn.btnIndex
3237
}
3338

39+
// SetFilePath allows the image file to be changed on the fly
3440
func (btn *ImageFileButton) SetFilePath(filePath string) error {
3541
btn.filePath = filePath
3642
err := btn.loadImage()
@@ -64,20 +70,27 @@ func (btn *ImageFileButton) loadImage() error {
6470
return nil
6571
}
6672

73+
// RegisterUpdateHandler is the interface implemention to let the engine give this button a callback to
74+
// use to request that the button image is updated on the Streamdeck.
6775
func (btn *ImageFileButton) RegisterUpdateHandler(f func(streamdeck.Button)) {
6876
btn.updateHandler = f
6977
}
7078

79+
// SetActionHandler allows a ButtonActionHandler implementation to be
80+
// set on this button, so that something can happen when the button is pressed.
7181
func (btn *ImageFileButton) SetActionHandler(a streamdeck.ButtonActionHandler) {
7282
btn.actionHandler = a
7383
}
7484

85+
// Pressed is the interface implementation for letting the engine notify that the button has been
86+
// pressed. This hands-off to the specified ButtonActionHandler if it has been set.
7587
func (btn *ImageFileButton) Pressed() {
7688
if btn.actionHandler != nil {
7789
btn.actionHandler.Pressed(btn)
7890
}
7991
}
8092

93+
// NewImageFileButton creates a new ImageFileButton with the specified image on it
8194
func NewImageFileButton(filePath string) (*ImageFileButton, error) {
8295
btn := &ImageFileButton{filePath: filePath}
8396
err := btn.loadImage()

buttons/text.go

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
streamdeck "github.com/magicmonkey/go-streamdeck"
1313
)
1414

15+
// TextButton represents a button with text on it
1516
type TextButton struct {
1617
label string
1718
textColour color.Color
@@ -21,53 +22,71 @@ type TextButton struct {
2122
actionHandler streamdeck.ButtonActionHandler
2223
}
2324

25+
// GetImageForButton is the interface implemention to get the button's image as an image.Image
2426
func (btn *TextButton) GetImageForButton() image.Image {
2527
img := getImageWithText(btn.label, btn.textColour, btn.backgroundColour)
2628
return img
2729
}
2830

31+
// SetButtonIndex is the interface implemention to set which button on the Streamdeck this is
2932
func (btn *TextButton) SetButtonIndex(btnIndex int) {
3033
btn.btnIndex = btnIndex
3134
}
3235

36+
// GetButtonIndex is the interface implemention to get which button on the Streamdeck this is
3337
func (btn *TextButton) GetButtonIndex() int {
3438
return btn.btnIndex
3539
}
3640

41+
// SetText allows the text on the button to be changed on the fly
3742
func (btn *TextButton) SetText(label string) {
3843
btn.label = label
3944
btn.updateHandler(btn)
4045
}
4146

47+
// SetTextColour allows the colour of the text on the button to be changed on the fly
4248
func (btn *TextButton) SetTextColour(textColour color.Color) {
4349
btn.textColour = textColour
4450
btn.updateHandler(btn)
4551
}
4652

53+
// SetBackgroundColor allows the background colour on the button to be changed on the fly
4754
func (btn *TextButton) SetBackgroundColor(backgroundColour color.Color) {
4855
btn.backgroundColour = backgroundColour
4956
btn.updateHandler(btn)
5057
}
5158

59+
// RegisterUpdateHandler is the interface implemention to let the engine give this button a callback to
60+
// use to request that the button image is updated on the Streamdeck.
5261
func (btn *TextButton) RegisterUpdateHandler(f func(streamdeck.Button)) {
5362
btn.updateHandler = f
5463
}
5564

65+
// SetActionHandler allows a ButtonActionHandler implementation to be
66+
// set on this button, so that something can happen when the button is pressed.
5667
func (btn *TextButton) SetActionHandler(a streamdeck.ButtonActionHandler) {
5768
btn.actionHandler = a
5869
}
5970

71+
// Pressed is the interface implementation for letting the engine notify that the button has been
72+
// pressed. This hands-off to the specified ButtonActionHandler if it has been set.
6073
func (btn *TextButton) Pressed() {
6174
if btn.actionHandler != nil {
6275
btn.actionHandler.Pressed(btn)
6376
}
6477
}
6578

79+
// NewTextButton creates a new TextButton with the specified text on it, in white on a black
80+
// background. The text will be set on a single line, and auto-sized to fill the button as best
81+
// as possible.
6682
func NewTextButton(label string) *TextButton {
6783
btn := NewTextButtonWithColours(label, color.White, color.Black)
6884
return btn
6985
}
7086

87+
// NewTextButtonWithColours creates a new TextButton with the specified text on it, in the specified
88+
// text and background colours. The text will be set on a single line, and auto-sized to fill the
89+
// button as best as possible.
7190
func NewTextButtonWithColours(label string, textColour color.Color, backgroundColour color.Color) *TextButton {
7291
btn := &TextButton{label: label, textColour: textColour, backgroundColour: backgroundColour}
7392
return btn
@@ -92,17 +111,17 @@ func getImageWithText(text string, textColour color.Color, backgroundColour colo
92111
}
93112
}
94113

95-
src_img := image.NewUniform(textColour)
114+
srcImg := image.NewUniform(textColour)
96115

97-
dst_img := image.NewRGBA(image.Rect(0, 0, ButtonSize, ButtonSize))
98-
draw.Draw(dst_img, dst_img.Bounds(), image.NewUniform(backgroundColour), image.Point{0, 0}, draw.Src)
116+
dstImg := image.NewRGBA(image.Rect(0, 0, ButtonSize, ButtonSize))
117+
draw.Draw(dstImg, dstImg.Bounds(), image.NewUniform(backgroundColour), image.Point{0, 0}, draw.Src)
99118

100119
c := freetype.NewContext()
101120
c.SetFont(myfont)
102-
c.SetDst(dst_img)
103-
c.SetSrc(src_img)
121+
c.SetDst(dstImg)
122+
c.SetSrc(srcImg)
104123
c.SetFontSize(size)
105-
c.SetClip(dst_img.Bounds())
124+
c.SetClip(dstImg.Bounds())
106125

107126
x := int((96 - width) / 2) // Horizontally centre text
108127
y := int(50 + (size / 3)) // Fudged vertical centre, erm, very "heuristic"
@@ -115,14 +134,14 @@ func getImageWithText(text string, textColour color.Color, backgroundColour colo
115134
fmt.Println(textWidth)
116135
117136
f := &font.Drawer{
118-
Dst: dst_img,
137+
Dst: dstImg,
119138
Src: src_img,
120139
Face: basicfont.Face7x13,
121140
Dot: fixed.Point26_6{fixed.Int26_6(x * 64), fixed.Int26_6(y * 64)},
122141
}
123142
f.DrawString(text)
124143
*/
125-
return dst_img
144+
return dstImg
126145
}
127146

128147
func getTextWidth(text string, size float64) int {

examples/client/client.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,47 +19,58 @@ func main() {
1919
}
2020
fmt.Printf("Found device [%s]\n", sd.GetName())
2121

22+
// Button in position 2, changes to "Bye!" at the end of the program
23+
// When pressed, this prints "You pressed me" to the terminal
2224
myButton := buttons.NewTextButton("Hi world")
2325
myButton.SetActionHandler(&actionhandlers.TextPrintAction{Label: "You pressed me"})
2426
sd.AddButton(2, myButton)
2527

28+
// Button in position 3, prints "5" to the terminal when pressed
2629
myOtherButton := buttons.NewTextButton("4")
2730
myOtherButton.SetActionHandler(&actionhandlers.NumberPrintAction{Number: 5})
2831
sd.AddButton(3, myOtherButton)
2932

33+
// Button in position 7 (top right on Streamdeck XL), says 7
34+
// When pressed, changes to display "8"
3035
myNextButton := buttons.NewTextButton("7")
3136
myNextButton.SetActionHandler(&actionhandlers.TextLabelChangeAction{NewLabel: "8"})
3237
sd.AddButton(7, myNextButton)
3338

39+
// Image button, no action handler
3440
anotherButton, err := buttons.NewImageFileButton("examples/test/play.jpg")
3541
if err != nil {
3642
panic(err)
3743
}
3844
sd.AddButton(9, anotherButton)
3945

46+
// Yellow button, no action handler but it goes to blue at the end of the program
4047
cButton := buttons.NewColourButton(color.RGBA{255, 255, 0, 255})
4148
sd.AddButton(26, cButton)
4249

50+
// One button, two actions (uses ChainedAction)
51+
// Purple button, prints to the console and turns red when pressed
4352
multiActionButton := buttons.NewColourButton(color.RGBA{255, 0, 255, 255})
4453
thisActionHandler := &actionhandlers.ChainedAction{}
4554
thisActionHandler.AddAction(&actionhandlers.TextPrintAction{Label: "Purple press"})
4655
thisActionHandler.AddAction(&actionhandlers.ColourChangeAction{NewColour: color.RGBA{255, 0, 0, 255}})
4756
multiActionButton.SetActionHandler(thisActionHandler)
4857
sd.AddButton(27, multiActionButton)
4958

59+
// Text button, gets a red highlight after 2 seconds, then a green
60+
// highlight after another 2 seconds
5061
decoratedButton := buttons.NewTextButton("ABC")
5162
sd.AddButton(19, decoratedButton)
52-
5363
time.Sleep(2 * time.Second)
5464
decorator1 := decorators.NewBorder(10, color.RGBA{0, 255, 0, 255})
5565
sd.SetDecorator(19, decorator1)
5666
time.Sleep(2 * time.Second)
5767
decorator2 := decorators.NewBorder(5, color.RGBA{255, 0, 0, 255})
5868
sd.SetDecorator(19, decorator2)
59-
6069
time.Sleep(2 * time.Second)
6170

71+
// When this button says "Bye!", the program ends
6272
myButton.SetText("Bye!")
73+
// When this button goes blue, the program ends
6374
cButton.SetColour(color.RGBA{0, 255, 255, 255})
6475
sd.UnsetDecorator(19)
6576
}

0 commit comments

Comments
 (0)