import "pkg:/source/utils/misc.bs" const LOGO_RIGHT_PADDING = 30 const OPTIONCONTROLS_TOP_PADDING = 50 sub init() m.videoControls = m.top.findNode("videoControls") m.optionControls = m.top.findNode("optionControls") m.inactivityTimer = m.top.findNode("inactivityTimer") m.videoInfo = m.top.findNode("videoInfo") m.itemTitle = m.top.findNode("itemTitle") m.videoPlayPause = m.top.findNode("videoPlayPause") m.videoPositionTime = m.top.findNode("videoPositionTime") m.videoRemainingTime = m.top.findNode("videoRemainingTime") m.progressBar = m.top.findNode("progressBar") m.progressBarBackground = m.top.findNode("progressBarBackground") m.top.observeField("visible", "onVisibleChanged") m.top.observeField("hasFocus", "onFocusChanged") m.top.observeField("progressPercentage", "onProgressPercentageChanged") m.top.observeField("playbackState", "onPlaybackStateChanged") m.top.observeField("itemTitleText", "onItemTitleTextChanged") m.top.observeField("seasonNumber", "onSeasonNumberChanged") m.top.observeField("episodeNumber", "onEpisodeNumberChanged") m.top.observeField("episodeNumberEnd", "onEpisodeNumberEndChanged") m.top.observeField("logoImage", "onLogoImageChanged") m.defaultButtonIndex = 2 m.focusedButtonIndex = 2 m.optionControlsMoved = false m.videoControls.buttonFocused = m.defaultButtonIndex m.optionControls.buttonFocused = m.optionControls.getChildCount() - 1 m.videoControls.getChild(m.defaultButtonIndex).focus = true m.deviceInfo = CreateObject("roDeviceInfo") end sub ' onProgressPercentageChanged: Handler for changes to m.top.progressPercentage param ' sub onProgressPercentageChanged() m.videoPositionTime.text = secondsToHuman(m.top.positionTime, true) m.videoRemainingTime.text = secondsToHuman(m.top.remainingPositionTime, true) m.progressBar.width = m.progressBarBackground.width * m.top.progressPercentage end sub ' onPlaybackStateChanged: Handler for changes to m.top.playbackState param ' sub onPlaybackStateChanged() if LCase(m.top.playbackState) = "playing" m.videoPlayPause.icon = "pkg:/images/icons/pause.png" return end if m.videoPlayPause.icon = "pkg:/images/icons/play.png" end sub ' onItemTitleTextChanged: Handler for changes to m.top.itemTitleText param. ' sub onItemTitleTextChanged() m.itemTitle.text = m.top.itemTitleText end sub ' onSeasonNumberChanged: Handler for changes to m.top.seasonNumber param. ' sub onSeasonNumberChanged() m.top.unobserveField("seasonNumber") itemSeason = m.top.findNode("itemSeason") itemSeason.font.size = 32 itemSeason.text = `S${m.top.seasonNumber}` ' Move the option controls down to give room for season number if not m.optionControlsMoved moveOptionControls(0, OPTIONCONTROLS_TOP_PADDING) m.optionControlsMoved = true end if end sub ' onEpisodeNumberChanged: Handler for changes to m.top.episodeNumber param. ' sub onEpisodeNumberChanged() m.top.unobserveField("episodeNumber") itemEpisode = m.top.findNode("itemEpisode") itemEpisode.font.size = 32 itemEpisode.text = `E${m.top.episodeNumber}` ' Move the option controls down to give room for episode number if not m.optionControlsMoved moveOptionControls(0, OPTIONCONTROLS_TOP_PADDING) m.optionControlsMoved = true end if end sub ' onEpisodeNumberEndChanged: Handler for changes to m.top.episodeNumberEnd param. ' sub onEpisodeNumberEndChanged() m.top.unobserveField("episodeNumberEnd") itemEpisodeEnd = m.top.findNode("itemEpisodeEnd") itemEpisodeEnd.font.size = 32 itemEpisodeEnd.text = `-${m.top.episodeNumberEnd}` ' Move the option controls down to give room for episode number if not m.optionControlsMoved moveOptionControls(0, OPTIONCONTROLS_TOP_PADDING) m.optionControlsMoved = true end if end sub ' moveOptionControls: Moves option controls node based on passed pixel values ' ' @param {integer} horizontalPixels - Number of horizontal pixels to move option controls ' @param {integer} verticalPixels - Number of vertical pixels to move option controls sub moveOptionControls(horizontalPixels as integer, verticalPixels as integer) m.optionControls.translation = `[${m.optionControls.translation[0] + horizontalPixels}, ${m.optionControls.translation[1] + verticalPixels}]` end sub ' onLogoLoadStatusChanged: Handler for changes to logo image's status. ' ' @param {dynamic} event - field change event sub onLogoLoadStatusChanged(event) if LCase(event.GetData()) = "ready" logoImage = event.getRoSGNode() logoImage.unobserveField("loadStatus") ' Move video info to the right based on the logo width m.videoInfo.translation = `[${m.videoInfo.translation[0] + logoImage.bitmapWidth + LOGO_RIGHT_PADDING}, ${m.videoInfo.translation[1]}]` m.itemTitle.maxWidth = m.itemTitle.maxWidth - (logoImage.bitmapWidth + LOGO_RIGHT_PADDING) ' Move the option controls down based on the logo height if not m.optionControlsMoved moveOptionControls(0, OPTIONCONTROLS_TOP_PADDING) m.optionControlsMoved = true end if end if end sub ' onLogoImageChanged: Handler for changes to m.top.logoImage param. ' sub onLogoImageChanged() if isValidAndNotEmpty(m.top.logoImage) logoImage = createObject("roSGNode", "Poster") logoImage.Id = "logoImage" logoImage.observeField("loadStatus", "onLogoLoadStatusChanged") logoImage.uri = m.top.logoImage logoImage.translation = [103, 61] m.top.appendChild(logoImage) end if end sub ' resetFocusToDefaultButton: Reset focus back to the default button ' sub resetFocusToDefaultButton() ' Remove focus from previously selected button for each child in m.videoControls.getChildren(-1, 0) if isValid(child.focus) child.focus = false end if end for for each child in m.optionControls.getChildren(-1, 0) if isValid(child.focus) child.focus = false end if end for m.optionControls.setFocus(false) ' Set focus back to the default button m.videoControls.setFocus(true) m.focusedButtonIndex = m.defaultButtonIndex m.videoControls.getChild(m.defaultButtonIndex).focus = true m.videoControls.buttonFocused = m.defaultButtonIndex m.optionControls.buttonFocused = m.optionControls.getChildCount() - 1 end sub ' onVisibleChanged: Handler for changes to the visibility of this menu. ' sub onVisibleChanged() if m.top.visible resetFocusToDefaultButton() m.inactivityTimer.observeField("fire", "inactiveCheck") m.inactivityTimer.control = "start" return end if m.inactivityTimer.unobserveField("fire") m.inactivityTimer.control = "stop" end sub ' onFocusChanged: Handler for changes to the focus of this menu. ' sub onFocusChanged() if m.top.hasfocus focusedButton = m.optionControls.getChild(m.focusedButtonIndex) if focusedButton.focus m.optionControls.setFocus(true) return end if m.videoControls.setFocus(true) end if end sub ' inactiveCheck: Checks if the time since last keypress is greater than or equal to the allowed inactive time of the menu. ' sub inactiveCheck() ' If user is currently seeing a dialog box, ignore inactive check if m.global.sceneManager.callFunc("isDialogOpen") return end if if m.deviceInfo.timeSinceLastKeypress() >= m.top.inactiveTimeout m.top.action = "hide" end if end sub ' onButtonSelected: Handler for selection of buttons from the menu. ' sub onButtonSelected() if m.optionControls.isInFocusChain() buttonGroup = m.optionControls else buttonGroup = m.videoControls end if selectedButton = buttonGroup.getChild(m.focusedButtonIndex) if LCase(selectedButton.id) = "chapterlist" m.top.showChapterList = not m.top.showChapterList end if m.top.action = selectedButton.id end sub function onKeyEvent(key as string, press as boolean) as boolean if not press then return false if key = "OK" onButtonSelected() return true end if if key = "play" m.top.action = "videoplaypause" return true end if if key = "right" if m.optionControls.isInFocusChain() buttonGroup = m.optionControls else buttonGroup = m.videoControls end if if m.focusedButtonIndex + 1 >= buttonGroup.getChildCount() return true end if focusedButton = buttonGroup.getChild(m.focusedButtonIndex) focusedButton.focus = false ' Skip spacer elements until next button is found for i = m.focusedButtonIndex + 1 to buttonGroup.getChildCount() m.focusedButtonIndex = i focusedButton = buttonGroup.getChild(m.focusedButtonIndex) if isValid(focusedButton.focus) buttonGroup.buttonFocused = m.focusedButtonIndex focusedButton.focus = true exit for end if end for return true end if if key = "left" if m.focusedButtonIndex = 0 return true end if if m.optionControls.isInFocusChain() buttonGroup = m.optionControls else buttonGroup = m.videoControls end if focusedButton = buttonGroup.getChild(m.focusedButtonIndex) focusedButton.focus = false ' Skip spacer elements until next button is found for i = m.focusedButtonIndex - 1 to 0 step -1 m.focusedButtonIndex = i focusedButton = buttonGroup.getChild(m.focusedButtonIndex) if isValid(focusedButton.focus) buttonGroup.buttonFocused = m.focusedButtonIndex focusedButton.focus = true exit for end if end for return true end if if key = "up" if m.videoControls.isInFocusChain() focusedButton = m.videoControls.getChild(m.focusedButtonIndex) focusedButton.focus = false m.videoControls.setFocus(false) m.focusedButtonIndex = m.optionControls.buttonFocused focusedButton = m.optionControls.getChild(m.focusedButtonIndex) focusedButton.focus = true m.optionControls.setFocus(true) end if return true end if if key = "down" if m.optionControls.isInFocusChain() focusedButton = m.optionControls.getChild(m.focusedButtonIndex) focusedButton.focus = false m.optionControls.setFocus(false) m.focusedButtonIndex = m.videoControls.buttonFocused focusedButton = m.videoControls.getChild(m.focusedButtonIndex) focusedButton.focus = true m.videoControls.setFocus(true) end if return true end if ' All other keys hide the menu m.top.action = "hide" return true end function