-- states/config_menu.lua — the options screens. -- -- These do NOT use modules/slider.lua. Values are changed through -- config.increase / config.decrease on the focused option, so the slider patch -- never sees them and this descriptor has to report the value itself. -- -- Three things move independently here: the tab (tabLeft/tabRight), the option -- (up/down), and the option's VALUE (left/right). All three must be announced, -- and the value especially -- pressing right with no feedback is indistinguishable -- from pressing a dead key. local config = require("models.config") local lastTab return { read = function(stateTable, menus) local activeTab = menus.getAnyUpvalue(stateTable, "activeTab") local selected = menus.getAnyUpvalue(stateTable, "currentSelectedOption") if type(activeTab) ~= "table" or type(selected) ~= "number" then return nil, nil end local options = activeTab.options if type(options) ~= "table" then return nil, nil end local option = options[selected] if not option then return nil, nil end local parts = {} if activeTab.header and activeTab.header ~= lastTab then lastTab = activeTab.header parts[#parts + 1] = activeTab.header end -- config.output returns (name, "< value >"). Strip the angle brackets: -- they are on-screen affordances for the left/right keys, not speech. local ok, name, value = pcall(config.output, option) if ok and name then parts[#parts + 1] = (name:gsub(":%s*$", "")) if value then parts[#parts + 1] = (value:gsub("^<%s*", ""):gsub("%s*>$", "")) end else parts[#parts + 1] = option.name or "?" end parts[#parts + 1] = selected .. " of " .. #options -- Key includes the value, so adjusting with left/right re-announces even -- though the focused option has not changed. local valueKey = ok and tostring(value) or "?" return table.concat(parts, ", "), table.concat({tostring(activeTab.header), tostring(selected), valueKey}, ":") end, }