2023-10-03 16:11:25 +00:00
|
|
|
import "pkg:/source/utils/misc.bs"
|
2023-10-03 16:27:07 +00:00
|
|
|
import "pkg:/source/roku_modules/log/LogMixin.brs"
|
2020-08-08 20:43:37 +00:00
|
|
|
|
2023-05-03 21:21:04 +00:00
|
|
|
sub init()
|
|
|
|
m.log = log.Logger("ItemGridOptions")
|
2021-07-09 20:08:32 +00:00
|
|
|
m.buttons = m.top.findNode("buttons")
|
2022-09-05 06:50:13 +00:00
|
|
|
m.buttons.buttons = [tr("View"), tr("Sort"), tr("Filter")]
|
2021-07-09 20:08:32 +00:00
|
|
|
m.buttons.selectedIndex = 1
|
|
|
|
m.buttons.setFocus(true)
|
2020-08-08 20:43:37 +00:00
|
|
|
|
2022-05-14 10:13:28 +00:00
|
|
|
m.favoriteMenu = m.top.findNode("favoriteMenu")
|
|
|
|
m.selectedFavoriteItem = m.top.findNode("selectedFavoriteItem")
|
|
|
|
|
2021-07-09 20:08:32 +00:00
|
|
|
m.selectedSortIndex = 0
|
|
|
|
m.selectedItem = 1
|
2020-08-08 20:43:37 +00:00
|
|
|
|
2021-07-09 20:08:32 +00:00
|
|
|
m.menus = []
|
|
|
|
m.menus.push(m.top.findNode("viewMenu"))
|
|
|
|
m.menus.push(m.top.findNode("sortMenu"))
|
|
|
|
m.menus.push(m.top.findNode("filterMenu"))
|
2020-08-08 20:43:37 +00:00
|
|
|
|
2023-02-25 19:51:36 +00:00
|
|
|
m.filterOptions = m.top.findNode("filterOptions")
|
|
|
|
|
|
|
|
m.filterMenu = m.top.findNode("filterMenu")
|
|
|
|
m.filterMenu.observeField("itemFocused", "onFilterFocusChange")
|
|
|
|
|
2021-07-09 20:08:32 +00:00
|
|
|
m.viewNames = []
|
|
|
|
m.sortNames = []
|
|
|
|
m.filterNames = []
|
2020-08-15 10:26:43 +00:00
|
|
|
|
2021-07-09 20:08:32 +00:00
|
|
|
' Animation
|
|
|
|
m.fadeAnim = m.top.findNode("fadeAnim")
|
|
|
|
m.fadeOutAnimOpacity = m.top.findNode("outOpacity")
|
|
|
|
m.fadeInAnimOpacity = m.top.findNode("inOpacity")
|
2023-02-25 19:51:36 +00:00
|
|
|
m.showChecklistAnimation = m.top.findNode("showChecklistAnimation")
|
|
|
|
m.hideChecklistAnimation = m.top.findNode("hideChecklistAnimation")
|
2020-08-16 16:17:41 +00:00
|
|
|
|
2021-07-09 20:08:32 +00:00
|
|
|
m.buttons.observeField("focusedIndex", "buttonFocusChanged")
|
2022-05-14 10:13:28 +00:00
|
|
|
m.favoriteMenu.observeField("buttonSelected", "toggleFavorite")
|
2020-08-08 20:43:37 +00:00
|
|
|
end sub
|
|
|
|
|
2023-02-25 19:51:36 +00:00
|
|
|
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()
|
2023-05-20 01:23:13 +00:00
|
|
|
if not isFilterMenuDataValid()
|
2023-04-20 16:01:52 +00:00
|
|
|
hideChecklist()
|
|
|
|
return
|
|
|
|
end if
|
|
|
|
|
2023-02-25 19:51:36 +00:00
|
|
|
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
|
2020-08-08 20:43:37 +00:00
|
|
|
|
2023-04-20 16:12:52 +00:00
|
|
|
' Check if data for Filter Menu is valid
|
2023-04-20 16:01:52 +00:00
|
|
|
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
|
2020-08-08 20:43:37 +00:00
|
|
|
|
2023-02-25 19:51:36 +00:00
|
|
|
sub optionsSet()
|
2021-07-09 20:08:32 +00:00
|
|
|
' Views Tab
|
|
|
|
if m.top.options.views <> invalid
|
|
|
|
viewContent = CreateObject("roSGNode", "ContentNode")
|
|
|
|
index = 0
|
2022-07-09 08:39:29 +00:00
|
|
|
selectedViewIndex = m.selectedViewIndex
|
2021-07-09 20:08:32 +00:00
|
|
|
|
|
|
|
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
|
2020-08-16 14:44:03 +00:00
|
|
|
|
2021-07-09 20:08:32 +00:00
|
|
|
' 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
|
2020-08-16 14:44:03 +00:00
|
|
|
else
|
2021-07-09 20:08:32 +00:00
|
|
|
m.menus[1].focusedCheckedIconUri = m.global.constants.icons.descending_black
|
|
|
|
m.menus[1].checkedIconUri = m.global.constants.icons.descending_white
|
2020-08-16 14:44:03 +00:00
|
|
|
end if
|
2021-07-09 20:08:32 +00:00
|
|
|
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
|
2023-02-25 19:51:36 +00:00
|
|
|
entry = filterContent.CreateChild("OptionNode")
|
2021-07-09 20:08:32 +00:00
|
|
|
entry.title = filterItem.Title
|
2023-02-25 19:51:36 +00:00
|
|
|
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
|
|
|
|
|
2021-07-09 20:08:32 +00:00
|
|
|
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
|
2020-08-16 14:44:03 +00:00
|
|
|
else
|
2021-07-09 20:08:32 +00:00
|
|
|
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
|
2020-08-16 14:44:03 +00:00
|
|
|
end if
|
|
|
|
end sub
|
2020-08-08 20:43:37 +00:00
|
|
|
|
2020-08-16 16:17:41 +00:00
|
|
|
' Switch menu shown when button focus changes
|
2020-08-16 14:44:03 +00:00
|
|
|
sub buttonFocusChanged()
|
2022-05-14 10:13:28 +00:00
|
|
|
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
|
2021-07-09 20:08:32 +00:00
|
|
|
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
|
2020-08-08 20:43:37 +00:00
|
|
|
end sub
|
|
|
|
|
2022-05-14 10:13:28 +00:00
|
|
|
sub toggleFavorite()
|
|
|
|
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)
|
2022-05-30 18:40:33 +00:00
|
|
|
try
|
2022-05-30 14:03:59 +00:00
|
|
|
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
|
2022-05-30 18:40:33 +00:00
|
|
|
catch e
|
2023-05-03 21:21:04 +00:00
|
|
|
m.log.error("setHeartColor()", e.number, e.message)
|
2022-05-30 18:40:33 +00:00
|
|
|
end try
|
2022-05-14 10:13:28 +00:00
|
|
|
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
|
2020-08-08 20:43:37 +00:00
|
|
|
|
|
|
|
function onKeyEvent(key as string, press as boolean) as boolean
|
2022-05-14 10:13:28 +00:00
|
|
|
if key = "down" or (key = "OK" and m.buttons.hasFocus())
|
|
|
|
m.buttons.setFocus(false)
|
2021-07-09 20:08:32 +00:00
|
|
|
m.menus[m.selectedItem].setFocus(true)
|
|
|
|
m.menus[m.selectedItem].drawFocusFeedback = true
|
2020-08-16 16:17:41 +00:00
|
|
|
|
2021-07-09 20:08:32 +00:00
|
|
|
'If user presses down from button menu, focus first item. If OK, focus checked item
|
|
|
|
if key = "down"
|
|
|
|
m.menus[m.selectedItem].jumpToItem = 0
|
2020-08-15 10:26:43 +00:00
|
|
|
else
|
2021-07-09 20:08:32 +00:00
|
|
|
m.menus[m.selectedItem].jumpToItem = m.menus[m.selectedItem].itemSelected
|
|
|
|
end if
|
2020-08-16 14:44:03 +00:00
|
|
|
|
2021-07-09 20:08:32 +00:00
|
|
|
return true
|
2023-02-25 19:51:36 +00:00
|
|
|
else if key = "right"
|
2023-05-20 01:23:13 +00:00
|
|
|
if not isFilterMenuDataValid() then return false
|
2023-04-25 18:18:21 +00:00
|
|
|
|
2023-02-25 19:51:36 +00:00
|
|
|
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
|
2022-05-14 10:13:28 +00:00
|
|
|
else if key = "left"
|
|
|
|
if m.favoriteMenu.hasFocus()
|
|
|
|
m.favoriteMenu.setFocus(false)
|
|
|
|
m.menus[m.selectedItem].visible = true
|
|
|
|
m.buttons.setFocus(true)
|
|
|
|
end if
|
2023-02-25 19:51:36 +00:00
|
|
|
|
|
|
|
' User wants to escape filter options
|
|
|
|
if m.filterOptions.isInFocusChain()
|
|
|
|
m.filterOptions.setFocus(false)
|
|
|
|
m.menus[m.selectedItem].setFocus(true)
|
|
|
|
return true
|
|
|
|
end if
|
2021-07-09 20:08:32 +00:00
|
|
|
else if key = "OK"
|
2023-04-25 18:18:21 +00:00
|
|
|
|
2021-07-09 20:08:32 +00:00
|
|
|
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
|
2023-02-25 19:51:36 +00:00
|
|
|
|
2021-07-09 20:08:32 +00:00
|
|
|
' Handle Filter screen
|
|
|
|
if m.selectedItem = 2
|
2023-05-20 01:23:13 +00:00
|
|
|
if not isFilterMenuDataValid() then return false
|
2023-02-25 19:51:36 +00:00
|
|
|
' 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
|
2021-07-09 20:08:32 +00:00
|
|
|
end if
|
2020-08-15 10:26:43 +00:00
|
|
|
end if
|
2023-02-25 19:51:36 +00:00
|
|
|
|
|
|
|
' 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
|
2021-07-09 20:08:32 +00:00
|
|
|
return true
|
|
|
|
else if key = "back" or key = "up"
|
2023-02-25 19:51:36 +00:00
|
|
|
if key = "back" then hideChecklist()
|
|
|
|
|
2022-05-14 10:13:28 +00:00
|
|
|
m.menus[2].visible = true ' Show Filter contents in case hidden by favorite button
|
2021-07-09 20:08:32 +00:00
|
|
|
if m.menus[m.selectedItem].isInFocusChain()
|
|
|
|
m.buttons.setFocus(true)
|
|
|
|
m.menus[m.selectedItem].drawFocusFeedback = false
|
|
|
|
return true
|
|
|
|
end if
|
|
|
|
else if key = "options"
|
2023-02-25 19:51:36 +00:00
|
|
|
hideChecklist()
|
2022-05-14 10:13:28 +00:00
|
|
|
m.menus[2].visible = true ' Show Filter contents in case hidden by favorite button
|
2021-07-09 20:08:32 +00:00
|
|
|
m.menus[m.selectedItem].drawFocusFeedback = false
|
|
|
|
return false
|
2020-08-08 20:43:37 +00:00
|
|
|
end if
|
|
|
|
|
2021-07-09 20:08:32 +00:00
|
|
|
return false
|
2022-05-30 12:57:40 +00:00
|
|
|
end function
|