Yeah, lots of people ask, so no biggie. One of these days, I'll create a new thread so I can actually put relevant info on the first post. I didn't author the first on this thead so can't do anything with it. :/
You have to register the callback before creating the group and/or skinning it.
Sorry for the late reply but I've been kinda busy lately. So what I'm doing now is this:
nivBuffs = CreateFrame("FRAME", "nivBuffs", UIParent)
nivBuffs:SetScript('OnEvent', function(self, event, ...) self[event](self, event, ...) end)
nivBuffs:RegisterEvent("ADDON_LOADED")
local LBF = LibStub('LibButtonFacade', true)
local bfButtons = {}
local BF = LBF and nivBuffDB.useButtonFacade
-- more addon related stuff here --
function nivBuffs:ADDON_LOADED(event, addon)
if (addon ~= 'nivBuffs') then return end
self:UnregisterEvent(event)
ChatFrame1:AddMessage(LBF and "OK" or "LBF missing!")
ChatFrame1:AddMessage(nivBuffDB.useButtonFacade and "OK" or "LBF deactivated!")
-- buttonfacade
if not nivBuffs_BF then nivBuffs_BF = {} end
if BF then
ChatFrame1:AddMessage(nivBuffs_BF.skinID or "?")
LBF:RegisterSkinCallback("nivBuffs", self.BFSkinCallBack, self)
ChatFrame1:AddMessage(nivBuffs_BF.skinID or "?")
bfButtons = LBF:Group("nivBuffs", "auras")
ChatFrame1:AddMessage(nivBuffs_BF.skinID or "?")
bfButtons:Skin(nivBuffs_BF.skinID, nivBuffs_BF.gloss, nivBuffs_BF.backdrop, nivBuffs_BF.colors)
ChatFrame1:AddMessage(nivBuffs_BF.skinID or "?")
end
end
function nivBuffs:BFSkinCallBack(skinID, gloss, backdrop, group, button, colors)
nivBuffs_BF.skinID = skinID
nivBuffs_BF.gloss = gloss
nivBuffs_BF.backdrop = backdrop
nivBuffs_BF.colors = colors
ChatFrame1:AddMessage("Callback: " .. (nivBuffs_BF.skinID or "?"))
end
The output is:
OK
OK
Serenity
Serenity
Serenity
Callback: Serenity
Serenity
Callback: Blizzard
Callback: Blizzard
The buttons are still not being skinned at this point (but they are when I set the skin manually in the BF config). So I think the two resetting callbacks appear before I add my buttons to the group. And now I'm kinda lost again.
**edit:
It's always exactly two resetting callbacks, independent of how many buttons there are to be skinned.
Ok. First things first. The root problem is that you're creating an add-on group and "auras" subgroup but your callback and skin functions aren't referencing the "auras" subgroup so they're overwriting the subgroup data with the add-on level data. Make sense?
In order for LBF to skin the subgroup, it has to first skin the add-on. So, since your callback function doesn't distinguish between add-on-level or subgroup-level of an update, it's applying both to your group, so to speak.
There's two ways to fix it. The simplest is to check and make sure the group parameter is not empty before skinning it.
IE:
function nivBuffs:BFSkinCallBack(skinID, gloss, backdrop, group, button, colors)
if group then
nivBuffs_BF.skinID = skinID
nivBuffs_BF.gloss = gloss
nivBuffs_BF.backdrop = backdrop
nivBuffs_BF.colors = colors
ChatFrame1:AddMessage("Callback: " .. (nivBuffs_BF.skinID or "?"))
end
end
But the proper way to do is to account for both the add-on level skin and the subgroup skin (because if you had more than one subgroup, they could be different). To do that, you still check, but add an extra section in your SV file, etc.
Like so,
In your ADDON_LOADED function (Note that I removed the chat command comments because they were distracting. :p) :
-- buttonfacade
if not nivBuffs_BF then nivBuffs_BF = {} end
if not nivBuffs_BF.auras then nivBuffs_BF.auras = {} end
if BF then
-- Register the skin callback.
LBF:RegisterSkinCallback("nivBuffs", self.BFSkinCallBack, self)
-- Skin the add-on level group
local g = LBF:Group("nivBuffs")
g:Skin(nivBuffs_BF.skinID, nivBuffs_BF.gloss, nivBuffs_BF.backdrop, nivBuffs_BF.colors)
-- Skin the subgroup
bfButtons = LBF:Group("nivBuffs","auras")
bfButtons:Skin(nivBuffs_BF.auras.skinID, nivBuffs_BF.auras.gloss, nivBuffs_BF.auras.backdrop, nivBuffs_BF.auras.colors)
end
You skin your add-on, then your group.
Now to fix the callback function:
function nivBuffs:BFSkinCallBack(skinID, gloss, backdrop, group, button, colors)
if not group then
-- Addon level
nivBuffs_BF.skinID = skinID
nivBuffs_BF.gloss = gloss
nivBuffs_BF.backdrop = backdrop
nivBuffs_BF.colors = colors
ChatFrame1:AddMessage("Callback: " .. (nivBuffs_BF.skinID or "?"))
else
-- Subgroup level
nivBuffs_BF.auras.skinID = skinID
nivBuffs_BF.auras.gloss = gloss
nivBuffs_BF.auras.backdrop = backdrop
nivBuffs_BF.auras.colors = colors
ChatFrame1:AddMessage("Callback: " .. (nivBuffs_BF.auras.skinID or "?"))
end
end
That should fix it. It will also make it display the correct skin for the add-on level group in BF's GUI. If you don't do the add-on level stuff, the GUI will always display the Blizzard skin for the add-on section.
I did notice something else and couldn't figure out why it was happening, but BF's GUI should be showing the subgroup but it's not. I'll have to play with it more when I'm not tired. :p
First thank you for your efforts to help me! :) Unfortunately I need more of it.
I tried the easiest ways first, since I need only one group. So:
1. Adding buttons to the addon level group. Nothing changes.
2. Your first suggestion. Still nothing.
3. Your second suggestion. Nope.
In all three cases, there's still one resetting callback for each, the addon level and my "auras" group (both are set to "Blizzard"!). They appear right after the skinning calls (which still seem to work fine and hand the correct skin values to my callback function), but before adding buttons. Behaviour stays the same: My buttons are not skinned after relog/reloadui, but setting the skin manually works fine. I committed the current code to GitHub again.
Alright, I'm going to bury my head in sand. Well, actually, it feels that way already. The first issue, that the skin is not sticking between reloads is actually my fault. When I was doing some tweaking, I adjusted the skinning function the GUI uses so the GUI was actually pre-skinning all of its children with the global skin (instead of just setting the global skin) and I forgot to change it back to the correct function. :p That's fixed in the latest alpha.
The other issue, that of the "auras" group not appearing in the GUI is because of the group creation's placement. For some stupid reason, having it in the ADDON_LOADED function is preventing the GUI update.
Finally, I've done a few tweaks in the code to account for the aforementioned issue and some other things:
First of all, change your declaration of bfButtons (Line 6) from
local bfButtons = {}
to
local bfButtons
We're going to use its nil value to prevent a duplicate call on the Group method.
Next, in your "createAuraButton" function, change line 94 from
if BF then bfButtons:AddButton(btn, { Icon = btn.icon.tex, Cooldown = btn.cd } ) end
to
if BF then
if not bfButtons then
bfButtons = LBF:Group("nivBuffs", "auras")
bfButtons:Skin(nivBuffs_BF.auras.skinID, nivBuffs_BF.auras.gloss, nivBuffs_BF.auras.backdrop, nivBuffs_BF.auras.colors)
end
bfButtons:AddButton(btn, { Icon = btn.icon.tex, Cooldown = btn.cd } )
end
Note that we created the group and skinned it only if the "bfButtons" variable was nil. Also, moving it to this function, which gets called later, actually makes the group show up in the GUI.
Lastly, in your ADDON_LOADED method, change:
-- buttonfacade
if not nivBuffs_BF then nivBuffs_BF = {} end
if not nivBuffs_BF.auras then nivBuffs_BF.auras = {} end
if BF then
LBF:RegisterSkinCallback("nivBuffs", self.BFSkinCallBack, self)
LBF:Group("nivBuffs"):Skin(nivBuffs_BF.skinID, nivBuffs_BF.gloss, nivBuffs_BF.backdrop, nivBuffs_BF.colors)
bfButtons = LBF:Group("nivBuffs", "auras")
bfButtons:Skin(nivBuffs_BF.auras.skinID, nivBuffs_BF.auras.gloss, nivBuffs_BF.auras.backdrop, nivBuffs_BF.auras.colors)
end
To
-- buttonfacade
nivBuffs_BF = nivBuffs_BF or {}
nivBuffs_BF.auras = nivBuffs_BF.auras or {}
if BF then
LBF:RegisterSkinCallback("nivBuffs", self.BFSkinCallBack, self)
LBF:Group("nivBuffs"):Skin(nivBuffs_BF.skinID, nivBuffs_BF.gloss, nivBuffs_BF.backdrop, nivBuffs_BF.colors)
end
That should fix everything. >.< So we hope.
For the record, you should also set up some saved variable defaults so that the skin functions don't initially get passed with nil values.
Wow, I've actually gone through all 106 pages in this thread...
Working on adding support to a mod and having some issues.
I'm not using templates for my buttons (they aren't action buttons) and I can't get them to show the disabled texture when the button is set with :SetButtonState("DISABLED", true)
Here's the most relevant code I can think to post:
Creating the actual button and the optional textures for LBF:
local indicator = CreateFrame("Button", name, RecycledFrame)
........
if(LBF) then
indicator.icon = indicator:CreateTexture(nil, "BACKGROUND")
indicator.disabledicon = indicator:CreateTexture(nil, "BACKGROUND")
end
Note that I've tried using different layers to no avail.
Setting the textures:
if(LBF) then
--LBF SUPPORT
indicator.icon:SetTexture(texture)
indicator.disabledicon:SetTexture(texture)
indicator.disabledicon:SetDesaturated(true)
else
--NO LBF
indicator:SetNormalTexture(texture)
indicator:SetDisabledTexture(texture)
indicator:GetDisabledTexture():SetDesaturated(true)
end
And finally, when it comes time to set the button data it looks like this:
--LBF SUPPORT
if(LBF) then
indicator.btndata = {
Icon = indicator.icon,
Cooldown = false,
Pushed = false,
Flash = false,
Normal = nil,
Disabled = indicator.disabledicon,
Checked = false,
Border = false,
Highlight = false,
AutoCast = false,
AutoCastable = false,
HotKey = false,
Count = false,
Name = false,
}
local group = LBF:Group(LBFHermes.Name, MODNAME);
group:AddButton(indicator, indicator.btndata)
end
Note that the sizing of the buttons is done elsewhere and I have to call group:ReSkin() but that part seems fine.
Quote a few comments/questions here.
1. Why is it that I must set Normal to nil? If I set it to false or an actual texture then things go to hell in a hand-basket. Note that I've tried SetNormalTexture on the button object and then leaving Normal set to nil and that causes the same problems.
2. The interaction between the various layers just seems real finicky overall. There must be something I don't understand about the requirements of buttons.
3. Why MUST I use Icon for the texture and not Normal? The ONLY way this is even close to working is by setting the texture to Icon.
When I disable LBF (by setting it to nil) the addon works perfectly well. I just can't figure out how to use LBF to show the Disabled texture when the button state is disabled. Is this supported?
My reply is based on what you've posted. I'd need to see the full code (in a usable add-on) in order to debug it correctly.
From what I can tell, it doesn't seem like you're using the layers correctly. As specified by the ButtonData specification, the Icon is the skill/item/macro icon that appears for the button. The "Normal" layer is the border-like graphic that appears over top of the icon.
The default behavior for a button is that the "Normal" texture is swapped out for the "Disabled" texture and the "Pushed" texture. However, skins have the ability to disable that functionality (and they should because it's a headache) and the "Disabled" texture altogether if they so choose. If a skin has its Normal.Static set to true, rather than swapping out those images, it allows the Disabled texture to become an accenting texture rather than a replacement texture. Additionally, if a skin's Disabled.Hide is set to true, the Disabled texture will never be visible.
If you can give me a link to the code you have worked up or something so I have a working copy I can test, I can find the solution. Unfortunately, snippets of code can only provide a glance at what's going on.
Thanks StormFX, I'll review what you posted in a day or so and then upload the current state of my addon for possible inspection if I haven't veen able to get anywhere further. I'm pretty sure it'll be something on my end :)
Alright, I'm going to bury my head in sand. Well, actually, it feels that way already. The first issue, that the skin is not sticking between reloads is actually my fault. When I was doing some tweaking, I adjusted the skinning function the GUI uses so the GUI was actually pre-skinning all of its children with the global skin (instead of just setting the global skin) and I forgot to change it back to the correct function. :p That's fixed in the latest alpha.
Thanks alot, it's working now! :D
Though I wonder why it did work for other addons, but not mine..
And also thanks for all your suggestions how to make the groups visible in the UI! However, since I really only need very basic support, I went back to the most simple solution which is perfectly fine for me (skinning the addon level).
Hi, just wanted to report back that I was able to achieve the behavior I wanted. I did a few things....
1. I derived from ActionButtonTemplate (only because it gave all the handy textures names that skins use such as $parentIcon)
2. I dropped ButtonData completely, not using that table.
3. Instead of trying to specify what to use as a "disabled" texture (since like you said, skins don't typically use it, which I confirmed by looking at their Lua config) I instead just manually desaturate the texture when needed via button:SetDesaturate(true)
Those three things solved all my problems with the additional benefit of GREATLY simplifying the code.
Thanks for your help, it helped me to know my entire approach was faulty and sent me in the right direction.
No problem. And for the record, I think Blizzard's actually using the desaturate method now (on the icon I believe) since I've yet to find a button where they're actually using the disabled texture.
When I'm grouped with others (and only then), I'll get some kind of taint error in combat now:
9x <event>ADDON_ACTION_BLOCKED:AddOn 'ButtonFacade' tried to call the protected function 'UNKNOWN()'.
<in C code>: ?
<in C code>: in function `SetFrameLevel'
...uttonFacade\Libs\LibButtonFacade\LibButtonFacade.lua:664: in function <...uttonFacade\Libs\LibButtonFacade\LibButtonFacade.lua:586>:
...uttonFacade\Libs\LibButtonFacade\LibButtonFacade.lua:763: in function `AddButton':
nivBuffs\nivBuffs.lua:102: in function <nivBuffs\nivBuffs.lua:39>
nivBuffs\nivBuffs.lua:198: in function <nivBuffs\nivBuffs.lua:197>
nivBuffs\nivBuffs.lua:303: in function <nivBuffs\nivBuffs.lua:300>
<in C code>: ?
I already googled and tried to search this thread here.. The only thing I found was a comment concerning XBar from 2008. The author said he fixed it but didn't say how. I also don't see anything special in his BF integration code other than not executing AddButton() in combat. But I somehow need to be able to do that, or else aura icons created in combat are not skinned..
I tried not to add the (secure) button but only my btn.icon subframe. That works for skinnig but it completely breaks interactivity (removing buffs on right click and showing the tooltip on mouseover). Moreover I wasn't able to test if that fixes the taint error yet.
PS: If you need to play around with the code again, use the r20 tagged version at GitHub, not the latest commit.
Those line numbers in nivBuffs don't match up to r20. As far as I know, none of the functions LBF uses are protected, but I'll try to see if I can reproduce the error when I get time.
Those line numbers in nivBuffs don't match up to r20. As far as I know, none of the functions LBF uses are protected, but I'll try to see if I can reproduce the error when I get time.
They do, GitHub messes them up.
And the one protected function BF uses is SetFrameLevel(). It's protected in my case because the icons of the SecureAuraHeader are protected frames.
:)
Sorry for the late reply but I've been kinda busy lately. So what I'm doing now is this:
The output is:
OK
OK
Serenity
Serenity
Serenity
Callback: Serenity
Serenity
Callback: Blizzard
Callback: Blizzard
The buttons are still not being skinned at this point (but they are when I set the skin manually in the BF config). So I think the two resetting callbacks appear before I add my buttons to the group. And now I'm kinda lost again.
**edit:
It's always exactly two resetting callbacks, independent of how many buttons there are to be skinned.
https://github.com/nivaya/nivBuffs
**edit:
I also made sure that the buttons are actually added AFTER the group initialisation (latest commit), but still the same behaviour.
LBF sees the group structure like so:
In order for LBF to skin the subgroup, it has to first skin the add-on. So, since your callback function doesn't distinguish between add-on-level or subgroup-level of an update, it's applying both to your group, so to speak.
There's two ways to fix it. The simplest is to check and make sure the group parameter is not empty before skinning it.
IE:
But the proper way to do is to account for both the add-on level skin and the subgroup skin (because if you had more than one subgroup, they could be different). To do that, you still check, but add an extra section in your SV file, etc.
Like so,
In your ADDON_LOADED function (Note that I removed the chat command comments because they were distracting. :p) :
You skin your add-on, then your group.
Now to fix the callback function:
That should fix it. It will also make it display the correct skin for the add-on level group in BF's GUI. If you don't do the add-on level stuff, the GUI will always display the Blizzard skin for the add-on section.
I did notice something else and couldn't figure out why it was happening, but BF's GUI should be showing the subgroup but it's not. I'll have to play with it more when I'm not tired. :p
I tried the easiest ways first, since I need only one group. So:
1. Adding buttons to the addon level group. Nothing changes.
2. Your first suggestion. Still nothing.
3. Your second suggestion. Nope.
In all three cases, there's still one resetting callback for each, the addon level and my "auras" group (both are set to "Blizzard"!). They appear right after the skinning calls (which still seem to work fine and hand the correct skin values to my callback function), but before adding buttons. Behaviour stays the same: My buttons are not skinned after relog/reloadui, but setting the skin manually works fine. I committed the current code to GitHub again.
The other issue, that of the "auras" group not appearing in the GUI is because of the group creation's placement. For some stupid reason, having it in the ADDON_LOADED function is preventing the GUI update.
Finally, I've done a few tweaks in the code to account for the aforementioned issue and some other things:
First of all, change your declaration of bfButtons (Line 6) from
to
We're going to use its nil value to prevent a duplicate call on the Group method.
Next, in your "createAuraButton" function, change line 94 from
to
Note that we created the group and skinned it only if the "bfButtons" variable was nil. Also, moving it to this function, which gets called later, actually makes the group show up in the GUI.
Lastly, in your ADDON_LOADED method, change:
To
That should fix everything. >.< So we hope.
For the record, you should also set up some saved variable defaults so that the skin functions don't initially get passed with nil values.
Working on adding support to a mod and having some issues.
I'm not using templates for my buttons (they aren't action buttons) and I can't get them to show the disabled texture when the button is set with :SetButtonState("DISABLED", true)
Here's the most relevant code I can think to post:
Creating the actual button and the optional textures for LBF:
Note that I've tried using different layers to no avail.
Setting the textures:
And finally, when it comes time to set the button data it looks like this:
Note that the sizing of the buttons is done elsewhere and I have to call group:ReSkin() but that part seems fine.
Quote a few comments/questions here.
1. Why is it that I must set Normal to nil? If I set it to false or an actual texture then things go to hell in a hand-basket. Note that I've tried SetNormalTexture on the button object and then leaving Normal set to nil and that causes the same problems.
2. The interaction between the various layers just seems real finicky overall. There must be something I don't understand about the requirements of buttons.
3. Why MUST I use Icon for the texture and not Normal? The ONLY way this is even close to working is by setting the texture to Icon.
When I disable LBF (by setting it to nil) the addon works perfectly well. I just can't figure out how to use LBF to show the Disabled texture when the button state is disabled. Is this supported?
From what I can tell, it doesn't seem like you're using the layers correctly. As specified by the ButtonData specification, the Icon is the skill/item/macro icon that appears for the button. The "Normal" layer is the border-like graphic that appears over top of the icon.
The default behavior for a button is that the "Normal" texture is swapped out for the "Disabled" texture and the "Pushed" texture. However, skins have the ability to disable that functionality (and they should because it's a headache) and the "Disabled" texture altogether if they so choose. If a skin has its Normal.Static set to true, rather than swapping out those images, it allows the Disabled texture to become an accenting texture rather than a replacement texture. Additionally, if a skin's Disabled.Hide is set to true, the Disabled texture will never be visible.
If you can give me a link to the code you have worked up or something so I have a working copy I can test, I can find the solution. Unfortunately, snippets of code can only provide a glance at what's going on.
I probably won't have time again until tomorrow.
Very much looking forward to solving this!
Thanks alot, it's working now! :D
Though I wonder why it did work for other addons, but not mine..
And also thanks for all your suggestions how to make the groups visible in the UI! However, since I really only need very basic support, I went back to the most simple solution which is perfectly fine for me (skinning the addon level).
1. I derived from ActionButtonTemplate (only because it gave all the handy textures names that skins use such as $parentIcon)
2. I dropped ButtonData completely, not using that table.
3. Instead of trying to specify what to use as a "disabled" texture (since like you said, skins don't typically use it, which I confirmed by looking at their Lua config) I instead just manually desaturate the texture when needed via button:SetDesaturate(true)
Those three things solved all my problems with the additional benefit of GREATLY simplifying the code.
Thanks for your help, it helped me to know my entire approach was faulty and sent me in the right direction.
Cheers!
I already googled and tried to search this thread here.. The only thing I found was a comment concerning XBar from 2008. The author said he fixed it but didn't say how. I also don't see anything special in his BF integration code other than not executing AddButton() in combat. But I somehow need to be able to do that, or else aura icons created in combat are not skinned..
I tried not to add the (secure) button but only my btn.icon subframe. That works for skinnig but it completely breaks interactivity (removing buffs on right click and showing the tooltip on mouseover). Moreover I wasn't able to test if that fixes the taint error yet.
PS: If you need to play around with the code again, use the r20 tagged version at GitHub, not the latest commit.
They do, GitHub messes them up.
And the one protected function BF uses is SetFrameLevel(). It's protected in my case because the icons of the SecureAuraHeader are protected frames.
**edit: I fixed it.