The only thing you can't do in Lua is create a template, but the only thing you need templates for are certain uncommon cases involving very advanced secure frames (unitframe/actionbutton) usage, so chances are you will never want to do anything that can't be done in Lua.
Here's a simple example of creating a movable frame with a title, a button, and font string, and resizing the frame based on the contents of the font string:
Code:
-- Give your main object a global name so you can access it more easily for debugging:
local frame = CreateFrame("Frame", "MyTestFrame", UIParent)
-- Put the frame in the middle of the screen:
frame:SetPoint("BOTTOM", UIParent, "CENTER", 0, 100)
-- Give it a starting size:
frame:SetSize(500, 200)
-- Give it a backdrop so you can see it:
frame:SetBackdrop({
bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tile = true, tileSize = 16,
edgeFile = [[Interface\Tooltips\UI-Tooltip-Border]], edgeSize = 5,
insets = { left = 5, right = 5, top = 5, bottom = 5 },
})
frame:SetBackdropColor(0, 0, 0)
frame:SetBackdropBorderColor(1, 1, 1)
-- Add a title:
local title = frame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
title:SetPoint("TOP", 0, -2)
title:SetText("My Test Frame")
-- Make it easy to access:
frame.Title = title
-- Make it draggable by the title:
local titleRegion = frame:CreateTitleRegion()
titleRegion:SetPoint("BOTTOMLEFT", title, -5, -2)
titleRegion:SetPoint("TOPRIGHT", title, 5, 2)
frame.TitleRegion = titleRegion
-- Add a button at the bottom. Use the pre-defined template for the "red button" style:
local button = CreateFrame("Button", "$parentOkayButton", frame, "UIPanelButtonTemplate")
button:SetPoint("BOTTOM", 0, 16)
button:SetText(OKAY) -- Use a pre-defined global string so it's "correct" in all WoW languages.
-- Make it close the frame when clicked:
button:SetScript("OnClick", function(self) self:GetParent():Hide() end)
frame.OkayButton = button
-- Add a font string in the middle:
local text = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
text:SetPoint("LEFT", 16, 0)
text:SetPoint("RIGHT", -16, 0)
text:SetPoint("TOP", title, "BOTTOM", 0, -16)
text:SetPoint("BOTTOM", button, "TOP", 0, 16)
text:SetJustifyH("CENTER")
text:SetJustifyV("TOP")
frame.Text = text
-- Frames don't normally have a SetText method, but we'll add one that sets the
-- text of the frame's font string, and adjusts the size of the frame to match.
function frame:SetText(text)
-- Set the text of the font string:
self.Text:SetText(text)
-- Find out how long the text is:
local width = self.Text:GetStringWidth()
-- Make sure it's at least as wide as the title and button:
local titleWidth = self.Title:GetWidth()
local buttonWidth = self.Button:GetWidth()
width = math.max(width, titleWidth, buttonWidth)
-- And adjust the width of the frame, accounting for the inner padding:
self:SetWidth(width + 32)
end
-- Then use it like this:
frame:SetText("This is my test frame! It has some text in it!")
-- Try a longer font string:
frame:SetText("Here is a long string. It doesn't really say anything. It's just long, so you can see how the frame gets bigger.")
-- And a shorter one:
frame:SetText("It's so short!")
For a more complete example of a frame with multiple rows of text, that shows a maximum of X lines at once and scrolls to show the rest, see here:
http://forums.wowace.com/showthread.php?p=320619