diff --git a/components/IconButton.brs b/components/IconButton.brs
index ed328cf1..20176757 100644
--- a/components/IconButton.brs
+++ b/components/IconButton.brs
@@ -9,11 +9,11 @@ sub init()
m.top.observeField("height", "onHeightChanged")
m.top.observeField("width", "onWidthChanged")
m.top.observeField("padding", "onPaddingChanged")
- m.top.observeField("focusedChild", "onFocusChanged")
+ m.top.observeField("focus", "onFocusChanged")
end sub
sub onFocusChanged()
- if m.top.hasFocus()
+ if m.top.focus
m.buttonBackground.blendColor = m.top.focusBackground
else
m.buttonBackground.blendColor = m.top.background
@@ -75,5 +75,13 @@ function onKeyEvent(key as string, press as boolean) as boolean
return true
end if
+ if key = "right" and m.top.hasFocus()
+ m.top.escape = "right"
+ end if
+
+ if key = "left" and m.top.hasFocus()
+ m.top.escape = "left"
+ end if
+
return false
end function
diff --git a/components/IconButton.xml b/components/IconButton.xml
index d8d0f51c..7201acdd 100644
--- a/components/IconButton.xml
+++ b/components/IconButton.xml
@@ -1,9 +1,9 @@
-
-
-
+
+
+
@@ -14,6 +14,8 @@
+
+
diff --git a/components/music/AlbumGrid.brs b/components/music/AlbumGrid.brs
index d3d5eb17..e029053c 100644
--- a/components/music/AlbumGrid.brs
+++ b/components/music/AlbumGrid.brs
@@ -1,6 +1,5 @@
sub init()
getData()
- m.top.infocus = false
end sub
function getData()
@@ -35,7 +34,17 @@ function onKeyEvent(key as string, press as boolean) as boolean
if key = "up"
if m.top.itemFocused <= 4
- m.top.infocus = false
+ m.top.escape = key
+ return true
+ end if
+ else if key = "left"
+ if m.top.itemFocused mod 5 = 0
+ m.top.escape = key
+ return true
+ end if
+ else if key = "right"
+ if m.top.itemFocused + 1 mod 5 = 0
+ m.top.escape = key
return true
end if
end if
diff --git a/components/music/AlbumGrid.xml b/components/music/AlbumGrid.xml
index e277b1aa..37221f33 100644
--- a/components/music/AlbumGrid.xml
+++ b/components/music/AlbumGrid.xml
@@ -2,7 +2,7 @@
-
+
diff --git a/components/music/ArtistView.brs b/components/music/ArtistView.brs
index f8d4401f..d2f70542 100644
--- a/components/music/ArtistView.brs
+++ b/components/music/ArtistView.brs
@@ -3,22 +3,23 @@ sub init()
setupMainNode()
setupButtons()
+ m.remoteButtonsActive = true
+
m.albumHeader = m.top.findNode("albumHeader")
m.albumHeader.text = tr("Albums")
m.albums = m.top.findNode("albums")
- m.albums.observeField("infocus", "onAlbumFocusChange")
+ m.albums.observeField("escape", "onAlbumsEscape")
m.pageLoadAnimation = m.top.findNode("pageLoad")
m.pageLoadAnimation.control = "start"
- m.showAlbumsAnimation = m.top.findNode("showAlbums")
- m.hideAlbumsAnimation = m.top.findNode("hideAlbums")
-
m.sectionNavigation = m.top.findNode("sectionNavigation")
m.sectionNavigation.observeField("escape", "onSectionNavigationEscape")
m.sectionNavigation.observeField("selected", "onSectionNavigationSelected")
+ m.sectionScroller = m.top.findNode("sectionScroller")
+
' Load background image
m.LoadBackdropImageTask = CreateObject("roSGNode", "LoadItemsTask")
m.LoadBackdropImageTask.itemsToLoad = "backdropImage"
@@ -30,6 +31,14 @@ sub init()
createDialogPallete()
end sub
+sub onAlbumsEscape()
+ if m.albums.escape = "up"
+ m.sectionNavigation.selected = m.sectionScroller.displayedIndex - 1
+ else if m.albums.escape = "left"
+ m.sectionNavigation.setFocus(true)
+ end if
+end sub
+
' Setup playback buttons, default to Play button selected
sub setupButtons()
m.buttonGrp = m.top.findNode("buttons")
@@ -46,13 +55,13 @@ end sub
sub onButtonSelectedChange()
' Change previously selected button back to default image
if m.previouslySelectedButtonIndex > -1
- selectedButton = m.buttonGrp.getChild(m.previouslySelectedButtonIndex)
- selectedButton.setFocus(false)
+ previousSelectedButton = m.buttonGrp.getChild(m.previouslySelectedButtonIndex)
+ previousSelectedButton.focus = false
end if
' Change selected button image to selected image
selectedButton = m.buttonGrp.getChild(m.top.selectedButtonIndex)
- selectedButton.setFocus(true)
+ selectedButton.focus = true
end sub
sub setupMainNode()
@@ -119,36 +128,16 @@ sub onEllipsisChanged()
end if
end sub
-sub onAlbumFocusChange()
- if m.albums.infocus
- m.albums.setFocus(true)
- m.showAlbumsAnimation.control = "start"
- return
- end if
-
- ' Change selected button image to selected image
- selectedButton = m.buttonGrp.getChild(m.top.selectedButtonIndex)
- selectedButton.setFocus(true)
-
- m.albums.setFocus(false)
- m.hideAlbumsAnimation.control = "start"
-end sub
-
sub onSectionNavigationEscape()
if m.sectionNavigation.escape = "right"
-
- if m.albums.infocus
- m.albums.setFocus(true)
- return
- end if
-
- selectedButton = m.buttonGrp.getChild(0)
- selectedButton.setFocus(true)
+ m.sectionNavigation.setFocus(false)
+ m.remoteButtonsActive = false
+ m.sectionScroller.focus = true
end if
end sub
sub onSectionNavigationSelected()
- m.albums.infocus = (m.sectionNavigation.selected = 1)
+ m.sectionScroller.displayedIndex = m.sectionNavigation.selected
end sub
sub dscrShowFocus()
@@ -191,9 +180,20 @@ sub createDialogPallete()
}
end sub
+sub OnScreenShown()
+ m.sectionScroller.focus = true
+
+ if m.sectionScroller.displayedIndex = 0
+ m.previouslySelectedButtonIndex = m.top.selectedButtonIndex
+ m.top.selectedButtonIndex = 0
+ m.buttonGrp.setFocus(true)
+ end if
+end sub
+
function onKeyEvent(key as string, press as boolean) as boolean
- if key = "left"
- if m.buttonGrp.isInFocusChain()
+
+ if m.buttonGrp.isInFocusChain()
+ if key = "left"
if m.top.selectedButtonIndex > 0
m.previouslySelectedButtonIndex = m.top.selectedButtonIndex
m.top.selectedButtonIndex = m.top.selectedButtonIndex - 1
@@ -201,7 +201,9 @@ function onKeyEvent(key as string, press as boolean) as boolean
end if
if press
- m.buttonGrp.setFocus(false)
+ selectedButton = m.buttonGrp.getChild(m.top.selectedButtonIndex)
+ selectedButton.focus = false
+
m.sectionNavigation.setFocus(true)
return true
end if
@@ -209,29 +211,27 @@ function onKeyEvent(key as string, press as boolean) as boolean
return false
end if
- if m.albums.isInFocusChain()
- if m.albums.itemFocused mod 5 = 0
- m.sectionNavigation.setFocus(true)
+ if key = "right"
+ if m.top.pageContent.count() = 1 then return false
+
+ if m.buttonGrp.getChild(m.top.selectedButtonIndex).escape = "right"
+ m.buttonGrp.getChild(m.top.selectedButtonIndex).escape = ""
+ m.previouslySelectedButtonIndex = m.top.selectedButtonIndex
+
+ if m.top.selectedButtonIndex < m.buttonCount - 1
+ m.top.selectedButtonIndex = m.top.selectedButtonIndex + 1
+ end if
+
return true
end if
end if
- end if
- if m.buttonGrp.isInFocusChain()
if key = "down"
- m.albums.infocus = true
- return true
- else if key = "right"
- if m.sectionNavigation.escape = "right"
- m.sectionNavigation.escape = ""
- return true
- end if
+ selectedButton = m.buttonGrp.getChild(m.top.selectedButtonIndex)
+ selectedButton.focus = false
- if m.top.pageContent.count() = 1 then return false
- m.previouslySelectedButtonIndex = m.top.selectedButtonIndex
- if m.top.selectedButtonIndex < m.buttonCount - 1 then m.top.selectedButtonIndex = m.top.selectedButtonIndex + 1
-
- return true
+ m.top.selectedButtonIndex = 0
+ m.sectionNavigation.selected = m.sectionScroller.displayedIndex + 1
end if
end if
diff --git a/components/music/ArtistView.xml b/components/music/ArtistView.xml
index 6dbbeefe..f02c2edd 100644
--- a/components/music/ArtistView.xml
+++ b/components/music/ArtistView.xml
@@ -1,22 +1,30 @@
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
@@ -24,26 +32,10 @@
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/components/section/section.brs b/components/section/section.brs
new file mode 100644
index 00000000..98dd6944
--- /dev/null
+++ b/components/section/section.brs
@@ -0,0 +1,61 @@
+sub init()
+ m.showFromBottomAnimation = m.top.findNode("showFromBottomAnimation")
+ m.showFromBottomPosition = m.top.findNode("showFromBottomPosition")
+ m.showFromBottomOpacity = m.top.findNode("showFromBottomOpacity")
+
+ m.showFromTopAnimation = m.top.findNode("showFromTopAnimation")
+ m.showFromTopPosition = m.top.findNode("showFromTopPosition")
+ m.showFromTopOpacity = m.top.findNode("showFromTopOpacity")
+
+ m.scrollOffTopAnimation = m.top.findNode("scrollOffTopAnimation")
+ m.scrollOffTopPosition = m.top.findNode("scrollOffTopPosition")
+ m.scrollOffTopOpacity = m.top.findNode("scrollOffTopOpacity")
+
+ m.scrollOffBottomAnimation = m.top.findNode("scrollOffBottomAnimation")
+ m.scrollOffBottomPosition = m.top.findNode("scrollOffBottomPosition")
+ m.scrollOffBottomOpacity = m.top.findNode("scrollOffBottomOpacity")
+
+ m.top.observeField("id", "onIDChange")
+ m.top.observeField("focusedChild", "onFocusChange")
+end sub
+
+sub onIDChange()
+ m.showFromBottomPosition.fieldToInterp = m.top.id + ".translation"
+ m.showFromBottomOpacity.fieldToInterp = m.top.id + ".opacity"
+
+ m.showFromTopPosition.fieldToInterp = m.top.id + ".translation"
+ m.showFromTopOpacity.fieldToInterp = m.top.id + ".opacity"
+
+ m.scrollOffTopPosition.fieldToInterp = m.top.id + ".translation"
+ m.scrollOffTopOpacity.fieldToInterp = m.top.id + ".opacity"
+
+ m.scrollOffBottomPosition.fieldToInterp = m.top.id + ".translation"
+ m.scrollOffBottomOpacity.fieldToInterp = m.top.id + ".opacity"
+end sub
+
+sub showFromTop()
+ m.showFromTopAnimation.control = "start"
+end sub
+
+sub showFromBottom()
+ m.showFromBottomAnimation.control = "start"
+end sub
+
+sub scrollOffBottom()
+ m.scrollOffBottomAnimation.control = "start"
+end sub
+
+sub scrollOffTop()
+ m.scrollOffTopAnimation.control = "start"
+end sub
+
+sub onFocusChange()
+ defaultFocusElement = m.top.findNode(m.top.defaultFocusID)
+
+ if isValid(defaultFocusElement)
+ defaultFocusElement.setFocus(m.top.isInFocusChain())
+ if isValid(defaultFocusElement.focus)
+ defaultFocusElement.focus = m.top.isInFocusChain()
+ end if
+ end if
+end sub
diff --git a/components/section/section.xml b/components/section/section.xml
new file mode 100644
index 00000000..ffba7582
--- /dev/null
+++ b/components/section/section.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/section/sectionScroller.brs b/components/section/sectionScroller.brs
new file mode 100644
index 00000000..9749813e
--- /dev/null
+++ b/components/section/sectionScroller.brs
@@ -0,0 +1,37 @@
+sub init()
+ m.previouslyDisplayedSection = 0
+end sub
+
+sub onFocusChange()
+ if m.top.focus
+ m.top.getChild(m.top.displayedIndex).setFocus(true)
+ end if
+end sub
+
+sub displayedIndexChanged()
+ if not m.top.affectsFocus then return
+
+ if m.top.displayedIndex < 0
+ return
+ end if
+
+ if m.top.displayedIndex > (m.top.getChildCount() - 1)
+ return
+ end if
+
+ m.top.getChild(m.previouslyDisplayedSection).setFocus(false)
+
+ displayedSection = m.top.getChild(m.top.displayedIndex)
+ displayedSection.setFocus(true)
+
+ ' Move sections either up or down depending on what index we're moving to
+ if m.top.displayedIndex > m.previouslyDisplayedSection
+ m.top.getChild(m.previouslyDisplayedSection).callFunc("scrollOffTop")
+ displayedSection.callFunc("showFromBottom")
+ else if m.top.displayedIndex < m.previouslyDisplayedSection
+ m.top.getChild(m.previouslyDisplayedSection).callFunc("scrollOffBottom")
+ displayedSection.callFunc("showFromTop")
+ end if
+
+ m.previouslyDisplayedSection = m.top.displayedIndex
+end sub
diff --git a/components/section/sectionScroller.xml b/components/section/sectionScroller.xml
new file mode 100644
index 00000000..13aeef54
--- /dev/null
+++ b/components/section/sectionScroller.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/package-lock.json b/package-lock.json
index c4699ea5..ce612aed 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -11,7 +11,7 @@
"license": "GPL-2.0",
"dependencies": {
"api": "npm:jellyfin-api-bs-client@^1.0.5",
- "bgv": "npm:button-group-vert@^1.0.1",
+ "bgv": "npm:button-group-vert@^1.0.2",
"brighterscript-formatter": "^1.6.8",
"intKeyboard": "npm:integer-keyboard@^1.0.12",
"sob": "npm:slide-out-button@^1.0.1"
@@ -784,9 +784,9 @@
},
"node_modules/bgv": {
"name": "button-group-vert",
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/button-group-vert/-/button-group-vert-1.0.1.tgz",
- "integrity": "sha512-PtOAglZ7w1ebPR5PVxtPNfADydhwU9pJ8X4KKkaqvuDwNMOcD2LkwpgCH0nuGm/yzrws9Kqkqf86IC5mZh8xsQ=="
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/button-group-vert/-/button-group-vert-1.0.2.tgz",
+ "integrity": "sha512-pfrUYI/aFubtjhA8I08qNCtDluyIScksldR15icR7Pj24tNELYCYXE7M0jaU7xgdiFAhZJcYuB3aCXzyI1CoMw=="
},
"node_modules/binary-extensions": {
"version": "1.13.1",
@@ -6927,9 +6927,9 @@
}
},
"bgv": {
- "version": "npm:button-group-vert@1.0.1",
- "resolved": "https://registry.npmjs.org/button-group-vert/-/button-group-vert-1.0.1.tgz",
- "integrity": "sha512-PtOAglZ7w1ebPR5PVxtPNfADydhwU9pJ8X4KKkaqvuDwNMOcD2LkwpgCH0nuGm/yzrws9Kqkqf86IC5mZh8xsQ=="
+ "version": "npm:button-group-vert@1.0.2",
+ "resolved": "https://registry.npmjs.org/button-group-vert/-/button-group-vert-1.0.2.tgz",
+ "integrity": "sha512-pfrUYI/aFubtjhA8I08qNCtDluyIScksldR15icR7Pj24tNELYCYXE7M0jaU7xgdiFAhZJcYuB3aCXzyI1CoMw=="
},
"binary-extensions": {
"version": "1.13.1",
diff --git a/package.json b/package.json
index e661db23..0b20c6f5 100644
--- a/package.json
+++ b/package.json
@@ -36,7 +36,7 @@
"homepage": "https://github.com/jellyfin/jellyfin-roku#readme",
"dependencies": {
"api": "npm:jellyfin-api-bs-client@^1.0.5",
- "bgv": "npm:button-group-vert@^1.0.1",
+ "bgv": "npm:button-group-vert@^1.0.2",
"brighterscript-formatter": "^1.6.8",
"sob": "npm:slide-out-button@^1.0.1",
"intKeyboard": "npm:integer-keyboard@^1.0.12"