Skip to content

Commit 89f4a5d

Browse files
feat: add Mixer widget (#262)
1 parent aa971db commit 89f4a5d

6 files changed

Lines changed: 471 additions & 0 deletions

File tree

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
local app_name = "Mixers"
2+
local app_ver = "1.0"
3+
4+
local M = {}
5+
6+
local lvSCALE = lvgl.LCD_SCALE or 1
7+
local is800 = (LCD_W==800)
8+
9+
-- better font names
10+
local FS={FONT_38=XXLSIZE,FONT_16=DBLSIZE,FONT_12=MIDSIZE,FONT_8=0,FONT_6=SMLSIZE}
11+
12+
--------------------------------------------------------------
13+
local function log(fmt, ...)
14+
print(string.format("[%s] "..fmt, app_name, ...))
15+
end
16+
--------------------------------------------------------------
17+
18+
local function background(wgt)
19+
for i = 1, 16 do
20+
wgt.values[i] = getValue("ch" .. i)
21+
wgt.names[i] = model.getOutput(i-1).name
22+
wgt.percent[i] = math.floor(100 * (wgt.values[i]+5) / 1024) -- +3 to remove fluctuations
23+
-- log("%s. name: %s, val: %s%%", i, wgt.names[i], wgt.values[i], wgt.percent[i])
24+
end
25+
end
26+
27+
local function build_ui_column(wgt, from_ch, to_ch, zx, zy, zw, zh, headr_text)
28+
local bZone1 = lvgl.box({x=zx, y=zy, w=zw, h=zh})
29+
local bZone2 = bZone1:box({x=0, y=20*lvSCALE})
30+
local bBars = bZone2:box({x=40*lvSCALE, y=0})
31+
32+
-- title
33+
bZone1:label({x=40*lvSCALE, y=0, text=headr_text, color=wgt.text_color, font=FS.FONT_6})
34+
35+
local bar_area_w = zw - 40*lvSCALE
36+
37+
local line_height = 18*lvSCALE
38+
local bar_height = line_height - 2
39+
40+
for i = from_ch, to_ch do
41+
local yy = line_height * (i-from_ch)
42+
local x_mid = bar_area_w / 2
43+
44+
-- text channel
45+
bZone2:label({x=6, y=yy-1, text=string.format("CH%d", i), color=wgt.text_color, font=FS.FONT_6})
46+
47+
bBars:box({x=0, y=yy, w=zw, h=zh,
48+
children={
49+
-- border
50+
{type="rectangle", x=0, y=0, w=bar_area_w, h=bar_height, color=(wgt.bar_bkg_enabled and wgt.bar_bkg_color or 0), style=SOLID, filled=true, visible=function() return wgt.bar_bkg_enabled end},
51+
52+
-- bar
53+
{type="rectangle", color=wgt.bar_color, style=SOLID, filled=true,
54+
pos=function() return x_mid + math.min(0, wgt.percent[i] * bar_area_w /2/100), 0 end,
55+
size=function() return math.abs( wgt.percent[i] * bar_area_w /2/100), bar_height end,
56+
},
57+
58+
-- border
59+
-- {type="line", x1=0, y1=yy, x2=0 + bar_area_w, y2=yy, color=BLACK, style=SOLID},
60+
61+
-- middle mark
62+
{type="rectangle", x=x_mid-1, y=0, w=1, h=bar_height, color=WHITE, style=SOLID, filled=true},
63+
64+
-- text output name
65+
{type="label", x=6, y=-1, text=function() return wgt.names[i] end, color=WHITE, font=FS.FONT_6},
66+
67+
-- text percent
68+
{type="label", color=WHITE, font=FS.FONT_6,
69+
pos=function()
70+
local dx = (wgt.percent[i] > 0) and -37*lvSCALE or 15*lvSCALE
71+
return x_mid + dx, -1
72+
end,
73+
text=function() return string.format("%d%%", wgt.percent[i]) end,
74+
}
75+
76+
}
77+
})
78+
end
79+
end
80+
81+
local function build_ui(wgt)
82+
lvgl.rectangle({x=wgt.zone.x, y=wgt.zone.y, w=wgt.zone.w, h=wgt.zone.h, color=wgt.background_color, style=SOLID, filled=true, visible=function() return wgt.background_enabled end})
83+
84+
if (wgt.zone.w < 320) then
85+
-- single column
86+
build_ui_column(wgt, 1, 16, 0, wgt.zone.y, wgt.zone.w -5, wgt.zone.h, "Mixers")
87+
else
88+
-- two columns
89+
build_ui_column(wgt, 1, 8, 0, wgt.zone.y, wgt.zone.w /2 -5, wgt.zone.h, "Mixers 1-8")
90+
build_ui_column(wgt, 9, 16, wgt.zone.w/2, wgt.zone.y, wgt.zone.w /2 -5, wgt.zone.h, "Mixers 9-16")
91+
end
92+
end
93+
94+
local function update(wgt, options)
95+
if (wgt == nil) then return end
96+
wgt.options = options
97+
wgt.text_color = options.text_color
98+
wgt.bar_color = options.bar_color
99+
wgt.bar_bkg_enabled = (options.bar_bkg_enabled==1)
100+
wgt.bar_bkg_color = options.bar_bkg_color
101+
wgt.background_enabled = (options.background_enabled==1)
102+
wgt.background_color = options.background_color or LIGHTGREY
103+
background(wgt)
104+
build_ui(wgt)
105+
return wgt
106+
end
107+
108+
local function create(zone, options)
109+
local wgt = {
110+
zone = zone,
111+
options = options,
112+
values = {},
113+
names = {},
114+
percent = {},
115+
}
116+
return update(wgt, options)
117+
end
118+
119+
local function refresh(wgt)
120+
background(wgt)
121+
end
122+
123+
return {name=app_name, create=create, update=update, refresh=refresh, background=background, useLvgl=true}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
2+
local app_name = "Mixers"
3+
4+
local options = {
5+
{ "text_color", COLOR, COLOR_THEME_SECONDARY1 },
6+
{ "bar_color", COLOR, COLOR_THEME_FOCUS },
7+
{ "bar_bkg_enabled", BOOL, 1 },
8+
{ "bar_bkg_color", COLOR, GREY },
9+
{ "background_enabled", BOOL, 0 },
10+
{ "background_color", COLOR, BLACK },
11+
}
12+
local function translate(nam)
13+
local translations = {
14+
text_color = "Text Color",
15+
bar_color = "Bar: Color",
16+
bar_bkg_enabled = "Bar Background Enabled",
17+
bar_bkg_color = "Bar Background Color",
18+
background_enabled="Background Enabled",
19+
background_color = "Background Color",
20+
}
21+
return translations[nam]
22+
end
23+
24+
25+
local tool = nil
26+
local function create(zone, options)
27+
tool = assert(loadScript("/WIDGETS/" .. app_name .. "/app.lua", "btd"))()
28+
return tool.create(zone, options)
29+
end
30+
local function update(wgt, options) return tool.update(wgt, options) end
31+
local function background(wgt) return tool.background(wgt) end
32+
local function refresh(wgt) return tool.refresh(wgt) end
33+
34+
return {name=app_name, options=options, translate=translate, create=create, update=update, refresh=refresh, background=background, useLvgl=true}
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
local app_name = "Mixers"
2+
local app_ver = "1.0"
3+
4+
local M = {}
5+
6+
local lvSCALE = lvgl.LCD_SCALE or 1
7+
local is800 = (LCD_W==800)
8+
9+
-- better font names
10+
local FS={FONT_38=XXLSIZE,FONT_16=DBLSIZE,FONT_12=MIDSIZE,FONT_8=0,FONT_6=SMLSIZE}
11+
12+
--------------------------------------------------------------
13+
local function log(fmt, ...)
14+
print(string.format("[%s] "..fmt, app_name, ...))
15+
end
16+
--------------------------------------------------------------
17+
18+
local function background(wgt)
19+
for i = 1, 16 do
20+
wgt.values[i] = getValue("ch" .. i)
21+
wgt.names[i] = model.getOutput(i-1).name
22+
wgt.percent[i] = math.floor(100 * (wgt.values[i]+5) / 1024) -- +3 to remove fluctuations
23+
-- log("%s. name: %s, val: %s%%", i, wgt.names[i], wgt.values[i], wgt.percent[i])
24+
end
25+
end
26+
27+
local function build_ui_column(wgt, from_ch, to_ch, zx, zy, zw, zh, headr_text)
28+
local bZone1 = lvgl.box({x=zx, y=zy, w=zw, h=zh})
29+
local bZone2 = bZone1:box({x=0, y=20*lvSCALE})
30+
local bBars = bZone2:box({x=40*lvSCALE, y=0})
31+
32+
-- title
33+
bZone1:label({x=40*lvSCALE, y=0, text=headr_text, color=wgt.text_color, font=FS.FONT_6})
34+
35+
local bar_area_w = zw - 40*lvSCALE
36+
37+
local line_height = 18*lvSCALE
38+
local bar_height = line_height - 2
39+
40+
for i = from_ch, to_ch do
41+
local yy = line_height * (i-from_ch)
42+
local x_mid = bar_area_w / 2
43+
44+
-- text channel
45+
bZone2:label({x=6, y=yy-1, text=string.format("CH%d", i), color=wgt.text_color, font=FS.FONT_6})
46+
47+
bBars:box({x=0, y=yy, w=zw, h=zh,
48+
children={
49+
-- border
50+
{type="rectangle", x=0, y=0, w=bar_area_w, h=bar_height, color=(wgt.bar_bkg_enabled and wgt.bar_bkg_color or 0), style=SOLID, filled=true, visible=function() return wgt.bar_bkg_enabled end},
51+
52+
-- bar
53+
{type="rectangle", color=wgt.bar_color, style=SOLID, filled=true,
54+
pos=function() return x_mid + math.min(0, wgt.percent[i] * bar_area_w /2/100), 0 end,
55+
size=function() return math.abs( wgt.percent[i] * bar_area_w /2/100), bar_height end,
56+
},
57+
58+
-- border
59+
-- {type="line", x1=0, y1=yy, x2=0 + bar_area_w, y2=yy, color=BLACK, style=SOLID},
60+
61+
-- middle mark
62+
{type="rectangle", x=x_mid-1, y=0, w=1, h=bar_height, color=WHITE, style=SOLID, filled=true},
63+
64+
-- text output name
65+
{type="label", x=6, y=-1, text=function() return wgt.names[i] end, color=WHITE, font=FS.FONT_6},
66+
67+
-- text percent
68+
{type="label", color=WHITE, font=FS.FONT_6,
69+
pos=function()
70+
local dx = (wgt.percent[i] > 0) and -37*lvSCALE or 15*lvSCALE
71+
return x_mid + dx, -1
72+
end,
73+
text=function() return string.format("%d%%", wgt.percent[i]) end,
74+
}
75+
76+
}
77+
})
78+
end
79+
end
80+
81+
local function build_ui(wgt)
82+
lvgl.rectangle({x=wgt.zone.x, y=wgt.zone.y, w=wgt.zone.w, h=wgt.zone.h, color=wgt.background_color, style=SOLID, filled=true, visible=function() return wgt.background_enabled end})
83+
84+
if (wgt.zone.w < 320) then
85+
-- single column
86+
build_ui_column(wgt, 1, 16, 0, wgt.zone.y, wgt.zone.w -5, wgt.zone.h, "Mixers")
87+
else
88+
-- two columns
89+
build_ui_column(wgt, 1, 8, 0, wgt.zone.y, wgt.zone.w /2 -5, wgt.zone.h, "Mixers 1-8")
90+
build_ui_column(wgt, 9, 16, wgt.zone.w/2, wgt.zone.y, wgt.zone.w /2 -5, wgt.zone.h, "Mixers 9-16")
91+
end
92+
end
93+
94+
local function update(wgt, options)
95+
if (wgt == nil) then return end
96+
wgt.options = options
97+
wgt.text_color = options.text_color
98+
wgt.bar_color = options.bar_color
99+
wgt.bar_bkg_enabled = (options.bar_bkg_enabled==1)
100+
wgt.bar_bkg_color = options.bar_bkg_color
101+
wgt.background_enabled = (options.background_enabled==1)
102+
wgt.background_color = options.background_color or LIGHTGREY
103+
background(wgt)
104+
build_ui(wgt)
105+
return wgt
106+
end
107+
108+
local function create(zone, options)
109+
local wgt = {
110+
zone = zone,
111+
options = options,
112+
values = {},
113+
names = {},
114+
percent = {},
115+
}
116+
return update(wgt, options)
117+
end
118+
119+
local function refresh(wgt)
120+
background(wgt)
121+
end
122+
123+
return {name=app_name, create=create, update=update, refresh=refresh, background=background, useLvgl=true}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
2+
local app_name = "Mixers"
3+
4+
local options = {
5+
{ "text_color", COLOR, COLOR_THEME_SECONDARY1 },
6+
{ "bar_color", COLOR, COLOR_THEME_FOCUS },
7+
{ "bar_bkg_enabled", BOOL, 1 },
8+
{ "bar_bkg_color", COLOR, GREY },
9+
{ "background_enabled", BOOL, 0 },
10+
{ "background_color", COLOR, BLACK },
11+
}
12+
local function translate(nam)
13+
local translations = {
14+
text_color = "Text Color",
15+
bar_color = "Bar: Color",
16+
bar_bkg_enabled = "Bar Background Enabled",
17+
bar_bkg_color = "Bar Background Color",
18+
background_enabled="Background Enabled",
19+
background_color = "Background Color",
20+
}
21+
return translations[nam]
22+
end
23+
24+
25+
local tool = nil
26+
local function create(zone, options)
27+
tool = assert(loadScript("/WIDGETS/" .. app_name .. "/app.lua", "btd"))()
28+
return tool.create(zone, options)
29+
end
30+
local function update(wgt, options) return tool.update(wgt, options) end
31+
local function background(wgt) return tool.background(wgt) end
32+
local function refresh(wgt) return tool.refresh(wgt) end
33+
34+
return {name=app_name, options=options, translate=translate, create=create, update=update, refresh=refresh, background=background, useLvgl=true}

0 commit comments

Comments
 (0)