commit
855ad0b8a2
|
@ -1,19 +1,66 @@
|
|||
sub init()
|
||||
m.top.observeField("buttonSelected", handle_button)
|
||||
options = m.top.findNode("optionList")
|
||||
options.focusBitmapBlendColor="0x0cb0e8"
|
||||
options.color="0xffffff"
|
||||
options.focusedColor="0xffffff"
|
||||
options.setFocus(true)
|
||||
end sub
|
||||
|
||||
function onKeyEvent(key as string, press as boolean) as boolean
|
||||
if key = "OK"
|
||||
m.top.buttonSelected = m.top.buttonFocused
|
||||
handle_button()
|
||||
if key = "back"
|
||||
m.top.backPressed = true
|
||||
return true
|
||||
end if
|
||||
|
||||
return false
|
||||
end function
|
||||
|
||||
function handle_button()
|
||||
' We just toggle the close state, so subsequent touches don't do anything funny
|
||||
m.top.close = true
|
||||
m.top.close = false
|
||||
end function
|
||||
sub updateOptions()
|
||||
for each item in m.top.options
|
||||
row = CreateObject("roSGNode", "ContentNode")
|
||||
row.title = item
|
||||
m.top.findNode("content").appendChild(row)
|
||||
end for
|
||||
m.top.findNode("optionList").numRows = m.top.options.count()
|
||||
redraw()
|
||||
end sub
|
||||
|
||||
sub updateMessage()
|
||||
message = m.top.findNode("messageText")
|
||||
message.text = m.top.message
|
||||
redraw()
|
||||
end sub
|
||||
|
||||
sub redraw()
|
||||
boxWidth = 900
|
||||
border = 40
|
||||
itemSpacing = 40
|
||||
optionHeight = 60
|
||||
|
||||
bg = m.top.findNode("dialogBackground")
|
||||
text = m.top.findNode("messageText")
|
||||
options = m.top.findNode("optionList")
|
||||
fontHeight = m.top.fontHeight
|
||||
fontWidth = m.top.fontWidth
|
||||
|
||||
if text.text.len() > 0 then
|
||||
textWidth = boxWidth - ( border * 2 )
|
||||
text.width = textWidth
|
||||
text.numLines = int(fontWidth / textWidth) + 1
|
||||
text.translation = [ border , border ]
|
||||
textHeight = (fontHeight * text.numLines)
|
||||
else
|
||||
textHeight = 0
|
||||
itemSpacing = border
|
||||
end if
|
||||
|
||||
options.translation = [ border * 2, textHeight + itemSpacing]
|
||||
options.itemSize = [ boxWidth - ( border * 4 ), optionHeight ]
|
||||
options.itemSpacing = "[0,20]"
|
||||
|
||||
boxHeight = options.translation[1] + (options.itemSize[1] * options.numRows ) + (options.itemSpacing[1] * (options.NumRows - 1)) + border
|
||||
|
||||
bg.width = boxWidth
|
||||
bg.height = boxHeight
|
||||
|
||||
m.top.translation = [(1920 - boxWidth)/2 , (1080 - boxHeight)/2]
|
||||
end sub
|
||||
|
|
|
@ -1,4 +1,24 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<component name="JFMessageDialog" extends="Dialog">
|
||||
<component name="JFMessageDialog" extends="JFGroup">
|
||||
<children>
|
||||
<Poster
|
||||
id="dialogBackground"
|
||||
uri="pkg:/images/dialog.9.png"
|
||||
blendColor="#000000"
|
||||
translation="[0, 0]"
|
||||
/>
|
||||
<Label id="messageText" horizAlign="center" wrap="true" />
|
||||
<LabelList id="optionList" vertFocusAnimationStyle="floatingFocus" textHorizAlign="center">
|
||||
<ContentNode id = "content" role = "content"></ContentNode>
|
||||
</LabelList>
|
||||
|
||||
</children>
|
||||
<interface>
|
||||
<field id="id" type="string" />
|
||||
<field id="message" type="string" onChange="updateMessage" />
|
||||
<field id="options" type="array" onChange="updateOptions" />
|
||||
<field id="fontHeight" type="integer" />
|
||||
<field id="fontWidth" type="integer" />
|
||||
</interface>
|
||||
<script type="text/brightscript" uri="JFMessageDialog.brs" />
|
||||
</component>
|
||||
|
|
BIN
images/dialog.9.png
Normal file
BIN
images/dialog.9.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 329 B |
|
@ -78,7 +78,6 @@ sub Main()
|
|||
group.lastFocus = group.focusedChild
|
||||
group.setFocus(false)
|
||||
group.visible = false
|
||||
|
||||
m.overhang.title = node.name
|
||||
group = CreateMovieListGroup(node)
|
||||
group.overhangTitle = node.name
|
||||
|
@ -103,7 +102,7 @@ sub Main()
|
|||
m.scene.appendChild(group)
|
||||
else
|
||||
' TODO - switch on more node types
|
||||
message_dialog("This library type is not yet implemented: " + node.type)
|
||||
message_dialog("This library type is not yet implemented: " + node.type + ".")
|
||||
end if
|
||||
else if isNodeEvent(msg, "collectionSelected")
|
||||
node = getMsgPicker(msg, "picker")
|
||||
|
@ -160,18 +159,19 @@ sub Main()
|
|||
else if isNodeEvent(msg, "episodeSelected")
|
||||
' If you select a TV Episode from ANYWHERE, follow this flow
|
||||
node = getMsgPicker(msg, "picker")
|
||||
|
||||
group.lastFocus = group.focusedChild
|
||||
group.setFocus(false)
|
||||
group.visible = false
|
||||
video_id = node.id
|
||||
|
||||
group = CreateVideoPlayerGroup(video_id)
|
||||
m.scene.appendChild(group)
|
||||
group.setFocus(true)
|
||||
group.control = "play"
|
||||
ReportPlayback(group, "start")
|
||||
m.overhang.visible = false
|
||||
video = CreateVideoPlayerGroup(video_id)
|
||||
if video <> invalid then
|
||||
group.lastFocus = group.focusedChild
|
||||
group.setFocus(false)
|
||||
group.visible = false
|
||||
group = video
|
||||
m.scene.appendChild(group)
|
||||
group.setFocus(true)
|
||||
group.control = "play"
|
||||
ReportPlayback(group, "start")
|
||||
m.overhang.visible = false
|
||||
end if
|
||||
else if isNodeEvent(msg, "search_value")
|
||||
query = msg.getRoSGNode().search_value
|
||||
group.findNode("SearchBox").visible = false
|
||||
|
@ -214,17 +214,19 @@ sub Main()
|
|||
if btn.id = "play-button"
|
||||
' TODO - Do a better job of picking the last focus
|
||||
' This is currently page layout Group, button Group, then button
|
||||
group.lastFocus = group.focusedChild.focusedChild.focusedChild
|
||||
group.setFocus(false)
|
||||
group.visible = false
|
||||
video_id = group.id
|
||||
|
||||
group = CreateVideoPlayerGroup(video_id)
|
||||
m.scene.appendChild(group)
|
||||
group.setFocus(true)
|
||||
group.control = "play"
|
||||
ReportPlayback(group, "start")
|
||||
m.overhang.visible = false
|
||||
video = CreateVideoPlayerGroup(video_id)
|
||||
if video <> invalid then
|
||||
group.lastFocus = group.focusedChild.focusedChild.focusedChild
|
||||
group.setFocus(false)
|
||||
group.visible = false
|
||||
group = video
|
||||
m.scene.appendChild(group)
|
||||
group.setFocus(true)
|
||||
group.control = "play"
|
||||
ReportPlayback(group, "start")
|
||||
m.overhang.visible = false
|
||||
end if
|
||||
else if btn.id = "watched-button"
|
||||
movie = group.itemContent
|
||||
if movie.watched
|
||||
|
|
|
@ -335,6 +335,7 @@ end function
|
|||
function CreateVideoPlayerGroup(video_id)
|
||||
' Video is Playing
|
||||
video = VideoPlayer(video_id)
|
||||
if video = invalid return invalid
|
||||
timer = video.findNode("playbackTimer")
|
||||
|
||||
video.observeField("backPressed", m.port)
|
||||
|
@ -358,7 +359,6 @@ function MovieLister(group, page_size)
|
|||
})
|
||||
group.objects = item_list
|
||||
|
||||
|
||||
p = group.findNode("paginator")
|
||||
p.maxPages = div_ceiling(group.objects.TotalRecordCount, page_size)
|
||||
end function
|
||||
|
|
|
@ -3,7 +3,9 @@ function VideoPlayer(id)
|
|||
video = CreateObject("roSGNode", "JFVideo")
|
||||
video.id = id
|
||||
video = VideoContent(video)
|
||||
|
||||
if video = invalid
|
||||
return invalid
|
||||
end if
|
||||
jellyfin_blue = "#00a4dcFF"
|
||||
|
||||
video.retrievingBar.filledBarBlendColor = jellyfin_blue
|
||||
|
@ -23,9 +25,18 @@ function VideoContent(video) as object
|
|||
|
||||
' If there is a last playback positon, ask user if they want to resume
|
||||
position = meta.json.UserData.PlaybackPositionTicks
|
||||
if position > 0 and startPlaybackOver(position) then
|
||||
position = 0
|
||||
if position > 0 then
|
||||
dialogResult = startPlaybackOver(position)
|
||||
'Dialog returns -1 when back pressed, 0 for resume, and 1 for start over
|
||||
if dialogResult = -1 then
|
||||
'User pressed back, return invalid and don't load video
|
||||
return invalid
|
||||
else if dialogResult = 1 then
|
||||
'Start Over selected, change position to 0
|
||||
position = 0
|
||||
end if
|
||||
end if
|
||||
print "dialogResult: " dialogResult
|
||||
video.content.BookmarkPosition = int(position/10000000)
|
||||
|
||||
video.PlaySessionId = ItemGetSession(video.id, position)
|
||||
|
@ -108,8 +119,8 @@ function getCaptionMode() as string
|
|||
end function
|
||||
|
||||
'Opens dialog asking user if they want to resume video or start playback over
|
||||
function startPlayBackOver(time as LongInteger) as boolean
|
||||
return option_dialog([ "Resume playing at " + ticksToHuman(time) + ".", "Start over from the begining." ])
|
||||
function startPlayBackOver(time as LongInteger) as integer
|
||||
return option_dialog([ "Resume playing at " + ticksToHuman(time) + ".", "Start over from the beginning." ])
|
||||
end function
|
||||
|
||||
function directPlaySupported(meta as object) as boolean
|
||||
|
|
|
@ -57,26 +57,65 @@ function div_ceiling(a as integer, b as integer) as integer
|
|||
return a/b + 1
|
||||
end function
|
||||
|
||||
function message_dialog(message = "" as string)
|
||||
' Takes a string and returns an object for dialog popup
|
||||
dialog = createObject("roSGNode", "JFMessageDialog")
|
||||
dialog.id = "popup"
|
||||
dialog.buttons = ["OK"]
|
||||
dialog.message = message
|
||||
|
||||
m.scene.dialog = dialog
|
||||
m.scene.dialog.setFocus(true)
|
||||
end function
|
||||
|
||||
function option_dialog(options) as integer
|
||||
dialog = CreateObject("roSGNode", "JFMessageDialog")
|
||||
dialog.backExitsDialog = false
|
||||
dialog.buttons = options
|
||||
m.scene.dialog = dialog
|
||||
m.scene.dialog.setFocus(true)
|
||||
|
||||
while m.scene.dialog <> invalid
|
||||
'Returns the item selected or -1 on backpress or other unhandled closure of dialog.
|
||||
function get_dialog_result(dialog, port)
|
||||
while dialog <> invalid
|
||||
msg = wait(0, port)
|
||||
if isNodeEvent(msg, "backPressed") then
|
||||
return -1
|
||||
elseif isNodeEvent(msg, "itemSelected")
|
||||
return dialog.findNode("optionList").itemSelected
|
||||
end if
|
||||
end while
|
||||
|
||||
return dialog.buttonSelected
|
||||
'Dialog has closed outside of this loop, return -1 for failure
|
||||
return -1
|
||||
end function
|
||||
|
||||
function lastFocusedChild(obj as object) as object
|
||||
child = obj
|
||||
for i = 0 to obj.getChildCount()
|
||||
child = child.focusedChild
|
||||
end for
|
||||
return child
|
||||
end function
|
||||
|
||||
function show_dialog(message as string, options = []) as integer
|
||||
group = m.scene.focusedChild
|
||||
lastFocus = lastFocusedChild(m.scene)
|
||||
'We want to handle backPressed instead of the main loop
|
||||
m.scene.unobserveField("backPressed")
|
||||
|
||||
dialog = createObject("roSGNode", "JFMessageDialog")
|
||||
if options.count() then dialog.options = options
|
||||
if message.len() > 0 then
|
||||
reg = CreateObject("roFontRegistry")
|
||||
font = reg.GetDefaultFont()
|
||||
dialog.fontHeight = font.GetOneLineHeight()
|
||||
dialog.fontWidth = font.GetOneLineWidth(message, 999999999)
|
||||
dialog.message = message
|
||||
end if
|
||||
|
||||
dialog.visible = true
|
||||
dialog.setFocus(true)
|
||||
m.scene.appendChild(dialog)
|
||||
|
||||
port = CreateObject("roMessagePort")
|
||||
dialog.observeField("backPressed", port)
|
||||
dialog.findNode("optionList").observeField("itemSelected", port)
|
||||
|
||||
result = get_dialog_result(dialog, port)
|
||||
|
||||
m.scene.removeChildIndex(m.scene.getChildCount() - 1)
|
||||
lastFocus.setFocus(true)
|
||||
m.scene.observeField("backPressed", m.port)
|
||||
|
||||
return result
|
||||
end function
|
||||
|
||||
function message_dialog(message = "" as string)
|
||||
return show_dialog(message,["OK"])
|
||||
end function
|
||||
|
||||
function option_dialog(options, message = "") as integer
|
||||
return show_dialog(message, options)
|
||||
end function
|
||||
|
|
Loading…
Reference in New Issue
Block a user