Thread Tools Display Modes
07-23-16, 08:07 AM   #1
Layback_
An Onyxian Warder
Join Date: Feb 2016
Posts: 358
Setting frame levels

Hi all,

Since yesterday, I have started to create my own unitframe with oUF which I am feeling a lot of fun !!

I Just got some questions regarding frame creation(?).

Let's have a look at the code first:
Lua Code:
  1. A.CreateHealth = function(f, unit)
  2.     A.CreateHealthBar(f, unit);
  3. end
  4.  
  5. A.CreateHealthBar = function(f, unit)
  6.     local Health = CreateFrame("StatusBar", f:GetName() .. "HealthBar", f);
  7.     Health:SetStatusBarTexture(HEALTH_BAR);
  8.     Health:SetStatusBarColor(0, 0, 0, 1);
  9.     Health:SetFrameLevel(3);
  10.  
  11.     if unit == "player" then
  12.         Health:SetPoint("TOPRIGHT", f, "TOPRIGHT", -1, -1);
  13.         Health:SetSize(f:GetWidth() - 12, f:GetHeight() - 12);
  14.     end
  15.  
  16.     local backdrop = CreateFrame("Frame", nil, Health);
  17.     backdrop:SetSize(Health:GetWidth() + 2, Health:GetHeight() + 2);
  18.     backdrop:SetPoint("CENTER");
  19.     backdrop:SetBackdrop({
  20.         edgeFile = BACKDROP,
  21.         edgeSize = 1,
  22.     });
  23.     backdrop:SetBackdropBorderColor(1, 0, 0, 1);
  24.  
  25.     Health.bg = Health:CreateTexture(nil, "BACKGROUND");
  26.     Health.bg:SetAllPoints(true);
  27.     Health.bg:SetTexture(BACKDROP);
  28.     Health.bg:SetVertexColor(0.5, 0.5, 0.5, 1);
  29.  
  30.     f.Health = Health;
  31.     f.Health.bg = Health.bg;
  32. end
  33.  
  34. A.CreatePower = function(f, unit)
  35.     A.CreatePowerBar(f, unit);
  36. end
  37.  
  38. A.CreatePowerBar = function(f, unit)
  39.     local Power = CreateFrame("StatusBar", f:GetName() .. "PowerBar", f);
  40.     Power:SetStatusBarTexture(HEALTH_BAR);
  41.     Power:SetStatusBarColor(1, 1, 1, 1);
  42.     Power:SetFrameLevel(2);
  43.  
  44.     if unit == "player" then
  45.         Power:SetPoint("BOTTOMLEFT", f, "BOTTOMLEFT", 1, 1);
  46.         Power:SetSize(f:GetWidth() - 12, f:GetHeight() - 12);
  47.     end
  48.  
  49.     local backdrop = CreateFrame("Frame", nil, Power);
  50.     backdrop:SetSize(Power:GetWidth() + 2, Power:GetHeight() + 2);
  51.     backdrop:SetPoint("CENTER");
  52.     backdrop:SetBackdrop({
  53.         edgeFile = BACKDROP,
  54.         edgeSize = 1,
  55.     });
  56.     backdrop:SetBackdropBorderColor(0, 0, 1, 1);
  57.  
  58.     f.Power = Power;
  59. end

The code above currently results in the following:

Health Bar - Black status bar with Red border and Grey background
Power Bar - White status bar with Blue border (currently have no background)


SO..... here's my question.

1. Would it be possible to create a border for status bar frame without creating another frame (which is called 'backdrop' in this case).

2. As you can see, Power Bar's border is sitting on top of the Health Bar's background. What would be the best solution to fix this problem?
  Reply With Quote
07-23-16, 10:53 AM   #2
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,313
1: If you're using the backdrop system, just set it on the StatusBar. You can also create textures directly on them so there's no need to create container frames for them and waste resources.

2: You have your health bar at FrameLevel 3 and power bar at FrameLevel 2. When you create a frame that's a child of another, it automatically gets its parent's FrameLevel+1. This means the container frames you use for textures and backdrops for the power bar share the same FrameLevel with your health bar and are melding together with it. This could be fixed easily by following the answer above.
Normally, you shouldn't mess with FrameLevel unless you need to bump it up by a specific amount. Don't set it to a solid number. For example, leave your power bar at its default and do this instead on your health bar: Health:SetFrameLevel(Health:GetFrameLevel()+1)
__________________
WoWInterface AddOns
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)

