Thread Tools Display Modes
11-30-14, 12:15 PM   #1
cokedrivers
A Rage Talon Dragon Guard
 
cokedrivers's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2009
Posts: 325
Centering Level Text

Attached is a Target frame default (with a couple of modifacations) I was wondering how I would center the Level Text to look better?

I searcher playerframeleveltext and found this in the PlayerFrame.xml
Code:
                                <FontString name="PlayerLevelText" inherits="GameFontNormalSmall">
                                    <Anchors>
                                        <Anchor point="CENTER">
                                            <Offset>
                                                <AbsDimension x="-63" y="-16"/>
                                            </Offset>
                                        </Anchor>
                                    </Anchors>
                                </FontString>
How would I convert this to lua just adjust the AbsDimension to be 61 instead of 63?

Thanks Coke
Attached Thumbnails
Click image for larger version

Name:	Unitframe.png
Views:	186
Size:	47.4 KB
ID:	8331  
  Reply With Quote
11-30-14, 12:39 PM   #2
ObbleYeah
A Cobalt Mageweaver
AddOn Author - Click to view addons
Join Date: Sep 2008
Posts: 210
Lua Code:
  1. PlayerLevelText:SetJustifyH'CENTER'
  2. PlayerLevelText:ClearAllPoints()
  3. PlayerLevelText:SetPoint('CENTER', PlayerFrame, -61, -16)
  Reply With Quote
11-30-14, 12:40 PM   #3
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
The numbers in an AbsDimension inside an Offset inside an Anchor are just like the values you pass to SetPoint in Lua. The Lua equivalent of that XML would be:

Code:
<parent frame reference>:CreateFontString("PlayerLevelText", <draw layer>, "GameFontNormalSmall")
PlayerLevelText:SetPoint("CENTER", -63, -16)
From there it's hopefully obvious what to do.
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote
11-30-14, 01:08 PM   #4
cokedrivers
A Rage Talon Dragon Guard
 
cokedrivers's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2009
Posts: 325
so would this one:
Code:
<FontString name="$parentLevelText" inherits="GameFontNormalSmall">
end up being:
Code:
TargetFrameLevelText:ClearAllPoints()
TargetFrameLevelText:SetPoint('CENTER', TargetFrame, -61, -16)
Coke
  Reply With Quote
11-30-14, 01:10 PM   #5
ObbleYeah
A Cobalt Mageweaver
AddOn Author - Click to view addons
Join Date: Sep 2008
Posts: 210
well the numbers would probably be positive because the targetframe is reversed, but yeah
  Reply With Quote
11-30-14, 01:16 PM   #6
cokedrivers
A Rage Talon Dragon Guard
 
cokedrivers's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2009
Posts: 325
Originally Posted by ObbleYeah View Post
well the numbers would probably be positive because the targetframe is reversed, but yeah
I get this error:
Code:
5x CokeUI\Unitframes.lua:115: attempt to index global 'TargetFrameLevelText' (a nil value)
CokeUI\Unitframes.lua:115: in main chunk
also here is my Unitframes.lua file.

Last edited by cokedrivers : 11-30-14 at 01:18 PM.
  Reply With Quote
11-30-14, 02:01 PM   #7
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
You're getting that error because "$parent" (when creating an object) refers to the name of the object's immediate parent. In the case of the level text on the target frame, that parent isn't "TargetFrame" -- there's another frame in between:

http://www.townlong-yak.com/framexml...tFrame.xml#184
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote
11-30-14, 02:26 PM   #8
cokedrivers
A Rage Talon Dragon Guard
 
cokedrivers's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2009
Posts: 325
I think it need to be done in some kinda function because nothing seems to be moving it, maybe its because of me scaling it up not sure, but thanks for the attempt.

Coke
  Reply With Quote
12-01-14, 01:10 AM   #9
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
On second glance at the relevant XML:
Code:
            <FontString name="$parentLevelText" inherits="GameNormalNumberFont" justifyH="CENTER">
              <!--WARNING:: This is re-anchored in code.-->
              <Anchors>
                <Anchor point="CENTER" x="61" y="-17"/>
              </Anchors>
            </FontString>
So then you can go over to the matching Lua file:
http://www.townlong-yak.com/framexml...argetFrame.lua

and search through for "leveltext" and find this function:
http://www.townlong-yak.com/framexml...tFrame.lua#302

which you can hook (using securehookfunc) to re-set your desired position after the default UI sets it.
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.

Last edited by Phanx : 12-01-14 at 01:13 AM.
  Reply With Quote
