-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcontroller.go
165 lines (144 loc) · 3.82 KB
/
controller.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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
package dmxthing
import (
"github.com/scottlaird/loupedeck"
"golang.org/x/image/font"
"golang.org/x/image/math/fixed"
"image"
"image/color"
"image/draw"
"strconv"
)
// LoupedeckArea represents an area of the Loupedeck touch display.
type LoupedeckArea int
const (
LeftTop LoupedeckArea = iota
LeftMiddle
LeftBottom
RightTop
RightMiddle
RightBottom
)
// Light is an interface for lights that are compatible with this
// controller.
type Light interface {
SetBrightness(int)
SetColorTemp(int)
MinColorTemp() int
MaxColorTemp() int
}
// LightController is a controller for one or more lights. It
// implements brightness and color control using buttons and dials on
// the Loupedeck.
type LightController struct {
Loupedeck *loupedeck.Loupedeck
Position LoupedeckArea
DialButtonID int
X, Y int
Brightness *loupedeck.WatchedInt
ColorTemp *loupedeck.WatchedInt
Lights []Light
knob *loupedeck.IntKnob
display *loupedeck.Display
minColorTemp int
}
// NewLightController creates a new LightController for a set of lights.
func NewLightController(l *loupedeck.Loupedeck, position LoupedeckArea, lights []Light) *LightController {
a := &LightController{
Loupedeck: l,
Position: position,
Brightness: loupedeck.NewWatchedInt(0),
ColorTemp: loupedeck.NewWatchedInt(128),
Lights: lights,
}
var knob loupedeck.Knob
var touch loupedeck.TouchButton
switch position {
case LeftTop:
a.X, a.Y = 0, 0
a.display = l.GetDisplay("left")
knob = loupedeck.Knob1
touch = loupedeck.Touch1
case LeftMiddle:
a.X, a.Y = 0, 90
a.display = l.GetDisplay("left")
knob = loupedeck.Knob2
touch = loupedeck.Touch5
case LeftBottom:
a.X, a.Y = 0, 180
a.display = l.GetDisplay("left")
knob = loupedeck.Knob3
touch = loupedeck.Touch9
case RightTop:
a.X, a.Y = 0, 0
a.display = l.GetDisplay("right")
knob = loupedeck.Knob4
touch = loupedeck.Touch4
case RightMiddle:
a.X, a.Y = 0, 90
a.display = l.GetDisplay("right")
knob = loupedeck.Knob5
touch = loupedeck.Touch8
case RightBottom:
a.X, a.Y = 0, 180
a.display = l.GetDisplay("right")
knob = loupedeck.Knob6
touch = loupedeck.Touch12
default:
panic("Unknown position!")
}
a.knob = l.IntKnob(knob, 0, 100, a.Brightness)
// Find minimum/maximum color temps for all lights in set.
min := lights[0].MinColorTemp()
max := lights[0].MaxColorTemp()
for _, l := range lights {
lMin := l.MinColorTemp()
lMax := l.MaxColorTemp()
if lMin < min {
min = lMin
}
if lMax > max {
max = lMax
}
}
a.minColorTemp = min
_ = ColorTempButton(l, a.ColorTemp, min, max, touch)
a.Brightness.AddWatcher(func(i int) {
for _, l := range a.Lights {
l.SetBrightness(i)
}
})
a.Brightness.AddWatcher(func(i int) { a.Draw() })
a.ColorTemp.AddWatcher(func(i int) {
for _, l := range a.Lights {
l.SetColorTemp(i)
}
})
a.ColorTemp.AddWatcher(func(i int) { a.Draw() })
return a
}
// Draw updates the Loupedeck display.
func (a *LightController) Draw() {
im := image.NewRGBA(image.Rect(0, 0, 60, 90))
bg := color.RGBA{0, 0, 0, 255}
draw.Draw(im, im.Bounds(), &image.Uniform{bg}, image.Point{}, draw.Src)
fd := a.Loupedeck.FontDrawer()
fd.Dst = im
baseline := 55
drawRightJustifiedStringAt(fd, strconv.Itoa(a.Brightness.Get()), 48, baseline)
a.display.Draw(im, a.X, a.Y)
}
// Reset sets the brightness to 0 and color to the minimum supported by the light.
func (a *LightController) Reset() {
// Many lights set the brightness to >0 when setting the color
// temp, so we're better off setting the temp first.
a.ColorTemp.Set(a.minColorTemp)
a.Brightness.Set(0)
}
func drawRightJustifiedStringAt(fd font.Drawer, s string, x, y int) {
bounds, _ := fd.BoundString(s)
width := bounds.Max.X - bounds.Min.X
x26 := fixed.I(x)
y26 := fixed.I(y)
fd.Dot = fixed.Point26_6{X: x26 - width, Y: y26}
fd.DrawString(s)
}