(635 b)
Updated: 11-11-13 01:22 AM
Updated:11-11-13 01:22 AM
Created:11-11-13 01:22 AM

Five - Easy frame-region z-level management

Version: 1
by: nefftd [More]

This is a nifty little library I wrote for myself a while ago, to tackle a problem that's fairly common but somewhat tedious. The problem being: what happens when you have more frame regions (textures and/or fontstrings) than there are draw layers available, but you want to ensure they're layered properly?

Normally, the solution is to create a container frame for some of those files, and that works well. But doing this often is tedious, and adds weight to your code reducing the readability. So I wrote Five, which will automatically manage an infinite amount of containers, so layering regions properly is as simple as calling the new API function: region:SetZLevel(n).



Five does not use LibStub, but it works in much the same way. Include a copy of libFive-1.0.lua in your addon (and load it via your .toc file), and then fetch a working reference to the library from _G:

local five = _G['libFive-1.0']
From here, replace all existing references to `CreateFrame` with Five's own CreateFrame method:

-- local myFrame = CreateFrame('Frame','MYFrame',UIParent)   -- old
local myFrame = five:CreateFrame('Frame','MYFrame',UIParent)  -- new
Alternately, you can call the library's reference directly as if it were a function, doing the same thing:

-- local myFrame = CreateFrame('Frame','MYFrame',UIParent)   -- old
local myFrame = five('Frame','MYFrame',UIParent)  -- new
Then, any fontstring or texture created as a child of that frame (by using myFrame:CreateTexture, or myFrame:CreateFontString) will have an additional API attached to it called SetZLevel:

local tex1 = myFrame:CreateTexture(nil,'OVERLAY')
local tex2 = myFrame:CreateTexture(nil,'BACKGROUND')
-- tex2 will appear layered above tex1
SetZLevel works intuitively. Pass it a number between 1 and infinity, and it places the region into the corresponding layer container. Containers are created transparently and on-the-fly. Passing it a number 0 or below will place the region back onto the parent frame (underneath all containers).



Five was made to be quick and simple, so it's pretty naive. One of its pitfalls is that it does nothing clever with containers to contain memory usage. Any time you call SetZLevel with a higher number than has been previously used (on THAT frame), the function will iterate between the highest container level in existence, and the z-level number you wish to use, and create every container in between. So if you set the z-level of some region to a large number like 2000, then 2000 frames will be created in the process, each one parented and anchored to the one before it. This is how z-levels are achieved.

This is not a big problem by itself. Just don't use arbitrarily large z-levels. Use the smallest z-level that will achieve you goal. Since there are 4 draw layers in the WoW API (BACKGROUND, BORDER, ARTWORK, OVERLAY), if you need to stack 12 regions atop one another, you should need no more than 3 z-levels (4 draw layers per container). In this case, use z-levels 0-2 (or 1-3); don't do something like:

-- ...
Nothing will necessarily break if you do this, but it's bad practice as it will bloat your memory usage.


If you have any questions or problems, I can be found at Freenode's #wowuidev channel as Neffi.

Optional Files (0)

There have been no comments posted to this file.
Be the first to add one.

Category Jump: