components_ui_buttongroup_JRButtonGroup.bs
import "pkg:/source/utils/misc.bs"
sub init()
m.top.layoutDirection = "horiz"
m.top.itemSpacings = 24
m.top.buttonFocused = 0
' Observe focus on the group to set child button focus
m.top.observeField("focusedChild", "onGroupFocusChanged")
end sub
sub onGroupFocusChanged()
' When group gains focus, set focus on the current button
if m.top.hasFocus() and m.top.buttonFocused <> invalid
button = m.top.getChild(m.top.buttonFocused)
if button <> invalid
button.setFocus(true)
end if
end if
end sub
' center the button group horizontally
' NOTE: this centers using the entire screen width, not the parent bounding rect
sub center()
' Check if any child buttons have a 'ready' field that's not yet true
' (This handles TextButtons that need to finish sizing before we can center)
allReady = true
for i = 0 to m.top.getChildCount() - 1
child = m.top.getChild(i)
if child <> invalid and child.hasField("ready") and not child.ready
allReady = false
' Observe this child's ready field if not already observing
if m.observingReadyFields = invalid
m.observingReadyFields = []
end if
' Check if we're already observing this child
alreadyObserving = false
for each observedChild in m.observingReadyFields
if observedChild.isSameNode(child)
alreadyObserving = true
exit for
end if
end for
if not alreadyObserving
child.observeField("ready", "onChildReady")
m.observingReadyFields.push(child)
end if
end if
end for
' If all children are ready (or don't have ready fields), center now
if allReady
doCentering()
end if
end sub
' Called when a child button becomes ready
sub onChildReady()
' Try centering again - this will check if ALL children are now ready
center()
end sub
' Actually perform the centering calculation
sub doCentering()
buttonsBoundingRect = m.top.boundingRect()
m.top.translation = [(1920 - buttonsBoundingRect.width) / 2, m.top.translation[1]]
end sub
' Use instead of setFocus(true)
sub focus()
m.top.setFocus(true)
if m.top.buttonFocused <> invalid
button = m.top.getChild(m.top.buttonFocused)
if button <> invalid
button.setFocus(true)
end if
end if
end sub
function onKeyEvent(key as string, press as boolean) as boolean
if not press then return false
currentFocus = m.top.buttonFocused
currentFocusButton = m.top.getChild(currentFocus)
' print "currentFocus =", currentFocus
' print "currentFocusButton =", currentFocusButton
' print "m.top.getChildCount() =", m.top.getChildCount()
if key = "right"
' Move right, skipping disabled buttons and non-button nodes
for i = currentFocus + 1 to m.top.getChildCount() - 1
button = m.top.getChild(i)
' Skip non-button nodes (Animation, etc)
if isValid(button) and button.hasField("enabled") and button.enabled
currentFocusButton.setFocus(false)
m.top.buttonFocused = i
button.setFocus(true)
return true
end if
end for
' wrap if needed
for i = 0 to currentFocus - 1
button = m.top.getChild(i)
' Skip non-button nodes (Animation, etc)
if isValid(button) and button.hasField("enabled") and button.enabled
currentFocusButton.setFocus(false)
m.top.buttonFocused = i
button.setFocus(true)
return true
end if
end for
else if key = "left"
' Move left, skipping disabled buttons and non-button nodes
for i = currentFocus - 1 to 0 step -1
button = m.top.getChild(i)
' Skip non-button nodes (Animation, etc)
if isValid(button) and button.hasField("enabled") and button.enabled
currentFocusButton.setFocus(false)
m.top.buttonFocused = i
button.setFocus(true)
return true
end if
end for
' wrap if needed
for i = m.top.getChildCount() - 1 to currentFocus + 1 step -1
button = m.top.getChild(i)
' Skip non-button nodes (Animation, etc)
if isValid(button) and button.hasField("enabled") and button.enabled
currentFocusButton.setFocus(false)
m.top.buttonFocused = i
button.setFocus(true)
return true
end if
end for
end if
if key = "OK"
print "OK pressed from JRButtonGroup, buttonFocused =", m.top.buttonFocused
m.top.buttonSelected = m.top.buttonFocused
return true
end if
return false
end function