jellyfin-roku/components/ItemGrid/ItemGridOptions.bs
2024-07-31 08:54:20 -04:00

391 lines
14 KiB
Plaintext

import "pkg:/source/utils/misc.bs"
import "pkg:/source/roku_modules/log/LogMixin.brs"
sub init()
m.log = log.Logger("ItemGridOptions")
m.buttons = m.top.findNode("buttons")
m.buttons.buttons = [tr("View"), tr("Sort"), tr("Filter")]
m.buttons.selectedIndex = 1
m.buttons.setFocus(true)
m.favoriteMenu = m.top.findNode("favoriteMenu")
m.selectedFavoriteItem = m.top.findNode("selectedFavoriteItem")
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.filterOptions = m.top.findNode("filterOptions")
m.filterMenu = m.top.findNode("filterMenu")
m.filterMenu.observeField("itemFocused", "onFilterFocusChange")
m.viewNames = []
m.sortNames = []
m.filterNames = []
' Animation
m.fadeAnim = m.top.findNode("fadeAnim")
m.fadeOutAnimOpacity = m.top.findNode("outOpacity")
m.fadeInAnimOpacity = m.top.findNode("inOpacity")
m.showChecklistAnimation = m.top.findNode("showChecklistAnimation")
m.hideChecklistAnimation = m.top.findNode("hideChecklistAnimation")
m.buttons.observeField("focusedIndex", "buttonFocusChanged")
m.favoriteMenu.observeField("buttonSelected", "toggleFavorite")
end sub
sub showChecklist()
if m.filterOptions.opacity = 0
if m.showChecklistAnimation.state = "stopped"
m.showChecklistAnimation.control = "start"
end if
end if
end sub
sub hideChecklist()
if m.filterOptions.opacity = 1
if m.hideChecklistAnimation.state = "stopped"
m.hideChecklistAnimation.control = "start"
end if
end if
end sub
sub onFilterFocusChange()
if not isFilterMenuDataValid()
hideChecklist()
return
end if
if m.filterMenu.content.getChild(m.filterMenu.itemFocused).getChildCount() > 0
showChecklist()
else
hideChecklist()
end if
m.filterOptions.content = m.filterMenu.content.getChild(m.filterMenu.itemFocused)
if isValid(m.filterMenu.content.getChild(m.filterMenu.itemFocused).checkedState)
m.filterOptions.checkedState = m.filterMenu.content.getChild(m.filterMenu.itemFocused).checkedState
else
m.filterOptions.checkedState = []
end if
end sub
' Check if data for Filter Menu is valid
function isFilterMenuDataValid() as boolean
if not isValid(m.filterMenu) or not isValid(m.filterMenu.content) or not isValid(m.filterMenu.itemFocused)
return false
end if
if not isValid(m.filterMenu.content.getChild(m.filterMenu.itemFocused))
return false
end if
return true
end function
sub optionsSet()
' Views Tab
if m.top.options.views <> invalid
viewContent = CreateObject("roSGNode", "ContentNode")
index = 0
selectedViewIndex = m.selectedViewIndex
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) or viewContent.Name = m.top.view
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
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
m.selectedSortIndex = index
if sortItem.Ascending <> invalid and sortItem.Ascending = false
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
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
' Filter Tab
if m.top.options.filter <> invalid
filterContent = CreateObject("roSGNode", "ContentNode")
index = 0
m.selectedFilterIndex = 0
for each filterItem in m.top.options.filter
entry = filterContent.CreateChild("OptionNode")
entry.title = filterItem.Title
entry.name = filterItem.Name
entry.delimiter = filterItem.Delimiter
if isValid(filterItem.options)
for each filterItemOption in filterItem.options
entryOption = entry.CreateChild("ContentNode")
entryOption.title = toString(filterItemOption)
end for
entry.checkedState = filterItem.checkedState
end if
m.filterNames.push(filterItem.Name)
if filterItem.selected <> invalid and filterItem.selected = true
m.selectedFilterIndex = index
end if
index = index + 1
end for
m.menus[2].content = filterContent
m.menus[2].checkedItem = m.selectedFilterIndex
else
filterContent = CreateObject("roSGNode", "ContentNode")
entry = filterContent.CreateChild("ContentNode")
entry.title = "All"
m.filterNames.push("All")
m.menus[2].content = filterContent
m.menus[2].checkedItem = 0
end if
end sub
' Switch menu shown when button focus changes
sub buttonFocusChanged()
if m.buttons.focusedIndex = m.selectedItem
if m.buttons.hasFocus()
m.buttons.setFocus(false)
m.menus[m.selectedItem].setFocus(false)
m.menus[m.selectedItem].visible = false
m.favoriteMenu.setFocus(true)
end if
end if
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
sub toggleFavorite()
if not isValid(m.selectedFavoriteItem) then return
m.favItemsTask = createObject("roSGNode", "FavoriteItemsTask")
if m.favoriteMenu.iconUri = "pkg:/images/icons/favorite.png"
m.favoriteMenu.iconUri = "pkg:/images/icons/favorite_selected.png"
m.favoriteMenu.focusedIconUri = "pkg:/images/icons/favorite_selected.png"
' Run the task to actually favorite it via API
m.favItemsTask.favTask = "Favorite"
m.favItemsTask.itemId = m.selectedFavoriteItem.id
m.favItemsTask.control = "RUN"
else
m.favoriteMenu.iconUri = "pkg:/images/icons/favorite.png"
m.favoriteMenu.focusedIconUri = "pkg:/images/icons/favorite.png"
m.favItemsTask.favTask = "Unfavorite"
m.favItemsTask.itemId = m.selectedFavoriteItem.id
m.favItemsTask.control = "RUN"
end if
' Make sure we set the Favorite Heart color for the appropriate child
setHeartColor("#cc3333")
end sub
sub setHeartColor(color as string)
try
for i = 0 to 6
node = m.favoriteMenu.getChild(i)
if node <> invalid and node.uri <> invalid and node.uri = "pkg:/images/icons/favorite_selected.png"
m.favoriteMenu.getChild(i).blendColor = color
end if
end for
catch e
m.log.error("setHeartColor()", e.number, e.message)
end try
end sub
sub saveFavoriteItemSelected(msg)
data = msg.GetData()
m.selectedFavoriteItem = data
' Favorite button
if m.selectedFavoriteItem <> invalid
if m.selectedFavoriteItem.favorite = true
m.favoriteMenu.iconUri = "pkg:/images/icons/favorite_selected.png"
m.favoriteMenu.focusedIconUri = "pkg:/images/icons/favorite_selected.png"
' Make sure we set the Favorite Heart color for the appropriate child
setHeartColor("#cc3333")
else
m.favoriteMenu.iconUri = "pkg:/images/icons/favorite.png"
m.favoriteMenu.focusedIconUri = "pkg:/images/icons/favorite.png"
' Make sure we set the Favorite Heart color for the appropriate child
setHeartColor("#cc3333")
end if
end if
end sub
function onKeyEvent(key as string, press as boolean) as boolean
if key = "down" or (key = "OK" and m.buttons.hasFocus())
m.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"
m.menus[m.selectedItem].jumpToItem = 0
else
m.menus[m.selectedItem].jumpToItem = m.menus[m.selectedItem].itemSelected
end if
return true
else if key = "right"
if not isFilterMenuDataValid() then return false
if m.menus[m.selectedItem].isInFocusChain()
' Handle Filter screen
if m.selectedItem = 2
' Selected filter has options, move cursor to it
if m.filterMenu.content.getChild(m.filterMenu.itemFocused).getChildCount() > 0
m.menus[m.selectedItem].setFocus(false)
m.filterOptions.setFocus(true)
return true
end if
end if
end if
else if key = "left"
if m.favoriteMenu.hasFocus()
m.favoriteMenu.setFocus(false)
m.menus[m.selectedItem].visible = true
m.buttons.setFocus(true)
end if
' User wants to escape filter options
if m.filterOptions.isInFocusChain()
m.filterOptions.setFocus(false)
m.menus[m.selectedItem].setFocus(true)
return true
end if
else if key = "OK"
if m.menus[m.selectedItem].isInFocusChain()
' Handle View Screen
if m.selectedItem = 0
m.selectedViewIndex = m.menus[0].itemSelected
m.top.view = m.viewNames[m.selectedViewIndex]
end if
' Handle Sort screen
if m.selectedItem = 1
if m.menus[1].itemSelected <> m.selectedSortIndex
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
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
' Handle Filter screen
if m.selectedItem = 2
if not isFilterMenuDataValid() then return false
' If filter has no options, select it
if m.filterMenu.content.getChild(m.filterMenu.itemFocused).getChildCount() = 0
m.menus[2].checkedItem = m.menus[2].itemSelected
m.selectedFilterIndex = m.menus[2].itemSelected
m.top.filter = m.filterNames[m.selectedFilterIndex]
m.top.filterOptions = {}
return true
end if
' Selected filter has options, move cursor to it
m.filterOptions.setFocus(true)
m.menus[m.selectedItem].setFocus(false)
return true
end if
end if
' User pressed OK from inside the filter's options
if m.filterOptions.isInFocusChain()
selectedOptions = []
for i = 0 to m.filterOptions.checkedState.count() - 1
if m.filterOptions.checkedState[i]
selectedValue = toString(m.filterOptions.content.getChild(i).title)
selectedOptions.push(selectedValue)
end if
end for
if selectedOptions.Count() > 0
m.menus[2].checkedItem = m.menus[2].itemFocused
m.selectedFilterIndex = m.menus[2].itemFocused
m.top.filter = m.filterMenu.content.getChild(m.filterMenu.itemFocused).Name
newFilter = {}
newFilter[m.top.filter] = selectedOptions.join(m.filterMenu.content.getChild(m.filterMenu.itemFocused).delimiter)
m.top.filterOptions = newFilter
else
m.menus[2].checkedItem = 0
m.selectedFilterIndex = 0
m.top.filter = m.filterNames[0]
m.top.filterOptions = {}
end if
m.filterMenu.content.getChild(m.filterMenu.itemFocused).checkedState = m.filterOptions.checkedState
return true
end if
return true
else if key = "back" or key = "up"
if key = "back" then hideChecklist()
m.menus[2].visible = true ' Show Filter contents in case hidden by favorite button
if m.menus[m.selectedItem].isInFocusChain()
m.buttons.setFocus(true)
m.menus[m.selectedItem].drawFocusFeedback = false
return true
end if
else if key = "options"
hideChecklist()
m.menus[2].visible = true ' Show Filter contents in case hidden by favorite button
m.menus[m.selectedItem].drawFocusFeedback = false
return false
end if
return false
end function