Merge pull request #265 from neilsb/itemgrid2-sort-options
Add Options popup for ItemGrid and enable sorting
116
components/Buttons/JFButtons.brs
Normal file
|
@ -0,0 +1,116 @@
|
|||
sub init()
|
||||
|
||||
m.top.focusable = true
|
||||
|
||||
m.menubg = m.top.findNode("menubg")
|
||||
|
||||
m.focusRing = m.top.findNode("focus")
|
||||
m.buttonGroup = m.top.findNode("buttonGroup")
|
||||
m.focusAnim = m.top.findNode("moveFocusAnimation")
|
||||
m.focusAnimTranslation = m.top.findNode("focusLocation")
|
||||
m.focusAnimWidth = m.top.findNode("focusWidth")
|
||||
m.focusAnimHeight = m.top.findNode("focusHeight")
|
||||
|
||||
' Set button color to global
|
||||
m.focusRing.color = m.global.constants.colors.button
|
||||
|
||||
m.buttonCount = 0
|
||||
m.selectedFocusedIndex = 1
|
||||
|
||||
m.textSizeTask = createObject("roSGNode", "TextSizeTask")
|
||||
|
||||
m.top.observeField("focusedChild", "focusChanged")
|
||||
m.top.enableRenderTracking = true
|
||||
m.top.observeField("renderTracking", "renderChanged")
|
||||
|
||||
end sub
|
||||
|
||||
'
|
||||
' When options are fully displayed, set focus and selected option
|
||||
sub renderChanged()
|
||||
if m.top.renderTracking = "full" then
|
||||
highlightSelected(m.selectedFocusedIndex, false)
|
||||
m.top.setfocus(true)
|
||||
end if
|
||||
end sub
|
||||
|
||||
|
||||
sub updateButtons()
|
||||
m.textSizeTask.fontsize = 40
|
||||
m.textSizeTask.text= m.top.buttons
|
||||
m.textSizeTask.name = m.buttonCount
|
||||
m.textSizeTask.observeField("width", "showButtons")
|
||||
m.textSizeTask.control = "RUN"
|
||||
end sub
|
||||
|
||||
sub showButtons()
|
||||
|
||||
totalWidth = 110 ' track for menu background width - start with side padding
|
||||
|
||||
for i = 0 to m.top.buttons.count() - 1
|
||||
m.buttonCount = m.buttonCount + 1
|
||||
l = m.buttonGroup.createChild("Label")
|
||||
l.text = m.top.buttons[i]
|
||||
l.font.size = 40
|
||||
l.translation=[0,10]
|
||||
l.height = m.textSizeTask.height
|
||||
l.width = m.textSizeTask.width[i] + 50
|
||||
l.horizAlign = "center"
|
||||
l.vertAlign="center"
|
||||
totalWidth = totalWidth + l.width + 45
|
||||
end for
|
||||
|
||||
m.menubg.width = totalWidth
|
||||
m.menubg.height = m.textSizeTask.height + 40
|
||||
|
||||
end sub
|
||||
|
||||
' Highlight selected menu option
|
||||
sub highlightSelected(index as integer, animate = true)
|
||||
|
||||
val = m.buttonGroup.getChild(index)
|
||||
rect = val.ancestorBoundingRect(m.top)
|
||||
|
||||
if animate = true then
|
||||
m.focusAnimTranslation.keyValue = [m.focusRing.translation, [rect.x - 25, rect.y - 30]]
|
||||
m.focusAnimWidth.keyValue = [m.focusRing.width, val.width + 50]
|
||||
m.focusAnimHeight.keyValue = [m.focusRing.height, val.height + 60]
|
||||
m.focusAnim.control = "start"
|
||||
else
|
||||
m.focusRing.translation = [rect.x - 25, rect.y - 30]
|
||||
m.focusRing.width = val.width + 50
|
||||
m.focusRing.height = val.height + 60
|
||||
end if
|
||||
|
||||
end sub
|
||||
|
||||
' Change opacity of the highlighted menu item based on focus
|
||||
sub focusChanged()
|
||||
if m.top.isInFocusChain() then
|
||||
m.focusRing.opacity = 1
|
||||
else
|
||||
m.focusRing.opacity = 0.6
|
||||
end if
|
||||
end sub
|
||||
|
||||
|
||||
function onKeyEvent(key as string, press as boolean) as boolean
|
||||
|
||||
if not press then return false
|
||||
|
||||
if key = "left"
|
||||
if(m.selectedFocusedIndex > 0) m.selectedFocusedIndex = m.selectedFocusedIndex - 1
|
||||
highlightSelected(m.selectedFocusedIndex)
|
||||
m.top.focusedIndex = m.selectedFocusedIndex
|
||||
return true
|
||||
else if key = "right"
|
||||
if(m.selectedFocusedIndex < m.buttonCount - 1) m.selectedFocusedIndex = m.selectedFocusedIndex + 1
|
||||
highlightSelected(m.selectedFocusedIndex)
|
||||
m.top.focusedIndex = m.selectedFocusedIndex
|
||||
return true
|
||||
else if key = "OK"
|
||||
m.top.selectedIndex = m.selectedFocusedIndex
|
||||
return true
|
||||
end if
|
||||
return false
|
||||
end function
|
29
components/Buttons/JFButtons.xml
Normal file
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<component name="JFButtons" extends="Group">
|
||||
<children>
|
||||
<Group>
|
||||
|
||||
<!-- Background Bar -->
|
||||
<Poster id="menubg" uri="pkg:/images/option-menu-bg.9.png" width="800" height="100" />
|
||||
|
||||
<rectangle id="focus" />
|
||||
|
||||
<LayoutGroup id="buttonGroup" layoutDirection="horiz" itemSpacings = "[75]" translation="[50,20]">
|
||||
</LayoutGroup>
|
||||
|
||||
<Animation id="moveFocusAnimation" duration="0.25" repeat="false" easeFunction="outQuad">
|
||||
<FloatFieldInterpolator id = "focusWidth" key="[0.0, 1.0]" keyValue="[ 0.00, 0.25 ]" fieldToInterp="focus.width" />
|
||||
<FloatFieldInterpolator id = "focusHeight" key="[0.0, 1.0]" keyValue="[ 0.25, 0.00 ]" fieldToInterp="focus.height" />
|
||||
<Vector2DFieldInterpolator id = "focusLocation" key="[0.0, 1.0]" keyValue="[]" fieldToInterp="focus.translation" />
|
||||
</Animation>
|
||||
</Group>
|
||||
|
||||
</children>
|
||||
<interface>
|
||||
<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" />
|
||||
</interface>
|
||||
<script type="text/brightscript" uri="JFButtons.brs" />
|
||||
</component>
|
21
components/Buttons/TextSizeTask.brs
Normal file
|
@ -0,0 +1,21 @@
|
|||
sub init()
|
||||
m.top.functionName = "getTextSize"
|
||||
end sub
|
||||
|
||||
sub getTextSize()
|
||||
|
||||
reg = CreateObject("roFontRegistry")
|
||||
font = reg.GetDefaultFont(m.top.fontsize, false, false)
|
||||
|
||||
res = []
|
||||
|
||||
for each line in m.top.text
|
||||
res.push(font.GetOneLineWidth(line, m.top.maxWidth))
|
||||
end for
|
||||
|
||||
m.top.height = font.GetOneLineHeight()
|
||||
|
||||
|
||||
m.top.width = res
|
||||
|
||||
end sub
|
16
components/Buttons/TextSizeTask.xml
Normal file
|
@ -0,0 +1,16 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
|
||||
<component name="TextSizeTask" extends="Task">
|
||||
<interface>
|
||||
<field id="fontName" type="string" />
|
||||
<field id="fontSize" type="int" />
|
||||
<field id="text" type="array" />
|
||||
<field id="maxWidth" type="int" value="1920" />
|
||||
<field id="name" type="string" />
|
||||
|
||||
<!-- Results -->
|
||||
<field id="width" type="array" />
|
||||
<field id="height" type="int" />
|
||||
</interface>
|
||||
<script type="text/brightscript" uri="TextSizeTask.brs" />
|
||||
</component>
|
|
@ -13,7 +13,7 @@ end sub
|
|||
sub itemContentChanged()
|
||||
|
||||
' Set Randmom background colors from pallet
|
||||
posterBackgrounds = m.global.poster_bg_pallet
|
||||
posterBackgrounds = m.global.constants.poster_bg_pallet
|
||||
m.backdrop.color = posterBackgrounds[rnd(posterBackgrounds.count()) - 1]
|
||||
|
||||
itemData = m.top.itemContent
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
sub init()
|
||||
|
||||
m.options = m.top.findNode("options")
|
||||
|
||||
m.itemGrid = m.top.findNode("itemGrid")
|
||||
m.backdrop = m.top.findNode("backdrop")
|
||||
m.newBackdrop = m.top.findNode("backdropTransition")
|
||||
|
@ -7,7 +9,7 @@ sub init()
|
|||
|
||||
m.swapAnimation = m.top.findNode("backroundSwapAnimation")
|
||||
m.swapAnimation.observeField("state", "swapDone")
|
||||
|
||||
|
||||
m.loadedRows = 0
|
||||
m.loadedItems = 0
|
||||
|
||||
|
@ -23,20 +25,27 @@ sub init()
|
|||
'Background Image Queued for loading
|
||||
m.queuedBGUri = ""
|
||||
|
||||
'Item sort - maybe load defaults from user prefs?
|
||||
m.sortField = "SortName"
|
||||
m.sortAscending = true
|
||||
|
||||
m.loadItemsTask = createObject("roSGNode", "LoadItemsTask2")
|
||||
|
||||
m.loadItemsTask.observeField("content", "ItemDataLoaded")
|
||||
|
||||
end sub
|
||||
|
||||
'
|
||||
'Load initial set of Data
|
||||
sub loadInitialItems()
|
||||
sub loadInitialItems()
|
||||
|
||||
if m.top.parentItem.backdropUrl <> invalid then
|
||||
SetBackground(m.top.parentItem.backdropUrl)
|
||||
end if
|
||||
|
||||
m.loadItemsTask.itemId = m.top.parentItem.Id
|
||||
m.loadItemsTask.observeField("content", "ItemDataLoaded")
|
||||
m.loadItemsTask.sortField = m.sortField
|
||||
m.loadItemsTask.sortAscending = m.sortAscending
|
||||
m.loadItemsTask.startIndex = 0
|
||||
|
||||
if m.top.parentItem.collectionType = "movies" then
|
||||
m.loadItemsTask.itemType = "Movie"
|
||||
|
@ -45,18 +54,66 @@ sub loadInitialItems()
|
|||
end if
|
||||
|
||||
m.loadItemsTask.control = "RUN"
|
||||
|
||||
SetUpOptions()
|
||||
|
||||
end sub
|
||||
|
||||
' Data to display when options button selected
|
||||
sub SetUpOptions()
|
||||
|
||||
options = {}
|
||||
|
||||
'Movies
|
||||
if m.top.parentItem.collectionType = "movies" then
|
||||
options.views = [{ "Title": tr("Movies"), "Name": "movies" }]
|
||||
options.sort = [
|
||||
{ "Title": tr("TITLE"), "Name": "SortName" },
|
||||
{ "Title": tr("IMDB_RATING"), "Name": "CommunityRating" },
|
||||
{ "Title": tr("CRITIC_RATING"), "Name": "CriticRating" },
|
||||
{ "Title": tr("DATE_ADDED"), "Name": "DateCreated" },
|
||||
{ "Title": tr("DATE_PLAYED"), "Name": "DatePlayed" },
|
||||
{ "Title": tr("OFFICIAL_RATING"), "Name": "OfficialRating" },
|
||||
{ "Title": tr("PLAY_COUNT"), "Name": "PlayCount" },
|
||||
{ "Title": tr("RELEASE_DATE"), "Name": "PremiereDate" },
|
||||
{ "Title": tr("RUNTIME"), "Name": "Runtime" }
|
||||
]
|
||||
'TV Shows
|
||||
else if m.top.parentItem.collectionType = "tvshows" then
|
||||
options.views = [{ "Title": tr("Shows"), "Name": "shows" }]
|
||||
options.sort = [
|
||||
{ "Title": tr("TITLE"), "Name": "SortName" },
|
||||
{ "Title": tr("IMDB_RATING"), "Name": "CommunityRating" },
|
||||
{ "Title": tr("DATE_ADDED"), "Name": "DateCreated" },
|
||||
{ "Title": tr("DATE_PLAYED"), "Name": "DatePlayed" },
|
||||
{ "Title": tr("OFFICIAL_RATING"), "Name": "OfficialRating" },
|
||||
{ "Title": tr("RELEASE_DATE"), "Name": "PremiereDate" },
|
||||
]
|
||||
|
||||
end if
|
||||
|
||||
for each o in options.sort
|
||||
if o.Name = m.sortField then
|
||||
o.Selected = true
|
||||
o.Ascending = m.sortAscending
|
||||
end if
|
||||
end for
|
||||
|
||||
m.options.options = options
|
||||
|
||||
end sub
|
||||
|
||||
|
||||
'
|
||||
'Handle loaded data, and add to Grid
|
||||
sub ItemDataLoaded(msg)
|
||||
|
||||
|
||||
itemData = msg.GetData()
|
||||
data = msg.getField()
|
||||
|
||||
if itemData = invalid then
|
||||
if itemData = invalid then
|
||||
m.Loading = false
|
||||
return
|
||||
return
|
||||
end if
|
||||
|
||||
for each item in itemData
|
||||
|
@ -64,7 +121,7 @@ sub ItemDataLoaded(msg)
|
|||
end for
|
||||
|
||||
'Update the stored counts
|
||||
m.loadedItems = m.itemGrid.content.getChildCount()
|
||||
m.loadedItems = m.itemGrid.content.getChildCount()
|
||||
m.loadedRows = m.loadedItems / m.itemGrid.numColumns
|
||||
m.Loading = false
|
||||
|
||||
|
@ -111,7 +168,7 @@ sub onItemFocused()
|
|||
if focusedRow >= m.loadedRows - 3 and m.loadeditems < m.loadItemsTask.totalRecordCount then
|
||||
loadMoreData()
|
||||
end if
|
||||
end sub
|
||||
end sub
|
||||
|
||||
'
|
||||
'When Image Loading Status changes
|
||||
|
@ -127,16 +184,16 @@ end sub
|
|||
sub swapDone()
|
||||
|
||||
if m.swapAnimation.state = "stopped" then
|
||||
|
||||
|
||||
'Set main BG node image and hide transitioning node
|
||||
m.backdrop.uri = m.newBackdrop.uri
|
||||
m.backdrop.opacity = 0.25
|
||||
m.newBackdrop.opacity = 0
|
||||
|
||||
|
||||
'If there is another one to load
|
||||
if m.newBackdrop.uri <> m.queuedBGUri and m.queuedBGUri <> "" then
|
||||
SetBackground(m.queuedBGUri)
|
||||
m.queuedBGUri = ""
|
||||
if m.newBackdrop.uri <> m.queuedBGUri and m.queuedBGUri <> "" then
|
||||
SetBackground(m.queuedBGUri)
|
||||
m.queuedBGUri = ""
|
||||
end if
|
||||
end if
|
||||
end sub
|
||||
|
@ -156,4 +213,44 @@ end sub
|
|||
'Item Selected
|
||||
sub onItemSelected()
|
||||
m.top.selectedItem = m.itemGrid.content.getChild(m.itemGrid.itemSelected)
|
||||
end sub
|
||||
end sub
|
||||
|
||||
|
||||
'
|
||||
'Check if options updated and any reloading required
|
||||
sub optionsClosed()
|
||||
if m.options.sortField <> m.sortField or m.options.sortAscending <> m.sortAscending then
|
||||
m.sortField = m.options.sortField
|
||||
m.sortAscending = m.options.sortAscending
|
||||
m.loadedRows = 0
|
||||
m.loadedItems = 0
|
||||
m.data = CreateObject("roSGNode", "ContentNode")
|
||||
m.itemGrid.content = m.data
|
||||
loadInitialItems()
|
||||
end if
|
||||
m.itemGrid.setFocus(true)
|
||||
end sub
|
||||
|
||||
|
||||
function onKeyEvent(key as string, press as boolean) as boolean
|
||||
|
||||
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
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
itemSpacing = "[ 0, 45 ]"
|
||||
drawFocusFeedback = "false" />
|
||||
<Label translation="[0,540]" id="emptyText" font="font:LargeSystemFont" width="1920" horizAlign="center" vertAlign="center" height="64" visible="false" />
|
||||
<OptionsSlider id="options" />
|
||||
<ItemGridOptions id="options" visible="false" />
|
||||
<Animation id="backroundSwapAnimation" duration="1" repeat="false" easeFunction="linear" >
|
||||
<FloatFieldInterpolator id = "fadeinLoading" key="[0.0, 1.0]" keyValue="[ 0.00, 0.25 ]" fieldToInterp="backdropTransition.opacity" />
|
||||
<FloatFieldInterpolator id = "fadeoutLoaded" key="[0.0, 1.0]" keyValue="[ 0.25, 0.00 ]" fieldToInterp="backdrop.opacity" />
|
||||
|
|
147
components/ItemGrid2/ItemGridOptions.brs
Normal file
|
@ -0,0 +1,147 @@
|
|||
sub init()
|
||||
|
||||
m.buttons = m.top.findNode("buttons")
|
||||
m.buttons.buttons = [tr("TAB_VIEW"), tr("TAB_SORT"), tr("TAB_FILTER")]
|
||||
m.buttons.setFocus(true)
|
||||
|
||||
m.selectedSortIndex = 0
|
||||
m.selectedItem = 1
|
||||
|
||||
m.menus = []
|
||||
m.menus.push(m.top.findNode("viewMenu"))
|
||||
m.menus.push(m.top.findNode("sortMenu"))
|
||||
m.menus.push(m.top.findNode("filterMenu"))
|
||||
|
||||
m.viewNames = []
|
||||
m.sortNames = []
|
||||
|
||||
' 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("ContentNode")
|
||||
entry.title = view.Title
|
||||
m.viewNames.push(view.Name)
|
||||
if view.selected <> invalid and view.selected = true then
|
||||
selectedViewIndex = index
|
||||
end if
|
||||
index = index + 1
|
||||
end for
|
||||
m.menus[0].content = viewContent
|
||||
m.menus[0].checkedItem = selectedViewIndex
|
||||
end if
|
||||
|
||||
' Sort Tab
|
||||
if m.top.options.sort <> invalid then
|
||||
sortContent = CreateObject("roSGNode", "ContentNode")
|
||||
index = 0
|
||||
m.selectedSortIndex = 0
|
||||
|
||||
for each sortItem in m.top.options.sort
|
||||
entry = sortContent.CreateChild("ContentNode")
|
||||
entry.title = sortItem.Title
|
||||
m.sortNames.push(sortItem.Name)
|
||||
if sortItem.Selected <> invalid and sortItem.Selected = true then
|
||||
m.selectedSortIndex = index
|
||||
if sortItem.Ascending <> invalid and sortItem.Ascending = false then
|
||||
m.top.sortAscending = 0
|
||||
else
|
||||
m.top.sortAscending = 1
|
||||
end if
|
||||
end if
|
||||
index = index + 1
|
||||
end for
|
||||
m.menus[1].content = sortContent
|
||||
m.menus[1].checkedItem = m.selectedSortIndex
|
||||
|
||||
if m.top.sortAscending = 1 then
|
||||
m.menus[1].focusedCheckedIconUri = m.global.constants.icons.ascending_black
|
||||
m.menus[1].checkedIconUri = m.global.constants.icons.ascending_white
|
||||
else
|
||||
m.menus[1].focusedCheckedIconUri = m.global.constants.icons.descending_black
|
||||
m.menus[1].checkedIconUri = m.global.constants.icons.descending_white
|
||||
end if
|
||||
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"
|
||||
' Handle Sort screen
|
||||
if(m.menus[m.selectedItem].isInFocusChain()) then
|
||||
if(m.selectedItem = 1) then
|
||||
if m.menus[1].itemSelected <> m.selectedSortIndex then
|
||||
m.menus[1].focusedCheckedIconUri = m.global.constants.icons.ascending_black
|
||||
m.menus[1].checkedIconUri = m.global.constants.icons.ascending_white
|
||||
|
||||
m.selectedSortIndex = m.menus[1].itemSelected
|
||||
m.top.sortAscending = true
|
||||
m.top.sortField = m.sortNames[m.selectedSortIndex]
|
||||
else
|
||||
|
||||
if m.top.sortAscending = true then
|
||||
m.top.sortAscending = false
|
||||
m.menus[1].focusedCheckedIconUri = m.global.constants.icons.descending_black
|
||||
m.menus[1].checkedIconUri = m.global.constants.icons.descending_white
|
||||
else
|
||||
m.top.sortAscending = true
|
||||
m.menus[1].focusedCheckedIconUri = m.global.constants.icons.ascending_black
|
||||
m.menus[1].checkedIconUri = m.global.constants.icons.ascending_white
|
||||
end if
|
||||
end if
|
||||
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
|
39
components/ItemGrid2/ItemGridOptions.xml
Normal file
|
@ -0,0 +1,39 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<component name="ItemGridOptions" 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>
|
||||
<RadiobuttonList id="viewMenu" itemspacing="[0,10]" vertFocusAnimationStyle="floatingFocus" opacity="0" drawFocusFeedback="false">
|
||||
</RadiobuttonList>
|
||||
<RadiobuttonList id="sortMenu" itemspacing="[0,10]" vertFocusAnimationStyle="floatingFocus" opacity="1" numRows="8" drawFocusFeedback="false">
|
||||
</RadiobuttonList>
|
||||
<LabelList id = "filterMenu" itemspacing="[0,10]" vertFocusAnimationStyle="floatingFocus" opacity="0" drawFocusFeedback="false">
|
||||
<ContentNode id = "filterMenuContent" role = "content">
|
||||
<ContentNode title = "Coming Soon..." />
|
||||
</ContentNode>
|
||||
</LabelList>
|
||||
</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="view" type="string" />
|
||||
<field id="sortField" type="string" value="SortName" />
|
||||
<field id="sortAscending" type="boolean" value="false" />
|
||||
|
||||
</interface>
|
||||
<script type="text/brightscript" uri="ItemGridOptions.brs" />
|
||||
</component>
|
|
@ -6,9 +6,13 @@ sub loadItems()
|
|||
|
||||
results = []
|
||||
|
||||
sort_order = get_user_setting("movie_sort_order", "Ascending")
|
||||
sort_field = get_user_setting("movie_sort_field", "SortName")
|
||||
|
||||
sort_field = m.top.sortField
|
||||
|
||||
if m.top.sortAscending = true then
|
||||
sort_order = "Ascending"
|
||||
else
|
||||
sort_order = "Descending"
|
||||
end if
|
||||
|
||||
params = {
|
||||
limit: m.top.limit,
|
||||
|
@ -16,7 +20,8 @@ sub loadItems()
|
|||
parentid: m.top.itemId,
|
||||
SortBy: sort_field,
|
||||
SortOrder: sort_order,
|
||||
recursive: true
|
||||
recursive: true,
|
||||
Fields: "Overview"
|
||||
}
|
||||
|
||||
if m.top.ItemType <> "" then
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
<field id="itemType" type="string" value="" />
|
||||
<field id="limit" type="integer" value="36" />
|
||||
<field id="metadata" type="associativearray" />
|
||||
<field id="sortField" type="string" value="SortName" />
|
||||
<field id="sortAscending" type="boolean" value="true" />
|
||||
|
||||
<!-- Total records available from server-->
|
||||
<field id="totalRecordCount" type="int" value="-1" />
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
sub init()
|
||||
m.top.backgroundColor = "#101010"
|
||||
m.top.backgroundColor = "#262626" '"#101010"
|
||||
m.top.backgroundURI = ""
|
||||
end sub
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ sub init()
|
|||
m.backdrop = m.top.findNode("backdrop")
|
||||
|
||||
' Randmomise the background colors
|
||||
posterBackgrounds = m.global.poster_bg_pallet
|
||||
posterBackgrounds = m.global.constants.poster_bg_pallet
|
||||
m.backdrop.color = posterBackgrounds[rnd(posterBackgrounds.count()) - 1]
|
||||
|
||||
updateSize()
|
||||
|
|
|
@ -19,7 +19,7 @@ sub itemContentChanged()
|
|||
|
||||
' Randmomise the background colors
|
||||
m.backdrop = m.top.findNode("backdrop")
|
||||
posterBackgrounds = m.global.poster_bg_pallet
|
||||
posterBackgrounds = m.global.constants.poster_bg_pallet
|
||||
m.backdrop.color = posterBackgrounds[rnd(posterBackgrounds.count()) - 1]
|
||||
m.backdrop.width = imageWidth
|
||||
|
||||
|
|
Before Width: | Height: | Size: 329 B After Width: | Height: | Size: 1.9 KiB |
BIN
images/icons/down_black.png
Normal file
After Width: | Height: | Size: 198 B |
BIN
images/icons/down_white.png
Normal file
After Width: | Height: | Size: 196 B |
BIN
images/icons/up_black.png
Normal file
After Width: | Height: | Size: 212 B |
BIN
images/icons/up_white.png
Normal file
After Width: | Height: | Size: 223 B |
BIN
images/option-menu-bg.9.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
|
@ -225,7 +225,7 @@
|
|||
<translation>Error During Playback</translation>
|
||||
<extracomment>Dialog title when error occurs during playback</extracomment>
|
||||
</message>
|
||||
|
||||
|
||||
<message>
|
||||
<source>There was an error retrieving the data for this item from the server.</source>
|
||||
<translation>There was an error retrieving the data for this item from the server.</translation>
|
||||
|
@ -259,6 +259,61 @@
|
|||
<translation>This %1 contains no items</translation>
|
||||
</message>
|
||||
|
||||
</context>
|
||||
<message>
|
||||
<comment>Name or Title field of media item</comment>
|
||||
<source>TITLE</source>
|
||||
<translation>Name</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>IMDB_RATING</source>
|
||||
<translation>IMDb Rating</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>CRITIC_RATING</source>
|
||||
<translation>Critic Rating</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DATE_ADDED</source>
|
||||
<translation>Date Added</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DATE_PLAYED</source>
|
||||
<translation>Date Played</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>OFFICIAL_RATING</source>
|
||||
<translation>Parental Rating</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PLAY_COUNT</source>
|
||||
<translation>Play Count</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>RELEASE_DATE</source>
|
||||
<translation>Release Date</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>RUNTIME</source>
|
||||
<translation>Run Time</translation>
|
||||
</message>
|
||||
|
||||
<message>
|
||||
<comment>Title of Tab for switching "views" when looking at a library</comment>
|
||||
<source>TAB_VIEW</source>
|
||||
<translation>View</translation>
|
||||
</message>
|
||||
|
||||
<message>
|
||||
<comment>Title of Tab for options to sort library content</comment>
|
||||
<source>TAB_SORT</source>
|
||||
<translation>Sort</translation>
|
||||
</message>
|
||||
|
||||
<message>
|
||||
<comment>Title of Tab for options to filter library content</comment>
|
||||
<source>TAB_FILTER</source>
|
||||
<translation>Filter</translation>
|
||||
</message>
|
||||
|
||||
</context>
|
||||
</TS>
|
||||
|
|
|
@ -259,5 +259,61 @@
|
|||
<translation>This %1 contains no items</translation>
|
||||
</message>
|
||||
|
||||
<message>
|
||||
<comment>Name or Title field of media item</comment>
|
||||
<source>TITLE</source>
|
||||
<translation>Name</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>IMDB_RATING</source>
|
||||
<translation>IMDb Rating</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>CRITIC_RATING</source>
|
||||
<translation>Critic Rating</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DATE_ADDED</source>
|
||||
<translation>Date Added</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DATE_PLAYED</source>
|
||||
<translation>Date Played</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>OFFICIAL_RATING</source>
|
||||
<translation>Parental Rating</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PLAY_COUNT</source>
|
||||
<translation>Play Count</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>RELEASE_DATE</source>
|
||||
<translation>Release Date</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>RUNTIME</source>
|
||||
<translation>Run Time</translation>
|
||||
</message>
|
||||
|
||||
<message>
|
||||
<comment>Title of Tab for switching "views" when looking at a library</comment>
|
||||
<source>TAB_VIEW</source>
|
||||
<translation>View</translation>
|
||||
</message>
|
||||
|
||||
<message>
|
||||
<comment>Title of Tab for options to sort library content</comment>
|
||||
<source>TAB_SORT</source>
|
||||
<translation>Sort</translation>
|
||||
</message>
|
||||
|
||||
<message>
|
||||
<comment>Title of Tab for options to filter library content</comment>
|
||||
<source>TAB_FILTER</source>
|
||||
<translation>Filter</translation>
|
||||
</message>
|
||||
|
||||
</context>
|
||||
</TS>
|
||||
|
|
|
@ -6,9 +6,8 @@ sub Main()
|
|||
' The main function that runs when the application is launched.
|
||||
m.screen = CreateObject("roSGScreen")
|
||||
|
||||
' Set Global Constants
|
||||
m.global = m.screen.getGlobalNode()
|
||||
m.global.addFields({ poster_bg_pallet : [ "#00455c", "#44bae1", "#00a4db", "#1c4c5c", "#007ea8" ] })
|
||||
' Set global constants
|
||||
setConstants()
|
||||
|
||||
m.port = CreateObject("roMessagePort")
|
||||
m.screen.setMessagePort(m.port)
|
||||
|
|
29
source/api/constants.brs
Normal file
|
@ -0,0 +1,29 @@
|
|||
' Set global constants
|
||||
sub setConstants()
|
||||
|
||||
globals = m.screen.getGlobalNode()
|
||||
|
||||
' Set Global Constants
|
||||
globals.addFields({
|
||||
constants: {
|
||||
|
||||
poster_bg_pallet: ["#00455c", "#44bae1", "#00a4db", "#1c4c5c", "#007ea8"],
|
||||
|
||||
colors: {
|
||||
button: "#006fab"
|
||||
},
|
||||
|
||||
icons: {
|
||||
ascending_black: "pkg:/images/icons/up_black.png",
|
||||
ascending_white: "pkg:/images/icons/up_white.png",
|
||||
descending_black: "pkg:/images/icons/down_black.png",
|
||||
descending_white: "pkg:/images/icons/down_white.png"
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
|
||||
end sub
|