Merge pull request #140 from thomabx/master

Redesigned JFMessageDialog
This commit is contained in:
Charles Ewert 2020-03-03 23:33:11 -05:00 committed by GitHub
commit 855ad0b8a2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 180 additions and 61 deletions

View File

@ -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

View File

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 329 B

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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