summaryrefslogtreecommitdiff
path: root/lua/settings.lua
diff options
context:
space:
mode:
authorailurux <ailuruxx@gmail.com>2024-03-20 13:42:03 +1100
committerailurux <ailuruxx@gmail.com>2024-03-20 13:42:03 +1100
commit51dfb5b3e30caf823c2355ff957c01864f35f9f6 (patch)
tree1f0e41397259c6e206aba136ad5070b9de30e1b1 /lua/settings.lua
parent170c23b832eed6dad2b118e50164464cc93e5c4c (diff)
parenta05d93a1e26181237a76da5ce398c6b08497d591 (diff)
downloadtangara-fw-51dfb5b3e30caf823c2355ff957c01864f35f9f6.tar.gz
Merge branch 'main' into themes
Diffstat (limited to 'lua/settings.lua')
-rw-r--r--lua/settings.lua491
1 files changed, 249 insertions, 242 deletions
diff --git a/lua/settings.lua b/lua/settings.lua
index aac5ce9b..c9103de3 100644
--- a/lua/settings.lua
+++ b/lua/settings.lua
@@ -8,8 +8,7 @@ local controls = require("controls")
local bluetooth = require("bluetooth")
local theme = require("theme")
local database = require("database")
-
-local settings = {}
+local screen = require("screen")
local function SettingsScreen(title)
local menu = widgets.MenuScreen {
@@ -32,158 +31,161 @@ local function SettingsScreen(title)
return menu
end
-function settings.bluetooth()
- local menu = SettingsScreen("Bluetooth")
+local BluetoothSettings = screen:new {
+ createUi = function(self)
+ self.menu = SettingsScreen("Bluetooth")
+
+ local enable_container = self.menu.content:Object {
+ flex = {
+ flex_direction = "row",
+ justify_content = "flex-start",
+ align_items = "content",
+ align_content = "flex-start",
+ },
+ w = lvgl.PCT(100),
+ h = lvgl.SIZE_CONTENT,
+ pad_bottom = 1,
+ }
+ enable_container:Label { text = "Enable", flex_grow = 1 }
+ local enable_sw = enable_container:Switch {}
+ enable_sw:onevent(lvgl.EVENT.VALUE_CHANGED, function()
+ local enabled = enable_sw:enabled()
+ bluetooth.enabled:set(enabled)
+ end)
- local enable_container = menu.content:Object {
- flex = {
- flex_direction = "row",
- justify_content = "flex-start",
- align_items = "content",
- align_content = "flex-start",
- },
- w = lvgl.PCT(100),
- h = lvgl.SIZE_CONTENT,
- pad_bottom = 1,
- }
- enable_container:Label { text = "Enable", flex_grow = 1 }
- local enable_sw = enable_container:Switch {}
- enable_sw:onevent(lvgl.EVENT.VALUE_CHANGED, function()
- local enabled = enable_sw:enabled()
- bluetooth.enabled:set(enabled)
- end)
-
- theme.set_style(menu.content:Label {
+ theme.set_style(self.menu.content:Label {
text = "Paired Device",
pad_bottom = 1,
}, "settings_title")
- local paired_container = menu.content:Object {
- flex = {
- flex_direction = "row",
- justify_content = "flex-start",
- align_items = "flex-start",
- align_content = "flex-start",
- },
- w = lvgl.PCT(100),
- h = lvgl.SIZE_CONTENT,
- pad_bottom = 2,
- }
+ local paired_container = self.menu.content:Object {
+ flex = {
+ flex_direction = "row",
+ justify_content = "flex-start",
+ align_items = "flex-start",
+ align_content = "flex-start",
+ },
+ w = lvgl.PCT(100),
+ h = lvgl.SIZE_CONTENT,
+ pad_bottom = 2,
+ }
- local paired_device = paired_container:Label {
- flex_grow = 1,
- }
- local clear_paired = paired_container:Button {}
- clear_paired:Label { text = "x" }
- clear_paired:onClicked(function()
- bluetooth.paired_device:set()
- end)
+ local paired_device = paired_container:Label {
+ flex_grow = 1,
+ }
+ local clear_paired = paired_container:Button {}
+ clear_paired:Label { text = "x" }
+ clear_paired:onClicked(function()
+ bluetooth.paired_device:set()
+ end)
- theme.set_style(menu.content:Label {
+ theme.set_style(self.menu.content:Label {
text = "Nearby Devices",
pad_bottom = 1,
}, "settings_title")
- local devices = menu.content:List {
- w = lvgl.PCT(100),
- h = lvgl.SIZE_CONTENT,
- }
+ local devices = self.menu.content:List {
+ w = lvgl.PCT(100),
+ h = lvgl.SIZE_CONTENT,
+ }
- menu.bindings = {
- bluetooth.enabled:bind(function(en)
- if en then
- enable_sw:add_state(lvgl.STATE.CHECKED)
- else
- enable_sw:clear_state(lvgl.STATE.CHECKED)
- end
- end),
- bluetooth.paired_device:bind(function(device)
- if device then
- paired_device:set { text = device.name }
- clear_paired:clear_flag(lvgl.FLAG.HIDDEN)
- else
- paired_device:set { text = "None" }
- clear_paired:add_flag(lvgl.FLAG.HIDDEN)
- end
- end),
- bluetooth.devices:bind(function(devs)
- devices:clean()
- for _, dev in pairs(devs) do
- devices:add_btn(nil, dev.name):onClicked(function()
- bluetooth.paired_device:set(dev)
- end)
- end
- end)
- }
-end
+ self.bindings = {
+ bluetooth.enabled:bind(function(en)
+ if en then
+ enable_sw:add_state(lvgl.STATE.CHECKED)
+ else
+ enable_sw:clear_state(lvgl.STATE.CHECKED)
+ end
+ end),
+ bluetooth.paired_device:bind(function(device)
+ if device then
+ paired_device:set { text = device.name }
+ clear_paired:clear_flag(lvgl.FLAG.HIDDEN)
+ else
+ paired_device:set { text = "None" }
+ clear_paired:add_flag(lvgl.FLAG.HIDDEN)
+ end
+ end),
+ bluetooth.devices:bind(function(devs)
+ devices:clean()
+ for _, dev in pairs(devs) do
+ devices:add_btn(nil, dev.name):onClicked(function()
+ bluetooth.paired_device:set(dev)
+ end)
+ end
+ end)
+ }
+ end
+}
-function settings.headphones()
- local menu = SettingsScreen("Headphones")
+local HeadphonesSettings = screen:new {
+ createUi = function(self)
+ self.menu = SettingsScreen("Headphones")
- theme.set_style(menu.content:Label {
+ theme.set_style(self.menu.content:Label {
text = "Maxiumum volume limit",
}, "settings_title")
- local volume_chooser = menu.content:Dropdown {
- options = "Line Level (-10 dB)\nCD Level (+6 dB)\nMaximum (+10dB)",
- selected = 1,
- }
- local limits = { -10, 6, 10 }
- volume_chooser:onevent(lvgl.EVENT.VALUE_CHANGED, function()
- -- luavgl dropdown binding uses 0-based indexing :(
- local selection = volume_chooser:get('selected') + 1
- volume.limit_db:set(limits[selection])
- end)
-
- theme.set_style(menu.content:Label {
+ local volume_chooser = self.menu.content:Dropdown {
+ options = "Line Level (-10 dB)\nCD Level (+6 dB)\nMaximum (+10dB)",
+ selected = 1,
+ }
+ local limits = { -10, 6, 10 }
+ volume_chooser:onevent(lvgl.EVENT.VALUE_CHANGED, function()
+ -- luavgl dropdown binding uses 0-based indexing :(
+ local selection = volume_chooser:get('selected') + 1
+ volume.limit_db:set(limits[selection])
+ end)
+
+ theme.set_style(self.menu.content:Label {
text = "Left/Right balance",
}, "settings_title")
- local balance = menu.content:Slider {
- w = lvgl.PCT(100),
- h = 5,
- range = { min = -100, max = 100 },
- value = 0,
- }
- balance:onevent(lvgl.EVENT.VALUE_CHANGED, function()
- volume.left_bias:set(balance:value())
- end)
+ local balance = self.menu.content:Slider {
+ w = lvgl.PCT(100),
+ h = 5,
+ range = { min = -100, max = 100 },
+ value = 0,
+ }
+ balance:onevent(lvgl.EVENT.VALUE_CHANGED, function()
+ volume.left_bias:set(balance:value())
+ end)
- local balance_label = menu.content:Label {}
+ local balance_label = self.menu.content:Label {}
- menu.bindings = {
- volume.limit_db:bind(function(limit)
- for i = 1, #limits do
- if limits[i] == limit then
- volume_chooser:set { selected = i - 1 }
+ self.bindings = {
+ volume.limit_db:bind(function(limit)
+ for i = 1, #limits do
+ if limits[i] == limit then
+ volume_chooser:set { selected = i - 1 }
+ end
end
- end
- end),
- volume.left_bias:bind(function(bias)
- balance:set {
- value = bias
- }
- if bias < 0 then
- balance_label:set {
- text = string.format("Left %.2fdB", bias / 4)
+ end),
+ volume.left_bias:bind(function(bias)
+ balance:set {
+ value = bias
}
- elseif bias > 0 then
- balance_label:set {
- text = string.format("Right %.2fdB", -bias / 4)
- }
- else
- balance_label:set { text = "Balanced" }
- end
- end),
- }
-
- return menu
-end
+ if bias < 0 then
+ balance_label:set {
+ text = string.format("Left %.2fdB", bias / 4)
+ }
+ elseif bias > 0 then
+ balance_label:set {
+ text = string.format("Right %.2fdB", -bias / 4)
+ }
+ else
+ balance_label:set { text = "Balanced" }
+ end
+ end),
+ }
+ end
+}
-function settings.display()
- local menu = SettingsScreen("Display")
+local DisplaySettings = screen:new {
+ createUi = function(self)
+ self.menu = SettingsScreen("Display")
- local brightness_title = menu.content:Object {
+ local brightness_title = self.menu.content:Object {
flex = {
flex_direction = "row",
justify_content = "flex-start",
@@ -198,91 +200,91 @@ function settings.display()
local brightness_pct = brightness_title:Label {}
theme.set_style(brightness_pct, "settings_title")
- local brightness = menu.content:Slider {
- w = lvgl.PCT(100),
- h = 5,
- range = { min = 0, max = 100 },
- value = display.brightness:get(),
- }
- brightness:onevent(lvgl.EVENT.VALUE_CHANGED, function()
- display.brightness:set(brightness:value())
- end)
-
- menu.bindings = {
- display.brightness:bind(function(b)
- brightness_pct:set { text = tostring(b) .. "%" }
+ local brightness = self.menu.content:Slider {
+ w = lvgl.PCT(100),
+ h = 5,
+ range = { min = 0, max = 100 },
+ value = display.brightness:get(),
+ }
+ brightness:onevent(lvgl.EVENT.VALUE_CHANGED, function()
+ display.brightness:set(brightness:value())
end)
- }
- return menu
-end
+ self.bindings = {
+ display.brightness:bind(function(b)
+ brightness_pct:set { text = tostring(b) .. "%" }
+ end)
+ }
+ end
+}
-function settings.input()
- local menu = SettingsScreen("Input Method")
+local InputSettings = screen:new {
+ createUi = function(self)
+ self.menu = SettingsScreen("Input Method")
- theme.set_style(menu.content:Label {
+ theme.set_style(self.menu.content:Label {
text = "Control scheme",
}, "settings_title")
- local schemes = controls.schemes()
- local option_to_scheme = {}
- local scheme_to_option = {}
+ local schemes = controls.schemes()
+ local option_to_scheme = {}
+ local scheme_to_option = {}
- local option_idx = 0
- local options = ""
+ local option_idx = 0
+ local options = ""
- for i, v in pairs(schemes) do
- option_to_scheme[option_idx] = i
- scheme_to_option[i] = option_idx
- if option_idx > 0 then
- options = options .. "\n"
+ for i, v in pairs(schemes) do
+ option_to_scheme[option_idx] = i
+ scheme_to_option[i] = option_idx
+ if option_idx > 0 then
+ options = options .. "\n"
+ end
+ options = options .. v
+ option_idx = option_idx + 1
end
- options = options .. v
- option_idx = option_idx + 1
- end
- local controls_chooser = menu.content:Dropdown {
- options = options,
- }
+ local controls_chooser = self.menu.content:Dropdown {
+ options = options,
+ }
- menu.bindings = {
- controls.scheme:bind(function(s)
- local option = scheme_to_option[s]
- controls_chooser:set({ selected = option })
- end)
- }
+ self.bindings = {
+ controls.scheme:bind(function(s)
+ local option = scheme_to_option[s]
+ controls_chooser:set({ selected = option })
+ end)
+ }
- controls_chooser:onevent(lvgl.EVENT.VALUE_CHANGED, function()
- local option = controls_chooser:get('selected')
- local scheme = option_to_scheme[option]
- controls.scheme:set(scheme)
- end)
+ controls_chooser:onevent(lvgl.EVENT.VALUE_CHANGED, function()
+ local option = controls_chooser:get('selected')
+ local scheme = option_to_scheme[option]
+ controls.scheme:set(scheme)
+ end)
- theme.set_style(menu.content:Label {
+ theme.set_style(self.menu.content:Label {
text = "Scroll Sensitivity",
}, "settings_title")
- local slider_scale = 4; -- Power steering
- local sensitivity = menu.content:Slider {
- w = lvgl.PCT(90),
- h = 5,
- range = { min = 0, max = 255/slider_scale },
- value = controls.scroll_sensitivity:get()/slider_scale,
- }
- sensitivity:onevent(lvgl.EVENT.VALUE_CHANGED, function()
- controls.scroll_sensitivity:set(sensitivity:value()*slider_scale)
- end)
-
- return menu
-end
+ local slider_scale = 4; -- Power steering
+ local sensitivity = self.menu.content:Slider {
+ w = lvgl.PCT(90),
+ h = 5,
+ range = { min = 0, max = 255 / slider_scale },
+ value = controls.scroll_sensitivity:get() / slider_scale,
+ }
+ sensitivity:onevent(lvgl.EVENT.VALUE_CHANGED, function()
+ controls.scroll_sensitivity:set(sensitivity:value() * slider_scale)
+ end)
+ end
+}
-function settings.database()
- local menu = SettingsScreen("Database")
- local db = require("database")
- widgets.Row(menu.content, "Schema version", db.version())
- widgets.Row(menu.content, "Size on disk", string.format("%.1f KiB", db.size() / 1024))
+local DatabaseSettings = screen:new {
+ createUi = function(self)
+ self.menu = SettingsScreen("Database")
+ local db = require("database")
+ widgets.Row(self.menu.content, "Schema version", db.version())
+ widgets.Row(self.menu.content, "Size on disk", string.format("%.1f KiB", db.size() / 1024))
- local actions_container = menu.content:Object {
+ local actions_container = self.menu.content:Object {
w = lvgl.PCT(100),
h = lvgl.SIZE_CONTENT,
flex = {
@@ -296,64 +298,69 @@ function settings.database()
}
actions_container:add_style(styles.list_item)
- local update = actions_container:Button {}
- update:Label { text = "Update" }
- update:onClicked(function()
- database.update()
- end)
-end
+ local update = actions_container:Button {}
+ update:Label { text = "Update" }
+ update:onClicked(function()
+ database.update()
+ end)
+ end
+}
+
+local FirmwareSettings = screen:new {
+ createUi = function(self)
+ self.menu = SettingsScreen("Firmware")
+ local version = require("version")
+ widgets.Row(self.menu.content, "ESP32", version.esp())
+ widgets.Row(self.menu.content, "SAMD21", version.samd())
+ widgets.Row(self.menu.content, "Collator", version.collator())
+ end
+}
-function settings.firmware()
- local menu = SettingsScreen("Firmware")
- local version = require("version")
- widgets.Row(menu.content, "ESP32", version.esp())
- widgets.Row(menu.content, "SAMD21", version.samd())
- widgets.Row(menu.content, "Collator", version.collator())
-end
+local LicensesScreen = screen:new {
+ createUi = function(self)
+ self.root = require("licenses")()
+ end
+}
-function settings.root()
- local menu = widgets.MenuScreen {
- show_back = true,
- title = "Settings",
- }
- menu.list = menu.root:List {
- w = lvgl.PCT(100),
- h = lvgl.PCT(100),
- flex_grow = 1,
- }
+return screen:new {
+ createUi = function(self)
+ self.menu = widgets.MenuScreen {
+ show_back = true,
+ title = "Settings",
+ }
+ self.list = self.menu.root:List {
+ w = lvgl.PCT(100),
+ h = lvgl.PCT(100),
+ flex_grow = 1,
+ }
local function section(name)
- local elem = menu.list:Label {
+ local elem = self.list:Label {
text = name,
pad_left = 4,
}
theme.set_style(elem, "settings_title")
end
- local function submenu(name, fn)
- local item = menu.list:add_btn(nil, name)
- item:onClicked(function()
- backstack.push(fn)
- end)
- item:add_style(styles.list_item)
- end
-
- section("Audio")
- submenu("Bluetooth", settings.bluetooth)
- submenu("Headphones", settings.headphones)
-
- section("Interface")
- submenu("Display", settings.display)
- submenu("Input Method", settings.input)
+ local function submenu(name, class)
+ local item = self.list:add_btn(nil, name)
+ item:onClicked(function()
+ backstack.push(class:new())
+ end)
+ item:add_style(styles.list_item)
+ end
- section("System")
- submenu("Database", settings.database)
- submenu("Firmware", settings.firmware)
- submenu("Licenses", function()
- return require("licenses")()
- end)
+ section("Audio")
+ submenu("Bluetooth", BluetoothSettings)
+ submenu("Headphones", HeadphonesSettings)
- return menu
-end
+ section("Interface")
+ submenu("Display", DisplaySettings)
+ submenu("Input Method", InputSettings)
-return settings
+ section("System")
+ submenu("Database", DatabaseSettings)
+ submenu("Firmware", FirmwareSettings)
+ submenu("Licenses", LicensesScreen)
+ end
+}