07-23-16, 08:07 AM | #1 |
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:
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? |
|
07-23-16, 10:53 AM | #2 | |
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
Last edited by SDPhantom : 07-23-16 at 11:00 AM. |
||
07-23-16, 10:56 PM | #3 | |
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:
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...) |
||
07-24-16, 02:33 AM | #4 |
You can get the backdrop frame with this call, then override the frame level manually like this:
Lua Code:
But Backdrop have a lot of issues, thats why i like to avoid using it. |
|
07-24-16, 02:43 AM | #5 | |
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. |
||
07-24-16, 04:32 AM | #6 | |
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 |
||
07-24-16, 06:08 AM | #7 | |
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:
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? |
||
07-24-16, 06:45 AM | #8 |
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.
|
|
07-24-16, 09:16 AM | #9 | |
|
||
07-24-16, 09:18 AM | #10 | |
I can give you an example to save some typing: Lua Code:
Last edited by Resike : 07-24-16 at 09:21 AM. |
||
07-24-16, 10:09 AM | #11 |
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 |
|
07-24-16, 07:48 PM | #12 |
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:
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. |
|
07-26-16, 11:28 AM | #13 | ||
Code:
f.Health:CreateFontString("$parentText", "OVERLAY");
__________________
WoWInterface AddOns
Last edited by SDPhantom : 07-26-16 at 11:42 AM. |
|||
07-26-16, 04:54 PM | #14 | |
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. |
||
07-26-16, 07:52 PM | #15 | |
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
Last edited by SDPhantom : 07-26-16 at 07:56 PM. |
||
07-26-16, 08:23 PM | #16 | |
Maybe I should have a look at XML in close future! Thank you for explanation |
||
WoWInterface » Developer Discussions » Lua/XML Help » Setting frame levels |
«
Previous Thread
|
Next Thread
»
|
Display Modes |
Linear Mode |
Switch to Hybrid Mode |
Switch to Threaded Mode |
|
|