Last edited by SDPhantom : 07-23-16 at 11:00 AM.
  Reply With Quote
07-23-16, 10:56 PM   #3
Layback_
An Onyxian Warder
Join Date: Feb 2016
Posts: 358
Originally Posted by SDPhantom View Post
1: If you're using the backdrop system, just set it on the StatusBar. You can also create textures directly on them so there's no need to create container frames for them and waste resources.

2: You have your health bar at FrameLevel 3 and power bar at FrameLevel 2. When you create a frame that's a child of another, it automatically gets its parent's FrameLevel+1. This means the container frames you use for textures and backdrops for the power bar share the same FrameLevel with your health bar and are melding together with it. This could be fixed easily by following the answer above.
Normally, you shouldn't mess with FrameLevel unless you need to bump it up by a specific amount. Don't set it to a solid number. For example, leave your power bar at its default and do this instead on your health bar: Health:SetFrameLevel(Health:GetFrameLevel()+1)
Hi SDPhantom,

Based on your advice, I made some modifications, but I'm unsure whether I did correctly or not.

Please have a look at the code below:
Lua Code:
  1. A.CreateHealth = function(f, unit)
  2.     A.CreateHealthBar(f, unit);
  3.     A.CreateHealthText(f, unit);
  4. end
  5.  
  6. A.CreateHealthBar = function(f, unit)
  7.     local Health = CreateFrame("StatusBar", f:GetName() .. "HealthBar", f);
  8.     Health:SetFrameLevel(Health:GetFrameLevel() + 1);
  9.     Health:SetStatusBarTexture(HEALTH_BAR);
  10.     Health:SetStatusBarColor(0, 0, 0, 1);
  11.  
  12.     if unit == "player" then
  13.         Health:SetPoint("TOPRIGHT", f, "TOPRIGHT", 0, 0);
  14.         Health:SetSize(f:GetWidth() - 10, f:GetHeight() - 10);
  15.     end
  16.  
  17.     Health:SetBackdrop({
  18.         edgeFile = BACKDROP,
  19.         edgeSize = 1,
  20.         insets = {
  21.             left = 1,
  22.             right = 1,
  23.             top = 1,
  24.             bottom = 1,
  25.         },
  26.     });
  27.     Health:SetBackdropBorderColor(1, 0, 0, 1);
  28.  
  29.     Health.bg = Health:CreateTexture(nil, "BACKGROUND");
  30.     Health.bg:SetAllPoints(true);
  31.     Health.bg:SetTexture(BACKDROP);
  32.     Health.bg:SetVertexColor(0.5, 0.5, 0.5, 1);
  33.  
  34.     f.Health = Health;
  35.     f.Health.bg = Health.bg;
  36. end
  37.  
  38. A.CreateHealthText = function(f, unit)
  39.  
  40. end
  41.  
  42. A.CreatePower = function(f, unit)
  43.     A.CreatePowerBar(f, unit);
  44.     A.CreatePowerText(f, unit);
  45. end
  46.  
  47. A.CreatePowerBar = function(f, unit)
  48.     local Power = CreateFrame("StatusBar", f:GetName() .. "PowerBar", f);
  49.     Power:SetFrameLevel(f.Health:GetFrameLevel() - 1);
  50.     Power:SetStatusBarTexture(HEALTH_BAR);
  51.     Power:SetStatusBarColor(1, 1, 1, 1);
  52.  
  53.     if unit == "player" then
  54.         Power:SetPoint("BOTTOMLEFT", f, "BOTTOMLEFT", 0, 0);
  55.         Power:SetSize(f:GetWidth() - 10, f:GetHeight() - 10);
  56.     end
  57.  
  58.     Power:SetBackdrop({
  59.         edgeFile = BACKDROP,
  60.         edgeSize = 1,
  61.         insets = {
  62.             left = 1,
  63.             right = 1,
  64.             top = 1,
  65.             bottom = 1,
  66.         },
  67.     });
  68.     Power:SetBackdropBorderColor(0, 0, 1, 1);
  69.  
  70.     f.Power = Power;
  71. end
  72.  
  73. A.CreatePowerText = function(f, unit)
  74.  
  75. end

