Forum Discussion

tutash's avatar
tutash
Binge Watcher
9 years ago

Creating a MarkupGrid itemComponent in code.

I want to create a MarkupGrid from code, not markup. 

I can build a MarkupGrid like so: 


sub buildGrid()
    print "GRID"
    m.grid = createObject("roSGNode","MarkupGrid")
    m.grid.translation = "[100,100]"
    REM m.grid.itemComponentName = "gridItem"
    m.grid.itemSize = [100,100]
    m.grid.itemSpacing = [10,10]
    m.grid.numColumns = 5
    m.grid.numRows = 1
    m.grid.content = m.content
    m.top.appendChild(m.grid)
    print m.grid
end sub


My issue is with the field "itemComponentName". I believe that I should be able to create a node, give it an id, and point to the itemComponentName to it, but that's not working. 

So, how would I go about building an "itemComponent" using Brightscript without markup?
Any suggestions?
  • Have you previously defined the component "gridItem" somewhere yourself?  itemComponentName should refer to a previously defined component.  If you haven't defined it (and it doesn't exist by default) then you can't use it in itemComponentName
  • tutash's avatar
    tutash
    Binge Watcher
    So what you're saying is: I can define the component. 
    sub makeGridItem()
    m.gridItem = createObject("roSGNode","Rectangle")
    m.gridItem.color = "0xFF0000FF"
    m.gridItem.width = "100"
    m.gridItem.height = "100"
    m.gridItem.id = "gridItem"
    m.top.appendChild(m.gridItem)
    end sub()

    So how would I define the above object to be the itemComponent if it doesn't have a "name" field? Remember I'm not using markup, and want to create the itemComponent in code.
  • As far as I'm aware, you can't do it. 

    There's a compilation step when using Scene Graph XML that only happens once on startup.  During that step is where you define a component and give it a name.

    <component name = "MyPoster" extends = "Poster" >


    Then later you refer to this component by name.  

    m.grid = createObject("roSGNode","MarkupGrid")
    m.grid.translation = "[100,100]"
    m.grid.itemComponentName = "MyPoster"


    What you've done with makeGridItem() is created a single instance of the Rectangle component type and given that instance a unique id of `gridItem`.  MarkupGrid isn't looking at id's of object instances with itemComponentName, it's looking at the registry of defined component types.
  • tutash's avatar
    tutash
    Binge Watcher
    Okay, if that's the issue; creating only one instance, then what about something like this: We return the instance from a function call.

    m.gridItem = function() as Object
            g = createObject("roSGNode","Rectangle")
            g.width = "100"
            g.height = "100"
            g.color = "0xFF0000FF"
            return g
        end function


    Now each call creates an instance, but that doesn't matter.

    Still doesn't work because it can't be assigned as the itemComponent.
    Anyway, my reasoning for asking is that I want to create MarkupGrids in code at runtime. I can use PosterGrid for my needs for now, but I'd like to have the option to point the itemComponent something other than markup. 

    Alas, this ain't happening.
  • "tutash" wrote:

    Anyway, my reasoning for asking is that I want to create MarkupGrids in code at runtime. I can use PosterGrid for my needs for now, but I'd like to have the option to point the itemComponent something other than markup. 

    Alas, this ain't happening.

    What's your objection to having the pre-defined component in XML?  You can still create your MarkupGrids at runtime, just pre-define your "gridItem" itemComponent in XML as the container for your grid items and you're good to go.
  • tutash's avatar
    tutash
    Binge Watcher
    It's not an objection, really, but a requirement that I have no XML-based components, and that it remain scene graph based.
  • "tutash" wrote:
    It's not an objection, really, but a requirement that I have no XML-based components, and that it remain scene graph based.

    one of the realizations you will have going along with RSG is that it uses a somewhat brain-dead "binding by name" in different parts - fr example for event handlers instead of passing function by reference, have to pass the name of a global function. Ditto here - can't give instance, have to give "class" name.

    PS. a few months ago i was working on a framework to get away with the XML "mandate" and that is feasible, abeit at the cost of heroic (for the library) contortions
  • "Veeta" wrote:
    As far as I'm aware, you can't do it. 
    [spoiler=on class-name as a factory in RSG:18uh2wpi]There's a compilation step when using Scene Graph XML that only happens once on startup.  During that step is where you define a component and give it a name.

    <component name = "MyPoster" extends = "Poster" >


    Then later you refer to this component by name.  

    m.grid = createObject("roSGNode","MarkupGrid")
    m.grid.translation = "[100,100]"
    m.grid.itemComponentName = "MyPoster"


    What you've done with makeGridItem() is created a single instance of the Rectangle component type and given that instance a unique id of `gridItem`.  MarkupGrid isn't looking at id's of object instances with itemComponentName, it's looking at the registry of defined component types.[/spoiler:18uh2wpi]

    Well explained!

    Follow-up/lead question - how about using one a the pre-defined classes (e.g. m.grid.itemComponentName = "Poster" instead of = "MyPoster") ... works?