114c8c5f72
The bar is host-owned chrome: the firmware clips apps into a viewport below it, so no app can paint over it, while /lib/statusbar.lua owns the height, repaint interval and painting. gui.fullscreen() lets touch calibration take the physical panel back. Launcher and settings become grids of square cards (3 across landscape, 2 portrait) via the new gui.setTextSize, ui.label and ui.cardSide. The one function on the `app` table moves to sys.setTickInterval, alongside the new sys.appName the bar needs.
111 lines
3.8 KiB
Lua
111 lines
3.8 KiB
Lua
-- Run: lua test/settings_calibration.lua
|
|
-- Drives the settings app on a desktop Lua, through the shared fake device.
|
|
package.path = "sdcard/lib/?.lua;test/?.lua;" .. package.path
|
|
|
|
local device = require("fake_device").install()
|
|
|
|
dofile("sdcard/apps/settings/main.lua")
|
|
|
|
local function tap(point)
|
|
on_touch_down(point.x, point.y)
|
|
on_touch_up(point.x, point.y)
|
|
end
|
|
|
|
-- Rows are found by their label rather than by a pixel row, because every hardcoded
|
|
-- coordinate silently retargets to the wrong control the day a row is inserted.
|
|
local targets = {}
|
|
local function tapRow(prefix)
|
|
device.painted = {}
|
|
draw()
|
|
local target
|
|
for _, item in ipairs(device.painted) do
|
|
targets[item.label] = item
|
|
-- First match wins: the status line at the bottom repeats a row's words back
|
|
-- ("timezone saved"), and tapping that hits nothing.
|
|
if not target and item.label:sub(1, #prefix) == prefix then target = item end
|
|
end
|
|
if not target then
|
|
for label, item in pairs(targets) do
|
|
if label:sub(1, #prefix) == prefix then target = item break end
|
|
end
|
|
end
|
|
if not target then error("no row labelled '" .. prefix .. "'") end
|
|
tap{x = target.x + 2, y = target.y + 2}
|
|
end
|
|
|
|
-- A perfectly linear panel spanning raw 200..3800 over 320x480 must round-trip
|
|
-- to those same extremes from the two inset samples.
|
|
local inset, w, h = 30, 320, 480
|
|
local function raw(pixel, size) return 200 + (3800 - 200) * pixel / size end
|
|
local s1 = {x = raw(inset, w), y = raw(inset, h)}
|
|
local s2 = {x = raw(w - inset, w), y = raw(h - inset, h)}
|
|
|
|
local x0, y0, x1, y1 = computeCalibration(s1, s2, w, h, inset)
|
|
assert(math.abs(x0 - 200) <= 1, "x0 " .. x0)
|
|
assert(math.abs(y0 - 200) <= 1, "y0 " .. y0)
|
|
assert(math.abs(x1 - 3800) <= 1, "x1 " .. x1)
|
|
assert(math.abs(y1 - 3800) <= 1, "y1 " .. y1)
|
|
|
|
-- A flipped panel (raw decreasing with pixel) must yield a descending range.
|
|
local s3 = {x = 3800 - raw(inset, w) + 200, y = s1.y}
|
|
local s4 = {x = 3800 - raw(w - inset, w) + 200, y = s2.y}
|
|
local fx0, _, fx1 = computeCalibration(s3, s4, w, h, inset)
|
|
assert(fx0 > fx1, "flipped axis should descend")
|
|
|
|
-- Timezone cycles through the picker list.
|
|
local zones = require("timezones")
|
|
init()
|
|
tapRow("timezone")
|
|
assert(sys.getTimezone() == zones[2].tz, "timezone " .. sys.getTimezone())
|
|
tapRow("timezone")
|
|
assert(sys.getTimezone() == zones[3].tz, "timezone " .. sys.getTimezone())
|
|
|
|
-- Rotation cycles through the four quarter turns and wraps back to 0.
|
|
init()
|
|
for _, expected in ipairs({90, 180, 270, 0}) do
|
|
tapRow("rotation")
|
|
assert(sys.getRotation() == expected, "rotation " .. sys.getRotation())
|
|
end
|
|
|
|
-- Calibration collects one sample per target and saves on the second release.
|
|
init()
|
|
tapRow("calibrate")
|
|
on_tick() -- release after the menu tap arms sampling
|
|
device.raw = {s1.x, s1.y}
|
|
on_tick()
|
|
device.raw = nil
|
|
on_tick()
|
|
device.raw = {s2.x, s2.y}
|
|
on_tick()
|
|
device.raw = nil
|
|
on_tick()
|
|
local saved = device.calibration
|
|
assert(saved, "calibration was not saved")
|
|
assert(math.abs(saved[1] - 200) <= 1, "saved x0 " .. saved[1])
|
|
|
|
-- Open networks connect directly from scan results.
|
|
init()
|
|
device.networks = {{ssid = "qemu", rssi = -25, secure = false}}
|
|
tapRow("wifi")
|
|
tapRow("scan networks")
|
|
on_tick()
|
|
tapRow("qemu")
|
|
assert(device.connected, "open network should connect without a keyboard")
|
|
assert(device.connected[1] == "qemu" and device.connected[2] == "", "open wifi connect")
|
|
|
|
-- Secure networks route through the keyboard and preserve typed punctuation.
|
|
init()
|
|
device.networks = {{ssid = "secure", rssi = -40, secure = true}}
|
|
tapRow("wifi")
|
|
tapRow("scan networks")
|
|
on_tick()
|
|
tapRow("secure")
|
|
on_tick()
|
|
tapRow("q") -- keyboard key
|
|
tapRow("connect")
|
|
assert(#device.painted == 1,
|
|
"typing rebuilt the keyboard instead of repainting the password")
|
|
assert(device.connected[1] == "secure" and device.connected[2] == "q", "secure wifi password")
|
|
|
|
print("ok")
|