Using a function to create multiple widgets

Hi all,

Just got back into Corona and going over my old programs. I am trying to cut down the repetitiveness of my code by using a function to create widgets rather than creating them individually. This is working except where I need to update the label of a button and I get an error about trying to index either a global or upvalue. I know the problem is something to do with scope but I can’t find it.

Thanks in advance for any help.

local warriorBuy

local function createBtn ( name, btnLabel, eventCall, btnWidth, btnHeight, xLocation, yLocation )

    – Create a button that will call a function

    name = widget.newButton(

        {

            label = btnLabel,

            onEvent = eventCall,

            emboss = false,

            shape = “roundedRect”,

            width = btnWidth,

            height = btnHeight,

            cornerRadius = 2,

            fillColor = { default={0,0,0,1}, over={0,0,0,1} },

            strokeColor = {default={1,1,1,1}, over={1,1,1,1} },

            strokeWidth = 4,

        }

    )

    sceneGroup:insert(name)

    name.x = xLocation

    name.y = yLocation

end

local function increaseWarrior ( event )

    – Let player buy a warrior for the said price, given they have enough money

    if ( “ended” == event.phase ) then

        if mydata.money >= mydata.warriorBuy then

            mydata.warriorAm = mydata.warriorAm + 1

            mydata.money = mydata.money - mydata.warriorBuy

            mydata.warriorBuy = math.floor( (mydata.warriorAm)^(1.01) )

            moneyHave.text = "Money "…mydata.money

            unitWarriors.text = “Warriors:”…mydata.warriorAm

            buyWarrior:setLabel(“Buy Warrior $”…mydata.warriorBuy) --This is where the error occurs

            if mydata.warriorAm >= mydata.warriorMax then

                mydata.warriorMax = mydata.warriorAm

            end

        end

    end

end

createBtn( buyWarrior, “Buy Warrior $”…mydata.warriorBuy, increaseWarrior, 150, 50, cenx, (toty*4)/20 )

Hi @daniel299,

It looks like your method is creating global variables which can lead to problems.

How many buttons might you have on screen? Many? If so, you should probably add them as references to some kind of local “container” table, then access them within by either name, index, or some other method that makes sense in your design.

Brent

Hi Brent,

Thanks for the suggestion. I’ve never tried anything like that, do you know where I could find some tutorials or information on how to do that.

Daniel

Hi Daniel,

Well there’s not really a tutorial on it, it’s just a fairly common way to store references in Lua. The idea is that you create a Lua table which can then hold references to other tables.

How to best do this depends on how many buttons/items you need to keep track of. Can they be “named” in some logical way within your app, and that name remains consistent with the object? Or are things very flexible and changing often?

Brent

Hey Brent,

I think I understand what you are meaning and I will give it a try.

There as several buttons and they all have a consistent, logical name. Only a few require their label to be updated each time they are pressed.

Hi @daniel299,

If that’s the case, probably easier to just create a “dictionary” style table with named key-value pairs, like this:

[lua]

local buttonContainer = {}

local button1 = … – Your code to create a button, whatever that is

buttonContainer[“button1”] = button1

[/lua]

Then sometime later, you know the direct Lua reference to that button and you can change things about it. For instance, if it’s a widget button, you can change its label using the “:setLabel()” API.

Just remember, if you ever delete a button, you must remove this reference from the container table, otherwise it will forever be locked in memory.

Brent

Hi @daniel299,

It looks like your method is creating global variables which can lead to problems.

How many buttons might you have on screen? Many? If so, you should probably add them as references to some kind of local “container” table, then access them within by either name, index, or some other method that makes sense in your design.

Brent

Hi Brent,

Thanks for the suggestion. I’ve never tried anything like that, do you know where I could find some tutorials or information on how to do that.

Daniel

Hi Daniel,

Well there’s not really a tutorial on it, it’s just a fairly common way to store references in Lua. The idea is that you create a Lua table which can then hold references to other tables.

How to best do this depends on how many buttons/items you need to keep track of. Can they be “named” in some logical way within your app, and that name remains consistent with the object? Or are things very flexible and changing often?

Brent

Hey Brent,

I think I understand what you are meaning and I will give it a try.

There as several buttons and they all have a consistent, logical name. Only a few require their label to be updated each time they are pressed.

Hi @daniel299,

If that’s the case, probably easier to just create a “dictionary” style table with named key-value pairs, like this:

[lua]

local buttonContainer = {}

local button1 = … – Your code to create a button, whatever that is

buttonContainer[“button1”] = button1

[/lua]

Then sometime later, you know the direct Lua reference to that button and you can change things about it. For instance, if it’s a widget button, you can change its label using the “:setLabel()” API.

Just remember, if you ever delete a button, you must remove this reference from the container table, otherwise it will forever be locked in memory.

Brent