<component name = "MaskGroupexample" extends = "Group" >
<script>
<![CDATA[
sub init()
maskgroupanimation = m.top.findNode("MaskGroupAnimation")
maskgroupanimation.control = "start"
end sub
]]>
</script>
<children>
<MaskGroup id="exampleMaskGroup" maskuri="pkg:/images/GradientLinear.png" masksize="[512, 288]" maskOffset="[0, 0]" >
<Poster uri = "pkg:/images/dialogpg.jpg" width = "512" height = "288" />
</MaskGroup>
<Animation id = "MaskGroupAnimation" duration = "3" easeFunction = "linear" repeat = "true" >
<Vector2DFieldInterpolator id = "interpolator" fieldToInterp = "exampleMaskGroup.maskOffset" key = "[ 0.0, 0.50, 1.0 ]"
keyValue = "[ [512,0], [-512,0], [512,0] ]" />
</Animation>
</children>
</component>
... and this is perfectly valid BrightScript - just nested array and dictionary literals! It may look unusual if you don't know B/S implies comma when new line separates items but yeah... can save on commas there. And since this is all evaluated as B/S, attributes don't have to be string constants like "[ [512,0], [-512,0], [512,0] ]" - they are genuine expressions that can be calculated during object construction.
["component", {name: "MaskGroupexample", extends: "Group"
init: function()
maskgroupanimation = m.top.findNode("MaskGroupAnimation")
maskgroupanimation.control = "start"
end function
}
["children"
["MaskGroup", {id: "exampleMaskGroup", maskuri: "pkg:/images/GradientLinear.png",
masksize: [512, 288], maskOffset: [0, 0]}
"Poster", {uri: "pkg:/images/dialogpg.jpg", width: 512, height: 288}
]
["Animation", {id: "MaskGroupAnimation", duration: 3, easeFunction: "linear", repeat: true}
"Vector2DFieldInterpolator", {id: "interpolator", fieldToInterp: "exampleMaskGroup.maskOffset",
key: [0.0, 0.50, 1.0], keyValue: [[512,0], [-512,0], [512,0]] }
]
]
]
mg_ex = createObject("roSgNode", "Group")Much better but still tad tedious, since there is createObject() within createObject() or the use temp variables. But notice how "the need" to sub-class and write an initializer vanished naturally.
mg_ex.createChild("MaskGroup", {id: "exampleMaskGroup",
maskuri: "pkg:/images/GradientLinear.png", masksize: [512, 288], maskOffset: [0, 0]
children: [
createObject("roSgNode", "Poster", {uri: "pkg:/images/dialogpg.jpg", width: 512, height: 288})
]
})
mga = createObject("roSgNode", "Animation", {id: "MaskGroupAnimation",
duration: 3, easeFunction: "linear", repeat: true
children: [
createObject("roSgNode", "Vector2DFieldInterpolator", {id: "interpolator",
fieldToInterp: "exampleMaskGroup.maskOffset",
key: [0.0, 0.50, 1.0], keyValue: [[512,0], [-512,0], [512,0]]
})
]
})
mg_ex.appendChild(mga)
mga.control = "start"
MaskGroupExample = { type: "Group"So that's ust a roAA, what do we do with it? Well, in a perfect world i should be able to create the node by calling
init: function()
maskgroupanimation = m.top.findNode("MaskGroupAnimation")
maskgroupanimation.control = "start"
end function
children: [
{ type: "MaskGroup", id: "exampleMaskGroup",
maskuri: "pkg:/images/GradientLinear.png", masksize: [512, 288], maskOffset: [0, 0]
children: [
{ type: "Poster", uri: "pkg:/images/dialogpg.jpg", width: 512, height: 288}
]
}
{ type: "Animation", id: "MaskGroupAnimation",
duration: 3, easeFunction: "linear", repeat: true
children: [
{ type: "Vector2DFieldInterpolator", id: "interpolator",
fieldToInterp: "exampleMaskGroup.maskOffset",
key: [0.0, 0.50, 1.0], keyValue: [[512,0], [-512,0], [512,0]]
}
]
}
]
}
mg_ex = createObject("roSgNode", MaskGroupExample)i.e. passing roAA as argument (instead of string) would be walked by the sgNode constructor, creating all nested nodes. In the mean time though - till the cows come home - it's trivial for us to write own B/S utility function that does the same by walking the tree and createObject() the nested levels.
sub main():
screen = createObject("roSGScreen")
port = createObject("roMessagePort")
screen.setMessagePort(port)
scene = screen.createScene("_scene")
screen.show()
scene.setFocus(true)
scene.backgroundURI = "pkg:/images/rsgde_bg_hd.jpg"
scene._ingest = {__: [
{ _: "Rectangle", id: "textRectangle"
width: 640, height: 60
color: "0x10101000"
backgroundURI: "pkg:/images/rsgde_bg_hd.jpg"
__: { _: "Label", id: "movingLabel"
width: 280, height: 60
horizAlign: "center", vertAlign: "center"
text: "All The Best Videos!"
}
}
{ _: "Animation", id: "scrollbackAnimation"
duration: 10
repeat: true
easeFunction: "linear"
__: { _: "Vector2DFieldInterpolator"
fieldToInterp: "movingLabel.translation"
key: [0.0, 0.5, 1.0]
keyValue: [[0.0, 0.0], [360.0, 0.0], [0.0, 0.0]]
}
}
{ _: "Timer", id: "textTimer"
duration: 5
repeat: true
}
]}
scene._ingest = {_m: {
defaulttext: "All The Best Videos!"
alternatetext: "All The Time!!!"
}}
scene._ingest = {_exec: [
" _observeField(m.texttimer, ""fire"", function(msg): "
" lbl = m.movingLabel "
" if lbl.text = m.defaultText: "
" lbl.text = m.alternateText "
" else: "
" lbl.text = m.defaultText "
" end if "
" end function) "
]}
rect = scene.textRectangle.boundingRect()
centerx = (1280 - rect.width) / 2
centery = (720 - rect.height) / 2
scene.textRectangle.translation = [centerx, centery]
scene.textTimer.control = "start"
scene.scrollbackAnimation.control = "start"
while true:
msg = wait(0, port)
if type(msg) = "roSGScreenEvent" and msg.isScreenClosed() then exit while
end while
end sub
<MyComp messages="["hi", "hello", "world", "none"]">
<!-- after failing with -->
<MyComp messages="['hi', 'hello', 'world', 'none']"
<?xml version="1.0" encoding="utf-8" ?>
<!--********** Copyright 2016 Roku Corp. All Rights Reserved. **********-->
<component name = "EventObserverExample" extends = "Scene" >
<script type = "text/brightscript" >
<![CDATA[
sub init()
m.top.backgroundURI = "pkg:/images/rsgde_bg_hd.jpg"
example = m.top.findNode("textRectangle")
examplerect = example.boundingRect()
centerx = (1280 - examplerect.width) / 2
centery = (720 - examplerect.height) / 2
example.translation = [ centerx, centery ]
m.movinglabel = m.top.findNode("movingLabel")
m.defaulttext = "All The Best Videos!"
m.alternatetext = "All The Time!!!"
m.textchange = false
scrollback = m.top.findNode("scrollbackAnimation")
scrollback.control = "start"
texttimer = m.top.findNode("textTimer")
texttimer.observeField("fire", "changetext")
texttimer.control = "start"
m.top.setFocus(true)
end sub
sub changetext()
if (m.textchange = false) then
m.movinglabel.text = m.alternatetext
m.textchange = true
else
m.movinglabel.text = m.defaulttext
m.textchange = false
end if
end sub
]]>
</script>
<children>
<Rectangle
id = "textRectangle"
width = "640"
height = "60"
color = "0x10101000" >
<Label
id = "movingLabel"
width = "280"
height = "60"
text = "All The Best Videos!"
horizAlign = "center"
vertAlign = "center" />
</Rectangle>
<Animation
id = "scrollbackAnimation"
duration = "10"
repeat = "true"
easeFunction = "linear" >
<Vector2DFieldInterpolator
key = "[ 0.0, 0.5, 1.0 ]"
keyValue = "[ [0.0, 0.0], [360.0, 0.0], [0.0, 0.0] ]"
fieldToInterp = "movingLabel.translation" />
</Animation>
<Timer
id = "textTimer"
repeat = "true"
duration = "5" />
</children>
</component>