This currently results in...



The frame level issue has been successfully fixed(?), but the border issue is still remaining.

The backdrop has been added directly to the status bar frame, but it seems to be sitting right behind the status bar so that the border is only shown when the unit loses the health.
(Which is same for PowerBar as well)

I have gone through the API to review how SetBackdrop function works and could not figure it out

The image file that I used for edgeFile can be found on the attachment.
(Which is just 16x16 white square in fact...)
Attached Files
File Type: blp backdrop.BLP (1.3 KB, 91 views)
  Reply With Quote
07-24-16, 02:33 AM   #4
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
You can get the backdrop frame with this call, then override the frame level manually like this:

Lua Code:
  1. local backdrop = Health:GetBackdrop()
  2. backdrop:SetFrameLevel()

But Backdrop have a lot of issues, thats why i like to avoid using it.
  Reply With Quote
07-24-16, 02:43 AM   #5
Layback_
An Onyxian Warder
Join Date: Feb 2016
Posts: 358
Originally Posted by Resike View Post
You can get the backdrop frame with this call, then override the frame level manually like this:

Lua Code:
  1. local backdrop = Health:GetBackdrop()
  2. backdrop:SetFrameLevel()

But Backdrop have a lot of issues, thats why i like to avoid using it.
Hi Resike,

If that is the issue, what would be the best solution to draw a border with a .blp file (16x16 white square) that I attached?

Last edited by Layback_ : 07-24-16 at 02:48 AM.
  Reply With Quote
07-24-16, 04:32 AM   #6
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
Originally Posted by Layback_ View Post
Hi Resike,

If that is the issue, what would be the best solution to draw a border with a .blp file (16x16 white square) that I attached?
Thats a bit more advanced stuff, I don't think you need that right now. Also it might be useless since your border is very simple

But basically you split up the texture phisically or virtuaally with SetTextCoords to 8 parts (9 if you also need to middle) and SetPointing the textures yourself. With this method you gain full control over the textures and pointing and scaling wise gives you much better accuracy, allowing to create absolutely non-blurry pixel perfection border images at any scale level with even very narrow edge files.

http://tr1.cbsistatic.com/hub/i/2015...indowSmall.gif
  Reply With Quote
07-24-16, 06:08 AM   #7
Layback_
An Onyxian Warder
Join Date: Feb 2016
Posts: 358
Originally Posted by Resike View Post
Thats a bit more advanced stuff, I don't think you need that right now. Also it might be useless since your border is very simple

But basically you split up the texture phisically or virtuaally with SetTextCoords to 8 parts (9 if you also need to middle) and SetPointing the textures yourself. With this method you gain full control over the textures and pointing and scaling wise gives you much better accuracy, allowing to create absolutely non-blurry pixel perfection border images at any scale level with even very narrow edge files.

http://tr1.cbsistatic.com/hub/i/2015...indowSmall.gif
Hi again Resike,

Actually, the current border is just for testing and it would possibly be changed later as I make a solid decision.

Firstly, I have tried with your first method
Lua Code:
  1. local backdrop = Health:GetBackdrop()
  2. backdrop:SetFrameLevel(Health:GetFrameLevel() + 1)

Unfortunately, it doesn't seem to be working as it passes me an error saying that SetFrameLevel function cannot be applied to backdrop.

Secondly, about your second option, u mean that I'll have to create 8 different textures around status bar like top-left corner, top, top-right corner, right, bottom-right corner, bottom, bottom-left corner and left?
  Reply With Quote
07-24-16, 06:45 AM   #8
Vrul
A Scalebane Royal Guard
 
Vrul's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2007
Posts: 404
For frames you use the methods SetFrameLevel and SetFrameStrata to adjust how they're drawn relative to others. For textures (like your backdrop) you would use the method SetDrawLayer to determine how they are drawn in respect to each other within a parent frame.
  Reply With Quote
