initial commit
This commit is contained in:
346
Libraries/oUF_Plugins/oUF_Fader/oUF_Fader.lua
Normal file
346
Libraries/oUF_Plugins/oUF_Fader/oUF_Fader.lua
Normal file
@@ -0,0 +1,346 @@
|
||||
local _, ns = ...
|
||||
local oUF = _G.oUF or ns.oUF
|
||||
assert(oUF, "oUF_Fader cannot find an instance of oUF. If your oUF is embedded into a layout, it may not be embedded properly.")
|
||||
|
||||
-------------
|
||||
-- Credits -- p3lim, Azilroka, Simpy
|
||||
-------------
|
||||
|
||||
local _G = _G
|
||||
local pairs, ipairs, type = pairs, ipairs, type
|
||||
local next, tinsert, tremove = next, tinsert, tremove
|
||||
local CreateFrame = CreateFrame
|
||||
local GetMouseFocus = GetMouseFocus
|
||||
local UnitAffectingCombat = UnitAffectingCombat
|
||||
local UnitCastingInfo = UnitCastingInfo
|
||||
local UnitChannelInfo = UnitChannelInfo
|
||||
local UnitExists = UnitExists
|
||||
local UnitHasVehicleUI = UnitHasVehicleUI
|
||||
local UnitHealth = UnitHealth
|
||||
local UnitHealthMax = UnitHealthMax
|
||||
local UnitPower = UnitPower
|
||||
local UnitPowerMax = UnitPowerMax
|
||||
local UnitPowerType = UnitPowerType
|
||||
|
||||
-- These variables will be left-over when disabled if they were used (for reuse later if they become re-enabled):
|
||||
---- Fader.HoverHooked, Fader.TargetHooked
|
||||
|
||||
local E -- ElvUI engine defined in ClearTimers
|
||||
local MIN_ALPHA, MAX_ALPHA = .35, 1
|
||||
local onRangeObjects, onRangeFrame = {}
|
||||
local PowerTypesFull = {MANA = true, FOCUS = true, ENERGY = true}
|
||||
|
||||
local function ClearTimers(element)
|
||||
if not E then E = _G.ElvUI[1] end
|
||||
|
||||
if element.configTimer then
|
||||
E:CancelTimer(element.configTimer)
|
||||
element.configTimer = nil
|
||||
end
|
||||
|
||||
if element.delayTimer then
|
||||
E:CancelTimer(element.delayTimer)
|
||||
element.delayTimer = nil
|
||||
end
|
||||
end
|
||||
|
||||
local function ToggleAlpha(self, element, endAlpha)
|
||||
element:ClearTimers()
|
||||
|
||||
if element.Smooth then
|
||||
E:UIFrameFadeOut(self, element.Smooth, self:GetAlpha(), endAlpha)
|
||||
else
|
||||
self:SetAlpha(endAlpha)
|
||||
end
|
||||
end
|
||||
|
||||
local function Update(self, _, unit)
|
||||
local element = self.Fader
|
||||
if self.isForced or (not element or not element.count or element.count <= 0) then
|
||||
self:SetAlpha(1)
|
||||
return
|
||||
end
|
||||
|
||||
unit = unit or self.unit
|
||||
|
||||
-- range fader
|
||||
if element.Range then
|
||||
if element.UpdateRange then
|
||||
element.UpdateRange(self, unit)
|
||||
end
|
||||
if element.RangeAlpha then
|
||||
ToggleAlpha(self, element, element.RangeAlpha)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
-- normal fader
|
||||
local _, powerType
|
||||
if element.Power then
|
||||
_, powerType = UnitPowerType(unit)
|
||||
end
|
||||
|
||||
if
|
||||
(element.Casting and (UnitCastingInfo(unit) or UnitChannelInfo(unit))) or
|
||||
(element.Combat and UnitAffectingCombat(unit)) or
|
||||
(element.PlayerTarget and UnitExists('target')) or
|
||||
(element.UnitTarget and UnitExists(unit..'target')) or
|
||||
(element.Focus and UnitExists('focus')) or
|
||||
(element.Health and UnitHealth(unit) < UnitHealthMax(unit)) or
|
||||
(element.Power and (PowerTypesFull[powerType] and UnitPower(unit) < UnitPowerMax(unit))) or
|
||||
(element.Vehicle and UnitHasVehicleUI(unit)) or
|
||||
(element.Hover and GetMouseFocus() == (self.__faderobject or self))
|
||||
then
|
||||
ToggleAlpha(self, element, element.MaxAlpha)
|
||||
else
|
||||
if element.Delay then
|
||||
if element.DelayAlpha then
|
||||
ToggleAlpha(self, element, element.DelayAlpha)
|
||||
end
|
||||
|
||||
element:ClearTimers()
|
||||
element.delayTimer = E:ScheduleTimer(ToggleAlpha, element.Delay, self, element, element.MinAlpha)
|
||||
else
|
||||
ToggleAlpha(self, element, element.MinAlpha)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function ForceUpdate(element)
|
||||
return Update(element.__owner, "ForceUpdate", element.__owner.unit)
|
||||
end
|
||||
|
||||
local function onRangeUpdate(frame, elapsed)
|
||||
frame.timer = (frame.timer or 0) + elapsed
|
||||
|
||||
if (frame.timer >= .20) then
|
||||
for _, object in next, onRangeObjects do
|
||||
if object:IsVisible() then
|
||||
object.Fader:ForceUpdate()
|
||||
end
|
||||
end
|
||||
|
||||
frame.timer = 0
|
||||
end
|
||||
end
|
||||
|
||||
local function HoverScript(self)
|
||||
local Fader = self.__faderelement or self.Fader
|
||||
if Fader and Fader.HoverHooked == 1 then
|
||||
Fader:ForceUpdate()
|
||||
end
|
||||
end
|
||||
|
||||
local function TargetScript(self)
|
||||
if self.Fader and self.Fader.TargetHooked == 1 then
|
||||
if self:IsShown() then
|
||||
self.Fader:ForceUpdate()
|
||||
else
|
||||
self:SetAlpha(0)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local options = {
|
||||
Range = {
|
||||
enable = function(self)
|
||||
if not onRangeFrame then
|
||||
onRangeFrame = CreateFrame('Frame')
|
||||
onRangeFrame:SetScript('OnUpdate', onRangeUpdate)
|
||||
end
|
||||
|
||||
onRangeFrame:Show()
|
||||
tinsert(onRangeObjects, self)
|
||||
end,
|
||||
disable = function(self)
|
||||
if onRangeFrame then
|
||||
for idx, obj in next, onRangeObjects do
|
||||
if obj == self then
|
||||
self.Fader.RangeAlpha = nil
|
||||
tremove(onRangeObjects, idx)
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if #onRangeObjects == 0 then
|
||||
onRangeFrame:Hide()
|
||||
end
|
||||
end
|
||||
end
|
||||
},
|
||||
Hover = {
|
||||
enable = function(self)
|
||||
if not self.Fader.HoverHooked then
|
||||
local Frame = self.__faderobject or self
|
||||
Frame:HookScript('OnEnter', HoverScript)
|
||||
Frame:HookScript('OnLeave', HoverScript)
|
||||
end
|
||||
|
||||
self.Fader.HoverHooked = 1 -- on state
|
||||
end,
|
||||
disable = function(self)
|
||||
if self.Fader.HoverHooked == 1 then
|
||||
self.Fader.HoverHooked = 0 -- off state
|
||||
end
|
||||
end
|
||||
},
|
||||
Combat = {
|
||||
enable = function(self)
|
||||
self:RegisterEvent('PLAYER_REGEN_ENABLED', Update, true)
|
||||
self:RegisterEvent('PLAYER_REGEN_DISABLED', Update, true)
|
||||
self:RegisterEvent('UNIT_FLAGS', Update)
|
||||
end,
|
||||
events = {'PLAYER_REGEN_ENABLED','PLAYER_REGEN_DISABLED','UNIT_FLAGS'}
|
||||
},
|
||||
Target = { --[[ UnitTarget, PlayerTarget ]]
|
||||
enable = function(self)
|
||||
if not self.Fader.TargetHooked then
|
||||
self:HookScript('OnShow', TargetScript)
|
||||
self:HookScript('OnHide', TargetScript)
|
||||
end
|
||||
|
||||
self.Fader.TargetHooked = 1 -- on state
|
||||
|
||||
if not self:IsShown() then
|
||||
self:SetAlpha(0)
|
||||
end
|
||||
|
||||
self:RegisterEvent('UNIT_TARGET', Update)
|
||||
self:RegisterEvent('PLAYER_TARGET_CHANGED', Update, true)
|
||||
self:RegisterEvent('PLAYER_FOCUS_CHANGED', Update, true)
|
||||
end,
|
||||
events = {'UNIT_TARGET','PLAYER_TARGET_CHANGED','PLAYER_FOCUS_CHANGED'},
|
||||
disable = function(self)
|
||||
if self.Fader.TargetHooked == 1 then
|
||||
self.Fader.TargetHooked = 0 -- off state
|
||||
end
|
||||
end
|
||||
},
|
||||
Focus = {
|
||||
enable = function(self)
|
||||
self:RegisterEvent('PLAYER_FOCUS_CHANGED', Update, true)
|
||||
end,
|
||||
events = {'PLAYER_FOCUS_CHANGED'}
|
||||
},
|
||||
Health = {
|
||||
enable = function(self)
|
||||
self:RegisterEvent('UNIT_HEALTH', Update)
|
||||
self:RegisterEvent('UNIT_MAXHEALTH', Update)
|
||||
end,
|
||||
events = {'UNIT_HEALTH','UNIT_MAXHEALTH'}
|
||||
},
|
||||
Power = {
|
||||
enable = function(self)
|
||||
self:RegisterEvent('UNIT_POWER_UPDATE', Update)
|
||||
self:RegisterEvent('UNIT_MAXPOWER', Update)
|
||||
end,
|
||||
events = {'UNIT_POWER_UPDATE','UNIT_MAXPOWER'}
|
||||
},
|
||||
Vehicle = {
|
||||
enable = function(self)
|
||||
self:RegisterEvent('UNIT_ENTERED_VEHICLE', Update, true)
|
||||
self:RegisterEvent('UNIT_EXITED_VEHICLE', Update, true)
|
||||
end,
|
||||
events = {'UNIT_ENTERED_VEHICLE','UNIT_EXITED_VEHICLE'}
|
||||
},
|
||||
Casting = {
|
||||
enable = function(self)
|
||||
self:RegisterEvent('UNIT_SPELLCAST_START', Update)
|
||||
self:RegisterEvent('UNIT_SPELLCAST_FAILED', Update)
|
||||
self:RegisterEvent('UNIT_SPELLCAST_STOP', Update)
|
||||
self:RegisterEvent('UNIT_SPELLCAST_INTERRUPTED', Update)
|
||||
self:RegisterEvent('UNIT_SPELLCAST_CHANNEL_START', Update)
|
||||
self:RegisterEvent('UNIT_SPELLCAST_CHANNEL_STOP', Update)
|
||||
end,
|
||||
events = {'UNIT_SPELLCAST_START','UNIT_SPELLCAST_FAILED','UNIT_SPELLCAST_STOP','UNIT_SPELLCAST_INTERRUPTED','UNIT_SPELLCAST_CHANNEL_START','UNIT_SPELLCAST_CHANNEL_STOP'}
|
||||
},
|
||||
MinAlpha = {
|
||||
countIgnored = true,
|
||||
enable = function(self, state)
|
||||
self.Fader.MinAlpha = state or MIN_ALPHA
|
||||
end
|
||||
},
|
||||
MaxAlpha = {
|
||||
countIgnored = true,
|
||||
enable = function(self, state)
|
||||
self.Fader.MaxAlpha = state or MAX_ALPHA
|
||||
end
|
||||
},
|
||||
Smooth = {countIgnored = true},
|
||||
DelayAlpha = {countIgnored = true},
|
||||
Delay = {countIgnored = true},
|
||||
}
|
||||
|
||||
local function CountOption(element, state, oldState)
|
||||
if state and not oldState then
|
||||
element.count = (element.count or 0) + 1
|
||||
elseif oldState and element.count and not state then
|
||||
element.count = element.count - 1
|
||||
end
|
||||
end
|
||||
|
||||
local function SetOption(element, opt, state)
|
||||
local option = ((opt == 'UnitTarget' or opt == 'PlayerTarget') and 'Target') or opt
|
||||
local oldState = element[opt]
|
||||
|
||||
if option and options[option] and (oldState ~= state) then
|
||||
element[opt] = state
|
||||
|
||||
if state then
|
||||
if type(state) == 'table' then
|
||||
state.__faderelement = element
|
||||
element.__owner.__faderobject = state
|
||||
end
|
||||
|
||||
if options[option].enable then
|
||||
options[option].enable(element.__owner, state)
|
||||
end
|
||||
else
|
||||
if options[option].events and next(options[option].events) then
|
||||
for _, event in ipairs(options[option].events) do
|
||||
element.__owner:UnregisterEvent(event, Update)
|
||||
end
|
||||
end
|
||||
|
||||
if options[option].disable then
|
||||
options[option].disable(element.__owner)
|
||||
end
|
||||
end
|
||||
|
||||
if not options[option].countIgnored then
|
||||
CountOption(element, state, oldState)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function Enable(self)
|
||||
if self.Fader then
|
||||
self.Fader.__owner = self
|
||||
self.Fader.ForceUpdate = ForceUpdate
|
||||
self.Fader.SetOption = SetOption
|
||||
self.Fader.ClearTimers = ClearTimers
|
||||
|
||||
self.Fader.MinAlpha = MIN_ALPHA
|
||||
self.Fader.MaxAlpha = MAX_ALPHA
|
||||
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
local function Disable(self)
|
||||
if self.Fader then
|
||||
for opt in pairs(options) do
|
||||
if opt == 'Target' then
|
||||
self.Fader:SetOption('UnitTarget')
|
||||
self.Fader:SetOption('PlayerTarget')
|
||||
else
|
||||
self.Fader:SetOption(opt)
|
||||
end
|
||||
end
|
||||
|
||||
self.Fader.count = nil
|
||||
self.Fader:ClearTimers()
|
||||
end
|
||||
end
|
||||
|
||||
oUF:AddElement('Fader', nil, Enable, Disable)
|
||||
Reference in New Issue
Block a user