feat(ui): 优化购卡键盘渲染逻辑与单程区间选中样式
- 重构 showCardNameInput 渲染逻辑,添加 renderInput 局部更新,解决按键闪烁问题 - 优化单程区间的选中样式,移除文本前缀,改为绿色背景高亮,与购票界面保持一致 - 更新版本号至 v1.5.30
This commit is contained in:
+62
-29
@@ -1,6 +1,6 @@
|
|||||||
local CURRENT_STATION_CODE = 'Ticket-Machine'
|
local CURRENT_STATION_CODE = 'Ticket-Machine'
|
||||||
local API_BASE = 'https://ticket.fse-media.group/api'
|
local API_BASE = 'https://ticket.fse-media.group/api'
|
||||||
local VERSION = 'v1.5.29'
|
local VERSION = 'v1.5.30'
|
||||||
local UPDATE_CHECK_INTERVAL = 5
|
local UPDATE_CHECK_INTERVAL = 5
|
||||||
|
|
||||||
-- ###########################
|
-- ###########################
|
||||||
@@ -1435,10 +1435,11 @@ local function showSingleSegmentSelection()
|
|||||||
local lineColor = nearestCCColor(seg.color)
|
local lineColor = nearestCCColor(seg.color)
|
||||||
local textColor = contrastTextColor(lineColor)
|
local textColor = contrastTextColor(lineColor)
|
||||||
local isSelected = (state.singleSegment == seg)
|
local isSelected = (state.singleSegment == seg)
|
||||||
|
local bg = isSelected and colors.green or lineColor
|
||||||
|
local fg = isSelected and colors.white or textColor
|
||||||
local label = seg.lineName .. ' ' .. tostring(seg.cost) .. 'c'
|
local label = seg.lineName .. ' ' .. tostring(seg.cost) .. 'c'
|
||||||
if isSelected then label = '>' .. label end
|
|
||||||
if #label > bw then label = label:sub(1, bw) end
|
if #label > bw then label = label:sub(1, bw) end
|
||||||
addButton(x, y, label, bw, 3, {lineColor, textColor}, function()
|
addButton(x, y, label, bw, 3, {bg, fg}, function()
|
||||||
state.singleSegment = seg
|
state.singleSegment = seg
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
@@ -1579,6 +1580,25 @@ local function showCardNameInput()
|
|||||||
{'+'}
|
{'+'}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
local function clearLine(y)
|
||||||
|
termDev.setBackgroundColor(colors.black)
|
||||||
|
termDev.setCursorPos(1, y)
|
||||||
|
termDev.write(string.rep(' ', w))
|
||||||
|
end
|
||||||
|
|
||||||
|
local function renderInput()
|
||||||
|
local placeholder = name
|
||||||
|
if #placeholder == 0 then
|
||||||
|
placeholder = 'ENTER NAME'
|
||||||
|
elseif #placeholder > (w - 8) then
|
||||||
|
placeholder = '...' .. placeholder:sub(-(w - 11))
|
||||||
|
end
|
||||||
|
clearLine(4)
|
||||||
|
clearLine(5)
|
||||||
|
centerText(4, '[' .. placeholder .. ']', colors.yellow)
|
||||||
|
if msg and #msg > 0 then centerText(5, msg, msgCol) end
|
||||||
|
end
|
||||||
|
|
||||||
local function isAllowedHolderChar(ch)
|
local function isAllowedHolderChar(ch)
|
||||||
if type(ch) ~= 'string' or #ch ~= 1 then return false end
|
if type(ch) ~= 'string' or #ch ~= 1 then return false end
|
||||||
if ch:match('[A-Za-z ]') then return true end
|
if ch:match('[A-Za-z ]') then return true end
|
||||||
@@ -1590,19 +1610,14 @@ local function showCardNameInput()
|
|||||||
if ch:match('[A-Za-z]') then ch = ch:upper() end
|
if ch:match('[A-Za-z]') then ch = ch:upper() end
|
||||||
if ch == ' ' and (#name == 0 or name:sub(-1) == ' ') then return end
|
if ch == ' ' and (#name == 0 or name:sub(-1) == ' ') then return end
|
||||||
name = name .. ch
|
name = name .. ch
|
||||||
|
msg = ''
|
||||||
|
renderInput()
|
||||||
end
|
end
|
||||||
|
|
||||||
while state.page == 'card_name' do
|
while state.page == 'card_name' do
|
||||||
local placeholder = name
|
|
||||||
if #placeholder == 0 then
|
|
||||||
placeholder = 'ENTER NAME'
|
|
||||||
elseif #placeholder > (w - 8) then
|
|
||||||
placeholder = '...' .. placeholder:sub(-(w - 11))
|
|
||||||
end
|
|
||||||
local rows = (keyboardMode == 'symbol') and symbolRows or alphaRows
|
local rows = (keyboardMode == 'symbol') and symbolRows or alphaRows
|
||||||
drawHeader('Enter Holder Name', (keyboardMode == 'symbol') and 'Symbol keyboard' or 'Letters / symbols / space')
|
drawHeader('Enter Holder Name', (keyboardMode == 'symbol') and 'Symbol keyboard' or 'Letters / symbols / space')
|
||||||
centerText(4, '[' .. placeholder .. ']', colors.yellow)
|
renderInput()
|
||||||
if msg and #msg > 0 then centerText(5, msg, msgCol) end
|
|
||||||
Buttons = {}
|
Buttons = {}
|
||||||
local keyW, keyH = (w < 44 and 2 or 3), 2
|
local keyW, keyH = (w < 44 and 2 or 3), 2
|
||||||
local sY = 7
|
local sY = 7
|
||||||
@@ -1621,36 +1636,54 @@ local function showCardNameInput()
|
|||||||
appendHolderChar(' ')
|
appendHolderChar(' ')
|
||||||
end)
|
end)
|
||||||
addButton(2, h-3, '<-back', 8, 3, {colors.black, colors.red}, function() state.page = 'card_home' end)
|
addButton(2, h-3, '<-back', 8, 3, {colors.black, colors.red}, function() state.page = 'card_home' end)
|
||||||
|
|
||||||
|
local currentKeyboardMode = keyboardMode
|
||||||
addButton(12, h-3, (keyboardMode == 'symbol') and 'ABC' or 'SYM', 8, 3, {colors.black, colors.orange}, function()
|
addButton(12, h-3, (keyboardMode == 'symbol') and 'ABC' or 'SYM', 8, 3, {colors.black, colors.orange}, function()
|
||||||
keyboardMode = (keyboardMode == 'symbol') and 'alpha' or 'symbol'
|
keyboardMode = (keyboardMode == 'symbol') and 'alpha' or 'symbol'
|
||||||
end)
|
end)
|
||||||
addButton(w-31, h-3, 'BKSP', 8, 3, {colors.black, colors.red}, function() name = name:sub(1, -2) end)
|
|
||||||
addButton(w-21, h-3, 'CLEAR', 8, 3, {colors.black, colors.red}, function() name = '' end)
|
addButton(w-31, h-3, 'BKSP', 8, 3, {colors.black, colors.red}, function()
|
||||||
|
name = name:sub(1, -2)
|
||||||
|
msg = ''
|
||||||
|
renderInput()
|
||||||
|
end)
|
||||||
|
addButton(w-21, h-3, 'CLEAR', 8, 3, {colors.black, colors.red}, function()
|
||||||
|
name = ''
|
||||||
|
msg = ''
|
||||||
|
renderInput()
|
||||||
|
end)
|
||||||
addButton(w-11, h-3, 'NEXT->', 10, 3, {colors.black, colors.green}, function()
|
addButton(w-11, h-3, 'NEXT->', 10, 3, {colors.black, colors.green}, function()
|
||||||
local clean = firstString(name)
|
local clean = firstString(name)
|
||||||
if #clean < 2 then
|
if #clean < 2 then
|
||||||
msg, msgCol = 'Name too short', colors.red
|
msg, msgCol = 'Name too short', colors.red
|
||||||
|
renderInput()
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
state.holderName = clean
|
state.holderName = clean
|
||||||
state.page = 'card_topup'
|
state.page = 'card_topup'
|
||||||
end)
|
end)
|
||||||
local ev, p1, p2, p3 = os.pullEvent()
|
|
||||||
if ev == 'mouse_click' or ev == 'monitor_touch' then
|
while state.page == 'card_name' and keyboardMode == currentKeyboardMode do
|
||||||
for _, b in ipairs(Buttons) do
|
local ev, p1, p2, p3 = os.pullEvent()
|
||||||
if inRect(b, p2, p3) then clickSound(); if b.onClick then b.onClick() end; break end
|
if ev == 'mouse_click' or ev == 'monitor_touch' then
|
||||||
end
|
for _, b in ipairs(Buttons) do
|
||||||
elseif ev == 'char' then
|
if inRect(b, p2, p3) then clickSound(); if b.onClick then b.onClick() end; break end
|
||||||
appendHolderChar(tostring(p1 or ''))
|
end
|
||||||
elseif ev == 'key' and p1 == keys.backspace then
|
elseif ev == 'char' then
|
||||||
name = name:sub(1, -2)
|
appendHolderChar(tostring(p1 or ''))
|
||||||
elseif ev == 'key' and (p1 == keys.enter or p1 == keys.numPadEnter) then
|
elseif ev == 'key' and p1 == keys.backspace then
|
||||||
local clean = firstString(name)
|
name = name:sub(1, -2)
|
||||||
if #clean >= 2 then
|
msg = ''
|
||||||
state.holderName = clean
|
renderInput()
|
||||||
state.page = 'card_topup'
|
elseif ev == 'key' and (p1 == keys.enter or p1 == keys.numPadEnter) then
|
||||||
else
|
local clean = firstString(name)
|
||||||
msg, msgCol = 'Name too short', colors.red
|
if #clean >= 2 then
|
||||||
|
state.holderName = clean
|
||||||
|
state.page = 'card_topup'
|
||||||
|
else
|
||||||
|
msg, msgCol = 'Name too short', colors.red
|
||||||
|
renderInput()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user