07-24-16, 09:16 AM   #9
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
Originally Posted by Vrul View Post
For frames you use the methods SetFrameLevel and SetFrameStrata to adjust how they're drawn relative to others. For textures (like your backdrop) you would use the method SetDrawLayer to determine how they are drawn in respect to each other within a parent frame.
But the backdrop is a very special object it's not a frame nor a texture, so you lose any subfunction to properly modify it.
  Reply With Quote
07-24-16, 09:18 AM   #10
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
Originally Posted by Layback_ View Post
Hi again Resike,

Actually, the current border is just for testing and it would possibly be changed later as I make a solid decision.

Firstly, I have tried with your first method
Lua Code:
  1. local backdrop = Health:GetBackdrop()
  2. backdrop:SetFrameLevel(Health:GetFrameLevel() + 1)

Unfortunately, it doesn't seem to be working as it passes me an error saying that SetFrameLevel function cannot be applied to backdrop.

Secondly, about your second option, u mean that I'll have to create 8 different textures around status bar like top-left corner, top, top-right corner, right, bottom-right corner, bottom, bottom-left corner and left?
Yes. I was wrong then, seems like you can't even apply this to a backdrop object then.

I can give you an example to save some typing:

Lua Code:
  1. frame.name.edge = CreateFrame("Frame", nil, frame.name)
  2. frame.name.edge:SetFrameStrata(frame.strata)
  3. frame.name.edge:SetFrameLevel(18)
  4.  
  5. frame.name.edge.tl = frame.name.edge:CreateTexture(nil, "Border")
  6. frame.name.edge.tl:SetTexture("Interface\\AddOns\\ZPerl2\\Textures\\UI-Tooltip-TL")
  7. frame.name.edge.tl:SetSize(8, 8)
  8. frame.name.edge.tl:SetPoint("TopLeft", frame.name, "TopLeft", -1, 1)
  9. frame.name.edge.tl:SetVertexColor(0.5, 0.5, 0.5, 1)
  10.  
  11. frame.name.edge.tr = frame.name.edge:CreateTexture(nil, "Border")
  12. frame.name.edge.tr:SetTexture("Interface\\AddOns\\ZPerl2\\Textures\\UI-Tooltip-TR")
  13. frame.name.edge.tr:SetSize(8, 8)
  14. frame.name.edge.tr:SetPoint("TopRight", frame.name, "TopRight", 1, 1)
  15. frame.name.edge.tr:SetVertexColor(0.5, 0.5, 0.5, 1)
  16.  
  17. frame.name.edge.bl = frame.name.edge:CreateTexture(nil, "Border")
  18. frame.name.edge.bl:SetTexture("Interface\\AddOns\\ZPerl2\\Textures\\UI-Tooltip-BL")
  19. frame.name.edge.bl:SetSize(8, 8)
  20. frame.name.edge.bl:SetPoint("BottomLeft", frame.name, "BottomLeft", -1, -1)
  21. frame.name.edge.bl:SetVertexColor(0.5, 0.5, 0.5, 1)
  22.  
  23. frame.name.edge.br = frame.name.edge:CreateTexture(nil, "Border")
  24. frame.name.edge.br:SetTexture("Interface\\AddOns\\ZPerl2\\Textures\\UI-Tooltip-BR")
  25. frame.name.edge.br:SetSize(8, 8)
  26. frame.name.edge.br:SetPoint("BottomRight", frame.name, "BottomRight", 1, -1)
  27. frame.name.edge.br:SetVertexColor(0.5, 0.5, 0.5, 1)
  28.  
  29. frame.name.edge.t = frame.name.edge:CreateTexture(nil, "Border")
  30. frame.name.edge.t:SetTexture("Interface\\AddOns\\ZPerl2\\Textures\\UI-Tooltip-T")
  31. frame.name.edge.t:SetSize(8, 8)
  32. frame.name.edge.t:SetPoint("TopLeft", frame.name.edge.tl, "TopRight", 0, 0)
  33. frame.name.edge.t:SetPoint("TopRight", frame.name.edge.tr, "TopLeft", 0, 0)
  34. frame.name.edge.t:SetVertexColor(0.5, 0.5, 0.5, 1)
  35.  
  36. frame.name.edge.b = frame.name.edge:CreateTexture(nil, "Border")
  37. frame.name.edge.b:SetTexture("Interface\\AddOns\\ZPerl2\\Textures\\UI-Tooltip-B")
  38. frame.name.edge.b:SetSize(8, 8)
  39. frame.name.edge.b:SetPoint("TopLeft", frame.name.edge.bl, "TopRight", 0, 0)
  40. frame.name.edge.b:SetPoint("TopRight", frame.name.edge.br, "TopLeft", 0, 0)
  41. frame.name.edge.b:SetVertexColor(0.5, 0.5, 0.5, 1)
  42.  
  43. frame.name.edge.l = frame.name.edge:CreateTexture(nil, "Border")
  44. frame.name.edge.l:SetTexture("Interface\\AddOns\\ZPerl2\\Textures\\UI-Tooltip-L")
  45. frame.name.edge.l:SetSize(8, 8)
  46. frame.name.edge.l:SetPoint("TopLeft", frame.name.edge.tl, "BottomLeft", 0, 0)
  47. frame.name.edge.l:SetPoint("BottomLeft", frame.name.edge.bl, "TopLeft", 0, 0)
  48. frame.name.edge.l:SetVertexColor(0.5, 0.5, 0.5, 1)
  49.  
  50. frame.name.edge.r = frame.name.edge:CreateTexture(nil, "Border")
  51. frame.name.edge.r:SetTexture("Interface\\AddOns\\ZPerl2\\Textures\\UI-Tooltip-R")
  52. frame.name.edge.r:SetSize(8, 8)
  53. frame.name.edge.r:SetPoint("TopRight", frame.name.edge.tr, "BottomRight", 0, 0)
  54. frame.name.edge.r:SetPoint("BottomRight", frame.name.edge.br, "TopRight", 0, 0)
  55. frame.name.edge.r:SetVertexColor(0.5, 0.5, 0.5, 1)

