Lua - how do I create frames?

I am making my own version of TellMeWhen. First I make frames and then I add text. The problem I have is that I can make the frames with this code:

function CreateSquare(squareName, x, y, colour)
    local myFrame = squareName
    myFrame = CreateFrame("Frame", nil, UIParent)
    myFrame:SetFrameStrata("BACKGROUND")
    myFrame:SetWidth(5) 
    myFrame:SetHeight(5) 
    myFrame.texture = myFrame:CreateTexture(nil,"BACKGROUND")
    myFrame.texture:SetAllPoints(myFrame)
    myFrame:SetPoint("TOPLEFT",x,y)
    myFrame:Show()
    myFrame.texture:SetColorTexture(colour[1], colour[2], colour[3]) 
end

But when I try to change the color or to add text I get messages like “attempt to index global 'CommandStartStop”

Is there a better way to make a frame so that the rest of the addon can see it and interface with it?

The second parameter of CreateFrame is the name, which I assume you wanted to be named CommandStartStop. Try this:

function CreateSquare(squareName, x, y, colour)
    local myFrame = CreateFrame("Frame", squareName, UIParent)
    myFrame:SetFrameStrata("BACKGROUND")
    myFrame:SetWidth(5) 
    myFrame:SetHeight(5) 
    myFrame.texture = myFrame:CreateTexture(nil,"BACKGROUND")
    myFrame.texture:SetAllPoints(myFrame)
    myFrame:SetPoint("TOPLEFT",x,y)
    myFrame:Show()
    myFrame.texture:SetColorTexture(colour[1], colour[2], colour[3]) 
end

As an aside, these names that aren’t local (named frames, the function CreateSquare) share the same namespace as all other addons and the default UI itself. Globals aren’t inherently bad, just take care to make them uniquely named.

Also if you did want an anonymous frame and reference it by a variable, a small adjustment to your “factory” function:

local function CreateSquare(x, y, colour)
    local myFrame = CreateFrame("Frame", nil, UIParent)
    myFrame:SetFrameStrata("BACKGROUND")
    myFrame:SetWidth(5) 
    myFrame:SetHeight(5) 
    myFrame.texture = myFrame:CreateTexture(nil,"BACKGROUND")
    myFrame.texture:SetAllPoints(myFrame)
    myFrame:SetPoint("TOPLEFT",x,y)
    myFrame:Show()
    myFrame.texture:SetColorTexture(colour[1], colour[2], colour[3]) 
    return myFrame
end

Now you can do things like:

local myFrames = {}
for i=1,10 do
  myFrames[i] = CreateSquare(i*10+300,-(i-1)*10-300,{1,0,0})
end

Note the function is local too so it will only exist in the scope of the current file it’s in. You can make it global or a member of your addon’s namespace. Again, creating named frames is totally fine; and it’s nice to be able to /fstack to see what addon is putting them on the screen–if they include the addon name in their name–but since these are tiny 5x5 I expect you’ll be making lots.

1 Like

Sadly that fails the same way.