246 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			246 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
--[[
 | 
						|
# Element: Runes
 | 
						|
 | 
						|
Handles the visibility and updating of Death Knight's runes.
 | 
						|
 | 
						|
## Widget
 | 
						|
 | 
						|
Runes - An `table` holding `StatusBar`s.
 | 
						|
 | 
						|
## Sub-Widgets
 | 
						|
 | 
						|
.bg - A `Texture` used as a background. It will inherit the color of the main StatusBar.
 | 
						|
 | 
						|
## Notes
 | 
						|
 | 
						|
A default texture will be applied if the sub-widgets are StatusBars and don't have a texture set.
 | 
						|
 | 
						|
## Options
 | 
						|
 | 
						|
.colorSpec - Use `self.colors.runes[specID]` to color the bar based on player's spec. `specID` is defined by the return
 | 
						|
             value of [GetSpecialization](http://wowprogramming.com/docs/api/GetSpecialization.html) (boolean)
 | 
						|
.sortOrder - Sorting order. Sorts by the remaining cooldown time, 'asc' - from the least cooldown time remaining (fully
 | 
						|
             charged) to the most (fully depleted), 'desc' - the opposite (string?)['asc', 'desc']
 | 
						|
 | 
						|
## Sub-Widgets Options
 | 
						|
 | 
						|
.multiplier - Used to tint the background based on the main widgets R, G and B values. Defaults to 1 (number)[0-1]
 | 
						|
 | 
						|
## Examples
 | 
						|
 | 
						|
    local Runes = {}
 | 
						|
    for index = 1, 6 do
 | 
						|
        -- Position and size of the rune bar indicators
 | 
						|
        local Rune = CreateFrame('StatusBar', nil, self)
 | 
						|
        Rune:SetSize(120 / 6, 20)
 | 
						|
        Rune:SetPoint('TOPLEFT', self, 'BOTTOMLEFT', index * 120 / 6, 0)
 | 
						|
 | 
						|
        Runes[index] = Rune
 | 
						|
    end
 | 
						|
 | 
						|
    -- Register with oUF
 | 
						|
    self.Runes = Runes
 | 
						|
--]]
 | 
						|
 | 
						|
if(select(2, UnitClass('player')) ~= 'DEATHKNIGHT') then return end
 | 
						|
 | 
						|
local _, ns = ...
 | 
						|
local oUF = ns.oUF
 | 
						|
 | 
						|
local runemap = {1, 2, 3, 4, 5, 6}
 | 
						|
local hasSortOrder = false
 | 
						|
 | 
						|
local function onUpdate(self, elapsed)
 | 
						|
	local duration = self.duration + elapsed
 | 
						|
	self.duration = duration
 | 
						|
	self:SetValue(duration)
 | 
						|
end
 | 
						|
 | 
						|
local function ascSort(runeAID, runeBID)
 | 
						|
	local runeAStart, _, runeARuneReady = GetRuneCooldown(runeAID)
 | 
						|
	local runeBStart, _, runeBRuneReady = GetRuneCooldown(runeBID)
 | 
						|
	if(runeARuneReady ~= runeBRuneReady) then
 | 
						|
		return runeARuneReady
 | 
						|
	elseif(runeAStart ~= runeBStart) then
 | 
						|
		return runeAStart < runeBStart
 | 
						|
	else
 | 
						|
		return runeAID < runeBID
 | 
						|
	end
 | 
						|
end
 | 
						|
 | 
						|
local function descSort(runeAID, runeBID)
 | 
						|
	local runeAStart, _, runeARuneReady = GetRuneCooldown(runeAID)
 | 
						|
	local runeBStart, _, runeBRuneReady = GetRuneCooldown(runeBID)
 | 
						|
	if(runeARuneReady ~= runeBRuneReady) then
 | 
						|
		return runeBRuneReady
 | 
						|
	elseif(runeAStart ~= runeBStart) then
 | 
						|
		return runeAStart > runeBStart
 | 
						|
	else
 | 
						|
		return runeAID > runeBID
 | 
						|
	end
 | 
						|
end
 | 
						|
 | 
						|
local function UpdateColor(self, event)
 | 
						|
	local element = self.Runes
 | 
						|
 | 
						|
	local spec = GetSpecialization() or 0
 | 
						|
 | 
						|
	local color
 | 
						|
	if(spec > 0 and spec < 4 and element.colorSpec) then
 | 
						|
		color = self.colors.runes[spec]
 | 
						|
	else
 | 
						|
		color = self.colors.power.RUNES
 | 
						|
	end
 | 
						|
 | 
						|
	local r, g, b = color[1], color[2], color[3]
 | 
						|
 | 
						|
	for index = 1, #element do
 | 
						|
		element[index]:SetStatusBarColor(r, g, b)
 | 
						|
 | 
						|
		local bg = element[index].bg
 | 
						|
		if(bg) then
 | 
						|
			local mu = bg.multiplier or 1
 | 
						|
			bg:SetVertexColor(r * mu, g * mu, b * mu)
 | 
						|
		end
 | 
						|
	end
 | 
						|
 | 
						|
	--[[ Callback: Runes:PostUpdateColor(r, g, b)
 | 
						|
	Called after the element color has been updated.
 | 
						|
 | 
						|
	* self - the Runes element
 | 
						|
	* r    - the red component of the used color (number)[0-1]
 | 
						|
	* g    - the green component of the used color (number)[0-1]
 | 
						|
	* b    - the blue component of the used color (number)[0-1]
 | 
						|
	--]]
 | 
						|
	if(element.PostUpdateColor) then
 | 
						|
		element:PostUpdateColor(r, g, b)
 | 
						|
	end
 | 
						|
end
 | 
						|
 | 
						|
local function ColorPath(self, ...)
 | 
						|
	--[[ Override: Runes.UpdateColor(self, event, ...)
 | 
						|
	Used to completely override the internal function for updating the widgets' colors.
 | 
						|
 | 
						|
	* self  - the parent object
 | 
						|
	* event - the event triggering the update (string)
 | 
						|
	* ...   - the arguments accompanying the event
 | 
						|
	--]]
 | 
						|
	(self.Runes.UpdateColor or UpdateColor) (self, ...)
 | 
						|
end
 | 
						|
 | 
						|
local function Update(self, event)
 | 
						|
	local element = self.Runes
 | 
						|
 | 
						|
	if(element.sortOrder == 'asc') then
 | 
						|
		table.sort(runemap, ascSort)
 | 
						|
		hasSortOrder = true
 | 
						|
	elseif(element.sortOrder == 'desc') then
 | 
						|
		table.sort(runemap, descSort)
 | 
						|
		hasSortOrder = true
 | 
						|
	elseif(hasSortOrder) then
 | 
						|
		table.sort(runemap)
 | 
						|
		hasSortOrder = false
 | 
						|
	end
 | 
						|
 | 
						|
	local rune, start, duration, runeReady
 | 
						|
	for index, runeID in next, runemap do
 | 
						|
		rune = element[index]
 | 
						|
		if(not rune) then break end
 | 
						|
 | 
						|
		if(UnitHasVehicleUI('player')) then
 | 
						|
			rune:Hide()
 | 
						|
		else
 | 
						|
			start, duration, runeReady = GetRuneCooldown(runeID)
 | 
						|
			if(runeReady) then
 | 
						|
				rune:SetMinMaxValues(0, 1)
 | 
						|
				rune:SetValue(1)
 | 
						|
				rune:SetScript('OnUpdate', nil)
 | 
						|
			elseif(start) then
 | 
						|
				rune.duration = GetTime() - start
 | 
						|
				rune:SetMinMaxValues(0, duration)
 | 
						|
				rune:SetValue(0)
 | 
						|
				rune:SetScript('OnUpdate', onUpdate)
 | 
						|
			end
 | 
						|
 | 
						|
			rune:Show()
 | 
						|
		end
 | 
						|
	end
 | 
						|
 | 
						|
	--[[ Callback: Runes:PostUpdate(runemap)
 | 
						|
	Called after the element has been updated.
 | 
						|
 | 
						|
	* self    - the Runes element
 | 
						|
	* runemap - the ordered list of runes' indices (table)
 | 
						|
	--]]
 | 
						|
	if(element.PostUpdate) then
 | 
						|
		return element:PostUpdate(runemap)
 | 
						|
	end
 | 
						|
end
 | 
						|
 | 
						|
local function Path(self, ...)
 | 
						|
	--[[ Override: Runes.Override(self, event, ...)
 | 
						|
	Used to completely override the internal update function.
 | 
						|
 | 
						|
	* self  - the parent object
 | 
						|
	* event - the event triggering the update (string)
 | 
						|
	* ...   - the arguments accompanying the event
 | 
						|
	--]]
 | 
						|
	(self.Runes.Override or Update) (self, ...)
 | 
						|
end
 | 
						|
 | 
						|
local function AllPath(...)
 | 
						|
	Path(...)
 | 
						|
	ColorPath(...)
 | 
						|
end
 | 
						|
 | 
						|
local function ForceUpdate(element)
 | 
						|
	Path(element.__owner, 'ForceUpdate')
 | 
						|
	ColorPath(element.__owner, 'ForceUpdate')
 | 
						|
end
 | 
						|
 | 
						|
local function Enable(self, unit)
 | 
						|
	local element = self.Runes
 | 
						|
	if(element and UnitIsUnit(unit, 'player')) then
 | 
						|
		element.__owner = self
 | 
						|
		element.ForceUpdate = ForceUpdate
 | 
						|
 | 
						|
		for i = 1, #element do
 | 
						|
			local rune = element[i]
 | 
						|
			if(rune:IsObjectType('StatusBar') and not (rune:GetStatusBarTexture() or rune:GetStatusBarAtlas())) then
 | 
						|
				rune:SetStatusBarTexture([[Interface\TargetingFrame\UI-StatusBar]])
 | 
						|
			end
 | 
						|
		end
 | 
						|
 | 
						|
		-- ElvUI block
 | 
						|
		if element.IsObjectType and element:IsObjectType("Frame") then
 | 
						|
			element:Show()
 | 
						|
		end
 | 
						|
		-- end block
 | 
						|
 | 
						|
		self:RegisterEvent('PLAYER_SPECIALIZATION_CHANGED', ColorPath)
 | 
						|
		self:RegisterEvent('RUNE_POWER_UPDATE', Path, true)
 | 
						|
 | 
						|
		return true
 | 
						|
	end
 | 
						|
end
 | 
						|
 | 
						|
local function Disable(self)
 | 
						|
	local element = self.Runes
 | 
						|
	if(element) then
 | 
						|
		for i = 1, #element do
 | 
						|
			element[i]:Hide()
 | 
						|
		end
 | 
						|
 | 
						|
		-- ElvUI block
 | 
						|
		if element.IsObjectType and element:IsObjectType("Frame") then
 | 
						|
			element:Hide()
 | 
						|
		end
 | 
						|
		-- end block
 | 
						|
 | 
						|
		self:UnregisterEvent('PLAYER_SPECIALIZATION_CHANGED', ColorPath)
 | 
						|
		self:UnregisterEvent('RUNE_POWER_UPDATE', Path)
 | 
						|
	end
 | 
						|
end
 | 
						|
 | 
						|
oUF:AddElement('Runes', AllPath, Enable, Disable)
 |