diff --git a/.gitignore b/.gitignore
index fa001aa..f86df33 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,4 @@
out/
out/roku-deploy.zip
+.history/
+.vscode/
\ No newline at end of file
diff --git a/.vscode/launch.json b/.vscode/launch.json
deleted file mode 100644
index dca2ab3..0000000
--- a/.vscode/launch.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- // Use IntelliSense to learn about possible attributes.
- // Hover to view descriptions of existing attributes.
- // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
- "version": "0.2.0",
- "configurations": [
- {
- "type": "brightscript",
- "request": "launch",
- "name": "BrightScript Debug: Launch",
- "stopOnEntry": false,
- "host": "${promptForHost}",
- "password": "mega",
- "rootDir": "${workspaceFolder}",
- "enableDebuggerAutoRecovery": false,
- "stopDebuggerOnAppExit": false
- }
- ]
-}
\ No newline at end of file
diff --git a/components/keyboardScene.brs b/components/keyboardScene.brs
new file mode 100644
index 0000000..1905668
--- /dev/null
+++ b/components/keyboardScene.brs
@@ -0,0 +1,155 @@
+sub init()
+ m.keyboard = m.top.findNode("myKeyboard")
+ m.itemsList = m.top.findNode("searchList")
+ m.video = m.top.findNode("video")
+ m.itemsList.observeField("itemSelected", "handleItemSelected")
+ m.heading = m.top.findNode("heading")
+ m.keyboard.setFocus(true)
+ m.keyboard.observeField("text", "handleText")
+ m.http = createObject("roSGNode", "httpTask")
+ m.http.observeFieldScoped("response", "useResponse")
+ m.keyboard.textBox.observeField("text", "handleText")
+ m.keyboard.observeField("submit", "handleSubmit")
+end sub
+
+sub handleText()
+ m.text = m.keyboard.textBox.text
+end sub
+
+sub handleSubmit()
+ handleVideoPlaybackResponse()
+
+ ' m.http.request = { payload: {
+ ' userId: 1,
+ ' title: "WOW, IT WORKED ^_^",
+ ' }, url: "https://youtube.googleapis.com/youtube/v3/search?part=snippet&q=" + m.text + "&maxResults=25&type=video&key=AIzaSyCxEpZ8-3gkiFpoc2SAkPBfcPFqQd6m_dw", requestType: "GET" }
+ ' m.http.control = "RUN"
+end sub
+
+sub useResponse()
+ m.itemsThatContainString = createObject("roSGNode", "ContentNode")
+ items = []
+ m.itemsList.numColumns = 3
+ for each item in parseJson(m.http.response.body).items
+ Content = m.itemsThatContainString.createChild("ContentNode")
+ Content.HDPosterUrl = item.snippet.thumbnails.medium.url
+ Content.id = item.id.videoId
+ items.push(item)
+ end for
+ if items.count() = 2
+ m.itemsList.numColumns = 2
+ else if items.count() = 1
+ m.itemsList.numColumns = 1
+ end if
+ ' handle empty text box
+ if m.keyboard.textBox.text = ""
+ m.itemsList.content = invalid
+ m.heading.visible = false
+ else
+ m.heading.visible = true
+ m.itemsList.content = m.itemsThatContainString
+ handleHeading()
+ end if
+end sub
+
+sub handleHeading()
+ m.heading.text = "These are the top videos that match " + Chr(34) + m.keyboard.textBox.text + Chr(34)
+end sub
+
+sub handleItemSelected()
+ ' http://scienceandfilm.org/uploads/videos/files/afronauts_trailer.mp4
+ ' playVideo(m.itemsThatContainString.getChild(m.itemsList.itemSelected).id)
+end sub
+
+function onKeyEvent(key as String, press as Boolean) as Boolean
+ if press and m.keyboard.visible = true
+ if key = "right" and not m.itemsList.hasFocus()
+ m.itemsList.setFocus(true)
+ return true
+ else if key = "left" and not m.keyboard.hasFocus()
+ m.keyboard.setFocus(true)
+ end if
+ end if
+ return false
+end function
+
+sub playVideo(id as String)
+ ' m.videoPlaybackTask = createObject("roSGNode", "httpTask")
+ ' m.videoPlaybackTask.request = { payload: {
+ ' userId: 1,
+ ' title: "WOW, IT WORKED ^_^",
+ ' }, url: "https://www.youtube.com/watch?v=" + id, requestType: "GET" }
+ ' m.videoPlaybackTask.control = "RUN"
+ ' m.videoPlaybackTask.observeFieldScoped("response", "handleVideoPlaybackResponse")
+end sub
+
+sub handleVideoPlaybackResponse()
+ ' initialPlayerResponseRegEx = createObject("roRegex", "ytInitialPlayerResponse\s*=\s*({.+?})\s*;", "m")
+ ' matches = initialPlayerResponseRegEx.match(m.videoPlaybackTask.response.body)
+ videoContent = createObject("RoSGNode", "ContentNode")
+ ' YouTube API Limit Exceeded
+ ' videoContent.url = parseJson(matches[1]).streamingData.formats[0].url
+ videoContent.url = "https://bitmovin-a.akamaihd.net/content/art-of-motion_drm/m3u8s/11331.m3u8"
+ videoContent.streamFormat = "hls"
+ videoContent.drmParams = {
+ name: "Vertimatrix",
+ authDomain: "https://playready.directtaps.net/pr/svc/rightsmanager.asmx?PlayRight=1&ContentKey=EAtsIJQPd5pFiRUrV9Layw==",
+ serializationUrl: "https://playready.directtaps.net/pr/svc/rightsmanager.asmx?PlayRight=1&ContentKey=EAtsIJQPd5pFiRUrV9Layw=="
+ }
+ m.video.content = videoContent
+ m.video.visible = true
+ m.video.enableUI = false
+ m.video.enableTrickPlay = false
+ m.video.createChild("TrickPlay")
+ m.keyboard.visible = false
+ m.video.seekMode = "accurate"
+ m.video.setFocus(true)
+ m.video.control = "play"
+ m.video.getChild(2).setFocus(true)
+ m.video.getChild(2).observeField("play", "handlePlay")
+ m.video.getChild(2).observeField("forward", "handleForward")
+ m.video.getChild(2).observeField("back", "handleBack")
+ m.video.getChild(2).observeField("cc", "handleCC")
+ m.video.observeField("state", "videoStarted")
+ m.video.observeField("position", "updatePosition")
+ m.video.observeField("bufferingStatus", "updateBuffering")
+end sub
+
+sub updateBuffering()
+ if m.video.bufferingStatus <> invalid
+ m.video.getChild(2).loadingData = { percentage: m.video.bufferingStatus.percentage, done: m.video.bufferingStatus.prebufferDone }
+ end if
+end sub
+
+sub updatePosition()
+ m.video.getChild(2).position = m.video.position
+end sub
+
+sub videoStarted()
+ m.video.getChild(2).duration = m.video.duration
+end sub
+
+sub handlePlay()
+ if m.video.control = "play" or m.video.control = "resume"
+ m.video.control = "pause"
+ else
+ m.video.control = "resume"
+ end if
+ if m.video.state = "finished"
+ m.video.control = "play"
+ end if
+end sub
+
+sub handleForward()
+ m.video.seek = m.video.position + 15
+ m.video.control = "resume"
+end sub
+
+sub handleBack()
+ m.video.seek = m.video.position - 15
+ m.video.control = "resume"
+end sub
+
+sub handleCC()
+
+end sub
\ No newline at end of file
diff --git a/components/keyboardScene.xml b/components/keyboardScene.xml
new file mode 100644
index 0000000..c4719b0
--- /dev/null
+++ b/components/keyboardScene.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/keyboardSceneItem.brs b/components/keyboardSceneItem.brs
new file mode 100644
index 0000000..694e262
--- /dev/null
+++ b/components/keyboardSceneItem.brs
@@ -0,0 +1,7 @@
+sub init()
+ m.itemPoster = m.top.findNode("imagePoster")
+end sub
+
+sub showContent()
+ m.itemPoster.uri = m.top.itemContent.HDPOSTERURL
+end sub
\ No newline at end of file
diff --git a/components/keyboardSceneItem.xml b/components/keyboardSceneItem.xml
new file mode 100644
index 0000000..3c3cfee
--- /dev/null
+++ b/components/keyboardSceneItem.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/keyboardcomponent/icons/backspaceblack.png b/components/keyboardcomponent/icons/backspaceblack.png
new file mode 100644
index 0000000..72e5f1d
Binary files /dev/null and b/components/keyboardcomponent/icons/backspaceblack.png differ
diff --git a/components/keyboardcomponent/icons/backspacewhite.png b/components/keyboardcomponent/icons/backspacewhite.png
new file mode 100644
index 0000000..09aa5ba
Binary files /dev/null and b/components/keyboardcomponent/icons/backspacewhite.png differ
diff --git a/components/keyboardcomponent/keyboardComponent.brs b/components/keyboardcomponent/keyboardComponent.brs
new file mode 100644
index 0000000..2279e78
--- /dev/null
+++ b/components/keyboardcomponent/keyboardComponent.brs
@@ -0,0 +1,178 @@
+sub init()
+ m.keyboardController = m.top.findNode("keyboardController")
+ m.keys = ["A", "J", "S", "1", "B", "K", "T", "2", "C", "L", "U", "3", "D", "M", "V", "4", "E", "N", "W", "5", "F", "O", "X", "6", "G", "P", "Y", "7", "H", "Q", "Z", "8", "I", "R", "0", "9"]
+ m.symbolsKeys = ["!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "-", "_", "+", "-", "/", "\", "|", "[", "]", "{", "}", ":", ";", "", "'", ",", ".", "<", ">", "?", "=", "`", "~", "X", "O", "..."]
+ m.symbolsFlag = false
+ initButtons()
+ m.focusIdx = 0
+ m.Col1.getChild(0).setFocus(true)
+ initObservers()
+end sub
+
+sub initButtons()
+ m.Col1 = m.keyboardController.findNode("Col1")
+ m.Col2 = m.keyboardController.findNode("Col2")
+ m.Col3 = m.keyboardController.findNode("Col3")
+ m.Col4 = m.keyboardController.findNode("Col4")
+ m.Col5 = m.keyboardController.findNode("Col5")
+ m.Col6 = m.keyboardController.findNode("Col6")
+ m.Col7 = m.keyboardController.findNode("Col7")
+ m.Col8 = m.keyboardController.findNode("Col8")
+ m.Col9 = m.keyboardController.findNode("Col9")
+ m.SYMBOLS = m.keyboardController.findNode("SYMBOLS")
+ m.SPACEBAR = m.keyboardController.findNode("SPACEBAR")
+ m.DELETE = m.keyboardController.findNode("DELETE")
+ m.SEARCH = m.keyboardController.findNode("SEARCH")
+ m.textBox = m.top.findNode("textBox")
+ it = -1
+ for each child in m.keyboardController.getChildren(9, 0)
+ it++
+ it2 = it + 3
+ for i = it to it2
+ childButton = createObject("roSGNode", "Button")
+ childButton.getChild(1).uri = ""
+ childButton.getChild(2).text = m.keys[i]
+ childButton.getChild(2).width = 72
+ childButton.getChild(2).height = 72
+ childButton.getChild(2).font = "font:SmallestBoldSystemFont"
+ childButton.getChild(2).horizAlign = "center"
+ childButton.iconUri = ""
+ childButton.focusedIconUri = ""
+ childButton.focusedTextFont = "font:SmallestBoldSystemFont"
+ childButton.textFont = "font:SmallestBoldSystemFont"
+ child.appendChild(childButton)
+ end for
+ it = it2
+ end for
+end sub
+
+sub handleSymbols()
+ it = -1
+ if m.symbolsFlag
+ for each child in m.keyboardController.getChildren(9, 0)
+ it++
+ it2 = it + 3
+ btnIdx = 0
+ for i = it to it2
+ child.getChild(btnIdx).getChild(2).text = m.keys[i]
+ btnIdx++
+ end for
+ it = it2
+ end for
+ m.symbolsFlag = false
+ else
+ for each child in m.keyboardController.getChildren(9, 0)
+ it++
+ it2 = it + 3
+ btnIdx = 0
+ for i = it to it2
+ child.getChild(btnIdx).getChild(2).text = m.symbolsKeys[i]
+ btnIdx++
+ end for
+ it = it2
+ end for
+ m.symbolsFlag = true
+ end if
+end sub
+
+sub initObservers()
+ m.Col1.observeField("buttonSelected", "handleItemSelect")
+ m.Col2.observeField("buttonSelected", "handleItemSelect")
+ m.Col3.observeField("buttonSelected", "handleItemSelect")
+ m.Col4.observeField("buttonSelected", "handleItemSelect")
+ m.Col5.observeField("buttonSelected", "handleItemSelect")
+ m.Col6.observeField("buttonSelected", "handleItemSelect")
+ m.Col7.observeField("buttonSelected", "handleItemSelect")
+ m.Col8.observeField("buttonSelected", "handleItemSelect")
+ m.Col9.observeField("buttonSelected", "handleItemSelect")
+ m.DELETE.observeField("buttonSelected", "handleExternalButtonSelect")
+ m.SPACEBAR.observeField("buttonSelected", "handleExternalButtonSelect")
+ m.SYMBOLS.observeField("buttonSelected", "handleExternalButtonSelect")
+ m.SEARCH.observeField("buttonSelected", "handleExternalButtonSelect")
+ m.top.textBox = m.textBox
+end sub
+
+sub handleExternalButtonSelect(event)
+ if event.getRoSGNode().text = "SPACE"
+ m.textBox.text += " "
+ else if event.getRoSGNode().id = "DELETE"
+ m.textBox.text = m.textBox.text.Left(m.textBox.text.Len() - 1)
+ else if event.getRoSGNode().id = "DELETE"
+ m.top.submit = not m.top.submit
+ else if event.getRoSGNode().id = "SEARCH"
+ m.top.submit = not m.top.submit
+ else
+ handleSymbols()
+ end if
+end sub
+
+sub handleItemSelect(event)
+ text = event.getRoSGNode().focusedChild.getChild(2).text
+ m.textBox.text += text
+end sub
+
+function onKeyEvent(key as String, press as Boolean) as Boolean
+ m.rowIdx = m.keyboardController.getChild(m.focusIdx).buttonFocused
+ if press
+ if key = "right" and m.focusIdx < 8 and not m.DELETE.hasFocus() and not m.SYMBOLS.hasFocus() and not m.SPACEBAR.hasFocus()
+ m.focusIdx++
+ m.keyboardController.getChild(m.focusIdx).focusButton = m.rowIdx
+ return true
+ else if key = "left" and m.focusIdx > 0 and not m.DELETE.hasFocus() and not m.SYMBOLS.hasFocus() and not m.SPACEBAR.hasFocus()
+ m.focusIdx--
+ m.keyboardController.getChild(m.focusIdx).focusButton = m.rowIdx
+ return true
+ else if key = "down" and m.focusIdx >= 2 and m.focusIdx <= 5
+ m.SPACEBAR.setFocus(true)
+ return true
+ else if key = "down" and m.focusIdx < 2
+ m.SYMBOLS.setFocus(true)
+ return true
+ else if key = "down" and m.focusIdx = 8
+ m.SEARCH.setFocus(true)
+ else if key = "down" and m.focusIdx > 5
+ m.DELETE.setFocus(true)
+ return true
+ else if key = "up" and m.focusIdx > 5
+ ' Go to the item right above DELETE
+ m.keyboardController.getChild(8).focusButton = 3
+ m.focusIdx = 8
+ return true
+ else if key = "up" and m.focusIdx >= 2 and m.focusIdx <= 5
+ ' Go to the item right above SPACE
+ m.keyboardController.getChild(4).focusButton = 3
+ m.focusIdx = 4
+ return true
+ else if key = "up" and m.focusIdx < 2
+ ' Go to the item right above SYMBOLS
+ m.keyboardController.getChild(0).focusButton = 3
+ m.focusIdx = 0
+ return true
+ else if key = "right" and m.SPACEBAR.hasFocus()
+ m.focusIdx = 8
+ m.DELETE.setFocus(true)
+ return true
+ else if key = "right" and m.SYMBOLS.hasFocus()
+ m.focusIdx = 4
+ m.SPACEBAR.setFocus(true)
+ return true
+ else if key = "left" and m.DELETE.hasFocus()
+ m.focusIdx = 4
+ m.SPACEBAR.setFocus(true)
+ return true
+ else if key = "left" and m.SPACEBAR.hasFocus()
+ m.focusIdx = 0
+ m.SYMBOLS.setFocus(true)
+ return true
+ else if key = "left" and m.SEARCH.hasFocus()
+ m.focusIdx = 0
+ m.DELETE.setFocus(true)
+ return true
+ else if key = "right" and m.DELETE.hasFocus()
+ m.focusIdx = 0
+ m.SEARCH.setFocus(true)
+ return true
+ end if
+ end if
+ return false
+end function
\ No newline at end of file
diff --git a/components/keyboardcomponent/keyboardComponent.xml b/components/keyboardcomponent/keyboardComponent.xml
new file mode 100644
index 0000000..6808238
--- /dev/null
+++ b/components/keyboardcomponent/keyboardComponent.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/rowListContent.xml b/components/rowListContent.xml
index 28e7d8e..f70ce16 100644
--- a/components/rowListContent.xml
+++ b/components/rowListContent.xml
@@ -1,5 +1,5 @@
-
+
\ No newline at end of file
diff --git a/components/rowListItem.xml b/components/rowListItem.xml
index 65e51b9..897af09 100644
--- a/components/rowListItem.xml
+++ b/components/rowListItem.xml
@@ -5,7 +5,7 @@
-
+
diff --git a/components/rowListScene.brs b/components/rowListScene.brs
index 22d7821..fd43c17 100644
--- a/components/rowListScene.brs
+++ b/components/rowListScene.brs
@@ -1,8 +1,5 @@
sub init()
- m.global.addField("http", "node", FALSE)
m.global.addField("ratio", "float", FALSE)
- m.global.http = createObject("roSGNode", "httpTask")
- m.global.http.control = "RUN"
m.global.ratio = 1
m.rowList = m.top.findNode("mainRowList")
m.rowList.content = createObject("roSGNode", "RowListContent")
diff --git a/components/tasks/httpTask.brs b/components/tasks/httpTask.brs
index aee48f2..76b664f 100644
--- a/components/tasks/httpTask.brs
+++ b/components/tasks/httpTask.brs
@@ -1,11 +1,11 @@
sub init()
m.top.functionname = "handleCalls"
m.port = createObject("roMessagePort")
- m.top.observeField("request", m.port)
+ m.top.observeFieldScoped("request", m.port)
m.urlRequest = {}
end sub
-function handleCalls() as Object
+function handleCalls() as object
while(true)
msg = wait(0, m.port)
msgType = type(msg)
@@ -14,24 +14,23 @@ function handleCalls() as Object
response = fire(msg.getData())
end if
else if msgType = "roUrlEvent"
- if msg.getInt() = 1
- if msg.getResponseCode() > 0
- response = handleResponse(msg.getString(),msg,true)
- else
- response = handleResponse(msg.getFailureReason(),msg,false)
- end if
+ if msg.getInt() = 1
+ if msg.getResponseCode() > 0
+ response = handleResponse(msg.getString(), msg, true)
+ else
+ response = handleResponse(msg.getFailureReason(), msg, false)
end if
- m.top.response = response
- return response
+ end if
+ m.top.response = response
end if
end while
end function
-function fire(request as Object) as Object
+function fire(request as object) as object
httpRequest = initiateHttpClient(request.url)
requestId = httpRequest.getIdentity().ToStr()
m.urlRequest[requestId] = {
- request:httpRequest
+ request: httpRequest
}
if checkRequestType(request.requestType)
httpRequest.AsyncPostFromString(formatJson(request.payload))
@@ -40,21 +39,21 @@ function fire(request as Object) as Object
end if
end function
-function handleResponse(responseString as String, message as Object, isOk as Boolean) as Object
+function handleResponse(responseString as string, message as object, isOk as boolean) as object
if isOk
- body = parseJson(responseString)
+ body = responseString
else
body = "An Error has Occurred!!"
end if
- requestId = message.GetSourceIdentity().ToStr()
- m.urlRequest[requestId] = invalid
+ requestId = message.GetSourceIdentity().ToStr()
+ m.urlRequest[requestId] = invalid
return {
requestId: requestId
- body:body
+ body: body
}
end function
-function initiateHttpClient(url as String) as Object
+function initiateHttpClient(url as string) as object
httpRequest = createObject("roUrlTransfer")
httpRequest.SetCertificatesFile("common:/certs/ca-bundle.crt")
httpRequest.InitClientCertificates()
@@ -66,7 +65,7 @@ function initiateHttpClient(url as String) as Object
return httpRequest
end function
-function checkRequestType(requestType as String) as Boolean
+function checkRequestType(requestType as string) as boolean
if requestType = "POST" or requestType = "DELETE" or requestType = "PUT" or requestType = "PATCH"
return true
else
diff --git a/components/tasks/httpTask.xml b/components/tasks/httpTask.xml
index d3c075c..14f5754 100644
--- a/components/tasks/httpTask.xml
+++ b/components/tasks/httpTask.xml
@@ -3,6 +3,6 @@
-
+
\ No newline at end of file
diff --git a/components/trickplay/TrickPlay.brs b/components/trickplay/TrickPlay.brs
new file mode 100644
index 0000000..f83a19e
--- /dev/null
+++ b/components/trickplay/TrickPlay.brs
@@ -0,0 +1,146 @@
+sub init()
+ initItems()
+ initObservers()
+end sub
+
+sub initItems()
+ m.main = m.top.findNode("main")
+ m.timer = m.top.findNode("animTimer")
+ m.mainParent = m.main.findNode("mainParent")
+ m.UIShow = m.main.findNode("UIShow")
+ m.UIHide = m.main.findNode("UIHide")
+ m.elapsedTime = m.mainParent.findNode("elapsedTime")
+ m.ScrubberFilled = m.mainParent.findNode("ScrubberFilled")
+ m.LoadingGroup = m.top.findNode("LoadingGroup")
+ m.loadingFilled = m.LoadingGroup.findNode("loadingFilled")
+ m.loadingPercent = m.LoadingGroup.findNode("loadingPercent")
+ m.totalTime = m.mainParent.findNode("totalTime")
+ m.bottomButtons = m.top.findNode("bottomButtons")
+ m.back15 = m.bottomButtons.findNode("back15")
+ m.playPause = m.bottomButtons.findNode("playPause")
+ m.forward15 = m.bottomButtons.findNode("forward15")
+ m.CC = m.bottomButtons.findNode("CC")
+end sub
+
+sub initObservers()
+ m.playPause.observeField("buttonSelected", "fireEvent")
+ m.back15.observeField("buttonSelected", "fireEvent")
+ m.forward15.observeField("buttonSelected", "fireEvent")
+ m.CC.observeField("buttonSelected", "fireEvent")
+ m.top.observeField("duration", "updateDuration")
+ m.top.observeField("position", "updatePosition")
+ m.top.observeField("loadingData", "updateLoading")
+ hideLoading()
+ focusOnFirstBtn()
+end sub
+
+sub hideLoading()
+ m.LoadingGroup.opacity = 0
+end sub
+
+sub updateDuration()
+ m.totalTime.text = handleTimeDisplay(m.top.duration)
+ m.fillingRatio = 700 / m.top.duration
+end sub
+
+sub focusOnFirstBtn()
+ m.back15.setFocus(true)
+end sub
+
+sub updateLoading()
+ m.loadingPercent.text = (m.top.loadingData.percentage).toStr() + "%"
+ m.loadingFilled.width = INT((m.top.loadingData.percentage) * 1.5)
+ m.LoadingGroup.opacity = 1
+ if (m.top.loadingData.percentage) = 100
+ m.LoadingGroup.opacity = 0
+ end if
+end sub
+
+sub updatePosition()
+ m.ScrubberFilled.width = m.top.position * m.fillingRatio
+ m.elapsedTime.text = handleTimeDisplay(m.top.position)
+end sub
+
+sub handleTimeDisplay(time as Integer) as String
+ minutes = INT(time / 60)
+ seconds = INT(time MOD 60)
+ if minutes < 10
+ minutesStr = "0"
+ else
+ secondsStr = ""
+ end if
+ if seconds < 10
+ secondsStr = "0"
+ else
+ secondsStr = ""
+ end if
+ return minutesStr + minutes.toStr() + ":" + secondsStr + seconds.toStr()
+end sub
+
+sub fireEvent(event)
+ if event.getNode() = "playPause"
+ m.top.play = not m.top.play
+ else if event.getNode() = "back15"
+ m.top.back = not m.top.back
+ else if event.getNode() = "forward15"
+ m.top.forward = not m.top.forward
+ else if event.getNode() = "CC"
+ m.top.CC = not m.top.CC
+ end if
+end sub
+
+sub showNav()
+ if m.main.opacity = 0
+ m.UIShow.control = "start"
+ else
+ m.timer.control = "start"
+ m.timer.observeField("fire", "hideUI")
+ end if
+end sub
+
+sub hideUI()
+ m.UIHide.control = "start"
+end sub
+
+function onKeyEvent(key as String, press as Boolean) as Boolean
+ if press
+ showNav()
+ if key = "right" and m.back15.hasFocus()
+ m.playPause.setFocus(true)
+ m.back15.setFocus(false)
+ return true
+ else if key = "right" and m.playPause.hasFocus()
+ m.forward15.setFocus(true)
+ return true
+ else if key = "right" and m.forward15.hasFocus()
+ m.CC.setFocus(true)
+ return true
+ else if key = "right" and m.CC.hasFocus()
+ return false
+ else if key = "left" and m.CC.hasFocus()
+ m.forward15.setFocus(true)
+ return true
+ else if key = "left" and m.forward15.hasFocus()
+ m.playPause.setFocus(true)
+ return true
+ else if key = "left" and m.playPause.hasFocus()
+ m.back15.setFocus(true)
+ return true
+ else if key = "left" and m.back15.hasFocus()
+ return false
+ else if key = "left" and m.ScrubberFilled.hasFocus()
+ m.top.back = not m.top.back
+ return true
+ else if key = "right" and m.ScrubberFilled.hasFocus()
+ m.top.forward = not m.top.forward
+ return true
+ else if key = "up"
+ m.ScrubberFilled.setFocus(true)
+ return true
+ else if key = "down" and m.ScrubberFilled.hasFocus()
+ m.back15.setFocus(true)
+ return true
+ end if
+ end if
+ return false
+end function
\ No newline at end of file
diff --git a/components/trickplay/TrickPlay.xml b/components/trickplay/TrickPlay.xml
new file mode 100644
index 0000000..c0096e9
--- /dev/null
+++ b/components/trickplay/TrickPlay.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/images/blackback.png b/images/blackback.png
new file mode 100644
index 0000000..d766715
Binary files /dev/null and b/images/blackback.png differ
diff --git a/images/blackleft.png b/images/blackleft.png
new file mode 100644
index 0000000..0426910
Binary files /dev/null and b/images/blackleft.png differ
diff --git a/images/blackpause.png b/images/blackpause.png
new file mode 100644
index 0000000..c64506b
Binary files /dev/null and b/images/blackpause.png differ
diff --git a/images/blackquote.png b/images/blackquote.png
new file mode 100644
index 0000000..88a9f82
Binary files /dev/null and b/images/blackquote.png differ
diff --git a/images/blackright.png b/images/blackright.png
new file mode 100644
index 0000000..23b276f
Binary files /dev/null and b/images/blackright.png differ
diff --git a/images/buttonbg.png b/images/buttonbg.png
new file mode 100644
index 0000000..0d03300
Binary files /dev/null and b/images/buttonbg.png differ
diff --git a/images/gradient.png b/images/gradient.png
new file mode 100644
index 0000000..529b757
Binary files /dev/null and b/images/gradient.png differ
diff --git a/images/white.jpg b/images/white.jpg
new file mode 100644
index 0000000..746d65d
Binary files /dev/null and b/images/white.jpg differ
diff --git a/images/white2.jpg b/images/white2.jpg
new file mode 100644
index 0000000..746d65d
Binary files /dev/null and b/images/white2.jpg differ
diff --git a/images/whiteback.png b/images/whiteback.png
new file mode 100644
index 0000000..a49e04a
Binary files /dev/null and b/images/whiteback.png differ
diff --git a/images/whiteleft.png b/images/whiteleft.png
new file mode 100644
index 0000000..faf75a7
Binary files /dev/null and b/images/whiteleft.png differ
diff --git a/images/whitepause.png b/images/whitepause.png
new file mode 100644
index 0000000..2a2be3a
Binary files /dev/null and b/images/whitepause.png differ
diff --git a/images/whitequote.png b/images/whitequote.png
new file mode 100644
index 0000000..b20be5a
Binary files /dev/null and b/images/whitequote.png differ
diff --git a/images/whiteright.png b/images/whiteright.png
new file mode 100644
index 0000000..3d2fb86
Binary files /dev/null and b/images/whiteright.png differ
diff --git a/manifest b/manifest
index 3a2d81f..36a8099 100644
--- a/manifest
+++ b/manifest
@@ -21,3 +21,5 @@ splash_color=#662D91
splash_min_time=1000
ui_resolutions = "fhd,hd"
+requires_verimatrix_drm=1
+requires_verimatrix_version=1.0
diff --git a/source/main.brs b/source/main.brs
index edcb6a6..eb82e3f 100644
--- a/source/main.brs
+++ b/source/main.brs
@@ -5,7 +5,7 @@ sub showChannelSGScreen()
screen = CreateObject("roSGScreen")
m.port = CreateObject("roMessagePort")
screen.setMessagePort(m.port)
- scene = screen.CreateScene("rowListScene")
+ scene = screen.CreateScene("keyboardScene")
screen.show()
while(true)
msg = wait(0, m.port)