Last edited by Resike : 07-24-16 at 09:21 AM.
  Reply With Quote
07-24-16, 10:09 AM   #11
Vrul
A Scalebane Royal Guard
 
Vrul's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2007
Posts: 404
I was thinking more along the lines of:
Code:
local function ChangeDrawLayer(regionType, oldDrawLayer, newDrawLayer, ...)
	for index = 1, select('#', ...) do
		local region = select(index, ...)
		if region:IsObjectType(regionType) and region:GetDrawLayer() == oldDrawLayer then
			region:SetDrawLayer(newDrawLayer)
		end
	end
end

A.CreateHealth = function(f, unit)
    A.CreateHealthBar(f, unit);
    A.CreateHealthText(f, unit);
end
 
A.CreateHealthBar = function(f, unit)
    local Health = CreateFrame("StatusBar", f:GetName() .. "HealthBar", f);
    Health:SetFrameLevel(Health:GetFrameLevel() + 1);
    Health:SetStatusBarTexture(HEALTH_BAR);
    Health:SetStatusBarColor(0, 0, 0, 1);
 
    if unit == "player" then
        Health:SetPoint("TOPRIGHT", f, "TOPRIGHT", 0, 0);
        Health:SetSize(f:GetWidth() - 10, f:GetHeight() - 10);
    end
 
    Health:SetBackdrop({
        edgeFile = BACKDROP,
        edgeSize = 1,
        insets = {
            left = 1,
            right = 1,
            top = 1,
            bottom = 1,
        },
    });
    Health:SetBackdropBorderColor(1, 0, 0, 1);

    ChangeDrawLayer('Texture', 'BORDER', 'OVERLAY', Health:GetRegions())

    Health.bg = Health:CreateTexture(nil, "BACKGROUND");
    Health.bg:SetAllPoints(true);
    Health.bg:SetTexture(BACKDROP);
    Health.bg:SetVertexColor(0.5, 0.5, 0.5, 1);
 
    f.Health = Health;
    f.Health.bg = Health.bg;
end
 
A.CreateHealthText = function(f, unit)
 
end
 
A.CreatePower = function(f, unit)
    A.CreatePowerBar(f, unit);
    A.CreatePowerText(f, unit);
end
 
