Grid Screen Development And Documentation

I am trying to learn and develop a grid screen for an application/channel. Like most Roku Brightscript language documentation, that for roGridScreen is drastically minimal.

The point specifically I am at now is what property do I set for each record in order to show an image?

Also, where is the full documentation with all the attributes available for roGridScreen?

Thanks.

http://sdkdocs.roku.com/display/sdkdoc/roGridScreen

http://sdkdocs.roku.com/display/sdkdoc/ifGridScreen

Thanks for the links, but the roGridScreen link I’ve already been to. The example and/or documentation doesn’t list how to set the image attribute nor is there documentation on the other attributes either.

All content metadata is documented here: http://sdkdocs.roku.com/display/sdkdoc/ … +Meta-Data
For posters, you’d use HDPosterUrl and SDPosterUrl, the same as you do for most other screens.

Aaahhh, now there we go! Thanks!

Perhaps such an explanation and link could be added to the documentation for each screen.

Now for the next step. Once an item’s information is set and the app is running, when you click on the item/poster, how do you retrieve the associated information for that item? I haven’t found anything in the documentation for this.


Function Main()
    port = CreateObject("roMessagePort")
    grid = CreateObject("roGridScreen")
    grid.SetMessagePort(port) 
    rowTitles = CreateObject("roArray", 10, true)
    for j = 0 to 10
        rowTitles.Push("[Row Title " + j.toStr() + " ] ")
    end for
    grid.SetupLists(rowTitles.Count())
    grid.SetListNames(rowTitles) 
    for j = 0 to 10
    list = CreateObject("roArray", 10, true)
    for i = 0 to 10 
             o = CreateObject("roAssociativeArray")
             o.ContentType = "episode"
             o.Title = "[Title" + i.toStr() + "]"
             o.ShortDescriptionLine1 = "[ShortDescriptionLine1]"
             o.ShortDescriptionLine2 = "[ShortDescriptionLine2]"
             o.Description = ""
             o.Description = "[Description] "
             o.Rating = "NR"
             o.StarRating = "75"
             o.ReleaseDate = "[<mm/dd/yyyy]"
             o.Length = 5400
             o.Actors = []
             o.Actors.Push("[Actor1]")
             o.Actors.Push("[Actor2]")
             o.Actors.Push("[Actor3]")
             o.Director = "[Director]"
             list.Push(o)
         end for
         grid.SetContentList(j, list) 
     end for 
     grid.Show() 
     while true
         msg = wait(0, port)
         if type(msg) = "roGridScreenEvent" then
             if msg.isScreenClosed() then
                 return -1
             elseif msg.isListItemFocused()
                 print "Focused msg: ";msg.GetMessage();"row: ";msg.GetIndex();
                 print " col: ";msg.GetData()
             elseif msg.isListItemSelected()
                 print "Selected msg: ";msg.GetMessage();"row: ";msg.GetIndex();
                 print " col: ";msg.GetData()
             endif
         endif
     end while
End Function

Given the above sample code from the roGridScreen documentation, once an item is selected, how do you get each piece of information that has been set for that item? Also, can you just take the entire item of information as an object?

You can look at a grid as an array of arrays of associative arrays. Each AA looks something like this:

aa={ ContentType : "episode"
	 Title : "[Title" + i.toStr() + "]"
	 ShortDescriptionLine1 : "[ShortDescriptionLine1]"
	 ShortDescriptionLine2 : "[ShortDescriptionLine2]"
	 Description : ""
	 Description : "[Description] "
	 Rating : "NR"
	 StarRating : "75"
	 ReleaseDate : "[<mm/dd/yyyy]"
	 Length : 5400
	 Actors : []
	 Actors.Push("[Actor1]")
	 Actors.Push("[Actor2]")
	 Actors.Push("[Actor3]")
	 Director : "[Director]"
	 }
	 

Each row array looks something like this:

row=[aa,aa,aa,aa,aa,aa,aa,aa,aa]

and the top level, array of arrays of associative arrays looks like this:


grid=[row
	  row
	  row
	  row
	  row
	  row
	  row]

