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