colors.lua 7.72 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12
local parent, ns = ...
local oUF = ns.oUF
local Private = oUF.Private

local frame_metatable = Private.frame_metatable

local colors = {
	smooth = {
		1, 0, 0,
		1, 1, 0,
		0, 1, 0
	},
Val Voronov's avatar
Val Voronov committed
13
	health = {49 / 255, 207 / 255, 37 / 255},
14
	disconnected = {.6, .6, .6},
Val Voronov's avatar
Val Voronov committed
15
	tapped = {.6, .6, .6},
16 17
	class = {},
	reaction = {},
Val Voronov's avatar
Val Voronov committed
18
	power = {},
19 20 21 22
}

-- We do this because people edit the vars directly, and changing the default
-- globals makes SPICE FLOW!
Adrian L Lange's avatar
Adrian L Lange committed
23
local function customClassColors()
24
	if(CUSTOM_CLASS_COLORS) then
Adrian L Lange's avatar
Adrian L Lange committed
25 26 27
		local function updateColors()
			for classToken, color in next, CUSTOM_CLASS_COLORS do
				colors.class[classToken] = {color.r, color.g, color.b}
28
			end
29

30
			for _, obj in next, oUF.objects do
Adrian L Lange's avatar
Adrian L Lange committed
31
				obj:UpdateAllElements('CUSTOM_CLASS_COLORS')
32
			end
33 34
		end

35 36 37 38 39 40
		updateColors()
		CUSTOM_CLASS_COLORS:RegisterCallback(updateColors)

		return true
	end
end
Adrian L Lange's avatar
Adrian L Lange committed
41 42 43 44

if(not customClassColors()) then
	for classToken, color in next, RAID_CLASS_COLORS do
		colors.class[classToken] = {color.r, color.g, color.b}
45
	end
46

Adrian L Lange's avatar
Adrian L Lange committed
47 48 49 50 51 52
	local eventHandler = CreateFrame('Frame')
	eventHandler:RegisterEvent('ADDON_LOADED')
	eventHandler:SetScript('OnEvent', function(self)
		if(customClassColors()) then
			self:UnregisterEvent('ADDON_LOADED')
			self:SetScript('OnEvent', nil)
53 54
		end
	end)
55 56 57 58 59 60
end

for eclass, color in next, FACTION_BAR_COLORS do
	colors.reaction[eclass] = {color.r, color.g, color.b}
end

Val Voronov's avatar
Val Voronov committed
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
for power, color in next, PowerBarColor do
	if (type(power) == 'string') then
		if(type(select(2, next(color))) == 'table') then
			colors.power[power] = {}

			for index, color in next, color do
				colors.power[power][index] = {color.r, color.g, color.b}
			end
		else
			colors.power[power] = {color.r, color.g, color.b, atlas = color.atlas}
		end
	end
end

-- sourced from FrameXML/Constants.lua
colors.power[0] = colors.power.MANA
colors.power[1] = colors.power.RAGE
colors.power[2] = colors.power.FOCUS
colors.power[3] = colors.power.ENERGY
colors.power[4] = colors.power.COMBO_POINTS
colors.power[5] = colors.power.RUNES
colors.power[6] = colors.power.RUNIC_POWER
colors.power[7] = colors.power.SOUL_SHARDS
colors.power[8] = colors.power.LUNAR_POWER
colors.power[9] = colors.power.HOLY_POWER
colors.power[11] = colors.power.MAELSTROM
colors.power[12] = colors.power.CHI
colors.power[13] = colors.power.INSANITY
colors.power[16] = colors.power.ARCANE_CHARGES
colors.power[17] = colors.power.FURY
colors.power[18] = colors.power.PAIN

Adrian L Lange's avatar
Adrian L Lange committed
93 94
local function colorsAndPercent(a, b, ...)
	if(a <= 0 or b == 0) then
95
		return nil, ...
Adrian L Lange's avatar
Adrian L Lange committed
96
	elseif(a >= b) then
97 98 99 100
		return nil, select(select('#', ...) - 2, ...)
	end

	local num = select('#', ...) / 3
Adrian L Lange's avatar
Adrian L Lange committed
101 102
	local segment, relperc = math.modf((a / b) * (num - 1))
	return relperc, select((segment * 3) + 1, ...)
103 104
end

