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

Allow audio track selection for Movies #275

Merged
merged 2 commits into from
Oct 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion components/Buttons/JFButtons.brs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ sub init()
m.focusRing.color = m.global.constants.colors.button

m.buttonCount = 0
m.selectedFocusedIndex = 1
m.selectedFocusedIndex = 0

m.textSizeTask = createObject("roSGNode", "TextSizeTask")

Expand All @@ -25,6 +25,12 @@ sub init()

end sub

'
' When Selected Index set, ensure it is the one Focused
sub selectedIndexChanged()
m.selectedFocusedIndex = m.top.selectedIndex
end sub

'
' When options are fully displayed, set focus and selected option
sub renderChanged()
Expand Down
2 changes: 1 addition & 1 deletion components/Buttons/JFButtons.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<field id="buttons" type="array" onChange="updateButtons" />
<field id="focusedChild" type="node" onChange="focusChanged" />
<field id="focusedIndex" type="integer" alwaysNotify="true" />
<field id="selectedIndex" type="integer" />
<field id="selectedIndex" type="integer" onChange="selectedIndexChanged" />
</interface>
<script type="text/brightscript" uri="JFButtons.brs" />
</component>
1 change: 1 addition & 0 deletions components/ItemGrid2/ItemGridOptions.brs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ sub init()

m.buttons = m.top.findNode("buttons")
m.buttons.buttons = [tr("TAB_VIEW"), tr("TAB_SORT"), tr("TAB_FILTER")]
m.buttons.selectedIndex = 1
m.buttons.setFocus(true)

m.selectedSortIndex = 0
Expand Down
7 changes: 7 additions & 0 deletions components/movies/AudioTrackListData.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8" ?>
<component name="AudioTrackListData" extends="ContentNode">
<interface>
<field id="selected" type="boolean" value="false" />
<field id="streamIndex" type="integer" value="-1" />
</interface>
</component>
33 changes: 33 additions & 0 deletions components/movies/AudioTrackListItem.brs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
function init()
m.title = m.top.findNode("title")
m.description = m.top.findNode("description")
m.selectedIcon = m.top.findNode("selectedIcon")
end function

function itemContentChanged()
m.title.text = m.top.itemContent.title
m.description.text = m.top.itemContent.description

if m.top.itemContent.description = "" then
m.title.translation = [50, 20]
end if

if m.top.itemContent.selected then
m.selectedIcon.uri = m.global.constants.icons.check_white
else
m.selectedIcon.uri = ""
end if

end function

'
'Scroll description if focused
sub focusChanged()

if m.top.itemHasFocus = true then
m.description.repeatCount = -1
else
m.description.repeatCount = 0
end if

end sub
13 changes: 13 additions & 0 deletions components/movies/AudioTrackListItem.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8" ?>
<component name="AudioTrackListItem" extends="Group">
<children>
<Poster width="32" height="32" id="selectedIcon" translation="[5,19]" uri="" />
<Label id="title" font="font:MediumSystemFont" color="0xffffffff" translation="[50,3]" />
<ScrollingLabel id="description" font="font:SmallestSystemFont" color="0xabababff" maxWidth="800" repeatCount="0" translation="[50,45]" />
</children>
<interface>
<field id="itemContent" type="node" onChange="itemContentChanged"/>
<field id="itemHasFocus" type="boolean" onChange="focusChanged" />
</interface>
<script type="text/brightscript" uri="AudioTrackListItem.brs" />
</component>
71 changes: 70 additions & 1 deletion components/movies/MovieDetails.brs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
sub init()
m.top.optionsAvailable = false
m.options = m.top.findNode("options")

main = m.top.findNode("main_group")
main.translation = [96, 175]
Expand All @@ -18,6 +19,14 @@ sub itemContentChanged()

m.top.findNode("moviePoster").uri = m.top.itemContent.posterURL

' Find first Audio Stream and set that as default
For i=0 To itemData.mediaStreams.Count() - 1
if itemData.mediaStreams[i].Type = "Audio" then
m.top.selectedAudioStreamIndex = i
exit for
end if
End For

' Handle all "As Is" fields
m.top.overhangTitle = itemData.name
setFieldText("releaseYear", itemData.productionYear)
Expand Down Expand Up @@ -56,15 +65,34 @@ sub itemContentChanged()
setFieldText("director", tr("Director") + ": " + director)
end if
setFieldText("video_codec", tr("Video") + ": " + itemData.mediaStreams[0].displayTitle)
setFieldText("audio_codec", tr("Audio") + ": " + itemData.mediaStreams[1].displayTitle)
setFieldText("audio_codec", tr("Audio") + ": " + itemData.mediaStreams[m.top.selectedAudioStreamIndex].displayTitle)
' TODO - cmon now. these are buttons, not words
if itemData.taglines.count() > 0
setFieldText("tagline", itemData.taglines[0])
end if
setFavoriteColor()
setWatchedColor()
SetUpOptions(itemData.mediaStreams)
end sub


