I wrote a unitframe oUF, but it has a bunch of bugs, mainly, that I don't know how to make it change target when the unitframe is clicked, ie, if I clicked target-of-target unitframe, then it won't change target. I know it can be done because Clique does it and other oUF files do it.
If anyone has a little time, (because of xpac and work and xmas shopping I really am behind for a couple more weeks).. this addon needs some assistance, with the clique thing or any other bugs that are obvious in how to fix.
I'll link whole thing in case anyone has time to help, because the problem isn't in any particular line of code, but in that my structure isn't exactly like other oUF files and thus doesn't work in quite the same way at all, I couldn't place my menus where theirs were and have it work, so copying their click code also didn't help.
Why are you creating a bunch of extra frames to listen for events? You're already creating an AceAddon-3.0 object; just register your events on that.
You shouldn't need the section of code under the comment "Check if we have a target and show or hide graphics accordingly" at all. Anything that's "part of" the target frame should be parented to the target frame. That way, it will automatically hide when the target frame is hidden by WoW based on its secure attributes (eg. it's set to watch the "target" unit, so WoW will hide it if no "target" unit exists). Same goes for the code under "Check if we have a focus and show or hide Container accordingly" and "Check if we have a ToT and show or hide Container accordingly".
The section of code under "Added some colors for player pet, since it defaulted to white and seemed confusing" is also unnecessary. You should be handling pet bar coloring either by setting the bar color manually in your spawn function, or by setting oUF-specific attributes like "colorHappiness" or "colorSmooth" or "colorPower" on the health and/or power bars for that frame.
"PreUpdate is called far less often than PostUpdate, so everything that can go in here, should" leads me to believe that you don't really understand how oUF works. Look in oUF's health module:
-- oUF does stuff here, but NEVER returns out here.
return health:PostUpdate(unit, min, max)
PreUpdate and PostUpdate are both called every time your frame's health bar is updated. Same goes for the power bar, and any other element. oUF first calls your PreUpdate if it exists, then its default update code, then your PostUpdate if it exists.
Also, setting a script (and defining the script function) on your health and power bars every time they changes is a horrible way to do things. If you actually need an OnMouseUp script on your health/power bars for some reason, define each function once, and then set it once per frame in your spawn function.
Again, "Have to set class colors in here, or using the Update will overwrite them" shows a significant lack of understanding of oUF's functionality and capabilities. If you want your bar to be class-colored, simply set "healthBar.colorClass" when you spawn the frame. Again, refer to the oUF health module to see how it handles bar coloring:
if(health.colorTapping and UnitIsTapped(unit) and not UnitIsTappedByPlayer(unit)) then
t = self.colors.tapped
elseif(health.colorDisconnected and not UnitIsConnected(unit)) then
t = self.colors.disconnected
elseif(health.colorHappiness and UnitIsUnit(unit, "pet") and GetPetHappiness()) then
t = self.colors.happiness[GetPetHappiness()]
[B] elseif(health.colorClass and UnitIsPlayer(unit)) or
(health.colorClassNPC and not UnitIsPlayer(unit)) or
(health.colorClassPet and UnitPlayerControlled(unit) and not UnitIsPlayer(unit)) then
local _, class = UnitClass(unit)
t = self.colors.class[class][/B]
elseif(health.colorReaction and UnitReaction(unit, 'player')) then
t = self.colors.reaction[UnitReaction(unit, "player")]
r, g, b = self.ColorGradient(min / max, unpack(health.smoothGradient or self.colors.smooth))
t = self.colors.health
You can also set "healthBar.colorReaction" to color non-player units by their reaction, "healthBar.colorTapping" to color tapped units, "healthBar.colorDisconnected" to color offline units, "healthBar.colorHappiness" to color the pet unit by happiness, or "healthBar.colorSmooth" to color as a smooth gradient by health.
The only manual override you may want to make, in PostUpdate, would be to give the bar a different color if the unit is dead, since oUF doesn't have a "colorDead" attribute (yet).
Same goes for the power bar. Use "powerBar.colorPower" instead of manually coloring it in PostUpdate.
if Health.offline then Health.offline:Hide() end
If you have a special texture that shows for offline units, why are you doing it this way? Set up your offline texture as a separate element, and only update it when the UNIT_CONNECTION event fires.
You should never need to manually pop up a menu on right-click using a script. Set your frame's "type2" attribute to "menu" and then define a menu on your frame. See pretty much any oUF layout (Haste's oUF_Classic and oUF_Lily are good simple examples) to see how to do this.
Change "UIParent" to "self" to fix your parenting issues and remove the need for extra event registrations, manual unit existence checking and element hiding. Anything parented to, for instance, the target frame will automatically hide when the target frame hides.
I'd recommend getting rid of all the dragging stuff, and just letting users install oUF_MovableFrames if they want to move your frames.
-- see https://github.com/haste/oUF/wiki for meaning of these
-- Do any of these work placed here?
self.Health.Smooth = true
self.Health.frequentUpdates = true
self.Health.colorDisconnected = true
self.Health.colorClass = true
Yes. It doesn't matter where you put these; oUF checks them each time it updates the bar.
-- Create a textframe to anchor texts to correct framelevel.
self.Textframe = CreateFrame("Frame", nil, self.Container)
I haven't puzzled through everything to figure out exactly what you're trying to do, but it seems really wasteful to create a half dozen or so "overlay" frames for this purpose on every unit frame. Create one overlay frame per unit, and attach all your extra stuff to it.
if not (IsAddOnLoaded"!ClassColors") then
local r, g, b = unpack(myclasscolors.class[ctype])
local r, g, b = unpack(oUF.colors.class[ctype])
1. You should check for the existence of a global table named "CUSTOM_CLASS_COLORS", not for whether an addon named "!ClassColors" is loaded. See the Class Colors documentation for more information.
2. You don't need this code at all. oUF already supports CUSTOM_CLASS_COLORS, and updates the oUF.colors table with the class colors from it if it exists. Just read from oUF.colors, and you'll get the correct color.
3. Re: your note about the portrait background color requiring a UI reload to update when you change a class color, you should register for a callback; again, I'll refer you to the Class Colors documentation.
--Add lightning bolt graphic for offline, but hide til they are.
local offlinetex = "Interface\\AddOns\\oUF_Henna\\icons\\Offline"
self.offlineframe = CreateFrame("Frame", nil, self.Container)
self.Health.offline = self.offlineframe:CreateTexture(nil, "BACKGROUND")
self.Health.offline:SetPoint("RIGHT", self.PortraitBorder, "RIGHT", -4, 0)
Why are you creating a whole new frame just for one texture? Just create the texture. You're making everything way more complicated than it needs to be, or is even reasonably useful.
Overall, I'd say your code is such a mess that you should just start over. Start by making a simple, functional frame. Then add one thing at a time, making sure it works at each step, until you've built up to the final product. Focus on doing things as simply as possible, creating as few frames as possible, and duplicating as little code (both within your layout, and between your layout and oUF) as possible.