WIP for Itemgrid Options
|
@ -18,7 +18,7 @@ function onKeyEvent(key as string, press as boolean) as boolean
|
||||||
return true
|
return true
|
||||||
else if key = "up" or key = "down"
|
else if key = "up" or key = "down"
|
||||||
m.top.escape = true
|
m.top.escape = true
|
||||||
return true
|
return false
|
||||||
end if
|
end if
|
||||||
|
|
||||||
return false
|
return false
|
||||||
|
|
112
components/Buttons/JFButtons.brs
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
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")
|
||||||
|
|
||||||
|
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
|
||||||
|
end if
|
||||||
|
return false
|
||||||
|
end function
|
32
components/Buttons/JFButtons.xml
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
<?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" color="#006fab" />
|
||||||
|
|
||||||
|
<LayoutGroup id="buttonGroup" layoutDirection="horiz" itemSpacings = "[75]" translation="[50,20]">
|
||||||
|
</LayoutGroup>
|
||||||
|
|
||||||
|
<Animation id="moveFocusAnimation" duration="0.25" repeat="false" easeFunction="outQuad" >
|
||||||
|
<!-- <FloatFieldInterpolator id = "focusOpacity" key="[0.0, 0.5, 1.0]" keyValue="[ 1, 0.6, 1 ]" fieldToInterp="focus.opacity" /> -->
|
||||||
|
<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>
|
||||||
|
|
||||||
|
<!-- <customEPGGrid /> -->
|
||||||
|
</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>
|
|
@ -1,5 +1,8 @@
|
||||||
sub init()
|
sub init()
|
||||||
|
|
||||||
|
m.options = m.top.findNode("options")
|
||||||
|
|
||||||
|
|
||||||
m.itemGrid = m.top.findNode("itemGrid")
|
m.itemGrid = m.top.findNode("itemGrid")
|
||||||
m.backdrop = m.top.findNode("backdrop")
|
m.backdrop = m.top.findNode("backdrop")
|
||||||
m.newBackdrop = m.top.findNode("backdropTransition")
|
m.newBackdrop = m.top.findNode("backdropTransition")
|
||||||
|
@ -157,3 +160,24 @@ end sub
|
||||||
sub onItemSelected()
|
sub onItemSelected()
|
||||||
m.top.selectedItem = m.itemGrid.content.getChild(m.itemGrid.itemSelected)
|
m.top.selectedItem = m.itemGrid.content.getChild(m.itemGrid.itemSelected)
|
||||||
end sub
|
end sub
|
||||||
|
|
||||||
|
|
||||||
|
function onKeyEvent(key as string, press as boolean) as boolean
|
||||||
|
|
||||||
|
' print "IG KeyPress " key
|
||||||
|
|
||||||
|
if not press then return false
|
||||||
|
|
||||||
|
if key = "options"
|
||||||
|
print "OPTIONS!!!!!!!!!"
|
||||||
|
if m.options.visible = true then
|
||||||
|
m.options.visible = false
|
||||||
|
m.itemGrid.setFocus(true)
|
||||||
|
else
|
||||||
|
m.options.visible = true
|
||||||
|
m.options.setFocus(true)
|
||||||
|
end if
|
||||||
|
return true
|
||||||
|
end if
|
||||||
|
return false
|
||||||
|
end function
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
itemSpacing = "[ 0, 45 ]"
|
itemSpacing = "[ 0, 45 ]"
|
||||||
drawFocusFeedback = "false" />
|
drawFocusFeedback = "false" />
|
||||||
<Label translation="[0,540]" id="emptyText" font="font:LargeSystemFont" width="1920" horizAlign="center" vertAlign="center" height="64" visible="false" />
|
<Label translation="[0,540]" id="emptyText" font="font:LargeSystemFont" width="1920" horizAlign="center" vertAlign="center" height="64" visible="false" />
|
||||||
<OptionsSlider id="options" />
|
<OptionsScreen id="options" visible="false" />
|
||||||
<Animation id="backroundSwapAnimation" duration="1" repeat="false" easeFunction="linear" >
|
<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 = "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" />
|
<FloatFieldInterpolator id = "fadeoutLoaded" key="[0.0, 1.0]" keyValue="[ 0.25, 0.00 ]" fieldToInterp="backdrop.opacity" />
|
||||||
|
|
|
@ -16,7 +16,8 @@ sub loadItems()
|
||||||
parentid: m.top.itemId,
|
parentid: m.top.itemId,
|
||||||
SortBy: sort_field,
|
SortBy: sort_field,
|
||||||
SortOrder: sort_order,
|
SortOrder: sort_order,
|
||||||
recursive: true
|
recursive: true,
|
||||||
|
Fields: "Overview"
|
||||||
}
|
}
|
||||||
|
|
||||||
if m.top.ItemType <> "" then
|
if m.top.ItemType <> "" then
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
sub init()
|
sub init()
|
||||||
m.top.backgroundColor = "#101010"
|
m.top.backgroundColor = "#262626" '"#101010"
|
||||||
m.top.backgroundURI = ""
|
m.top.backgroundURI = ""
|
||||||
end sub
|
end sub
|
||||||
|
|
||||||
|
|
87
components/options/OptionsScreen.brs
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
sub init()
|
||||||
|
|
||||||
|
m.buttons = m.top.findNode("buttons")
|
||||||
|
m.buttons.buttons = ["View", "Sort", "Filter"]
|
||||||
|
m.buttons.setFocus(true)
|
||||||
|
|
||||||
|
m.ascending = true
|
||||||
|
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.buttons.observeField("focusedIndex", "buttonFocusChanged")
|
||||||
|
|
||||||
|
end sub
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
sub buttonFocusChanged()
|
||||||
|
|
||||||
|
print "Button focus changed to index ", m.buttons.focusedIndex
|
||||||
|
|
||||||
|
if m.buttons.focusedIndex = m.selectedItem then return
|
||||||
|
|
||||||
|
print "Hiding " m.selectedItem
|
||||||
|
m.menus[m.selectedItem].visible = false
|
||||||
|
|
||||||
|
print "Showing " m.buttons.focusedIndex
|
||||||
|
m.menus[m.buttons.focusedIndex].visible = true
|
||||||
|
|
||||||
|
m.selectedItem = m.buttons.focusedIndex
|
||||||
|
|
||||||
|
end sub
|
||||||
|
|
||||||
|
|
||||||
|
function onKeyEvent(key as string, press as boolean) as boolean
|
||||||
|
|
||||||
|
|
||||||
|
' print "OS KeyPress " key
|
||||||
|
|
||||||
|
if not press then
|
||||||
|
' print "OS Not Press!!"
|
||||||
|
' return false
|
||||||
|
end if
|
||||||
|
|
||||||
|
if key = "down"
|
||||||
|
' print "OS Down Pressed.else.else.else.else.else.else.else.else. "
|
||||||
|
m.top.findNode("buttons").setFocus(false)
|
||||||
|
m.top.findNode("sortMenu").setFocus(true)
|
||||||
|
return true
|
||||||
|
else if key = "OK"
|
||||||
|
print "OS Key OK"
|
||||||
|
|
||||||
|
' if m.optionList.itemSelected <> m.selectedItem then
|
||||||
|
' print "OS - Resetting to ASC"
|
||||||
|
' m.optionList.focusedCheckedIconUri = "pkg:/images/icons/up_black.png"
|
||||||
|
' m.optionList.checkedIconUri="pkg:/images/icons/up_white.png"
|
||||||
|
' m.selectedItem = m.optionList.itemSelected
|
||||||
|
' m.ascending = true
|
||||||
|
' else
|
||||||
|
' if m.ascending = true then
|
||||||
|
' print "Setting ascending to false"
|
||||||
|
' m.ascending = false
|
||||||
|
' m.optionList.focusedCheckedIconUri = "pkg:/images/icons/down_black.png"
|
||||||
|
' m.optionList.checkedIconUri="pkg:/images/icons/down_white.png"
|
||||||
|
' else
|
||||||
|
' print "Setting ascending to true"
|
||||||
|
' m.ascending = true
|
||||||
|
' m.optionList.focusedCheckedIconUri = "pkg:/images/icons/up_black.png"
|
||||||
|
' m.optionList.checkedIconUri="pkg:/images/icons/up_white.png"
|
||||||
|
' end if
|
||||||
|
' end if
|
||||||
|
return true
|
||||||
|
else if key = "back"
|
||||||
|
if m.sortMenu.isInFocusChain() then
|
||||||
|
m.buttons.setFocus(true)
|
||||||
|
return true
|
||||||
|
end if
|
||||||
|
else
|
||||||
|
' print "Key Unhandled"
|
||||||
|
return false
|
||||||
|
end if
|
||||||
|
|
||||||
|
print "Moo?????"
|
||||||
|
end function
|
69
components/options/OptionsScreen.xml
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<component name="OptionsScreen" extends="Group">
|
||||||
|
<children>
|
||||||
|
<Rectangle width="1920" height="1080" color="#000000" opacity="0.75" />
|
||||||
|
<!-- <MaskGroup maskUri="pkg:/images/dialog.9.png" maskSize="[1000,700]" maskBitmapWidth="26" maskBitmapHeight="26" translation="[460,190]"> -->
|
||||||
|
<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" />
|
||||||
|
|
||||||
|
<!-- <LabelList id = "moviemenu" translation = "[100,180]" itemspacing="[0,10]" vertFocusAnimationStyle="floatingFocus" focusedCheckedIconUri="pkg:/images/icons/up_black.png" checkedIconUri="pkg:/images/icons/up_white.png" focusFootprintBitmapUri="pkg:/images/dialog.9.png" checkedItem="1"> -->
|
||||||
|
|
||||||
|
<Group>
|
||||||
|
<LabelList id = "viewMenu" itemspacing="[0,10]" vertFocusAnimationStyle="floatingFocus" visible="false">
|
||||||
|
<ContentNode id = "viewMenuContent" role = "content">
|
||||||
|
<ContentNode title = "Movies" />
|
||||||
|
<ContentNode title = "Collections" />
|
||||||
|
</ContentNode>
|
||||||
|
</LabelList>
|
||||||
|
|
||||||
|
<RadiobuttonList id = "sortMenu" itemspacing="[0,10]" vertFocusAnimationStyle="floatingFocus" visible="true" numRows="8">
|
||||||
|
<ContentNode id = "sortMenuContent" role = "content">
|
||||||
|
<ContentNode title = "Name" />
|
||||||
|
<ContentNode title = "IMDb Rating" />
|
||||||
|
<ContentNode title = "Critic Rating" />
|
||||||
|
<ContentNode title = "Date Added" />
|
||||||
|
<ContentNode title = "Date Played" />
|
||||||
|
<ContentNode title = "Parental Rating" />
|
||||||
|
<ContentNode title = "Play Count" />
|
||||||
|
<ContentNode title = "Release Date" />
|
||||||
|
<ContentNode title = "Runtime" />
|
||||||
|
</ContentNode>
|
||||||
|
</RadiobuttonList>
|
||||||
|
|
||||||
|
<LabelList id = "filterMenu" itemspacing="[0,10]" vertFocusAnimationStyle="floatingFocus" visible="false">
|
||||||
|
<ContentNode id = "filterMenuContent" role = "content">
|
||||||
|
<ContentNode title = "Filter..." />
|
||||||
|
<ContentNode title = "Suggestions" />
|
||||||
|
<ContentNode title = "Latest" />
|
||||||
|
<ContentNode title = "Upcoming" />
|
||||||
|
<ContentNode title = "Genres" />
|
||||||
|
<ContentNode title = "Networks" />
|
||||||
|
<ContentNode title = "Episodes" />
|
||||||
|
</ContentNode>
|
||||||
|
</LabelList>
|
||||||
|
</Group>
|
||||||
|
|
||||||
|
<!-- <RadiobuttonList id = "moviemenu" itemspacing="[0,10]" itemSize = "[300,55]" vertFocusAnimationStyle="floatingFocus">
|
||||||
|
<ContentNode id = "moviemenucontent" role = "content">
|
||||||
|
<ContentNode title = "Ascending" />
|
||||||
|
<ContentNode title = "Decending" />
|
||||||
|
</ContentNode>
|
||||||
|
</RadiobuttonList> -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</LayoutGroup>
|
||||||
|
</Group>
|
||||||
|
<!-- </MaskGroup> -->
|
||||||
|
<!-- <Poster width="1000" height="700" translation="[460,190]" uri="pkg:/images" -->
|
||||||
|
</children>
|
||||||
|
<interface>
|
||||||
|
<field id="buttons" type="nodearray" />
|
||||||
|
<field id="options" type="nodearray" />
|
||||||
|
</interface>
|
||||||
|
<script type="text/brightscript" uri="OptionsScreen.brs" />
|
||||||
|
</component>
|
BIN
images/backgroundmask.png
Normal file
After Width: | Height: | Size: 810 KiB |
BIN
images/button_bg_focus.9.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
images/button_bg_focus_t.9.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
images/button_bg_off.9.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
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 |