Note that you can delimit an array with either a comma or a carriage return, so I used that method for the last one so you can visualize it.

When the user clicks on an item in the grid, the isListItemSelected() property of the roGridScreenEvent is true and the index values of that event are then available through msg.getIndex() for the horizontal position and msg.getData() for the vertical position. You can then retrieve video information from the arrays using those values:

VideoItem=grid[msg.getdata()][msg.getindex()]

or

selectedRow=grid[msg.getdata()]
selectedvideo=selectedRow[msg.getindex()]

Because you know that isListItemSelected() is true, you know that the user has clicked on an item, and now that you’ve extracted the video information, you just need to call your Springboard function or video playback function with selectedVideo as the parameter.

Note that it is a good practice to create your grid as an array first, and then use it to set the rows of the grid - that way you can easily rebuild the grid after you’ve closed it (a necessity on legacy firmware before opening another screen) without having to hit your server again and reparse the data.

Hope that helps,

  • Joel

And this, my friend, is why you are awesome. Not only example code, but also explanations, reasonings, and tips.

I vote for your answer to be included in the official documentation for roGridScreen at http://sdkdocs.roku.com/display/sdkdoc/roGridScreen and/or for you to write the documentation for the Roku BrightScript.

Thanks again!

Alright, so I tried what you suggested with


title = grid[msg.GetData()][msg.GetIndex()].Title.gettext()
print "Title => "+title

But it’s throwing an error


Array operation attempted on variable not DIM'd. (runtime error &he7) in ...TZPco/pkg:/source/appMain.brs(91)
091:                  title = grid[msg.GetData()][msg.GetIndex()].Title.gettext()

Also tried “tostr()” in place of “gettext()”, but produced the same error.

Ok, so I have tried every variation that I can think of. I have worked with the suggestions that have been put forth so far. I have searched the Google-sphere and tried to look at the work of others, but to no avail. I am still unable to pull, parse, and use the information from a selected grid screen item.

Doing things like this:


column = msg.GetData()
row = msg.GetIndex()

title = grid[column]
title = title[row]
title = title.Title
print "Title => "+title.toStr()

**AND**

title = grid[msg.GetData()][msg.GetIndex()].Title.toStr()
print "Title => "+title

all result in


Array operation attempted on variable not DIM'd. (runtime error &he7) in ...TZPco/pkg:/source/appMain.brs(91)
091:                  title = grid[msg.GetData()][msg.GetIndex()].Title.gettext()

and unfortunately there is absolutely no documentation in the Brightscript manual or online information about how to get information from a selected grid screen item.

So how in the world do you click on an item and be able to use the information from the item that was clicked on?

The error message means “grid” is not an array, or “grid[msg.GetData()]” is not an array. You can do those steps separately to see which is the problem.

–Mark

Tried both of those and here are the results:


title = grid[msg.GetData()]

**THROWS**

Array operation attempted on variable not DIM'd. (runtime error &he7) in ...adUeh/pkg:/source/appMain.brs(95)
095:                  title = grid[msg.GetData()]

And…


title = grid

**THROWS**

Type Mismatch. (runtime error &h18) in ...skqSY/pkg:/source/appMain.brs(96)
096:                  print "Title => "+title

In the list of variables that is printed in the debugger, what is the type of grid? Your code expects it to be an array, but it doesn’t seem to be.

grid is showing as roGridScreen

From the last output:


Local Variables:
global   &h0020 rotINTERFACE:ifGlobal
m        &h0010 bsc:roAssociativeArray, refcnt=2
request  &h0010 bsc:roUrlTransfer, refcnt=1
html     &h8010 bsc:roString (2.1 was String), refcnt=1
rsp      &h0010 bsc:roXMLElement, refcnt=1
port     &h0010 bsc:roMessagePort, refcnt=2
grid     &h0010 bsc:roGridScreen, refcnt=3
rowtitles &h0010 bsc:roArray, refcnt=1
j        &h0002 Integer val:4
total_count &h0002 Integer val:40
divided_count &h0004 Float val:4
iterator &h0002 Integer val:40
list     &h0010 bsc:roArray, refcnt=1
i        &h0002 Integer val:40
title    &h0010 bsc:roGridScreen, refcnt=3
sd_img   &h0010 bsc:roString, refcnt=3
hd_img   &h0010 bsc:roString, refcnt=3
o        &h0010 bsc:roAssociativeArray, refcnt=2
msg      &h0010 bsc:roGridScreenEvent, refcnt=1