sub SetUpOptions(streams)

tracks = []

for i=0 To streams.Count() - 1
if streams[i].Type = "Audio" then
tracks.push({"Title": streams[i].displayTitle, "Description" : streams[i].Title, "Selected" : m.top.selectedAudioStreamIndex = i, "StreamIndex" : i})
end if
end for

options = {}
options.views = tracks
m.options.options = options

end sub


sub setFieldText(field, value)
node = m.top.findNode(field)
if node = invalid or value = invalid then return
Expand Down Expand Up @@ -137,3 +165,44 @@ function round(f as float) as integer
return n
end if
end function

'
'Check if options updated and any reloading required
sub optionsClosed()
if m.options.audioSteamIndex <> m.top.selectedAudioStreamIndex then
m.top.selectedAudioStreamIndex = m.options.audioSteamIndex
setFieldText("audio_codec", tr("Audio") + ": " + m.top.itemContent.json.mediaStreams[m.top.selectedAudioStreamIndex].displayTitle)
end if
m.top.findNode("buttons").setFocus(true)
end sub


function onKeyEvent(key as string, press as boolean) as boolean

' Due to the way the button pressed event works, need to catch the release for the button as the press is being sent
' directly to the main loop. Will get this sorted in the layout update for Movie Details
if (key = "OK" and m.top.findNode("audio-button").isInFocusChain())
m.options.visible = true
m.options.setFocus(true)
end if

if not press then return false

if key = "options"
if m.options.visible = true then
m.options.visible = false
optionsClosed()
else
m.options.visible = true
m.options.setFocus(true)
end if
return true
else if key = "back" then
if m.options.visible = true then
m.options.visible = false
optionsClosed()
return true
end if
end if
return false
end function
9 changes: 6 additions & 3 deletions components/movies/MovieDetails.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,21 @@
<Label id="video_codec" />
<Label id="audio_codec" />
<ButtonGroupHoriz id="buttons" itemSpacings="[10]">
<Button text="Play" id="play-button" />
<Button text="Watched" id="watched-button" />
<Button text="Favorite" id="favorite-button" />
<Button text="Play" id="play-button" iconUri="" focusedIconUri="" maxWidth="320" minWidth="320" />
<Button text="Audio" id="audio-button" iconUri="" focusedIconUri="" maxWidth="320" minWidth="320" />
<Button text="Watched" id="watched-button" iconUri="" focusedIconUri="" maxWidth="320" minWidth="320" />
<Button text="Favorite" id="favorite-button" iconUri="" focusedIconUri="" maxWidth="320" minWidth="320" />
</ButtonGroupHoriz>
<Label id="tagline" />
<Label id="overview" wrap="true" maxLines="8" />

</LayoutGroup>
</LayoutGroup>
<MovieOptions id="options" visible="false" />
</children>
<interface>
<field id="itemContent" type="node" onChange="itemContentChanged" />
<field id="selectedAudioStreamIndex" type="integer" />
</interface>
<script type="text/brightscript" uri="pkg:/source/utils/misc.brs" />
<script type="text/brightscript" uri="MovieDetails.brs" />
Expand Down
111 changes: 111 additions & 0 deletions components/movies/MovieOptions.brs
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
sub init()

m.buttons = m.top.findNode("buttons")
m.buttons.buttons = [tr("Audio")]
m.buttons.setFocus(true)

m.selectedItem = 0
m.selectedAudioIndex = 0

m.menus = []
m.menus.push(m.top.findNode("audioMenu"))

m.viewNames = []

' Set button color to global
m.top.findNode("audioMenu").focusBitmapBlendColor = m.global.constants.colors.button

' Animation
m.fadeAnim = m.top.findNode("fadeAnim")
m.fadeOutAnimOpacity = m.top.findNode("outOpacity")
m.fadeInAnimOpacity = m.top.findNode("inOpacity")

m.buttons.observeField("focusedIndex", "buttonFocusChanged")

end sub

sub optionsSet()

' Views Tab
if m.top.options.views <> invalid then
viewContent = CreateObject("roSGNode", "ContentNode")
index = 0
selectedViewIndex = 0

for each view in m.top.options.views
entry = viewContent.CreateChild("AudioTrackListData")
entry.title = view.Title
entry.description = view.Description
entry.streamIndex = view.StreamIndex
m.viewNames.push(view.Name)
if view.Selected <> invalid and view.Selected = true then
selectedViewIndex = index
entry.selected = true
m.top.audioSteamIndex = view.streamIndex
end if
index = index + 1
end for