105
-- http://www.wowwiki.com/ColorGradient
Rainrider's avatar
Rainrider committed
106
--[[ Colors: oUF:RGBColorGradient(a, b, ...)
Rainrider's avatar
Rainrider committed
107 108 109 110 111 112 113 114 115 116 117
Used to convert a percent value (the quotient of `a` and `b`) into a gradient from 2 or more RGB colors. If more than 2
colors are passed, the gradient will be between the two colors which perc lies in an evenly divided range. A RGB color
is a sequence of 3 consecutive RGB percent values (in the range [0-1]). If `a` is negative or `b` is zero then the first
RGB color (the first 3 RGB values passed to the function) is returned. If `a` is bigger than or equal to `b`, then the
last 3 RGB values are returned.

* self - the global oUF object
* a    - value used as numerator to calculate the percentage (number)
* b    - value used as denominator to calculate the percentage (number)
* ...  - a list of RGB percent values. At least 6 values should be passed (number [0-1])
--]]
Adrian L Lange's avatar
Adrian L Lange committed
118 119 120 121
local function RGBColorGradient(...)
	local relperc, r1, g1, b1, r2, g2, b2 = colorsAndPercent(...)
	if(relperc) then
		return r1 + (r2 - r1) * relperc, g1 + (g2 - g1) * relperc, b1 + (b2 - b1) * relperc
122
	else
123
		return r1, g1, b1
124
	end
125 126
end

127
-- HCY functions are based on http://www.chilliant.com/rgb2hsv.html
Adrian L Lange's avatar
Adrian L Lange committed
128
local function getY(r, g, b)
129
	return 0.299 * r + 0.587 * g + 0.114 * b
130 131
end

Rainrider's avatar
Rainrider committed
132
--[[ Colors: oUF:RGBToHCY(r, g, b)
Rainrider's avatar
Rainrider committed
133 134 135 136 137 138 139
Used to convert a color from RGB to HCY color space.

* self - the global oUF object
* r    - red color component (number [0-1])
* g    - green color component (number [0-1])
* b    - blue color component (number [0-1])
--]]
Adrian L Lange's avatar
Adrian L Lange committed
140
function oUF:RGBToHCY(r, g, b)
141 142 143
	local min, max = min(r, g, b), max(r, g, b)
	local chroma = max - min
	local hue
Adrian L Lange's avatar
Adrian L Lange committed
144 145
	if(chroma > 0) then
		if(r == max) then
146
			hue = ((g - b) / chroma) % 6
Adrian L Lange's avatar
Adrian L Lange committed
147
		elseif(g == max) then
148
			hue = (b - r) / chroma + 2
Adrian L Lange's avatar
Adrian L Lange committed
149
		elseif(b == max) then
150 151 152
			hue = (r - g) / chroma + 4
		end
		hue = hue / 6
153
	end
Adrian L Lange's avatar
Adrian L Lange committed
154
	return hue, chroma, getY(r, g, b)
155
end
156

Adrian L Lange's avatar
Adrian L Lange committed
157
local math_abs = math.abs
Rainrider's avatar
Rainrider committed
158
--[[ Colors: oUF:HCYtoRGB(hue, chroma, luma)
Rainrider's avatar
Rainrider committed
159 160 161 162 163 164 165
Used to convert a color from HCY to RGB color space.

* self   - the global oUF object
* hue    - hue color component (number [0-1])
* chroma - chroma color component (number [0-1])
* luma   - luminance color component (number [0-1])
--]]
Adrian L Lange's avatar
Adrian L Lange committed
166
function oUF:HCYtoRGB(hue, chroma, luma)
167
	local r, g, b = 0, 0, 0
Adrian L Lange's avatar
Adrian L Lange committed
168
	if(hue and luma > 0) then
169
		local h2 = hue * 6
Adrian L Lange's avatar
Adrian L Lange committed
170 171
		local x = chroma * (1 - math_abs(h2 % 2 - 1))
		if(h2 < 1) then
172
			r, g, b = chroma, x, 0
Adrian L Lange's avatar
Adrian L Lange committed
173
		elseif(h2 < 2) then
174
			r, g, b = x, chroma, 0
Adrian L Lange's avatar
Adrian L Lange committed
175
		elseif(h2 < 3) then
176
			r, g, b = 0, chroma, x
Adrian L Lange's avatar
Adrian L Lange committed
177
		elseif(h2 < 4) then