A.CreatePowerBar = function(f, unit)
    local Power = CreateFrame("StatusBar", f:GetName() .. "PowerBar", f);
    Power:SetFrameLevel(f.Health:GetFrameLevel() - 1);
    Power:SetStatusBarTexture(HEALTH_BAR);
    Power:SetStatusBarColor(1, 1, 1, 1);
 
    if unit == "player" then
        Power:SetPoint("BOTTOMLEFT", f, "BOTTOMLEFT", 0, 0);
        Power:SetSize(f:GetWidth() - 10, f:GetHeight() - 10);
    end
 
    Power:SetBackdrop({
        edgeFile = BACKDROP,
        edgeSize = 1,
        insets = {
            left = 1,
            right = 1,
            top = 1,
            bottom = 1,
        },
    });
    Power:SetBackdropBorderColor(0, 0, 1, 1);

    ChangeDrawLayer('Texture', 'BORDER', 'OVERLAY', Power:GetRegions())
 
    f.Power = Power;
end
 
A.CreatePowerText = function(f, unit)
 
end
  Reply With Quote
07-24-16, 07:48 PM   #12
Layback_
An Onyxian Warder
Join Date: Feb 2016
Posts: 358
I have tried both Resike's and Vrul's approach and they both worked perfectly !

So... I did move on to next step to display unit's health text on top of the health bar and it's having the issue.