Ok, so still not sure if it’s even possible to pull the information from a selected item after the grid is built and displayed, but I created a band-aid; a work-around. I created my own content array before the looping to create the grid screen information. As the loop iterates through the information and builds the grid screen, I insert the information into my own array which I can then use later on at will.


    iterator = 0

    ' Create my own content array with the same number of items
    content = CreateObject("roArray", 4, true)

    for j = 0 to 3
    	list = CreateObject("roArray", 4, true)

    	for i = (0+iterator) to (iterator+9)
    		title = rsp.item[i].title.gettext()
    		sd_img = rsp.item[i]@sdImg
    		hd_img = rsp.item[i]@hdImg

            o = CreateObject("roAssociativeArray")
            o.ContentType = "episode"
            o.Title = title
            o.ShortDescriptionLine1 = "[ShortDescriptionLine1]"
            o.ShortDescriptionLine2 = "[ShortDescriptionLine2]"
            o.Description = ""
            o.Description = "[Description] "
            o.Rating = "NR"
            o.StarRating = "75"
            o.ReleaseDate = "[<mm/dd/yyyy]"
            o.Length = 5400
            o.SDPosterUrl = sd_img
            o.HDPosterUrl = hd_img
            o.Actors = []
            o.Actors.Push("[Actor1]")
            o.Actors.Push("[Actor2]")
            o.Actors.Push("[Actor3]")
            o.Director = "[Director]"
            list.Push(o)

             iterator = iterator + 1
         end for
         
         ' Add the content to our own custom array
         content[j] = list

         grid.SetContentList(j, list)
     end for
     grid.Show()
     while true
         msg = wait(0, port)
         if type(msg) = "roGridScreenEvent" then
             if msg.isScreenClosed() then
                 'return -1
             elseif msg.isListItemFocused()
                 print "Focused msg: ";msg.GetMessage();"row: ";msg.GetIndex();
                 print " col: ";msg.GetData()

                 ' Now that we know what is selected through the GetData() and GetIndex(), we can now access the information from our own array of information
                 title = content[msg.GetData()][msg.GetIndex()].Title
                 print "Title => "+title

             elseif msg.isListItemSelected()
                 print "Selected msg: ";msg.GetMessage();"row: ";msg.GetIndex();
                 print " col: ";msg.GetData()
             endif
         endif
     end while

“DukeOfMarshall” wrote:
Ok, so still not sure if it’s even possible to pull the information from a selected item after the grid is built and displayed, but I created a band-aid; a work-around. I created my own content array before the looping to create the grid screen information. As the loop iterates through the information and builds the grid screen, I insert the information into my own array which I can then use later on at will.
Hm, yeah. Joel was confusing starting with
“RokuJoel” wrote:
You can look at a grid as an array of arrays of associative arrays.That’s easy to mis-interpret. You cannot “look at [the] grid as an array of …” - no peeking. It’s a black box, all it will give you back is row# and column#. But then he kinda/sorta redeemed what was said by adding at the end “create your grid as an array first, and then use it to set the rows of the grid” (it’s better here to take that out of context).

Yes, it’s up to you to keep track of what metadata you fed roGridScreen, in your own structures.

Aaahhh, that’s starting to clarify.

So just to be more specific, you CAN’T get information from the grid screen. You HAVE to have a separate array of information to access from with the same indexes/structure of information.

Is that correct?

Ok, So I’m trying to set the url for each video in the grid screen meta data, but having no luck. Should it be set via StreamUrls or Stream?

Either will work.

where is the documentation for properties of GridScreen. ifGridScreen or GridSceen component documentation only talks about the available methods.

need to see documentation about focusedContent & rowItemSelected properties of grid and need to know if i can change focusedContent from brightscript while grid is not visible and if that will fire rowItemSelected event or not.