m.menus[0].content = viewContent
m.menus[0].jumpToItem = selectedViewIndex
m.selectedAudioIndex = selectedViewIndex
end if

end sub

' Switch menu shown when button focus changes
sub buttonFocusChanged()
if m.buttons.focusedIndex = m.selectedItem then return
m.fadeOutAnimOpacity.fieldToInterp = m.menus[m.selectedItem].id + ".opacity"
m.fadeInAnimOpacity.fieldToInterp = m.menus[m.buttons.focusedIndex].id + ".opacity"
m.fadeAnim.control = "start"
m.selectedItem = m.buttons.focusedIndex
end sub


function onKeyEvent(key as string, press as boolean) as boolean

if key = "down" or (key = "OK" and m.top.findNode("buttons").hasFocus()) then
m.top.findNode("buttons").setFocus(false)
m.menus[m.selectedItem].setFocus(true)
m.menus[m.selectedItem].drawFocusFeedback = true

'If user presses down from button menu, focus first item. If OK, focus checked item
if key = "down" then
m.menus[m.selectedItem].jumpToItem = 0
else
m.menus[m.selectedItem].jumpToItem = m.menus[m.selectedItem].itemSelected
end if

return true
else if key = "OK"
if(m.menus[m.selectedItem].isInFocusChain()) then

selMenu = m.menus[m.selectedItem]
selIndex = selMenu.itemSelected
child = selMenu.content.GetChild(selIndex)

if m.selectedAudioIndex = selIndex then
else
selMenu.content.GetChild(m.selectedAudioIndex).selected = false
newSelection = selMenu.content.GetChild(selIndex)
newSelection.selected = true
m.selectedAudioIndex = selIndex
m.top.audioSteamIndex = newSelection.streamIndex
end if
end if
return true
else if key = "back" or key = "up"
if m.menus[m.selectedItem].isInFocusChain() then
m.buttons.setFocus(true)
m.menus[m.selectedItem].drawFocusFeedback = false
return true
end if
else if key = "options"
m.menus[m.selectedItem].drawFocusFeedback = false
return false
end if

return false

end function
37 changes: 37 additions & 0 deletions components/movies/MovieOptions.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8" ?>
<component name="MovieOptions" extends="Group">
<children>
<Rectangle width="1920" height="1080" color="#000000" opacity="0.75" />
<Group translation="[100,100]">
<Poster width="1720" height="880" uri="pkg:/images/dialog.9.png" />
<LayoutGroup horizAlignment="center" translation="[860,50]" itemSpacings="[50]">
<JFButtons id="buttons" />
<Group>
<MarkupList
id="audioMenu"
itemComponentName="AudioTrackListItem"
itemSize="[600, 70]"
itemSpacing="[20,20]"
numrows = "8"
vertFocusAnimationStyle="floatingFocus"
focusFootprintBlendColor="#00000000"
/>
<!-- <RadiobuttonList id="audioMenu" itemspacing="[0,10]" vertFocusAnimationStyle="floatingFocus" drawFocusFeedback="false">
</RadiobuttonList> -->
</Group>
</LayoutGroup>
</Group>

<Animation id="fadeAnim" duration="0.5" repeat="false">
<FloatFieldInterpolator id="outOpacity" key="[0.0, 0.5, 1.0]" keyValue="[ 1, 0, 0 ]" fieldToInterp="focus.opacity" />
<FloatFieldInterpolator id="inOpacity" key="[0.0, 0.5, 1.0]" keyValue="[ 0, 0, 1 ]" fieldToInterp="focus.opacity" />
</Animation>

</children>
<interface>
<field id="buttons" type="nodearray" />
<field id="options" type="associativearray" onChange="optionsSet" />
<field id="audioSteamIndex" type="integer" />
</interface>
<script type="text/brightscript" uri="MovieOptions.brs" />
</component>
Binary file added images/icons/check_black.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/icons/check_white.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 7 additions & 1 deletion source/Main.brs
Original file line number Diff line number Diff line change
Expand Up @@ -334,10 +334,16 @@ sub Main()
' If a button is selected, we have some determining to do
btn = getButton(msg)
if btn.id = "play-button"
' Check is a specific Audio Stream was selected
audio_stream_idx = 1
if group.selectedAudioStreamIndex <> invalid
audio_stream_idx = group.selectedAudioStreamIndex
end if

' TODO - Do a better job of picking the last focus
' This is currently page layout Group, button Group, then button
video_id = group.id
video = CreateVideoPlayerGroup(video_id)
video = CreateVideoPlayerGroup(video_id, audio_stream_idx)
if video <> invalid then
group.lastFocus = group.focusedChild.focusedChild.focusedChild
group.setFocus(false)
Expand Down
Loading