feat(ui): default controller navigation on and set starting focus to Layer 3 (Import/Play)

This commit is contained in:
Shane McGovern
2026-08-26 12:50:12 +01:00
parent f5f9e60b3c
commit 9886920c7a
2 changed files with 27 additions and 16 deletions
+2 -2
View File
@@ -3360,9 +3360,9 @@ end
function RomImporter:gamepadaxis(_, axis, value) function RomImporter:gamepadaxis(_, axis, value)
if axis == "leftx" or axis == "lefty" or axis == "righty" then if axis == "leftx" or axis == "lefty" or axis == "righty" then
self._padAxis[axis] = value self._padAxis[axis] = value
if math.abs(value) > PAD_DEAD then if self._padCursorActive and math.abs(value) > PAD_DEAD then
self:_activatePadCursor() self:_activatePadCursor()
elseif axis == "lefty" then elseif axis == "lefty" and math.abs(value) <= PAD_DEAD then
self._padStickCentered = true self._padStickCentered = true
end end
end end
+25 -14
View File
@@ -352,10 +352,26 @@ function Kit.endFrame()
-- This frame's focusables become next frame's navigation graph. -- This frame's focusables become next frame's navigation graph.
local n = Kit._navN or 0 local n = Kit._navN or 0
Kit._navPrevN = n Kit._navPrevN = n
-- If the focused id vanished (panel switch, list repaged), park the ring -- If the focused id vanished or not set yet, park the ring on Layer 3 (Import ROM / Play)
-- on the first focusable so the keyboard is never stranded. if (not Kit.focusId or not Kit._navSeen[Kit.focusId]) and n > 0 then
if Kit.focusId and not Kit._navSeen[Kit.focusId] and n > 0 then -- 1. Prefer ROM Action (Layer 3)
Kit.focusId = Kit._nav[1] and Kit._nav[1].id or nil local chosen = nil
for i = 1, n do
local slot = Kit._nav[i]
if slot and slot.id and tostring(slot.id):match("^rom%-") then
chosen = slot.id; break
end
end
-- 2. Prefer any Layer 3 control
if not chosen then
for i = 1, n do
local slot = Kit._nav[i]
if slot and getNavLayer(slot) == 3 then
chosen = slot.id; break
end
end
end
Kit.focusId = chosen or (Kit._nav[1] and Kit._nav[1].id) or nil
end end
for k in pairs(Kit._navSeen) do Kit._navSeen[k] = nil end for k in pairs(Kit._navSeen) do Kit._navSeen[k] = nil end
end end
@@ -363,21 +379,16 @@ end
-- ------------------------------------------------------------ focus ring -- ------------------------------------------------------------ focus ring
-- Spatial navigation. Every focusable control registers its rect as it -- Spatial navigation. Every focusable control registers its rect as it
-- draws; a queued direction picks the nearest candidate in that direction -- draws; a queued direction picks the nearest candidate in that direction
-- from the previous frame's set. Spatial rather than index-order because -- from the previous frame's set.
-- the launcher is a multi-column layout: tab-order would zigzag between
-- columns, while "press right, go right" is what both a keyboard and a
-- d-pad user expects.
Kit._nav = {} Kit._nav = {}
Kit._navN = 0 Kit._navN = 0
Kit._navPrevN = 0 Kit._navPrevN = 0
Kit._navSeen = {} Kit._navSeen = {}
Kit._navQueue = nil Kit._navQueue = nil
Kit._activateId = nil Kit._activateId = nil
Kit._ringShown = false Kit._ringShown = true
-- Register a focusable. Returns true when it currently holds the ring. -- Register a focusable. Returns true when it currently holds the ring.
-- Shielded widgets do not register: while a modal owns the frame the ring
-- must not wander through (or Enter-activate) the controls underneath it.
function Kit.focusable(id, x, y, w, h) function Kit.focusable(id, x, y, w, h)
if Kit.blockClicks then return false end if Kit.blockClicks then return false end
local n = (Kit._navN or 0) + 1 local n = (Kit._navN or 0) + 1
@@ -386,9 +397,9 @@ function Kit.focusable(id, x, y, w, h)
if not slot then slot = {}; Kit._nav[n] = slot end if not slot then slot = {}; Kit._nav[n] = slot end
slot.id, slot.x, slot.y, slot.w, slot.h = id, x, y, w, h slot.id, slot.x, slot.y, slot.w, slot.h = id, x, y, w, h
Kit._navSeen[id] = true Kit._navSeen[id] = true
-- First focusable ever drawn adopts the ring, so keyboard users start if Kit.focusId == nil and tostring(id):match("^rom%-") then
-- somewhere rather than nowhere. Kit.focusId = id
if Kit.focusId == nil then Kit.focusId = id end end
return Kit._ringShown and Kit.focusId == id return Kit._ringShown and Kit.focusId == id
end end