From 788e3f959f54edbec809ad5d8628664929c1a155 Mon Sep 17 00:00:00 2001 From: Moritz Biering Date: Wed, 9 Jun 2021 16:18:01 +0200 Subject: [PATCH] Small corrections and add flatten option to button --- widget_button.go | 34 ++++++++++++++++++++++++++++++--- widget_weather.go | 48 +++++++++++++++++++++++------------------------ 2 files changed, 54 insertions(+), 28 deletions(-) diff --git a/widget_button.go b/widget_button.go index 88d55a4..5c5ba59 100644 --- a/widget_button.go +++ b/widget_button.go @@ -3,6 +3,7 @@ package main import ( "image" "image/color" + "image/draw" "github.com/muesli/streamdeck" ) @@ -15,6 +16,7 @@ type ButtonWidget struct { label string fontsize float64 color color.Color + flatten bool } // NewButtonWidget returns a new ButtonWidget. @@ -28,12 +30,19 @@ func NewButtonWidget(bw BaseWidget, opts WidgetConfig) (*ButtonWidget, error) { _ = ConfigValue(opts.Config["fontsize"], &fontsize) var color color.Color _ = ConfigValue(opts.Config["color"], &color) + var flatten bool + _ = ConfigValue(opts.Config["flatten"], &flatten) + + if color == nil { + color = DefaultColor + } w := &ButtonWidget{ BaseWidget: bw, label: label, fontsize: fontsize, color: color, + flatten: flatten, } if icon != "" { @@ -45,6 +54,9 @@ func NewButtonWidget(bw BaseWidget, opts WidgetConfig) (*ButtonWidget, error) { if err != nil { return nil, err } + if w.flatten { + w.icon = flattenImage(w.icon, w.color) + } } return w, nil @@ -74,9 +86,6 @@ func (w *ButtonWidget) Update(dev *streamdeck.Device) error { bounds.Min.Y += iconsize + margin bounds.Max.Y -= margin } - if w.color == nil { - w.color = DefaultColor - } drawString(img, bounds, @@ -99,3 +108,22 @@ func (w *ButtonWidget) Update(dev *streamdeck.Device) error { return w.render(dev, img) } + +func flattenImage(img image.Image, clr color.Color) image.Image { + bounds := img.Bounds() + flatten := image.NewRGBA(image.Rect(0, 0, bounds.Dx(), bounds.Dy())) + draw.Draw(flatten, flatten.Bounds(), img, image.Point{}, draw.Src) + alphaThreshold := uint32(20000) + + for x := 0; x < bounds.Dx(); x++ { + for y := 0; y < bounds.Dy(); y++ { + _, _, _, alpha := flatten.At(x, y).RGBA() + if alpha > alphaThreshold { + flatten.Set(x, y, clr) + } else { + flatten.Set(x, y, color.RGBA{0, 0, 0, 0}) + } + } + } + return flatten +} diff --git a/widget_weather.go b/widget_weather.go index 8ce30be..f289744 100644 --- a/widget_weather.go +++ b/widget_weather.go @@ -36,8 +36,9 @@ func weatherImage(name string) image.Image { type WeatherWidget struct { BaseWidget - data WeatherData - color color.Color + data WeatherData + color color.Color + flatten bool } // WeatherData handles fetches and parsing weather data. @@ -131,6 +132,8 @@ func NewWeatherWidget(bw BaseWidget, opts WidgetConfig) *WeatherWidget { _ = ConfigValue(opts.Config["unit"], &unit) var color color.Color _ = ConfigValue(opts.Config["color"], &color) + var flatten bool + _ = ConfigValue(opts.Config["flatten"], &flatten) if color == nil { color = DefaultColor @@ -142,7 +145,8 @@ func NewWeatherWidget(bw BaseWidget, opts WidgetConfig) *WeatherWidget { location: location, unit: unit, }, - color: color, + color: color, + flatten: flatten, } } @@ -162,49 +166,43 @@ func (w *WeatherWidget) Update(dev *streamdeck.Device) error { return err } - var weatherIcon image.Image - /* - The serialized conditions are formatted the following way: - Every entry is an unsigned 8 bit value - if the first bit (msd) is not set this 8 bit value resembles a series of transparent pixels - the number of transparent pixels is defined by the lower 7 pixels - if the first bit is set this bit-string resembles a series of opaque pixels - analog the lower 7 pixels define the number of opaque pixels - The image is sampled as follows: top to bottom and left to right - */ + var iconName string switch cond { case "mm", "mmm": // cloudy - weatherIcon = weatherImage("assets/weather/cloudy.png") + iconName = "cloudy" case "m": // partly cloudy - weatherIcon = weatherImage("assets/weather/partly_cloudy.png") + iconName = "partly_cloudy" case "=": // fog - weatherIcon = weatherImage("assets/weather/fog.png") + iconName = "fog" case "///", "//", "x", "x/": // rain - weatherIcon = weatherImage("assets/weather/rain.png") + iconName = "rain" case "/", ".": // light rain - weatherIcon = weatherImage("assets/weather/rain.png") + iconName = "rain" case "**", "*/*": // heavy snow - weatherIcon = weatherImage("assets/weather/snow.png") + iconName = "snow" case "*", "*/": // light snow - weatherIcon = weatherImage("assets/weather/snow.png") + iconName = "snow" case "/!/": // thunder - weatherIcon = weatherImage("assets/weather/lightning.png") + iconName = "lightning" case "!/", "*!*": // thunder rain - weatherIcon = weatherImage("assets/weather/thunder_rain.png") + iconName = "thunder_rain" // case "o": // sunny default: if time.Now().Hour() < 7 || time.Now().Hour() > 21 { - weatherIcon = weatherImage("assets/weather/moon.png") + iconName = "moon" } else { - weatherIcon = weatherImage("assets/weather/sun.png") + iconName = "sun" } } + weatherIcon := weatherImage("assets/weather/" + iconName + ".png") + bw := ButtonWidget{ BaseWidget: w.BaseWidget, color: w.color, icon: weatherIcon, label: temp, + flatten: w.flatten, } return bw.Update(dev) } @@ -214,7 +212,7 @@ func formatUnit(unit string) string { case "f", "fahrenheit": return "&u" case "c", "celsius": - return "&u" + return "&m" default: return "" }