WoWInterface (
-   oUF (Otravi Unit Frames) (
-   -   Need help coloring "widget" (

Sauerkraut 05-26-11 01:06 PM

Need help coloring "widget"
I've started playing around with a new layout and I've gotten most things working, however there is a small arrow that I am using to indicate power on the power bar. I've included an image since it is a little hard to explain

I'm currently using the follow to color it


  oUF.colors.power['MANA'] = {0.0, 0.56, 1.0}
  oUF.colors.power['RAGE'] = {1.0,0,0}
  oUF.colors.power['FOCUS'] = {1.0,0.75,0.25}
  oUF.colors.power['ENERGY'] = {1.0, 0.9, 0.35}
  oUF.colors.power['RUNIC_POWER'] = {0.44,0.44,0.44}
  local _, pType = UnitPowerType("player")
  local pcolor = oUF.colors.power[pType] or {.3,.45,.65}


It works most of the time but others I need to do a /rl to have it pick up the proper color. Also if I am on a druid and I shapeshift to a different form it doesn't update. I'm sure I'm just missing some thing but I'm not sure how to go about making it update. Any help would be appreciated.

Rainrider 05-26-11 01:55 PM

How did you created the arror? (is it a texture, what is its parent frame and what events are registered to the frame?)

You have 2 options: creating an element as an oUF module and registering the proper events so it updates correctly, or just do it directly in the layout. This is what I currently use for threat, maybe it helps you a bit

create the element and expose it to the namespace
lua Code:
  1. local AddThreatHighlight = function(self, event, unit)
  2.     if (unit ~= self.unit) then return end
  4.     local status = UnitThreatSituation(unit)
  5.     if (status and status > 0) then
  6.         local r, g, b = GetThreatStatusColor(status)
  8.         self.FrameBackdrop:SetBackdropBorderColor(r, g, b)
  9.     else
  10.         self.FrameBackdrop:SetBackdropBorderColor(0, 0, 0)
  11.     end
  12. end
  13. ns.AddThreatHighlight = AddThreatHighlight

enable it for the frame:
lua Code:
  1. self:RegisterEvent("UNIT_THREAT_SITUATION_UPDATE", ns.AddThreatHighlight)

I'm unsure if an element as a module has any benefits.

And if you plan to release your layout, you should use metatables for the colors and not overwrite the oUF dafault table, in case a user wants to use a diffenrent layout for say raid frames or so.
lua Code:
  1. ns.colors = setmetatable({
  2.     power = setmetatable({
  3.         ['MANA'] = {0.0, 0.56, 1.0},
  4.         ['RAGE'] = {1.0,0,0},
  5.         ['FOCUS'] = {1.0,0.75,0.25},
  6.         ['ENERGY'] = {1.0, 0.9, 0.35},
  7.         ['RUNIC_POWER'] = {0.44,0.44,0.44},
  8.     }, {__index = oUF.colors.power}),
  9. }, {__index = oUF.colors})

Sauerkraut 05-26-11 02:43 PM

The arrow is a texture spawned on the power bar frame.


                s.arrow = s:CreateTexture(nil, "OVERLAY")
                s.arrow:SetPoint("BOTTOM", s:GetStatusBarTexture(), "RIGHT", 0, 7)

Thanks for the code i'll see if I can figure out how or if it will work.

Rainrider 05-27-11 03:07 AM

You could probably just use PostUpdate for the power element to change the color of the arrow.

Sauerkraut 05-27-11 09:58 AM

I'm stumped. I'm sure I am doing something stupid but I can't figure it out. I found and example of a similar postupdate in Dawn's oUF_Nivea but I can't get it to work.


local PostUpdatePower = function(f, event, unit, Power)

        local _, ptype = UnitPowerType("player")
        if(oUF.colors.power[ptype]) then
                r, g, b = unpack(oUF.colors.power[ptype])

        f:SetVertexColor(r, g, b)


NM I figured it out. Thanks for the help.

zork 05-27-11 10:30 AM

There are events to track the druid shapeshift.

Your arrow frame needs to hook them and change it's color accordingly.

The unit powertype colors of oUF are initiated on login.

By the time it loads it may be possible that UnitPowerType("player") still returns nil. But not sure about that. I think it should work, at least UnitClass etc. does.


"Fired when the unit's mana stype is changed. Occurs when a druid shapeshifts as well as in certain other cases."
Basically...register the event to your arrow frame and then call UnitPowerType player and set the color of the arrow.

I recommend registering PLAYER_LOGIN aswell. By that time the function will be working and you should be able to set the color correctly.

Sth like this should work...

lua Code:
  1. --set color
  2.   lib.setArrowColor = function(self)
  3.     local _, pType = UnitPowerType("player")
  4.     local pcolor = oUF.colors.power[pType] or {.3,.45,.65}
  5.     self.arrow:SetVertexColor(unpack(pcolor))
  6.   end
  8.   --hook events  
  9.   self:RegisterEvent("PLAYER_LOGIN", lib.setArrowColor)
  10.   self:RegisterEvent("PLAYER_ENTERING_WORLD", lib.setArrowColor)
  11.   self:RegisterEvent("UNIT_DISPLAYPOWER", lib.setArrowColor)


Btw I found a neat trick for threat coloring (I guess I'm the last one to find out about forceUpdate O_O).
It is awesome because if color is set via self.Health.colorHealth = true then if you don't have aggro the color will stay and the color is updated as soon as any of the events if fired.

lua Code:
  1. --update health func
  2.   lib.updateHealth = function(bar, unit, min, max)
  3.     --color the hp bar in red if the unit has aggro
  4.     if unit and UnitThreatSituation(unit) == 3 then
  5.       bar:SetStatusBarColor(1,0,0)
  6.       if then*,0,0) end
  7.     end  
  8.   end
  10.   --check threat
  11.   lib.checkThreat = function(self,event,unit)
  12.     --force an update on the health frame
  13.     self.Health:ForceUpdate()
  14.   end
  16.   self.Health.PostUpdate = lib.updateHealth
  17.   self:RegisterEvent("PLAYER_TARGET_CHANGED", lib.checkThreat)
  18.   self:RegisterEvent("UNIT_THREAT_SITUATION_UPDATE", lib.checkThreat)

Sauerkraut 05-27-11 12:16 PM

Thanks Zork. My way didn't work. Well it works, until you enter combat and try to perform an action. How would I implement your solution. Would I just call it from within the arrow code or would I have to add it in some where else? I'm going to try and play around with it see if I can figure it out. I do appreciate any help you can offer though. I think I'm in way over my head here.

Sauerkraut 05-27-11 01:34 PM

I either need to start drinking or stop I'm not sure which. I've got the postupdate working. Seems to be doing the job. I've uploaded a short vid to youtube since it is pretty hard to describe exactly what is going on.

If you watch it in 1080p you can see what is going on. The lower resolutions suck.

Oh and I made this video on my really crappy laptop that only gets like 12fps so excuse the crappy quality.

Rainrider 05-27-11 01:36 PM


in Zork's (and in mine) example you register an event and assign an event handler (that's setArrowColor in Zork's code) to it. You'll just pick the player frame for this. The handler has to be known before you assign it, meaning if you are using one file for all, setArrowColor has to be defined before your style function. If you are using different files, then the file that contains the declaration of setArrowColor has to be loaded before the file with your style function. By style function I mean the function set in oUF:RegisterStyle("style name", style_function). If you use the UnitSpecific table, you could register the event there, else it goes into the style function like this:

lua Code:
  1. if unit == "player" then
  2.     self:RegisterEvent("UNIT_DISPLAYPOWER", lib.setArrowColor)
  3. end

The same for the other events if they are needed.

Sauerkraut 05-27-11 02:17 PM

Again way over my head. I am amazed anything I write even works. Anyhow using PostUpdate works and seems to be doing exactly what I needed.


local PostUpdatePower = function(Power, unit, min, max)
        local _, ptype = UnitPowerType("player")
        if(oUF.colors.power[ptype]) then
                r, g, b = unpack(oUF.colors.power[ptype])
        Power.arrow:SetVertexColor(r, g, b)


                s.PostUpdate = PostUpdatePower
It may not be the most elegant or the best way to do it, but it seems to work.

Rainrider 05-27-11 03:13 PM

Only using UNIT_DISPLAYPOWER would be better as it is the only one you need (maybe apart from PLAYER_ENTERING_WORLD but you'd rather test this) and it fires a whole lot less that UNIT_POWER. Why does registering the events to the frame not work? Any errors? Could you post your code?

Sauerkraut 05-27-11 04:55 PM

Well I finally figured out what I was doing wrong. I was trying to put the registerevent lines into the creation code for the arrow rather than in the layout code. If that makes sense. Anyhow it is working. Final code looks like this:

in my lib.lua file

--set color
lib.setArrowColor = function(self)
        local _, pType = UnitPowerType("player")
        local pcolor = oUF.colors.power[pType] or {.3,.45,.65}

in the player section of my core.lua file

                self:RegisterEvent("PLAYER_LOGIN", lib.setArrowColor)
                self:RegisterEvent("PLAYER_ENTERING_WORLD", lib.setArrowColor)
                self:RegisterEvent("UNIT_DISPLAYPOWER", lib.setArrowColor)

Big thanks to both of you for helping. I get my head so twisted up some times I think I over complicate things. This code seems much faster for the updates.

New question now, can I use the same sort of RegisterEvent in a tag? It seems now that if my power bar is at full (say in cat form full energy) and I switch to caster form (full mana) it still shows 100 (energy) rather than 6.0k (mana).

zork 05-28-11 04:24 AM

Isn't that exactly what I wrote? :)

Dawn wrote it in the other thread and oUF_Simple2 has a tag tutorial aswell.

Coypied from Dawn
lua Code:
  1. local MAELSTROM_WEAPON = GetSpellInfo(53817)
  2. oUF.Tags["maelstrom"] = function(unit)
  3.     if unit == "player" then
  4.         local name, _, icon, count = UnitBuff("player", MAELSTROM_WEAPON)
  5.         return name and count
  6.     end
  7. end
  8. oUF.TagEvents["maelstrom"] = "UNIT_AURA UNIT_HEALTH"

The "UNIT_AURA UNIT_HEALTH" part is where you have your events that will call the tag.

Sauerkraut 05-28-11 07:55 AM


Originally Posted by zork (Post 238281)
Isn't that exactly what I wrote? :)

Yes and thank you. I was frustrated and lost my focus. Things just didn't want to line up yesterday. When I went back to it after a couple hours I saw the errors I had made and it finally clicked. I really appreciate your help and patience Zork. Thank you.

Coldkil 06-01-11 06:18 AM

I have a similar problem with druids. (i hate they multiple forms)

I have made the combobar as a simple frame with 5 text strings, that stay at .2 alpha when not up, then go at alpha 1 when the combo builds up.

The fact is that i want to register the shapeshift events for make them disappear completely when the druid isn't in cat form.

Same would be good for eclipse bar, displaying it only when in moonkin form.

Is it possible or it's something that i canot achieve? thanks.

Mischback 06-01-11 07:49 AM


Originally Posted by Coldkil (Post 238560)
The fact is that i want to register the shapeshift events for make them disappear completely when the druid isn't in cat form.

No you don't want to do this, because there are some quests, spots where you will need Combo-Point-display, even if you're not cat nor rogue.

You can use the cpoints PostUpdate-mechanism to achieve this (hide, if there is no CP, show if there is at least one).

As for the eclipse-bar: Yes, using a shapeshift event to check if you're in moonkin-form would do the trick, works exactly as you already described it!

Coldkil 06-01-11 08:14 AM

Ok, can i do that just editing the combopoint_update method? I made a simple edit on the oUF element, from show/hide to .2/1 alpha.

Looking better at the eclipse bar elemnt though, it seems it's already handled, so no problem for that.

Can you give me more details? An example of pseudo code wold be fantastic, i still have some difficulties with lua.

edit: this is what i have done

the original

local cpoints = self.CPoints
        for i=1, MAX_COMBO_POINTS do
                if(i <= cp) then

my edit

local cpoints = self.CPoints
        for i=1, MAX_COMBO_POINTS do
                if(i <= cp) then

Mischback 06-01-11 11:52 AM


Originally Posted by Coldkil (Post 238560)
I have a similar problem with druids. (i hate they multiple forms)

I have made the combobar as a simple frame with 5 text strings, that stay at .2 alpha when not up, then go at alpha 1 when the combo builds up.

The fact is that i want to register the shapeshift events for make them disappear completely when the druid isn't in cat form.

Same would be good for eclipse bar, displaying it only when in moonkin form.

Is it possible or it's something that i canot achieve? thanks.

No, I didn't want to suggest an altering of oUF's core! At least not on parts, that are working perfectly.
On the other hand, the cpoints-module doesn't include a PostUpdate (hint at haste!), so you'll have to put some effort into it!

Go and style your CPoints in your layout as you want them to be. Don't include any conditions to them, though.

The oUF-module DOES include the possibility to override the original update-function, and this would be the way to go!

You can merely use, what you already got and put it into a function inside of your layout

lua Code:
  1. local function CPointsOverride(self, event, unit)
  2.         if (unit == 'pet') then return end
  3.     local cp = nil
  4.     if(UnitHasVehicleUI'player') then
  5.         cp = GetComboPoints('vehicle', 'target')
  6.     else
  7.         cp = GetComboPoints('player', 'target')
  8.     end
  10.         local cpoints = self.CPoints
  11.         if (cp) then
  12.                 cpoints:Show()
  13.             for i=1, MAX_COMBO_POINTS do
  14.                 if(i <= cp) then
  15.                     cpoints[i]:SetAlpha(1)
  16.                 else
  17.                     cpoints[i]:SetAlpha(0.2)
  18.                 end
  19.             end
  20.         else
  21.                 cpoints:Hide()
  22.         end
  23. end

This way, you're getting your CPoints shown everytime, when CPoints are on the target, regardless of your class. If there is at least one combo point, the whole element is shown and updated as you want it with the alpha settings.

Note: You don't have to include those cpoints:Show() / :Hide() stuff, it would be my approach.
If you want your CPoints always visible if you're in cat-form or on an rogue, just show them all the time (rogue) or if you're in cat (drood).

Create a frame and register the "UPDATE_SHAPESHIFT_FORM"-event and apply a script to this event

lua Code:
  1. local function ShapeshiftControl()
  2.     if (currentform == CAT) then
  3.         ShowCPoints()
  4.     else
  5.         HideCPoints()
  6.     end
  7. end

This is of course pseudo-code, you will have to fill it with life.

edit: Second approach is easily modified to handle eclipse-bar, too!

Coldkil 06-01-11 12:54 PM

Thanks a lot. That was the thing i was searching for. Gonna give it a try this night.

Anyway, since eclipse bar is already handled in this way by default and, in fact, it could be useful to keep track of combo points even if not in cat form (i'm thinking about feral PvP, dunno if it's really useful) i think i'll fiollow your approach.

It's simple, easily understandable for the ones who likes to edit lua, and works well.

Thanks again.

Mischback 06-01-11 02:00 PM

Glad I could help you!

In fact, I'm currently working on this problem myself, so here's my override:

lua Code:
  1. core.CPointOverride = function(self, event, unit)
  2.     if ( unit == 'pet' ) then return end
  4.     local cp
  5.     if ( UnitHasVehicleUI('player') ) then
  6.         cp = GetComboPoints('vehicle', 'target')
  7.     else
  8.         cp = GetComboPoints('player', 'target')
  9.     end
  11.     local cpoints = self.CPoints
  12.     if ( cp > 0 ) then
  13.         cpoints:Show()
  14.         self.Debuffs:SetPoint('BOTTOM', cpoints, 'TOP', 0, 7)
  15.         for i=1, MAX_COMBO_POINTS do
  16.             if( i <= cp ) then
  17.                 cpoints[i]:SetAlpha(1)
  18.             else
  19.                 cpoints[i]:SetAlpha(0.35)
  20.             end
  21.         end
  22.     else
  23.         cpoints:Hide()
  24.         self.Debuffs:SetPoint('BOTTOM', self, 'TOP', 0, 10)
  25.     end
  26. end

Note that I'm moving my Debuffs with this, you should erase these lines!

All times are GMT -6. The time now is 01:25 AM.

vBulletin © 2018, Jelsoft Enterprises Ltd
© 2004 - 2017 MMOUI