Lua Code:
  1. A.CreateHealth = function(f, unit)
  2.     A.CreateHealthBar(f, unit);
  3.  
  4.     if unit == "player" or unit == "target" then
  5.         A.CreateHealthText(f, unit);
  6.     end
  7. end
  8.  
  9. A.CreateHealthBar = function(f, unit)
  10.     local Health = CreateFrame("StatusBar", f:GetName() .. "HealthBar", f);
  11.     Health:SetFrameLevel(Health:GetFrameLevel() + 1);
  12.     Health:SetStatusBarTexture(HEALTH_BAR);
  13.     Health:SetStatusBarColor(0, 0, 0, 1);
  14.  
  15.     if unit == "player" then
  16.         Health:SetPoint("TOPRIGHT", f, "TOPRIGHT", -1, -1);
  17.         Health:SetSize(f:GetWidth() - 12, f:GetHeight() - 12);
  18.     elseif unit == "target" then
  19.         Health:SetPoint("TOPLEFT", f, "TOPLEFT", 1, -1);
  20.         Health:SetSize(f:GetWidth() - 12, f:GetHeight() - 12);
  21.     elseif unit == "targettarget" then
  22.         Health:SetPoint("TOP", f, "TOP", 0, -1);
  23.         Health:SetSize(f:GetWidth() - 22, f:GetHeight() - 12);
  24.     end
  25.  
  26.     A.CreateBorder(Health, "Border", BACKDROP, {1, 1}, {"BOTTOMRIGHT", Health, "TOPLEFT", 0, 0}, {1, 0, 0, 1});
  27.     A.CreateBorder(Health, "Border", BACKDROP, {1, 1}, {"BOTTOMLEFT", Health, "TOPRIGHT", 0, 0}, {1, 0, 0, 1});
  28.     A.CreateBorder(Health, "Border", BACKDROP, {1, 1}, {"TOPRIGHT", Health, "BOTTOMLEFT", 0, 0}, {1, 0, 0, 1});
  29.     A.CreateBorder(Health, "Border", BACKDROP, {1, 1}, {"TOPLEFT", Health, "BOTTOMRIGHT", 0, 0}, {1, 0, 0, 1});
  30.     A.CreateBorder(Health, "Border", BACKDROP, {Health:GetWidth(), 1}, {"BOTTOM", Health, "TOP", 0, 0}, {1, 0, 0, 1});
  31.     A.CreateBorder(Health, "Border", BACKDROP, {Health:GetWidth(), 1}, {"TOP", Health, "BOTTOM", 0, 0}, {1, 0, 0, 1});
  32.     A.CreateBorder(Health, "Border", BACKDROP, {1, Health:GetHeight()}, {"RIGHT", Health, "LEFT", 0, 0}, {1, 0, 0, 1});
  33.     A.CreateBorder(Health, "Border", BACKDROP, {1, Health:GetHeight()}, {"LEFT", Health, "RIGHT", 0, 0}, {1, 0, 0, 1});
  34.  
  35.     Health.bg = Health:CreateTexture(nil, "BACKGROUND");
  36.     Health.bg:SetAllPoints(true);
  37.     Health.bg:SetTexture(BACKDROP);
  38.     Health.bg:SetVertexColor(0.5, 0.5, 0.5, 1);
  39.  
  40.     f.Health = Health;
  41.     f.Health.bg = Health.bg;
  42. end
  43.  
  44. A.CreateHealthText = function(f, unit)
  45.     local HealthValue = f:CreateFontString(f.Health:GetName() .. "Text", "OVERLAY");
  46.     HealthValue:SetFont(VALUE_FONT, 12);
  47.     HealthValue:SetTextColor(1, 1, 1, 1);
  48.  
  49.     if unit == "player" then
  50.         HealthValue:SetPoint("BOTTOMRIGHT", f.Health, "BOTTOMRIGHT", -1, 2);
  51.  
  52.         f:Tag(HealthValue, "[perhp]% | [curhp]");
  53.     else
  54.         HealthValue:SetPoint("BOTTOMLEFT", f.Health, "BOTTOMLEFT", 0, 2);
  55.  
  56.         f:Tag(HealthValue, "[curhp] | [perhp]%");
  57.     end
  58.  
  59.     f.HealthValue = HealthValue;
  60. end
  61.  
  62. A.CreatePower = function(f, unit)
  63.     A.CreatePowerBar(f, unit);
  64.  
  65.     if unit == "player" or unit == "target" then
  66.         A.CreatePowerText(f, unit);
  67.     end
  68. end
  69.  
  70. A.CreatePowerBar = function(f, unit)
  71.     local Power = CreateFrame("StatusBar", f:GetName() .. "PowerBar", f);
  72.     Power:SetFrameLevel(f.Health:GetFrameLevel() - 1);
  73.     Power:SetStatusBarTexture(HEALTH_BAR);
  74.     Power:SetStatusBarColor(1, 1, 1, 1);
  75.  
  76.     if unit == "player" then
  77.         Power:SetPoint("BOTTOMLEFT", f, "BOTTOMLEFT", 1, 1);
  78.         Power:SetSize(f:GetWidth() - 12, f:GetHeight() - 12);
  79.     elseif unit == "target" then
  80.         Power:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", -1, 1);
  81.         Power:SetSize(f:GetWidth() - 12, f:GetHeight() - 12);
  82.     elseif unit == "targettarget" then
  83.         Power:SetPoint("BOTTOM", f, "BOTTOM", 0, 1);
  84.         Power:SetSize(f:GetWidth() - 2, f:GetHeight() - 12);
  85.     end
  86.  
  87.     A.CreateBorder(Power, "Border", BACKDROP, {1, 1}, {"BOTTOMRIGHT", Power, "TOPLEFT", 0, 0}, {0, 0, 1, 1});
  88.     A.CreateBorder(Power, "Border", BACKDROP, {1, 1}, {"BOTTOMLEFT", Power, "TOPRIGHT", 0, 0}, {0, 0, 1, 1});
  89.     A.CreateBorder(Power, "Border", BACKDROP, {1, 1}, {"TOPRIGHT", Power, "BOTTOMLEFT", 0, 0}, {0, 0, 1, 1});
  90.     A.CreateBorder(Power, "Border", BACKDROP, {1, 1}, {"TOPLEFT", Power, "BOTTOMRIGHT", 0, 0}, {0, 0, 1, 1});
  91.     A.CreateBorder(Power, "Border", BACKDROP, {Power:GetWidth(), 1}, {"BOTTOM", Power, "TOP", 0, 0}, {0, 0, 1, 1});
  92.     A.CreateBorder(Power, "Border", BACKDROP, {Power:GetWidth(), 1}, {"TOP", Power, "BOTTOM", 0, 0}, {0, 0, 1, 1});
  93.     A.CreateBorder(Power, "Border", BACKDROP, {1, Power:GetHeight()}, {"RIGHT", Power, "LEFT", 0, 0}, {0, 0, 1, 1});
  94.     A.CreateBorder(Power, "Border", BACKDROP, {1, Power:GetHeight()}, {"LEFT", Power, "RIGHT", 0, 0}, {0, 0, 1, 1});
  95.  
  96.     A.ApplyOptions(Power, "frequentUpdates");
  97.  
  98.     f.Power = Power;
  99. end
  100.  
  101. A.CreatePowerText = function(f, unit)
  102.  
  103. end

