Skip to content
This repository has been archived by the owner on Mar 15, 2018. It is now read-only.
Mischback edited this page Jun 24, 2011 · 6 revisions

Step 05 – Refine the look

We have just spawned the first unitframe, which only consists of a health-bar. We will now add some more elements to the unitframe to refine the look.

Remember: We’re creating the very basic default-frame. We will only add elements that are common to all frames.

a) Power-bar

Add these lines just after the creation of the Health-bar in the function core.CreateUnitFrame in core.lua:

	-- Creating the Power-bar
	local pb = CreateFrame('StatusBar', nil, self)
	pb:SetFrameLevel(61)
	pb:SetHeight(cfg.powerHeight)
	pb:SetPoint('LEFT', self, 'BOTTOMLEFT', cfg.powerXOff, 0)
	pb:SetPoint('RIGHT', self, 'BOTTOMRIGHT', -cfg.powerXOff, 0)
	pb:SetStatusBarTexture(settings.tex.power)

	pb.bg = pb:CreateTexture(nil, 'BACKGROUND')
	pb.bg:SetAllPoints(pb)
	pb.bg:SetTexture(settings.tex.solid)
	pb.bg:SetAlpha(SplashSettings.general.powerBGModifier)

	pb.border = CreateFrame('Frame', nil, pb)
	pb.border:SetFrameLevel(60)
	pb.border:SetPoint('TOPLEFT', pb, 'TOPLEFT', -1, 1)
	pb.border:SetPoint('BOTTOMRIGHT', pb, 'BOTTOMRIGHT', 1, -1)
	pb.border.tex = pb.border:CreateTexture(nil, 'BACKGROUND')
	pb.border.tex:SetAllPoints(pb.border)
	pb.border.tex:SetTexture(0, 0, 0, 1)

	pb.colorDisconnected = true
	pb.colorClass = true
	pb.colorReaction = true

	self.Power = pb

This will create a Power-bar for our unitframe. Pay attention to the last line: self.Power is the name of the oUF-element.

b) Text-elements

You may have noticed the several calls of SetFrameLevel(). Remember the look of the unitframes we created in Photoshop. There were many elements overlapping each other. To keep them aligned, SetFrameLevel() is used.

To add text-elements, you can simply create a font-object. To keep our “layers” ordered, we will first spawn a frame to anchor these text-elements to:

	-- Text-holder
	self.Text = CreateFrame('Frame', nil, self)
	self.Text:SetFrameLevel(31)

Now we will add a health-value to our frame. Since there will be many font-objects in our layout, we start by creating a function to spawn these font-objects.

Open up lib.lua and add this function:

lib.CreateFontObject = function(parent, size, font)
	local fo = parent:CreateFontString(nil, 'OVERLAY')
	fo:SetFont(font, size)
	fo:SetJustifyH('CENTER')
	fo:SetShadowColor(0,0,0)
	fo:SetShadowOffset(1, 1)
	return fo
end

Note how the first parameter parent is used: The font-object will be created as a child of a given frame. This way, we can exactly control on which layer the font-object will be.

The size and font can be handled aswell, so we are able to use different fonts with the same function.

We will now use this function to create a font-object for the health-text. In core.lua we add

	self.Health.value = lib.CreateFontObject(self.Text, 14, settings.fonts.grunge)
	self.Health.value:SetJustifyH('RIGHT')
	self.Health.value:SetPoint('BOTTOMRIGHT', self.Health, 'BOTTOMRIGHT', -2, 6)

just behind the creation of the text-holder-frame self.Text.

c) Break

When you reload your interface right now, you will see the power-bar, but no health-text.

This is the code we got now.

You should not put any further attention to the element self.Gloss in core.lua, this is part of the look and has no real function. It is not part of oUF-elements, but styling.

So, how do we get our health-text to show up?

d) oUF’s PostUpdate-hooks

oUF is a framework, which will do all the nasty work for you, but in some cases, you want some other behaviour or have some special requirements to the update-mechanism of an element.

Most of oUF’s elements provide you with the necessary means to implement your own code, while keeping the original (oUF-provided) functionality. These means are called PostUpdate-hooks.

When you look at the source code of oUF-elements, you will often find a call to a PostUpdate-function inside of the Update-function. The PostUpdate-function has to be provided from the layout.

While oUF is handling the health-bar itsself, it does not handle the updating of the health-value. We will use a PostUpdate-hook to do so.

The only important thing is, to provide a function with the correct prototype.

Open up oUF/elements/health.lua in your editor and have a look at the Update-function.

You will find these lines:

	if(health.PostUpdate) then
		return health:PostUpdate(unit, min, max)
	end

Here you can see the necessary prototype. Just remember one thing: The first parameter is implicitly a reference to the frame, the function is attached to, it’s usually called self.

e) Player’s health.PostUpdate

I already mentioned that the player-frame is special in some ways. The display of the health-value is one of these things. We will create a special PostUpdate for the player-frame.

Open core.lua and add

--[ [ Player's Health-value 
	VOID UpdateHealth_player(FRAME health, STRING unit, INT min, INT max)
	Plain HP, just the current value!
] ]
core.UpdateHealth_player = function(health, unit, min, max)
	health.value:SetText(lib.Shorten(min))
end

You can see, that we use the function SetText to apply the health-value to health-value. We are in Cataclysm right now, so health-values tend to be real huge, so we want to shorten the value a bit (we will do some mathematical magic to the number).

The function lib.Shorten should be in lib.lua and looks like this:

--[ [ Shortening the values displayed on the Health- and Power-Bars
	STRING Shorten(INT value)
] ]
lib.Shorten = function(value)
	if value >= 1e7 then
		return ('%.1fm'):format(value / 1e6):gsub('%.?0+([km])$', '%1')
	elseif value >= 1e6 then
		return ('%.2fm'):format(value / 1e6):gsub('%.?0+([km])$', '%1')
	elseif value >= 1e5 then
		return ('%.0fk'):format(value / 1e3)
	elseif value >= 1e3 then
		return ('%.1fk'):format(value / 1e3):gsub('%.?0+([km])$', '%1')
	else
		return value
	end
end

Ok, now we want to apply this function as PostUpdate-hook. Remember, it will only be used on the player-frame, so we add the hook into the creation of this frame in layout.lua : self.Health.PostUpdate = core.UpdateHealth_player

f) Conclusion

So, just reload your UI now and your health-value should be visible.

Your code should look like this right now.

This is the look!

Clone this wiki locally