Thread Tools Display Modes
05-26-11, 01:06 PM   #1
Sauerkraut
A Wyrmkin Dreamwalker
 
Sauerkraut's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2008
Posts: 52
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

Code:
  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}
Code:
	s.arrow:SetVertexColor(unpack(pcolor))
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.
  Reply With Quote
05-26-11, 01:55 PM   #2
Rainrider
A Firelord
AddOn Author - Click to view addons
Join Date: Nov 2008
Posts: 454
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
  3.  
  4.     local status = UnitThreatSituation(unit)
  5.     if (status and status > 0) then
  6.         local r, g, b = GetThreatStatusColor(status)
  7.    
  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})

Last edited by Rainrider : 05-26-11 at 02:01 PM.
  Reply With Quote
05-26-11, 02:43 PM   #3
Sauerkraut
A Wyrmkin Dreamwalker
 
Sauerkraut's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2008
Posts: 52
The arrow is a texture spawned on the power bar frame.

Code:
		s.arrow = s:CreateTexture(nil, "OVERLAY")
		s.arrow:SetTexture([[Interface\Addons\oUF_Fail\media\textureArrow]])
		s.arrow:SetSize(16,16)
		s.arrow:SetPoint("BOTTOM", s:GetStatusBarTexture(), "RIGHT", 0, 7)
		s.arrow:SetVertexColor(unpack(pcolor))
		fixTex(s.arrow)
Thanks for the code i'll see if I can figure out how or if it will work.
  Reply With Quote
05-27-11, 03:07 AM   #4
Rainrider
A Firelord
AddOn Author - Click to view addons
Join Date: Nov 2008
Posts: 454
You could probably just use PostUpdate for the power element to change the color of the arrow.
  Reply With Quote
05-27-11, 09:58 AM   #5
Sauerkraut
A Wyrmkin Dreamwalker
 
Sauerkraut's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2008
Posts: 52
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.

Code:
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])
	end

	f:SetVertexColor(r, g, b)

end
NM I figured it out. Thanks for the help.

Last edited by Sauerkraut : 05-27-11 at 10:29 AM.
  Reply With Quote
05-27-11, 10:30 AM   #6
zork
A Pyroguard Emberseer
 
zork's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2008
Posts: 1,740
@Kraut
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.

EVENT: UNIT_DISPLAYPOWER
"Fired when the unit's mana stype is changed. Occurs when a druid shapeshifts as well as in certain other cases."
http://wowprogramming.com/docs/events/UNIT_DISPLAYPOWER
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
  7.  
  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 bar.bg then bar.bg:SetVertexColor(1*bar.bg.multiplier,0,0) end
  7.     end  
  8.   end
  9.  
  10.   --check threat
  11.   lib.checkThreat = function(self,event,unit)
  12.     --force an update on the health frame
  13.     self.Health:ForceUpdate()
  14.   end
  15.  
  16.   self.Health.PostUpdate = lib.updateHealth
  17.   self:RegisterEvent("PLAYER_TARGET_CHANGED", lib.checkThreat)
  18.   self:RegisterEvent("UNIT_THREAT_SITUATION_UPDATE", lib.checkThreat)
__________________
| Simple is beautiful.
| WoWI AddOns | GitHub | Zork (WoW)

"I wonder what the non-pathetic people are doing tonight?" - Rajesh Koothrappali (The Big Bang Theory)

Last edited by zork : 05-27-11 at 10:43 AM.
  Reply With Quote
05-27-11, 12:16 PM   #7
Sauerkraut
A Wyrmkin Dreamwalker
 
Sauerkraut's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2008
Posts: 52
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.
  Reply With Quote
05-27-11, 01:34 PM   #8
Sauerkraut
A Wyrmkin Dreamwalker
 
Sauerkraut's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2008
Posts: 52
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.

http://www.youtube.com/watch?v=Iq7Fy0Jr-g8

Oh and I made this video on my really crappy laptop that only gets like 12fps so excuse the crappy quality.
  Reply With Quote