178
			r, g, b = 0, x, chroma
Adrian L Lange's avatar
Adrian L Lange committed
179
		elseif(h2 < 5) then
180 181 182 183
			r, g, b = x, 0, chroma
		else
			r, g, b = chroma, 0, x
		end
Adrian L Lange's avatar
Adrian L Lange committed
184 185 186

		local y = getY(r, g, b)
		if(luma < y) then
187
			chroma = chroma * (luma / y)
Adrian L Lange's avatar
Adrian L Lange committed
188
		elseif(y < 1) then
189 190
			chroma = chroma * (1 - luma) / (1 - y)
		end
Adrian L Lange's avatar
Adrian L Lange committed
191

192 193 194
		r = (r - y) * chroma + luma
		g = (g - y) * chroma + luma
		b = (b - y) * chroma + luma
195
	end
196
	return r, g, b
197 198
end

Rainrider's avatar
Rainrider committed
199
--[[ Colors: oUF:HCYColorGradient(a, b, ...)
Rainrider's avatar
Rainrider committed
200 201 202 203 204 205 206 207 208 209 210
Used to convert a percent value (the quotient of `a` and `b`) into a gradient from 2 or more HCY colors. If more than 2
colors are passed, the gradient will be between the two colors which perc lies in an evenly divided range. A HCY color
is a sequence of 3 consecutive values in the range [0-1]. If `a` is negative or `b` is zero then the first
HCY color (the first 3 HCY values passed to the function) is returned. If `a` is bigger than or equal to `b`, then the
last 3 HCY values are returned.

* self - the global oUF object
* a    - value used as numerator to calculate the percentage (number)
* b    - value used as denominator to calculate the percentage (number)
* ...  - a list of HCY color values. At least 6 values should be passed (number [0-1])
--]]
Adrian L Lange's avatar
Adrian L Lange committed
211 212 213 214 215 216 217 218 219 220 221 222
local function HCYColorGradient(...)
	local relperc, r1, g1, b1, r2, g2, b2 = colorsAndPercent(...)
	if(not relperc) then
		return r1, g1, b1
	end

	local h1, c1, y1 = self:RGBToHCY(r1, g1, b1)
	local h2, c2, y2 = self:RGBToHCY(r2, g2, b2)
	local c = c1 + (c2 - c1) * relperc
	local y = y1 + (y2 - y1) * relperc

	if(h1 and h2) then
223
		local dh = h2 - h1
Adrian L Lange's avatar
Adrian L Lange committed
224
		if(dh < -0.5) then
225
			dh = dh + 1
Adrian L Lange's avatar
Adrian L Lange committed
226
		elseif(dh > 0.5) then
227 228
			dh = dh - 1
		end
Adrian L Lange's avatar
Adrian L Lange committed
229 230

		return self:HCYtoRGB((h1 + dh * relperc) % 1, c, y)
231
	else
Adrian L Lange's avatar
Adrian L Lange committed
232
		return self:HCYtoRGB(h1 or h2, c, y)
233
	end
234 235 236

end

Rainrider's avatar
Rainrider committed
237
--[[ Colors: oUF:ColorGradient(a, b, ...) or frame:ColorGradient(a, b, ...)
Rainrider's avatar
Rainrider committed
238 239 240 241 242 243 244 245
Used as a proxy to call the proper gradient function depending on the user's preference. If `oUF.useHCYColorGradient` is
set to true, `:HCYColorGradient` will be called, else `:RGBColorGradient`.

* self - the global oUF object or a unit frame
* a    - value used as numerator to calculate the percentage (number)
* b    - value used as denominator to calculate the percentage (number)
* ...  - a list of color values. At least 6 values should be passed (number [0-1])
--]]
Adrian L Lange's avatar
Adrian L Lange committed
246
local function ColorGradient(...)
247 248 249
	return (oUF.useHCYColorGradient and HCYColorGradient or RGBColorGradient)(...)
end

250 251 252
Private.colors = colors

oUF.colors = colors
253
oUF.ColorGradient = ColorGradient
254
oUF.RGBColorGradient = RGBColorGradient
255
oUF.HCYColorGradient = HCYColorGradient
256
oUF.useHCYColorGradient = false
257 258

frame_metatable.__index.colors = colors
259
frame_metatable.__index.ColorGradient = ColorGradient