A.CreateHealthText function is the one that creates the health text and here's the result.



The health text is surely created as I could've find it via '/fstack', but it is hidden at the back.

I have made few guesses on what is causing this issue.

1. Because Health frame is set to have higher frame level than its parent frame, so that the health text is not drawn on Health frame. Thus, I did comment out

Health:SetFrameLevel(Health:GetFrameLevel() + 1);

but it did not seem to be working.

2. Because the HealthValue is the child of base frame, f, not Health frame, f.Health.

Actually, changing

f:CreateFontString(f.Health:GetName() .. "Text", "OVERLAY");

to

f.Health:CreateFontString(f.Health:GetName() .. "Text", "OVERLAY");

did solve the trick, but I personally think this is not a good coding in terms of memory efficiency(?).

Could I get some advice regarding this?

Last edited by Layback_ : 07-24-16 at 08:03 PM.
  Reply With Quote
07-26-16, 11:28 AM   #13
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,313
Originally Posted by Layback_ View Post
2. Because the HealthValue is the child of base frame, f, not Health frame, f.Health.

Actually, changing

f:CreateFontString(f.Health:GetName() .. "Text", "OVERLAY");

to

f.Health:CreateFontString(f.Health:GetName() .. "Text", "OVERLAY");

did solve the trick, but I personally think this is not a good coding in terms of memory efficiency.
This guess is correct and it has no impact to performance as it's just creating it as a child of a different frame. If you're talking about preforming the same indexing operation repeatedly, it depends on how frequent the function runs and how often you do it in the function. Normally, since this is just at frame creation, it should be fine as-is. In this specific example though, you can use the $parent tag at frame creation to reference the name of the frame's parent.
Code:
f.Health:CreateFontString("$parentText", "OVERLAY");
__________________
WoWInterface AddOns
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)

Last edited by SDPhantom : 07-26-16 at 11:42 AM.
  Reply With Quote
07-26-16, 04:54 PM   #14
Layback_
An Onyxian Warder
Join Date: Feb 2016
Posts: 358
Originally Posted by SDPhantom View Post
This guess is correct and it has no impact to performance as it's just creating it as a child of a different frame. If you're talking about preforming the same indexing operation repeatedly, it depends on how frequent the function runs and how often you do it in the function. Normally, since this is just at frame creation, it should be fine as-is. In this specific example though, you can use the $parent tag at frame creation to reference the name of the frame's parent.
Code:
f.Health:CreateFontString("$parentText", "OVERLAY");
Hi SDPhantom,

Thank you for your reply!

That eased my concern

BTW, what is '$parent'? It seems like it gets the name of the parent frame, but what is it called?

Last edited by Layback_ : 07-26-16 at 05:06 PM.
  Reply With Quote
07-26-16, 07:52 PM   #15
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,313
It's an old XML feature that made its way over to the Lua implementation of creating frames. Adding $parent to the beginning of a frame name tells WoW to take the name of the parent frame and insert it there. In this case, it's a direct replacement for the line you had before and ends up giving it the same name. It may work in Frame:SetPoint() too, but nobody ever uses it for that since it's better to use a frame pointer anyway.
__________________
WoWInterface AddOns
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)

Last edited by SDPhantom : 07-26-16 at 07:56 PM.
  Reply With Quote
07-26-16, 08:23 PM   #16
Layback_
An Onyxian Warder
Join Date: Feb 2016
Posts: 358
Originally Posted by SDPhantom View Post
It's an old XML feature that made its way over to the Lua implementation of creating frames. Adding $parent to the beginning of a frame name tells WoW to take the name of the parent frame and insert it there. In this case, it's a direct replacement for the line you had before and ends up giving it the same name. It may work in Frame:SetPoint() too, but nobody ever uses it for that since it's better to use a frame pointer anyway.
Sounds interesting

Maybe I should have a look at XML in close future!

Thank you for explanation
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Setting frame levels

Thread Tools
Display Modes

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