diff --git a/cmd/streamdeck/config.go b/cmd/streamdeck/config.go index 6b9414f..d785688 100644 --- a/cmd/streamdeck/config.go +++ b/cmd/streamdeck/config.go @@ -18,35 +18,40 @@ func init() { } type attributeCollection struct { - AttachStderr bool `json:"attach_stderr,omitempty" yaml:"attach_stderr,omitempty"` - AttachStdout bool `json:"attach_stdout,omitempty" yaml:"attach_stdout,omitempty"` - Border *int `json:"border,omitempty" yaml:"border,omitempty"` - Caption string `json:"caption,omitempty" yaml:"caption,omitempty"` - ChangeVolume *float64 `json:"change_volume,omitempty" yaml:"change_volume,omitempty"` - Color string `json:"color,omitempty" yaml:"color,omitempty"` - Command []string `json:"command,omitempty" yaml:"command,omitempty"` - Delay time.Duration `json:"delay,omitempty" yaml:"delay,omitempty"` - Device string `json:"device,omitempty" yaml:"device,omitempty"` - Env map[string]string `json:"env,omitempty" yaml:"env,omitempty"` - FontSize *float64 `json:"font_size,omitempty" yaml:"font_size,omitempty"` - Image string `json:"image,omitempty" yaml:"image,omitempty"` - Interval time.Duration `json:"interval,omitempty" yaml:"interval,omitempty"` - KeyCodes []int `json:"key_codes,omitempty" yaml:"key_codes,omitempty"` - Keys []string `json:"keys,omitempty" yaml:"keys,omitempty"` - Match string `json:"match,omitempty" yaml:"match,omitempty"` - ModAlt bool `json:"mod_alt,omitempty" yaml:"mod_alt,omitempty"` - ModCtrl bool `json:"mod_ctrl,omitempty" yaml:"mod_ctrl,omitempty"` - ModShift bool `json:"mod_shift,omitempty" yaml:"mod_shift,omitempty"` - ModMeta bool `json:"mod_meta,omitempty" yaml:"mod_meta,omitempty"` - Mute string `json:"mute,omitempty" yaml:"mute,omitempty"` - Name string `json:"name,omitempty" yaml:"name,omitempty"` - Path string `json:"path,omitempty" yaml:"path,omitempty"` - Relative int `json:"relative,omitempty" yaml:"relative,omitempty"` - RGBA []int `json:"rgba,omitempty" yaml:"rgba,omitempty"` - SetVolume *float64 `json:"set_volume,omitempty" yaml:"set_volume,omitempty"` - Text string `json:"text,omitempty" yaml:"text,omitempty"` - URL string `json:"url,omitempty" yaml:"url,omitempty"` - Wait bool `json:"wait,omitempty" yaml:"wait,omitempty"` + AttachStderr bool `json:"attach_stderr,omitempty" yaml:"attach_stderr,omitempty"` + AttachStdout bool `json:"attach_stdout,omitempty" yaml:"attach_stdout,omitempty"` + BackgroundColor []int `json:"background_color,omitempty" yaml:"background_color,omitempty"` + Border *int `json:"border,omitempty" yaml:"border,omitempty"` + Caption string `json:"caption,omitempty" yaml:"caption,omitempty"` + ChangeVolume *float64 `json:"change_volume,omitempty" yaml:"change_volume,omitempty"` + Color string `json:"color,omitempty" yaml:"color,omitempty"` + Command []string `json:"command,omitempty" yaml:"command,omitempty"` + Delay time.Duration `json:"delay,omitempty" yaml:"delay,omitempty"` + Device string `json:"device,omitempty" yaml:"device,omitempty"` + Env map[string]string `json:"env,omitempty" yaml:"env,omitempty"` + FontSize *float64 `json:"font_size,omitempty" yaml:"font_size,omitempty"` + Image string `json:"image,omitempty" yaml:"image,omitempty"` + Interval time.Duration `json:"interval,omitempty" yaml:"interval,omitempty"` + KeyCodes []int `json:"key_codes,omitempty" yaml:"key_codes,omitempty"` + Keys []string `json:"keys,omitempty" yaml:"keys,omitempty"` + Match string `json:"match,omitempty" yaml:"match,omitempty"` + ModAlt bool `json:"mod_alt,omitempty" yaml:"mod_alt,omitempty"` + ModCtrl bool `json:"mod_ctrl,omitempty" yaml:"mod_ctrl,omitempty"` + ModShift bool `json:"mod_shift,omitempty" yaml:"mod_shift,omitempty"` + ModMeta bool `json:"mod_meta,omitempty" yaml:"mod_meta,omitempty"` + Mute string `json:"mute,omitempty" yaml:"mute,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Path string `json:"path,omitempty" yaml:"path,omitempty"` + Relative int `json:"relative,omitempty" yaml:"relative,omitempty"` + RGBA []int `json:"rgba,omitempty" yaml:"rgba,omitempty"` + SetVolume *float64 `json:"set_volume,omitempty" yaml:"set_volume,omitempty"` + Text string `json:"text,omitempty" yaml:"text,omitempty"` + URL string `json:"url,omitempty" yaml:"url,omitempty"` + Wait bool `json:"wait,omitempty" yaml:"wait,omitempty"` +} + +func (a attributeCollection) BackgroundToColor() color.RGBA { + return a.rgbaToColor(a.BackgroundColor) } func (a attributeCollection) Clone() attributeCollection { @@ -62,10 +67,14 @@ func (a attributeCollection) Clone() attributeCollection { } func (a attributeCollection) RGBAToColor() color.RGBA { - if len(a.RGBA) != 4 { + return a.rgbaToColor(a.RGBA) +} + +func (a attributeCollection) rgbaToColor(src []int) color.RGBA { + if len(src) != 4 { return color.RGBA{} } - return color.RGBA{uint8(a.RGBA[0]), uint8(a.RGBA[1]), uint8(a.RGBA[2]), uint8(a.RGBA[3])} + return color.RGBA{uint8(src[0]), uint8(src[1]), uint8(src[2]), uint8(src[3])} } type config struct { diff --git a/cmd/streamdeck/display_text.go b/cmd/streamdeck/display_text.go index 3340305..0ce1718 100644 --- a/cmd/streamdeck/display_text.go +++ b/cmd/streamdeck/display_text.go @@ -2,11 +2,12 @@ package main import ( "context" - "github.com/pkg/errors" "image/color" _ "image/jpeg" _ "image/png" "strings" + + "github.com/pkg/errors" ) func init() { @@ -24,6 +25,19 @@ func (d displayElementText) Display(ctx context.Context, idx int, attributes att ) // Initialize background + if attributes.BackgroundColor != nil { + if len(attributes.BackgroundColor) != 4 { + return errors.New("Background color definition needs 4 hex values") + } + + if err := ctx.Err(); err != nil { + // Page context was cancelled, do not draw + return err + } + + imgRenderer.DrawBackgroundColor(attributes.BackgroundToColor()) + } + if attributes.Image != "" { if err = imgRenderer.DrawBackgroundFromFile(attributes.Image); err != nil { return errors.Wrap(err, "Unable to draw background from disk") diff --git a/cmd/streamdeck/helper_displayText.go b/cmd/streamdeck/helper_displayText.go index 06e8b52..f2eb919 100644 --- a/cmd/streamdeck/helper_displayText.go +++ b/cmd/streamdeck/helper_displayText.go @@ -42,6 +42,18 @@ func (t *textOnImageRenderer) DrawBackground(bgi image.Image) { draw.Draw(t.img, t.img.Bounds(), bgi, image.ZP, draw.Src) } +func (t *textOnImageRenderer) DrawBackgroundColor(col color.RGBA) { + img := image.NewRGBA(image.Rect(0, 0, sd.IconSize(), sd.IconSize())) + + for x := 0; x < sd.IconSize(); x++ { + for y := 0; y < sd.IconSize(); y++ { + img.Set(x, y, col) + } + } + + t.DrawBackground(img) +} + func (t *textOnImageRenderer) DrawBackgroundFromFile(filename string) error { bgi, err := t.getImageFromDisk(filename) if err != nil { @@ -70,7 +82,7 @@ func (t *textOnImageRenderer) DrawBigText(text string, fontSizeHint float64, bor } func (t *textOnImageRenderer) DrawCaptionText(text string) error { - var fontFile = userConfig.CaptionFont + fontFile := userConfig.CaptionFont if fontFile == "" { fontFile = userConfig.RenderFont } @@ -91,7 +103,7 @@ func (t *textOnImageRenderer) DrawCaptionText(text string) error { } } - var anchor = textDrawAnchorBottom + anchor := textDrawAnchorBottom if userConfig.CaptionPosition == "top" { anchor = textDrawAnchorTop }