Commit 2bdd35b8 authored by Tukz's avatar Tukz

Update oUF Classic

parent 7e42ecbc
......@@ -17,7 +17,7 @@ env:
- secure: mbIhu/gxl1XmTjBArVwvsfn6BOazK/sUAl96wQmayWyOwM1ZCKqo0o6ENSxJi+rKtsguIydM6ncdla+OTjRO1ewoZdvnkeSxLFCcfWCEKciRLk836qF2lpyAFF5LiZhSmEJyVMzqpZ2/l8T5CPtEwhLaNfZ2PuMsF+UiCJlVRJ5fcPrDYx/H6mj80t01pHW7jZq8t/mFlqGVEfLe++qnozSRlKOc0UC7EypOUeIotGMbh08cGNWQlOdL6g9i+aexkX1K9SN4aXErGggjn5cn5HCHTSxzwrxc0n7tLmhooPilQbwjl5d+ssjg251t7ugUM89h/D1kPMhtkDEEp7uqjZcOQwjBSrNIX+Oc35TxzM3JpqdArZGRfyhOD3F9rCMGGHJhz4Rn+iUNrsvV28SsMW/iuc80JP/z+GXf1Qlq0IccWdR7qLH80aWbD56XpRjiQ+9BFEq+lFYV6L/nuuJjx9wa7lzba6hw5FWjkd4sLVPOA3L3sLzyaOEApfvBr+QchHOb7EeUBjxjjrq+uTh5dJ1XN/6PtfeXjjsqhBzll588WZxhIPV8hbijXhOtjl27PkZ5vMoLZYgjBoKlK1aEC0rmavvNnzktpAV5vjPV3MzmWlTqopMukZOI6ghRctfJKg83u32/MPyFpwFjlIcIPOr5b9Tf62AjhYWN2pH1dCw=
before_script: "./utils/changelog > CHANGELOG.md"
script: curl -s https://raw.githubusercontent.com/oUF-wow/packager/master/release.sh | bash
script: curl -s https://raw.githubusercontent.com/BigWigsMods/packager/master/release.sh | bash
notifications:
email: false
......
......@@ -14,7 +14,11 @@ local hiddenParent = CreateFrame('Frame', nil, UIParent)
hiddenParent:SetAllPoints()
hiddenParent:Hide()
local function handleFrame(baseName)
local function insecureOnShow(self)
self:Hide()
end
local function handleFrame(baseName, doNotReparent)
local frame
if(type(baseName) == 'string') then
frame = _G[baseName]
......@@ -26,8 +30,9 @@ local function handleFrame(baseName)
frame:UnregisterAllEvents()
frame:Hide()
-- Keep frame hidden without causing taint
frame:SetParent(hiddenParent)
if(not doNotReparent) then
frame:SetParent(hiddenParent)
end
local health = frame.healthBar or frame.healthbar
if(health) then
......@@ -44,11 +49,6 @@ local function handleFrame(baseName)
spell:UnregisterAllEvents()
end
local altpowerbar = frame.powerBarAlt
if(altpowerbar) then
altpowerbar:UnregisterAllEvents()
end
local buffFrame = frame.BuffFrame
if(buffFrame) then
buffFrame:UnregisterAllEvents()
......@@ -75,15 +75,6 @@ function oUF:DisableBlizzard(unit)
handleFrame(ComboFrame)
elseif(unit == 'targettarget') then
handleFrame(TargetFrameToT)
elseif(unit:match('boss%d?$')) then
local id = unit:match('boss(%d)')
if(id) then
handleFrame('Boss' .. id .. 'TargetFrame')
else
for i = 1, MAX_BOSS_FRAMES do
handleFrame(string.format('Boss%dTargetFrame', i))
end
end
elseif(unit:match('party%d?$')) then
local id = unit:match('party(%d)')
if(id) then
......@@ -96,7 +87,12 @@ function oUF:DisableBlizzard(unit)
elseif(unit:match('nameplate%d+$')) then
local frame = C_NamePlate.GetNamePlateForUnit(unit)
if(frame and frame.UnitFrame) then
handleFrame(frame.UnitFrame)
if(not frame.UnitFrame.isHooked) then
frame.UnitFrame:HookScript('OnShow', insecureOnShow)
frame.UnitFrame.isHooked = true
end
handleFrame(frame.UnitFrame, true)
end
end
end
......@@ -13,11 +13,6 @@ local colors = {
health = {49 / 255, 207 / 255, 37 / 255},
disconnected = {0.6, 0.6, 0.6},
tapped = {0.6, 0.6, 0.6},
runes = {
{247 / 255, 65 / 255, 57 / 255}, -- blood
{148 / 255, 203 / 255, 247 / 255}, -- frost
{173 / 255, 235 / 255, 66 / 255}, -- unholy
},
selection = {
[ 0] = {255 / 255, 0 / 255, 0 / 255}, -- HOSTILE
[ 1] = {255 / 255, 129 / 255, 0 / 255}, -- UNFRIENDLY
......@@ -101,20 +96,8 @@ 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
colors.power[2] = colors.power.ENERGY
colors.power[3] = colors.power.COMBO_POINTS
local function colorsAndPercent(a, b, ...)
if(a <= 0 or b == 0) then
......
......@@ -28,6 +28,8 @@ At least one of the above widgets must be present for the element to work.
.initialAnchor - Anchor point for the icons. Defaults to 'BOTTOMLEFT' (string)
.filter - Custom filter list for auras to display. Defaults to 'HELPFUL' for buffs and 'HARMFUL' for
debuffs (string)
.tooltipAnchor - Anchor point for the tooltip. Defaults to 'ANCHOR_BOTTOMRIGHT', however, if a frame has anchoring
restrictions it will be set to 'ANCHOR_CURSOR' (string)
## Options Auras
......@@ -78,7 +80,7 @@ end
local function onEnter(self)
if(not self:IsVisible()) then return end
GameTooltip:SetOwner(self, 'ANCHOR_BOTTOMRIGHT')
GameTooltip:SetOwner(self, self:GetParent().__owner.tooltipAnchor)
self:UpdateTooltip()
end
......@@ -488,6 +490,12 @@ local function Enable(self)
buffs.createdIcons = buffs.createdIcons or 0
buffs.anchoredIcons = 0
if(not pcall(self.GetCenter, self)) then
buffs.tooltipAnchor = 'ANCHOR_CURSOR'
else
buffs.tooltipAnchor = buffs.tooltipAnchor or 'ANCHOR_BOTTOMRIGHT'
end
buffs:Show()
end
......@@ -499,6 +507,12 @@ local function Enable(self)
debuffs.createdIcons = debuffs.createdIcons or 0
debuffs.anchoredIcons = 0
if(not pcall(self.GetCenter, self)) then
debuffs.tooltipAnchor = 'ANCHOR_CURSOR'
else
debuffs.tooltipAnchor = debuffs.tooltipAnchor or 'ANCHOR_BOTTOMRIGHT'
end
debuffs:Show()
end
......@@ -510,6 +524,12 @@ local function Enable(self)
auras.createdIcons = auras.createdIcons or 0
auras.anchoredIcons = 0
if(not pcall(self.GetCenter, self)) then
auras.tooltipAnchor = 'ANCHOR_CURSOR'
else
auras.tooltipAnchor = auras.tooltipAnchor or 'ANCHOR_BOTTOMRIGHT'
end
auras:Show()
end
......
......@@ -25,7 +25,9 @@ A default texture will be applied if the widget is a Texture and doesn't have a
local _, ns = ...
local oUF = ns.oUF
local function Update(self, event)
local function Update(self, event, unit)
if(self.unit ~= unit) then return end
local element = self.PhaseIndicator
--[[ Callback: PhaseIndicator:PreUpdate()
......@@ -37,8 +39,8 @@ local function Update(self, event)
element:PreUpdate()
end
local isInSamePhase = UnitInPhase(self.unit) and not UnitIsWarModePhased(self.unit)
if(not isInSamePhase and UnitIsPlayer(self.unit) and UnitIsConnected(self.unit)) then
local isInSamePhase = UnitInPhase(unit) and not UnitIsWarModePhased(unit)
if(not isInSamePhase and UnitIsPlayer(unit) and UnitIsConnected(unit)) then
element:Show()
else
element:Hide()
......@@ -67,7 +69,7 @@ local function Path(self, ...)
end
local function ForceUpdate(element)
return Path(element.__owner, 'ForceUpdate')
return Path(element.__owner, 'ForceUpdate', element.__owner.unit)
end
local function Enable(self)
......@@ -76,7 +78,7 @@ local function Enable(self)
element.__owner = self
element.ForceUpdate = ForceUpdate
self:RegisterEvent('UNIT_PHASE', Path, true)
self:RegisterEvent('UNIT_PHASE', Path)
if(element:IsObjectType('Texture') and not element:GetTexture()) then
element:SetTexture([[Interface\TargetingFrame\UI-PhasingIcon]])
......
......@@ -68,10 +68,9 @@ local function Update(self, event, unit)
local mainPowerType = UnitPowerType(unit)
local mainCost, altCost = 0, 0
if(event == 'UNIT_SPELLCAST_START' or startTime ~= endTime) then
if(event == 'UNIT_SPELLCAST_START' and startTime ~= endTime) then
local costTable = GetSpellPowerCost(spellID)
for _, costInfo in pairs(costTable) do
for _, costInfo in next, costTable do
-- costInfo content:
-- - name: string (powerToken)
-- - type: number (powerType)
......
......@@ -99,35 +99,6 @@ local tagStrings = {
end
end]],
['arcanecharges'] = [[function()
if(GetSpecialization() == SPEC_MAGE_ARCANE) then
local num = UnitPower('player', Enum.PowerType.ArcaneCharges)
if(num > 0) then
return num
end
end
end]],
['arenaspec'] = [[function(u)
local id = u:match('arena(%d)$')
if(id) then
local specID = GetArenaOpponentSpec(tonumber(id))
if(specID and specID > 0) then
local _, specName = GetSpecializationInfoByID(specID)
return specName
end
end
end]],
['chi'] = [[function()
if(GetSpecialization() == SPEC_MONK_WINDWALKER) then
local num = UnitPower('player', Enum.PowerType.Chi)
if(num > 0) then
return num
end
end
end]],
['classification'] = [[function(u)
local c = UnitClassification(u)
if(c == 'rare') then
......@@ -197,15 +168,6 @@ local tagStrings = {
end
end]],
['holypower'] = [[function()
if(GetSpecialization() == SPEC_PALADIN_RETRIBUTION) then
local num = UnitPower('player', Enum.PowerType.HolyPower)
if(num > 0) then
return num
end
end
end]],
['leader'] = [[function(u)
if(UnitIsGroupLeader(u)) then
return 'L'
......@@ -395,13 +357,6 @@ local tagStrings = {
end
end]],
['soulshards'] = [[function()
local num = UnitPower('player', Enum.PowerType.SoulShards)
if(num > 0) then
return num
end
end]],
['status'] = [[function(u)
if(UnitIsDead(u)) then
return 'Dead'
......@@ -427,39 +382,56 @@ local tags = setmetatable(
},
{
__index = function(self, key)
local tagFunc = tagStrings[key]
if(tagFunc) then
local func, err = loadstring('return ' .. tagFunc)
if(func) then
func = func()
-- Want to trigger __newindex, so no rawset.
self[key] = func
tagStrings[key] = nil
return func
else
error(err, 3)
end
local tagString = tagStrings[key]
if(tagString) then
self[key] = tagString
tagStrings[key] = nil
end
return rawget(self, key)
end,
__newindex = function(self, key, val)
if(type(val) == 'string') then
tagStrings[key] = val
elseif(type(val) == 'function') then
-- So we don't clash with any custom envs.
if(getfenv(val) == _G) then
setfenv(val, _PROXY)
local func, err = loadstring('return ' .. val)
if(func) then
val = func()
else
error(err, 3)
end
end
rawset(self, key, val)
assert(type(val) == 'function', 'Tag function must be a function or a string that evaluates to a function.')
-- We don't want to clash with any custom envs
if(getfenv(val) == _G) then
-- pcall is needed for cases when Blizz functions are passed as
-- strings, for intance, 'UnitPowerMax', an attempt to set a
-- custom env will result in an error
pcall(setfenv, val, _PROXY)
end
rawset(self, key, val)
end,
}
)
_ENV._TAGS = tags
local vars = setmetatable({}, {
__newindex = function(self, key, val)
if(type(val) == 'string') then
local func = loadstring('return ' .. val)
if(func) then
val = func() or val
end
end
rawset(self, key, val)
end,
})
_ENV._VARS = vars
local tagEvents = {
['affix'] = 'UNIT_CLASSIFICATION_CHANGED',
['classification'] = 'UNIT_CLASSIFICATION_CHANGED',
......@@ -491,7 +463,6 @@ local tagEvents = {
['resting'] = 'PLAYER_UPDATE_RESTING',
['shortclassification'] = 'UNIT_CLASSIFICATION_CHANGED',
['smartlevel'] = 'UNIT_LEVEL PLAYER_LEVEL_UP UNIT_CLASSIFICATION_CHANGED',
['soulshards'] = 'UNIT_POWER_UPDATE',
['status'] = 'UNIT_HEALTH PLAYER_UPDATE_RESTING UNIT_CONNECTION',
}
......@@ -507,8 +478,8 @@ local unitlessEvents = {
}
local events = {}
local frame = CreateFrame('Frame')
frame:SetScript('OnEvent', function(self, event, unit)
local eventFrame = CreateFrame('Frame')
eventFrame:SetScript('OnEvent', function(self, event, unit)
local strings = events[event]
if(strings) then
for _, fs in next, strings do
......@@ -523,9 +494,7 @@ local onUpdates = {}
local eventlessUnits = {}
local function createOnUpdate(timer)
local OnUpdate = onUpdates[timer]
if(not OnUpdate) then
if(not onUpdates[timer]) then
local total = timer
local frame = CreateFrame('Frame')
local strings = eventlessUnits[timer]
......@@ -555,12 +524,16 @@ Used to update all tags on a frame.
--]]
local function Update(self)
if(self.__tags) then
for _, fs in next, self.__tags do
for fs in next, self.__tags do
fs:UpdateTag()
end
end
end
local tagPool = {}
local funcPool = {}
local tmp = {}
local function getTagName(tag)
local tagStart = (tag:match('>+()') or 2)
local tagEnd = tag:match('.*()<+')
......@@ -569,71 +542,7 @@ local function getTagName(tag)
return tag:sub(tagStart, tagEnd), tagStart, tagEnd
end
local function registerEvent(fontstr, event)
if(not events[event]) then events[event] = {} end
frame:RegisterEvent(event)
table.insert(events[event], fontstr)
end
local function registerEvents(fontstr, tagstr)
for tag in tagstr:gmatch(_PATTERN) do
tag = getTagName(tag)
local tagevents = tagEvents[tag]
if(tagevents) then
for event in tagevents:gmatch('%S+') do
registerEvent(fontstr, event)
end
end
end
end
local function unregisterEvents(fontstr)
for event, data in next, events do
for i, tagfsstr in next, data do
if(tagfsstr == fontstr) then
if(#data == 1) then
frame:UnregisterEvent(event)
end
table.remove(data, i)
end
end
end
end
local tagPool = {}
local funcPool = {}
local tmp = {}
--[[ Tags: frame:Tag(fs, tagstr, ...)
Used to register a tag on a unit frame.
* self - the unit frame on which to register the tag
* fs - the font string to display the tag (FontString)
* tagstr - the tag string (string)
* ... - additional optional unitID(s) the tag should update for
--]]
local function Tag(self, fs, tagstr, ...)
if(not fs or not tagstr) then return end
if(not self.__tags) then
self.__tags = {}
table.insert(self.__elements, Update)
else
-- Since people ignore everything that's good practice - unregister the tag
-- if it already exists.
for _, tag in pairs(self.__tags) do
if(fs == tag) then
-- We don't need to remove it from the __tags table as Untag handles
-- that for us.
self:Untag(fs)
end
end
end
fs.parent = self
local function getTagFunc(tagstr)
local func = tagPool[tagstr]
if(not func) then
local format, numTags = tagstr:gsub('%%', '%%%%'):gsub(_PATTERN, '%%s')
......@@ -762,9 +671,68 @@ local function Tag(self, fs, tagstr, ...)
tagPool[tagstr] = func
end
fs.UpdateTag = func
local unit = self.unit
return func
end
local function registerEvent(fontstr, event)
if(not events[event]) then events[event] = {} end
eventFrame:RegisterEvent(event)
table.insert(events[event], fontstr)
end
local function registerEvents(fontstr, tagstr)
for tag in tagstr:gmatch(_PATTERN) do
tag = getTagName(tag)
local tagevents = tagEvents[tag]
if(tagevents) then
for event in tagevents:gmatch('%S+') do
registerEvent(fontstr, event)
end
end
end
end
local function unregisterEvents(fontstr)
for event, data in next, events do
for i, tagfsstr in next, data do
if(tagfsstr == fontstr) then
if(#data == 1) then
eventFrame:UnregisterEvent(event)
end
table.remove(data, i)
end
end
end
end
local taggedFS = {}
--[[ Tags: frame:Tag(fs, tagstr, ...)
Used to register a tag on a unit frame.
* self - the unit frame on which to register the tag
* fs - the font string to display the tag (FontString)
* tagstr - the tag string (string)
* ... - additional optional unitID(s) the tag should update for
--]]
local function Tag(self, fs, tagstr, ...)
if(not fs or not tagstr) then return end
if(not self.__tags) then
self.__tags = {}
table.insert(self.__elements, Update)
elseif(self.__tags[fs]) then
-- We don't need to remove it from the __tags table as Untag handles
-- that for us.
self:Untag(fs)
end
fs.parent = self
fs.UpdateTag = getTagFunc(tagstr)
if(self.__eventless or fs.frequentUpdates) then
local timer
if(type(fs.frequentUpdates) == 'number') then
......@@ -786,13 +754,13 @@ local function Tag(self, fs, tagstr, ...)
end
for index = 1, select('#', ...) do
local unit = select(index, ...)
fs.extraUnits[unit] = true
fs.extraUnits[select(index, ...)] = true
end
end
end
table.insert(self.__tags, fs)
taggedFS[fs] = tagstr
self.__tags[fs] = true
end
--[[ Tags: frame:Untag(fs)
......@@ -813,19 +781,54 @@ local function Untag(self, fs)
end
end
for i, fontstr in next, self.__tags do
if(fontstr == fs) then
table.remove(self.__tags, i)
end
end
fs.UpdateTag = nil
taggedFS[fs] = nil
self.__tags[fs] = nil
end
oUF.Tags = {
Methods = tags,
Events = tagEvents,
SharedEvents = unitlessEvents,
Vars = vars,
RefreshMethods = function(self, tag)
if(not tag) then return end
funcPool['[' .. tag .. ']'] = nil
tag = '%[' .. tag .. '%]'
for tagstr, func in next, tagPool do
if(tagstr:match(tag)) then
tagPool[tagstr] = nil
for fs in next, taggedFS do
if(fs.UpdateTag == func) then
fs.UpdateTag = getTagFunc(tagstr)
if(fs:IsVisible()) then
fs:UpdateTag()
end
end
end
end
end
end,
RefreshEvents = function(self, tag)
if(not tag) then return end
tag = '%[' .. tag .. '%]'
for tagstr in next, tagPool do
if(tagstr:match(tag)) then
for fs, ts in next, taggedFS do
if(ts == tagstr) then
unregisterEvents(fs)
registerEvents(fs, tagstr)
end
end
end
end
end,
}
oUF:RegisterMetaFunction('Tag', Tag)
......
## Interface: 80100
## Interface: 11302
## Title: oUF
## Author: Haste, lightspark, p3lim, Rainrider
## WoW-Classic-Compatibility-Update: Tukz
## Version: @project-version@
## Notes: Unit frame framework. Does nothing by itself.
## OptionalDeps: Clique
......
......@@ -19,11 +19,6 @@ local callback, objects, headers = {}, {}, {}
local elements = {}
local activeElements = {}
local PetBattleFrameHider = CreateFrame('Frame', (global or parent) .. '_PetBattleFrameHider', UIParent, 'SecureHandlerStateTemplate')
PetBattleFrameHider:SetAllPoints()
PetBattleFrameHider:SetFrameStrata('LOW')
RegisterStateDriver(PetBattleFrameHider, 'visibility', '[petbattle] hide; show')
-- updating of "invalid" units.
local function enableTargetUpdate(object)
object.onUpdateFrequency = object.onUpdateFrequency or .5
......@@ -626,7 +621,7 @@ do
local isPetHeader = template:match('PetHeader')
local name = overrideName or generateName(nil, ...)
local header = CreateFrame('Frame', name, PetBattleFrameHider, template)
local header = CreateFrame('Frame', name, UIParent, template)
header:SetAttribute('template', 'SecureUnitButtonTemplate, SecureHandlerStateTemplate, SecureHandlerEnterLeaveTemplate')
for i = 1, select('#', ...), 2 do
......@@ -644,7 +639,7 @@ do
-- We set it here so layouts can't directly override it.
header:SetAttribute('initialConfigFunction', initialConfigFunction)
header:SetAttribute('_initialAttributeNames', '_onenter,_onleave,refreshUnitChange,_onstate-vehicleui')
header:SetAttribute('_initialAttributeNames', '_onenter,_onleave,refreshUnitChange')
header:SetAttribute('_initialAttribute-_onenter', [[
local snippet = self:GetAttribute('clickcast_onenter')
if(snippet) then
......@@ -665,14 +660,6 @@ do
UnregisterStateDriver(self, 'vehicleui')
end
]])
header:SetAttribute('_initialAttribute-_onstate-vehicleui', [[
local unit = self:GetAttribute('unit')
if(newstate == 'vehicle' and unit and UnitPlayerOrPetInRaid(unit) and not UnitTargetsVehicleInRaidUI(unit)) then
self:SetAttribute('toggleForVehicle', false)
else
self:SetAttribute('toggleForVehicle', true)
end
]])
header:SetAttribute('oUF-headerType', isPetHeader and 'pet' or 'group')
if(Clique) then
......@@ -718,7 +705,7 @@ function oUF:Spawn(unit, overrideName)
unit = unit:lower()
local name = overrideName or generateName(unit)
local object = CreateFrame('Button', name, PetBattleFrameHider, 'SecureUnitButtonTemplate')
local object = CreateFrame('Button', name, UIParent, 'SecureUnitButtonTemplate')
Private.UpdateUnits(object, unit)
self:DisableBlizzard(unit)
......
......@@ -4,164 +4,6 @@ local Private = oUF.Private
local enableTargetUpdate = Private.enableTargetUpdate
local function updateArenaPreparationElements(self, event, elementName, specID)
local element = self[elementName]
if(element and self:IsElementEnabled(elementName)) then
if(element.OverrideArenaPreparation) then
--[[ Override: Health.OverrideArenaPreparation(self, event, specID)
Used to completely override the internal update function for arena preparation.
* self - the parent object
* event - the event triggering the update (string)
* specID - the specialization ID for the opponent (number)
--]]
--[[ Override: Power.OverrideArenaPreparation(self, event, specID)
Used to completely override the internal update function for arena preparation.
* self - the parent object
* event - the event triggering the update (string)
* specID - the specialization ID for the opponent (number)
--]]
element.OverrideArenaPreparation(self, event, specID)
return
end
element:SetMinMaxValues(0, 1)
element:SetValue(1)
if(element.UpdateColorArenaPreparation) then
--[[ Override: Health:UpdateColor(specID)
Used to completely override the internal function for updating the widget's colors
during arena preparation.
* self - the Health element
* specID - the specialization ID for the opponent (number)
--]]
--[[ Override: Power:UpdateColor(specID)
Used to completely override the internal function for updating the widget's colors
during arena preparation.
* self - the Power element
* specID - the specialization ID for the opponent (number)
--]]
element:UpdateColorArenaPreparation(specID)
else
-- this section just replicates the color options available to the Health and Power elements