05-27-11, 01:36 PM   #9
Rainrider
A Firelord
AddOn Author - Click to view addons
Join Date: Nov 2008
Posts: 454
Sauerkraut,

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.
  Reply With Quote
05-27-11, 02:17 PM   #10
Sauerkraut
A Wyrmkin Dreamwalker
 
Sauerkraut's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2008
Posts: 52
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.

Code:
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])
	end
	Power.arrow:SetVertexColor(r, g, b)
end
Code:
		s.PostUpdate = PostUpdatePower
It may not be the most elegant or the best way to do it, but it seems to work.
  Reply With Quote
05-27-11, 03:13 PM   #11
Rainrider
A Firelord
AddOn Author - Click to view addons
Join Date: Nov 2008
Posts: 454
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?
  Reply With Quote
05-27-11, 04:55 PM   #12
Sauerkraut
A Wyrmkin Dreamwalker
 
Sauerkraut's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2008
Posts: 52
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
Code:
--set color
lib.setArrowColor = function(self)
	local _, pType = UnitPowerType("player")
	local pcolor = oUF.colors.power[pType] or {.3,.45,.65}
	self.Power.arrow:SetVertexColor(unpack(pcolor))
end
in the player section of my core.lua file
Code:
		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).
  Reply With Quote
05-28-11, 04:24 AM   #13
zork
A Pyroguard Emberseer
 
zork's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2008
Posts: 1,740
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.
__________________
| Simple is beautiful.
| WoWI AddOns | GitHub | Zork (WoW)

"I wonder what the non-pathetic people are doing tonight?" - Rajesh Koothrappali (The Big Bang Theory)

Last edited by zork : 05-28-11 at 04:28 AM.
  Reply With Quote
05-28-11, 07:55 AM   #14
Sauerkraut
A Wyrmkin Dreamwalker
 
Sauerkraut's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2008
Posts: 52
Originally Posted by zork View Post
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.
  Reply With Quote
06-01-11, 06:18 AM   #15
Coldkil
A Cliff Giant
 
Coldkil's Avatar
AddOn Author - Click to view addons
Join Date: Jun 2010
Posts: 70
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.
  Reply With Quote
06-01-11, 07:49 AM   #16
Mischback
A Cobalt Mageweaver
 
Mischback's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2009
Posts: 221
Originally Posted by Coldkil View Post
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!
__________________
  Reply With Quote
06-01-11, 08:14 AM   #17
Coldkil
A Cliff Giant
 
Coldkil's Avatar
AddOn Author - Click to view addons
Join Date: Jun 2010
Posts: 70
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
Code:
local cpoints = self.CPoints
	for i=1, MAX_COMBO_POINTS do
		if(i <= cp) then
			cpoints[i]:Show()
		else
			cpoints[i]:Hide()
		end
	end
my edit
Code:
local cpoints = self.CPoints
	for i=1, MAX_COMBO_POINTS do
		if(i <= cp) then
			cpoints[i]:SetAlpha(1)
		else
			cpoints[i]:SetAlpha(.2)
		end
	end

Last edited by Coldkil : 06-01-11 at 08:17 AM.
  Reply With Quote
06-01-11, 11:52 AM   #18
Mischback
A Cobalt Mageweaver
 
Mischback's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2009
Posts: 221
Originally Posted by Coldkil View Post
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
  9.  
  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!
__________________
  Reply With Quote
06-01-11, 12:54 PM   #19
Coldkil
A Cliff Giant
 
Coldkil's Avatar
AddOn Author - Click to view addons
Join Date: Jun 2010
Posts: 70
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.
  Reply With Quote
06-01-11, 02:00 PM   #20
Mischback
A Cobalt Mageweaver
 
Mischback's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2009
Posts: 221
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
  3.  
  4.     local cp
  5.     if ( UnitHasVehicleUI('player') ) then
  6.         cp = GetComboPoints('vehicle', 'target')
  7.     else
  8.         cp = GetComboPoints('player', 'target')
  9.     end
  10.  
  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!
__________________
  Reply With Quote

WoWInterface » Featured Projects » oUF (Otravi Unit Frames) » Need help coloring "widget"

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