12-01-14, 09:07 AM   #10
cokedrivers
A Rage Talon Dragon Guard
 
cokedrivers's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2009
Posts: 325
Originally Posted by Phanx View Post
and search through for "leveltext" and find this function:
http://www.townlong-yak.com/framexml...tFrame.lua#302

which you can hook (using securehookfunc) to re-set your desired position after the default UI sets it.
Worked like a charm...

Player:
Code:
hooksecurefunc("PlayerFrame_UpdateLevelTextAnchor", function(level)
  if ( level >= 100 ) then
    PlayerLevelText:SetPoint("CENTER", PlayerFrameTexture, "CENTER", -61, -15);
  else
    PlayerLevelText:SetPoint("CENTER", PlayerFrameTexture, "CENTER", -61, -15);
  end
end)
Target:
Code:
hooksecurefunc("TargetFrame_UpdateLevelTextAnchor",  function(self, targetLevel)
  if ( targetLevel >= 100 ) then
    self.levelText:SetPoint("CENTER", 62, -15);
  else
    self.levelText:SetPoint("CENTER", 62, -15);
  end
end)
On a side not I'm trying to get the scale for the boss to work (again) but cant seem to get it to work.

Oh BTW thanks for the link to the lua on the web I like how you can click to follow functions.

here is the code I found and I think is what I need to change but it doesn't seems to work (used deadmines normal as a test beings it shows the boss frames)

Boss:
Code:
hooksecurefunc("BossTargetFrame_OnLoad", function(self, unit, event)
	--self.isBossFrame = true;
	--self.noTextPrefix = true;
	--self.showLevel = true;
	--self.showThreat = true;
	--self.maxBuffs = 0;
	--self.maxDebuffs = 0;
	--TargetFrame_OnLoad(self, unit, BossTargetFrameDropDown_Initialize);
	--self:RegisterEvent("UNIT_TARGETABLE_CHANGED");
	--self.borderTexture:SetTexture("Interface\\TargetingFrame\\UI-UnitFrame-Boss");
	--self.levelText:SetPoint("CENTER", 12, select(5, self.levelText:GetPoint("CENTER")));
	--self.raidTargetIcon:SetPoint("RIGHT", -90, 0);
	--self.threatNumericIndicator:SetPoint("BOTTOM", self, "TOP", -85, -22);
	--self.threatIndicator:SetTexture("Interface\\TargetingFrame\\UI-UnitFrame-Boss-Flash");
	--self.threatIndicator:SetTexCoord(0.0, 0.945, 0.0, 0.73125);
	--self:SetHitRectInsets(0, 95, 15, 30);
	self:SetScale(1.193);
	--if ( event ) then
		--self:RegisterEvent(event);
	--end
end)
This is the bossframe code I found in the targetframe section.

Coke
  Reply With Quote
12-01-14, 12:19 PM   #11
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
You can't hook the OnLoad for a frame created in Blizzard XML. Well, you can, but it won't actually do anything, since OnLoad scripts are executed immediately when the frame is created, so by the time your addon code is running, the OnLoad is long since over and done with. You should just be able to set the scale once anywhere, even in the main chunk of your addon:

Code:
for i = 1, 5 do
    _G["Boss"..i.."TargetFrame"]:SetScale(1.193)
