Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create pause menu #1461

Merged
merged 10 commits into from
Nov 10, 2023
39 changes: 39 additions & 0 deletions components/Clock.bs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import "pkg:/source/utils/misc.brs"

sub init()

' If hideclick setting is checked, exit without setting any variables
if m.global.session.user.settings["ui.design.hideclock"]
return
end if

m.clockTime = m.top.findNode("clockTime")

m.currentTimeTimer = m.top.findNode("currentTimeTimer")
m.dateTimeObject = CreateObject("roDateTime")

m.currentTimeTimer.observeField("fire", "onCurrentTimeTimerFire")
m.currentTimeTimer.control = "start"

' Default to 12 hour clock
m.format = "short-h12"

' If user has selected a 24 hour clock, update date display format
if LCase(m.global.device.clockFormat) = "24h"
m.format = "short-h24"
end if
end sub


' onCurrentTimeTimerFire: Code that runs every time the currentTimeTimer fires
'
sub onCurrentTimeTimerFire()
' Refresh time variable
m.dateTimeObject.Mark()

' Convert to local time zone
m.dateTimeObject.ToLocalTime()

' Format time as requested
m.clockTime.text = m.dateTimeObject.asTimeStringLoc(m.format)
end sub
9 changes: 9 additions & 0 deletions components/Clock.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<component name="Clock" extends="Group">
<children>
<Label id="clockTime" font="font:SmallSystemFont" horizAlign="right" vertAlign="center" height="64" width="200" />
<Timer id="currentTimeTimer" repeat="true" duration="1" />
</children>
<interface>
</interface>
</component>
1 change: 1 addition & 0 deletions components/ItemGrid/LoadVideoContentTask.brs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ sub LoadItems_AddVideoContent(video as object, mediaSourceId as dynamic, audio_s
video.content.contenttype = "episode"
end if

video.chapters = meta.json.Chapters
video.content.title = meta.title
video.showID = meta.showID

Expand Down
227 changes: 227 additions & 0 deletions components/video/PauseMenu.bs
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
import "pkg:/source/utils/misc.brs"

sub init()
m.videoControls = m.top.findNode("videoControls")
m.optionControls = m.top.findNode("optionControls")

m.inactivityTimer = m.top.findNode("inactivityTimer")
m.itemTitle = m.top.findNode("itemTitle")
m.videoPlayPause = m.top.findNode("videoPlayPause")

m.top.observeField("visible", "onVisibleChanged")
m.top.observeField("hasFocus", "onFocusChanged")
m.top.observeField("playbackState", "onPlaybackStateChanged")
m.top.observeField("itemTitleText", "onItemTitleTextChanged")

m.defaultButtonIndex = 1
m.focusedButtonIndex = 1

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

' 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

' 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 = 1
m.optionControls.buttonFocused = m.optionControls.getChildCount() - 1
end sub

' onVisibleChanged: Handler for changes to the visibility of this pause 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 pause 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 pause menu.
'
sub inactiveCheck()
if m.deviceInfo.timeSinceLastKeypress() >= m.top.inactiveTimeout
m.top.action = "hide"
end if
end sub

' onButtonSelected: Handler for selection of buttons from the pause 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
29 changes: 29 additions & 0 deletions components/video/PauseMenu.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<component name="PauseMenu" extends="Group" initialFocus="chapterNext">
<children>
<Label id="itemTitle" font="font:LargeBoldSystemFont" translation="[103,61]" />
<Clock id="clock" translation="[1618, 46]" />

<ButtonGroup id="optionControls" itemSpacings="[20]" layoutDirection="horiz" horizAlignment="left" translation="[103,120]">
<IconButton id="showVideoInfoPopup" background="#070707" focusBackground="#00a4dc" padding="16" icon="pkg:/images/icons/videoInfo.png" height="65" width="100" />
<IconButton id="chapterList" background="#070707" focusBackground="#00a4dc" padding="16" icon="pkg:/images/icons/numberList.png" height="65" width="100" />
<IconButton id="showSubtitleMenu" background="#070707" focusBackground="#00a4dc" padding="0" icon="pkg:/images/icons/subtitle.png" height="65" width="100" />
</ButtonGroup>

<ButtonGroup id="videoControls" itemSpacings="[20]" layoutDirection="horiz" horizAlignment="center" translation="[960,950]">
<IconButton id="chapterBack" background="#070707" focusBackground="#00a4dc" padding="16" icon="pkg:/images/icons/previousChapter.png" height="65" width="100" />
<IconButton id="videoPlayPause" background="#070707" focusBackground="#00a4dc" padding="35" icon="pkg:/images/icons/play.png" height="65" width="100" />
<IconButton id="chapterNext" background="#070707" focusBackground="#00a4dc" padding="16" icon="pkg:/images/icons/nextChapter.png" height="65" width="100" />
</ButtonGroup>

<Timer id="inactivityTimer" duration="1" repeat="true" />
</children>
<interface>
<field id="itemTitleText" type="string" />
<field id="inactiveTimeout" type="integer" />
<field id="playbackState" type="string" alwaysNotify="true" />
<field id="action" type="string" alwaysNotify="true" />
<field id="showChapterList" type="boolean" alwaysNotify="true" />
<field id="hasFocus" type="boolean" alwaysNotify="true" />
</interface>
</component>
Loading