end
(On a side note, that's a very specific scale value. o_O)
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote
12-01-14, 01:04 PM   #12
cokedrivers
A Rage Talon Dragon Guard
 
cokedrivers's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2009
Posts: 325
Originally Posted by Phanx View Post
You should just be able to set the scale once anywhere, even in the main chunk of your addon:
I tried this before and it threw up errors. I will try once more.

Originally Posted by Phanx View Post
(On a side note, that's a very specific scale value. o_O)
This seems to be the size NeavUi was and it seems to work for me

would I be able to put all this:
Code:
-- Player Frame
PlayerFrame:SetScale(ns.unitframesPlayerScale)
CastingBarFrame:SetScale(ns.unitframesCastbarScale)
hooksecurefunc("PlayerFrame_UpdateLevelTextAnchor", function(level)
  if ( level >= 100 ) then
    PlayerLevelText:SetPoint("CENTER", PlayerFrameTexture, "CENTER", -61, -15);
  else
    PlayerLevelText:SetPoint("CENTER", PlayerFrameTexture, "CENTER", -61, -15);
  end
end)

-- Target Frame
TargetFrame:SetScale(ns.unitframesTargetScale)
hooksecurefunc("TargetFrame_UpdateLevelTextAnchor",  function(self, targetLevel)
  if ( targetLevel >= 100 ) then
    self.levelText:SetPoint("CENTER", 62, -15);
  else
    self.levelText:SetPoint("CENTER", 62, -15);
  end
end)

-- Focus Frame
FocusFrame:SetScale(ns.unitframesFocusScale)


-- Party
hooksecurefunc("PartyMemberFrame_UpdateMember", function(self)
	if self:IsShown() then
		for i = 1, MAX_PARTY_MEMBERS do
			_G["PartyMemberFrame"..i]:SetScale(ns.unitframesPartyScale)
		end	
		PartyMemberFrame1:SetPoint(db.unitframes.party.position.relAnchor, UIParent, db.unitframes.party.position.offSetX, db.unitframes.party.position.offSetY);
	end
end)
	
if not ArenaEnemyFrame1 then
	return true
end

-- Arena
for i = 1, MAX_ARENA_ENEMIES do
	_G["ArenaPrepFrame"..i]:SetScale(ns.unitframesArenaScale)
	_G["ArenaEnemyFrame"..i]:SetScale(ns.unitframesArenaScale)
end	

-- Boss
if (event == "INSTANCE_ENCOUNTER_ENGAGE_UNIT") then
	for i = 1, MAX_BOSS_FRAMES do
		_G["Boss"..i.."TargetFrame"]:SetScale(ns.unitframesBossScale)
	end
end
Into a hooksecurfunc like
Code:
hooksecurefunc("UnitFrame_Update",  function(self, level, targetLevel, isParty, isBossFrame)
 -- code here
end)
Just wondering if it would make things work smoother?

Coke
  Reply With Quote
12-01-14, 01:21 PM   #13
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
No. When defining variables, you should limit them to the narrowest scope necessary. Likewise, when hooking functions, you should limit your hooks to the most specific functions necessary. If you're hooking a function for the purpose of moving the level text, you should hook the actual function that moves the level text, not some other function that calls the function that moves the level text, particularly in this case where you're running different code inside each different function hook. If you hooked UnitFrame_Update instead, you'd have to add additional logic to check which unit was being updated.

Some other things:

Code:
hooksecurefunc("PartyMemberFrame_UpdateMember", function(self)
	if self:IsShown() then
		for i = 1, MAX_PARTY_MEMBERS do
			_G["PartyMemberFrame"..i]:SetScale(ns.unitframesPartyScale)
		end	
		PartyMemberFrame1:SetPoint(db.unitframes.party.position.relAnchor, UIParent, db.unitframes.party.position.offSetX, db.unitframes.party.position.offSetY);
	end
end)
There are several problems with this:

You cannot move unit frames while in combat, so you need to check for InCombatLockdown() before attempting to move a unit frame.

PartyMemberFrame_UpdateMember doesn't move the party frames, so hooking it is probably not a very good way to move the party frames. I don't know that the default UI ever moves the party frames, but if it does, you should find the function that actually does it, and hook that instead. If it doesn't, then you can just move them once and not worry about it.

PartyMemberFrame_UpdateMember is called for each frame being updated, but you're updating all the frames there, leading to a lot of extra updates. Also, the default UI never calls SetScale on the party frames, so you can just do that once, as with the boss frames.

Code:
if not ArenaEnemyFrame1 then
	return true
end
The arena frames are created by the Blizzard_ArenaUI "addon" which is loaded on demand, so unless you are in an arena when you log in, they will probably never exist when your addon loads, so nothing after this check will ever execute.

Instead, if the arena frames don't exist yet, you should delay dealing with them until they are created:

Code:
local function ScaleArenaFrames()
	for i = 1, MAX_ARENA_ENEMIES do
		_G["ArenaPrepFrame"..i]:SetScale(ns.unitframesArenaScale)
		_G["ArenaEnemyFrame"..i]:SetScale(ns.unitframesArenaScale)
	end
end

if IsAddOnLoaded("Blizzard_ArenaUI") then
	ScaleArenaFrames()
else
	local f = CreateFrame("Frame")
	f:RegisterEvent("ADDON_LOADED")
	f:SetScript("OnEvent", function(self, event, addon)
		if addon == "Blizzard_ArenaUI" then
			self:UnregisterEvent(event)
			ScaleArenaFrames()
		end
	end)
end
Another problem with your arena frame check is you put the code to scale the boss frames after it, meaning that isn't getting run either.

And as for the boss frame code itself:

Code:
if (event == "INSTANCE_ENCOUNTER_ENGAGE_UNIT") then
	for i = 1, MAX_BOSS_FRAMES do
		_G["Boss"..i.."TargetFrame"]:SetScale(ns.unitframesBossScale)
	end
end
This code isn't (I hope) running inside an event handler -- it's just in the main chunk of your file. There is no "event" variable there, so even if this code was being run, that "if" check would fail since its value is effectively nil, which doesn't match "INSTANCE_ENCOUNTER_ENGAGE_UNIT".

However, the boss frames are already created when your addon loads, so you can just run your "for" loop right away; there's no need to delay or listen for any events.

Overall your coding skills are improving. You're just overthinking/overcomplicating things here.
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote
12-01-14, 03:38 PM   #14
cokedrivers
A Rage Talon Dragon Guard
 
cokedrivers's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2009
Posts: 325
Thank You again like always for the help.

I went with a simple approach when creating this new UI. If I would have kept on with BasicUI I would be totally lost. im using the (local _, ns = ...) for my variables then as you see in the code ns.variable.

Everything so far seems to be going better no errors with boss fights (just doing the "for" instead of a function works great.

Here is what my unitframe.lua looks like now.

and these are the options for it:
Code:
ns.unitframesEnable = true
ns.unitframesCastbarScale = 1.193
ns.unitframesPlayerScale = 1.193	-- Player Frame Scale
ns.unitframesTargetScale = 1.193	-- Target Frame Scale
ns.unitframesFocusScale = 1.193		-- Focus Frame Scale
ns.unitframesPartyScale = 1.193
ns.unitframesPartyPosition = {relAnchor = "TOPLEFT", offSetX = 10, offSetY = -200}
ns.unitframesArenaScale = 1.193
ns.unitframesBossScale = 1.193
Again thanks for the help.

Coke
  Reply With Quote
12-01-14, 07:18 PM   #15
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Code:
if InCombatLockdown() == true then
        return
else
        PartyMemberFrame1:SetPoint(ns.unitframesPartyPosition.relAnchor, UIParent, ns.unitframesPartyPosition.offSetX, ns.unitframesPartyPosition.offSetY);
end
That "if" check will never pass, since you have a brief window when addons load to execute code that can't be run in combat. It's also good that it won't pass, because that "return" would stop execution of the rest of file, not just the "if/else" block. Remember, "return" stops execution of a function, and as far as WoW is concerned your whole file is just one big function. If your addon has two files, for example, you can think of it like this:

Code:
local addonTable = {}

local func1 = function(addonName, addonTable)
    -- file 1 contents are here
end

func1("MyAddon", addonTable)

local func2 = function(addonName, addonTable)
    -- file 2 contents are here
end

func2("MyAddon", addonTable)
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote
12-01-14, 09:00 PM   #16
cokedrivers
A Rage Talon Dragon Guard
 
cokedrivers's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2009
Posts: 325
so would something like this work?
Code:
local partyPosition = CreateFrame("Frame")
partyPosition:RegisterEvent("PARTY_MEMBERS_CHANGED")
partyPosition:SetScript("OnEvent", function(self, event)
	if (event == "PARTY_MEMBERS_CHANGED") and not InCombatLockdown() then
		PartyMemberFrame1:SetPoint(ns.unitframesPartyPosition.relAnchor, UIParent, ns.unitframesPartyPosition.offSetX, ns.unitframesPartyPosition.offSetY);
	end
end)
  Reply With Quote
12-02-14, 10:40 PM   #17
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
I think you missed the point of my last two posts, which is that as far as I can tell, the default UI never moves the party frames, so you do not need to hook any functions or wait for any events to move them. Just move them, without any wrapping:

Code:
PartyMemberFrame1:SetPoint(ns.unitframesPartyPosition.relAnchor, UIParent, ns.unitframesPartyPosition.offSetX, ns.unitframesPartyPosition.offSetY)
That's all you need.
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote
12-03-14, 11:51 PM   #18
cokedrivers
A Rage Talon Dragon Guard
 
cokedrivers's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2009
Posts: 325
Originally Posted by Phanx View Post
Also, the default UI never calls SetScale on the party frames, so you can just do that once, as with the boss frames.
I FINALLY took the time and read what you posted instead of glancing over it.

Thank You
Coke
  Reply With Quote
12-04-14, 11:53 PM   #19
cokedrivers
A Rage Talon Dragon Guard
 
cokedrivers's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2009
Posts: 325
Thank You

Phanx I just want to say Thank You for the help you have given me with coding, below is a screenshot of all the work (even tho to most it will look like the normal wow UI)

Coke
Attached Thumbnails
Click image for larger version

Name:	WoWScrnShot_120414_214737.jpg
Views:	227
Size:	502.1 KB
ID:	8341  
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Centering Level Text


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off