mirror of
https://github.com/Bluewhale1337/ElvUIModernized.git
synced 2026-07-29 17:25:27 +00:00
big commit
This commit is contained in:
@@ -1,7 +1,8 @@
|
|||||||
## Interface: 11200
|
## Interface: 11200
|
||||||
## Title: !Compatibility
|
## Title: !Compatibility
|
||||||
## Notes: Compatibility functions for Vanilla
|
## Notes: Compatibility functions for Vanilla
|
||||||
## Version: 1.0
|
## Version: 1.1
|
||||||
|
|
||||||
|
errorHandler.lua
|
||||||
api\api.xml
|
api\api.xml
|
||||||
debugTools.lua
|
slashCommands.lua
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
<Ui xmlns="http://www.blizzard.com/wow/ui/">
|
<Ui xmlns="http://www.blizzard.com/wow/ui/">
|
||||||
<Script file="wowLua.lua"/>
|
<Script file="luaAPI.lua"/>
|
||||||
|
<Include file="..\libs\libs.xml"/>
|
||||||
<Script file="wowAPI.lua"/>
|
<Script file="wowAPI.lua"/>
|
||||||
</Ui>
|
</Ui>
|
||||||
@@ -0,0 +1,201 @@
|
|||||||
|
-- Cache global variables
|
||||||
|
local assert = assert
|
||||||
|
local error = error
|
||||||
|
local geterrorhandler = geterrorhandler
|
||||||
|
local pairs = pairs
|
||||||
|
local pcall = pcall
|
||||||
|
local tostring = tostring
|
||||||
|
local type = type
|
||||||
|
local unpack = unpack
|
||||||
|
local ceil, floor = math.ceil, math.floor
|
||||||
|
local find, format, gsub, sub = string.find, string.format, string.gsub, string.sub
|
||||||
|
local getn, insert = table.getn, table.insert
|
||||||
|
|
||||||
|
math.huge = 1/0
|
||||||
|
string.gmatch = string.gfind
|
||||||
|
|
||||||
|
function difftime(time2, time1)
|
||||||
|
assert(type(time2) == "number", format("bad argument #1 to 'difftime' (number expected, got %s)", time2 and type(time2) or "no value"))
|
||||||
|
assert(not time1 or type(time1) == "number", format("bad argument #2 to 'difftime' (number expected, got %s)", time1 and type(time1) or "no value"))
|
||||||
|
|
||||||
|
return time1 and time2 - time1 or time2
|
||||||
|
end
|
||||||
|
|
||||||
|
function select(n, ...)
|
||||||
|
assert(type(n) == "number" or type(n) == "string", format("bad argument #1 to 'select' (number expected, got %s)", n and type(n) or "no value"))
|
||||||
|
|
||||||
|
if type(n) == "string" and n == "#" then
|
||||||
|
if type(arg) == "table" then
|
||||||
|
return getn(arg)
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local temp = {}
|
||||||
|
|
||||||
|
for i = n, getn(arg) do
|
||||||
|
insert(temp, arg[i])
|
||||||
|
end
|
||||||
|
|
||||||
|
return unpack(temp)
|
||||||
|
end
|
||||||
|
|
||||||
|
function math.modf(i)
|
||||||
|
assert(type(i) == "number", format("bad argument #1 to 'modf' (number expected, got %s)", i and type(i) or "no value"))
|
||||||
|
|
||||||
|
local int = i >= 0 and floor(i) or ceil(i)
|
||||||
|
|
||||||
|
return int, i - int
|
||||||
|
end
|
||||||
|
|
||||||
|
function string.join(delimiter, ...)
|
||||||
|
assert(type(delimiter) == "string" or type(delimiter) == "number", format("bad argument #1 to 'join' (string expected, got %s)", delimiter and type(delimiter) or "no value"))
|
||||||
|
|
||||||
|
local size = getn(arg)
|
||||||
|
if size == 0 then
|
||||||
|
return ""
|
||||||
|
end
|
||||||
|
|
||||||
|
local text = arg[1]
|
||||||
|
for i = 2, size do
|
||||||
|
text = text..delimiter..arg[i]
|
||||||
|
end
|
||||||
|
|
||||||
|
return text
|
||||||
|
end
|
||||||
|
strjoin = string.join
|
||||||
|
|
||||||
|
function string.match(str, pattern, index)
|
||||||
|
assert(type(str) == "string" or type(str) == "number", format("bad argument #1 to 'match' (string expected, got %s)", str and type(str) or "no value"))
|
||||||
|
assert(type(pattern) == "string", format("bad argument #2 to 'match' (string expected, got %s)", pattern and type(pattern) or "no value"))
|
||||||
|
|
||||||
|
str = type(str) == "number" and tostring(str) or str
|
||||||
|
local _, _, match = find(index and sub(str, index) or str, "("..pattern..")")
|
||||||
|
|
||||||
|
return match
|
||||||
|
end
|
||||||
|
strmatch = string.match
|
||||||
|
|
||||||
|
function string.split(delimiter, str)
|
||||||
|
assert(type(delimiter) == "string" or type(str) == "number", format("bad argument #1 to 'split' (string expected, got %s)", delimiter and type(delimiter) or "no value"))
|
||||||
|
assert(type(str) == "string", format("bad argument #2 to 'split' (string expected, got %s)", str and type(str) or "no value"))
|
||||||
|
|
||||||
|
local fields = {}
|
||||||
|
local pattern = format("([^%s]+)", delimiter)
|
||||||
|
|
||||||
|
str = type(str) == "number" and tostring(str) or str
|
||||||
|
gsub(str, pattern, function(c) fields[getn(fields) + 1] = c end)
|
||||||
|
|
||||||
|
return unpack(fields)
|
||||||
|
end
|
||||||
|
strsplit = string.split
|
||||||
|
|
||||||
|
function string.trim(str, chars)
|
||||||
|
assert(type(str) == "string" or type(str) == "number", format("bad argument #1 to 'trim' (string expected, got %s)", delimiter and type(delimiter) or "no value"))
|
||||||
|
|
||||||
|
str = type(str) == "number" and tostring(str) or str
|
||||||
|
--[[
|
||||||
|
if chars then
|
||||||
|
local size = string.len(chars)
|
||||||
|
local token = ""
|
||||||
|
|
||||||
|
for i = 1, size do
|
||||||
|
token = token .. string.sub(chars, i, i + 1) .. "*"
|
||||||
|
|
||||||
|
if size > 1 and i < size then
|
||||||
|
token = token.."|"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
token = "["..token.."]"
|
||||||
|
|
||||||
|
local trimed = 1
|
||||||
|
while trimed == 1 do
|
||||||
|
str, trimed = string.gsub(str, "^"..token.."(._)"..token.."$", "")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- remove leading/trailing [space][tab][return][newline]
|
||||||
|
str = string.gsub(str, "^%s*(.-)%s*$", "%1")
|
||||||
|
end
|
||||||
|
|
||||||
|
return str
|
||||||
|
]]
|
||||||
|
|
||||||
|
return string.gsub(str, "^%s*(.-)%s*$", "%1")
|
||||||
|
end
|
||||||
|
strtrim = string.trim
|
||||||
|
|
||||||
|
function table.wipe(t)
|
||||||
|
assert(type(t) == "table", format("bad argument #1 to 'wipe' (table expected, got %s)", t and type(t) or "no value"))
|
||||||
|
|
||||||
|
for k in pairs(t) do
|
||||||
|
t[k] = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
return t
|
||||||
|
end
|
||||||
|
wipe = table.wipe
|
||||||
|
|
||||||
|
local LOCAL_ToStringAllTemp = {}
|
||||||
|
function tostringall(...)
|
||||||
|
local n = getn(arg)
|
||||||
|
-- Simple versions for common argument counts
|
||||||
|
if (n == 1) then
|
||||||
|
return tostring(arg[1])
|
||||||
|
elseif (n == 2) then
|
||||||
|
return tostring(arg[1]), tostring(arg[2])
|
||||||
|
elseif (n == 3) then
|
||||||
|
return tostring(arg[1]), tostring(arg[2]), tostring(arg[3])
|
||||||
|
elseif (n == 0) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local needfix
|
||||||
|
for i = 1, n do
|
||||||
|
local v = arg[i]
|
||||||
|
if (type(v) ~= "string") then
|
||||||
|
needfix = i
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if (not needfix) then return unpack(arg) end
|
||||||
|
|
||||||
|
wipe(LOCAL_ToStringAllTemp)
|
||||||
|
for i = 1, needfix - 1 do
|
||||||
|
LOCAL_ToStringAllTemp[i] = arg[i]
|
||||||
|
end
|
||||||
|
for i = needfix, n do
|
||||||
|
LOCAL_ToStringAllTemp[i] = tostring(arg[i])
|
||||||
|
end
|
||||||
|
return unpack(LOCAL_ToStringAllTemp)
|
||||||
|
end
|
||||||
|
|
||||||
|
local LOCAL_PrintHandler = function(...)
|
||||||
|
DEFAULT_CHAT_FRAME:AddMessage(strjoin(" ", tostringall(unpack(arg))))
|
||||||
|
end
|
||||||
|
|
||||||
|
function setprinthandler(func)
|
||||||
|
if (type(func) ~= "function") then
|
||||||
|
error("Invalid print handler")
|
||||||
|
else
|
||||||
|
LOCAL_PrintHandler = func
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function getprinthandler() return LOCAL_PrintHandler end
|
||||||
|
|
||||||
|
local function print_inner(...)
|
||||||
|
local ok, err = pcall(LOCAL_PrintHandler, unpack(arg))
|
||||||
|
if (not ok) then
|
||||||
|
local func = geterrorhandler()
|
||||||
|
func(err)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function print(...)
|
||||||
|
pcall(print_inner, unpack(arg))
|
||||||
|
end
|
||||||
|
|
||||||
|
SLASH_PRINT1 = "/print"
|
||||||
|
SlashCmdList["PRINT"] = print
|
||||||
@@ -1,39 +1,134 @@
|
|||||||
-- Cache global variables
|
-- Cache global variables
|
||||||
local _G = getfenv()
|
local _G = _G
|
||||||
local assert = assert
|
local assert = assert
|
||||||
local error = error
|
local date = date
|
||||||
|
local pairs = pairs
|
||||||
|
local tonumber = tonumber
|
||||||
local type = type
|
local type = type
|
||||||
local unpack = unpack
|
local unpack = unpack
|
||||||
local date = date
|
local format, gsub, lower, match, upper = string.format, string.gsub, string.lower, string.match, string.upper
|
||||||
local gsub = string.gsub
|
local getn = table.getn
|
||||||
|
-- WoW API
|
||||||
|
local GetQuestGreenRange = GetQuestGreenRange
|
||||||
|
local GetRealZoneText = GetRealZoneText
|
||||||
|
local IsInInstance = IsInInstance
|
||||||
|
local UnitBuff = UnitBuff
|
||||||
|
local UnitDebuff = UnitDebuff
|
||||||
|
local UnitLevel = UnitLevel
|
||||||
|
-- WoW Variables
|
||||||
|
local DUNGEON_DIFFICULTY1 = DUNGEON_DIFFICULTY1
|
||||||
|
local TIMEMANAGER_AM = gsub(TIME_TWELVEHOURAM, "^.-(%w+)$", "%1")
|
||||||
|
local TIMEMANAGER_PM = gsub(TIME_TWELVEHOURPM, "^.-(%w+)$", "%1")
|
||||||
|
-- Libs
|
||||||
|
local LBC = LibStub("LibBabble-Class-3.0"):GetLookupTable()
|
||||||
|
local LBZ = LibStub("LibBabble-Zone-3.0"):GetLookupTable()
|
||||||
|
|
||||||
|
CLASS_SORT_ORDER = {
|
||||||
|
"WARRIOR",
|
||||||
|
"PALADIN",
|
||||||
|
"PRIEST",
|
||||||
|
"SHAMAN",
|
||||||
|
"DRUID",
|
||||||
|
"ROGUE",
|
||||||
|
"MAGE",
|
||||||
|
"WARLOCK",
|
||||||
|
"HUNTER"
|
||||||
|
}
|
||||||
|
MAX_CLASSES = getn(CLASS_SORT_ORDER)
|
||||||
|
|
||||||
|
LOCALIZED_CLASS_NAMES_MALE = {}
|
||||||
|
LOCALIZED_CLASS_NAMES_FEMALE = {}
|
||||||
|
|
||||||
|
CLASS_ICON_TCOORDS = {
|
||||||
|
["WARRIOR"] = {0, 0.25, 0, 0.25},
|
||||||
|
["MAGE"] = {0.25, 0.49609375, 0, 0.25},
|
||||||
|
["ROGUE"] = {0.49609375, 0.7421875, 0, 0.25},
|
||||||
|
["DRUID"] = {0.7421875, 0.98828125, 0, 0.25},
|
||||||
|
["HUNTER"] = {0, 0.25, 0.25, 0.5},
|
||||||
|
["SHAMAN"] = {0.25, 0.49609375, 0.25, 0.5},
|
||||||
|
["PRIEST"] = {0.49609375, 0.7421875, 0.25, 0.5},
|
||||||
|
["WARLOCK"] = {0.7421875, 0.98828125, 0.25, 0.5},
|
||||||
|
["PALADIN"] = {0, 0.25, 0.5, 0.75}
|
||||||
|
}
|
||||||
|
|
||||||
|
QuestDifficultyColors = {
|
||||||
|
["impossible"] = {r = 1.00, g = 0.10, b = 0.10},
|
||||||
|
["verydifficult"] = {r = 1.00, g = 0.50, b = 0.25},
|
||||||
|
["difficult"] = {r = 1.00, g = 1.00, b = 0.00},
|
||||||
|
["standard"] = {r = 0.25, g = 0.75, b = 0.25},
|
||||||
|
["trivial"] = {r = 0.50, g = 0.50, b = 0.50},
|
||||||
|
["header"] = {r = 0.70, g = 0.70, b = 0.70}
|
||||||
|
}
|
||||||
|
|
||||||
|
function HookScript(frame, scriptType, handler)
|
||||||
|
assert(type(frame) == "table" and frame.GetScript and type(scriptType) == "string" and type(handler) == "function", "Usage: HookScript(frame, \"type\", function)")
|
||||||
|
|
||||||
|
local original_scipt = frame:GetScript(scriptType)
|
||||||
|
if original_scipt then
|
||||||
|
frame:SetScript(scriptType, function(...)
|
||||||
|
local original_return = {original_scipt(unpack(arg))}
|
||||||
|
handler(unpack(arg))
|
||||||
|
|
||||||
|
return unpack(original_return)
|
||||||
|
end)
|
||||||
|
else
|
||||||
|
frame:SetScript(scriptType, handler)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function hooksecurefunc(arg1, arg2, arg3)
|
function hooksecurefunc(arg1, arg2, arg3)
|
||||||
if type(arg1) == "string" then
|
local isMethod = type(arg1) == "table" and type(arg2) == "string" and type(arg1[arg2]) == "function" and type(arg3) == "function"
|
||||||
|
assert(isMethod or (type(arg1) == "string" and type(_G[arg1]) == "function" and type(arg2) == "function"), "Usage: hooksecurefunc([table,] \"functionName\", hookfunc)")
|
||||||
|
|
||||||
|
if not isMethod then
|
||||||
arg1, arg2, arg3 = _G, arg1, arg2
|
arg1, arg2, arg3 = _G, arg1, arg2
|
||||||
end
|
end
|
||||||
|
|
||||||
local orig = arg1[arg2]
|
local original_func = arg1[arg2]
|
||||||
if type(orig) ~= "function" then
|
|
||||||
error("The function "..arg2.." does not exist", 2)
|
|
||||||
end
|
|
||||||
|
|
||||||
arg1[arg2] = function(...)
|
arg1[arg2] = function(...)
|
||||||
local tmp = {orig(unpack(arg))}
|
local original_return = {original_func(unpack(arg))}
|
||||||
arg3(unpack(arg))
|
arg3(unpack(arg))
|
||||||
return unpack(tmp)
|
|
||||||
|
return unpack(original_return)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function noop() end
|
--[[ issecurevariable
|
||||||
function HookScript(frame, method, func)
|
Returns 1, nil for undefined variables. This is because an undefined variable is secure since you have not tainted it.
|
||||||
assert(frame, "HookScript: frame argument missing")
|
Returns 1, nil for all untainted variables (i.e. Blizzard variables).
|
||||||
|
Returns nil for any global variable that is hooked insecurely (tainted), even unprotected ones like UnitName().
|
||||||
|
Returns nil for all user defined global variables.
|
||||||
|
If a table is passed first, it checks table.variable (e.g. issecurevariable(PlayerFrame, "Show") checks PlayerFrame["Show"] or PlayerFrame.Show (they are the same thing)).
|
||||||
|
]]
|
||||||
|
function issecurevariable(tab, var)
|
||||||
|
-- assert(type(tab) == "table" and type(var) == "string", "Usage: issecurevariable([table,] \"variable\")")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
local orig = frame:GetScript(method) or noop
|
function tContains(table, item)
|
||||||
frame:SetScript(method, function(...)
|
local index = 1
|
||||||
local tmp = {orig(unpack(arg))}
|
|
||||||
func(unpack(arg))
|
while table[index] do
|
||||||
return unpack(tmp)
|
if item == table[index] then
|
||||||
end)
|
return 1
|
||||||
|
end
|
||||||
|
index = index + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
function UnitAura(unit, i, filter)
|
||||||
|
assert((type(unit) == "string" or type(unit) == "number") and (type(i) == "string" or type(i) == "number"), "Usage: UnitAura(\"unit\", index [, filter])")
|
||||||
|
|
||||||
|
if not filter or match(filter, "(HELPFUL)") then
|
||||||
|
local name, rank, aura, count, duration, maxDuration = UnitBuff(unit, i, filter)
|
||||||
|
return name, rank, aura, count, nil, duration or 0, maxDuration or 0
|
||||||
|
else
|
||||||
|
local name, rank, aura, count, dType, duration, maxDuration = UnitDebuff(unit, i, filter)
|
||||||
|
return name, rank, aura, count, dType, duration or 0, maxDuration or 0
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function BetterDate(formatString, timeVal)
|
function BetterDate(formatString, timeVal)
|
||||||
@@ -47,29 +142,8 @@ function BetterDate(formatString, timeVal)
|
|||||||
return date(formatString, timeVal)
|
return date(formatString, timeVal)
|
||||||
end
|
end
|
||||||
|
|
||||||
RAID_CLASS_COLORS = {
|
|
||||||
["HUNTER"] = {r = 0.67, g = 0.83, b = 0.45},
|
|
||||||
["WARLOCK"] = {r = 0.58, g = 0.51, b = 0.79},
|
|
||||||
["PRIEST"] = {r = 1.0, g = 1.0, b = 1.0},
|
|
||||||
["PALADIN"] = {r = 0.96, g = 0.55, b = 0.73},
|
|
||||||
["MAGE"] = {r = 0.41, g = 0.8, b = 0.94},
|
|
||||||
["ROGUE"] = {r = 1.0, g = 0.96, b = 0.41},
|
|
||||||
["DRUID"] = {r = 1.0, g = 0.49, b = 0.04},
|
|
||||||
["WARRIOR"] = {r = 0.78, g = 0.61, b = 0.43},
|
|
||||||
};
|
|
||||||
|
|
||||||
QuestDifficultyColors = {
|
|
||||||
["impossible"] = {r = 1.00, g = 0.10, b = 0.10};
|
|
||||||
["verydifficult"] = {r = 1.00, g = 0.50, b = 0.25};
|
|
||||||
["difficult"] = {r = 1.00, g = 1.00, b = 0.00};
|
|
||||||
["standard"] = {r = 0.25, g = 0.75, b = 0.25};
|
|
||||||
["trivial"] = {r = 0.50, g = 0.50, b = 0.50};
|
|
||||||
["header"] = {r = 0.70, g = 0.70, b = 0.70};
|
|
||||||
};
|
|
||||||
|
|
||||||
function GetQuestDifficultyColor(level)
|
function GetQuestDifficultyColor(level)
|
||||||
local levelDiff = level - UnitLevel("player")
|
local levelDiff = level - UnitLevel("player")
|
||||||
local color
|
|
||||||
if levelDiff >= 5 then
|
if levelDiff >= 5 then
|
||||||
return QuestDifficultyColors["impossible"]
|
return QuestDifficultyColors["impossible"]
|
||||||
elseif levelDiff >= 3 then
|
elseif levelDiff >= 3 then
|
||||||
@@ -83,21 +157,204 @@ function GetQuestDifficultyColor(level)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function EasyMenu(menuList, menuFrame, anchor, x, y, displayMode, autoHideDelay)
|
function FillLocalizedClassList(tab, female)
|
||||||
if displayMode == "MENU" then
|
assert(type(tab) == "table", "Usage: FillLocalizedClassList(classTable[, isFemale])")
|
||||||
menuFrame.displayMode = displayMode
|
|
||||||
|
for _, engClass in ipairs(CLASS_SORT_ORDER) do
|
||||||
|
if female then
|
||||||
|
tab[engClass] = LBC[engClass]
|
||||||
|
else
|
||||||
|
tab[engClass] = LBC[gsub(lower(engClass), "^%l", upper)]
|
||||||
end
|
end
|
||||||
UIDropDownMenu_Initialize(menuFrame, EasyMenu_Initialize, displayMode)
|
|
||||||
ToggleDropDownMenu(1, nil, menuFrame, anchor, x, y, menuList)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function EasyMenu_Initialize()
|
return true
|
||||||
print(level, info)
|
end
|
||||||
for index = 1, getn(menuList) do
|
|
||||||
local value = menuList[index]
|
FillLocalizedClassList(LOCALIZED_CLASS_NAMES_MALE)
|
||||||
if value.text then
|
FillLocalizedClassList(LOCALIZED_CLASS_NAMES_FEMALE, true)
|
||||||
value.index = index;
|
|
||||||
UIDropDownMenu_AddButton(value, level)
|
local zoneInfo = {
|
||||||
|
-- Battlegrounds
|
||||||
|
[LBZ["Warsong Gulch"]] = {mapID = 443, maxPlayers = 10},
|
||||||
|
[LBZ["Arathi Basin"]] = {mapID = 461, maxPlayers = 15},
|
||||||
|
[LBZ["Alterac Valley"]] = {mapID = 401, maxPlayers = 40},
|
||||||
|
|
||||||
|
-- Raids
|
||||||
|
[LBZ["Zul'Gurub"]] = {mapID = 309, maxPlayers = 20},
|
||||||
|
[LBZ["Onyxia's Lair"]] = {mapID = 249, maxPlayers = 40},
|
||||||
|
[LBZ["Molten Core"]] = {mapID = 409, maxPlayers = 40},
|
||||||
|
[LBZ["Ruins of Ahn'Qiraj"]] = {mapID = 509, maxPlayers = 20},
|
||||||
|
[LBZ["Temple of Ahn'Qiraj"]] = {mapID = 531, maxPlayers = 40},
|
||||||
|
[LBZ["Blackwing Lair"]] = {mapID = 469, maxPlayers = 40},
|
||||||
|
[LBZ["Naxxramas"]] = {mapID = 533, maxPlayers = 40},
|
||||||
|
}
|
||||||
|
|
||||||
|
local mapByID = {}
|
||||||
|
for mapName in pairs(zoneInfo) do
|
||||||
|
mapByID[zoneInfo[mapName].mapID] = mapName
|
||||||
|
end
|
||||||
|
|
||||||
|
local function GetMaxPlayersByType(instanceType, zoneName)
|
||||||
|
if instanceType == "none" then
|
||||||
|
return 40
|
||||||
|
elseif instanceType == "party" then
|
||||||
|
return 5
|
||||||
|
elseif instanceType == "arena" then
|
||||||
|
return 5
|
||||||
|
elseif zoneName ~= "" and zoneInfo[zoneName] then
|
||||||
|
if instanceType == "pvp" then
|
||||||
|
return zoneInfo[zoneName].maxPlayers
|
||||||
|
elseif instanceType == "raid" then
|
||||||
|
return zoneInfo[zoneName].maxPlayers
|
||||||
|
end
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function GetInstanceInfo()
|
||||||
|
local inInstance, instanceType = IsInInstance()
|
||||||
|
if not inInstance then return end
|
||||||
|
|
||||||
|
local name = GetRealZoneText()
|
||||||
|
|
||||||
|
local difficulty = 1
|
||||||
|
local difficultyName = DUNGEON_DIFFICULTY1
|
||||||
|
local maxPlayers = GetMaxPlayersByType(instanceType, name)
|
||||||
|
|
||||||
|
difficultyName = format("%d %s", maxPlayers, difficultyName)
|
||||||
|
|
||||||
|
return name, instanceType, difficulty, difficultyName, maxPlayers
|
||||||
|
end
|
||||||
|
|
||||||
|
function GetCurrentMapAreaID()
|
||||||
|
if not IsInInstance() then return end
|
||||||
|
local zoneName = GetRealZoneText()
|
||||||
|
|
||||||
|
if zoneName ~= "" and zoneInfo[zoneName] then
|
||||||
|
return zoneInfo[zoneName].mapID
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function GetMapNameByID(id)
|
||||||
|
assert(type(id) == "string" or type(id) == "number", format("Bad argument #1 to \"GetMapNameByID\" (number expected, got %s)", id and type(id) or "no value"))
|
||||||
|
|
||||||
|
return mapByID[tonumber(id)]
|
||||||
|
end
|
||||||
|
|
||||||
|
local arrow
|
||||||
|
function GetPlayerFacing()
|
||||||
|
if not arrow then
|
||||||
|
local obj = Minimap
|
||||||
|
for i = 1, obj:GetNumChildren() do
|
||||||
|
local child = select(i, obj:GetChildren())
|
||||||
|
if child and child.GetModel and child:GetModel() == "interface\\minimap\\minimaparrow.m2" then
|
||||||
|
arrow = child
|
||||||
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
return arrow and arrow:GetFacing()
|
||||||
|
end
|
||||||
|
|
||||||
|
function ToggleFrame(frame)
|
||||||
|
if frame:IsShown() then
|
||||||
|
HideUIPanel(frame)
|
||||||
|
else
|
||||||
|
ShowUIPanel(frame)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function OnOrientationChanged(self, orientation)
|
||||||
|
self.texturePointer.verticalOrientation = orientation == "VERTICAL"
|
||||||
|
|
||||||
|
if self.texturePointer.verticalOrientation then
|
||||||
|
self.texturePointer:SetPoint("BOTTOMLEFT", self)
|
||||||
|
else
|
||||||
|
self.texturePointer:SetPoint("LEFT", self)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function OnSizeChanged()
|
||||||
|
local width, height = ElvUF_Player.Health:GetWidth(), ElvUF_Player.Health:GetHeight()
|
||||||
|
this.texturePointer.width = width
|
||||||
|
this.texturePointer.height = height
|
||||||
|
this.texturePointer:SetWidth(width)
|
||||||
|
this.texturePointer:SetHeight(height)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function OnValueChanged()
|
||||||
|
local _, max = this:GetMinMaxValues()
|
||||||
|
if this.texturePointer.verticalOrientation then
|
||||||
|
this.texturePointer:SetHeight(this.texturePointer.height * (arg1 / max))
|
||||||
|
else
|
||||||
|
this.texturePointer:SetWidth(this.texturePointer.width * (arg1 / max))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function CreateStatusBarTexturePointer(statusbar)
|
||||||
|
assert(type(statusbar) == "table", format("Bad argument #1 to \"CreateStatusBarTexturePointer\" (table expected, got %s)", statusbar and type(statusbar) or "no value"))
|
||||||
|
assert(statusbar.GetObjectType and statusbar:GetObjectType() == "StatusBar", "Bad argument #1 to \"CreateStatusBarTexturePointer\" (statusbar object expected)")
|
||||||
|
|
||||||
|
local f = statusbar:CreateTexture()
|
||||||
|
f.width = statusbar:GetWidth()
|
||||||
|
f.height = statusbar:GetHeight()
|
||||||
|
f.vertical = statusbar:GetOrientation() == "VERTICAL"
|
||||||
|
f:SetWidth(f.width)
|
||||||
|
f:SetHeight(f.height)
|
||||||
|
|
||||||
|
if f.verticalOrientation then
|
||||||
|
f:SetPoint("BOTTOMLEFT", statusbar)
|
||||||
|
else
|
||||||
|
f:SetPoint("LEFT", statusbar)
|
||||||
|
end
|
||||||
|
|
||||||
|
statusbar.texturePointer = f
|
||||||
|
|
||||||
|
statusbar:SetScript("OnSizeChanged", OnSizeChanged)
|
||||||
|
statusbar:SetScript("OnValueChanged", OnValueChanged)
|
||||||
|
|
||||||
|
hooksecurefunc(statusbar, "SetOrientation", OnOrientationChanged)
|
||||||
|
|
||||||
|
return f
|
||||||
|
end
|
||||||
|
|
||||||
|
local threatColors = {
|
||||||
|
[0] = {0.69, 0.69, 0.69},
|
||||||
|
[1] = {1, 1, 0.47},
|
||||||
|
[2] = {1, 0.6, 0},
|
||||||
|
[3] = {1, 0, 0}
|
||||||
|
}
|
||||||
|
|
||||||
|
function GetThreatStatusColor(statusIndex)
|
||||||
|
if not (type(statusIndex) == "number" and statusIndex >= 0 and statusIndex < 4) then
|
||||||
|
statusIndex = 0
|
||||||
|
end
|
||||||
|
|
||||||
|
return threatColors[statusIndex][1], threatColors[statusIndex][2], threatColors[statusIndex][3]
|
||||||
|
end
|
||||||
|
|
||||||
|
function GetThreatStatus(currentThreat, maxThreat)
|
||||||
|
assert(type(currentThreat) == "number" and type(maxThreat) == "number", "Usage: GetThreatStatus(currentThreat, maxThreat)")
|
||||||
|
|
||||||
|
if not maxThreat or maxThreat == 0 then
|
||||||
|
maxThreat = 0
|
||||||
|
maxThreat = 1
|
||||||
|
end
|
||||||
|
|
||||||
|
local threatPercent = currentThreat / maxThreat * 100
|
||||||
|
|
||||||
|
if threatPercent >= 100 then
|
||||||
|
return 3, threatPercent
|
||||||
|
elseif threatPercent < 100 and threatPercent >= 80 then
|
||||||
|
return 2, threatPercent
|
||||||
|
elseif threatPercent < 80 and threatPercent >= 50 then
|
||||||
|
return 1, threatPercent
|
||||||
|
else
|
||||||
|
return 0, threatPercent
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -1,142 +0,0 @@
|
|||||||
--Cache global variables
|
|
||||||
local assert = assert
|
|
||||||
local error = error
|
|
||||||
local geterrorhandler = geterrorhandler
|
|
||||||
local pairs = pairs
|
|
||||||
local pcall = pcall
|
|
||||||
local tostring = tostring
|
|
||||||
local type = type
|
|
||||||
local unpack = unpack
|
|
||||||
local ceil, floor = math.ceil, math.floor
|
|
||||||
local format, gsub = string.format, string.gsub
|
|
||||||
local getn, insert = table.getn, table.insert
|
|
||||||
|
|
||||||
function select(n, ...)
|
|
||||||
assert(type(n) == "number" or type(n) == "string", "bad argument #1 to 'select' (number expected, got no value)")
|
|
||||||
|
|
||||||
if type(n) == "string" and n == "#" then
|
|
||||||
if type(arg) == "table" then
|
|
||||||
return getn(arg)
|
|
||||||
else
|
|
||||||
return 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local temp = {}
|
|
||||||
|
|
||||||
for i = n, getn(arg) do
|
|
||||||
insert(temp, arg[i])
|
|
||||||
end
|
|
||||||
|
|
||||||
return unpack(temp)
|
|
||||||
end
|
|
||||||
|
|
||||||
function math.modf(i)
|
|
||||||
assert(type(i) == "number", "bad argument #1 to 'modf' (number expected, got no value)")
|
|
||||||
|
|
||||||
local int = i >= 0 and floor(i) or ceil(i)
|
|
||||||
|
|
||||||
return int, i - int
|
|
||||||
end
|
|
||||||
|
|
||||||
function string.join(delimiter, ...)
|
|
||||||
-- assert(type(delimiter) == "number", "bad argument #1 to 'join' (string expected, got no value)")
|
|
||||||
|
|
||||||
local size = getn(arg)
|
|
||||||
if size == 0 then
|
|
||||||
return ""
|
|
||||||
end
|
|
||||||
|
|
||||||
local text = arg[1]
|
|
||||||
for i = 2, size do
|
|
||||||
text = text..delimiter..arg[i]
|
|
||||||
end
|
|
||||||
|
|
||||||
return text
|
|
||||||
end
|
|
||||||
strjoin = string.join
|
|
||||||
|
|
||||||
function string.split(delimiter, subject)
|
|
||||||
assert(type(delimiter) == "string", "bad argument #1 to 'split' (string expected, got no value)")
|
|
||||||
|
|
||||||
local delimiter, fields = delimiter or ":", {}
|
|
||||||
local pattern = format("([^%s]+)", delimiter)
|
|
||||||
gsub(subject, pattern, function(c) fields[getn(fields) + 1] = c end)
|
|
||||||
|
|
||||||
return unpack(fields)
|
|
||||||
end
|
|
||||||
strsplit = string.split
|
|
||||||
|
|
||||||
function table.wipe(t)
|
|
||||||
assert(type(t) == "table", "bad argument #1 to 'wipe' (table expected, got no value)")
|
|
||||||
|
|
||||||
for k in pairs(t) do
|
|
||||||
t[k] = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
return t
|
|
||||||
end
|
|
||||||
wipe = table.wipe
|
|
||||||
|
|
||||||
local LOCAL_ToStringAllTemp = {}
|
|
||||||
function tostringall(...)
|
|
||||||
local n = getn(arg)
|
|
||||||
-- Simple versions for common argument counts
|
|
||||||
if (n == 1) then
|
|
||||||
return tostring(arg[1])
|
|
||||||
elseif (n == 2) then
|
|
||||||
return tostring(arg[1]), tostring(arg[2])
|
|
||||||
elseif (n == 3) then
|
|
||||||
return tostring(arg[1]), tostring(arg[2]), tostring(arg[3])
|
|
||||||
elseif (n == 0) then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local needfix
|
|
||||||
for i = 1, n do
|
|
||||||
local v = arg[i]
|
|
||||||
if (type(v) ~= "string") then
|
|
||||||
needfix = i
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if (not needfix) then return unpack(arg) end
|
|
||||||
|
|
||||||
wipe(LOCAL_ToStringAllTemp)
|
|
||||||
for i = 1, needfix - 1 do
|
|
||||||
LOCAL_ToStringAllTemp[i] = arg[i]
|
|
||||||
end
|
|
||||||
for i = needfix, n do
|
|
||||||
LOCAL_ToStringAllTemp[i] = tostring(arg[i])
|
|
||||||
end
|
|
||||||
return unpack(LOCAL_ToStringAllTemp)
|
|
||||||
end
|
|
||||||
|
|
||||||
local LOCAL_PrintHandler = function(...)
|
|
||||||
DEFAULT_CHAT_FRAME:AddMessage(strjoin(" ", tostringall(unpack(arg))))
|
|
||||||
end
|
|
||||||
|
|
||||||
function setprinthandler(func)
|
|
||||||
if (type(func) ~= "function") then
|
|
||||||
error("Invalid print handler")
|
|
||||||
else
|
|
||||||
LOCAL_PrintHandler = func
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function getprinthandler() return LOCAL_PrintHandler end
|
|
||||||
|
|
||||||
local function print_inner(...)
|
|
||||||
local ok, err = pcall(LOCAL_PrintHandler, unpack(arg))
|
|
||||||
if (not ok) then
|
|
||||||
local func = geterrorhandler()
|
|
||||||
func(err)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function print(...)
|
|
||||||
pcall(print_inner, unpack(arg))
|
|
||||||
end
|
|
||||||
|
|
||||||
SLASH_PRINT1 = "/print"
|
|
||||||
SlashCmdList["PRINT"] = print
|
|
||||||
+6
-27
@@ -1,10 +1,11 @@
|
|||||||
|
_G = getfenv()
|
||||||
|
|
||||||
-- Cache global variables
|
-- Cache global variables
|
||||||
local strmatch = strmatch
|
local strmatch = strmatch
|
||||||
-- WoW API
|
-- WoW API
|
||||||
local GetCVar = GetCVar
|
local GetCVar = GetCVar
|
||||||
local IsAddOnLoaded = IsAddOnLoaded
|
local IsAddOnLoaded = IsAddOnLoaded
|
||||||
local LoadAddOn = LoadAddOn
|
local LoadAddOn = LoadAddOn
|
||||||
local UIParentLoadAddOn = UIParentLoadAddOn
|
|
||||||
|
|
||||||
local _ERROR_COUNT = 0
|
local _ERROR_COUNT = 0
|
||||||
local _ERROR_LIMIT = 1000
|
local _ERROR_LIMIT = 1000
|
||||||
@@ -15,7 +16,7 @@ function _ERRORMESSAGE_NEW(message)
|
|||||||
LoadAddOn("!DebugTools")
|
LoadAddOn("!DebugTools")
|
||||||
local loaded = IsAddOnLoaded("!DebugTools")
|
local loaded = IsAddOnLoaded("!DebugTools")
|
||||||
|
|
||||||
-- if (GetCVar("scriptErrors") == 1) then
|
if (GetCVar("ShowErrors") == "1") then
|
||||||
if (not loaded or DEBUG_DEBUGTOOLS) then
|
if (not loaded or DEBUG_DEBUGTOOLS) then
|
||||||
ScriptErrors_Message:SetText(message)
|
ScriptErrors_Message:SetText(message)
|
||||||
ScriptErrors:Show()
|
ScriptErrors:Show()
|
||||||
@@ -25,9 +26,9 @@ function _ERRORMESSAGE_NEW(message)
|
|||||||
else
|
else
|
||||||
ScriptErrorsFrame_OnError(message)
|
ScriptErrorsFrame_OnError(message)
|
||||||
end
|
end
|
||||||
-- elseif (loaded) then
|
elseif (loaded) then
|
||||||
-- ScriptErrorsFrame_OnError(message, true)
|
ScriptErrorsFrame_OnError(message, true)
|
||||||
-- end
|
end
|
||||||
|
|
||||||
_ERROR_COUNT = _ERROR_COUNT + 1
|
_ERROR_COUNT = _ERROR_COUNT + 1
|
||||||
if (_ERROR_COUNT == _ERROR_LIMIT) then
|
if (_ERROR_COUNT == _ERROR_LIMIT) then
|
||||||
@@ -45,25 +46,3 @@ function message(text)
|
|||||||
ScriptErrors:Show()
|
ScriptErrors:Show()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
SLASH_FRAMESTACK1 = "/framestack"
|
|
||||||
SLASH_FRAMESTACK2 = "/fstack"
|
|
||||||
SlashCmdList["FRAMESTACK"] = function(msg)
|
|
||||||
UIParentLoadAddOn("!DebugTools")
|
|
||||||
|
|
||||||
|
|
||||||
FrameStackTooltip_Toggle(showHidden)
|
|
||||||
end
|
|
||||||
|
|
||||||
SLASH_EVENTTRACE1 = "/eventtrace"
|
|
||||||
SLASH_EVENTTRACE2 = "/etrace"
|
|
||||||
SlashCmdList["EVENTTRACE"] = function(msg)
|
|
||||||
UIParentLoadAddOn("!DebugTools")
|
|
||||||
EventTraceFrame_HandleSlashCmd(msg)
|
|
||||||
end
|
|
||||||
|
|
||||||
SLASH_DUMP1 = "/dump"
|
|
||||||
SlashCmdList["DUMP"] = function(msg)
|
|
||||||
UIParentLoadAddOn("!DebugTools")
|
|
||||||
DevTools_DumpCommand(msg)
|
|
||||||
end
|
|
||||||
@@ -0,0 +1,292 @@
|
|||||||
|
-- LibBabble-3.0 is hereby placed in the Public Domain
|
||||||
|
-- Credits: ckknight
|
||||||
|
local LIBBABBLE_MAJOR, LIBBABBLE_MINOR = "LibBabble-3.0", 2
|
||||||
|
|
||||||
|
local LibBabble = LibStub:NewLibrary(LIBBABBLE_MAJOR, LIBBABBLE_MINOR)
|
||||||
|
if not LibBabble then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local data = LibBabble.data or {}
|
||||||
|
for k,v in pairs(LibBabble) do
|
||||||
|
LibBabble[k] = nil
|
||||||
|
end
|
||||||
|
LibBabble.data = data
|
||||||
|
|
||||||
|
local tablesToDB = {}
|
||||||
|
for namespace, db in pairs(data) do
|
||||||
|
for k,v in pairs(db) do
|
||||||
|
tablesToDB[v] = db
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function warn(message)
|
||||||
|
local _, ret = pcall(error, message, 3)
|
||||||
|
geterrorhandler()(ret)
|
||||||
|
end
|
||||||
|
|
||||||
|
local lookup_mt = { __index = function(self, key)
|
||||||
|
local db = tablesToDB[self]
|
||||||
|
local current_key = db.current[key]
|
||||||
|
if current_key then
|
||||||
|
self[key] = current_key
|
||||||
|
return current_key
|
||||||
|
end
|
||||||
|
local base_key = db.base[key]
|
||||||
|
local real_MAJOR_VERSION
|
||||||
|
for k,v in pairs(data) do
|
||||||
|
if v == db then
|
||||||
|
real_MAJOR_VERSION = k
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not real_MAJOR_VERSION then
|
||||||
|
real_MAJOR_VERSION = LIBBABBLE_MAJOR
|
||||||
|
end
|
||||||
|
if base_key then
|
||||||
|
warn(string.format("%s: Translation %q not found for locale %q", real_MAJOR_VERSION, key, GetLocale()))
|
||||||
|
rawset(self, key, base_key)
|
||||||
|
return base_key
|
||||||
|
end
|
||||||
|
warn(string.format("%s: Translation %q not found.", real_MAJOR_VERSION, key))
|
||||||
|
rawset(self, key, key)
|
||||||
|
return key
|
||||||
|
end }
|
||||||
|
|
||||||
|
local function initLookup(module, lookup)
|
||||||
|
local db = tablesToDB[module]
|
||||||
|
for k in pairs(lookup) do
|
||||||
|
lookup[k] = nil
|
||||||
|
end
|
||||||
|
setmetatable(lookup, lookup_mt)
|
||||||
|
tablesToDB[lookup] = db
|
||||||
|
db.lookup = lookup
|
||||||
|
return lookup
|
||||||
|
end
|
||||||
|
|
||||||
|
local function initReverse(module, reverse)
|
||||||
|
local db = tablesToDB[module]
|
||||||
|
for k in pairs(reverse) do
|
||||||
|
reverse[k] = nil
|
||||||
|
end
|
||||||
|
for k,v in pairs(db.current) do
|
||||||
|
reverse[v] = k
|
||||||
|
end
|
||||||
|
tablesToDB[reverse] = db
|
||||||
|
db.reverse = reverse
|
||||||
|
db.reverseIterators = nil
|
||||||
|
return reverse
|
||||||
|
end
|
||||||
|
|
||||||
|
local prototype = {}
|
||||||
|
local prototype_mt = {__index = prototype}
|
||||||
|
|
||||||
|
--[[---------------------------------------------------------------------------
|
||||||
|
Notes:
|
||||||
|
* If you try to access a nonexistent key, it will warn but allow the code to pass through.
|
||||||
|
Returns:
|
||||||
|
A lookup table for english to localized words.
|
||||||
|
Example:
|
||||||
|
local B = LibStub("LibBabble-Module-3.0") -- where Module is what you want.
|
||||||
|
local BL = B:GetLookupTable()
|
||||||
|
assert(BL["Some english word"] == "Some localized word")
|
||||||
|
DoSomething(BL["Some english word that doesn't exist"]) -- warning!
|
||||||
|
-----------------------------------------------------------------------------]]
|
||||||
|
function prototype:GetLookupTable()
|
||||||
|
local db = tablesToDB[self]
|
||||||
|
|
||||||
|
local lookup = db.lookup
|
||||||
|
if lookup then
|
||||||
|
return lookup
|
||||||
|
end
|
||||||
|
return initLookup(self, {})
|
||||||
|
end
|
||||||
|
--[[---------------------------------------------------------------------------
|
||||||
|
Notes:
|
||||||
|
* If you try to access a nonexistent key, it will return nil.
|
||||||
|
Returns:
|
||||||
|
A lookup table for english to localized words.
|
||||||
|
Example:
|
||||||
|
local B = LibStub("LibBabble-Module-3.0") -- where Module is what you want.
|
||||||
|
local B_has = B:GetUnstrictLookupTable()
|
||||||
|
assert(B_has["Some english word"] == "Some localized word")
|
||||||
|
assert(B_has["Some english word that doesn't exist"] == nil)
|
||||||
|
-----------------------------------------------------------------------------]]
|
||||||
|
function prototype:GetUnstrictLookupTable()
|
||||||
|
local db = tablesToDB[self]
|
||||||
|
|
||||||
|
return db.current
|
||||||
|
end
|
||||||
|
--[[---------------------------------------------------------------------------
|
||||||
|
Notes:
|
||||||
|
* If you try to access a nonexistent key, it will return nil.
|
||||||
|
* This is useful for checking if the base (English) table has a key, even if the localized one does not have it registered.
|
||||||
|
Returns:
|
||||||
|
A lookup table for english to localized words.
|
||||||
|
Example:
|
||||||
|
local B = LibStub("LibBabble-Module-3.0") -- where Module is what you want.
|
||||||
|
local B_hasBase = B:GetBaseLookupTable()
|
||||||
|
assert(B_hasBase["Some english word"] == "Some english word")
|
||||||
|
assert(B_hasBase["Some english word that doesn't exist"] == nil)
|
||||||
|
-----------------------------------------------------------------------------]]
|
||||||
|
function prototype:GetBaseLookupTable()
|
||||||
|
local db = tablesToDB[self]
|
||||||
|
|
||||||
|
return db.base
|
||||||
|
end
|
||||||
|
--[[---------------------------------------------------------------------------
|
||||||
|
Notes:
|
||||||
|
* If you try to access a nonexistent key, it will return nil.
|
||||||
|
* This will return only one English word that it maps to, if there are more than one to check, see :GetReverseIterator("word")
|
||||||
|
Returns:
|
||||||
|
A lookup table for localized to english words.
|
||||||
|
Example:
|
||||||
|
local B = LibStub("LibBabble-Module-3.0") -- where Module is what you want.
|
||||||
|
local BR = B:GetReverseLookupTable()
|
||||||
|
assert(BR["Some localized word"] == "Some english word")
|
||||||
|
assert(BR["Some localized word that doesn't exist"] == nil)
|
||||||
|
-----------------------------------------------------------------------------]]
|
||||||
|
function prototype:GetReverseLookupTable()
|
||||||
|
local db = tablesToDB[self]
|
||||||
|
|
||||||
|
local reverse = db.reverse
|
||||||
|
if reverse then
|
||||||
|
return reverse
|
||||||
|
end
|
||||||
|
return initReverse(self, {})
|
||||||
|
end
|
||||||
|
local blank = {}
|
||||||
|
local weakVal = {__mode="v"}
|
||||||
|
--[[---------------------------------------------------------------------------
|
||||||
|
Arguments:
|
||||||
|
string - the localized word to chek for.
|
||||||
|
Returns:
|
||||||
|
An iterator to traverse all English words that map to the given key
|
||||||
|
Example:
|
||||||
|
local B = LibStub("LibBabble-Module-3.0") -- where Module is what you want.
|
||||||
|
for word in B:GetReverseIterator("Some localized word") do
|
||||||
|
DoSomething(word)
|
||||||
|
end
|
||||||
|
-----------------------------------------------------------------------------]]
|
||||||
|
function prototype:GetReverseIterator(key)
|
||||||
|
local db = tablesToDB[self]
|
||||||
|
local reverseIterators = db.reverseIterators
|
||||||
|
if not reverseIterators then
|
||||||
|
reverseIterators = setmetatable({}, weakVal)
|
||||||
|
db.reverseIterators = reverseIterators
|
||||||
|
elseif reverseIterators[key] then
|
||||||
|
return pairs(reverseIterators[key])
|
||||||
|
end
|
||||||
|
local t
|
||||||
|
for k,v in pairs(db.current) do
|
||||||
|
if v == key then
|
||||||
|
if not t then
|
||||||
|
t = {}
|
||||||
|
end
|
||||||
|
t[k] = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
reverseIterators[key] = t or blank
|
||||||
|
return pairs(reverseIterators[key])
|
||||||
|
end
|
||||||
|
--[[---------------------------------------------------------------------------
|
||||||
|
Returns:
|
||||||
|
An iterator to traverse all translations English to localized.
|
||||||
|
Example:
|
||||||
|
local B = LibStub("LibBabble-Module-3.0") -- where Module is what you want.
|
||||||
|
for english, localized in B:Iterate() do
|
||||||
|
DoSomething(english, localized)
|
||||||
|
end
|
||||||
|
-----------------------------------------------------------------------------]]
|
||||||
|
function prototype:Iterate()
|
||||||
|
local db = tablesToDB[self]
|
||||||
|
|
||||||
|
return pairs(db.current)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- #NODOC
|
||||||
|
-- modules need to call this to set the base table
|
||||||
|
function prototype:SetBaseTranslations(base)
|
||||||
|
local db = tablesToDB[self]
|
||||||
|
local oldBase = db.base
|
||||||
|
if oldBase then
|
||||||
|
for k in pairs(oldBase) do
|
||||||
|
oldBase[k] = nil
|
||||||
|
end
|
||||||
|
for k, v in pairs(base) do
|
||||||
|
oldBase[k] = v
|
||||||
|
end
|
||||||
|
base = oldBase
|
||||||
|
else
|
||||||
|
db.base = base
|
||||||
|
end
|
||||||
|
for k,v in pairs(base) do
|
||||||
|
if v == true then
|
||||||
|
base[k] = k
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function init(module)
|
||||||
|
local db = tablesToDB[module]
|
||||||
|
if db.lookup then
|
||||||
|
initLookup(module, db.lookup)
|
||||||
|
end
|
||||||
|
if db.reverse then
|
||||||
|
initReverse(module, db.reverse)
|
||||||
|
end
|
||||||
|
db.reverseIterators = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
-- #NODOC
|
||||||
|
-- modules need to call this to set the current table. if current is true, use the base table.
|
||||||
|
function prototype:SetCurrentTranslations(current)
|
||||||
|
local db = tablesToDB[self]
|
||||||
|
if current == true then
|
||||||
|
db.current = db.base
|
||||||
|
else
|
||||||
|
local oldCurrent = db.current
|
||||||
|
if oldCurrent then
|
||||||
|
for k in pairs(oldCurrent) do
|
||||||
|
oldCurrent[k] = nil
|
||||||
|
end
|
||||||
|
for k, v in pairs(current) do
|
||||||
|
oldCurrent[k] = v
|
||||||
|
end
|
||||||
|
current = oldCurrent
|
||||||
|
else
|
||||||
|
db.current = current
|
||||||
|
end
|
||||||
|
end
|
||||||
|
init(self)
|
||||||
|
end
|
||||||
|
|
||||||
|
for namespace, db in pairs(data) do
|
||||||
|
setmetatable(db.module, prototype_mt)
|
||||||
|
init(db.module)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- #NODOC
|
||||||
|
-- modules need to call this to create a new namespace.
|
||||||
|
function LibBabble:New(namespace, minor)
|
||||||
|
local module, oldminor = LibStub:NewLibrary(namespace, minor)
|
||||||
|
if not module then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if not oldminor then
|
||||||
|
local db = {
|
||||||
|
module = module,
|
||||||
|
}
|
||||||
|
data[namespace] = db
|
||||||
|
tablesToDB[module] = db
|
||||||
|
else
|
||||||
|
for k,v in pairs(module) do
|
||||||
|
module[k] = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
setmetatable(module, prototype_mt)
|
||||||
|
|
||||||
|
return module
|
||||||
|
end
|
||||||
@@ -0,0 +1,221 @@
|
|||||||
|
--[[
|
||||||
|
Name: LibBabble-Class-3.0
|
||||||
|
Revision: $Rev: 50 $
|
||||||
|
Author(s): ckknight (ckknight@gmail.com)
|
||||||
|
Website: http://ckknight.wowinterface.com/
|
||||||
|
Dependencies: None
|
||||||
|
License: MIT
|
||||||
|
]]
|
||||||
|
|
||||||
|
local MAJOR_VERSION = "LibBabble-Class-3.0"
|
||||||
|
local MINOR_VERSION = 90000 + tonumber(string.match("$Revision: 50 $", "%d+"))
|
||||||
|
|
||||||
|
if not LibStub then error(MAJOR_VERSION .. " requires LibStub.") end
|
||||||
|
local lib = LibStub("LibBabble-3.0"):New(MAJOR_VERSION, MINOR_VERSION)
|
||||||
|
if not lib then return end
|
||||||
|
|
||||||
|
local GAME_LOCALE = GetLocale()
|
||||||
|
|
||||||
|
lib:SetBaseTranslations {
|
||||||
|
Warlock = true,
|
||||||
|
Warrior = true,
|
||||||
|
Hunter = true,
|
||||||
|
Mage = true,
|
||||||
|
Priest = true,
|
||||||
|
Druid = true,
|
||||||
|
Paladin = true,
|
||||||
|
Shaman = true,
|
||||||
|
Rogue = true,
|
||||||
|
|
||||||
|
WARLOCK = true,
|
||||||
|
WARRIOR = true,
|
||||||
|
HUNTER = true,
|
||||||
|
MAGE = true,
|
||||||
|
PRIEST = true,
|
||||||
|
DRUID = true,
|
||||||
|
PALADIN = true,
|
||||||
|
SHAMAN = true,
|
||||||
|
ROGUE = true,
|
||||||
|
}
|
||||||
|
|
||||||
|
if GAME_LOCALE == "enUS" then
|
||||||
|
lib:SetCurrentTranslations(true)
|
||||||
|
elseif GAME_LOCALE == "deDE" then
|
||||||
|
lib:SetCurrentTranslations {
|
||||||
|
["Warlock"] = "Hexenmeister",
|
||||||
|
["Warrior"] = "Krieger",
|
||||||
|
["Hunter"] = "Jäger",
|
||||||
|
["Mage"] = "Magier",
|
||||||
|
["Priest"] = "Priester",
|
||||||
|
["Druid"] = "Druide",
|
||||||
|
["Paladin"] = "Paladin",
|
||||||
|
["Shaman"] = "Schamane",
|
||||||
|
["Rogue"] = "Schurke",
|
||||||
|
|
||||||
|
["WARLOCK"] = "Hexenmeisterin",
|
||||||
|
["WARRIOR"] = "Kriegerin",
|
||||||
|
["HUNTER"] = "Jägerin",
|
||||||
|
["MAGE"] = "Magierin",
|
||||||
|
["PRIEST"] = "Priesterin",
|
||||||
|
["DRUID"] = "Druidin",
|
||||||
|
["PALADIN"] = "Paladin",
|
||||||
|
["SHAMAN"] = "Schamanin",
|
||||||
|
["ROGUE"] = "Schurkin",
|
||||||
|
}
|
||||||
|
elseif GAME_LOCALE == "frFR" then
|
||||||
|
lib:SetCurrentTranslations {
|
||||||
|
["Warlock"] = "Démoniste",
|
||||||
|
["Warrior"] = "Guerrier",
|
||||||
|
["Hunter"] = "Chasseur",
|
||||||
|
["Mage"] = "Mage",
|
||||||
|
["Priest"] = "Prêtre",
|
||||||
|
["Druid"] = "Druide",
|
||||||
|
["Paladin"] = "Paladin",
|
||||||
|
["Shaman"] = "Chaman",
|
||||||
|
["Rogue"] = "Voleur",
|
||||||
|
|
||||||
|
["WARLOCK"] = "Démoniste",
|
||||||
|
["WARRIOR"] = "Guerrière",
|
||||||
|
["HUNTER"] = "Chasseresse",
|
||||||
|
["MAGE"] = "Mage",
|
||||||
|
["PRIEST"] = "Prêtresse",
|
||||||
|
["DRUID"] = "Druidesse",
|
||||||
|
["PALADIN"] = "Paladin",
|
||||||
|
["SHAMAN"] = "Chamane",
|
||||||
|
["ROGUE"] = "Voleuse",
|
||||||
|
}
|
||||||
|
elseif GAME_LOCALE == "zhCN" then
|
||||||
|
lib:SetCurrentTranslations {
|
||||||
|
["Warlock"] = "术士",
|
||||||
|
["Warrior"] = "战士",
|
||||||
|
["Hunter"] = "猎人",
|
||||||
|
["Mage"] = "法师",
|
||||||
|
["Priest"] = "牧师",
|
||||||
|
["Druid"] = "德鲁伊",
|
||||||
|
["Paladin"] = "圣骑士",
|
||||||
|
["Shaman"] = "萨满祭司",
|
||||||
|
["Rogue"] = "潜行者",
|
||||||
|
|
||||||
|
["WARLOCK"] = "术士",
|
||||||
|
["WARRIOR"] = "战士",
|
||||||
|
["HUNTER"] = "猎人",
|
||||||
|
["MAGE"] = "法师",
|
||||||
|
["PRIEST"] = "牧师",
|
||||||
|
["DRUID"] = "德鲁伊",
|
||||||
|
["PALADIN"] = "圣骑士",
|
||||||
|
["SHAMAN"] = "萨满祭司",
|
||||||
|
["ROGUE"] = "潜行者",
|
||||||
|
}
|
||||||
|
elseif GAME_LOCALE == "zhTW" then
|
||||||
|
lib:SetCurrentTranslations {
|
||||||
|
["Warlock"] = "術士",
|
||||||
|
["Warrior"] = "戰士",
|
||||||
|
["Hunter"] = "獵人",
|
||||||
|
["Mage"] = "法師",
|
||||||
|
["Priest"] = "牧師",
|
||||||
|
["Druid"] = "德魯伊",
|
||||||
|
["Paladin"] = "聖騎士",
|
||||||
|
["Shaman"] = "薩滿",
|
||||||
|
["Rogue"] = "盜賊",
|
||||||
|
|
||||||
|
["WARLOCK"] = "術士",
|
||||||
|
["WARRIOR"] = "戰士",
|
||||||
|
["HUNTER"] = "獵人",
|
||||||
|
["MAGE"] = "法師",
|
||||||
|
["PRIEST"] = "牧師",
|
||||||
|
["DRUID"] = "德魯伊",
|
||||||
|
["PALADIN"] = "聖騎士",
|
||||||
|
["SHAMAN"] = "薩滿",
|
||||||
|
["ROGUE"] = "盜賊",
|
||||||
|
}
|
||||||
|
elseif GAME_LOCALE == "koKR" then
|
||||||
|
lib:SetCurrentTranslations {
|
||||||
|
["Warlock"] = "흑마법사",
|
||||||
|
["Warrior"] = "전사",
|
||||||
|
["Hunter"] = "사냥꾼",
|
||||||
|
["Mage"] = "마법사",
|
||||||
|
["Priest"] = "사제",
|
||||||
|
["Druid"] = "드루이드",
|
||||||
|
["Paladin"] = "성기사",
|
||||||
|
["Shaman"] = "주술사",
|
||||||
|
["Rogue"] = "도적",
|
||||||
|
|
||||||
|
["WARLOCK"] = "흑마법사",
|
||||||
|
["WARRIOR"] = "전사",
|
||||||
|
["HUNTER"] = "사냥꾼",
|
||||||
|
["MAGE"] = "마법사",
|
||||||
|
["PRIEST"] = "사제",
|
||||||
|
["DRUID"] = "드루이드",
|
||||||
|
["PALADIN"] = "성기사",
|
||||||
|
["SHAMAN"] = "주술사",
|
||||||
|
["ROGUE"] = "도적",
|
||||||
|
}
|
||||||
|
elseif GAME_LOCALE == "esES" then
|
||||||
|
lib:SetCurrentTranslations {
|
||||||
|
["Warlock"] = "Brujo",
|
||||||
|
["Warrior"] = "Guerrero",
|
||||||
|
["Hunter"] = "Cazador",
|
||||||
|
["Mage"] = "Mago",
|
||||||
|
["Priest"] = "Sacerdote",
|
||||||
|
["Druid"] = "Druida",
|
||||||
|
["Paladin"] = "Paladín",
|
||||||
|
["Shaman"] = "Chamán",
|
||||||
|
["Rogue"] = "Pícaro",
|
||||||
|
|
||||||
|
["WARLOCK"] = "Bruja",
|
||||||
|
["WARRIOR"] = "Guerrera",
|
||||||
|
["HUNTER"] = "Cazadora",
|
||||||
|
["MAGE"] = "Maga",
|
||||||
|
["PRIEST"] = "Sacerdotisa",
|
||||||
|
["DRUID"] = "Druida",
|
||||||
|
["PALADIN"] = "Paladín",
|
||||||
|
["SHAMAN"] = "Chamán",
|
||||||
|
["ROGUE"] = "Pícara",
|
||||||
|
}
|
||||||
|
elseif GAME_LOCALE == "esMX" then
|
||||||
|
lib:SetCurrentTranslations {
|
||||||
|
["Warlock"] = "Brujo",
|
||||||
|
["Warrior"] = "Guerrero",
|
||||||
|
["Hunter"] = "Cazador",
|
||||||
|
["Mage"] = "Mago",
|
||||||
|
["Priest"] = "Sacerdote",
|
||||||
|
["Druid"] = "Druida",
|
||||||
|
["Paladin"] = "Paladín",
|
||||||
|
["Shaman"] = "Chamán",
|
||||||
|
["Rogue"] = "Pícaro",
|
||||||
|
|
||||||
|
["WARLOCK"] = "Bruja",
|
||||||
|
["WARRIOR"] = "Guerrera",
|
||||||
|
["HUNTER"] = "Cazadora",
|
||||||
|
["MAGE"] = "Maga",
|
||||||
|
["PRIEST"] = "Sacerdotisa",
|
||||||
|
["DRUID"] = "Druida",
|
||||||
|
["PALADIN"] = "Paladín",
|
||||||
|
["SHAMAN"] = "Chamán",
|
||||||
|
["ROGUE"] = "Pícara",
|
||||||
|
}
|
||||||
|
elseif GAME_LOCALE == "ruRU" then
|
||||||
|
lib:SetCurrentTranslations {
|
||||||
|
["Warlock"] = "Чернокнижник",
|
||||||
|
["Warrior"] = "Воин",
|
||||||
|
["Hunter"] = "Охотник",
|
||||||
|
["Mage"] = "Маг",
|
||||||
|
["Priest"] = "Жрец",
|
||||||
|
["Druid"] = "Друид",
|
||||||
|
["Paladin"] = "Паладин",
|
||||||
|
["Shaman"] = "Шаман",
|
||||||
|
["Rogue"] = "Разбойник",
|
||||||
|
|
||||||
|
["WARLOCK"] = "Чернокнижница",
|
||||||
|
["WARRIOR"] = "Воин",
|
||||||
|
["HUNTER"] = "Охотница",
|
||||||
|
["MAGE"] = "Маг",
|
||||||
|
["PRIEST"] = "Жрица",
|
||||||
|
["DRUID"] = "Друид",
|
||||||
|
["PALADIN"] = "Паладин",
|
||||||
|
["SHAMAN"] = "Шаманка",
|
||||||
|
["ROGUE"] = "Разбойница",
|
||||||
|
}
|
||||||
|
else
|
||||||
|
error(string.format("%s: Locale %q not supported", MAJOR_VERSION, GAME_LOCALE))
|
||||||
|
end
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,51 @@
|
|||||||
|
-- $Id: LibStub.lua 103 2014-10-16 03:02:50Z mikk $
|
||||||
|
-- LibStub is a simple versioning stub meant for use in Libraries. http://www.wowace.com/addons/libstub/ for more info
|
||||||
|
-- LibStub is hereby placed in the Public Domain
|
||||||
|
-- Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel, joshborke
|
||||||
|
local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 2 -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS!
|
||||||
|
local LibStub = _G[LIBSTUB_MAJOR]
|
||||||
|
|
||||||
|
-- Check to see is this version of the stub is obsolete
|
||||||
|
if not LibStub or LibStub.minor < LIBSTUB_MINOR then
|
||||||
|
LibStub = LibStub or {libs = {}, minors = {} }
|
||||||
|
_G[LIBSTUB_MAJOR] = LibStub
|
||||||
|
LibStub.minor = LIBSTUB_MINOR
|
||||||
|
|
||||||
|
-- LibStub:NewLibrary(major, minor)
|
||||||
|
-- major (string) - the major version of the library
|
||||||
|
-- minor (string or number ) - the minor version of the library
|
||||||
|
--
|
||||||
|
-- returns nil if a newer or same version of the lib is already present
|
||||||
|
-- returns empty library object or old library object if upgrade is needed
|
||||||
|
function LibStub:NewLibrary(major, minor)
|
||||||
|
assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)")
|
||||||
|
minor = assert(tonumber(strmatch(minor, "%d+")), "Minor version must either be a number or contain a number.")
|
||||||
|
|
||||||
|
local oldminor = self.minors[major]
|
||||||
|
if oldminor and oldminor >= minor then return nil end
|
||||||
|
self.minors[major], self.libs[major] = minor, self.libs[major] or {}
|
||||||
|
return self.libs[major], oldminor
|
||||||
|
end
|
||||||
|
|
||||||
|
-- LibStub:GetLibrary(major, [silent])
|
||||||
|
-- major (string) - the major version of the library
|
||||||
|
-- silent (boolean) - if true, library is optional, silently return nil if its not found
|
||||||
|
--
|
||||||
|
-- throws an error if the library can not be found (except silent is set)
|
||||||
|
-- returns the library object if found
|
||||||
|
function LibStub:GetLibrary(major, silent)
|
||||||
|
if not self.libs[major] and not silent then
|
||||||
|
error(string.format("Cannot find a library instance of %q.", tostring(major)), 2)
|
||||||
|
end
|
||||||
|
return self.libs[major], self.minors[major]
|
||||||
|
end
|
||||||
|
|
||||||
|
-- LibStub:IterateLibraries()
|
||||||
|
--
|
||||||
|
-- Returns an iterator for the currently registered libraries
|
||||||
|
function LibStub:IterateLibraries()
|
||||||
|
return pairs(self.libs)
|
||||||
|
end
|
||||||
|
|
||||||
|
setmetatable(LibStub, { __call = LibStub.GetLibrary })
|
||||||
|
end
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<Ui xmlns="http://www.blizzard.com/wow/ui/">
|
||||||
|
<Script file="LibStub.lua"/>
|
||||||
|
<Script file="LibBabble-3.0.lua"/>
|
||||||
|
<Script file="LibBabble-Class-3.0.lua"/>
|
||||||
|
<Script file="LibBabble-Zone-3.0.lua"/>
|
||||||
|
</Ui>
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
-- Cache global variables
|
||||||
|
local strmatch = strmatch
|
||||||
|
|
||||||
|
local checked
|
||||||
|
local function LoadDebugTools()
|
||||||
|
if checked then return end
|
||||||
|
|
||||||
|
local _, _, _, lod, _, reason = GetAddOnInfo("!DebugTools")
|
||||||
|
checked = true
|
||||||
|
|
||||||
|
if reason == "MISSING" then return end
|
||||||
|
|
||||||
|
if lod then
|
||||||
|
LoadAddOn("!DebugTools")
|
||||||
|
else
|
||||||
|
EnableAddOn("!DebugTools")
|
||||||
|
LoadAddOn("!DebugTools")
|
||||||
|
DisableAddOn("!DebugTools")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
SLASH_FRAMESTACK1 = "/framestack"
|
||||||
|
SLASH_FRAMESTACK2 = "/fstack"
|
||||||
|
SlashCmdList["FRAMESTACK"] = function(msg)
|
||||||
|
LoadDebugTools()
|
||||||
|
|
||||||
|
if IsAddOnLoaded("!DebugTools") then
|
||||||
|
local showHiddenArg, showRegionsArg = strmatch(msg, "^%s*(%S+)%s+(%S+)%s*$")
|
||||||
|
if (not showHiddenArg or not showRegionsArg) then
|
||||||
|
showHiddenArg = strmatch(msg, "^%s*(%S+)%s*$")
|
||||||
|
showRegionsArg = "1"
|
||||||
|
end
|
||||||
|
local showHidden = showHiddenArg == "true" or showHiddenArg == "1"
|
||||||
|
local showRegions = showRegions == "true" or showRegionsArg == "1"
|
||||||
|
|
||||||
|
FrameStackTooltip_Toggle(showHidden, showRegions)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
SLASH_EVENTTRACE1 = "/eventtrace"
|
||||||
|
SLASH_EVENTTRACE2 = "/etrace"
|
||||||
|
SlashCmdList["EVENTTRACE"] = function(msg)
|
||||||
|
LoadDebugTools()
|
||||||
|
EventTraceFrame_HandleSlashCmd(msg)
|
||||||
|
end
|
||||||
|
|
||||||
|
SLASH_DUMP1 = "/dump"
|
||||||
|
SlashCmdList["DUMP"] = function(msg)
|
||||||
|
LoadDebugTools()
|
||||||
|
DevTools_DumpCommand(msg)
|
||||||
|
end
|
||||||
@@ -1,10 +1,11 @@
|
|||||||
## Interface: 20400
|
## Interface: 11200
|
||||||
## Title: !DebugTools
|
## Title: !DebugTools
|
||||||
## Notes: Tools for developing addons (Blizzard UI Debug Tools)
|
## Notes: Tools for developing addons (Blizzard UI Debug Tools)
|
||||||
## Author: Blizzard Entertainment
|
## Author: Blizzard Entertainment
|
||||||
## Special Thanks: Iriel, Kirov, Esamynn
|
## Special Thanks: Iriel, Kirov, Esamynn
|
||||||
## Version: 1.0
|
## Version: 1.0
|
||||||
## Dependencies: !Compatibility
|
## Dependencies: !Compatibility
|
||||||
|
## LoadOnDemand: 1
|
||||||
|
|
||||||
Compatibility.lua
|
Compatibility.lua
|
||||||
Dump.lua
|
Dump.lua
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
local _G = getfenv()
|
local mod = math.mod
|
||||||
|
local getn = table.getn
|
||||||
|
|
||||||
EVENT_TRACE_EVENT_HEIGHT = 16;
|
EVENT_TRACE_EVENT_HEIGHT = 16;
|
||||||
EVENT_TRACE_MAX_ENTRIES = 1000;
|
EVENT_TRACE_MAX_ENTRIES = 1000;
|
||||||
@@ -44,7 +45,7 @@ function EventTraceFrame_OnLoad(self)
|
|||||||
self.lastIndex = 0;
|
self.lastIndex = 0;
|
||||||
self.visibleButtons = 0;
|
self.visibleButtons = 0;
|
||||||
_EventTraceFrame = self;
|
_EventTraceFrame = self;
|
||||||
self:SetScript("OnSizeChanged", function() EventTraceFrame_OnSizeChanged(this, arg1, arg2) end);
|
self:SetScript("OnSizeChanged", function() EventTraceFrame_OnSizeChanged(this, this:GetWidth(), this:GetHeight()) end);
|
||||||
EventTraceFrame_OnSizeChanged(self, self:GetWidth(), self:GetHeight());
|
EventTraceFrame_OnSizeChanged(self, self:GetWidth(), self:GetHeight());
|
||||||
self:EnableMouse(true);
|
self:EnableMouse(true);
|
||||||
self:EnableMouseWheel(true);
|
self:EnableMouseWheel(true);
|
||||||
@@ -99,18 +100,18 @@ function EventTraceFrame_OnEvent (self, event, ...)
|
|||||||
local hours = math.floor(minutes / 60);
|
local hours = math.floor(minutes / 60);
|
||||||
seconds = seconds - 60 * minutes;
|
seconds = seconds - 60 * minutes;
|
||||||
minutes = minutes - 60 * hours;
|
minutes = minutes - 60 * hours;
|
||||||
hours = math.mod(hours, 1000);
|
hours = mod(hours, 1000)
|
||||||
self.times[nextIndex] = string.format("%.2d:%.2d:%06.3f", hours, minutes, seconds);
|
self.times[nextIndex] = string.format("%.2d:%.2d:%06.3f", hours, minutes, seconds);
|
||||||
self.timeSinceLast[nextIndex] = 0;
|
self.timeSinceLast[nextIndex] = 0;
|
||||||
self.framesSinceLast[nextIndex] = 0;
|
self.framesSinceLast[nextIndex] = 0;
|
||||||
self.eventids[nextIndex] = GetCurrentEventID();
|
self.eventids[nextIndex] = GetCurrentEventID();
|
||||||
|
|
||||||
local numArgs = select("#", unpack(arg));
|
local numArgs = select("#", arg);
|
||||||
for i=1, numArgs do
|
for i=1, numArgs do
|
||||||
if (not self.args[i]) then
|
if (not self.args[i]) then
|
||||||
self.args[i] = {};
|
self.args[i] = {};
|
||||||
end
|
end
|
||||||
self.args[i][nextIndex] = select(i, unpack(arg));
|
self.args[i][nextIndex] = select(i, arg);
|
||||||
end
|
end
|
||||||
|
|
||||||
if (self.eventsToCapture) then
|
if (self.eventsToCapture) then
|
||||||
@@ -127,8 +128,8 @@ function EventTraceFrame_OnEvent (self, event, ...)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function EventTraceFrame_OnShow()
|
function EventTraceFrame_OnShow(self)
|
||||||
wipe(this.ignoredEvents);
|
wipe(self.ignoredEvents);
|
||||||
local scrollBar = _G["EventTraceFrameScroll"];
|
local scrollBar = _G["EventTraceFrameScroll"];
|
||||||
local minValue, maxValue = scrollBar:GetMinMaxValues();
|
local minValue, maxValue = scrollBar:GetMinMaxValues();
|
||||||
scrollBar:SetValue(maxValue);
|
scrollBar:SetValue(maxValue);
|
||||||
@@ -140,7 +141,7 @@ end
|
|||||||
|
|
||||||
function EventTraceFrame_OnSizeChanged (self, width, height)
|
function EventTraceFrame_OnSizeChanged (self, width, height)
|
||||||
local numButtonsToDisplay = math.floor((height - 36)/EVENT_TRACE_EVENT_HEIGHT);
|
local numButtonsToDisplay = math.floor((height - 36)/EVENT_TRACE_EVENT_HEIGHT);
|
||||||
local numButtonsCreated = getn(self.buttons)
|
local numButtonsCreated = getn(self.buttons);
|
||||||
|
|
||||||
if (numButtonsCreated < numButtonsToDisplay) then
|
if (numButtonsCreated < numButtonsToDisplay) then
|
||||||
for i = numButtonsCreated + 1, numButtonsToDisplay do
|
for i = numButtonsCreated + 1, numButtonsToDisplay do
|
||||||
@@ -162,7 +163,7 @@ function EventTraceFrame_OnSizeChanged (self, width, height)
|
|||||||
EventTraceFrame_Update();
|
EventTraceFrame_Update();
|
||||||
elseif (numButtonsToDisplay < self.visibleButtons) then
|
elseif (numButtonsToDisplay < self.visibleButtons) then
|
||||||
for i = numButtonsToDisplay + 1, self.visibleButtons do
|
for i = numButtonsToDisplay + 1, self.visibleButtons do
|
||||||
-- self.buttons[i]:Hide();
|
self.buttons[i]:Hide();
|
||||||
end
|
end
|
||||||
self.visibleButtons = numButtonsToDisplay;
|
self.visibleButtons = numButtonsToDisplay;
|
||||||
end
|
end
|
||||||
@@ -493,9 +494,14 @@ function EventTraceFrameEventHideButton_OnClick (button)
|
|||||||
EventTraceFrame_Update();
|
EventTraceFrame_Update();
|
||||||
end
|
end
|
||||||
|
|
||||||
local ERROR_FORMAT = "|cffffd200Message:|r|cffffffff %s|r\n|cffffd200Time:|r|cffffffff %s|r\n|cffffd200Count:|r|cffffffff %s|r\n|cffffd200Stack:|r|cffffffff %s|r";
|
local ERROR_FORMAT = [[|cffffd200Message:|r|cffffffff %s|r
|
||||||
|
|cffffd200Time:|r|cffffffff %s|r
|
||||||
|
|cffffd200Count:|r|cffffffff %s|r
|
||||||
|
|cffffd200Stack:|r|cffffffff %s|r]];
|
||||||
|
|
||||||
local WARNING_AS_ERROR_FORMAT = "|cffffd200Message:|r|cffffffff %s|r\n|cffffd200Time:|r|cffffffff %s|r\n|cffffd200Count:|r|cffffffff %s|r";
|
local WARNING_AS_ERROR_FORMAT = [[|cffffd200Message:|r|cffffffff %s|r
|
||||||
|
|cffffd200Time:|r|cffffffff %s|r
|
||||||
|
|cffffd200Count:|r|cffffffff %s|r]];
|
||||||
|
|
||||||
local WARNING_FORMAT = "Lua Warning:\n"..WARNING_AS_ERROR_FORMAT;
|
local WARNING_FORMAT = "Lua Warning:\n"..WARNING_AS_ERROR_FORMAT;
|
||||||
|
|
||||||
@@ -522,7 +528,7 @@ function ScriptErrorsFrame_OnLoad (self)
|
|||||||
_ScriptErrorsFrame = self;
|
_ScriptErrorsFrame = self;
|
||||||
end
|
end
|
||||||
|
|
||||||
function ScriptErrorsFrame_OnShow (self)
|
function ScriptErrorsFrame_OnShow ()
|
||||||
ScriptErrorsFrame_Update();
|
ScriptErrorsFrame_Update();
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -663,7 +669,7 @@ function FrameStackTooltip_OnLoad(self)
|
|||||||
self:RegisterEvent("DISPLAY_SIZE_CHANGED")
|
self:RegisterEvent("DISPLAY_SIZE_CHANGED")
|
||||||
end
|
end
|
||||||
|
|
||||||
function FrameStackTooltip_OnEvent(self, event, ...)
|
function FrameStackTooltip_OnEvent(self, event)
|
||||||
if (event == "DISPLAY_SIZE_CHANGED") then
|
if (event == "DISPLAY_SIZE_CHANGED") then
|
||||||
FrameStackTooltip_OnDisplaySizeChanged(self)
|
FrameStackTooltip_OnDisplaySizeChanged(self)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -57,9 +57,9 @@
|
|||||||
<Scripts>
|
<Scripts>
|
||||||
<OnLoad>
|
<OnLoad>
|
||||||
local frameName = this:GetName();
|
local frameName = this:GetName();
|
||||||
this.time = getglobal(frameName.."Time");
|
this.time = _G[frameName.."Time"];
|
||||||
this.event = getglobal(frameName.."Event");
|
this.event = _G[frameName.."Event"];
|
||||||
this.HideButton = getglobal(frameName.."HideButton");
|
this.HideButton = _G[frameName.."HideButton"];
|
||||||
this:GetHighlightTexture():SetAlpha(.15);
|
this:GetHighlightTexture():SetAlpha(.15);
|
||||||
</OnLoad>
|
</OnLoad>
|
||||||
<OnEnter>
|
<OnEnter>
|
||||||
@@ -326,12 +326,12 @@
|
|||||||
this:RegisterForDrag("LeftButton");
|
this:RegisterForDrag("LeftButton");
|
||||||
</OnLoad>
|
</OnLoad>
|
||||||
<OnDragStart>
|
<OnDragStart>
|
||||||
local eventTraceFrame = getglobal("EventTraceFrame");
|
local eventTraceFrame = _G["EventTraceFrame"];
|
||||||
eventTraceFrame.moving = true;
|
eventTraceFrame.moving = true;
|
||||||
eventTraceFrame:StartMoving();
|
eventTraceFrame:StartMoving();
|
||||||
</OnDragStart>
|
</OnDragStart>
|
||||||
<OnDragStop>
|
<OnDragStop>
|
||||||
local eventTraceFrame = getglobal("EventTraceFrame");
|
local eventTraceFrame = _G["EventTraceFrame"];
|
||||||
eventTraceFrame.moving = nil;
|
eventTraceFrame.moving = nil;
|
||||||
eventTraceFrame:StopMovingOrSizing();
|
eventTraceFrame:StopMovingOrSizing();
|
||||||
</OnDragStop>
|
</OnDragStop>
|
||||||
@@ -356,7 +356,7 @@
|
|||||||
</Layers>
|
</Layers>
|
||||||
<Scripts>
|
<Scripts>
|
||||||
<OnLoad>
|
<OnLoad>
|
||||||
this:SetFrameLevel(this:GetFrameLevel() + 1);
|
this:SetFrameLevel(self:GetFrameLevel() + 1);
|
||||||
this:SetValue(0);
|
this:SetValue(0);
|
||||||
this:SetValueStep(1);
|
this:SetValueStep(1);
|
||||||
</OnLoad>
|
</OnLoad>
|
||||||
@@ -375,7 +375,7 @@
|
|||||||
EventTraceFrame_OnShow(this);
|
EventTraceFrame_OnShow(this);
|
||||||
</OnShow>
|
</OnShow>
|
||||||
<OnEvent>
|
<OnEvent>
|
||||||
EventTraceFrame_OnEvent(this, unpack(arg));
|
EventTraceFrame_OnEvent(this, event, arg);
|
||||||
</OnEvent>
|
</OnEvent>
|
||||||
<OnUpdate>
|
<OnUpdate>
|
||||||
EventTraceFrame_OnUpdate(this, arg1);
|
EventTraceFrame_OnUpdate(this, arg1);
|
||||||
@@ -414,12 +414,12 @@
|
|||||||
this:RegisterForDrag("LeftButton");
|
this:RegisterForDrag("LeftButton");
|
||||||
</OnLoad>
|
</OnLoad>
|
||||||
<OnDragStart>
|
<OnDragStart>
|
||||||
local frame = getglobal("ScriptErrorsFrame");
|
local frame = _G["ScriptErrorsFrame"];
|
||||||
frame.moving = true;
|
frame.moving = true;
|
||||||
frame:StartMoving();
|
frame:StartMoving();
|
||||||
</OnDragStart>
|
</OnDragStart>
|
||||||
<OnDragStop>
|
<OnDragStop>
|
||||||
local frame = getglobal("ScriptErrorsFrame");
|
local frame = _G["ScriptErrorsFrame"];
|
||||||
frame.moving = nil;
|
frame.moving = nil;
|
||||||
frame:StopMovingOrSizing();
|
frame:StopMovingOrSizing();
|
||||||
</OnDragStop>
|
</OnDragStop>
|
||||||
@@ -543,7 +543,7 @@
|
|||||||
FrameStackTooltip_OnUpdate(this, arg1);
|
FrameStackTooltip_OnUpdate(this, arg1);
|
||||||
</OnUpdate>
|
</OnUpdate>
|
||||||
<OnEvent>
|
<OnEvent>
|
||||||
FrameStackTooltip_OnEvent(this, unpack(arg));
|
FrameStackTooltip_OnEvent(this, arg);
|
||||||
</OnEvent>
|
</OnEvent>
|
||||||
</Scripts>
|
</Scripts>
|
||||||
</GameTooltip>
|
</GameTooltip>
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
-- Cache global variables
|
-- Cache global variables
|
||||||
local _G = getfenv()
|
|
||||||
local format, match = string.format, string.match
|
|
||||||
local tinsert, tsort, twipe = table.insert, table.sort, table.wipe
|
|
||||||
local mod = math.mod
|
local mod = math.mod
|
||||||
local pairs = pairs
|
local pairs = pairs
|
||||||
local tostring = tostring
|
local tostring = tostring
|
||||||
|
local format, match = string.format, string.match
|
||||||
|
local getn, tinsert, tsort, twipe = table.getn, table.insert, table.sort, table.wipe
|
||||||
-- WoW API
|
-- WoW API
|
||||||
local GetTime = GetTime
|
local GetTime = GetTime
|
||||||
|
|
||||||
@@ -87,7 +86,11 @@ local function FrameStackSort(b, a)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if a and b then
|
||||||
return a < b
|
return a < b
|
||||||
|
else
|
||||||
|
return
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function UpdateFrameStack(tooltip, showHidden)
|
function UpdateFrameStack(tooltip, showHidden)
|
||||||
@@ -154,7 +157,7 @@ function UpdateFrameStack(tooltip, showHidden)
|
|||||||
|
|
||||||
frameStackList[getn(frameStackList) + 1] = nil
|
frameStackList[getn(frameStackList) + 1] = nil
|
||||||
|
|
||||||
--tsort(frameStackList, FrameStackSort)
|
tsort(frameStackList, FrameStackSort)
|
||||||
|
|
||||||
tooltip:ClearLines()
|
tooltip:ClearLines()
|
||||||
tooltip:AddDoubleLine(DEBUG_FRAMESTACK, format("(%.2f,%.2f)", x, y), 1, 1, 1, 1, .82, 0)
|
tooltip:AddDoubleLine(DEBUG_FRAMESTACK, format("(%.2f,%.2f)", x, y), 1, 1, 1, 1, .82, 0)
|
||||||
@@ -174,12 +177,12 @@ function UpdateFrameStack(tooltip, showHidden)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if l ~= ol then
|
if l ~= ol then
|
||||||
cs = mod(cs, cn) + 1 or 0
|
cs = mod(cs, cn) + 1
|
||||||
ol = l
|
ol = l
|
||||||
end
|
end
|
||||||
|
|
||||||
if not highlighted then
|
if not highlighted then
|
||||||
local frameName = _G[n] --[[or match(n, "%((.+)%)$")]] or n
|
local frameName = _G[n] or match(n, "%((.+)%)$") or n
|
||||||
if frameName and frameName == highlightFrame then
|
if frameName and frameName == highlightFrame then
|
||||||
tooltip:AddLine("-->" .. (a[cs] or "|cff444444") .. "<" .. l .. "> " .. n .. "|r")
|
tooltip:AddLine("-->" .. (a[cs] or "|cff444444") .. "<" .. l .. "> " .. n .. "|r")
|
||||||
highlighted = true
|
highlighted = true
|
||||||
|
|||||||
@@ -35,6 +35,10 @@ local AceAddon, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
|
|||||||
|
|
||||||
if not AceAddon then return end -- No Upgrade needed.
|
if not AceAddon then return end -- No Upgrade needed.
|
||||||
|
|
||||||
|
local AceCore = LibStub("AceCore-3.0")
|
||||||
|
local new, del = AceCore.new, AceCore.del
|
||||||
|
local wipe, truncate = AceCore.wipe, AceCore.truncate
|
||||||
|
|
||||||
AceAddon.frame = AceAddon.frame or CreateFrame("Frame", "AceAddon30Frame") -- Our very own frame
|
AceAddon.frame = AceAddon.frame or CreateFrame("Frame", "AceAddon30Frame") -- Our very own frame
|
||||||
AceAddon.addons = AceAddon.addons or {} -- addons in general
|
AceAddon.addons = AceAddon.addons or {} -- addons in general
|
||||||
AceAddon.statuses = AceAddon.statuses or {} -- statuses of addon.
|
AceAddon.statuses = AceAddon.statuses or {} -- statuses of addon.
|
||||||
@@ -43,9 +47,9 @@ AceAddon.enablequeue = AceAddon.enablequeue or {} -- addons that are initialized
|
|||||||
AceAddon.embeds = AceAddon.embeds or setmetatable({}, {__index = function(tbl, key) tbl[key] = {} return tbl[key] end }) -- contains a list of libraries embedded in an addon
|
AceAddon.embeds = AceAddon.embeds or setmetatable({}, {__index = function(tbl, key) tbl[key] = {} return tbl[key] end }) -- contains a list of libraries embedded in an addon
|
||||||
|
|
||||||
-- Lua APIs
|
-- Lua APIs
|
||||||
local getn, tinsert, tconcat, tremove = table.getn, table.insert, table.concat, table.remove
|
local tinsert, tconcat, tremove, tgetn = table.insert, table.concat, table.remove, table.getn
|
||||||
local fmt, tostring = string.format, tostring
|
local strfmt, tostring = string.format, tostring
|
||||||
local select, pairs, next, type, unpack = select, pairs, next, type, unpack
|
local pairs, next, type, unpack = pairs, next, type, unpack
|
||||||
local loadstring, assert, error = loadstring, assert, error
|
local loadstring, assert, error = loadstring, assert, error
|
||||||
local setmetatable, getmetatable, rawset, rawget = setmetatable, getmetatable, rawset, rawget
|
local setmetatable, getmetatable, rawset, rawget = setmetatable, getmetatable, rawset, rawget
|
||||||
|
|
||||||
@@ -56,54 +60,7 @@ local setmetatable, getmetatable, rawset, rawget = setmetatable, getmetatable, r
|
|||||||
--[[
|
--[[
|
||||||
xpcall safecall implementation
|
xpcall safecall implementation
|
||||||
]]
|
]]
|
||||||
local xpcall = xpcall
|
local safecall = AceCore.safecall
|
||||||
|
|
||||||
local function errorhandler(err)
|
|
||||||
return geterrorhandler()(err)
|
|
||||||
end
|
|
||||||
|
|
||||||
local function CreateDispatcher(argCount)
|
|
||||||
local code = [[
|
|
||||||
local method, ARGS
|
|
||||||
local function call() return method(ARGS) end
|
|
||||||
|
|
||||||
local function dispatch(func, ...)
|
|
||||||
method = func
|
|
||||||
if not method then return end
|
|
||||||
ARGS = unpack(arg)
|
|
||||||
return xpcall(call, function(err) return geterrorhandler()(err) end)
|
|
||||||
end
|
|
||||||
|
|
||||||
return dispatch
|
|
||||||
]]
|
|
||||||
|
|
||||||
local ARGS = {}
|
|
||||||
for i = 1, argCount do
|
|
||||||
ARGS[i] = "arg"..i
|
|
||||||
end
|
|
||||||
|
|
||||||
code = string.gsub(code, "ARGS", tconcat(ARGS, ", "))
|
|
||||||
return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(xpcall, errorhandler)
|
|
||||||
end
|
|
||||||
|
|
||||||
local Dispatchers = setmetatable({}, {__index=function(self, argCount)
|
|
||||||
local dispatcher = CreateDispatcher(argCount)
|
|
||||||
rawset(self, argCount, dispatcher)
|
|
||||||
return dispatcher
|
|
||||||
end})
|
|
||||||
Dispatchers[0] = function(func)
|
|
||||||
return xpcall(func, errorhandler)
|
|
||||||
end
|
|
||||||
|
|
||||||
local function safecall(func, ...)
|
|
||||||
-- we check to see if the func is passed is actually a function here and don't error when it isn't
|
|
||||||
-- this safecall is used for optional functions like OnInitialize OnEnable etc. When they are not
|
|
||||||
-- present execution should continue without hinderance
|
|
||||||
if type(func) == "function" then
|
|
||||||
--print(Dispatchers[getn(arg)](func, unpack(arg)))
|
|
||||||
return func(unpack(arg))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- local functions that will be implemented further down
|
-- local functions that will be implemented further down
|
||||||
local Enable, Disable, EnableModule, DisableModule, Embed, NewModule, GetModule, GetName, SetDefaultModuleState, SetDefaultModuleLibraries, SetEnabledState, SetDefaultModulePrototype
|
local Enable, Disable, EnableModule, DisableModule, Embed, NewModule, GetModule, GetName, SetDefaultModuleState, SetDefaultModuleLibraries, SetEnabledState, SetDefaultModulePrototype
|
||||||
@@ -113,7 +70,7 @@ local function addontostring( self ) return self.name end
|
|||||||
|
|
||||||
-- Check if the addon is queued for initialization
|
-- Check if the addon is queued for initialization
|
||||||
local function queuedForInitialization(addon)
|
local function queuedForInitialization(addon)
|
||||||
for i = 1, getn(AceAddon.initializequeue) do
|
for i = 1, tgetn(AceAddon.initializequeue) do
|
||||||
if AceAddon.initializequeue[i] == addon then
|
if AceAddon.initializequeue[i] == addon then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
@@ -136,24 +93,34 @@ end
|
|||||||
-- -- Create a Addon object based on the table of a frame
|
-- -- Create a Addon object based on the table of a frame
|
||||||
-- local MyFrame = CreateFrame("Frame")
|
-- local MyFrame = CreateFrame("Frame")
|
||||||
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon(MyFrame, "MyAddon", "AceEvent-3.0")
|
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon(MyFrame, "MyAddon", "AceEvent-3.0")
|
||||||
function AceAddon:NewAddon(objectorname, ...)
|
function AceAddon:NewAddon(objectorname,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||||
|
|
||||||
local object,name
|
local object,name
|
||||||
local i=1
|
|
||||||
if type(objectorname)=="table" then
|
if type(objectorname)=="table" then
|
||||||
object=objectorname
|
object=objectorname
|
||||||
name=unpack(arg)
|
name=a0
|
||||||
i=2
|
|
||||||
else
|
else
|
||||||
name=objectorname
|
name=objectorname
|
||||||
end
|
end
|
||||||
|
|
||||||
if type(name)~="string" then
|
if type(name)~="string" then
|
||||||
error(("Usage: NewAddon([object,] name, [lib, lib, lib, ...]): 'name' - string expected got '%s'."):format(type(name)), 2)
|
error(strfmt("Usage: NewAddon([object,] name, [lib, lib, lib, ...]): 'name' - string expected got '%s'.", type(name)), 2)
|
||||||
end
|
end
|
||||||
if self.addons[name] then
|
if self.addons[name] then
|
||||||
error(("Usage: NewAddon([object,] name, [lib, lib, lib, ...]): 'name' - Addon '%s' already exists."):format(name), 2)
|
error(strfmt("Usage: NewAddon([object,] name, [lib, lib, lib, ...]): 'name' - Addon '%s' already exists.", name), 2)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local args = new()
|
||||||
|
args[1] = a1
|
||||||
|
args[2] = a2
|
||||||
|
args[3] = a3
|
||||||
|
args[4] = a4
|
||||||
|
args[5] = a5
|
||||||
|
args[6] = a6
|
||||||
|
args[7] = a7
|
||||||
|
args[8] = a8
|
||||||
|
args[9] = a9
|
||||||
|
args[10] = a10
|
||||||
|
|
||||||
object = object or {}
|
object = object or {}
|
||||||
object.name = name
|
object.name = name
|
||||||
|
|
||||||
@@ -170,14 +137,18 @@ function AceAddon:NewAddon(objectorname, ...)
|
|||||||
object.orderedModules = {}
|
object.orderedModules = {}
|
||||||
object.defaultModuleLibraries = {}
|
object.defaultModuleLibraries = {}
|
||||||
Embed( object ) -- embed NewModule, GetModule methods
|
Embed( object ) -- embed NewModule, GetModule methods
|
||||||
self:EmbedLibraries(object, unpack(arg))
|
if type(objectorname)=="table" then
|
||||||
|
self:EmbedLibraries(object,nil,args)
|
||||||
|
elseif a0 then
|
||||||
|
self:EmbedLibraries(object,a0,args)
|
||||||
|
end
|
||||||
|
del(args)
|
||||||
|
|
||||||
-- add to queue of addons to be initialized upon ADDON_LOADED
|
-- add to queue of addons to be initialized upon ADDON_LOADED
|
||||||
tinsert(self.initializequeue, object)
|
tinsert(self.initializequeue, object)
|
||||||
return object
|
return object
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Get the addon object by its name from the internal AceAddon registry.
|
--- Get the addon object by its name from the internal AceAddon registry.
|
||||||
-- Throws an error if the addon object cannot be found (except if silent is set).
|
-- Throws an error if the addon object cannot be found (except if silent is set).
|
||||||
-- @param name unique name of the addon object
|
-- @param name unique name of the addon object
|
||||||
@@ -187,7 +158,7 @@ end
|
|||||||
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
|
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
|
||||||
function AceAddon:GetAddon(name, silent)
|
function AceAddon:GetAddon(name, silent)
|
||||||
if not silent and not self.addons[name] then
|
if not silent and not self.addons[name] then
|
||||||
error(("Usage: GetAddon(name): 'name' - Cannot find an AceAddon '%s'."):format(tostring(name)), 2)
|
error(strfmt("Usage: GetAddon(name): 'name' - Cannot find an AceAddon '%s'.", tostring(name)), 2)
|
||||||
end
|
end
|
||||||
return self.addons[name]
|
return self.addons[name]
|
||||||
end
|
end
|
||||||
@@ -200,10 +171,12 @@ end
|
|||||||
-- @paramsig addon, [lib, ...]
|
-- @paramsig addon, [lib, ...]
|
||||||
-- @param addon addon object to embed the libs in
|
-- @param addon addon object to embed the libs in
|
||||||
-- @param lib List of libraries to embed into the addon
|
-- @param lib List of libraries to embed into the addon
|
||||||
function AceAddon:EmbedLibraries(addon, ...)
|
function AceAddon:EmbedLibraries(addon,a1,arg)
|
||||||
for i=1, getn(arg) do
|
if a1 then self:EmbedLibrary(addon, a1, false, 4) end
|
||||||
local libname = arg[i]
|
-- 10 is the max number of variable arguments in the function NewAddon and NewModule
|
||||||
self:EmbedLibrary(addon, libname, false, 4)
|
for i=1,10 do
|
||||||
|
if not arg[i] then return end
|
||||||
|
self:EmbedLibrary(addon, arg[i], false, 4)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -221,13 +194,13 @@ end
|
|||||||
function AceAddon:EmbedLibrary(addon, libname, silent, offset)
|
function AceAddon:EmbedLibrary(addon, libname, silent, offset)
|
||||||
local lib = LibStub:GetLibrary(libname, true)
|
local lib = LibStub:GetLibrary(libname, true)
|
||||||
if not lib and not silent then
|
if not lib and not silent then
|
||||||
error(("Usage: EmbedLibrary(addon, libname, silent, offset): 'libname' - Cannot find a library instance of %q."):format(tostring(libname)), offset or 2)
|
error(strfmt("Usage: EmbedLibrary(addon, libname, silent, offset): 'libname' - Cannot find a library instance of %q.", tostring(libname)), offset or 2)
|
||||||
elseif lib and type(lib.Embed) == "function" then
|
elseif lib and type(lib.Embed) == "function" then
|
||||||
lib:Embed(addon)
|
lib:Embed(addon)
|
||||||
tinsert(self.embeds[addon], libname)
|
tinsert(self.embeds[addon], libname)
|
||||||
return true
|
return true
|
||||||
elseif lib then
|
elseif lib then
|
||||||
error(("Usage: EmbedLibrary(addon, libname, silent, offset): 'libname' - Library '%s' is not Embed capable"):format(libname), offset or 2)
|
error(strfmt("Usage: EmbedLibrary(addon, libname, silent, offset): 'libname' - Library '%s' is not Embed capable", libname), offset or 2)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -244,7 +217,7 @@ end
|
|||||||
-- MyModule = MyAddon:GetModule("MyModule")
|
-- MyModule = MyAddon:GetModule("MyModule")
|
||||||
function GetModule(self, name, silent)
|
function GetModule(self, name, silent)
|
||||||
if not self.modules[name] and not silent then
|
if not self.modules[name] and not silent then
|
||||||
error(("Usage: GetModule(name, silent): 'name' - Cannot find module '%s'."):format(tostring(name)), 2)
|
error(strfmt("Usage: GetModule(name, silent): 'name' - Cannot find module '%s'.", tostring(name)), 2)
|
||||||
end
|
end
|
||||||
return self.modules[name]
|
return self.modules[name]
|
||||||
end
|
end
|
||||||
@@ -267,26 +240,39 @@ local function IsModuleTrue(self) return true end
|
|||||||
-- -- Create a module with a prototype
|
-- -- Create a module with a prototype
|
||||||
-- local prototype = { OnEnable = function(self) print("OnEnable called!") end }
|
-- local prototype = { OnEnable = function(self) print("OnEnable called!") end }
|
||||||
-- MyModule = MyAddon:NewModule("MyModule", prototype, "AceEvent-3.0", "AceHook-3.0")
|
-- MyModule = MyAddon:NewModule("MyModule", prototype, "AceEvent-3.0", "AceHook-3.0")
|
||||||
function NewModule(self, name, prototype, ...)
|
function NewModule(self, name, prototype, a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||||
if type(name) ~= "string" then error(("Usage: NewModule(name, [prototype, [lib, lib, lib, ...]): 'name' - string expected got '%s'."):format(type(name)), 2) end
|
if type(name) ~= "string" then error(strfmt("Usage: NewModule(name, [prototype, [lib, lib, lib, ...]): 'name' - string expected got '%s'.", type(name)), 2) end
|
||||||
if type(prototype) ~= "string" and type(prototype) ~= "table" and type(prototype) ~= "nil" then error(("Usage: NewModule(name, [prototype, [lib, lib, lib, ...]): 'prototype' - table (prototype), string (lib) or nil expected got '%s'."):format(type(prototype)), 2) end
|
if type(prototype) ~= "string" and type(prototype) ~= "table" and type(prototype) ~= "nil" then error(strfmt("Usage: NewModule(name, [prototype, [lib, lib, lib, ...]): 'prototype' - table (prototype), string (lib) or nil expected got '%s'.", type(prototype)), 2) end
|
||||||
|
|
||||||
if self.modules[name] then error(("Usage: NewModule(name, [prototype, [lib, lib, lib, ...]): 'name' - Module '%s' already exists."):format(name), 2) end
|
if self.modules[name] then error(strfmt("Usage: NewModule(name, [prototype, [lib, lib, lib, ...]): 'name' - Module '%s' already exists.", name), 2) end
|
||||||
|
|
||||||
-- modules are basically addons. We treat them as such. They will be added to the initializequeue properly as well.
|
-- modules are basically addons. We treat them as such. They will be added to the initializequeue properly as well.
|
||||||
-- NewModule can only be called after the parent addon is present thus the modules will be initialized after their parent is.
|
-- NewModule can only be called after the parent addon is present thus the modules will be initialized after their parent is.
|
||||||
local module = AceAddon:NewAddon(fmt("%s_%s", self.name or tostring(self), name))
|
local module = AceAddon:NewAddon(strfmt("%s_%s", self.name or tostring(self), name))
|
||||||
|
|
||||||
module.IsModule = IsModuleTrue
|
module.IsModule = IsModuleTrue
|
||||||
module:SetEnabledState(self.defaultModuleState)
|
module:SetEnabledState(self.defaultModuleState)
|
||||||
module.moduleName = name
|
module.moduleName = name
|
||||||
|
|
||||||
|
local args = new()
|
||||||
|
args[1] = a1
|
||||||
|
args[2] = a2
|
||||||
|
args[3] = a3
|
||||||
|
args[4] = a4
|
||||||
|
args[5] = a5
|
||||||
|
args[6] = a6
|
||||||
|
args[7] = a7
|
||||||
|
args[8] = a8
|
||||||
|
args[9] = a9
|
||||||
|
args[10] = a10
|
||||||
|
|
||||||
if type(prototype) == "string" then
|
if type(prototype) == "string" then
|
||||||
AceAddon:EmbedLibraries(module, prototype, unpack(arg))
|
AceAddon:EmbedLibraries(module, prototype, args)
|
||||||
else
|
else
|
||||||
AceAddon:EmbedLibraries(module, unpack(arg))
|
AceAddon:EmbedLibraries(module, nil, args)
|
||||||
end
|
end
|
||||||
AceAddon:EmbedLibraries(module, unpack(self.defaultModuleLibraries))
|
del(args)
|
||||||
|
AceAddon:EmbedLibraries(module, nil, self.defaultModuleLibraries)
|
||||||
|
|
||||||
if not prototype or type(prototype) == "string" then
|
if not prototype or type(prototype) == "string" then
|
||||||
prototype = self.defaultModulePrototype or nil
|
prototype = self.defaultModulePrototype or nil
|
||||||
@@ -298,7 +284,7 @@ function NewModule(self, name, prototype, ...)
|
|||||||
setmetatable(module, mt) -- More of a Base class type feel.
|
setmetatable(module, mt) -- More of a Base class type feel.
|
||||||
end
|
end
|
||||||
|
|
||||||
safecall(self.OnModuleCreated, self, module) -- Was in Ace2 and I think it could be a cool thing to have handy.
|
safecall(self.OnModuleCreated, 2, self, module) -- Was in Ace2 and I think it could be a cool thing to have handy.
|
||||||
self.modules[name] = module
|
self.modules[name] = module
|
||||||
tinsert(self.orderedModules, module)
|
tinsert(self.orderedModules, module)
|
||||||
|
|
||||||
@@ -399,11 +385,25 @@ end
|
|||||||
-- MyAddon:SetDefaultModuleLibraries("AceEvent-3.0")
|
-- MyAddon:SetDefaultModuleLibraries("AceEvent-3.0")
|
||||||
-- -- Create a module
|
-- -- Create a module
|
||||||
-- MyModule = MyAddon:NewModule("MyModule")
|
-- MyModule = MyAddon:NewModule("MyModule")
|
||||||
function SetDefaultModuleLibraries(self, ...)
|
function SetDefaultModuleLibraries(self,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||||
if next(self.modules) then
|
if next(self.modules) then
|
||||||
error("Usage: SetDefaultModuleLibraries(...): cannot change the module defaults after a module has been registered.", 2)
|
error("Usage: SetDefaultModuleLibraries(...): cannot change the module defaults after a module has been registered.", 2)
|
||||||
end
|
end
|
||||||
self.defaultModuleLibraries = {unpack(arg)}
|
local args = self.defaultModuleLibraries or {}
|
||||||
|
|
||||||
|
args[1] = a1
|
||||||
|
args[2] = a2
|
||||||
|
args[3] = a3
|
||||||
|
args[4] = a4
|
||||||
|
args[5] = a5
|
||||||
|
args[6] = a6
|
||||||
|
args[7] = a7
|
||||||
|
args[8] = a8
|
||||||
|
args[9] = a9
|
||||||
|
args[10] = a10
|
||||||
|
truncate(tmp,10)
|
||||||
|
|
||||||
|
self.defaultModuleLibraries = args
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Set the default state in which new modules are being created.
|
--- Set the default state in which new modules are being created.
|
||||||
@@ -446,7 +446,7 @@ function SetDefaultModulePrototype(self, prototype)
|
|||||||
error("Usage: SetDefaultModulePrototype(prototype): cannot change the module defaults after a module has been registered.", 2)
|
error("Usage: SetDefaultModulePrototype(prototype): cannot change the module defaults after a module has been registered.", 2)
|
||||||
end
|
end
|
||||||
if type(prototype) ~= "table" then
|
if type(prototype) ~= "table" then
|
||||||
error(("Usage: SetDefaultModulePrototype(prototype): 'prototype' - table expected got '%s'."):format(type(prototype)), 2)
|
error(strfmt("Usage: SetDefaultModulePrototype(prototype): 'prototype' - table expected got '%s'.", type(prototype)), 2)
|
||||||
end
|
end
|
||||||
self.defaultModulePrototype = prototype
|
self.defaultModulePrototype = prototype
|
||||||
end
|
end
|
||||||
@@ -530,12 +530,12 @@ end
|
|||||||
-- **Note:** Do not call this function manually, unless you're absolutely sure that you know what you are doing.
|
-- **Note:** Do not call this function manually, unless you're absolutely sure that you know what you are doing.
|
||||||
-- @param addon addon object to intialize
|
-- @param addon addon object to intialize
|
||||||
function AceAddon:InitializeAddon(addon)
|
function AceAddon:InitializeAddon(addon)
|
||||||
safecall(addon.OnInitialize, addon)
|
safecall(addon.OnInitialize, 1, addon)
|
||||||
|
|
||||||
local embeds = self.embeds[addon]
|
local embeds = self.embeds[addon]
|
||||||
for i = 1, getn(embeds) do
|
for i = 1, tgetn(embeds) do
|
||||||
local lib = LibStub:GetLibrary(embeds[i], true)
|
local lib = LibStub:GetLibrary(embeds[i], true)
|
||||||
if lib then safecall(lib.OnEmbedInitialize, lib, addon) end
|
if lib then safecall(lib.OnEmbedInitialize, 2, lib, addon) end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- we don't call InitializeAddon on modules specifically, this is handled
|
-- we don't call InitializeAddon on modules specifically, this is handled
|
||||||
@@ -559,19 +559,19 @@ function AceAddon:EnableAddon(addon)
|
|||||||
-- set the statuses first, before calling the OnEnable. this allows for Disabling of the addon in OnEnable.
|
-- set the statuses first, before calling the OnEnable. this allows for Disabling of the addon in OnEnable.
|
||||||
self.statuses[addon.name] = true
|
self.statuses[addon.name] = true
|
||||||
|
|
||||||
safecall(addon.OnEnable, addon)
|
safecall(addon.OnEnable, 1, addon)
|
||||||
|
|
||||||
-- make sure we're still enabled before continueing
|
-- make sure we're still enabled before continueing
|
||||||
if self.statuses[addon.name] then
|
if self.statuses[addon.name] then
|
||||||
local embeds = self.embeds[addon]
|
local embeds = self.embeds[addon]
|
||||||
for i = 1, getn(embeds) do
|
for i = 1, tgetn(embeds) do
|
||||||
local lib = LibStub:GetLibrary(embeds[i], true)
|
local lib = LibStub:GetLibrary(embeds[i], true)
|
||||||
if lib then safecall(lib.OnEmbedEnable, lib, addon) end
|
if lib then safecall(lib.OnEmbedEnable, 2, lib, addon) end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- enable possible modules.
|
-- enable possible modules.
|
||||||
local modules = addon.orderedModules
|
local modules = addon.orderedModules
|
||||||
for i = 1, getn(modules) do
|
for i = 1, tgetn(modules) do
|
||||||
self:EnableAddon(modules[i])
|
self:EnableAddon(modules[i])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -594,18 +594,18 @@ function AceAddon:DisableAddon(addon)
|
|||||||
-- set statuses first before calling OnDisable, this allows for aborting the disable in OnDisable.
|
-- set statuses first before calling OnDisable, this allows for aborting the disable in OnDisable.
|
||||||
self.statuses[addon.name] = false
|
self.statuses[addon.name] = false
|
||||||
|
|
||||||
safecall( addon.OnDisable, addon )
|
safecall(addon.OnDisable, 1, addon)
|
||||||
|
|
||||||
-- make sure we're still disabling...
|
-- make sure we're still disabling...
|
||||||
if not self.statuses[addon.name] then
|
if not self.statuses[addon.name] then
|
||||||
local embeds = self.embeds[addon]
|
local embeds = self.embeds[addon]
|
||||||
for i = 1, getn(embeds) do
|
for i = 1, tgetn(embeds) do
|
||||||
local lib = LibStub:GetLibrary(embeds[i], true)
|
local lib = LibStub:GetLibrary(embeds[i], true)
|
||||||
if lib then safecall(lib.OnEmbedDisable, lib, addon) end
|
if lib then safecall(lib.OnEmbedDisable, 2, lib, addon) end
|
||||||
end
|
end
|
||||||
-- disable possible modules.
|
-- disable possible modules.
|
||||||
local modules = addon.orderedModules
|
local modules = addon.orderedModules
|
||||||
for i = 1, getn(modules) do
|
for i = 1, tgetn(modules) do
|
||||||
self:DisableAddon(modules[i])
|
self:DisableAddon(modules[i])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -636,13 +636,22 @@ function AceAddon:IterateAddonStatus() return pairs(self.statuses) end
|
|||||||
function AceAddon:IterateEmbedsOnAddon(addon) return pairs(self.embeds[addon]) end
|
function AceAddon:IterateEmbedsOnAddon(addon) return pairs(self.embeds[addon]) end
|
||||||
function AceAddon:IterateModulesOfAddon(addon) return pairs(addon.modules) end
|
function AceAddon:IterateModulesOfAddon(addon) return pairs(addon.modules) end
|
||||||
|
|
||||||
local IsLoggedIn
|
|
||||||
|
local onEvent
|
||||||
|
do
|
||||||
|
local IsLoggedIn = false
|
||||||
-- Event Handling
|
-- Event Handling
|
||||||
local function onEvent()
|
function onEvent()
|
||||||
-- 2011-08-17 nevcairiel - ignore the load event of Blizzard_DebugTools, so a potential startup error isn't swallowed up
|
-- 2011-08-17 nevcairiel - ignore the load event of Blizzard_DebugTools, so a potential startup error isn't swallowed up
|
||||||
|
-- Ace3v: When the ADDON_LOADED event is triggerd, global arg1 is the loaded addon name
|
||||||
|
-- so onEvent(event, arg1) won't work because it will cover the global variables
|
||||||
if (event == "ADDON_LOADED" and arg1 ~= "Blizzard_DebugTools") or event == "PLAYER_LOGIN" then
|
if (event == "ADDON_LOADED" and arg1 ~= "Blizzard_DebugTools") or event == "PLAYER_LOGIN" then
|
||||||
-- if a addon loads another addon, recursion could happen here, so we need to validate the table on every iteration
|
-- if a addon loads another addon, recursion could happen here, so we need to validate the table on every iteration
|
||||||
while(getn(AceAddon.initializequeue) > 0) do
|
-- Ace3v: When an Ace3 addons is loaded, then he initializeque should not be empty unless
|
||||||
|
-- the addon does not use the library. If an addon that does not use Ace3 library
|
||||||
|
-- is loaded, we will also receive the ADDON_LOADED event but in this case the
|
||||||
|
-- queue will be empty so we have nothing to do.
|
||||||
|
while(tgetn(AceAddon.initializequeue) > 0) do
|
||||||
local addon = tremove(AceAddon.initializequeue, 1)
|
local addon = tremove(AceAddon.initializequeue, 1)
|
||||||
-- this might be an issue with recursion - TODO: validate
|
-- this might be an issue with recursion - TODO: validate
|
||||||
if event == "ADDON_LOADED" then addon.baseName = arg1 end
|
if event == "ADDON_LOADED" then addon.baseName = arg1 end
|
||||||
@@ -655,13 +664,14 @@ local function onEvent()
|
|||||||
end
|
end
|
||||||
|
|
||||||
if IsLoggedIn then
|
if IsLoggedIn then
|
||||||
while(getn(AceAddon.enablequeue) > 0) do
|
while(tgetn(AceAddon.enablequeue) > 0) do
|
||||||
local addon = tremove(AceAddon.enablequeue, 1)
|
local addon = tremove(AceAddon.enablequeue, 1)
|
||||||
AceAddon:EnableAddon(addon)
|
AceAddon:EnableAddon(addon)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end -- onEvent
|
||||||
|
|
||||||
AceAddon.frame:RegisterEvent("ADDON_LOADED")
|
AceAddon.frame:RegisterEvent("ADDON_LOADED")
|
||||||
AceAddon.frame:RegisterEvent("PLAYER_LOGIN")
|
AceAddon.frame:RegisterEvent("PLAYER_LOGIN")
|
||||||
|
|||||||
@@ -16,87 +16,110 @@ local AceConsole, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
|
|||||||
|
|
||||||
if not AceConsole then return end -- No upgrade needed
|
if not AceConsole then return end -- No upgrade needed
|
||||||
|
|
||||||
|
local AceCore = LibStub("AceCore-3.0")
|
||||||
|
|
||||||
AceConsole.embeds = AceConsole.embeds or {} -- table containing objects AceConsole is embedded in.
|
AceConsole.embeds = AceConsole.embeds or {} -- table containing objects AceConsole is embedded in.
|
||||||
AceConsole.commands = AceConsole.commands or {} -- table containing commands registered
|
AceConsole.commands = AceConsole.commands or {} -- table containing commands registered
|
||||||
AceConsole.weakcommands = AceConsole.weakcommands or {} -- table containing self, command => func references for weak commands that don't persist through enable/disable
|
AceConsole.weakcommands = AceConsole.weakcommands or {} -- table containing self, command => func references for weak commands that don't persist through enable/disable
|
||||||
|
|
||||||
-- Lua APIs
|
-- Lua APIs
|
||||||
local tconcat, tostring, select = table.concat, tostring, select
|
local tinsert, tconcat, tgetn, tsetn = table.insert, table.concat, table.getn, table.setn
|
||||||
|
local tostring = tostring
|
||||||
local type, pairs, error = type, pairs, error
|
local type, pairs, error = type, pairs, error
|
||||||
local format, strfind, strsub = string.format, string.find, string.sub
|
local format, strfind, strsub = string.format, string.find, string.sub
|
||||||
local max = math.max
|
local max = math.max
|
||||||
|
local strupper, strlower = string.upper, string.lower
|
||||||
|
|
||||||
-- WoW APIs
|
-- WoW APIs
|
||||||
local _G = getfenv()
|
local _G = AceCore._G
|
||||||
|
|
||||||
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
|
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
|
||||||
-- List them here for Mikk's FindGlobals script
|
-- List them here for Mikk's FindGlobals script
|
||||||
-- GLOBALS: DEFAULT_CHAT_FRAME, SlashCmdList, hash_SlashCmdList
|
-- GLOBALS: DEFAULT_CHAT_FRAME, SlashCmdList, hash_SlashCmdList
|
||||||
|
local Print
|
||||||
|
do
|
||||||
local tmp = {}
|
local tmp = {}
|
||||||
local function Print(self,frame,...)
|
function Print(self, frame, arg)
|
||||||
local n=0
|
|
||||||
if self ~= AceConsole then
|
if self ~= AceConsole then
|
||||||
n=n+1
|
tmp[1] = "|cff33ff99"..tostring(self).."|r:"
|
||||||
tmp[n] = "|cff33ff99"..tostring( self ).."|r:"
|
else
|
||||||
|
tmp[1] = ''
|
||||||
end
|
end
|
||||||
for i=1, getn(arg) do
|
if type(arg) == "string" then
|
||||||
n=n+1
|
frame:AddMessage(tmp[1]..arg)
|
||||||
tmp[n] = tostring(arg[i])
|
else -- arg is table and may contain frame as first element if argument frame is nil
|
||||||
|
local b, e = frame and 1 or 2, tgetn(arg)
|
||||||
|
if e >= b then
|
||||||
|
frame = frame or arg[1]
|
||||||
|
for i=0,e-b do
|
||||||
|
tmp[2+i] = tostring(arg[b+i])
|
||||||
end
|
end
|
||||||
frame:AddMessage( tconcat(tmp," ",1,n) )
|
frame:AddMessage(tconcat(tmp," ",1,e-b+2)) -- explicitly, because the length is not affected by assignment
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end -- Print
|
||||||
|
|
||||||
--- Print to DEFAULT_CHAT_FRAME or given ChatFrame (anything with an .AddMessage function)
|
--- Print to DEFAULT_CHAT_FRAME or given ChatFrame (anything with an .AddMessage function)
|
||||||
-- @paramsig [chatframe ,] ...
|
-- @paramsig [chatframe ,] ...
|
||||||
-- @param chatframe Custom ChatFrame to print to (or any frame with an .AddMessage function)
|
-- @param chatframe Custom ChatFrame to print to (or any frame with an .AddMessage function)
|
||||||
-- @param ... List of any values to be printed
|
-- @param ... List of any values to be printed
|
||||||
function AceConsole:Print(...)
|
function AceConsole:Print(...)
|
||||||
local frame = arg
|
local frame = arg[1]
|
||||||
if type(frame) == "table" and frame.AddMessage then -- Is first argument something with an .AddMessage member?
|
if type(frame) == "table" and frame.AddMessage then -- Is first argument something with an .AddMessage member?
|
||||||
return Print(self, frame, arg[2])
|
return Print(self, nil, arg)
|
||||||
else
|
else
|
||||||
return Print(self, DEFAULT_CHAT_FRAME, arg)
|
return Print(self, DEFAULT_CHAT_FRAME, arg)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Formatted (using format()) print to DEFAULT_CHAT_FRAME or given ChatFrame (anything with an .AddMessage function)
|
--- Formatted (using format()) print to DEFAULT_CHAT_FRAME or given ChatFrame (anything with an .AddMessage function)
|
||||||
-- @paramsig [chatframe ,] "format"[, ...]
|
-- @paramsig [chatframe ,] "format"[, ...]
|
||||||
-- @param chatframe Custom ChatFrame to print to (or any frame with an .AddMessage function)
|
-- @param chatframe Custom ChatFrame to print to (or any frame with an .AddMessage function)
|
||||||
-- @param format Format string - same syntax as standard Lua format()
|
-- @param format Format string - same syntax as standard Lua format()
|
||||||
-- @param ... Arguments to the format string
|
-- @param ... Arguments to the format string
|
||||||
function AceConsole:Printf(...)
|
function AceConsole:Printf(a1, ...)
|
||||||
local frame = arg
|
local frame, succ, s
|
||||||
if type(frame) == "table" and frame.AddMessage then -- Is first argument something with an .AddMessage member?
|
if type(a1) == "table" and a1.AddMessage then -- Is first argument something with an .AddMessage member?
|
||||||
return Print(self, frame, format(arg[2]))
|
frame, succ, s = a1, pcall(format, unpack(arg))
|
||||||
else
|
else
|
||||||
return Print(self, DEFAULT_CHAT_FRAME, format(arg))
|
frame, succ, s = DEFAULT_CHAT_FRAME, pcall(format, a1, unpack(arg))
|
||||||
end
|
end
|
||||||
|
if not succ then error(s,2) end
|
||||||
|
return Print(self, frame, s)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- Register a simple chat command
|
--- Register a simple chat command
|
||||||
-- @param command Chat command to be registered WITHOUT leading "/"
|
-- @param command Chat command to be registered WITHOUT leading "/"
|
||||||
-- @param func Function to call when the slash command is being used (funcref or methodname)
|
-- @param func Function to call when the slash command is being used (funcref or methodname)
|
||||||
-- @param persist if false, the command will be soft disabled/enabled when aceconsole is used as a mixin (default: true)
|
-- @param persist if false, the command will be soft disabled/enabled when aceconsole is used as a mixin (default: true)
|
||||||
function AceConsole:RegisterChatCommand( command, func, persist )
|
function AceConsole:RegisterChatCommand( command, func, persist )
|
||||||
if type(command)~="string" then error([[Usage: AceConsole:RegisterChatCommand( "command", func[, persist ]): 'command' - expected a string]], 2) end
|
if type(command)~="string" then error([[Usage: AceConsole:RegisterChatCommand(command, func[, persist ]): 'command' - expected a string]], 2) end
|
||||||
|
|
||||||
if persist==nil then persist=true end -- I'd rather have my addon's "/addon enable" around if the author screws up. Having some extra slash regged when it shouldnt be isn't as destructive. True is a better default. /Mikk
|
if persist==nil then persist=true end -- I'd rather have my addon's "/addon enable" around if the author screws up. Having some extra slash regged when it shouldnt be isn't as destructive. True is a better default. /Mikk
|
||||||
|
|
||||||
local name = "ACECONSOLE_"..string.upper(command)
|
local name = "ACECONSOLE_"..strupper(command)
|
||||||
|
|
||||||
if type( func ) == "string" then
|
local t = type(func)
|
||||||
|
|
||||||
|
if t == "string" then
|
||||||
|
-- Ace3v: prevent user from using AceConSole as self
|
||||||
|
if self == AceConsole then
|
||||||
|
error([[Usage: RegisterChatCommand(command, func[, persist]): 'self' - use your own 'self']], 2)
|
||||||
|
end
|
||||||
SlashCmdList[name] = function(input, editBox)
|
SlashCmdList[name] = function(input, editBox)
|
||||||
self[func](self, input, editBox)
|
self[func](self, input, editBox)
|
||||||
end
|
end
|
||||||
else
|
elseif t == "function" then
|
||||||
SlashCmdList[name] = func
|
SlashCmdList[name] = func
|
||||||
|
else
|
||||||
|
error([[Usage: AceConsole:RegisterChatCommand(command, func[, persist ]): 'func' - expected a string or a function]], 2)
|
||||||
end
|
end
|
||||||
_G["SLASH_"..name.."1"] = "/"..string.lower(command)
|
_G["SLASH_"..name.."1"] = "/"..strlower(command)
|
||||||
AceConsole.commands[command] = name
|
AceConsole.commands[command] = name
|
||||||
-- non-persisting commands are registered for enabling disabling
|
-- non-persisting commands are registered for enabling disabling
|
||||||
if not persist then
|
if not persist then
|
||||||
@@ -113,7 +136,6 @@ function AceConsole:UnregisterChatCommand( command )
|
|||||||
if name then
|
if name then
|
||||||
SlashCmdList[name] = nil
|
SlashCmdList[name] = nil
|
||||||
_G["SLASH_" .. name .. "1"] = nil
|
_G["SLASH_" .. name .. "1"] = nil
|
||||||
hash_SlashCmdList["/" .. command:upper()] = nil
|
|
||||||
AceConsole.commands[command] = nil
|
AceConsole.commands[command] = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -122,18 +144,16 @@ end
|
|||||||
-- @return Iterator (pairs) over all commands
|
-- @return Iterator (pairs) over all commands
|
||||||
function AceConsole:IterateChatCommands() return pairs(AceConsole.commands) end
|
function AceConsole:IterateChatCommands() return pairs(AceConsole.commands) end
|
||||||
|
|
||||||
|
local function nils(n,argc,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||||
local function nils(n, ...)
|
if n >= 1 then
|
||||||
if n>1 then
|
return nil, nils(n-1,argc,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||||
return nil, nils(n-1, arg)
|
elseif not argc or argc == 0 then
|
||||||
elseif n==1 then
|
return
|
||||||
return nil, arg
|
|
||||||
else
|
else
|
||||||
return arg
|
return a1, nils(0,argc-1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Retreive one or more space-separated arguments from a string.
|
--- Retreive one or more space-separated arguments from a string.
|
||||||
-- Treats quoted strings and itemlinks as non-spaced.
|
-- Treats quoted strings and itemlinks as non-spaced.
|
||||||
-- @param str The raw argument string
|
-- @param str The raw argument string
|
||||||
@@ -150,7 +170,7 @@ function AceConsole:GetArgs(str, numargs, startpos)
|
|||||||
-- find start of new arg
|
-- find start of new arg
|
||||||
pos = strfind(str, "[^ ]", pos)
|
pos = strfind(str, "[^ ]", pos)
|
||||||
if not pos then -- whoops, end of string
|
if not pos then -- whoops, end of string
|
||||||
return nils(numargs, 1e9)
|
return nils(numargs, 1, 1e9)
|
||||||
end
|
end
|
||||||
|
|
||||||
if numargs<1 then
|
if numargs<1 then
|
||||||
@@ -205,7 +225,7 @@ function AceConsole:GetArgs(str, numargs, startpos)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- search aborted, we hit end of string. return it all as one argument. (yes, even if it's an unterminated quote or hyperlink)
|
-- search aborted, we hit end of string. return it all as one argument. (yes, even if it's an unterminated quote or hyperlink)
|
||||||
return strsub(str, startpos), nils(numargs-1, 1e9)
|
return strsub(str, startpos), nils(numargs-1, 1, 1e9)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ if not AceEvent then return end
|
|||||||
-- Lua APIs
|
-- Lua APIs
|
||||||
local pairs = pairs
|
local pairs = pairs
|
||||||
|
|
||||||
local CallbackHandler = LibStub("CallbackHandler-1.0")
|
local CallbackHandler = LibStub:GetLibrary("CallbackHandler-1.0")
|
||||||
|
|
||||||
AceEvent.frame = AceEvent.frame or CreateFrame("Frame", "AceEvent30Frame") -- our event frame
|
AceEvent.frame = AceEvent.frame or CreateFrame("Frame", "AceEvent30Frame") -- our event frame
|
||||||
AceEvent.embeds = AceEvent.embeds or {} -- what objects embed this lib
|
AceEvent.embeds = AceEvent.embeds or {} -- what objects embed this lib
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
--- **AceTimer-3.0** provides a central facility for registering timers.
|
--- **AceTimer-3.0** provides a central facility for registering timers.
|
||||||
-- AceTimer supports one-shot timers and repeating timers. All timers are stored in an efficient
|
-- AceTimer supports one-shot timers and repeating timers. All timers are stored in an efficient
|
||||||
-- data structure that allows easy dispatching and fast rescheduling. Timers can be registered, rescheduled
|
-- data structure that allows easy dispatching and fast rescheduling. Timers can be registered
|
||||||
-- or canceled at any time, even from within a running timer, without conflict or large overhead.\\
|
-- or canceled at any time, even from within a running timer, without conflict or large overhead.\\
|
||||||
-- AceTimer is currently limited to firing timers at a frequency of 0.1s. This constant may change
|
-- AceTimer is currently limited to firing timers at a frequency of 0.01s as this is what the WoW timer API
|
||||||
-- in the future, but for now it seemed like a good compromise in efficiency and accuracy.
|
-- restricts us to.
|
||||||
--
|
--
|
||||||
-- All `:Schedule` functions will return a handle to the current timer, which you will need to store if you
|
-- All `:Schedule` functions will return a handle to the current timer, which you will need to store if you
|
||||||
-- need to cancel or reschedule the timer you just registered.
|
-- need to cancel the timer you just registered.
|
||||||
--
|
--
|
||||||
-- **AceTimer-3.0** can be embeded into your addon, either explicitly by calling AceTimer:Embed(MyAddon) or by
|
-- **AceTimer-3.0** can be embeded into your addon, either explicitly by calling AceTimer:Embed(MyAddon) or by
|
||||||
-- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object
|
-- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object
|
||||||
@@ -15,54 +15,33 @@
|
|||||||
-- make into AceTimer.
|
-- make into AceTimer.
|
||||||
-- @class file
|
-- @class file
|
||||||
-- @name AceTimer-3.0
|
-- @name AceTimer-3.0
|
||||||
-- @release $Id: AceTimer-3.0.lua 895 2009-12-06 16:28:55Z nevcairiel $
|
-- @release $Id: AceTimer-3.0.lua 1119 2014-10-14 17:23:29Z nevcairiel $
|
||||||
|
|
||||||
--[[
|
local MAJOR, MINOR = "AceTimer-3.0", 17 -- Bump minor on changes
|
||||||
Basic assumptions:
|
|
||||||
* In a typical system, we do more re-scheduling per second than there are timer pulses per second
|
|
||||||
* Regardless of timer implementation, we cannot guarantee timely delivery due to FPS restriction (may be as low as 10)
|
|
||||||
|
|
||||||
This implementation:
|
|
||||||
CON: The smallest timer interval is constrained by HZ (currently 1/10s).
|
|
||||||
PRO: It will still correctly fire any timer slower than HZ over a length of time, e.g. 0.11s interval -> 90 times over 10 seconds
|
|
||||||
PRO: In lag bursts, the system simly skips missed timer intervals to decrease load
|
|
||||||
CON: Algorithms depending on a timer firing "N times per minute" will fail
|
|
||||||
PRO: (Re-)scheduling is O(1) with a VERY small constant. It's a simple linked list insertion in a hash bucket.
|
|
||||||
CAUTION: The BUCKETS constant constrains how many timers can be efficiently handled. With too many hash collisions, performance will decrease.
|
|
||||||
|
|
||||||
Major assumptions upheld:
|
|
||||||
- ALLOWS scheduling multiple timers with the same funcref/method
|
|
||||||
- ALLOWS scheduling more timers during OnUpdate processing
|
|
||||||
- ALLOWS unscheduling ANY timer (including the current running one) at any time, including during OnUpdate processing
|
|
||||||
]]
|
|
||||||
|
|
||||||
local MAJOR, MINOR = "AceTimer-3.0", 6
|
|
||||||
local AceTimer, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
|
local AceTimer, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
|
||||||
|
|
||||||
if not AceTimer then return end -- No upgrade needed
|
if not AceTimer then return end -- No upgrade needed
|
||||||
|
|
||||||
AceTimer.hash = AceTimer.hash or {} -- Array of [0..BUCKET-1] = linked list of timers (using .next member)
|
local AceCore = LibStub("AceCore-3.0")
|
||||||
-- Linked list gets around ACE-88 and ACE-90.
|
local safecall = AceCore.safecall
|
||||||
AceTimer.selfs = AceTimer.selfs or {} -- Array of [self]={[handle]=timerobj, [handle2]=timerobj2, ...}
|
|
||||||
|
AceTimer.counter = AceTimer.counter or {}
|
||||||
|
AceTimer.hash = AceTimer.hash or {} -- Array of [1..BUCKETS] = linked list of timers (using .next member)
|
||||||
|
AceTimer.activeTimers = AceTimer.activeTimers or {} -- Active timer list
|
||||||
AceTimer.frame = AceTimer.frame or CreateFrame("Frame", "AceTimer30Frame")
|
AceTimer.frame = AceTimer.frame or CreateFrame("Frame", "AceTimer30Frame")
|
||||||
|
|
||||||
|
local counter = AceTimer.counter
|
||||||
|
local activeTimers = AceTimer.activeTimers -- Upvalue our private data
|
||||||
|
local timerFrame = AceTimer.frame
|
||||||
|
|
||||||
-- Lua APIs
|
-- Lua APIs
|
||||||
local assert, error, loadstring = assert, error, loadstring
|
local type, unpack, next, error = type, unpack, next, error
|
||||||
local setmetatable, rawset, rawget = setmetatable, rawset, rawget
|
local floor, max, min, mod = math.floor, math.max, math.min, math.mod
|
||||||
local select, pairs, type, next, tostring = select, pairs, type, next, tostring
|
local tostring = tostring
|
||||||
local floor, max, min = math.floor, math.max, math.min
|
|
||||||
local tconcat = table.concat
|
|
||||||
|
|
||||||
-- WoW APIs
|
-- WoW APIs
|
||||||
local GetTime = GetTime
|
local GetTime = GetTime
|
||||||
|
|
||||||
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
|
|
||||||
-- List them here for Mikk's FindGlobals script
|
|
||||||
-- GLOBALS: DEFAULT_CHAT_FRAME, geterrorhandler
|
|
||||||
|
|
||||||
-- Simple ONE-SHOT timer cache. Much more efficient than a full compost for our purposes.
|
|
||||||
local timerCache = nil
|
|
||||||
|
|
||||||
--[[
|
--[[
|
||||||
Timers will not be fired more often than HZ-1 times per second.
|
Timers will not be fired more often than HZ-1 times per second.
|
||||||
Keep at intended speed PLUS ONE or we get bitten by floating point rounding errors (n.5 + 0.1 can be n.599999)
|
Keep at intended speed PLUS ONE or we get bitten by floating point rounding errors (n.5 + 0.1 can be n.599999)
|
||||||
@@ -70,6 +49,7 @@ local timerCache = nil
|
|||||||
If this number is ever changed, all entries need to be rehashed on lib upgrade.
|
If this number is ever changed, all entries need to be rehashed on lib upgrade.
|
||||||
]]
|
]]
|
||||||
local HZ = 11
|
local HZ = 11
|
||||||
|
local minDelay = 1/(HZ-1)
|
||||||
|
|
||||||
--[[
|
--[[
|
||||||
Prime for good distribution
|
Prime for good distribution
|
||||||
@@ -82,214 +62,122 @@ for i=1,BUCKETS do
|
|||||||
hash[i] = hash[i] or false -- make it an integer-indexed array; it's faster than hashes
|
hash[i] = hash[i] or false -- make it an integer-indexed array; it's faster than hashes
|
||||||
end
|
end
|
||||||
|
|
||||||
--[[
|
local new, del
|
||||||
xpcall safecall implementation
|
do
|
||||||
]]
|
local list = setmetatable({}, {__mode = "k"})
|
||||||
local xpcall = xpcall
|
function new(self, loop, func, delay, argc,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||||
|
local name = loop and "ScheduleRepeatingTimer" or "ScheduleTimer"
|
||||||
local function errorhandler(err)
|
if self == AceTimer then
|
||||||
return geterrorhandler()(err)
|
error(MAJOR..": " .. name .. "(callback, delay, argc, args...): use your own 'self'", 3)
|
||||||
end
|
end
|
||||||
|
if not func or not delay then
|
||||||
local function CreateDispatcher(argCount)
|
error(MAJOR..": " .. name .. "(callback, delay, argc, args...): 'callback' and 'delay' must have set values.", 3)
|
||||||
local code = [[
|
|
||||||
local method, ARGS
|
|
||||||
local function call() return method(ARGS) end
|
|
||||||
|
|
||||||
local function dispatch(func, ...)
|
|
||||||
method = func
|
|
||||||
if not method then return end
|
|
||||||
ARGS = unpack(arg)
|
|
||||||
return xpcall(call, function(err) return geterrorhandler()(err) end)
|
|
||||||
end
|
end
|
||||||
|
if argc and (type(argc) ~= "number" or floor(argc) ~= argc) then
|
||||||
return dispatch
|
error(MAJOR..": " .. name .. "(callback, delay, argc, args...): 'argc' must be an integer.", 3)
|
||||||
]]
|
|
||||||
|
|
||||||
local ARGS = {}
|
|
||||||
for i = 1, argCount do ARGS[i] = "arg"..i end
|
|
||||||
code = gsub(code, "ARGS", tconcat(ARGS, ", "))
|
|
||||||
return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(xpcall, errorhandler)
|
|
||||||
end
|
end
|
||||||
|
if type(func) == "string" then
|
||||||
local Dispatchers = setmetatable({}, {
|
|
||||||
__index=function(self, argCount)
|
|
||||||
local dispatcher = CreateDispatcher(argCount)
|
|
||||||
rawset(self, argCount, dispatcher)
|
|
||||||
return dispatcher
|
|
||||||
end
|
|
||||||
})
|
|
||||||
Dispatchers[0] = function(func)
|
|
||||||
return xpcall(func, errorhandler)
|
|
||||||
end
|
|
||||||
|
|
||||||
local function safecall(func, ...)
|
|
||||||
return Dispatchers[getn(arg)](func, unpack(arg))
|
|
||||||
end
|
|
||||||
|
|
||||||
local lastint = floor(GetTime() * HZ)
|
|
||||||
|
|
||||||
-- --------------------------------------------------------------------
|
|
||||||
-- OnUpdate handler
|
|
||||||
--
|
|
||||||
-- traverse buckets, always chasing "now", and fire timers that have expired
|
|
||||||
|
|
||||||
local function OnUpdate()
|
|
||||||
local now = GetTime()
|
|
||||||
local nowint = floor(now * HZ)
|
|
||||||
|
|
||||||
-- Have we passed into a new hash bucket?
|
|
||||||
if nowint == lastint then return end
|
|
||||||
|
|
||||||
local soon = now + 1 -- +1 is safe as long as 1 < HZ < BUCKETS/2
|
|
||||||
|
|
||||||
-- Pass through each bucket at most once
|
|
||||||
-- Happens on e.g. instance loads, but COULD happen on high local load situations also
|
|
||||||
for curint = (max(lastint, nowint - BUCKETS) + 1), nowint do -- loop until we catch up with "now", usually only 1 iteration
|
|
||||||
local curbucket = (math.mod(curint, BUCKETS))+1
|
|
||||||
-- Yank the list of timers out of the bucket and empty it. This allows reinsertion in the currently-processed bucket from callbacks.
|
|
||||||
local nexttimer = hash[curbucket]
|
|
||||||
hash[curbucket] = false -- false rather than nil to prevent the array from becoming a hash
|
|
||||||
|
|
||||||
while nexttimer do
|
|
||||||
local timer = nexttimer
|
|
||||||
nexttimer = timer.next
|
|
||||||
local when = timer.when
|
|
||||||
|
|
||||||
if when < soon then
|
|
||||||
-- Call the timer func, either as a method on given object, or a straight function ref
|
|
||||||
local callback = timer.callback
|
|
||||||
if type(callback) == "string" then
|
|
||||||
safecall(timer.object[callback], timer.object, timer.arg)
|
|
||||||
elseif callback then
|
|
||||||
safecall(callback, timer.arg)
|
|
||||||
else
|
|
||||||
-- probably nilled out by CancelTimer
|
|
||||||
timer.delay = nil -- don't reschedule it
|
|
||||||
end
|
|
||||||
|
|
||||||
local delay = timer.delay -- NOW make a local copy, can't do it earlier in case the timer cancelled itself in the callback
|
|
||||||
|
|
||||||
if not delay then
|
|
||||||
-- single-shot timer (or cancelled)
|
|
||||||
AceTimer.selfs[timer.object][tostring(timer)] = nil
|
|
||||||
timerCache = timer
|
|
||||||
else
|
|
||||||
-- repeating timer
|
|
||||||
local newtime = when + delay
|
|
||||||
if newtime < now then -- Keep lag from making us firing a timer unnecessarily. (Note that this still won't catch too-short-delay timers though.)
|
|
||||||
newtime = now + delay
|
|
||||||
end
|
|
||||||
timer.when = newtime
|
|
||||||
|
|
||||||
-- add next timer execution to the correct bucket
|
|
||||||
local bucket = (math.mod(floor(newtime * HZ), BUCKETS)) + 1
|
|
||||||
timer.next = hash[bucket]
|
|
||||||
hash[bucket] = timer
|
|
||||||
end
|
|
||||||
else -- if when>=soon
|
|
||||||
-- reinsert (yeah, somewhat expensive, but shouldn't be happening too often either due to hash distribution)
|
|
||||||
timer.next = hash[curbucket]
|
|
||||||
hash[curbucket] = timer
|
|
||||||
end -- if when<soon ... else
|
|
||||||
end -- while nexttimer do
|
|
||||||
end -- for curint=lastint,nowint
|
|
||||||
|
|
||||||
lastint = nowint
|
|
||||||
end
|
|
||||||
|
|
||||||
-- ---------------------------------------------------------------------
|
|
||||||
-- Reg( callback, delay, arg, repeating )
|
|
||||||
--
|
|
||||||
-- callback( function or string ) - direct function ref or method name in our object for the callback
|
|
||||||
-- delay(int) - delay for the timer
|
|
||||||
-- arg(variant) - any argument to be passed to the callback function
|
|
||||||
-- repeating(boolean) - repeating timer, or oneshot
|
|
||||||
--
|
|
||||||
-- returns the handle of the timer for later processing (canceling etc)
|
|
||||||
local function Reg(self, callback, delay, arg, repeating)
|
|
||||||
if type(callback) ~= "string" and type(callback) ~= "function" then
|
|
||||||
local error_origin = repeating and "ScheduleRepeatingTimer" or "ScheduleTimer"
|
|
||||||
error(MAJOR..": " .. error_origin .. "(callback, delay, arg): 'callback' - function or method name expected.", 3)
|
|
||||||
end
|
|
||||||
if type(callback) == "string" then
|
|
||||||
if type(self) ~= "table" then
|
if type(self) ~= "table" then
|
||||||
local error_origin = repeating and "ScheduleRepeatingTimer" or "ScheduleTimer"
|
error(MAJOR..": " .. name .. "(callback, delay, argc, args...): 'self' - must be a table.", 3)
|
||||||
error(MAJOR..": " .. error_origin .. "(\"methodName\", delay, arg): 'self' - must be a table.", 3)
|
elseif type(self[func]) ~= "function" then
|
||||||
end
|
error(MAJOR..": " .. name .. "(callback, delay, argc, args...): Tried to register '"..func.."' as the callback, but it is not a method.", 3)
|
||||||
if type(self[callback]) ~= "function" then
|
|
||||||
local error_origin = repeating and "ScheduleRepeatingTimer" or "ScheduleTimer"
|
|
||||||
error(MAJOR..": " .. error_origin .. "(\"methodName\", delay, arg): 'methodName' - method not found on target object.", 3)
|
|
||||||
end
|
end
|
||||||
|
elseif type(func) ~= "function" then
|
||||||
|
error(MAJOR..": " .. name .. "(callback, delay, argc, args...): Tried to register '"..tostring(func).."' as the callback, but it is not a function.", 3)
|
||||||
end
|
end
|
||||||
|
|
||||||
if delay < (1 / (HZ - 1)) then
|
if delay < minDelay then
|
||||||
delay = 1 / (HZ - 1)
|
delay = minDelay
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Create and stuff timer in the correct hash bucket
|
-- Create and stuff timer in the correct hash bucket
|
||||||
local now = GetTime()
|
local now = GetTime()
|
||||||
|
|
||||||
local timer = timerCache or {} -- Get new timer object (from cache if available)
|
local timer = next(list) or {}
|
||||||
timerCache = nil
|
list[timer] = nil
|
||||||
|
|
||||||
timer.object = self
|
timer.object = self
|
||||||
timer.callback = callback
|
timer.func = func
|
||||||
timer.delay = (repeating and delay)
|
timer.delay = delay
|
||||||
timer.arg = arg
|
timer.status = loop and "loop" or "once"
|
||||||
timer.when = now + delay
|
timer.ends = now + delay
|
||||||
|
timer.argsCount = argc or 0
|
||||||
|
timer[1] = a1
|
||||||
|
timer[2] = a2
|
||||||
|
timer[3] = a3
|
||||||
|
timer[4] = a4
|
||||||
|
timer[5] = a5
|
||||||
|
timer[6] = a6
|
||||||
|
timer[7] = a7
|
||||||
|
timer[8] = a8
|
||||||
|
timer[9] = a9
|
||||||
|
timer[10] = a10
|
||||||
|
|
||||||
local bucket = (math.mod(floor((now+delay)*HZ), BUCKETS)) + 1
|
local bucket = floor(mod((now+delay)*HZ,BUCKETS)) + 1
|
||||||
timer.next = hash[bucket]
|
timer.next = hash[bucket]
|
||||||
hash[bucket] = timer
|
hash[bucket] = timer
|
||||||
|
|
||||||
-- Insert timer in our self->handle->timer registry
|
local id = tostring(timer) -- user has only access to the id but not the table itself
|
||||||
local handle = tostring(timer)
|
activeTimers[id] = timer
|
||||||
|
|
||||||
local selftimers = AceTimer.selfs[self]
|
counter[self] = (counter[self] or 0) + 1
|
||||||
if not selftimers then
|
|
||||||
selftimers = {}
|
|
||||||
AceTimer.selfs[self] = selftimers
|
|
||||||
end
|
|
||||||
selftimers[handle] = timer
|
|
||||||
selftimers.__ops = (selftimers.__ops or 0) + 1
|
|
||||||
|
|
||||||
return handle
|
timerFrame:Show()
|
||||||
|
return id
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function del(t)
|
||||||
|
local id = tostring(t)
|
||||||
|
activeTimers[id] = nil
|
||||||
|
if not next(activeTimers) then
|
||||||
|
timerFrame:Hide()
|
||||||
|
end
|
||||||
|
local self = t.object
|
||||||
|
for k in pairs(t) do t[k] = nil end
|
||||||
|
list[t] = true
|
||||||
|
if counter[self] then
|
||||||
|
counter[self] = counter[self] - 1
|
||||||
|
else
|
||||||
|
counter[self] = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end -- new, del
|
||||||
|
|
||||||
--- Schedule a new one-shot timer.
|
--- Schedule a new one-shot timer.
|
||||||
-- The timer will fire once in `delay` seconds, unless canceled before.
|
-- The timer will fire once in `delay` seconds, unless canceled before.
|
||||||
-- @param callback Callback function for the timer pulse (funcref or method name).
|
-- @param callback Callback function for the timer pulse (funcref or method name).
|
||||||
-- @param delay Delay for the timer, in seconds.
|
-- @param delay Delay for the timer, in seconds.
|
||||||
-- @param arg An optional argument to be passed to the callback function.
|
-- @param argc The numbers of arguments to be passed to the callback function
|
||||||
|
-- @param a1,...,a10 The arguments
|
||||||
-- @usage
|
-- @usage
|
||||||
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("TimerTest", "AceTimer-3.0")
|
-- MyAddOn = LibStub("AceAddon-3.0"):NewAddon("MyAddOn", "AceTimer-3.0")
|
||||||
--
|
--
|
||||||
-- function MyAddon:OnEnable()
|
-- function MyAddOn:OnEnable()
|
||||||
-- self:ScheduleTimer("TimerFeedback", 5)
|
-- self:ScheduleTimer("TimerFeedback", 5)
|
||||||
-- end
|
-- end
|
||||||
--
|
--
|
||||||
-- function MyAddon:TimerFeedback()
|
-- function MyAddOn:TimerFeedback()
|
||||||
-- print("5 seconds passed")
|
-- print("5 seconds passed")
|
||||||
-- end
|
-- end
|
||||||
function AceTimer:ScheduleTimer(callback, delay, arg)
|
function AceTimer:ScheduleTimer(func, delay, argc,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||||
return Reg(self, callback, delay, arg)
|
return new(self, nil, func, delay, argc,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Schedule a repeating timer.
|
--- Schedule a repeating timer.
|
||||||
-- The timer will fire every `delay` seconds, until canceled.
|
-- The timer will fire every `delay` seconds, until canceled.
|
||||||
-- @param callback Callback function for the timer pulse (funcref or method name).
|
-- @param callback Callback function for the timer pulse (funcref or method name).
|
||||||
-- @param delay Delay for the timer, in seconds.
|
-- @param delay Delay for the timer, in seconds.
|
||||||
-- @param arg An optional argument to be passed to the callback function.
|
-- @param argc The numbers of arguments to be passed to the callback function
|
||||||
|
-- @param a1,...,a10 The arguments
|
||||||
-- @usage
|
-- @usage
|
||||||
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("TimerTest", "AceTimer-3.0")
|
-- MyAddOn = LibStub("AceAddon-3.0"):NewAddon("MyAddOn", "AceTimer-3.0")
|
||||||
--
|
--
|
||||||
-- function MyAddon:OnEnable()
|
-- function MyAddOn:OnEnable()
|
||||||
-- self.timerCount = 0
|
-- self.timerCount = 0
|
||||||
-- self.testTimer = self:ScheduleRepeatingTimer("TimerFeedback", 5)
|
-- self.testTimer = self:ScheduleRepeatingTimer("TimerFeedback", 5)
|
||||||
-- end
|
-- end
|
||||||
--
|
--
|
||||||
-- function MyAddon:TimerFeedback()
|
-- function MyAddOn:TimerFeedback()
|
||||||
-- self.timerCount = self.timerCount + 1
|
-- self.timerCount = self.timerCount + 1
|
||||||
-- print(("%d seconds passed"):format(5 * self.timerCount))
|
-- print(("%d seconds passed"):format(5 * self.timerCount))
|
||||||
-- -- run 30 seconds in total
|
-- -- run 30 seconds in total
|
||||||
@@ -297,131 +185,65 @@ end
|
|||||||
-- self:CancelTimer(self.testTimer)
|
-- self:CancelTimer(self.testTimer)
|
||||||
-- end
|
-- end
|
||||||
-- end
|
-- end
|
||||||
function AceTimer:ScheduleRepeatingTimer(callback, delay, arg)
|
function AceTimer:ScheduleRepeatingTimer(func, delay, argc,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||||
return Reg(self, callback, delay, arg, true)
|
return new(self, true, func, delay, argc,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Cancels a timer with the given handle, registered by the same addon object as used for `:ScheduleTimer`
|
--- Cancels a timer with the given id, registered by the same addon object as used for `:ScheduleTimer`
|
||||||
-- Both one-shot and repeating timers can be canceled with this function, as long as the `handle` is valid
|
-- Both one-shot and repeating timers can be canceled with this function, as long as the `id` is valid
|
||||||
-- and the timer has not fired yet or was canceled before.
|
-- and the timer has not fired yet or was canceled before.
|
||||||
-- @param handle The handle of the timer, as returned by `:ScheduleTimer` or `:ScheduleRepeatingTimer`
|
-- @param id The id of the timer, as returned by `:ScheduleTimer` or `:ScheduleRepeatingTimer`
|
||||||
-- @param silent If true, no error is raised if the timer handle is invalid (expired or already canceled)
|
function AceTimer:CancelTimer(id)
|
||||||
-- @return True if the timer was successfully cancelled.
|
local timer = activeTimers[id]
|
||||||
function AceTimer:CancelTimer(handle, silent)
|
|
||||||
if not handle then return end -- nil handle -> bail out without erroring
|
|
||||||
if type(handle) ~= "string" then
|
|
||||||
error(MAJOR..": CancelTimer(handle): 'handle' - expected a string", 2) -- for now, anyway
|
|
||||||
end
|
|
||||||
local selftimers = AceTimer.selfs[self]
|
|
||||||
local timer = selftimers and selftimers[handle]
|
|
||||||
if silent then
|
|
||||||
if timer then
|
|
||||||
timer.callback = nil -- don't run it again
|
|
||||||
timer.delay = nil -- if this is the currently-executing one: don't even reschedule
|
|
||||||
-- The timer object is removed in the OnUpdate loop
|
|
||||||
end
|
|
||||||
return not not timer -- might return "true" even if we double-cancel. we'll live.
|
|
||||||
else
|
|
||||||
if not timer then
|
if not timer then
|
||||||
geterrorhandler()(MAJOR..": CancelTimer(handle[, silent]): '"..tostring(handle).."' - no such timer registered")
|
|
||||||
return false
|
return false
|
||||||
end
|
else
|
||||||
if not timer.callback then
|
-- Ace3v: the timer will always be collected in the next update but not here
|
||||||
geterrorhandler()(MAJOR..": CancelTimer(handle[, silent]): '"..tostring(handle).."' - timer already cancelled or expired")
|
-- this is necessary for AceBucket to determinate if the bucket has been unregistered
|
||||||
return false
|
-- in the callback
|
||||||
end
|
timer.status = nil
|
||||||
timer.callback = nil -- don't run it again
|
activeTimers[id] = nil
|
||||||
timer.delay = nil -- if this is the currently-executing one: don't even reschedule
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Cancels all timers registered to the current addon object ('self')
|
--- Cancels all timers registered to the current addon object ('self')
|
||||||
function AceTimer:CancelAllTimers()
|
function AceTimer:CancelAllTimers()
|
||||||
if not(type(self) == "string" or type(self) == "table") then
|
if type(self) ~= "table" then
|
||||||
error(MAJOR..": CancelAllTimers(): 'self' - must be a string or a table",2)
|
error(MAJOR..": CancelAllTimers(): 'self' - must be a table",2)
|
||||||
end
|
end
|
||||||
if self == AceTimer then
|
if self == AceTimer then
|
||||||
error(MAJOR..": CancelAllTimers(): supply a meaningful 'self'", 2)
|
error(MAJOR..": CancelAllTimers(): supply a meaningful 'self'", 2)
|
||||||
end
|
end
|
||||||
|
|
||||||
local selftimers = AceTimer.selfs[self]
|
for k,v in pairs(activeTimers) do
|
||||||
if selftimers then
|
if v.object == self then
|
||||||
for handle,v in pairs(selftimers) do
|
AceTimer.CancelTimer(self, k)
|
||||||
if type(v) == "table" then -- avoid __ops, etc
|
|
||||||
AceTimer.CancelTimer(self, handle, true)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Returns the time left for a timer with the given handle, registered by the current addon object ('self').
|
--- Returns the time left for a timer with the given id, registered by the current addon object ('self').
|
||||||
-- This function will raise a warning when the handle is invalid, but not stop execution.
|
-- This function will return 0 when the id is invalid.
|
||||||
-- @param handle The handle of the timer, as returned by `:ScheduleTimer` or `:ScheduleRepeatingTimer`
|
-- @param id The id of the timer, as returned by `:ScheduleTimer` or `:ScheduleRepeatingTimer`
|
||||||
-- @return The time left on the timer, or false if the handle is invalid.
|
-- @return The time left on the timer.
|
||||||
function AceTimer:TimeLeft(handle)
|
function AceTimer:TimeLeft(id)
|
||||||
if not handle then return end
|
local timer = activeTimers[id]
|
||||||
if type(handle) ~= "string" then
|
|
||||||
error(MAJOR..": TimeLeft(handle): 'handle' - expected a string", 2) -- for now, anyway
|
|
||||||
end
|
|
||||||
local selftimers = AceTimer.selfs[self]
|
|
||||||
local timer = selftimers and selftimers[handle]
|
|
||||||
if not timer then
|
if not timer then
|
||||||
geterrorhandler()(MAJOR..": TimeLeft(handle): '"..tostring(handle).."' - no such timer registered")
|
return 0
|
||||||
return false
|
else
|
||||||
end
|
return timer.ends - GetTime()
|
||||||
return timer.when - GetTime()
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
-- ---------------------------------------------------------------------
|
|
||||||
-- PLAYER_REGEN_ENABLED: Run through our .selfs[] array step by step
|
|
||||||
-- and clean it out - otherwise the table indices can grow indefinitely
|
|
||||||
-- if an addon starts and stops a lot of timers. AceBucket does this!
|
|
||||||
--
|
|
||||||
-- See ACE-94 and tests/AceTimer-3.0-ACE-94.lua
|
|
||||||
|
|
||||||
local lastCleaned = nil
|
|
||||||
|
|
||||||
local function OnEvent()
|
|
||||||
if event~="PLAYER_REGEN_ENABLED" then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Get the next 'self' to process
|
|
||||||
local selfs = AceTimer.selfs
|
|
||||||
local self = next(selfs, lastCleaned)
|
|
||||||
if not self then
|
|
||||||
self = next(selfs)
|
|
||||||
end
|
|
||||||
lastCleaned = self
|
|
||||||
if not self then -- should only happen if .selfs[] is empty
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Time to clean it out?
|
|
||||||
local list = selfs[self]
|
|
||||||
if (list.__ops or 0) < 250 then -- 250 slosh indices = ~10KB wasted (worst case!). For one 'self'.
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Create a new table and copy all members over
|
|
||||||
local newlist = {}
|
|
||||||
local n=0
|
|
||||||
for k,v in pairs(list) do
|
|
||||||
newlist[k] = v
|
|
||||||
if type(v)=="table" and v.callback then -- if the timer is actually live: count it
|
|
||||||
n=n+1
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
newlist.__ops = 0 -- Reset operation count
|
|
||||||
|
|
||||||
-- And since we now have a count of the number of live timers, check that it's reasonable. Emit a warning if not.
|
function AceTimer:TimerStatus(id)
|
||||||
if n>BUCKETS then
|
local timer = activeTimers[id]
|
||||||
DEFAULT_CHAT_FRAME:AddMessage(MAJOR..": Warning: The addon/module '"..tostring(self).."' has "..n.." live timers. Surely that's not intended?")
|
if not timer then
|
||||||
|
return nil
|
||||||
|
else
|
||||||
|
return timer.status
|
||||||
end
|
end
|
||||||
|
|
||||||
selfs[self] = newlist
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- ---------------------------------------------------------------------
|
-- ---------------------------------------------------------------------
|
||||||
@@ -451,24 +273,107 @@ function AceTimer:OnEmbedDisable( target )
|
|||||||
target:CancelAllTimers()
|
target:CancelAllTimers()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
for addon in pairs(AceTimer.embeds) do
|
for addon in pairs(AceTimer.embeds) do
|
||||||
AceTimer:Embed(addon)
|
AceTimer:Embed(addon)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- ---------------------------------------------------------------------
|
-- --------------------------------------------------------------------
|
||||||
-- Debug tools (expose copies of internals to test suites)
|
-- OnUpdate handler
|
||||||
AceTimer.debug = AceTimer.debug or {}
|
--
|
||||||
AceTimer.debug.HZ = HZ
|
-- traverse buckets, always chasing "now", and fire timers that have expired
|
||||||
AceTimer.debug.BUCKETS = BUCKETS
|
local lastint = floor(GetTime() * HZ)
|
||||||
|
local function OnUpdate()
|
||||||
|
local now = GetTime()
|
||||||
|
local nowint = floor(now * HZ)
|
||||||
|
|
||||||
-- ---------------------------------------------------------------------
|
-- Have we passed into a new hash bucket?
|
||||||
-- Finishing touchups
|
if nowint == lastint then return end
|
||||||
|
|
||||||
AceTimer.frame:SetScript("OnUpdate", OnUpdate)
|
local soon = now + 1 -- +1 is safe as long as 1 < HZ < BUCKETS/2
|
||||||
AceTimer.frame:SetScript("OnEvent", OnEvent)
|
|
||||||
AceTimer.frame:RegisterEvent("PLAYER_REGEN_ENABLED")
|
|
||||||
|
|
||||||
-- In theory, we could hide&show the frame based on there being timers or not.
|
-- Pass through each bucket at most once
|
||||||
-- However, this job is fairly expensive, and the chance that there will
|
-- Happens on e.g. instance loads, but COULD happen on high local load situations also
|
||||||
-- actually be zero timers running is diminuitive to say the least.
|
for curint = (max(lastint, nowint-BUCKETS) + 1), nowint do -- loop until we catch up with "now", usually only 1 iteratio
|
||||||
|
local curbucket = mod(curint,BUCKETS) + 1 -- Ace3v: both int so no floor here
|
||||||
|
-- Yank the list of timers out of the bucket and empty it. This allows reinsertion in the currently-processed bucket from callbacks.
|
||||||
|
local nexttimer = hash[curbucket]
|
||||||
|
hash[curbucket] = false -- false rather than nil to prevent the array from becoming a hash
|
||||||
|
|
||||||
|
while nexttimer do
|
||||||
|
local timer = nexttimer
|
||||||
|
nexttimer = timer.next
|
||||||
|
local status = timer.status
|
||||||
|
if not status then
|
||||||
|
del(timer)
|
||||||
|
else
|
||||||
|
local ends = timer.ends
|
||||||
|
if (status == "loop" or status == "once") and ends < soon then
|
||||||
|
local object = timer.object
|
||||||
|
local callback = timer.func
|
||||||
|
if type(callback) == "string" then
|
||||||
|
callback = (type(object) == "table") and object[callback]
|
||||||
|
if type(callback) == "function" then
|
||||||
|
safecall(callback, timer.argsCount+1, object,
|
||||||
|
timer[1], timer[2], timer[3], timer[4], timer[5],
|
||||||
|
timer[6], timer[7], timer[8], timer[9], timer[10])
|
||||||
|
else
|
||||||
|
status = "once"
|
||||||
|
end
|
||||||
|
elseif type(callback) == "function" then
|
||||||
|
safecall(callback, timer.argsCount,
|
||||||
|
timer[1], timer[2], timer[3], timer[4], timer[5],
|
||||||
|
timer[6], timer[7], timer[8], timer[9], timer[10])
|
||||||
|
else
|
||||||
|
-- probably nilled out by CancelTimer
|
||||||
|
status = "once" -- don't reschedule it
|
||||||
|
end
|
||||||
|
|
||||||
|
if status == "once" then
|
||||||
|
del(timer)
|
||||||
|
else
|
||||||
|
local delay = timer.delay
|
||||||
|
local newends = ends + delay
|
||||||
|
if newends < now then -- Keep lag from making us firing a timer unnecessarily. (Note that this still won't catch too-short-delay timers though.)
|
||||||
|
newends = now + delay
|
||||||
|
end
|
||||||
|
timer.ends = newends
|
||||||
|
-- add next timer execution to the correct bucket
|
||||||
|
local bucket = floor(mod(newends*HZ,BUCKETS)) + 1
|
||||||
|
timer.next = hash[bucket]
|
||||||
|
hash[bucket] = timer
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- reinsert (yeah, somewhat expensive, but shouldn't be happening too often either due to hash distribution)
|
||||||
|
timer.next = hash[curbucket]
|
||||||
|
hash[curbucket] = timer
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
lastint = nowint
|
||||||
|
end
|
||||||
|
|
||||||
|
local lastchecked = nil
|
||||||
|
local function OnEvent()
|
||||||
|
if event ~= "PLAYER_REGEN_ENABLED" then return end
|
||||||
|
|
||||||
|
local addon = next(counter, lastchecked)
|
||||||
|
if not addon then
|
||||||
|
addon = next(counter)
|
||||||
|
end
|
||||||
|
lastchecked = addon
|
||||||
|
if not addon then -- should only happen if counter is empty
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local n = counter[addon]
|
||||||
|
if n > BUCKETS then
|
||||||
|
DEFAULT_CHAT_FRAME:AddMessage(MAJOR..": Warning: The addon/module '"..tostring(addon).."' has "..tostring(n).." live timers. Surely that's not intended?")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
timerFrame:SetScript("OnUpdate", OnUpdate)
|
||||||
|
timerFrame:SetScript("OnEvent", OnEvent)
|
||||||
|
timerFrame:RegisterEvent("PLAYER_REGEN_ENABLED")
|
||||||
|
timerFrame:Hide()
|
||||||
@@ -15,6 +15,7 @@
|
|||||||
<Include file="LibSimpleSticky\LibSimpleSticky.xml"/>
|
<Include file="LibSimpleSticky\LibSimpleSticky.xml"/>
|
||||||
<Include file="LibDataBroker\LibDataBroker-1.1.xml"/>
|
<Include file="LibDataBroker\LibDataBroker-1.1.xml"/>
|
||||||
<Include file="LibElvUIPlugin-1.0\LibElvUIPlugin-1.0.xml"/>
|
<Include file="LibElvUIPlugin-1.0\LibElvUIPlugin-1.0.xml"/>
|
||||||
|
<Include file="oUF\oUF.xml"/>
|
||||||
<!--
|
<!--
|
||||||
<Include file="UTF8\UTF8.xml"/>
|
<Include file="UTF8\UTF8.xml"/>
|
||||||
<Include file="LibCompress\LibCompress.xml"/>
|
<Include file="LibCompress\LibCompress.xml"/>
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
Copyright (c) 2006-2017 Trond A Ekseth <troeks@gmail.com>
|
||||||
|
Copyright (c) 2016-2017 Val Voronov <i.lightspark@gmail.com>
|
||||||
|
Copyright (c) 2016-2017 Adrian L Lange <contact@p3lim.net>
|
||||||
|
Copyright (c) 2016-2017 Rainrider <rainrider.wow@gmail.com>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person
|
||||||
|
obtaining a copy of this software and associated documentation
|
||||||
|
files (the "Software"), to deal in the Software without
|
||||||
|
restriction, including without limitation the rights to use,
|
||||||
|
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following
|
||||||
|
conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||||
|
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
OTHER DEALINGS IN THE SOFTWARE.
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
local ns = oUF
|
||||||
|
local oUF = ns.oUF
|
||||||
|
|
||||||
|
local hiddenParent = CreateFrame("Frame")
|
||||||
|
|
||||||
|
-- sourced from FrameXML/PartyMemberFrame.lua
|
||||||
|
local MAX_PARTY_MEMBERS = MAX_PARTY_MEMBERS or 4
|
||||||
|
|
||||||
|
local hiddenParent = CreateFrame('Frame', nil, UIParent)
|
||||||
|
hiddenParent:SetAllPoints()
|
||||||
|
hiddenParent:Hide()
|
||||||
|
|
||||||
|
local function handleFrame(baseName)
|
||||||
|
local frame
|
||||||
|
if(type(baseName) == 'string') then
|
||||||
|
frame = _G[baseName]
|
||||||
|
else
|
||||||
|
frame = baseName
|
||||||
|
end
|
||||||
|
|
||||||
|
if(frame) then
|
||||||
|
frame:UnregisterAllEvents()
|
||||||
|
frame:Hide()
|
||||||
|
|
||||||
|
-- Keep frame hidden without causing taint
|
||||||
|
frame:SetParent(hiddenParent)
|
||||||
|
|
||||||
|
local health = frame.healthBar or frame.healthbar
|
||||||
|
if(health) then
|
||||||
|
health:UnregisterAllEvents()
|
||||||
|
end
|
||||||
|
|
||||||
|
local power = frame.manabar
|
||||||
|
if(power) then
|
||||||
|
power:UnregisterAllEvents()
|
||||||
|
end
|
||||||
|
|
||||||
|
local spell = frame.castBar or frame.spellbar
|
||||||
|
if(spell) then
|
||||||
|
spell:UnregisterAllEvents()
|
||||||
|
end
|
||||||
|
|
||||||
|
local buffFrame = frame.BuffFrame
|
||||||
|
if(buffFrame) then
|
||||||
|
buffFrame:UnregisterAllEvents()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function oUF:DisableBlizzard(unit)
|
||||||
|
if(not unit) then return end
|
||||||
|
|
||||||
|
if(unit == 'player') then
|
||||||
|
handleFrame(PlayerFrame)
|
||||||
|
elseif(unit == 'pet') then
|
||||||
|
handleFrame(PetFrame)
|
||||||
|
elseif(unit == 'target') then
|
||||||
|
handleFrame(TargetFrame)
|
||||||
|
handleFrame(ComboFrame)
|
||||||
|
elseif(unit == 'targettarget') then
|
||||||
|
handleFrame(TargetofTargetFrame)
|
||||||
|
elseif(unit:match('party%d?$')) then
|
||||||
|
local id = unit:match('party(%d)')
|
||||||
|
if(id) then
|
||||||
|
handleFrame('PartyMemberFrame' .. id)
|
||||||
|
else
|
||||||
|
for i = 1, MAX_PARTY_MEMBERS do
|
||||||
|
handleFrame(string.format('PartyMemberFrame%d', i))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,234 @@
|
|||||||
|
local ns = oUF
|
||||||
|
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
|
||||||
|
},
|
||||||
|
health = {49 / 255, 207 / 255, 37 / 255},
|
||||||
|
disconnected = {.6, .6, .6},
|
||||||
|
tapped = {.6, .6, .6},
|
||||||
|
class = {},
|
||||||
|
reaction = {},
|
||||||
|
power = {},
|
||||||
|
}
|
||||||
|
|
||||||
|
-- We do this because people edit the vars directly, and changing the default
|
||||||
|
-- globals makes SPICE FLOW!
|
||||||
|
local function customClassColors()
|
||||||
|
if(CUSTOM_CLASS_COLORS) then
|
||||||
|
local function updateColors()
|
||||||
|
for classToken, color in next, CUSTOM_CLASS_COLORS do
|
||||||
|
colors.class[classToken] = {color.r, color.g, color.b}
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, obj in next, oUF.objects do
|
||||||
|
obj:UpdateAllElements('CUSTOM_CLASS_COLORS')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
updateColors()
|
||||||
|
CUSTOM_CLASS_COLORS:RegisterCallback(updateColors)
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if(not customClassColors()) then
|
||||||
|
for classToken, color in next, RAID_CLASS_COLORS do
|
||||||
|
colors.class[classToken] = {color.r, color.g, color.b}
|
||||||
|
end
|
||||||
|
|
||||||
|
local eventHandler = CreateFrame('Frame')
|
||||||
|
eventHandler:RegisterEvent('ADDON_LOADED')
|
||||||
|
eventHandler:SetScript('OnEvent', function(self)
|
||||||
|
if(customClassColors()) then
|
||||||
|
self:UnregisterEvent('ADDON_LOADED')
|
||||||
|
self:SetScript('OnEvent', nil)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
for eclass, color in next, FACTION_BAR_COLORS do
|
||||||
|
colors.reaction[eclass] = {color.r, color.g, color.b}
|
||||||
|
end
|
||||||
|
|
||||||
|
colors.power = {}
|
||||||
|
colors.power[0] = {0.00, 0.00, 1.00}
|
||||||
|
colors.power[1] = {1.00, 0.00, 0.00}
|
||||||
|
colors.power[2] = {1.00, 0.50, 0.25}
|
||||||
|
colors.power[3] = {1.00, 1.00, 0.00}
|
||||||
|
colors.power[4] = {0.00, 1.00, 1.00}
|
||||||
|
|
||||||
|
local function colorsAndPercent(a, b, ...)
|
||||||
|
if(a <= 0 or b == 0) then
|
||||||
|
return nil, unpack(arg)
|
||||||
|
elseif(a >= b) then
|
||||||
|
return nil, select(select('#', unpack(arg)) - 2, unpack(arg))
|
||||||
|
end
|
||||||
|
|
||||||
|
local num = select('#', unpack(arg)) / 3
|
||||||
|
local segment, relperc = math.modf((a / b) * (num - 1))
|
||||||
|
return relperc, select((segment * 3) + 1, unpack(arg))
|
||||||
|
end
|
||||||
|
|
||||||
|
-- http://www.wowwiki.com/ColorGradient
|
||||||
|
--[[ Colors: oUF:RGBColorGradient(a, b, ...)
|
||||||
|
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])
|
||||||
|
--]]
|
||||||
|
local function RGBColorGradient(...)
|
||||||
|
local relperc, r1, g1, b1, r2, g2, b2 = colorsAndPercent(unpack(arg))
|
||||||
|
if(relperc) then
|
||||||
|
return r1 + (r2 - r1) * relperc, g1 + (g2 - g1) * relperc, b1 + (b2 - b1) * relperc
|
||||||
|
else
|
||||||
|
return r1, g1, b1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- HCY functions are based on http://www.chilliant.com/rgb2hsv.html
|
||||||
|
local function getY(r, g, b)
|
||||||
|
return 0.299 * r + 0.587 * g + 0.114 * b
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[ Colors: oUF:RGBToHCY(r, g, b)
|
||||||
|
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])
|
||||||
|
--]]
|
||||||
|
function oUF:RGBToHCY(r, g, b)
|
||||||
|
local min, max = min(r, g, b), max(r, g, b)
|
||||||
|
local chroma = max - min
|
||||||
|
local hue
|
||||||
|
if(chroma > 0) then
|
||||||
|
if(r == max) then
|
||||||
|
hue = math.mod((g - b) / chroma, 6)
|
||||||
|
elseif(g == max) then
|
||||||
|
hue = (b - r) / chroma + 2
|
||||||
|
elseif(b == max) then
|
||||||
|
hue = (r - g) / chroma + 4
|
||||||
|
end
|
||||||
|
hue = hue / 6
|
||||||
|
end
|
||||||
|
return hue, chroma, getY(r, g, b)
|
||||||
|
end
|
||||||
|
|
||||||
|
local math_abs = math.abs
|
||||||
|
--[[ Colors: oUF:HCYtoRGB(hue, chroma, luma)
|
||||||
|
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])
|
||||||
|
--]]
|
||||||
|
function oUF:HCYtoRGB(hue, chroma, luma)
|
||||||
|
local r, g, b = 0, 0, 0
|
||||||
|
if(hue and luma > 0) then
|
||||||
|
local h2 = hue * 6
|
||||||
|
local x = chroma * (1 - math_abs(math.mod(h2, 2 - 1)))
|
||||||
|
if(h2 < 1) then
|
||||||
|
r, g, b = chroma, x, 0
|
||||||
|
elseif(h2 < 2) then
|
||||||
|
r, g, b = x, chroma, 0
|
||||||
|
elseif(h2 < 3) then
|
||||||
|
r, g, b = 0, chroma, x
|
||||||
|
elseif(h2 < 4) then
|
||||||
|
r, g, b = 0, x, chroma
|
||||||
|
elseif(h2 < 5) then
|
||||||
|
r, g, b = x, 0, chroma
|
||||||
|
else
|
||||||
|
r, g, b = chroma, 0, x
|
||||||
|
end
|
||||||
|
|
||||||
|
local y = getY(r, g, b)
|
||||||
|
if(luma < y) then
|
||||||
|
chroma = chroma * (luma / y)
|
||||||
|
elseif(y < 1) then
|
||||||
|
chroma = chroma * (1 - luma) / (1 - y)
|
||||||
|
end
|
||||||
|
|
||||||
|
r = (r - y) * chroma + luma
|
||||||
|
g = (g - y) * chroma + luma
|
||||||
|
b = (b - y) * chroma + luma
|
||||||
|
end
|
||||||
|
return r, g, b
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[ Colors: oUF:HCYColorGradient(a, b, ...)
|
||||||
|
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])
|
||||||
|
--]]
|
||||||
|
local function HCYColorGradient(...)
|
||||||
|
local relperc, r1, g1, b1, r2, g2, b2 = colorsAndPercent(unpack(arg))
|
||||||
|
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
|
||||||
|
local dh = h2 - h1
|
||||||
|
if(dh < -0.5) then
|
||||||
|
dh = dh + 1
|
||||||
|
elseif(dh > 0.5) then
|
||||||
|
dh = dh - 1
|
||||||
|
end
|
||||||
|
|
||||||
|
return self:HCYtoRGB(math.mod(h1 + dh * relperc, 1), c, y)
|
||||||
|
else
|
||||||
|
return self:HCYtoRGB(h1 or h2, c, y)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[ Colors: oUF:ColorGradient(a, b, ...) or frame:ColorGradient(a, b, ...)
|
||||||
|
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])
|
||||||
|
--]]
|
||||||
|
local function ColorGradient(...)
|
||||||
|
return (oUF.useHCYColorGradient and HCYColorGradient or RGBColorGradient)(unpack(arg))
|
||||||
|
end
|
||||||
|
|
||||||
|
Private.colors = colors
|
||||||
|
|
||||||
|
oUF.colors = colors
|
||||||
|
oUF.ColorGradient = ColorGradient
|
||||||
|
oUF.RGBColorGradient = RGBColorGradient
|
||||||
|
oUF.HCYColorGradient = HCYColorGradient
|
||||||
|
oUF.useHCYColorGradient = false
|
||||||
|
|
||||||
|
frame_metatable.__index.colors = colors
|
||||||
|
frame_metatable.__index.ColorGradient = ColorGradient
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
--[[
|
||||||
|
# Element: Assistant Indicator
|
||||||
|
|
||||||
|
Toggles the visibility of an indicator based on the unit's raid assistant status.
|
||||||
|
|
||||||
|
## Widget
|
||||||
|
|
||||||
|
AssistantIndicator - Any UI widget.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
A default texture will be applied if the widget is a Texture and doesn't have a texture or a color set.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
-- Position and size
|
||||||
|
local AssistantIndicator = self:CreateTexture(nil, 'OVERLAY')
|
||||||
|
AssistantIndicator:SetSize(16, 16)
|
||||||
|
AssistantIndicator:SetPoint('TOP', self)
|
||||||
|
|
||||||
|
-- Register it with oUF
|
||||||
|
self.AssistantIndicator = AssistantIndicator
|
||||||
|
--]]
|
||||||
|
|
||||||
|
local ns = oUF
|
||||||
|
local oUF = ns.oUF
|
||||||
|
|
||||||
|
local UnitInRaid = UnitInRaid
|
||||||
|
local UnitIsPartyLeader = UnitIsPartyLeader
|
||||||
|
local UnitIsRaidOfficer = UnitIsRaidOfficer
|
||||||
|
|
||||||
|
local function Update(self, event)
|
||||||
|
local element = self.AssistantIndicator
|
||||||
|
|
||||||
|
--[[ Callback: AssistantIndicator:PreUpdate()
|
||||||
|
Called before the element has been updated.
|
||||||
|
|
||||||
|
* self - the AssistantIndicator element
|
||||||
|
--]]
|
||||||
|
if(element.PreUpdate) then
|
||||||
|
element:PreUpdate()
|
||||||
|
end
|
||||||
|
|
||||||
|
local unit = self.unit
|
||||||
|
local isAssistant = UnitInRaid(unit) and UnitIsRaidOfficer(unit) and not UnitIsPartyLeader(unit)
|
||||||
|
if(isAssistant) then
|
||||||
|
element:Show()
|
||||||
|
else
|
||||||
|
element:Hide()
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[ Callback: AssistantIndicator:PostUpdate(isAssistant)
|
||||||
|
Called after the element has been updated.
|
||||||
|
|
||||||
|
* self - the AssistantIndicator element
|
||||||
|
* isAssistant - indicates whether the unit is a raid assistant (boolean)
|
||||||
|
--]]
|
||||||
|
if(element.PostUpdate) then
|
||||||
|
return element:PostUpdate(isAssistant)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Path(self, ...)
|
||||||
|
--[[ Override: AssistantIndicator.Override(self, event, ...)
|
||||||
|
Used to completely override the element's update process.
|
||||||
|
|
||||||
|
* self - the parent object
|
||||||
|
* event - the event triggering the update (string)
|
||||||
|
* ... - the arguments accompanying the event (string)
|
||||||
|
--]]
|
||||||
|
return (self.AssistantIndicator.Override or Update) (self, ...)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function ForceUpdate(element)
|
||||||
|
return Path(element.__owner, 'ForceUpdate')
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Enable(self)
|
||||||
|
local element = self.AssistantIndicator
|
||||||
|
if(element) then
|
||||||
|
element.__owner = self
|
||||||
|
element.ForceUpdate = ForceUpdate
|
||||||
|
|
||||||
|
self:RegisterEvent('PARTY_MEMBERS_CHANGED', Path)
|
||||||
|
|
||||||
|
if(element:IsObjectType('Texture') and not element:GetTexture()) then
|
||||||
|
element:SetTexture([[Interface\GroupFrame\UI-Group-AssistantIcon]])
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Disable(self)
|
||||||
|
local element = self.AssistantIndicator
|
||||||
|
if(element) then
|
||||||
|
element:Hide()
|
||||||
|
|
||||||
|
self:UnregisterEvent('PARTY_MEMBERS_CHANGED', Path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
oUF:AddElement('AssistantIndicator', Path, Enable, Disable)
|
||||||
@@ -0,0 +1,516 @@
|
|||||||
|
--[[
|
||||||
|
# Element: Auras
|
||||||
|
|
||||||
|
Handles creation and updating of aura icons.
|
||||||
|
|
||||||
|
## Widget
|
||||||
|
|
||||||
|
Auras - A Frame to hold `Button`s representing both buffs and debuffs.
|
||||||
|
Buffs - A Frame to hold `Button`s representing buffs.
|
||||||
|
Debuffs - A Frame to hold `Button`s representing debuffs.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
At least one of the above widgets must be present for the element to work.
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
.disableMouse - Disables mouse events (boolean)
|
||||||
|
.disableCooldown - Disables the cooldown spiral (boolean)
|
||||||
|
.size - Aura icon size. Defaults to 16 (number)
|
||||||
|
.spacing - Spacing between each icon. Defaults to 0 (number)
|
||||||
|
.['spacing-x'] - Horizontal spacing between each icon. Takes priority over `spacing` (number)
|
||||||
|
.['spacing-y'] - Vertical spacing between each icon. Takes priority over `spacing` (number)
|
||||||
|
.['growth-x'] - Horizontal growth direction. Defaults to 'RIGHT' (string)
|
||||||
|
.['growth-y'] - Vertical growth direction. Defaults to 'UP' (string)
|
||||||
|
.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)
|
||||||
|
|
||||||
|
## Options Auras
|
||||||
|
|
||||||
|
.numBuffs - The maximum number of buffs to display. Defaults to 32 (number)
|
||||||
|
.numDebuffs - The maximum number of debuffs to display. Defaults to 40 (number)
|
||||||
|
.numTotal - The maximum number of auras to display. Prioritizes buffs over debuffs. Defaults to the sum of
|
||||||
|
.numBuffs and .numDebuffs (number)
|
||||||
|
.gap - Controls the creation of an invisible icon between buffs and debuffs. Defaults to false (boolean)
|
||||||
|
.buffFilter - Custom filter list for buffs to display. Takes priority over `filter` (string)
|
||||||
|
.debuffFilter - Custom filter list for debuffs to display. Takes priority over `filter` (string)
|
||||||
|
|
||||||
|
## Options Buffs
|
||||||
|
|
||||||
|
.num - Number of buffs to display. Defaults to 32 (number)
|
||||||
|
|
||||||
|
## Options Debuffs
|
||||||
|
|
||||||
|
.num - Number of debuffs to display. Defaults to 40 (number)
|
||||||
|
|
||||||
|
## Attributes
|
||||||
|
|
||||||
|
button.filter - the filter list used to determine the visibility of the aura (string)
|
||||||
|
button.isDebuff - indicates if the button holds a debuff (boolean)
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
-- Position and size
|
||||||
|
local Buffs = CreateFrame('Frame', nil, self)
|
||||||
|
Buffs:SetPoint('RIGHT', self, 'LEFT')
|
||||||
|
Buffs:SetSize(16 * 2, 16 * 16)
|
||||||
|
|
||||||
|
-- Register with oUF
|
||||||
|
self.Buffs = Buffs
|
||||||
|
--]]
|
||||||
|
|
||||||
|
local ns = oUF
|
||||||
|
local oUF = ns.oUF
|
||||||
|
|
||||||
|
local tinsert = table.insert
|
||||||
|
local floor = math.floor
|
||||||
|
|
||||||
|
local CreateFrame = CreateFrame
|
||||||
|
local GetTime = GetTime
|
||||||
|
local UnitAura = UnitAura
|
||||||
|
|
||||||
|
local VISIBLE = 1
|
||||||
|
local HIDDEN = 0
|
||||||
|
|
||||||
|
local function UpdateTooltip(self)
|
||||||
|
if self.filter == 'HELPFUL' then
|
||||||
|
GameTooltip:SetUnitBuff(self:GetParent().__owner.unit, self:GetID(), self.filter)
|
||||||
|
else
|
||||||
|
GameTooltip:SetUnitDebuff(self:GetParent().__owner.unit, self:GetID(), self.filter)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function onEnter(self)
|
||||||
|
if(not self:IsVisible()) then return end
|
||||||
|
|
||||||
|
GameTooltip:SetOwner(self, 'ANCHOR_BOTTOMRIGHT')
|
||||||
|
self:UpdateTooltip()
|
||||||
|
end
|
||||||
|
|
||||||
|
local function onLeave()
|
||||||
|
GameTooltip:Hide()
|
||||||
|
end
|
||||||
|
|
||||||
|
local function createAuraIcon(element, index)
|
||||||
|
local button = CreateFrame('Button', '$parentButton' .. index, element)
|
||||||
|
button:RegisterForClicks('RightButtonUp')
|
||||||
|
|
||||||
|
local cd = CreateFrame('Cooldown', '$parentCooldown', button, 'oUF_CooldownFrameTemplate')
|
||||||
|
cd:SetAllPoints()
|
||||||
|
|
||||||
|
local icon = button:CreateTexture(nil, 'BORDER')
|
||||||
|
icon:SetAllPoints()
|
||||||
|
|
||||||
|
local count = button:CreateFontString(nil, 'OVERLAY', 'NumberFontNormal')
|
||||||
|
count:SetPoint('BOTTOMRIGHT', button, 'BOTTOMRIGHT', -1, 0)
|
||||||
|
|
||||||
|
local overlay = button:CreateTexture(nil, 'OVERLAY')
|
||||||
|
overlay:SetTexture([[Interface\Buttons\UI-Debuff-Overlays]])
|
||||||
|
overlay:SetAllPoints()
|
||||||
|
overlay:SetTexCoord(.296875, .5703125, 0, .515625)
|
||||||
|
button.overlay = overlay
|
||||||
|
|
||||||
|
button.UpdateTooltip = UpdateTooltip
|
||||||
|
button:SetScript('OnEnter', onEnter)
|
||||||
|
button:SetScript('OnLeave', onLeave)
|
||||||
|
|
||||||
|
button.icon = icon
|
||||||
|
button.count = count
|
||||||
|
button.cd = cd
|
||||||
|
|
||||||
|
--[[ Callback: Auras:PostCreateIcon(button)
|
||||||
|
Called after a new aura button has been created.
|
||||||
|
|
||||||
|
* self - the widget holding the aura buttons
|
||||||
|
* button - the newly created aura button (Button)
|
||||||
|
--]]
|
||||||
|
if(element.PostCreateIcon) then element:PostCreateIcon(button) end
|
||||||
|
|
||||||
|
return button
|
||||||
|
end
|
||||||
|
|
||||||
|
local function customFilter(element, unit, button, name)
|
||||||
|
if(name) then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function updateIcon(element, unit, index, offset, filter, isDebuff, visible)
|
||||||
|
local name, rank, texture, count, dispelType, duration, expiration = UnitAura(unit, index, filter)
|
||||||
|
|
||||||
|
if element.forceShow then
|
||||||
|
name, rank, texture = GetSpellInfo(26993)
|
||||||
|
count, dispelType, duration, expiration = 5, 'Magic', 0, 60
|
||||||
|
end
|
||||||
|
|
||||||
|
if(name) then
|
||||||
|
local position = visible + offset + 1
|
||||||
|
local button = element[position]
|
||||||
|
if(not button) then
|
||||||
|
--[[ Override: Auras:CreateIcon(position)
|
||||||
|
Used to create the aura button at a given position.
|
||||||
|
|
||||||
|
* self - the widget holding the aura buttons
|
||||||
|
* position - the position at which the aura button is to be created (number)
|
||||||
|
|
||||||
|
## Returns
|
||||||
|
|
||||||
|
* button - the button used to represent the aura (Button)
|
||||||
|
--]]
|
||||||
|
button = (element.CreateIcon or createAuraIcon) (element, position)
|
||||||
|
|
||||||
|
tinsert(element, button)
|
||||||
|
element.createdIcons = element.createdIcons + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
button.filter = filter
|
||||||
|
button.isDebuff = isDebuff
|
||||||
|
|
||||||
|
--[[ Override: Auras:CustomFilter(unit, button, ...)
|
||||||
|
Defines a custom filter that controls if the aura button should be shown.
|
||||||
|
|
||||||
|
* self - the widget holding the aura buttons
|
||||||
|
* unit - the unit on which the aura is cast (string)
|
||||||
|
* button - the button displaying the aura (Button)
|
||||||
|
* ... - the return values from [UnitAura](http://wowprogramming.com/docs/api/UnitAura)
|
||||||
|
|
||||||
|
## Returns
|
||||||
|
|
||||||
|
* show - indicates whether the aura button should be shown (boolean)
|
||||||
|
--]]
|
||||||
|
local show = true
|
||||||
|
if not element.forceShow then
|
||||||
|
show = (element.CustomFilter or customFilter) (element, unit, button, name, rank, texture, count, dispelType, duration, expiration)
|
||||||
|
end
|
||||||
|
|
||||||
|
if(show) then
|
||||||
|
-- We might want to consider delaying the creation of an actual cooldown
|
||||||
|
-- object to this point, but I think that will just make things needlessly
|
||||||
|
-- complicated.
|
||||||
|
if(button.cd and not element.disableCooldown) then
|
||||||
|
if(duration and duration > 0) then
|
||||||
|
button.cd:SetCooldown(GetTime() - (duration - expiration), duration)
|
||||||
|
button.cd:Show()
|
||||||
|
else
|
||||||
|
button.cd:Hide()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if(button.overlay) then
|
||||||
|
if((isDebuff and element.showDebuffType) or (not isDebuff and element.showBuffType) or element.showType) then
|
||||||
|
local color = DebuffTypeColor[dispelType] or DebuffTypeColor.none
|
||||||
|
|
||||||
|
button.overlay:SetVertexColor(color.r, color.g, color.b)
|
||||||
|
button.overlay:Show()
|
||||||
|
else
|
||||||
|
button.overlay:Hide()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if(button.icon) then button.icon:SetTexture(texture) end
|
||||||
|
if(button.count) then button.count:SetText(count > 1 and count) end
|
||||||
|
|
||||||
|
local size = element.size or 16
|
||||||
|
button:SetSize(size, size)
|
||||||
|
|
||||||
|
button:EnableMouse(not element.disableMouse)
|
||||||
|
button:SetID(index)
|
||||||
|
button:Show()
|
||||||
|
|
||||||
|
--[[ Callback: Auras:PostUpdateIcon(unit, button, index, position)
|
||||||
|
Called after the aura button has been updated.
|
||||||
|
|
||||||
|
* self - the widget holding the aura buttons
|
||||||
|
* unit - the unit on which the aura is cast (string)
|
||||||
|
* button - the updated aura button (Button)
|
||||||
|
* index - the index of the aura (number)
|
||||||
|
* position - the actual position of the aura button (number)
|
||||||
|
--]]
|
||||||
|
if(element.PostUpdateIcon) then
|
||||||
|
element:PostUpdateIcon(unit, button, index, position)
|
||||||
|
end
|
||||||
|
|
||||||
|
return VISIBLE
|
||||||
|
else
|
||||||
|
return HIDDEN
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function SetPosition(element, from, to)
|
||||||
|
local sizex = (element.size or 16) + (element['spacing-x'] or element.spacing or 0)
|
||||||
|
local sizey = (element.size or 16) + (element['spacing-y'] or element.spacing or 0)
|
||||||
|
local anchor = element.initialAnchor or 'BOTTOMLEFT'
|
||||||
|
local growthx = (element['growth-x'] == 'LEFT' and -1) or 1
|
||||||
|
local growthy = (element['growth-y'] == 'DOWN' and -1) or 1
|
||||||
|
local cols = floor(element:GetWidth() / sizex + 0.5)
|
||||||
|
|
||||||
|
for i = from, to do
|
||||||
|
local button = element[i]
|
||||||
|
|
||||||
|
-- Bail out if the to range is out of scope.
|
||||||
|
if(not button) then break end
|
||||||
|
local col = (i - 1) % cols
|
||||||
|
local row = floor((i - 1) / cols)
|
||||||
|
|
||||||
|
button:ClearAllPoints()
|
||||||
|
button:SetPoint(anchor, element, anchor, col * sizex * growthx, row * sizey * growthy)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function filterIcons(element, unit, filter, limit, isDebuff, offset, dontHide)
|
||||||
|
if(not offset) then offset = 0 end
|
||||||
|
local index = 1
|
||||||
|
local visible = 0
|
||||||
|
local hidden = 0
|
||||||
|
while(visible < limit) do
|
||||||
|
local result = updateIcon(element, unit, index, offset, filter, isDebuff, visible)
|
||||||
|
if(not result) then
|
||||||
|
break
|
||||||
|
elseif(result == VISIBLE) then
|
||||||
|
visible = visible + 1
|
||||||
|
elseif(result == HIDDEN) then
|
||||||
|
hidden = hidden + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
index = index + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
if(not dontHide) then
|
||||||
|
for i = visible + offset + 1, #element do
|
||||||
|
element[i]:Hide()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return visible, hidden
|
||||||
|
end
|
||||||
|
|
||||||
|
local function UpdateAuras(self, event, unit)
|
||||||
|
if(self.unit ~= unit) then return end
|
||||||
|
|
||||||
|
local auras = self.Auras
|
||||||
|
if(auras) then
|
||||||
|
--[[ Callback: Auras:PreUpdate(unit)
|
||||||
|
Called before the element has been updated.
|
||||||
|
|
||||||
|
* self - the widget holding the aura buttons
|
||||||
|
* unit - the unit for which the update has been triggered (string)
|
||||||
|
--]]
|
||||||
|
if(auras.PreUpdate) then auras:PreUpdate(unit) end
|
||||||
|
|
||||||
|
local numBuffs = auras.numBuffs or 32
|
||||||
|
local numDebuffs = auras.numDebuffs or 40
|
||||||
|
local max = auras.numTotal or numBuffs + numDebuffs
|
||||||
|
|
||||||
|
local visibleBuffs, hiddenBuffs = filterIcons(auras, unit, auras.buffFilter or auras.filter or 'HELPFUL', math.min(numBuffs, max), nil, 0, true)
|
||||||
|
|
||||||
|
local hasGap
|
||||||
|
if(visibleBuffs ~= 0 and auras.gap) then
|
||||||
|
hasGap = true
|
||||||
|
visibleBuffs = visibleBuffs + 1
|
||||||
|
|
||||||
|
local button = auras[visibleBuffs]
|
||||||
|
if(not button) then
|
||||||
|
button = (auras.CreateIcon or createAuraIcon) (auras, visibleBuffs)
|
||||||
|
tinsert(auras, button)
|
||||||
|
auras.createdIcons = auras.createdIcons + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Prevent the button from displaying anything.
|
||||||
|
if(button.cd) then button.cd:Hide() end
|
||||||
|
if(button.icon) then button.icon:SetTexture() end
|
||||||
|
if(button.overlay) then button.overlay:Hide() end
|
||||||
|
if(button.stealable) then button.stealable:Hide() end
|
||||||
|
if(button.count) then button.count:SetText() end
|
||||||
|
|
||||||
|
button:EnableMouse(false)
|
||||||
|
button:Show()
|
||||||
|
|
||||||
|
--[[ Callback: Auras:PostUpdateGapIcon(unit, gapButton, visibleBuffs)
|
||||||
|
Called after an invisible aura button has been created. Only used by Auras when the `gap` option is enabled.
|
||||||
|
|
||||||
|
* self - the widget holding the aura buttons
|
||||||
|
* unit - the unit that has the invisible aura button (string)
|
||||||
|
* gapButton - the invisible aura button (Button)
|
||||||
|
* visibleBuffs - the number of currently visible aura buttons (number)
|
||||||
|
--]]
|
||||||
|
if(auras.PostUpdateGapIcon) then
|
||||||
|
auras:PostUpdateGapIcon(unit, button, visibleBuffs)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local visibleDebuffs, hiddenDebuffs = filterIcons(auras, unit, auras.debuffFilter or auras.filter or 'HARMFUL', math.min(numDebuffs, max - visibleBuffs), true, visibleBuffs)
|
||||||
|
auras.visibleDebuffs = visibleDebuffs
|
||||||
|
|
||||||
|
if(hasGap and visibleDebuffs == 0) then
|
||||||
|
auras[visibleBuffs]:Hide()
|
||||||
|
visibleBuffs = visibleBuffs - 1
|
||||||
|
end
|
||||||
|
|
||||||
|
auras.visibleBuffs = visibleBuffs
|
||||||
|
auras.visibleAuras = auras.visibleBuffs + auras.visibleDebuffs
|
||||||
|
|
||||||
|
local fromRange, toRange
|
||||||
|
--[[ Callback: Auras:PreSetPosition(max)
|
||||||
|
Called before the aura buttons have been (re-)anchored.
|
||||||
|
|
||||||
|
* self - the widget holding the aura buttons
|
||||||
|
* max - the maximum possible number of aura buttons (number)
|
||||||
|
|
||||||
|
## Returns
|
||||||
|
|
||||||
|
* from - the offset of the first aura button to be (re-)anchored (number)
|
||||||
|
* to - the offset of the last aura button to be (re-)anchored (number)
|
||||||
|
--]]
|
||||||
|
if(auras.PreSetPosition) then
|
||||||
|
fromRange, toRange = auras:PreSetPosition(max)
|
||||||
|
end
|
||||||
|
|
||||||
|
if(fromRange or auras.createdIcons > auras.anchoredIcons) then
|
||||||
|
--[[ Override: Auras:SetPosition(from, to)
|
||||||
|
Used to (re-)anchor the aura buttons.
|
||||||
|
Called when new aura buttons have been created or if :PreSetPosition is defined.
|
||||||
|
|
||||||
|
* self - the widget that holds the aura buttons
|
||||||
|
* from - the offset of the first aura button to be (re-)anchored (number)
|
||||||
|
* to - the offset of the last aura button to be (re-)anchored (number)
|
||||||
|
--]]
|
||||||
|
(auras.SetPosition or SetPosition) (auras, fromRange or auras.anchoredIcons + 1, toRange or auras.createdIcons)
|
||||||
|
auras.anchoredIcons = auras.createdIcons
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[ Callback: Auras:PostUpdate(unit)
|
||||||
|
Called after the element has been updated.
|
||||||
|
|
||||||
|
* self - the widget holding the aura buttons
|
||||||
|
* unit - the unit for which the update has been triggered (string)
|
||||||
|
--]]
|
||||||
|
if(auras.PostUpdate) then auras:PostUpdate(unit) end
|
||||||
|
end
|
||||||
|
|
||||||
|
local buffs = self.Buffs
|
||||||
|
if(buffs) then
|
||||||
|
if(buffs.PreUpdate) then buffs:PreUpdate(unit) end
|
||||||
|
|
||||||
|
local numBuffs = buffs.num or 32
|
||||||
|
local visibleBuffs, hiddenBuffs = filterIcons(buffs, unit, buffs.filter or 'HELPFUL', numBuffs)
|
||||||
|
buffs.visibleBuffs = visibleBuffs
|
||||||
|
|
||||||
|
local fromRange, toRange
|
||||||
|
if(buffs.PreSetPosition) then
|
||||||
|
fromRange, toRange = buffs:PreSetPosition(numBuffs)
|
||||||
|
end
|
||||||
|
|
||||||
|
if(fromRange or buffs.createdIcons > buffs.anchoredIcons) then
|
||||||
|
(buffs.SetPosition or SetPosition) (buffs, fromRange or buffs.anchoredIcons + 1, toRange or buffs.createdIcons)
|
||||||
|
buffs.anchoredIcons = buffs.createdIcons
|
||||||
|
end
|
||||||
|
|
||||||
|
if(buffs.PostUpdate) then buffs:PostUpdate(unit) end
|
||||||
|
end
|
||||||
|
|
||||||
|
local debuffs = self.Debuffs
|
||||||
|
if(debuffs) then
|
||||||
|
if(debuffs.PreUpdate) then debuffs:PreUpdate(unit) end
|
||||||
|
|
||||||
|
local numDebuffs = debuffs.num or 40
|
||||||
|
local visibleDebuffs, hiddenDebuffs = filterIcons(debuffs, unit, debuffs.filter or 'HARMFUL', numDebuffs, true)
|
||||||
|
debuffs.visibleDebuffs = visibleDebuffs
|
||||||
|
|
||||||
|
local fromRange, toRange
|
||||||
|
if(debuffs.PreSetPosition) then
|
||||||
|
fromRange, toRange = debuffs:PreSetPosition(numDebuffs)
|
||||||
|
end
|
||||||
|
|
||||||
|
if(fromRange or debuffs.createdIcons > debuffs.anchoredIcons) then
|
||||||
|
(debuffs.SetPosition or SetPosition) (debuffs, fromRange or debuffs.anchoredIcons + 1, toRange or debuffs.createdIcons)
|
||||||
|
debuffs.anchoredIcons = debuffs.createdIcons
|
||||||
|
end
|
||||||
|
|
||||||
|
if(debuffs.PostUpdate) then debuffs:PostUpdate(unit) end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Update(self, event, unit)
|
||||||
|
if(self.unit ~= unit) then return end
|
||||||
|
|
||||||
|
UpdateAuras(self, event, unit)
|
||||||
|
|
||||||
|
-- Assume no event means someone wants to re-anchor things. This is usually
|
||||||
|
-- done by UpdateAllElements and :ForceUpdate.
|
||||||
|
if(event == 'ForceUpdate' or not event) then
|
||||||
|
local buffs = self.Buffs
|
||||||
|
if(buffs) then
|
||||||
|
(buffs.SetPosition or SetPosition) (buffs, 1, buffs.createdIcons)
|
||||||
|
end
|
||||||
|
|
||||||
|
local debuffs = self.Debuffs
|
||||||
|
if(debuffs) then
|
||||||
|
(debuffs.SetPosition or SetPosition) (debuffs, 1, debuffs.createdIcons)
|
||||||
|
end
|
||||||
|
|
||||||
|
local auras = self.Auras
|
||||||
|
if(auras) then
|
||||||
|
(auras.SetPosition or SetPosition) (auras, 1, auras.createdIcons)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function ForceUpdate(element)
|
||||||
|
return Update(element.__owner, 'ForceUpdate', element.__owner.unit)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Enable(self)
|
||||||
|
if(self.Buffs or self.Debuffs or self.Auras) then
|
||||||
|
self:RegisterEvent('UNIT_AURA', UpdateAuras)
|
||||||
|
|
||||||
|
local buffs = self.Buffs
|
||||||
|
if(buffs) then
|
||||||
|
buffs.__owner = self
|
||||||
|
buffs.ForceUpdate = ForceUpdate
|
||||||
|
|
||||||
|
buffs.createdIcons = buffs.createdIcons or 0
|
||||||
|
buffs.anchoredIcons = 0
|
||||||
|
|
||||||
|
--buffs:Show()
|
||||||
|
end
|
||||||
|
|
||||||
|
local debuffs = self.Debuffs
|
||||||
|
if(debuffs) then
|
||||||
|
debuffs.__owner = self
|
||||||
|
debuffs.ForceUpdate = ForceUpdate
|
||||||
|
|
||||||
|
debuffs.createdIcons = debuffs.createdIcons or 0
|
||||||
|
debuffs.anchoredIcons = 0
|
||||||
|
|
||||||
|
--debuffs:Show()
|
||||||
|
end
|
||||||
|
|
||||||
|
local auras = self.Auras
|
||||||
|
if(auras) then
|
||||||
|
auras.__owner = self
|
||||||
|
auras.ForceUpdate = ForceUpdate
|
||||||
|
|
||||||
|
auras.createdIcons = auras.createdIcons or 0
|
||||||
|
auras.anchoredIcons = 0
|
||||||
|
|
||||||
|
--auras:Show()
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Disable(self)
|
||||||
|
if(self.Buffs or self.Debuffs or self.Auras) then
|
||||||
|
self:UnregisterEvent('UNIT_AURA', UpdateAuras)
|
||||||
|
|
||||||
|
if(self.Buffs) then self.Buffs:Hide() end
|
||||||
|
if(self.Debuffs) then self.Debuffs:Hide() end
|
||||||
|
if(self.Auras) then self.Auras:Hide() end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
oUF:AddElement('Auras', Update, Enable, Disable)
|
||||||
@@ -0,0 +1,585 @@
|
|||||||
|
--[[
|
||||||
|
# Element: Castbar
|
||||||
|
|
||||||
|
Handles the visibility and updating of spell castbars.
|
||||||
|
Based upon oUF_Castbar by starlon.
|
||||||
|
|
||||||
|
## Widget
|
||||||
|
|
||||||
|
Castbar - A `StatusBar` to represent spell cast/channel progress.
|
||||||
|
|
||||||
|
## Sub-Widgets
|
||||||
|
|
||||||
|
.Text - A `FontString` to represent spell name.
|
||||||
|
.Icon - A `Texture` to represent spell icon.
|
||||||
|
.Time - A `FontString` to represent spell duration.
|
||||||
|
.SafeZone - A `Texture` to represent latency.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
A default texture will be applied to the StatusBar and Texture widgets if they don't have a texture or a color set.
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
.timeToHold - indicates for how many seconds the castbar should be visible after a _FAILED or _INTERRUPTED
|
||||||
|
event. Defaults to 0 (number)
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
-- Position and size
|
||||||
|
local Castbar = CreateFrame('StatusBar', nil, self)
|
||||||
|
Castbar:SetSize(20, 20)
|
||||||
|
Castbar:SetPoint('TOP')
|
||||||
|
Castbar:SetPoint('LEFT')
|
||||||
|
Castbar:SetPoint('RIGHT')
|
||||||
|
|
||||||
|
-- Add a background
|
||||||
|
local Background = Castbar:CreateTexture(nil, 'BACKGROUND')
|
||||||
|
Background:SetAllPoints(Castbar)
|
||||||
|
Background:SetTexture(1, 1, 1, .5)
|
||||||
|
|
||||||
|
-- Add a spark
|
||||||
|
local Spark = Castbar:CreateTexture(nil, 'OVERLAY')
|
||||||
|
Spark:SetSize(20, 20)
|
||||||
|
Spark:SetBlendMode('ADD')
|
||||||
|
|
||||||
|
-- Add a timer
|
||||||
|
local Time = Castbar:CreateFontString(nil, 'OVERLAY', 'GameFontNormalSmall')
|
||||||
|
Time:SetPoint('RIGHT', Castbar)
|
||||||
|
|
||||||
|
-- Add spell text
|
||||||
|
local Text = Castbar:CreateFontString(nil, 'OVERLAY', 'GameFontNormalSmall')
|
||||||
|
Text:SetPoint('LEFT', Castbar)
|
||||||
|
|
||||||
|
-- Add spell icon
|
||||||
|
local Icon = Castbar:CreateTexture(nil, 'OVERLAY')
|
||||||
|
Icon:SetSize(20, 20)
|
||||||
|
Icon:SetPoint('TOPLEFT', Castbar, 'TOPLEFT')
|
||||||
|
|
||||||
|
-- Add safezone
|
||||||
|
local SafeZone = Castbar:CreateTexture(nil, 'OVERLAY')
|
||||||
|
|
||||||
|
-- Register it with oUF
|
||||||
|
Castbar.bg = Background
|
||||||
|
Castbar.Spark = Spark
|
||||||
|
Castbar.Time = Time
|
||||||
|
Castbar.Text = Text
|
||||||
|
Castbar.Icon = Icon
|
||||||
|
Castbar.SafeZone = SafeZone
|
||||||
|
self.Castbar = Castbar
|
||||||
|
--]]
|
||||||
|
local ns = oUF
|
||||||
|
local oUF = ns.oUF
|
||||||
|
|
||||||
|
local GetNetStats = GetNetStats
|
||||||
|
local GetTime = GetTime
|
||||||
|
local UnitCastingInfo = UnitCastingInfo
|
||||||
|
local UnitChannelInfo = UnitChannelInfo
|
||||||
|
local UnitIsUnit = UnitIsUnit
|
||||||
|
|
||||||
|
local tradeskillCastTime, tradeskillCastDuration, tradeskillCurrent, tradeskillTotal, mergeTradeskill = 0, 0, 0, 0, false
|
||||||
|
|
||||||
|
local function updateSafeZone(self)
|
||||||
|
local safeZone = self.SafeZone
|
||||||
|
local width = self:GetWidth()
|
||||||
|
local _, _, ms = GetNetStats()
|
||||||
|
|
||||||
|
-- Guard against GetNetStats returning latencies of 0.
|
||||||
|
if(ms ~= 0) then
|
||||||
|
local safeZoneRatio = (ms / 1e3) / self.max
|
||||||
|
if(safeZoneRatio > 1) then
|
||||||
|
safeZoneRatio = 1
|
||||||
|
end
|
||||||
|
safeZone:SetWidth(width * safeZoneRatio)
|
||||||
|
safeZone:Show()
|
||||||
|
else
|
||||||
|
safeZone:Hide()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function UNIT_SPELLCAST_SENT(self, event, unit, spell, rank, target)
|
||||||
|
local element = self.Castbar
|
||||||
|
element.curTarget = (target and target ~= '') and target or nil
|
||||||
|
|
||||||
|
if element.isTradeSkill then
|
||||||
|
element.tradeSkillCastName = spell
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function UNIT_SPELLCAST_START(self, event, unit)
|
||||||
|
if(self.unit ~= unit and self.realUnit ~= unit) then return end
|
||||||
|
|
||||||
|
local element = self.Castbar
|
||||||
|
local name, _, text, texture, startTime, endTime, isTradeSkill = UnitCastingInfo(unit)
|
||||||
|
if(not name) then
|
||||||
|
return element:Hide()
|
||||||
|
end
|
||||||
|
|
||||||
|
endTime = endTime / 1e3
|
||||||
|
startTime = startTime / 1e3
|
||||||
|
local max = endTime - startTime
|
||||||
|
|
||||||
|
element.castName = name
|
||||||
|
element.duration = GetTime() - startTime
|
||||||
|
element.max = max
|
||||||
|
element.delay = 0
|
||||||
|
element.casting = true
|
||||||
|
element.holdTime = 0
|
||||||
|
element.isTradeSkill = isTradeSkill
|
||||||
|
|
||||||
|
if(mergeTradeskill and isTradeSkill and UnitIsUnit(unit, 'player')) then
|
||||||
|
element.duration = element.duration + (element.max * tradeskillCurrent)
|
||||||
|
element.max = max * tradeskillTotal
|
||||||
|
|
||||||
|
if(unit == 'player') then
|
||||||
|
tradeskillCurrent = tradeskillCurrent + 1
|
||||||
|
tradeskillCastDuration = element.duration
|
||||||
|
tradeskillCastTime = max
|
||||||
|
end
|
||||||
|
|
||||||
|
element:SetValue(element.duration)
|
||||||
|
else
|
||||||
|
element:SetValue(0)
|
||||||
|
end
|
||||||
|
element:SetMinMaxValues(0, element.max)
|
||||||
|
|
||||||
|
if(element.Text) then element.Text:SetText(text) end
|
||||||
|
if(element.Icon) then element.Icon:SetTexture(texture) end
|
||||||
|
if(element.Time) then element.Time:SetText() end
|
||||||
|
|
||||||
|
local sf = element.SafeZone
|
||||||
|
if(sf) then
|
||||||
|
sf:ClearAllPoints()
|
||||||
|
sf:SetPoint('RIGHT')
|
||||||
|
sf:SetPoint('TOP')
|
||||||
|
sf:SetPoint('BOTTOM')
|
||||||
|
updateSafeZone(element)
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[ Callback: Castbar:PostCastStart(unit, name)
|
||||||
|
Called after the element has been updated upon a spell cast start.
|
||||||
|
|
||||||
|
* self - the Castbar widget
|
||||||
|
* unit - unit for which the update has been triggered (string)
|
||||||
|
* name - name of the spell being cast (string)
|
||||||
|
--]]
|
||||||
|
if(element.PostCastStart) then
|
||||||
|
element:PostCastStart(unit, name)
|
||||||
|
end
|
||||||
|
element:Show()
|
||||||
|
end
|
||||||
|
|
||||||
|
local function UNIT_SPELLCAST_FAILED(self, event, unit, spellname)
|
||||||
|
if(not self.casting) then return end
|
||||||
|
if(self.unit ~= unit and self.realUnit ~= unit) then return end
|
||||||
|
|
||||||
|
local element = self.Castbar
|
||||||
|
if(spellname and (element.castName ~= spellname and element.tradeSkillCastName ~= spellname)) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if(mergeTradeskill and UnitIsUnit(unit, 'player')) then
|
||||||
|
mergeTradeskill = false
|
||||||
|
element.tradeSkillCastName = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local text = element.Text
|
||||||
|
if(text) then
|
||||||
|
text:SetText(FAILED)
|
||||||
|
end
|
||||||
|
|
||||||
|
element.casting = nil
|
||||||
|
element.holdTime = element.timeToHold or 0
|
||||||
|
|
||||||
|
--[[ Callback: Castbar:PostCastFailed(unit, name)
|
||||||
|
Called after the element has been updated upon a failed spell cast.
|
||||||
|
|
||||||
|
* self - the Castbar widget
|
||||||
|
* unit - unit for which the update has been triggered (string)
|
||||||
|
* name - name of the failed spell (string)
|
||||||
|
--]]
|
||||||
|
if(element.PostCastFailed) then
|
||||||
|
return element:PostCastFailed(unit, spellname)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function UNIT_SPELLCAST_FAILED_QUIET(self, event, unit, spellname)
|
||||||
|
if(not self.casting) then return end
|
||||||
|
if(self.unit ~= unit and self.realUnit ~= unit) then return end
|
||||||
|
|
||||||
|
local element = self.Castbar
|
||||||
|
if(spellname and (element.castName ~= spellname and element.tradeSkillCastName ~= spellname)) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if(mergeTradeskill and UnitIsUnit(unit, 'player')) then
|
||||||
|
mergeTradeskill = false
|
||||||
|
element.tradeSkillCastName = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
element.casting = nil
|
||||||
|
element:SetValue(0)
|
||||||
|
element:Hide()
|
||||||
|
end
|
||||||
|
|
||||||
|
local function UNIT_SPELLCAST_INTERRUPTED(self, event, unit, spellname)
|
||||||
|
if(self.unit ~= unit and self.realUnit ~= unit) then return end
|
||||||
|
|
||||||
|
local element = self.Castbar
|
||||||
|
if(spellname and element.castName ~= spellname) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local text = element.Text
|
||||||
|
if(text) then
|
||||||
|
text:SetText(INTERRUPTED)
|
||||||
|
end
|
||||||
|
|
||||||
|
element.casting = nil
|
||||||
|
element.channeling = nil
|
||||||
|
element.holdTime = element.timeToHold or 0
|
||||||
|
|
||||||
|
--[[ Callback: Castbar:PostCastInterrupted(unit, name)
|
||||||
|
Called after the element has been updated upon an interrupted spell cast.
|
||||||
|
|
||||||
|
* self - the Castbar widget
|
||||||
|
* unit - unit for which the update has been triggered (string)
|
||||||
|
* name - name of the interrupted spell (string)
|
||||||
|
--]]
|
||||||
|
if(element.PostCastInterrupted) then
|
||||||
|
return element:PostCastInterrupted(unit, spellname)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function UNIT_SPELLCAST_DELAYED(self, event, unit)
|
||||||
|
if(self.unit ~= unit and self.realUnit ~= unit) then return end
|
||||||
|
|
||||||
|
local element = self.Castbar
|
||||||
|
local name, _, _, _, startTime = UnitCastingInfo(unit)
|
||||||
|
if(not startTime or not element:IsShown()) then return end
|
||||||
|
|
||||||
|
local duration = GetTime() - (startTime / 1000)
|
||||||
|
if(duration < 0) then duration = 0 end
|
||||||
|
|
||||||
|
element.delay = element.delay + element.duration - duration
|
||||||
|
element.duration = duration
|
||||||
|
|
||||||
|
element:SetValue(duration)
|
||||||
|
|
||||||
|
--[[ Callback: Castbar:PostCastDelayed(unit, name)
|
||||||
|
Called after the element has been updated when a spell cast has been delayed.
|
||||||
|
|
||||||
|
* self - the Castbar widget
|
||||||
|
* unit - unit that the update has been triggered (string)
|
||||||
|
* name - name of the delayed spell (string)
|
||||||
|
--]]
|
||||||
|
if(element.PostCastDelayed) then
|
||||||
|
return element:PostCastDelayed(unit, name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function UNIT_SPELLCAST_STOP(self, event, unit, spellname)
|
||||||
|
if(self.unit ~= unit and self.realUnit ~= unit) then return end
|
||||||
|
|
||||||
|
local element = self.Castbar
|
||||||
|
if(spellname and (element.castName ~= spellname)) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if(mergeTradeskill and UnitIsUnit(unit, 'player')) then
|
||||||
|
if(tradeskillCurrent == tradeskillTotal) then
|
||||||
|
mergeTradeskill = false
|
||||||
|
end
|
||||||
|
else
|
||||||
|
element.casting = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[ Callback: Castbar:PostCastStop(unit, name)
|
||||||
|
Called after the element has been updated when a spell cast has finished.
|
||||||
|
|
||||||
|
* self - the Castbar widget
|
||||||
|
* unit - unit for which the update has been triggered (string)
|
||||||
|
* name - name of the spell (string)
|
||||||
|
--]]
|
||||||
|
if(element.PostCastStop) then
|
||||||
|
return element:PostCastStop(unit, spellname)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function UNIT_SPELLCAST_CHANNEL_START(self, event, unit)
|
||||||
|
if(self.unit ~= unit and self.realUnit ~= unit) then return end
|
||||||
|
|
||||||
|
local element = self.Castbar
|
||||||
|
local name, _, _, texture, startTime, endTime = UnitChannelInfo(unit)
|
||||||
|
if(not name) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
endTime = endTime / 1e3
|
||||||
|
startTime = startTime / 1e3
|
||||||
|
local max = (endTime - startTime)
|
||||||
|
local duration = endTime - GetTime()
|
||||||
|
|
||||||
|
element.duration = duration
|
||||||
|
element.max = max
|
||||||
|
element.delay = 0
|
||||||
|
element.startTime = startTime
|
||||||
|
element.endTime = endTime
|
||||||
|
element.extraTickRatio = 0
|
||||||
|
element.channeling = true
|
||||||
|
element.holdTime = 0
|
||||||
|
|
||||||
|
-- We have to do this, as it's possible for spell casts to never have _STOP
|
||||||
|
-- executed or be fully completed by the OnUpdate handler before CHANNEL_START
|
||||||
|
-- is called.
|
||||||
|
element.casting = nil
|
||||||
|
element.castName = nil
|
||||||
|
|
||||||
|
element:SetMinMaxValues(0, max)
|
||||||
|
element:SetValue(duration)
|
||||||
|
|
||||||
|
if(element.Text) then element.Text:SetText(name) end
|
||||||
|
if(element.Icon) then element.Icon:SetTexture(texture) end
|
||||||
|
if(element.Time) then element.Time:SetText() end
|
||||||
|
|
||||||
|
local sf = element.SafeZone
|
||||||
|
if(sf) then
|
||||||
|
sf:ClearAllPoints()
|
||||||
|
sf:SetPoint('LEFT')
|
||||||
|
sf:SetPoint('TOP')
|
||||||
|
sf:SetPoint('BOTTOM')
|
||||||
|
updateSafeZone(element)
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[ Callback: Castbar:PostChannelStart(unit, name)
|
||||||
|
Called after the element has been updated upon a spell channel start.
|
||||||
|
|
||||||
|
* self - the Castbar widget
|
||||||
|
* unit - unit for which the update has been triggered (string)
|
||||||
|
* name - name of the channeled spell (string)
|
||||||
|
--]]
|
||||||
|
if(element.PostChannelStart) then
|
||||||
|
element:PostChannelStart(unit, name)
|
||||||
|
end
|
||||||
|
element:Show()
|
||||||
|
end
|
||||||
|
|
||||||
|
local function UNIT_SPELLCAST_CHANNEL_UPDATE(self, event, unit)
|
||||||
|
if(self.unit ~= unit and self.realUnit ~= unit) then return end
|
||||||
|
|
||||||
|
local element = self.Castbar
|
||||||
|
local name, _, _, _, startTime, endTime = UnitChannelInfo(unit)
|
||||||
|
if(not name or not element:IsShown()) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local duration = (endTime / 1000) - GetTime()
|
||||||
|
element.delay = element.delay + element.duration - duration
|
||||||
|
element.duration = duration
|
||||||
|
element.max = (endTime - startTime) / 1000
|
||||||
|
element.startTime = startTime / 1000
|
||||||
|
element.endTime = endTime / 1000
|
||||||
|
|
||||||
|
element:SetMinMaxValues(0, element.max)
|
||||||
|
element:SetValue(duration)
|
||||||
|
|
||||||
|
--[[ Callback: Castbar:PostChannelUpdate(unit, name)
|
||||||
|
Called after the element has been updated after a channeled spell has been delayed or interrupted.
|
||||||
|
|
||||||
|
* self - the Castbar widget
|
||||||
|
* unit - unit for which the update has been triggered (string)
|
||||||
|
* name - name of the channeled spell (string)
|
||||||
|
--]]
|
||||||
|
if(element.PostChannelUpdate) then
|
||||||
|
return element:PostChannelUpdate(unit, name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function UNIT_SPELLCAST_CHANNEL_STOP(self, event, unit, spellname)
|
||||||
|
if(self.unit ~= unit and self.realUnit ~= unit) then return end
|
||||||
|
|
||||||
|
local element = self.Castbar
|
||||||
|
if(element:IsShown()) then
|
||||||
|
element.channeling = nil
|
||||||
|
|
||||||
|
--[[ Callback: Castbar:PostChannelUpdate(unit, name)
|
||||||
|
Called after the element has been updated after a channeled spell has been completed.
|
||||||
|
|
||||||
|
* self - the Castbar widget
|
||||||
|
* unit - unit for which the update has been triggered (string)
|
||||||
|
* name - name of the channeled spell (string)
|
||||||
|
--]]
|
||||||
|
if(element.PostChannelStop) then
|
||||||
|
return element:PostChannelStop(unit, spellname)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function onUpdate(self, elapsed)
|
||||||
|
if(self.casting) then
|
||||||
|
local duration = self.duration + elapsed
|
||||||
|
if(duration >= self.max or (tradeskillTotal > 1 and duration >= (tradeskillCastDuration + tradeskillCastTime * 1.25))) then
|
||||||
|
self.casting = nil
|
||||||
|
self:Hide()
|
||||||
|
tradeskillTotal = 0
|
||||||
|
|
||||||
|
if(self.PostCastStop) then self:PostCastStop(self.__owner.unit) end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if(self.Time) then
|
||||||
|
if(self.delay ~= 0) then
|
||||||
|
if(self.CustomDelayText) then
|
||||||
|
self:CustomDelayText(duration)
|
||||||
|
else
|
||||||
|
self.Time:SetFormattedText('%.1f|cffff0000-%.1f|r', duration, self.delay)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if(self.CustomTimeText) then
|
||||||
|
self:CustomTimeText(duration)
|
||||||
|
else
|
||||||
|
self.Time:SetFormattedText('%.1f', duration)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
self.duration = duration
|
||||||
|
self:SetValue(duration)
|
||||||
|
|
||||||
|
if(self.Spark) then
|
||||||
|
self.Spark:SetPoint('CENTER', self, 'LEFT', (duration / self.max) * self:GetWidth(), 0)
|
||||||
|
end
|
||||||
|
elseif(self.channeling) then
|
||||||
|
local duration = self.duration - elapsed
|
||||||
|
|
||||||
|
if(duration <= 0) then
|
||||||
|
self.channeling = nil
|
||||||
|
self:Hide()
|
||||||
|
|
||||||
|
if(self.PostChannelStop) then self:PostChannelStop(self.__owner.unit) end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if(self.Time) then
|
||||||
|
if(self.delay ~= 0) then
|
||||||
|
if(self.CustomDelayText) then
|
||||||
|
self:CustomDelayText(duration)
|
||||||
|
else
|
||||||
|
self.Time:SetFormattedText('%.1f|cffff0000-%.1f|r', duration, self.delay)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if(self.CustomTimeText) then
|
||||||
|
self:CustomTimeText(duration)
|
||||||
|
else
|
||||||
|
self.Time:SetFormattedText('%.1f', duration)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
self.duration = duration
|
||||||
|
self:SetValue(duration)
|
||||||
|
if(self.Spark) then
|
||||||
|
self.Spark:SetPoint('CENTER', self, 'LEFT', (duration / self.max) * self:GetWidth(), 0)
|
||||||
|
end
|
||||||
|
elseif(self.holdTime > 0) then
|
||||||
|
self.holdTime = self.holdTime - elapsed
|
||||||
|
else
|
||||||
|
self.casting = nil
|
||||||
|
self.castName = nil
|
||||||
|
self.channeling = nil
|
||||||
|
tradeskillTotal = 0
|
||||||
|
|
||||||
|
self:Hide()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Update(self, ...)
|
||||||
|
UNIT_SPELLCAST_START(self, ...)
|
||||||
|
return UNIT_SPELLCAST_CHANNEL_START(self, ...)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function ForceUpdate(element)
|
||||||
|
return Update(element.__owner, 'ForceUpdate', element.__owner.unit)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Enable(self, unit)
|
||||||
|
local element = self.Castbar
|
||||||
|
if(element) then
|
||||||
|
element.__owner = self
|
||||||
|
element.ForceUpdate = ForceUpdate
|
||||||
|
|
||||||
|
if(not (unit and unit:match('%wtarget$'))) then
|
||||||
|
self:RegisterEvent('UNIT_SPELLCAST_START', UNIT_SPELLCAST_START)
|
||||||
|
self:RegisterEvent('UNIT_SPELLCAST_FAILED', UNIT_SPELLCAST_FAILED)
|
||||||
|
self:RegisterEvent('UNIT_SPELLCAST_STOP', UNIT_SPELLCAST_STOP)
|
||||||
|
self:RegisterEvent('UNIT_SPELLCAST_INTERRUPTED', UNIT_SPELLCAST_INTERRUPTED)
|
||||||
|
self:RegisterEvent('UNIT_SPELLCAST_DELAYED', UNIT_SPELLCAST_DELAYED)
|
||||||
|
self:RegisterEvent('UNIT_SPELLCAST_CHANNEL_START', UNIT_SPELLCAST_CHANNEL_START)
|
||||||
|
self:RegisterEvent('UNIT_SPELLCAST_CHANNEL_UPDATE', UNIT_SPELLCAST_CHANNEL_UPDATE)
|
||||||
|
self:RegisterEvent('UNIT_SPELLCAST_CHANNEL_STOP', UNIT_SPELLCAST_CHANNEL_STOP)
|
||||||
|
self:RegisterEvent('UNIT_SPELLCAST_SENT', UNIT_SPELLCAST_SENT, true)
|
||||||
|
self:RegisterEvent('UNIT_SPELLCAST_FAILED_QUIET', UNIT_SPELLCAST_FAILED_QUIET)
|
||||||
|
end
|
||||||
|
|
||||||
|
element.holdTime = 0
|
||||||
|
element:SetScript('OnUpdate', element.OnUpdate or onUpdate)
|
||||||
|
|
||||||
|
if(self.unit == 'player') then
|
||||||
|
CastingBarFrame:UnregisterAllEvents()
|
||||||
|
CastingBarFrame.Show = CastingBarFrame.Hide
|
||||||
|
CastingBarFrame:Hide()
|
||||||
|
|
||||||
|
PetCastingBarFrame:UnregisterAllEvents()
|
||||||
|
PetCastingBarFrame.Show = PetCastingBarFrame.Hide
|
||||||
|
PetCastingBarFrame:Hide()
|
||||||
|
end
|
||||||
|
|
||||||
|
if(element:IsObjectType('StatusBar') and not element:GetStatusBarTexture()) then
|
||||||
|
element:SetStatusBarTexture([[Interface\TargetingFrame\UI-StatusBar]])
|
||||||
|
end
|
||||||
|
|
||||||
|
local spark = element.Spark
|
||||||
|
if(spark and spark:IsObjectType('Texture') and not spark:GetTexture()) then
|
||||||
|
spark:SetTexture([[Interface\CastingBar\UI-CastingBar-Spark]])
|
||||||
|
end
|
||||||
|
|
||||||
|
local safeZone = element.SafeZone
|
||||||
|
if(safeZone and safeZone:IsObjectType('Texture') and not safeZone:GetTexture()) then
|
||||||
|
safeZone:SetTexture(1, 0, 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
element:Hide()
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Disable(self)
|
||||||
|
local element = self.Castbar
|
||||||
|
if(element) then
|
||||||
|
element:Hide()
|
||||||
|
|
||||||
|
self:UnregisterEvent('UNIT_SPELLCAST_START', UNIT_SPELLCAST_START)
|
||||||
|
self:UnregisterEvent('UNIT_SPELLCAST_FAILED', UNIT_SPELLCAST_FAILED)
|
||||||
|
self:UnregisterEvent('UNIT_SPELLCAST_STOP', UNIT_SPELLCAST_STOP)
|
||||||
|
self:UnregisterEvent('UNIT_SPELLCAST_INTERRUPTED', UNIT_SPELLCAST_INTERRUPTED)
|
||||||
|
self:UnregisterEvent('UNIT_SPELLCAST_DELAYED', UNIT_SPELLCAST_DELAYED)
|
||||||
|
self:UnregisterEvent('UNIT_SPELLCAST_CHANNEL_START', UNIT_SPELLCAST_CHANNEL_START)
|
||||||
|
self:UnregisterEvent('UNIT_SPELLCAST_CHANNEL_UPDATE', UNIT_SPELLCAST_CHANNEL_UPDATE)
|
||||||
|
self:UnregisterEvent('UNIT_SPELLCAST_CHANNEL_STOP', UNIT_SPELLCAST_CHANNEL_STOP)
|
||||||
|
self:UnregisterEvent('UNIT_SPELLCAST_SENT', UNIT_SPELLCAST_SENT)
|
||||||
|
self:UnregisterEvent('UNIT_SPELLCAST_FAILED_QUIET', UNIT_SPELLCAST_FAILED_QUIET)
|
||||||
|
|
||||||
|
element:SetScript('OnUpdate', nil)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
hooksecurefunc('DoTradeSkill', function(_, num)
|
||||||
|
tradeskillCastTime = 0
|
||||||
|
tradeskillCastDuration = 0
|
||||||
|
tradeskillCurrent = 0
|
||||||
|
tradeskillTotal = num or 1
|
||||||
|
mergeTradeskill = true
|
||||||
|
end)
|
||||||
|
|
||||||
|
oUF:AddElement('Castbar', Update, Enable, Disable)
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
--[[
|
||||||
|
# Element: Combat Indicator
|
||||||
|
|
||||||
|
Toggles the visibility of an indicator based on the player's combat status.
|
||||||
|
|
||||||
|
## Widget
|
||||||
|
|
||||||
|
CombatIndicator - Any UI widget.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
A default texture will be applied if the widget is a Texture and doesn't have a texture or a color set.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
-- Position and size
|
||||||
|
local CombatIndicator = self:CreateTexture(nil, 'OVERLAY')
|
||||||
|
CombatIndicator:SetSize(16, 16)
|
||||||
|
CombatIndicator:SetPoint('TOP', self)
|
||||||
|
|
||||||
|
-- Register it with oUF
|
||||||
|
self.CombatIndicator = CombatIndicator
|
||||||
|
--]]
|
||||||
|
|
||||||
|
local ns = oUF
|
||||||
|
local oUF = ns.oUF
|
||||||
|
|
||||||
|
local UnitAffectingCombat = UnitAffectingCombat
|
||||||
|
|
||||||
|
local function Update(self, event)
|
||||||
|
local element = self.CombatIndicator
|
||||||
|
|
||||||
|
--[[ Callback: CombatIndicator:PreUpdate()
|
||||||
|
Called before the element has been updated.
|
||||||
|
|
||||||
|
* self - the CombatIndicator element
|
||||||
|
--]]
|
||||||
|
if(element.PreUpdate) then
|
||||||
|
element:PreUpdate()
|
||||||
|
end
|
||||||
|
|
||||||
|
local inCombat = UnitAffectingCombat('player')
|
||||||
|
if(inCombat) then
|
||||||
|
element:Show()
|
||||||
|
else
|
||||||
|
element:Hide()
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[ Callback: CombatIndicator:PostUpdate(inCombat)
|
||||||
|
Called after the element has been updated.
|
||||||
|
|
||||||
|
* self - the CombatIndicator element
|
||||||
|
* inCombat - indicates if the player is affecting combat (boolean)
|
||||||
|
--]]
|
||||||
|
if(element.PostUpdate) then
|
||||||
|
return element:PostUpdate(inCombat)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Path(self, ...)
|
||||||
|
--[[ Override: CombatIndicator.Override(self, event)
|
||||||
|
Used to completely override the internal update function.
|
||||||
|
|
||||||
|
* self - the parent object
|
||||||
|
* event - the event triggering the update (string)
|
||||||
|
--]]
|
||||||
|
return (self.CombatIndicator.Override or Update) (self, ...)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function ForceUpdate(element)
|
||||||
|
return Path(element.__owner, 'ForceUpdate')
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Enable(self, unit)
|
||||||
|
local element = self.CombatIndicator
|
||||||
|
if(element and unit == 'player') then
|
||||||
|
element.__owner = self
|
||||||
|
element.ForceUpdate = ForceUpdate
|
||||||
|
|
||||||
|
self:RegisterEvent('PLAYER_REGEN_DISABLED', Path)
|
||||||
|
self:RegisterEvent('PLAYER_REGEN_ENABLED', Path)
|
||||||
|
|
||||||
|
if(element:IsObjectType('Texture') and not element:GetTexture()) then
|
||||||
|
element:SetTexture([[Interface\CharacterFrame\UI-StateIcon]])
|
||||||
|
element:SetTexCoord(.5, 1, 0, .49)
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Disable(self)
|
||||||
|
local element = self.CombatIndicator
|
||||||
|
if(element) then
|
||||||
|
element:Hide()
|
||||||
|
|
||||||
|
self:UnregisterEvent('PLAYER_REGEN_DISABLED', Path)
|
||||||
|
self:UnregisterEvent('PLAYER_REGEN_ENABLED', Path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
oUF:AddElement('CombatIndicator', Path, Enable, Disable)
|
||||||
@@ -0,0 +1,118 @@
|
|||||||
|
--[[
|
||||||
|
# Element: ComboPoints
|
||||||
|
|
||||||
|
Handles the visibility and updating of the player's combo points.
|
||||||
|
|
||||||
|
## Widget
|
||||||
|
|
||||||
|
ComboPoints - An `table` consisting of as many Textures as the theoretical maximum return of [GetComboPoints](http://wowprogramming.com/docs/api/GetComboPoints).
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
A default texture will be applied if the widget is a Texture and doesn't have a texture or a color set.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
local ComboPoints = {}
|
||||||
|
for index = 1, 10 do
|
||||||
|
local Bar = CreateFrame('StatusBar', nil, self)
|
||||||
|
|
||||||
|
-- Position and size.
|
||||||
|
Bar:SetSize(16, 16)
|
||||||
|
Bar:SetPoint('TOPLEFT', self, 'BOTTOMLEFT', (index - 1) * Bar:GetWidth(), 0)
|
||||||
|
|
||||||
|
ComboPoints[index] = Bar
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Register with oUF
|
||||||
|
self.ComboPoints = ComboPoints
|
||||||
|
--]]
|
||||||
|
|
||||||
|
local ns = oUF
|
||||||
|
local oUF = ns.oUF
|
||||||
|
|
||||||
|
local GetComboPoints = GetComboPoints
|
||||||
|
local MAX_COMBO_POINTS = MAX_COMBO_POINTS
|
||||||
|
|
||||||
|
local function Update(self, event)
|
||||||
|
local element = self.ComboPoints
|
||||||
|
|
||||||
|
--[[ Callback: ComboPoints:PreUpdate()
|
||||||
|
Called before the element has been updated.
|
||||||
|
|
||||||
|
* self - the ComboPoints element
|
||||||
|
--]]
|
||||||
|
if(element.PreUpdate) then
|
||||||
|
element:PreUpdate()
|
||||||
|
end
|
||||||
|
|
||||||
|
local cp = GetComboPoints('player', 'target')
|
||||||
|
|
||||||
|
for i = 1, MAX_COMBO_POINTS do
|
||||||
|
if(i <= cp) then
|
||||||
|
element[i]:Show()
|
||||||
|
else
|
||||||
|
element[i]:Hide()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[ Callback: ComboPoints:PostUpdate(role)
|
||||||
|
Called after the element has been updated.
|
||||||
|
|
||||||
|
* self - the ComboPoints element
|
||||||
|
* cpoint - the current amount of combo points (number)
|
||||||
|
--]]
|
||||||
|
if(element.PostUpdate) then
|
||||||
|
return element:PostUpdate(cp)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Path(self, ...)
|
||||||
|
--[[ Override: ComboPoints.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
|
||||||
|
--]]
|
||||||
|
return (self.ComboPoints.Override or Update) (self, ...)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function ForceUpdate(element)
|
||||||
|
return Path(element.__owner, 'ForceUpdate', element.__owner.unit)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Enable(self)
|
||||||
|
local element = self.ComboPoints
|
||||||
|
if(element) then
|
||||||
|
element.__owner = self
|
||||||
|
element.ForceUpdate = ForceUpdate
|
||||||
|
|
||||||
|
self:RegisterEvent('PLAYER_COMBO_POINTS', Path, true)
|
||||||
|
self:RegisterEvent('PLAYER_TARGET_CHANGED', Path, true)
|
||||||
|
|
||||||
|
for index = 1, MAX_COMBO_POINTS do
|
||||||
|
local cp = element[index]
|
||||||
|
if(cp:IsObjectType('Texture') and not cp:GetTexture()) then
|
||||||
|
cp:SetTexture([[Interface\ComboFrame\ComboPoint]])
|
||||||
|
cp:SetTexCoord(0, 0.375, 0, 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Disable(self)
|
||||||
|
local element = self.ComboPoints
|
||||||
|
if(element) then
|
||||||
|
for index = 1, MAX_COMBO_POINTS do
|
||||||
|
element[index]:Hide()
|
||||||
|
end
|
||||||
|
|
||||||
|
self:UnregisterEvent('PLAYER_COMBO_POINTS', Path)
|
||||||
|
self:UnregisterEvent('PLAYER_TARGET_CHANGED', Path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
oUF:AddElement('ComboPoints', Path, Enable, Disable)
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
<Ui xmlns="http://www.blizzard.com/wow/ui/">
|
||||||
|
<Script file="power.lua"/>
|
||||||
|
<!--<Script file="auras.lua"/>-->
|
||||||
|
<Script file="health.lua"/>
|
||||||
|
<!--<Script file="raidtargetindicator.lua"/>
|
||||||
|
<Script file="leaderindicator.lua"/>
|
||||||
|
<Script file="combatindicator.lua"/>
|
||||||
|
<Script file="restingindicator.lua"/>
|
||||||
|
<Script file="pvpindicator.lua"/>-->
|
||||||
|
<Script file="portrait.lua"/>
|
||||||
|
<!--
|
||||||
|
<Script file="range.lua"/>
|
||||||
|
<Script file="castbar.lua"/>-->
|
||||||
|
<Script file="tags.lua"/>
|
||||||
|
<!-- <Script file="masterlooterindicator.lua"/>
|
||||||
|
<Script file="assistantindicator.lua"/>
|
||||||
|
<Script file="readycheckindicator.lua"/>
|
||||||
|
<Script file="combopoints.lua"/>
|
||||||
|
<Script file="raidroleindicator.lua"/>
|
||||||
|
<Script file="happinessindicator.lua"/>
|
||||||
|
-->
|
||||||
|
</Ui>
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
--[[
|
||||||
|
# Element: HappinessIndicator
|
||||||
|
|
||||||
|
Handles the visibility and updating of player pet happiness.
|
||||||
|
|
||||||
|
## Widget
|
||||||
|
|
||||||
|
HappinessIndicator - A `Texture` used to display the current happiness level.
|
||||||
|
The element works by changing the texture's vertex color.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
A default texture will be applied if the widget is a Texture and doesn't have a texture or a color set.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
-- Position and size
|
||||||
|
local HappinessIndicator = self:CreateTexture(nil, 'OVERLAY')
|
||||||
|
HappinessIndicator:SetSize(16, 16)
|
||||||
|
HappinessIndicator:SetPoint('TOPRIGHT', self)
|
||||||
|
|
||||||
|
-- Register it with oUF
|
||||||
|
self.HappinessIndicator = HappinessIndicator
|
||||||
|
--]]
|
||||||
|
|
||||||
|
local ns = oUF
|
||||||
|
local oUF = ns.oUF
|
||||||
|
|
||||||
|
local GetPetHappiness = GetPetHappiness
|
||||||
|
local HasPetUI = HasPetUI
|
||||||
|
|
||||||
|
local function Update(self, event, unit)
|
||||||
|
if(not unit or self.unit ~= unit) then return end
|
||||||
|
|
||||||
|
local element = self.HappinessIndicator
|
||||||
|
|
||||||
|
--[[ Callback: HappinessIndicator:PreUpdate()
|
||||||
|
Called before the element has been updated.
|
||||||
|
|
||||||
|
* self - the ComboPoints element
|
||||||
|
--]]
|
||||||
|
if(element.PreUpdate) then
|
||||||
|
element:PreUpdate()
|
||||||
|
end
|
||||||
|
|
||||||
|
local _, hunterPet = HasPetUI()
|
||||||
|
local happiness, damagePercentage = GetPetHappiness()
|
||||||
|
|
||||||
|
if(hunterPet and happiness) then
|
||||||
|
if(happiness == 1) then
|
||||||
|
element:SetTexCoord(0.375, 0.5625, 0, 0.359375)
|
||||||
|
elseif(happiness == 2) then
|
||||||
|
element:SetTexCoord(0.1875, 0.375, 0, 0.359375)
|
||||||
|
elseif(happiness == 3) then
|
||||||
|
element:SetTexCoord(0, 0.1875, 0, 0.359375)
|
||||||
|
end
|
||||||
|
|
||||||
|
element:Show()
|
||||||
|
else
|
||||||
|
return element:Hide()
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[ Callback: HappinessIndicator:PostUpdate(role)
|
||||||
|
Called after the element has been updated.
|
||||||
|
|
||||||
|
* self - the ComboPoints element
|
||||||
|
* unit - the unit for which the update has been triggered (string)
|
||||||
|
* happiness - the numerical happiness value of the pet (1 = unhappy, 2 = content, 3 = happy) (number)
|
||||||
|
* damagePercentage - damage modifier, happiness affects this (unhappy = 75%, content = 100%, happy = 125%) (number)
|
||||||
|
--]]
|
||||||
|
if(element.PostUpdate) then
|
||||||
|
return element:PostUpdate(unit, happiness, damagePercentage)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Path(self, ...)
|
||||||
|
--[[ Override: HappinessIndicator.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
|
||||||
|
--]]
|
||||||
|
return (self.HappinessIndicator.Override or Update) (self, ...)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function ForceUpdate(element)
|
||||||
|
return Path(element.__owner, 'ForceUpdate', element.__owner.unit)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Enable(self)
|
||||||
|
local element = self.HappinessIndicator
|
||||||
|
if(element) then
|
||||||
|
element.__owner = self
|
||||||
|
element.ForceUpdate = ForceUpdate
|
||||||
|
|
||||||
|
self:RegisterEvent('UNIT_HAPPINESS', Path)
|
||||||
|
|
||||||
|
if(element:IsObjectType('Texture') and not element:GetTexture()) then
|
||||||
|
element:SetTexture([[Interface\PetPaperDollFrame\UI-PetHappiness]])
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Disable(self)
|
||||||
|
local element = self.HappinessIndicator
|
||||||
|
if(element) then
|
||||||
|
element:Hide()
|
||||||
|
|
||||||
|
self:UnregisterEvent('UNIT_HAPPINESS', Path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
oUF:AddElement('HappinessIndicator', Path, Enable, Disable)
|
||||||
@@ -0,0 +1,292 @@
|
|||||||
|
--[[
|
||||||
|
# Element: Health Bar
|
||||||
|
|
||||||
|
Handles the updating of a status bar that displays the unit's health.
|
||||||
|
|
||||||
|
## Widget
|
||||||
|
|
||||||
|
Health - A `StatusBar` used to represent the unit's health.
|
||||||
|
|
||||||
|
## 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 widget is a StatusBar and doesn't have a texture set.
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
.frequentUpdates - Indicates whether to use OnUpdate script instead of UNIT_HEALTH to update the bar (boolean)
|
||||||
|
.smoothGradient - 9 color values to be used with the .colorSmooth option (table)
|
||||||
|
|
||||||
|
The following options are listed by priority. The first check that returns true decides the color of the bar.
|
||||||
|
|
||||||
|
.colorTapping - Use `self.colors.tapping` to color the bar if the unit isn't tapped by the player (boolean)
|
||||||
|
.colorDisconnected - Use `self.colors.disconnected` to color the bar if the unit is offline (boolean)
|
||||||
|
.colorHappiness - Use `self.colors.happiness` to color the bar if the unit is pet based on pet happiness (boolean)
|
||||||
|
.colorClass - Use `self.colors.class[class]` to color the bar based on unit class. `class` is defined by the
|
||||||
|
second return of [UnitClass](http://wowprogramming.com/docs/api/UnitClass) (boolean)
|
||||||
|
.colorClassNPC - Use `self.colors.class[class]` to color the bar if the unit is a NPC (boolean)
|
||||||
|
.colorClassPet - Use `self.colors.class[class]` to color the bar if the unit is player controlled, but not a player
|
||||||
|
(boolean)
|
||||||
|
.colorReaction - Use `self.colors.reaction[reaction]` to color the bar based on the player's reaction towards the
|
||||||
|
unit. `reaction` is defined by the return value of
|
||||||
|
[UnitReaction](http://wowprogramming.com/docs/api/UnitReaction) (boolean)
|
||||||
|
.colorSmooth - Use `smoothGradient` if present or `self.colors.smooth` to color the bar with a smooth gradient
|
||||||
|
based on the player's current health percentage (boolean)
|
||||||
|
.colorHealth - Use `self.colors.health` to color the bar. This flag is used to reset the bar color back to default
|
||||||
|
if none of the above conditions are met (boolean)
|
||||||
|
|
||||||
|
## 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]
|
||||||
|
|
||||||
|
## Attributes
|
||||||
|
|
||||||
|
.disconnected - Indicates whether the unit is disconnected (boolean)
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
-- Position and size
|
||||||
|
local Health = CreateFrame('StatusBar', nil, self)
|
||||||
|
Health:SetHeight(20)
|
||||||
|
Health:SetPoint('TOP')
|
||||||
|
Health:SetPoint('LEFT')
|
||||||
|
Health:SetPoint('RIGHT')
|
||||||
|
|
||||||
|
-- Add a background
|
||||||
|
local Background = Health:CreateTexture(nil, 'BACKGROUND')
|
||||||
|
Background:SetAllPoints(Health)
|
||||||
|
Background:SetTexture(1, 1, 1, .5)
|
||||||
|
|
||||||
|
-- Options
|
||||||
|
Health.frequentUpdates = true
|
||||||
|
Health.colorTapping = true
|
||||||
|
Health.colorDisconnected = true
|
||||||
|
Health.colorClass = true
|
||||||
|
Health.colorReaction = true
|
||||||
|
Health.colorHealth = true
|
||||||
|
|
||||||
|
-- Make the background darker.
|
||||||
|
Background.multiplier = .5
|
||||||
|
|
||||||
|
-- Register it with oUF
|
||||||
|
Health.bg = Background
|
||||||
|
self.Health = Health
|
||||||
|
--]]
|
||||||
|
|
||||||
|
local ns = oUF
|
||||||
|
local oUF = ns.oUF
|
||||||
|
|
||||||
|
local unpack = unpack
|
||||||
|
|
||||||
|
local GetPetHappiness = GetPetHappiness
|
||||||
|
local UnitClass = UnitClass
|
||||||
|
local UnitHealth = UnitHealth
|
||||||
|
local UnitHealthMax = UnitHealthMax
|
||||||
|
local UnitIsConnected = UnitIsConnected
|
||||||
|
local UnitIsPlayer = UnitIsPlayer
|
||||||
|
local UnitIsTapped = UnitIsTapped
|
||||||
|
local UnitIsTappedByPlayer = UnitIsTappedByPlayer
|
||||||
|
local UnitIsUnit = UnitIsUnit
|
||||||
|
local UnitPlayerControlled = UnitPlayerControlled
|
||||||
|
local UnitReaction = UnitReaction
|
||||||
|
|
||||||
|
local updateFrequentUpdates
|
||||||
|
|
||||||
|
local function UpdateColor(element, unit, cur, max)
|
||||||
|
local parent = element.__owner
|
||||||
|
|
||||||
|
if element.frequentUpdates ~= element.__frequentUpdates then
|
||||||
|
element.__frequentUpdates = element.frequentUpdates
|
||||||
|
updateFrequentUpdates(parent, unit)
|
||||||
|
end
|
||||||
|
|
||||||
|
local r, g, b, t
|
||||||
|
if(element.colorTapping and not UnitPlayerControlled(unit) and (UnitIsTapped(unit) and not UnitIsTappedByPlayer(unit))) then
|
||||||
|
t = parent.colors.tapped
|
||||||
|
elseif(element.colorDisconnected and element.disconnected) then
|
||||||
|
t = parent.colors.disconnected
|
||||||
|
elseif(element.colorHappiness and UnitIsUnit(unit, 'pet') and GetPetHappiness()) then
|
||||||
|
t = parent.colors.happiness[GetPetHappiness()]
|
||||||
|
elseif(element.colorClass and UnitIsPlayer(unit)) or
|
||||||
|
(element.colorClassNPC and not UnitIsPlayer(unit)) or
|
||||||
|
(element.colorClassPet and UnitPlayerControlled(unit) and not UnitIsPlayer(unit)) then
|
||||||
|
local _, class = UnitClass(unit)
|
||||||
|
t = parent.colors.class[class]
|
||||||
|
elseif(element.colorReaction and UnitReaction(unit, 'player')) then
|
||||||
|
t = parent.colors.reaction[UnitReaction(unit, 'player')]
|
||||||
|
elseif(element.colorSmooth) then
|
||||||
|
r, g, b = parent.ColorGradient(cur, max, unpack(element.smoothGradient or parent.colors.smooth))
|
||||||
|
elseif(element.colorHealth) then
|
||||||
|
t = parent.colors.health
|
||||||
|
end
|
||||||
|
|
||||||
|
if(t) then
|
||||||
|
r, g, b = t[1], t[2], t[3]
|
||||||
|
end
|
||||||
|
|
||||||
|
if(r or g or b) then
|
||||||
|
element:SetStatusBarColor(r, g, b)
|
||||||
|
|
||||||
|
local bg = element.bg
|
||||||
|
if(bg) then
|
||||||
|
local mu = bg.multiplier or 1
|
||||||
|
bg:SetVertexColor(r * mu, g * mu, b * mu)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Update(self, event, unit)
|
||||||
|
if(not unit or self.unit ~= unit) then return end
|
||||||
|
local element = self.Health
|
||||||
|
|
||||||
|
--[[ Callback: Health:PreUpdate(unit)
|
||||||
|
Called before the element has been updated.
|
||||||
|
|
||||||
|
* self - the Health element
|
||||||
|
* unit - the unit for which the update has been triggered (string)
|
||||||
|
--]]
|
||||||
|
if(element.PreUpdate) then
|
||||||
|
element:PreUpdate(unit)
|
||||||
|
end
|
||||||
|
|
||||||
|
local cur, max = UnitHealth(unit), UnitHealthMax(unit)
|
||||||
|
local disconnected = not UnitIsConnected(unit)
|
||||||
|
element:SetMinMaxValues(0, max)
|
||||||
|
|
||||||
|
if(disconnected) then
|
||||||
|
element:SetValue(max)
|
||||||
|
else
|
||||||
|
element:SetValue(cur)
|
||||||
|
end
|
||||||
|
|
||||||
|
element.disconnected = disconnected
|
||||||
|
|
||||||
|
--[[ Override: Health:UpdateColor(unit, cur, max)
|
||||||
|
Used to completely override the internal function for updating the widgets' colors.
|
||||||
|
|
||||||
|
* self - the Health element
|
||||||
|
* unit - the unit for which the update has been triggered (string)
|
||||||
|
* cur - the unit's current health value (number)
|
||||||
|
* max - the unit's maximum possible health value (number)
|
||||||
|
--]]
|
||||||
|
element:UpdateColor(unit, cur, max)
|
||||||
|
|
||||||
|
--[[ Callback: Health:PostUpdate(unit, cur, max)
|
||||||
|
Called after the element has been updated.
|
||||||
|
|
||||||
|
* self - the Health element
|
||||||
|
* unit - the unit for which the update has been triggered (string)
|
||||||
|
* cur - the unit's current health value (number)
|
||||||
|
* max - the unit's maximum possible health value (number)
|
||||||
|
--]]
|
||||||
|
if(element.PostUpdate) then
|
||||||
|
return element:PostUpdate(unit, cur, max)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Path(self, ...)
|
||||||
|
--[[ Override: Health.Override(self, event, unit)
|
||||||
|
Used to completely override the internal update function.
|
||||||
|
|
||||||
|
* self - the parent object
|
||||||
|
* event - the event triggering the update (string)
|
||||||
|
* unit - the unit accompanying the event (string)
|
||||||
|
--]]
|
||||||
|
return (self.Health.Override or Update) (self, unpack(arg))
|
||||||
|
end
|
||||||
|
|
||||||
|
local function ForceUpdate(element)
|
||||||
|
return Path(element.__owner, 'ForceUpdate', element.__owner.unit)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function onHealthUpdate()
|
||||||
|
if(this.disconnected) then return end
|
||||||
|
|
||||||
|
local unit = this.__owner.unit
|
||||||
|
local health = UnitHealth(unit)
|
||||||
|
|
||||||
|
if(health ~= this.min) then
|
||||||
|
this.min = health
|
||||||
|
|
||||||
|
return Path(this.__owner, 'OnHealthUpdate', unit)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function updateFrequentUpdates(self, unit)
|
||||||
|
if(not unit or string.match(unit, '%w+target$')) then return end
|
||||||
|
|
||||||
|
local element = self.Health
|
||||||
|
if(element.frequentUpdates and not element:GetScript('OnUpdate')) then
|
||||||
|
element:SetScript('OnUpdate', onHealthUpdate)
|
||||||
|
|
||||||
|
if((unit == 'party' or string.match(unit, 'party%d?$'))) then
|
||||||
|
self:RegisterEvent('UNIT_HEALTH', Path)
|
||||||
|
elseif(self:IsEventRegistered("UNIT_HEALTH")) then
|
||||||
|
self:UnregisterEvent('UNIT_HEALTH', Path)
|
||||||
|
end
|
||||||
|
elseif(not element.frequentUpdates and element:GetScript('OnUpdate')) then
|
||||||
|
element:SetScript('OnUpdate', nil)
|
||||||
|
|
||||||
|
self:RegisterEvent('UNIT_HEALTH', Path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Enable(self, unit)
|
||||||
|
local element = self.Health
|
||||||
|
if(element) then
|
||||||
|
element.__owner = self
|
||||||
|
element.ForceUpdate = ForceUpdate
|
||||||
|
element.__frequentUpdates = element.frequentUpdates
|
||||||
|
updateFrequentUpdates(self, unit)
|
||||||
|
|
||||||
|
if(element.frequentUpdates and (unit and not string.match(unit, '%w+target$'))) then
|
||||||
|
element:SetScript('OnUpdate', onHealthUpdate)
|
||||||
|
|
||||||
|
-- The party frames need this to handle disconnect states correctly.
|
||||||
|
if(unit == 'party') then
|
||||||
|
self:RegisterEvent('UNIT_HEALTH', Path)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
self:RegisterEvent('UNIT_HEALTH', Path)
|
||||||
|
end
|
||||||
|
|
||||||
|
self:RegisterEvent('UNIT_MAXHEALTH', Path)
|
||||||
|
self:RegisterEvent('UNIT_CONNECTION', Path)
|
||||||
|
self:RegisterEvent('UNIT_FACTION', Path) -- For tapping
|
||||||
|
self:RegisterEvent('UNIT_HAPPINESS', Path)
|
||||||
|
|
||||||
|
if(element:IsObjectType('StatusBar') and not element:GetStatusBarTexture()) then
|
||||||
|
element:SetStatusBarTexture([[Interface\TargetingFrame\UI-StatusBar]])
|
||||||
|
end
|
||||||
|
|
||||||
|
if(not element.UpdateColor) then
|
||||||
|
element.UpdateColor = UpdateColor
|
||||||
|
end
|
||||||
|
|
||||||
|
element:Show()
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Disable(self)
|
||||||
|
local element = self.Health
|
||||||
|
if(element) then
|
||||||
|
if(element:GetScript('OnUpdate')) then
|
||||||
|
element:SetScript('OnUpdate', nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
element:Hide()
|
||||||
|
|
||||||
|
self:UnregisterEvent('UNIT_HEALTH', Path)
|
||||||
|
self:UnregisterEvent('UNIT_MAXHEALTH', Path)
|
||||||
|
self:UnregisterEvent('UNIT_CONNECTION', Path)
|
||||||
|
self:UnregisterEvent('UNIT_FACTION', Path)
|
||||||
|
self:UnregisterEvent('UNIT_HAPPINESS', Path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
oUF:AddElement('Health', Path, Enable, Disable)
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
--[[
|
||||||
|
# Element: Leader Indicator
|
||||||
|
|
||||||
|
Toggles the visibility of an indicator based on the unit's leader status.
|
||||||
|
|
||||||
|
## Widget
|
||||||
|
|
||||||
|
LeaderIndicator - Any UI widget.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
A default texture will be applied if the widget is a Texture and doesn't have a texture or a color set.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
-- Position and size
|
||||||
|
local LeaderIndicator = self:CreateTexture(nil, 'OVERLAY')
|
||||||
|
LeaderIndicator:SetSize(16, 16)
|
||||||
|
LeaderIndicator:SetPoint('BOTTOM', self, 'TOP')
|
||||||
|
|
||||||
|
-- Register it with oUF
|
||||||
|
self.LeaderIndicator = LeaderIndicator
|
||||||
|
--]]
|
||||||
|
|
||||||
|
local ns = oUF
|
||||||
|
local oUF = ns.oUF
|
||||||
|
|
||||||
|
local UnitInParty = UnitInParty
|
||||||
|
local UnitInRaid = UnitInRaid
|
||||||
|
local UnitIsPartyLeader = UnitIsPartyLeader
|
||||||
|
|
||||||
|
local function Update(self, event)
|
||||||
|
local element = self.LeaderIndicator
|
||||||
|
|
||||||
|
--[[ Callback: LeaderIndicator:PreUpdate()
|
||||||
|
Called before the element has been updated.
|
||||||
|
|
||||||
|
* self - the LeaderIndicator element
|
||||||
|
--]]
|
||||||
|
if(element.PreUpdate) then
|
||||||
|
element:PreUpdate()
|
||||||
|
end
|
||||||
|
|
||||||
|
local unit = self.unit
|
||||||
|
local isLeader = (UnitInParty(unit) or UnitInRaid(unit)) and UnitIsPartyLeader(unit)
|
||||||
|
if(isLeader) then
|
||||||
|
element:Show()
|
||||||
|
else
|
||||||
|
element:Hide()
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[ Callback: LeaderIndicator:PostUpdate(isLeader)
|
||||||
|
Called after the element has been updated.
|
||||||
|
|
||||||
|
* self - the LeaderIndicator element
|
||||||
|
* isLeader - indicates whether the element is shown (boolean)
|
||||||
|
--]]
|
||||||
|
if(element.PostUpdate) then
|
||||||
|
return element:PostUpdate(isLeader)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Path(self, ...)
|
||||||
|
--[[ Override: LeaderIndicator.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
|
||||||
|
--]]
|
||||||
|
return (self.LeaderIndicator.Override or Update) (self, ...)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function ForceUpdate(element)
|
||||||
|
return Path(element.__owner, 'ForceUpdate')
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Enable(self)
|
||||||
|
local element = self.LeaderIndicator
|
||||||
|
if(element) then
|
||||||
|
element.__owner = self
|
||||||
|
element.ForceUpdate = ForceUpdate
|
||||||
|
|
||||||
|
self:RegisterEvent('PARTY_LEADER_CHANGED', Path)
|
||||||
|
self:RegisterEvent('PARTY_MEMBERS_CHANGED', Path)
|
||||||
|
self:RegisterEvent('RAID_ROSTER_UPDATE', Path)
|
||||||
|
|
||||||
|
if(element:IsObjectType('Texture') and not element:GetTexture()) then
|
||||||
|
element:SetTexture([[Interface\GroupFrame\UI-Group-LeaderIcon]])
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Disable(self)
|
||||||
|
local element = self.LeaderIndicator
|
||||||
|
if(element) then
|
||||||
|
element:Hide()
|
||||||
|
|
||||||
|
self:UnregisterEvent('PARTY_LEADER_CHANGED', Path)
|
||||||
|
self:UnregisterEvent('PARTY_MEMBERS_CHANGED', Path)
|
||||||
|
self:UnregisterEvent('RAID_ROSTER_UPDATE', Path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
oUF:AddElement('LeaderIndicator', Path, Enable, Disable)
|
||||||
@@ -0,0 +1,126 @@
|
|||||||
|
--[[
|
||||||
|
# Element: Master Looter Indicator
|
||||||
|
|
||||||
|
Toggles the visibility of an indicator based on the unit's master looter status.
|
||||||
|
|
||||||
|
## Widget
|
||||||
|
|
||||||
|
MasterLooterIndicator - Any UI widget.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
A default texture will be applied if the widget is a Texture and doesn't have a texture or a color set.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
-- Position and size
|
||||||
|
local MasterLooterIndicator = self:CreateTexture(nil, 'OVERLAY')
|
||||||
|
MasterLooterIndicator:SetSize(16, 16)
|
||||||
|
MasterLooterIndicator:SetPoint('TOPRIGHT', self)
|
||||||
|
|
||||||
|
-- Register it with oUF
|
||||||
|
self.MasterLooterIndicator = MasterLooterIndicator
|
||||||
|
--]]
|
||||||
|
|
||||||
|
local ns = oUF
|
||||||
|
local oUF = ns.oUF
|
||||||
|
|
||||||
|
local GetLootMethod = GetLootMethod
|
||||||
|
local UnitInParty = UnitInParty
|
||||||
|
local UnitInRaid = UnitInRaid
|
||||||
|
local UnitIsUnit = UnitIsUnit
|
||||||
|
|
||||||
|
local function Update(self, event)
|
||||||
|
local unit = self.unit
|
||||||
|
local element = self.MasterLooterIndicator
|
||||||
|
|
||||||
|
--[[ Callback: MasterLooterIndicator:PreUpdate()
|
||||||
|
Called before the element has been updated.
|
||||||
|
|
||||||
|
* self - the MasterLooterIndicator element
|
||||||
|
--]]
|
||||||
|
if(element.PreUpdate) then
|
||||||
|
element:PreUpdate()
|
||||||
|
end
|
||||||
|
|
||||||
|
local isShown = false
|
||||||
|
if(UnitInParty(unit) or UnitInRaid(unit)) then
|
||||||
|
local method, partyIndex, raidIndex = GetLootMethod()
|
||||||
|
if(method == 'master') then
|
||||||
|
local mlUnit
|
||||||
|
if(partyIndex) then
|
||||||
|
if(partyIndex == 0) then
|
||||||
|
mlUnit = 'player'
|
||||||
|
else
|
||||||
|
mlUnit = 'party' .. partyIndex
|
||||||
|
end
|
||||||
|
elseif(raidIndex) then
|
||||||
|
mlUnit = 'raid' .. raidIndex
|
||||||
|
end
|
||||||
|
|
||||||
|
if(mlUnit and UnitIsUnit(unit, mlUnit)) then
|
||||||
|
isShown = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if isShown then
|
||||||
|
element:Show()
|
||||||
|
else
|
||||||
|
element:Hide()
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[ Callback: MasterLooterIndicator:PostUpdate(isShown)
|
||||||
|
Called after the element has been updated.
|
||||||
|
|
||||||
|
* self - the MasterLooterIndicator element
|
||||||
|
* isShown - indicates whether the element is shown (boolean)
|
||||||
|
--]]
|
||||||
|
if(element.PostUpdate) then
|
||||||
|
return element:PostUpdate(isShown)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Path(self, ...)
|
||||||
|
--[[ Override: MasterLooterIndicator.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
|
||||||
|
--]]
|
||||||
|
return (self.MasterLooterIndicator.Override or Update) (self, ...)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function ForceUpdate(element)
|
||||||
|
return Path(element.__owner, 'ForceUpdate')
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Enable(self, unit)
|
||||||
|
local element = self.MasterLooterIndicator
|
||||||
|
if(element) then
|
||||||
|
element.__owner = self
|
||||||
|
element.ForceUpdate = ForceUpdate
|
||||||
|
|
||||||
|
self:RegisterEvent('PARTY_LOOT_METHOD_CHANGED', Path, true)
|
||||||
|
self:RegisterEvent('PARTY_MEMBERS_CHANGED', Path, true)
|
||||||
|
|
||||||
|
if(element:IsObjectType('Texture') and not element:GetTexture()) then
|
||||||
|
element:SetTexture([[Interface\GroupFrame\UI-Group-MasterLooter]])
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Disable(self)
|
||||||
|
local element = self.MasterLooterIndicator
|
||||||
|
if(element) then
|
||||||
|
element:Hide()
|
||||||
|
|
||||||
|
self:UnregisterEvent('PARTY_LOOT_METHOD_CHANGED', Path)
|
||||||
|
self:UnregisterEvent('PARTY_MEMBERS_CHANGED', Path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
oUF:AddElement('MasterLooterIndicator', Path, Enable, Disable)
|
||||||
@@ -0,0 +1,148 @@
|
|||||||
|
--[[
|
||||||
|
# Element: Portraits
|
||||||
|
|
||||||
|
Handles the updating of the unit's portrait.
|
||||||
|
|
||||||
|
## Widget
|
||||||
|
|
||||||
|
Portrait - A `PlayerModel` or a `Texture` used to represent the unit's portrait.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
A question mark model will be used if the widget is a PlayerModel and the client doesn't have the model information for
|
||||||
|
the unit.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
-- 3D Portrait
|
||||||
|
-- Position and size
|
||||||
|
local Portrait = CreateFrame('PlayerModel', nil, self)
|
||||||
|
Portrait:SetSize(32, 32)
|
||||||
|
Portrait:SetPoint('RIGHT', self, 'LEFT')
|
||||||
|
|
||||||
|
-- Register it with oUF
|
||||||
|
self.Portrait = Portrait
|
||||||
|
|
||||||
|
-- 2D Portrait
|
||||||
|
local Portrait = self:CreateTexture(nil, 'OVERLAY')
|
||||||
|
Portrait:SetSize(32, 32)
|
||||||
|
Portrait:SetPoint('RIGHT', self, 'LEFT')
|
||||||
|
|
||||||
|
-- Register it with oUF
|
||||||
|
self.Portrait = Portrait
|
||||||
|
--]]
|
||||||
|
|
||||||
|
local ns = oUF
|
||||||
|
local oUF = ns.oUF
|
||||||
|
|
||||||
|
local SetPortraitTexture = SetPortraitTexture
|
||||||
|
local UnitExists = UnitExists
|
||||||
|
local UnitName = UnitName
|
||||||
|
local UnitIsConnected = UnitIsConnected
|
||||||
|
local UnitIsUnit = UnitIsUnit
|
||||||
|
local UnitIsVisible = UnitIsVisible
|
||||||
|
|
||||||
|
local function Update(self, event, unit)
|
||||||
|
if(not unit or not UnitIsUnit(self.unit, unit)) then return end
|
||||||
|
|
||||||
|
local element = self.Portrait
|
||||||
|
|
||||||
|
--[[ Callback: Portrait:PreUpdate(unit)
|
||||||
|
Called before the element has been updated.
|
||||||
|
|
||||||
|
* self - the Portrait element
|
||||||
|
* unit - the unit for which the update has been triggered (string)
|
||||||
|
--]]
|
||||||
|
if(element.PreUpdate) then element:PreUpdate(unit) end
|
||||||
|
|
||||||
|
local name = UnitName(unit)
|
||||||
|
local isAvailable = UnitIsConnected(unit) and UnitIsVisible(unit)
|
||||||
|
if(event ~= 'OnUpdate' or element.name ~= name or element.state ~= isAvailable) then
|
||||||
|
if(element:IsObjectType('PlayerModel')) then
|
||||||
|
if(not isAvailable) then
|
||||||
|
element:SetModelScale(4.25)
|
||||||
|
element:SetCamera(0)
|
||||||
|
element:SetPosition(0, 0, -1.5)
|
||||||
|
element:SetModel([[Interface\Buttons\TalkToMeQuestionMark.m2]])
|
||||||
|
elseif(element.name ~= name or event == 'UNIT_MODEL_CHANGED') then
|
||||||
|
element:ClearModel()
|
||||||
|
element:SetUnit(unit)
|
||||||
|
element:SetModelScale(1)
|
||||||
|
element:SetCamera(0)
|
||||||
|
element:SetPosition(0, 0, 0)
|
||||||
|
else
|
||||||
|
element:SetCamera(0)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
SetPortraitTexture(element, unit)
|
||||||
|
end
|
||||||
|
|
||||||
|
element.name = name
|
||||||
|
element.state = isAvailable
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[ Callback: Portrait:PostUpdate(unit)
|
||||||
|
Called after the element has been updated.
|
||||||
|
|
||||||
|
* self - the Portrait element
|
||||||
|
* unit - the unit for which the update has been triggered (string)
|
||||||
|
--]]
|
||||||
|
if(element.PostUpdate) then
|
||||||
|
return element:PostUpdate(unit)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Path(self, ...)
|
||||||
|
--[[ Override: Portrait.Override(self, event, unit)
|
||||||
|
Used to completely override the internal update function.
|
||||||
|
|
||||||
|
* self - the parent object
|
||||||
|
* event - the event triggering the update (string)
|
||||||
|
* unit - the unit accompanying the event (string)
|
||||||
|
--]]
|
||||||
|
return (self.Portrait.Override or Update) (self, unpack(arg))
|
||||||
|
end
|
||||||
|
|
||||||
|
local function ForceUpdate(element)
|
||||||
|
return Path(element.__owner, 'ForceUpdate', element.__owner.unit)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Enable(self, unit)
|
||||||
|
local element = self.Portrait
|
||||||
|
if(element) then
|
||||||
|
element.__owner = self
|
||||||
|
element.ForceUpdate = ForceUpdate
|
||||||
|
|
||||||
|
self:RegisterEvent('UNIT_PORTRAIT_UPDATE', Path)
|
||||||
|
self:RegisterEvent('UNIT_MODEL_CHANGED', Path)
|
||||||
|
self:RegisterEvent('UNIT_CONNECTION', Path)
|
||||||
|
|
||||||
|
-- The quest log uses PARTY_MEMBER_{ENABLE,DISABLE} to handle updating of
|
||||||
|
-- party members overlapping quests. This will probably be enough to handle
|
||||||
|
-- model updating.
|
||||||
|
--
|
||||||
|
-- DISABLE isn't used as it fires when we most likely don't have the
|
||||||
|
-- information we want.
|
||||||
|
if(unit == 'party') then
|
||||||
|
self:RegisterEvent('PARTY_MEMBER_ENABLE', Path)
|
||||||
|
end
|
||||||
|
|
||||||
|
element:Show()
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Disable(self)
|
||||||
|
local element = self.Portrait
|
||||||
|
if(element) then
|
||||||
|
element:Hide()
|
||||||
|
|
||||||
|
self:UnregisterEvent('UNIT_PORTRAIT_UPDATE', Path)
|
||||||
|
self:UnregisterEvent('UNIT_MODEL_CHANGED', Path)
|
||||||
|
self:UnregisterEvent('PARTY_MEMBER_ENABLE', Path)
|
||||||
|
self:UnregisterEvent('UNIT_CONNECTION', Path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
oUF:AddElement('Portrait', Path, Enable, Disable)
|
||||||
@@ -0,0 +1,326 @@
|
|||||||
|
--[[
|
||||||
|
# Element: Power Bar
|
||||||
|
|
||||||
|
Handles the updating of a status bar that displays the unit's power.
|
||||||
|
|
||||||
|
## Widget
|
||||||
|
|
||||||
|
Power - A `StatusBar` used to represent the unit's power.
|
||||||
|
|
||||||
|
## 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 widget is a StatusBar and doesn't have a texture or a color set.
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
.frequentUpdates - Indicates whether to use OnUpdate script instead of UNIT_POWER to update the bar. Only valid for the
|
||||||
|
player and pet units (boolean)
|
||||||
|
.smoothGradient - 9 color values to be used with the .colorSmooth option (table)
|
||||||
|
|
||||||
|
The following options are listed by priority. The first check that returns true decides the color of the bar.
|
||||||
|
|
||||||
|
.colorTapping - Use `self.colors.tapping` to color the bar if the unit isn't tapped by the player (boolean)
|
||||||
|
.colorDisconnected - Use `self.colors.disconnected` to color the bar if the unit is offline (boolean)
|
||||||
|
.colorHappiness - Use `self.colors.happiness` to color the bar if the unit is pet based on pet happiness (boolean)
|
||||||
|
.colorPower - Use `self.colors.power[token]` to color the bar based on the unit's power type. This method will
|
||||||
|
fall-back to `:GetAlternativeColor()` if it can't find a color matching the token. If this function
|
||||||
|
isn't defined, then it will attempt to color based upon the alternative power colors returned by
|
||||||
|
[UnitPowerType](http://wowprogramming.com/docs/api/UnitPowerType). Finally, if these aren't
|
||||||
|
defined, then it will attempt to color the bar based upon `self.colors.power[type]` (boolean)
|
||||||
|
.colorClass - Use `self.colors.class[class]` to color the bar based on unit class. `class` is defined by the
|
||||||
|
second return of [UnitClass](http://wowprogramming.com/docs/api/UnitClass) (boolean)
|
||||||
|
.colorClassNPC - Use `self.colors.class[class]` to color the bar if the unit is a NPC (boolean)
|
||||||
|
.colorClassPet - Use `self.colors.class[class]` to color the bar if the unit is player controlled, but not a player
|
||||||
|
(boolean)
|
||||||
|
.colorReaction - Use `self.colors.reaction[reaction]` to color the bar based on the player's reaction towards the
|
||||||
|
unit. `reaction` is defined by the return value of
|
||||||
|
[UnitReaction](http://wowprogramming.com/docs/api/UnitReaction) (boolean)
|
||||||
|
.colorSmooth - Use `smoothGradient` if present or `self.colors.smooth` to color the bar with a smooth gradient
|
||||||
|
based on the player's current power percentage (boolean)
|
||||||
|
|
||||||
|
## Sub-Widget Options
|
||||||
|
|
||||||
|
.multiplier - A multiplier used to tint the background based on the main widgets R, G and B values. Defaults to 1
|
||||||
|
(number)[0-1]
|
||||||
|
|
||||||
|
## Attributes
|
||||||
|
|
||||||
|
.disconnected - Indicates whether the unit is disconnected (boolean)
|
||||||
|
.tapped - Indicates whether the unit is tapped by the player (boolean)
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
-- Position and size
|
||||||
|
local Power = CreateFrame('StatusBar', nil, self)
|
||||||
|
Power:SetHeight(20)
|
||||||
|
Power:SetPoint('BOTTOM')
|
||||||
|
Power:SetPoint('LEFT')
|
||||||
|
Power:SetPoint('RIGHT')
|
||||||
|
|
||||||
|
-- Add a background
|
||||||
|
local Background = Power:CreateTexture(nil, 'BACKGROUND')
|
||||||
|
Background:SetAllPoints(Power)
|
||||||
|
Background:SetTexture(1, 1, 1, .5)
|
||||||
|
|
||||||
|
-- Options
|
||||||
|
Power.frequentUpdates = true
|
||||||
|
Power.colorTapping = true
|
||||||
|
Power.colorDisconnected = true
|
||||||
|
Power.colorPower = true
|
||||||
|
Power.colorClass = true
|
||||||
|
Power.colorReaction = true
|
||||||
|
|
||||||
|
-- Make the background darker.
|
||||||
|
Background.multiplier = .5
|
||||||
|
|
||||||
|
-- Register it with oUF
|
||||||
|
Power.bg = Background
|
||||||
|
self.Power = Power
|
||||||
|
--]]
|
||||||
|
|
||||||
|
local ns = oUF
|
||||||
|
local oUF = ns.oUF
|
||||||
|
|
||||||
|
local unpack = unpack
|
||||||
|
|
||||||
|
local GetPetHappiness = GetPetHappiness
|
||||||
|
local UnitClass = UnitClass
|
||||||
|
local UnitIsConnected = UnitIsConnected
|
||||||
|
local UnitIsPlayer = UnitIsPlayer
|
||||||
|
local UnitIsTapped = UnitIsTapped
|
||||||
|
local UnitIsTappedByPlayer = UnitIsTappedByPlayer
|
||||||
|
local UnitIsUnit = UnitIsUnit
|
||||||
|
local UnitMana = UnitMana
|
||||||
|
local UnitManaMax = UnitManaMax
|
||||||
|
local UnitPlayerControlled = UnitPlayerControlled
|
||||||
|
local UnitPowerType = UnitPowerType
|
||||||
|
local UnitReaction = UnitReaction
|
||||||
|
|
||||||
|
local updateFrequentUpdates
|
||||||
|
|
||||||
|
local function UpdateColor(element, unit, cur, min, max)
|
||||||
|
local parent = element.__owner
|
||||||
|
|
||||||
|
if element.frequentUpdates ~= element.__frequentUpdates then
|
||||||
|
element.__frequentUpdates = element.frequentUpdates
|
||||||
|
updateFrequentUpdates(element, unit)
|
||||||
|
end
|
||||||
|
|
||||||
|
local ptype = UnitPowerType(unit)
|
||||||
|
local r, g, b, t
|
||||||
|
if(element.colorTapping and element.tapped) then
|
||||||
|
t = parent.colors.tapped
|
||||||
|
elseif(element.colorDisconnected and element.disconnected) then
|
||||||
|
t = parent.colors.disconnected
|
||||||
|
elseif(element.colorHappiness and UnitIsUnit(unit, 'pet') and GetPetHappiness()) then
|
||||||
|
t = parent.colors.happiness[GetPetHappiness()]
|
||||||
|
elseif(element.colorPower) then
|
||||||
|
t = parent.colors.power[ptype]
|
||||||
|
elseif(element.colorClass and UnitIsPlayer(unit)) or
|
||||||
|
(element.colorClassNPC and not UnitIsPlayer(unit)) or
|
||||||
|
(element.colorClassPet and UnitPlayerControlled(unit) and not UnitIsPlayer(unit)) then
|
||||||
|
local _, class = UnitClass(unit)
|
||||||
|
t = parent.colors.class[class]
|
||||||
|
elseif(element.colorReaction and UnitReaction(unit, 'player')) then
|
||||||
|
t = parent.colors.reaction[UnitReaction(unit, 'player')]
|
||||||
|
elseif(element.colorSmooth) then
|
||||||
|
local adjust = 0 - (min or 0)
|
||||||
|
r, g, b = parent.ColorGradient(cur + adjust, max + adjust, unpack(element.smoothGradient or parent.colors.smooth))
|
||||||
|
end
|
||||||
|
|
||||||
|
if(t) then
|
||||||
|
r, g, b = t[1], t[2], t[3]
|
||||||
|
end
|
||||||
|
|
||||||
|
t = parent.colors.power[ptype]
|
||||||
|
|
||||||
|
element:SetStatusBarTexture(element.texture)
|
||||||
|
|
||||||
|
if(r or g or b) then
|
||||||
|
element:SetStatusBarColor(r, g, b)
|
||||||
|
end
|
||||||
|
|
||||||
|
local bg = element.bg
|
||||||
|
if(bg and b) then
|
||||||
|
local mu = bg.multiplier or 1
|
||||||
|
bg:SetVertexColor(r * mu, g * mu, b * mu)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Update(self, event, unit)
|
||||||
|
if(self.unit ~= unit) then return end
|
||||||
|
local element = self.Power
|
||||||
|
|
||||||
|
--[[ Callback: Power:PreUpdate(unit)
|
||||||
|
Called before the element has been updated.
|
||||||
|
|
||||||
|
* self - the Power element
|
||||||
|
* unit - the unit for which the update has been triggered (string)
|
||||||
|
--]]
|
||||||
|
if(element.PreUpdate) then
|
||||||
|
element:PreUpdate(unit)
|
||||||
|
end
|
||||||
|
|
||||||
|
local cur, max = UnitMana(unit), UnitManaMax(unit)
|
||||||
|
local disconnected = not UnitIsConnected(unit)
|
||||||
|
local tapped = not UnitPlayerControlled(unit) and (UnitIsTapped(unit) and not UnitIsTappedByPlayer(unit))
|
||||||
|
element:SetMinMaxValues(0, max)
|
||||||
|
|
||||||
|
if(disconnected) then
|
||||||
|
element:SetValue(max)
|
||||||
|
else
|
||||||
|
element:SetValue(cur)
|
||||||
|
end
|
||||||
|
|
||||||
|
element.disconnected = disconnected
|
||||||
|
element.tapped = tapped
|
||||||
|
|
||||||
|
--[[ Override: Power:UpdateColor(unit, cur, max)
|
||||||
|
Used to completely override the internal function for updating the widget's colors.
|
||||||
|
|
||||||
|
* self - the Power element
|
||||||
|
* unit - the unit for which the update has been triggered (string)
|
||||||
|
* cur - the unit's current power value (number)
|
||||||
|
* max - the unit's maximum possible power value (number)
|
||||||
|
--]]
|
||||||
|
element:UpdateColor(unit, cur, max)
|
||||||
|
|
||||||
|
--[[ Callback: Power:PostUpdate(unit, cur, max)
|
||||||
|
Called after the element has been updated.
|
||||||
|
|
||||||
|
* self - the Power element
|
||||||
|
* unit - the unit for which the update has been triggered (string)
|
||||||
|
* cur - the unit's current power value (number)
|
||||||
|
* max - the unit's maximum possible power value (number)
|
||||||
|
--]]
|
||||||
|
if(element.PostUpdate) then
|
||||||
|
return element:PostUpdate(unit, cur, max)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Path(self, ...)
|
||||||
|
--[[ Override: Power.Override(self, event, unit, ...)
|
||||||
|
Used to completely override the internal update function.
|
||||||
|
|
||||||
|
* self - the parent object
|
||||||
|
* event - the event triggering the update (string)
|
||||||
|
* unit - the unit accompanying the event (string)
|
||||||
|
* ... - the arguments accompanying the event
|
||||||
|
--]]
|
||||||
|
return (self.Power.Override or Update) (self, unpack(arg))
|
||||||
|
end
|
||||||
|
|
||||||
|
local function ForceUpdate(element)
|
||||||
|
return Path(element.__owner, 'ForceUpdate', element.__owner.unit)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function onPowerUpdate()
|
||||||
|
if(this.disconnected) then return end
|
||||||
|
|
||||||
|
local unit = this.__owner.unit
|
||||||
|
local power = UnitMana(unit)
|
||||||
|
|
||||||
|
if(power ~= this.min) then
|
||||||
|
this.min = power
|
||||||
|
|
||||||
|
return Path(this.__owner, 'OnPowerUpdate', unit)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function updateFrequentUpdates(self, unit)
|
||||||
|
if(not unit or (unit ~= 'player' and unit ~= 'pet')) then return end
|
||||||
|
|
||||||
|
local element = self.Power
|
||||||
|
if(element.frequentUpdates and not element:GetScript('OnUpdate')) then
|
||||||
|
element:SetScript('OnUpdate', onPowerUpdate)
|
||||||
|
|
||||||
|
self:UnregisterEvent('UNIT_MANA', Path)
|
||||||
|
self:UnregisterEvent('UNIT_RAGE', Path)
|
||||||
|
self:UnregisterEvent('UNIT_FOCUS', Path)
|
||||||
|
self:UnregisterEvent('UNIT_ENERGY', Path)
|
||||||
|
elseif(not element.frequentUpdates and element:GetScript('OnUpdate')) then
|
||||||
|
element:SetScript('OnUpdate', nil)
|
||||||
|
|
||||||
|
self:RegisterEvent('UNIT_MANA', Path)
|
||||||
|
self:RegisterEvent('UNIT_RAGE', Path)
|
||||||
|
self:RegisterEvent('UNIT_FOCUS', Path)
|
||||||
|
self:RegisterEvent('UNIT_ENERGY', Path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Enable(self, unit)
|
||||||
|
local element = self.Power
|
||||||
|
if(element) then
|
||||||
|
element.__owner = self
|
||||||
|
element.ForceUpdate = ForceUpdate
|
||||||
|
element.__frequentUpdates = element.frequentUpdates
|
||||||
|
updateFrequentUpdates(self, unit)
|
||||||
|
|
||||||
|
if(element.frequentUpdates and (unit == 'player' or unit == 'pet')) then
|
||||||
|
element:SetScript('OnUpdate', onPowerUpdate)
|
||||||
|
else
|
||||||
|
self:RegisterEvent('UNIT_MANA', Path)
|
||||||
|
self:RegisterEvent('UNIT_RAGE', Path)
|
||||||
|
self:RegisterEvent('UNIT_FOCUS', Path)
|
||||||
|
self:RegisterEvent('UNIT_ENERGY', Path)
|
||||||
|
end
|
||||||
|
|
||||||
|
self:RegisterEvent('UNIT_MAXMANA', Path)
|
||||||
|
self:RegisterEvent('UNIT_MAXRAGE', Path)
|
||||||
|
self:RegisterEvent('UNIT_MAXFOCUS', Path)
|
||||||
|
self:RegisterEvent('UNIT_MAXENERGY', Path)
|
||||||
|
self:RegisterEvent('UNIT_MAXRUNIC_POWER', Path)
|
||||||
|
self:RegisterEvent('UNIT_DISPLAYPOWER', Path)
|
||||||
|
|
||||||
|
self:RegisterEvent('UNIT_CONNECTION', Path)
|
||||||
|
self:RegisterEvent('UNIT_HAPPINESS', Path)
|
||||||
|
self:RegisterEvent('UNIT_FACTION', Path) -- For tapping
|
||||||
|
|
||||||
|
if(element:IsObjectType('StatusBar')) then
|
||||||
|
element.texture = element:GetStatusBarTexture() and element:GetStatusBarTexture():GetTexture() or [[Interface\TargetingFrame\UI-StatusBar]]
|
||||||
|
element:SetStatusBarTexture(element.texture)
|
||||||
|
end
|
||||||
|
|
||||||
|
if(not element.UpdateColor) then
|
||||||
|
element.UpdateColor = UpdateColor
|
||||||
|
end
|
||||||
|
|
||||||
|
element:Show()
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Disable(self)
|
||||||
|
local element = self.Power
|
||||||
|
if(element) then
|
||||||
|
element:Hide()
|
||||||
|
|
||||||
|
if(element:GetScript('OnUpdate')) then
|
||||||
|
element:SetScript('OnUpdate', nil)
|
||||||
|
else
|
||||||
|
self:UnregisterEvent('UNIT_MANA', Path)
|
||||||
|
self:UnregisterEvent('UNIT_RAGE', Path)
|
||||||
|
self:UnregisterEvent('UNIT_FOCUS', Path)
|
||||||
|
self:UnregisterEvent('UNIT_ENERGY', Path)
|
||||||
|
self:UnregisterEvent('UNIT_RUNIC_POWER', Path)
|
||||||
|
end
|
||||||
|
|
||||||
|
self:UnregisterEvent('UNIT_MAXMANA', Path)
|
||||||
|
self:UnregisterEvent('UNIT_MAXRAGE', Path)
|
||||||
|
self:UnregisterEvent('UNIT_MAXFOCUS', Path)
|
||||||
|
self:UnregisterEvent('UNIT_MAXENERGY', Path)
|
||||||
|
self:UnregisterEvent('UNIT_MAXRUNIC_POWER', Path)
|
||||||
|
self:UnregisterEvent('UNIT_DISPLAYPOWER', Path)
|
||||||
|
|
||||||
|
self:UnregisterEvent('UNIT_CONNECTION', Path)
|
||||||
|
self:UnregisterEvent('UNIT_HAPPINESS', Path)
|
||||||
|
self:UnregisterEvent('UNIT_FACTION', Path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
oUF:AddElement('Power', Path, Enable, Disable)
|
||||||
@@ -0,0 +1,118 @@
|
|||||||
|
--[[
|
||||||
|
# Element: PvP Icon
|
||||||
|
|
||||||
|
Handles the visibility and updating of an indicator based on the unit's PvP status.
|
||||||
|
|
||||||
|
## Widget
|
||||||
|
|
||||||
|
PvPIndicator - A `Texture` used to display faction, FFA PvP status icon.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
This element updates by changing the texture.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
-- Position and size
|
||||||
|
local PvPIndicator = self:CreateTexture(nil, 'ARTWORK', nil, 1)
|
||||||
|
PvPIndicator:SetSize(30, 30)
|
||||||
|
PvPIndicator:SetPoint('RIGHT', self, 'LEFT')
|
||||||
|
|
||||||
|
-- Register it with oUF
|
||||||
|
self.PvPIndicator = PvPIndicator
|
||||||
|
--]]
|
||||||
|
|
||||||
|
local ns = oUF
|
||||||
|
local oUF = ns.oUF
|
||||||
|
|
||||||
|
local UnitFactionGroup = UnitFactionGroup
|
||||||
|
local UnitIsPVP = UnitIsPVP
|
||||||
|
local UnitIsPVPFreeForAll = UnitIsPVPFreeForAll
|
||||||
|
|
||||||
|
local FFA_ICON = [[Interface\TargetingFrame\UI-PVP-FFA]]
|
||||||
|
local FACTION_ICON = [[Interface\TargetingFrame\UI-PVP-]]
|
||||||
|
|
||||||
|
local function Update(self, event, unit)
|
||||||
|
if(unit ~= self.unit) then return end
|
||||||
|
|
||||||
|
local element = self.PvPIndicator
|
||||||
|
|
||||||
|
--[[ Callback: PvPIndicator:PreUpdate(unit)
|
||||||
|
Called before the element has been updated.
|
||||||
|
|
||||||
|
* self - the PvPIndicator element
|
||||||
|
* unit - the unit for which the update has been triggered (string)
|
||||||
|
--]]
|
||||||
|
if(element.PreUpdate) then
|
||||||
|
element:PreUpdate(unit)
|
||||||
|
end
|
||||||
|
|
||||||
|
local status
|
||||||
|
local factionGroup = UnitFactionGroup(unit)
|
||||||
|
|
||||||
|
if(UnitIsPVPFreeForAll(unit)) then
|
||||||
|
element:SetTexture(FFA_ICON)
|
||||||
|
element:SetTexCoord(0, 0.65625, 0, 0.65625)
|
||||||
|
status = 'ffa'
|
||||||
|
elseif(factionGroup and factionGroup ~= 'Neutral' and UnitIsPVP(unit)) then
|
||||||
|
element:SetTexture(FACTION_ICON .. factionGroup)
|
||||||
|
element:SetTexCoord(0, 0.65625, 0, 0.65625)
|
||||||
|
status = factionGroup
|
||||||
|
end
|
||||||
|
|
||||||
|
if(status) then
|
||||||
|
element:Show()
|
||||||
|
else
|
||||||
|
element:Hide()
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[ Callback: PvPIndicator:PostUpdate(unit, status)
|
||||||
|
Called after the element has been updated.
|
||||||
|
|
||||||
|
* self - the PvPIndicator element
|
||||||
|
* unit - the unit for which the update has been triggered (string)
|
||||||
|
* status - the unit's current PvP status or faction accounting for mercenary mode (string)['ffa', 'Alliance',
|
||||||
|
'Horde']
|
||||||
|
--]]
|
||||||
|
if(element.PostUpdate) then
|
||||||
|
return element:PostUpdate(unit, status)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Path(self, ...)
|
||||||
|
--[[Override: PvPIndicator.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
|
||||||
|
--]]
|
||||||
|
return (self.PvPIndicator.Override or Update) (self, ...)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function ForceUpdate(element)
|
||||||
|
return Path(element.__owner, 'ForceUpdate', element.__owner.unit)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Enable(self)
|
||||||
|
local element = self.PvPIndicator
|
||||||
|
if(element) then
|
||||||
|
element.__owner = self
|
||||||
|
element.ForceUpdate = ForceUpdate
|
||||||
|
|
||||||
|
self:RegisterEvent('UNIT_FACTION', Path)
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Disable(self)
|
||||||
|
local element = self.PvPIndicator
|
||||||
|
if(element) then
|
||||||
|
element:Hide()
|
||||||
|
|
||||||
|
self:UnregisterEvent('UNIT_FACTION', Path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
oUF:AddElement('PvPIndicator', Path, Enable, Disable)
|
||||||
@@ -0,0 +1,114 @@
|
|||||||
|
--[[
|
||||||
|
# Element: Raid Role Indicator
|
||||||
|
|
||||||
|
Handles the visibility and updating of an indicator based on the unit's raid assignment (main tank or main assist).
|
||||||
|
|
||||||
|
## Widget
|
||||||
|
|
||||||
|
RaidRoleIndicator - A `Texture` representing the unit's raid assignment.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
This element updates by changing the texture.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
-- Position and size
|
||||||
|
local RaidRoleIndicator = self:CreateTexture(nil, 'OVERLAY')
|
||||||
|
RaidRoleIndicator:SetSize(16, 16)
|
||||||
|
RaidRoleIndicator:SetPoint('TOPLEFT')
|
||||||
|
|
||||||
|
-- Register it with oUF
|
||||||
|
self.RaidRoleIndicator = RaidRoleIndicator
|
||||||
|
--]]
|
||||||
|
|
||||||
|
local ns = oUF
|
||||||
|
local oUF = ns.oUF
|
||||||
|
|
||||||
|
local GetPartyAssignment = GetPartyAssignment
|
||||||
|
local UnitInRaid = UnitInRaid
|
||||||
|
|
||||||
|
local MAINTANK_ICON = [[Interface\GROUPFRAME\UI-GROUP-MAINTANKICON]]
|
||||||
|
local MAINASSIST_ICON = [[Interface\GROUPFRAME\UI-GROUP-MAINASSISTICON]]
|
||||||
|
|
||||||
|
local function Update(self, event)
|
||||||
|
local unit = self.unit
|
||||||
|
|
||||||
|
local element = self.RaidRoleIndicator
|
||||||
|
|
||||||
|
--[[ Callback: RaidRoleIndicator:PreUpdate()
|
||||||
|
Called before the element has been updated.
|
||||||
|
|
||||||
|
* self - the RaidRoleIndicator element
|
||||||
|
--]]
|
||||||
|
if(element.PreUpdate) then
|
||||||
|
element:PreUpdate()
|
||||||
|
end
|
||||||
|
|
||||||
|
local role, isShown
|
||||||
|
if(UnitInRaid(unit)) then
|
||||||
|
if(GetPartyAssignment('MAINTANK', unit)) then
|
||||||
|
isShown = true
|
||||||
|
element:SetTexture(MAINTANK_ICON)
|
||||||
|
role = 'MAINTANK'
|
||||||
|
elseif(GetPartyAssignment('MAINASSIST', unit)) then
|
||||||
|
isShown = true
|
||||||
|
element:SetTexture(MAINASSIST_ICON)
|
||||||
|
role = 'MAINASSIST'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if isShown then
|
||||||
|
element:Show()
|
||||||
|
else
|
||||||
|
element:Hide()
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[ Callback: RaidRoleIndicator:PostUpdate(role)
|
||||||
|
Called after the element has been updated.
|
||||||
|
|
||||||
|
* self - the RaidRoleIndicator element
|
||||||
|
* role - the unit's raid assignment (string?)['MAINTANK', 'MAINASSIST']
|
||||||
|
--]]
|
||||||
|
if(element.PostUpdate) then
|
||||||
|
return element:PostUpdate(role)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Path(self, ...)
|
||||||
|
--[[ Override: RaidRoleIndicator.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
|
||||||
|
--]]
|
||||||
|
return (self.RaidRoleIndicator.Override or Update)(self, ...)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function ForceUpdate(element)
|
||||||
|
return Path(element.__owner, 'ForceUpdate')
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Enable(self)
|
||||||
|
local element = self.RaidRoleIndicator
|
||||||
|
if(element) then
|
||||||
|
element.__owner = self
|
||||||
|
element.ForceUpdate = ForceUpdate
|
||||||
|
|
||||||
|
self:RegisterEvent('PARTY_MEMBERS_CHANGED', Path, true)
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Disable(self)
|
||||||
|
local element = self.RaidRoleIndicator
|
||||||
|
if(element) then
|
||||||
|
element:Hide()
|
||||||
|
|
||||||
|
self:UnregisterEvent('PARTY_MEMBERS_CHANGED', Path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
oUF:AddElement('RaidRoleIndicator', Path, Enable, Disable)
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
--[[
|
||||||
|
# Element: Raid Target Indicator
|
||||||
|
|
||||||
|
Handles the visibility and updating of an indicator based on the unit's raid target assignment.
|
||||||
|
|
||||||
|
## Widget
|
||||||
|
|
||||||
|
RaidTargetIndicator - A `Texture` used to display the raid target icon.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
A default texture will be applied if the widget is a Texture and doesn't have a texture set.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
-- Position and size
|
||||||
|
local RaidTargetIndicator = self:CreateTexture(nil, 'OVERLAY')
|
||||||
|
RaidTargetIndicator:SetSize(16, 16)
|
||||||
|
RaidTargetIndicator:SetPoint('TOPRIGHT', self)
|
||||||
|
|
||||||
|
-- Register it with oUF
|
||||||
|
self.RaidTargetIndicator = RaidTargetIndicator
|
||||||
|
--]]
|
||||||
|
|
||||||
|
local ns = oUF
|
||||||
|
local oUF = ns.oUF
|
||||||
|
|
||||||
|
local GetRaidTargetIndex = GetRaidTargetIndex
|
||||||
|
local SetRaidTargetIconTexture = SetRaidTargetIconTexture
|
||||||
|
|
||||||
|
local function Update(self, event)
|
||||||
|
local element = self.RaidTargetIndicator
|
||||||
|
|
||||||
|
--[[ Callback: RaidTargetIndicator:PreUpdate()
|
||||||
|
Called before the element has been updated.
|
||||||
|
|
||||||
|
* self - the RaidTargetIndicator element
|
||||||
|
--]]
|
||||||
|
if(element.PreUpdate) then
|
||||||
|
element:PreUpdate()
|
||||||
|
end
|
||||||
|
|
||||||
|
local index = GetRaidTargetIndex(self.unit)
|
||||||
|
if(index) then
|
||||||
|
SetRaidTargetIconTexture(element, index)
|
||||||
|
element:Show()
|
||||||
|
else
|
||||||
|
element:Hide()
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[ Callback: RaidTargetIndicator:PostUpdate(index)
|
||||||
|
Called after the element has been updated.
|
||||||
|
|
||||||
|
* self - the RaidTargetIndicator element
|
||||||
|
* index - the index of the raid target marker (number?)[1-8]
|
||||||
|
--]]
|
||||||
|
if(element.PostUpdate) then
|
||||||
|
return element:PostUpdate(index)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Path(self, ...)
|
||||||
|
--[[ Override: RaidTargetIndicator.Override(self, event)
|
||||||
|
Used to completely override the internal update function.
|
||||||
|
|
||||||
|
* self - the parent object
|
||||||
|
* event - the event triggering the update (string)
|
||||||
|
--]]
|
||||||
|
return (self.RaidTargetIndicator.Override or Update) (self, ...)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function ForceUpdate(element)
|
||||||
|
if(not element.__owner.unit) then return end
|
||||||
|
return Path(element.__owner, 'ForceUpdate')
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Enable(self)
|
||||||
|
local element = self.RaidTargetIndicator
|
||||||
|
if(element) then
|
||||||
|
element.__owner = self
|
||||||
|
element.ForceUpdate = ForceUpdate
|
||||||
|
|
||||||
|
self:RegisterEvent('RAID_TARGET_UPDATE', Path, true)
|
||||||
|
|
||||||
|
if(element:IsObjectType('Texture') and not element:GetTexture()) then
|
||||||
|
element:SetTexture([[Interface\TargetingFrame\UI-RaidTargetingIcons]])
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Disable(self)
|
||||||
|
local element = self.RaidTargetIndicator
|
||||||
|
if(element) then
|
||||||
|
element:Hide()
|
||||||
|
|
||||||
|
self:UnregisterEvent('RAID_TARGET_UPDATE', Path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
oUF:AddElement('RaidTargetIndicator', Path, Enable, Disable)
|
||||||
@@ -0,0 +1,137 @@
|
|||||||
|
--[[
|
||||||
|
# Element: Range Fader
|
||||||
|
|
||||||
|
Changes the opacity of a unit frame based on whether the frame's unit is in the player's range.
|
||||||
|
|
||||||
|
## Widget
|
||||||
|
|
||||||
|
Range - A table containing opacity values.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
Offline units are handled as if they are in range.
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
.outsideAlpha - Opacity when the unit is out of range. Defaults to 0.55 (number)[0-1].
|
||||||
|
.insideAlpha - Opacity when the unit is within range. Defaults to 1 (number)[0-1].
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
-- Register with oUF
|
||||||
|
self.Range = {
|
||||||
|
insideAlpha = 1,
|
||||||
|
outsideAlpha = 1/2,
|
||||||
|
}
|
||||||
|
--]]
|
||||||
|
|
||||||
|
local ns = oUF
|
||||||
|
local oUF = ns.oUF
|
||||||
|
|
||||||
|
local _FRAMES = {}
|
||||||
|
local OnRangeFrame
|
||||||
|
|
||||||
|
local UnitInRange, UnitIsConnected = UnitInRange, UnitIsConnected
|
||||||
|
|
||||||
|
local function Update(self, event)
|
||||||
|
local element = self.Range
|
||||||
|
local unit = self.unit
|
||||||
|
|
||||||
|
--[[ Callback: Range:PreUpdate()
|
||||||
|
Called before the element has been updated.
|
||||||
|
|
||||||
|
* self - the Range element
|
||||||
|
--]]
|
||||||
|
if(element.PreUpdate) then
|
||||||
|
element:PreUpdate()
|
||||||
|
end
|
||||||
|
|
||||||
|
local inRange
|
||||||
|
local connected = UnitIsConnected(unit)
|
||||||
|
if(connected) then
|
||||||
|
inRange = UnitInRange(unit)
|
||||||
|
if(not inRange) then
|
||||||
|
self:SetAlpha(element.outsideAlpha)
|
||||||
|
else
|
||||||
|
self:SetAlpha(element.insideAlpha)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
self:SetAlpha(element.insideAlpha)
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[ Callback: Range:PostUpdate(object, inRange, isConnected)
|
||||||
|
Called after the element has been updated.
|
||||||
|
|
||||||
|
* self - the Range element
|
||||||
|
* object - the parent object
|
||||||
|
* inRange - indicates if the unit was within 40 yards of the player (boolean)
|
||||||
|
* isConnected - indicates if the unit is online (boolean)
|
||||||
|
--]]
|
||||||
|
if(element.PostUpdate) then
|
||||||
|
return element:PostUpdate(self, inRange, connected)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Path(self, ...)
|
||||||
|
--[[ Override: Range.Override(self, event)
|
||||||
|
Used to completely override the internal update function.
|
||||||
|
|
||||||
|
* self - the parent object
|
||||||
|
* event - the event triggering the update (string)
|
||||||
|
--]]
|
||||||
|
return (self.Range.Override or Update) (self, ...)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Internal updating method
|
||||||
|
local timer = 0
|
||||||
|
local function OnRangeUpdate(_, elapsed)
|
||||||
|
timer = timer + elapsed
|
||||||
|
|
||||||
|
if(timer >= .20) then
|
||||||
|
for _, object in next, _FRAMES do
|
||||||
|
if(object:IsShown()) then
|
||||||
|
Path(object, 'OnUpdate')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
timer = 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Enable(self)
|
||||||
|
local element = self.Range
|
||||||
|
if(element) then
|
||||||
|
element.__owner = self
|
||||||
|
element.insideAlpha = element.insideAlpha or 1
|
||||||
|
element.outsideAlpha = element.outsideAlpha or 0.55
|
||||||
|
|
||||||
|
if(not OnRangeFrame) then
|
||||||
|
OnRangeFrame = CreateFrame('Frame')
|
||||||
|
OnRangeFrame:SetScript('OnUpdate', OnRangeUpdate)
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(_FRAMES, self)
|
||||||
|
OnRangeFrame:Show()
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Disable(self)
|
||||||
|
local element = self.Range
|
||||||
|
if(element) then
|
||||||
|
for index, frame in next, _FRAMES do
|
||||||
|
if(frame == self) then
|
||||||
|
table.remove(_FRAMES, index)
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
self:SetAlpha(element.insideAlpha)
|
||||||
|
|
||||||
|
if(#_FRAMES == 0) then
|
||||||
|
OnRangeFrame:Hide()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
oUF:AddElement('Range', nil, Enable, Disable)
|
||||||
@@ -0,0 +1,150 @@
|
|||||||
|
--[[
|
||||||
|
# Element: Ready Check Indicator
|
||||||
|
|
||||||
|
Handles the visibility and updating of an indicator based on the unit's ready check status.
|
||||||
|
|
||||||
|
## Widget
|
||||||
|
|
||||||
|
ReadyCheckIndicator - A `Texture` representing ready check status.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
This element updates by changing the texture.
|
||||||
|
Default textures will be applied if the layout does not provide custom ones. See Options.
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
.finishedTime - For how many seconds the icon should stick after a check has completed. Defaults to 10 (number).
|
||||||
|
.fadeTime - For how many seconds the icon should fade away after the stick duration has completed. Defaults to
|
||||||
|
1.5 (number).
|
||||||
|
.readyTexture - Path to an alternate texture for the ready check 'ready' status.
|
||||||
|
.notReadyTexture - Path to an alternate texture for the ready check 'notready' status.
|
||||||
|
.waitingTexture - Path to an alternate texture for the ready check 'waiting' status.
|
||||||
|
|
||||||
|
## Attributes
|
||||||
|
|
||||||
|
.status - the unit's ready check status (string?)['ready', 'noready', 'waiting']
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
-- Position and size
|
||||||
|
local ReadyCheckIndicator = self:CreateTexture(nil, 'OVERLAY')
|
||||||
|
ReadyCheckIndicator:SetSize(16, 16)
|
||||||
|
ReadyCheckIndicator:SetPoint('TOP')
|
||||||
|
|
||||||
|
-- Register with oUF
|
||||||
|
self.ReadyCheckIndicator = ReadyCheckIndicator
|
||||||
|
--]]
|
||||||
|
|
||||||
|
local ns = oUF
|
||||||
|
local oUF = ns.oUF
|
||||||
|
|
||||||
|
local GetReadyCheckStatus = GetReadyCheckStatus
|
||||||
|
local UnitExists = UnitExists
|
||||||
|
|
||||||
|
local function OnFinished(self)
|
||||||
|
local element = self:GetParent()
|
||||||
|
element:Hide()
|
||||||
|
|
||||||
|
--[[ Callback: ReadyCheckIndicator:PostUpdateFadeOut()
|
||||||
|
Called after the element has been faded out.
|
||||||
|
|
||||||
|
* self - the ReadyCheckIndicator element
|
||||||
|
--]]
|
||||||
|
if(element.PostUpdateFadeOut) then
|
||||||
|
element:PostUpdateFadeOut()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Update(self, event)
|
||||||
|
local element = self.ReadyCheckIndicator
|
||||||
|
|
||||||
|
--[[ Callback: ReadyCheckIndicator:PreUpdate()
|
||||||
|
Called before the element has been updated.
|
||||||
|
|
||||||
|
* self - the ReadyCheckIndicator element
|
||||||
|
--]]
|
||||||
|
if(element.PreUpdate) then
|
||||||
|
element:PreUpdate()
|
||||||
|
end
|
||||||
|
|
||||||
|
local unit = self.unit
|
||||||
|
local status = GetReadyCheckStatus(unit)
|
||||||
|
if(UnitExists(unit) and status) then
|
||||||
|
if(status == 'ready') then
|
||||||
|
element:SetTexture(element.readyTexture)
|
||||||
|
elseif(status == 'notready') then
|
||||||
|
element:SetTexture(element.notReadyTexture)
|
||||||
|
else
|
||||||
|
element:SetTexture(element.waitingTexture)
|
||||||
|
end
|
||||||
|
|
||||||
|
element.status = status
|
||||||
|
element:Show()
|
||||||
|
elseif(event ~= 'READY_CHECK_FINISHED') then
|
||||||
|
element.status = nil
|
||||||
|
element:Hide()
|
||||||
|
end
|
||||||
|
|
||||||
|
if(event == 'READY_CHECK_FINISHED') then
|
||||||
|
if(element.status == 'waiting') then
|
||||||
|
element:SetTexture(element.notReadyTexture)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[ Callback: ReadyCheckIndicator:PostUpdate(status)
|
||||||
|
Called after the element has been updated.
|
||||||
|
|
||||||
|
* self - the ReadyCheckIndicator element
|
||||||
|
* status - the unit's ready check status (string?)['ready', 'notready', 'waiting']
|
||||||
|
--]]
|
||||||
|
if(element.PostUpdate) then
|
||||||
|
return element:PostUpdate(status)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Path(self, ...)
|
||||||
|
--[[ Override: ReadyCheckIndicator.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
|
||||||
|
--]]
|
||||||
|
return (self.ReadyCheckIndicator.Override or Update) (self, ...)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function ForceUpdate(element)
|
||||||
|
return Path(element.__owner, 'ForceUpdate')
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Enable(self, unit)
|
||||||
|
local element = self.ReadyCheckIndicator
|
||||||
|
if(element and (unit and (unit:sub(1, 5) == 'party' or unit:sub(1, 4) == 'raid'))) then
|
||||||
|
element.__owner = self
|
||||||
|
element.ForceUpdate = ForceUpdate
|
||||||
|
|
||||||
|
element.readyTexture = element.readyTexture or READY_CHECK_READY_TEXTURE
|
||||||
|
element.notReadyTexture = element.notReadyTexture or READY_CHECK_NOT_READY_TEXTURE
|
||||||
|
element.waitingTexture = element.waitingTexture or READY_CHECK_WAITING_TEXTURE
|
||||||
|
|
||||||
|
self:RegisterEvent('READY_CHECK', Path, true)
|
||||||
|
self:RegisterEvent('READY_CHECK_CONFIRM', Path, true)
|
||||||
|
self:RegisterEvent('READY_CHECK_FINISHED', Path, true)
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Disable(self)
|
||||||
|
local element = self.ReadyCheckIndicator
|
||||||
|
if(element) then
|
||||||
|
element:Hide()
|
||||||
|
|
||||||
|
self:UnregisterEvent('READY_CHECK', Path)
|
||||||
|
self:UnregisterEvent('READY_CHECK_CONFIRM', Path)
|
||||||
|
self:UnregisterEvent('READY_CHECK_FINISHED', Path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
oUF:AddElement('ReadyCheckIndicator', Path, Enable, Disable)
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
--[[
|
||||||
|
# Element: Resting Indicator
|
||||||
|
|
||||||
|
Toggles the visibility of an indicator based on the player's resting status.
|
||||||
|
|
||||||
|
## Widget
|
||||||
|
|
||||||
|
RestingIndicator - Any UI widget.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
A default texture will be applied if the widget is a Texture and doesn't have a texture or a color set.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
-- Position and size
|
||||||
|
local RestingIndicator = self:CreateTexture(nil, 'OVERLAY')
|
||||||
|
RestingIndicator:SetSize(16, 16)
|
||||||
|
RestingIndicator:SetPoint('TOPLEFT', self)
|
||||||
|
|
||||||
|
-- Register it with oUF
|
||||||
|
self.RestingIndicator = RestingIndicator
|
||||||
|
--]]
|
||||||
|
|
||||||
|
local ns = oUF
|
||||||
|
local oUF = ns.oUF
|
||||||
|
|
||||||
|
local IsResting = IsResting
|
||||||
|
|
||||||
|
local function Update(self, event)
|
||||||
|
local element = self.RestingIndicator
|
||||||
|
|
||||||
|
--[[ Callback: RestingIndicator:PreUpdate()
|
||||||
|
Called before the element has been updated.
|
||||||
|
|
||||||
|
* self - the RestingIndicator element
|
||||||
|
--]]
|
||||||
|
if(element.PreUpdate) then
|
||||||
|
element:PreUpdate()
|
||||||
|
end
|
||||||
|
|
||||||
|
local isResting = IsResting()
|
||||||
|
if(isResting) then
|
||||||
|
element:Show()
|
||||||
|
else
|
||||||
|
element:Hide()
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[ Callback: RestingIndicator:PostUpdate(isResting)
|
||||||
|
Called after the element has been updated.
|
||||||
|
|
||||||
|
* self - the RestingIndicator element
|
||||||
|
* isResting - indicates if the player is resting (boolean)
|
||||||
|
--]]
|
||||||
|
if(element.PostUpdate) then
|
||||||
|
return element:PostUpdate(isResting)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Path(self, ...)
|
||||||
|
--[[ Override: RestingIndicator.Override(self, event)
|
||||||
|
Used to completely override the internal update function.
|
||||||
|
|
||||||
|
* self - the parent object
|
||||||
|
* event - the event triggering the update (string)
|
||||||
|
--]]
|
||||||
|
return (self.RestingIndicator.Override or Update) (self, ...)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function ForceUpdate(element)
|
||||||
|
return Path(element.__owner, 'ForceUpdate')
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Enable(self, unit)
|
||||||
|
local element = self.RestingIndicator
|
||||||
|
if(element and unit == 'player') then
|
||||||
|
element.__owner = self
|
||||||
|
element.ForceUpdate = ForceUpdate
|
||||||
|
|
||||||
|
self:RegisterEvent('PLAYER_UPDATE_RESTING', Path, true)
|
||||||
|
|
||||||
|
if(element:IsObjectType('Texture') and not element:GetTexture()) then
|
||||||
|
element:SetTexture([[Interface\CharacterFrame\UI-StateIcon]])
|
||||||
|
element:SetTexCoord(0, 0.5, 0, 0.421875)
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Disable(self)
|
||||||
|
local element = self.RestingIndicator
|
||||||
|
if(element) then
|
||||||
|
element:Hide()
|
||||||
|
|
||||||
|
self:UnregisterEvent('PLAYER_UPDATE_RESTING', Path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
oUF:AddElement('RestingIndicator', Path, Enable, Disable)
|
||||||
@@ -0,0 +1,828 @@
|
|||||||
|
-- Credits: Vika, Cladhaire, Tekkub
|
||||||
|
--[[
|
||||||
|
# Element: Tags
|
||||||
|
|
||||||
|
Provides a system for text-based display of information by binding a tag string to a font string widget which in turn is
|
||||||
|
tied to a unit frame.
|
||||||
|
|
||||||
|
## Widget
|
||||||
|
|
||||||
|
A FontString to hold a tag string. Unlike other elements, this widget must not have a preset name.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
A `Tag` is a Lua string consisting of a function name surrounded by square brackets. The tag will be replaced by the
|
||||||
|
output of the function and displayed as text on the font string widget with that the tag has been registered. Literals
|
||||||
|
can be pre- or appended by separating them with a `>` before or `<` after the function name. The literals will be only
|
||||||
|
displayed when the function returns a non-nil value. I.e. `"[perhp<%]"` will display the current health as a percentage
|
||||||
|
of the maximum health followed by the % sign.
|
||||||
|
|
||||||
|
A `Tag String` is a Lua string consisting of one or multiple tags with optional literals between them. Each tag will be
|
||||||
|
updated individually and the output will follow the tags order. Literals will be displayed in the output string
|
||||||
|
regardless of whether the surrounding tag functions return a value. I.e. `"[curhp]/[maxhp]"` will resolve to something
|
||||||
|
like `2453/5000`.
|
||||||
|
|
||||||
|
A `Tag Function` is used to replace a single tag in a tag string by its output. A tag function receives only two
|
||||||
|
arguments - the unit and the realUnit of the unit frame used to register the tag (see Options for further details). The
|
||||||
|
tag function is called when the unit frame is shown or when a specified event has fired. It the tag is registered on an
|
||||||
|
eventless frame (i.e. one holding the unit "targettarget"), then the tag function is called in a set time interval.
|
||||||
|
|
||||||
|
A number of built-in tag functions exist. The layout can also define its own tag functions by adding them to the
|
||||||
|
`oUF.Tags.Methods` table. The events upon which the function will be called are specified in a white-space separated
|
||||||
|
list added to the `oUF.Tags.Events` table. Should an event fire without unit information, then it should also be listed
|
||||||
|
in the `oUF.Tags.SharedEvents` table as follows: `oUF.Tags.SharedEvents.EVENT_NAME = true`.
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
.overrideUnit - if specified on the font string widget, the frame's realUnit will be passed as the second argument to
|
||||||
|
every tag function whose name is contained in the relevant tag string. Otherwise the second argument
|
||||||
|
is always nil (boolean)
|
||||||
|
.frequentUpdates - defines how often the correspondig tag function(s) should be called. This will override the events for
|
||||||
|
the tag(s), if any. If the value is a number, it is taken as a time interval in seconds. If the value
|
||||||
|
is a boolean, the time interval is set to 0.5 seconds (number or boolean)
|
||||||
|
|
||||||
|
## Attributes
|
||||||
|
|
||||||
|
.parent - the unit frame on which the tag has been registered
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
-- define the tag function
|
||||||
|
oUF.Tags.Methods['mylayout:threatname'] = function(unit, realUnit)
|
||||||
|
local color = _TAGS['threatcolor'](unit)
|
||||||
|
local name = _TAGS['name'](unit, realUnit)
|
||||||
|
return string.format('%s%s|r', color, name)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- add the events
|
||||||
|
oUF.Tags.Events['mylayout:threatname'] = 'UNIT_NAME_UPDATE UNIT_THREAT_SITUATION_UPDATE'
|
||||||
|
|
||||||
|
-- create the text widget
|
||||||
|
local info = self.Health:CreateFontString(nil, 'OVERLAY', 'GameFontNormal')
|
||||||
|
info:SetPoint('LEFT')
|
||||||
|
|
||||||
|
-- register the tag on the text widget with oUF
|
||||||
|
self:Tag(info, '[mylayout:threatname]')
|
||||||
|
--]]
|
||||||
|
|
||||||
|
local ns = oUF
|
||||||
|
local oUF = ns.oUF
|
||||||
|
|
||||||
|
local _G = _G
|
||||||
|
local unpack = unpack
|
||||||
|
local floor = math.floor
|
||||||
|
local format = string.format
|
||||||
|
local tinsert, tremove = table.insert, table.remove
|
||||||
|
|
||||||
|
local GetComboPoints = GetComboPoints
|
||||||
|
local GetNumRaidMembers = GetNumRaidMembers
|
||||||
|
local GetPetHappiness = GetPetHappiness
|
||||||
|
local GetQuestDifficultyColor = GetQuestDifficultyColor
|
||||||
|
local GetRaidRosterInfo = GetRaidRosterInfo
|
||||||
|
local IsResting = IsResting
|
||||||
|
local UnitCanAttack = UnitCanAttack
|
||||||
|
local UnitClass = UnitClass
|
||||||
|
local UnitClassification = UnitClassification
|
||||||
|
local UnitCreatureFamily = UnitCreatureFamily
|
||||||
|
local UnitCreatureType = UnitCreatureType
|
||||||
|
local UnitFactionGroup = UnitFactionGroup
|
||||||
|
local UnitIsConnected = UnitIsConnected
|
||||||
|
local UnitIsDead = UnitIsDead
|
||||||
|
local UnitIsGhost = UnitIsGhost
|
||||||
|
local UnitIsPVP = UnitIsPVP
|
||||||
|
local UnitIsPartyLeader = UnitIsPartyLeader
|
||||||
|
local UnitIsPlayer = UnitIsPlayer
|
||||||
|
local UnitLevel = UnitLevel
|
||||||
|
local UnitMana = UnitMana
|
||||||
|
local UnitManaMax = UnitManaMax
|
||||||
|
local UnitName = UnitName
|
||||||
|
local UnitPowerType = UnitPowerType
|
||||||
|
local UnitRace = UnitRace
|
||||||
|
local UnitSex = UnitSex
|
||||||
|
|
||||||
|
local _PATTERN = '%[..-%]+'
|
||||||
|
|
||||||
|
local _ENV = {
|
||||||
|
Hex = function(r, g, b)
|
||||||
|
if(type(r) == 'table') then
|
||||||
|
if(r.r) then
|
||||||
|
r, g, b = r.r, r.g, r.b
|
||||||
|
else
|
||||||
|
r, g, b = unpack(r)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not r or type(r) == 'string' then
|
||||||
|
return '|cffFFFFFF'
|
||||||
|
end
|
||||||
|
return format('|cff%02x%02x%02x', r * 255, g * 255, b * 255)
|
||||||
|
end,
|
||||||
|
ColorGradient = oUF.ColorGradient,
|
||||||
|
}
|
||||||
|
local _PROXY = setmetatable(_ENV, {__index = _G})
|
||||||
|
|
||||||
|
local tagStrings = {
|
||||||
|
['creature'] = [[function(u)
|
||||||
|
return UnitCreatureFamily(u) or UnitCreatureType(u)
|
||||||
|
end]],
|
||||||
|
|
||||||
|
['dead'] = [[function(u)
|
||||||
|
if(UnitIsDead(u)) then
|
||||||
|
return 'Dead'
|
||||||
|
elseif(UnitIsGhost(u)) then
|
||||||
|
return 'Ghost'
|
||||||
|
end
|
||||||
|
end]],
|
||||||
|
|
||||||
|
['difficulty'] = [[function(u)
|
||||||
|
if UnitCanAttack('player', u) then
|
||||||
|
local l = UnitLevel(u)
|
||||||
|
return Hex(GetQuestDifficultyColor((l > 0) and l or 999))
|
||||||
|
end
|
||||||
|
end]],
|
||||||
|
|
||||||
|
['leader'] = [[function(u)
|
||||||
|
if(UnitIsPartyLeader(u)) then
|
||||||
|
return 'L'
|
||||||
|
end
|
||||||
|
end]],
|
||||||
|
|
||||||
|
['leaderlong'] = [[function(u)
|
||||||
|
if(UnitIsPartyLeader(u)) then
|
||||||
|
return 'Leader'
|
||||||
|
end
|
||||||
|
end]],
|
||||||
|
|
||||||
|
['level'] = [[function(u)
|
||||||
|
local l = UnitLevel(u)
|
||||||
|
if(l > 0) then
|
||||||
|
return l
|
||||||
|
else
|
||||||
|
return '??'
|
||||||
|
end
|
||||||
|
end]],
|
||||||
|
|
||||||
|
['missinghp'] = [[function(u)
|
||||||
|
local current = UnitHealthMax(u) - UnitHealth(u)
|
||||||
|
if(current > 0) then
|
||||||
|
return current
|
||||||
|
end
|
||||||
|
end]],
|
||||||
|
|
||||||
|
['missingpp'] = [[function(u)
|
||||||
|
local current = UnitManaMax(u) - UnitMana(u)
|
||||||
|
if(current > 0) then
|
||||||
|
return current
|
||||||
|
end
|
||||||
|
end]],
|
||||||
|
|
||||||
|
['name'] = [[function(u, r)
|
||||||
|
return UnitName(r or u)
|
||||||
|
end]],
|
||||||
|
|
||||||
|
['offline'] = [[function(u)
|
||||||
|
if(not UnitIsConnected(u)) then
|
||||||
|
return 'Offline'
|
||||||
|
end
|
||||||
|
end]],
|
||||||
|
|
||||||
|
['perhp'] = [[function(u)
|
||||||
|
local m = UnitHealthMax(u)
|
||||||
|
if(m == 0) then
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
return floor(UnitHealth(u) / m * 100 + .5)
|
||||||
|
end
|
||||||
|
end]],
|
||||||
|
|
||||||
|
['perpp'] = [[function(u)
|
||||||
|
local m = UnitManaMax(u)
|
||||||
|
if(m == 0) then
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
return floor(UnitMana(u) / m * 100 + .5)
|
||||||
|
end
|
||||||
|
end]],
|
||||||
|
|
||||||
|
['plus'] = [[function(u)
|
||||||
|
local c = UnitClassification(u)
|
||||||
|
if(c == 'elite' or c == 'rareelite') then
|
||||||
|
return '+'
|
||||||
|
end
|
||||||
|
end]],
|
||||||
|
|
||||||
|
['pvp'] = [[function(u)
|
||||||
|
if(UnitIsPVP(u)) then
|
||||||
|
return 'PvP'
|
||||||
|
end
|
||||||
|
end]],
|
||||||
|
|
||||||
|
['raidcolor'] = [[function(u)
|
||||||
|
local _, x = UnitClass(u)
|
||||||
|
if(x) then
|
||||||
|
return Hex(_COLORS.class[x])
|
||||||
|
end
|
||||||
|
end]],
|
||||||
|
|
||||||
|
['rare'] = [[function(u)
|
||||||
|
local c = UnitClassification(u)
|
||||||
|
if(c == 'rare' or c == 'rareelite') then
|
||||||
|
return 'Rare'
|
||||||
|
end
|
||||||
|
end]],
|
||||||
|
|
||||||
|
['resting'] = [[function(u)
|
||||||
|
if(u == 'player' and IsResting()) then
|
||||||
|
return 'zzz'
|
||||||
|
end
|
||||||
|
end]],
|
||||||
|
|
||||||
|
['sex'] = [[function(u)
|
||||||
|
local s = UnitSex(u)
|
||||||
|
if(s == 2) then
|
||||||
|
return 'Male'
|
||||||
|
elseif(s == 3) then
|
||||||
|
return 'Female'
|
||||||
|
end
|
||||||
|
end]],
|
||||||
|
|
||||||
|
['smartclass'] = [[function(u)
|
||||||
|
if(UnitIsPlayer(u)) then
|
||||||
|
return _TAGS['class'](u)
|
||||||
|
end
|
||||||
|
|
||||||
|
return _TAGS['creature'](u)
|
||||||
|
end]],
|
||||||
|
|
||||||
|
['status'] = [[function(u)
|
||||||
|
if(UnitIsDead(u)) then
|
||||||
|
return 'Dead'
|
||||||
|
elseif(UnitIsGhost(u)) then
|
||||||
|
return 'Ghost'
|
||||||
|
elseif(not UnitIsConnected(u)) then
|
||||||
|
return 'Offline'
|
||||||
|
else
|
||||||
|
return _TAGS['resting'](u)
|
||||||
|
end
|
||||||
|
end]],
|
||||||
|
|
||||||
|
['cpoints'] = [[function(u)
|
||||||
|
local cp = GetComboPoints('player', 'target')
|
||||||
|
if(cp > 0) then
|
||||||
|
return cp
|
||||||
|
end
|
||||||
|
end]],
|
||||||
|
|
||||||
|
['smartlevel'] = [[function(u)
|
||||||
|
local c = UnitClassification(u)
|
||||||
|
if(c == 'worldboss') then
|
||||||
|
return 'Boss'
|
||||||
|
else
|
||||||
|
local plus = _TAGS['plus'](u)
|
||||||
|
local level = _TAGS['level'](u)
|
||||||
|
if(plus) then
|
||||||
|
return level .. plus
|
||||||
|
else
|
||||||
|
return level
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end]],
|
||||||
|
|
||||||
|
['classification'] = [[function(u)
|
||||||
|
local c = UnitClassification(u)
|
||||||
|
if(c == 'rare') then
|
||||||
|
return 'Rare'
|
||||||
|
elseif(c == 'rareelite') then
|
||||||
|
return 'Rare Elite'
|
||||||
|
elseif(c == 'elite') then
|
||||||
|
return 'Elite'
|
||||||
|
elseif(c == 'worldboss') then
|
||||||
|
return 'Boss'
|
||||||
|
end
|
||||||
|
end]],
|
||||||
|
|
||||||
|
['shortclassification'] = [[function(u)
|
||||||
|
local c = UnitClassification(u)
|
||||||
|
if(c == 'rare') then
|
||||||
|
return 'R'
|
||||||
|
elseif(c == 'rareelite') then
|
||||||
|
return 'R+'
|
||||||
|
elseif(c == 'elite') then
|
||||||
|
return '+'
|
||||||
|
elseif(c == 'worldboss') then
|
||||||
|
return 'B'
|
||||||
|
end
|
||||||
|
end]],
|
||||||
|
|
||||||
|
['group'] = [[function(unit)
|
||||||
|
local name, server = UnitName(unit)
|
||||||
|
if(server and server ~= '') then
|
||||||
|
name = format('%s-%s', name, server)
|
||||||
|
end
|
||||||
|
|
||||||
|
for i=1, GetNumRaidMembers() do
|
||||||
|
local raidName, _, group = GetRaidRosterInfo(i)
|
||||||
|
if(raidName == name) then
|
||||||
|
return group
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end]],
|
||||||
|
|
||||||
|
['deficit:name'] = [[function(u)
|
||||||
|
local missinghp = _TAGS['missinghp'](u)
|
||||||
|
if(missinghp) then
|
||||||
|
return '-' .. missinghp
|
||||||
|
else
|
||||||
|
return _TAGS['name'](u)
|
||||||
|
end
|
||||||
|
end]],
|
||||||
|
|
||||||
|
['curmana'] = [[function(unit)
|
||||||
|
return UnitMana(unit, SPELL_POWER_MANA)
|
||||||
|
end]],
|
||||||
|
|
||||||
|
['maxmana'] = [[function(unit)
|
||||||
|
return UnitManaMax(unit, SPELL_POWER_MANA)
|
||||||
|
end]],
|
||||||
|
|
||||||
|
['happiness'] = [[function(u)
|
||||||
|
if(UnitIsUnit(u, 'pet')) then
|
||||||
|
local happiness = GetPetHappiness()
|
||||||
|
if(happiness == 1) then
|
||||||
|
return ':<'
|
||||||
|
elseif(happiness == 2) then
|
||||||
|
return ':|'
|
||||||
|
elseif(happiness == 3) then
|
||||||
|
return ':D'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end]],
|
||||||
|
|
||||||
|
['powercolor'] = [[function(u)
|
||||||
|
local pType, pToken, altR, altG, altB = UnitPowerType(u)
|
||||||
|
local t = _COLORS.power[pToken]
|
||||||
|
|
||||||
|
if(not t) then
|
||||||
|
if(altR) then
|
||||||
|
if(altR > 1 or altG > 1 or altB > 1) then
|
||||||
|
return Hex(altR / 255, altG / 255, altB / 255)
|
||||||
|
else
|
||||||
|
return Hex(altR, altG, altB)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
return Hex(_COLORS.power[pType])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return Hex(t)
|
||||||
|
end]],
|
||||||
|
}
|
||||||
|
|
||||||
|
local tags = setmetatable(
|
||||||
|
{
|
||||||
|
curhp = UnitHealth,
|
||||||
|
curpp = UnitMana,
|
||||||
|
maxhp = UnitHealthMax,
|
||||||
|
maxpp = UnitManaMax,
|
||||||
|
class = UnitClass,
|
||||||
|
faction = UnitFactionGroup,
|
||||||
|
race = UnitRace,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
__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
|
||||||
|
end
|
||||||
|
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)
|
||||||
|
end
|
||||||
|
|
||||||
|
rawset(self, key, val)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
_ENV._TAGS = tags
|
||||||
|
|
||||||
|
local tagEvents = {
|
||||||
|
['curhp'] = 'UNIT_HEALTH',
|
||||||
|
['maxhp'] = 'UNIT_MAXHEALTH',
|
||||||
|
['curpp'] = 'UNIT_ENERGY UNIT_FOCUS UNIT_MANA UNIT_RAGE',
|
||||||
|
['maxpp'] = 'UNIT_MAXENERGY UNIT_MAXFOCUS UNIT_MAXMANA UNIT_MAXRAGE',
|
||||||
|
['dead'] = 'UNIT_HEALTH',
|
||||||
|
['leader'] = 'PARTY_LEADER_CHANGED',
|
||||||
|
['leaderlong'] = 'PARTY_LEADER_CHANGED',
|
||||||
|
['level'] = 'UNIT_LEVEL PLAYER_LEVEL_UP',
|
||||||
|
['missinghp'] = 'UNIT_HEALTH UNIT_MAXHEALTH',
|
||||||
|
['missingpp'] = 'UNIT_MAXENERGY UNIT_MAXFOCUS UNIT_MAXMANA UNIT_MAXRAGE UNIT_ENERGY UNIT_FOCUS UNIT_MANA UNIT_RAGE',
|
||||||
|
['name'] = 'UNIT_NAME_UPDATE',
|
||||||
|
['offline'] = 'UNIT_HEALTH',
|
||||||
|
['perhp'] = 'UNIT_HEALTH UNIT_MAXHEALTH',
|
||||||
|
['perpp'] = 'UNIT_MAXENERGY UNIT_MAXFOCUS UNIT_MAXMANA UNIT_MAXRAGE UNIT_ENERGY UNIT_FOCUS UNIT_MANA UNIT_RAGE',
|
||||||
|
['plus'] = 'UNIT_CLASSIFICATION_CHANGED',
|
||||||
|
['pvp'] = 'UNIT_FACTION',
|
||||||
|
['rare'] = 'UNIT_CLASSIFICATION_CHANGED',
|
||||||
|
['resting'] = 'PLAYER_UPDATE_RESTING',
|
||||||
|
['status'] = 'UNIT_HEALTH PLAYER_UPDATE_RESTING',
|
||||||
|
['cpoints'] = 'PLAYER_COMBO_POINTS PLAYER_TARGET_CHANGED',
|
||||||
|
['smartlevel'] = 'UNIT_LEVEL PLAYER_LEVEL_UP UNIT_CLASSIFICATION_CHANGED',
|
||||||
|
['classification'] = 'UNIT_CLASSIFICATION_CHANGED',
|
||||||
|
['shortclassification'] = 'UNIT_CLASSIFICATION_CHANGED',
|
||||||
|
['group'] = 'PARTY_MEMBERS_CHANGED RAID_ROSTER_UPDATE',
|
||||||
|
['curmana'] = 'UNIT_MANA UNIT_MAXMANA',
|
||||||
|
['maxmana'] = 'UNIT_MANA UNIT_MAXMANA',
|
||||||
|
['happiness'] = 'UNIT_HAPPINESS',
|
||||||
|
['powercolor'] = 'UNIT_DISPLAYPOWER',
|
||||||
|
}
|
||||||
|
|
||||||
|
local unitlessEvents = {
|
||||||
|
PLAYER_LEVEL_UP = true,
|
||||||
|
PLAYER_UPDATE_RESTING = true,
|
||||||
|
PLAYER_TARGET_CHANGED = true,
|
||||||
|
|
||||||
|
RAID_ROSTER_UPDATE = true,
|
||||||
|
PARTY_MEMBERS_CHANGED = true,
|
||||||
|
PARTY_LEADER_CHANGED = true,
|
||||||
|
|
||||||
|
PLAYER_COMBO_POINTS = true,
|
||||||
|
}
|
||||||
|
|
||||||
|
local events = {}
|
||||||
|
local frame = CreateFrame('Frame')
|
||||||
|
frame:SetScript('OnEvent', function(self, event, unit)
|
||||||
|
local strings = events[event]
|
||||||
|
if(strings) then
|
||||||
|
for _, fontstring in next, strings do
|
||||||
|
if(fontstring:IsVisible() and (unitlessEvents[event] or fontstring.parent.unit == unit)) then
|
||||||
|
fontstring:UpdateTag()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
local onUpdates = {}
|
||||||
|
local eventlessUnits = {}
|
||||||
|
|
||||||
|
local function createOnUpdate(timer)
|
||||||
|
local OnUpdate = onUpdates[timer]
|
||||||
|
|
||||||
|
if(not OnUpdate) then
|
||||||
|
local total = timer
|
||||||
|
local frame = CreateFrame('Frame')
|
||||||
|
local strings = eventlessUnits[timer]
|
||||||
|
|
||||||
|
frame:SetScript('OnUpdate', function()
|
||||||
|
if(total >= timer) then
|
||||||
|
for _, fs in next, strings do
|
||||||
|
if(fs.parent:IsShown() and UnitExists(fs.parent.unit)) then
|
||||||
|
fs:UpdateTag()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
total = 0
|
||||||
|
end
|
||||||
|
|
||||||
|
total = total + arg1
|
||||||
|
end)
|
||||||
|
|
||||||
|
onUpdates[timer] = frame
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function onShow(self)
|
||||||
|
for _, fs in next, self.__tags do
|
||||||
|
fs:UpdateTag()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function getTagName(tag)
|
||||||
|
local tagStart = (string.match(tag, '>+()') or 2)
|
||||||
|
local tagEnd = string.match(tag, '.*()<+')
|
||||||
|
tagEnd = (tagEnd and tagEnd - 1) or -2
|
||||||
|
|
||||||
|
return string.sub(tag, tagStart, tagEnd), tagStart, tagEnd
|
||||||
|
end
|
||||||
|
|
||||||
|
local function registerEvent(fontstr, event)
|
||||||
|
if(not events[event]) then events[event] = {} end
|
||||||
|
|
||||||
|
frame:RegisterEvent(event)
|
||||||
|
tinsert(events[event], fontstr)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function registerEvents(fontstr, tagstr)
|
||||||
|
for tag in string.gmatch(tagstr, _PATTERN) do
|
||||||
|
tag = getTagName(tag)
|
||||||
|
local tagevents = tagEvents[tag]
|
||||||
|
if(tagevents) then
|
||||||
|
for event in string.gmatch(tagevents, '%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(getn(data) == 1) then
|
||||||
|
frame:UnregisterEvent(event)
|
||||||
|
end
|
||||||
|
|
||||||
|
tremove(data, i)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local OnEnter = function(self)
|
||||||
|
for _, fs in pairs(self.__mousetags) do
|
||||||
|
fs:SetAlpha(1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local OnLeave = function(self)
|
||||||
|
for _, fs in pairs(self.__mousetags) do
|
||||||
|
fs:SetAlpha(0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local onUpdateDelay = {}
|
||||||
|
local tagPool = {}
|
||||||
|
local funcPool = {}
|
||||||
|
local tmp = {}
|
||||||
|
local escapeSequences = {
|
||||||
|
["||c"] = "|c",
|
||||||
|
["||r"] = "|r",
|
||||||
|
["||T"] = "|T",
|
||||||
|
["||t"] = "|t",
|
||||||
|
}
|
||||||
|
|
||||||
|
--[[ 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)
|
||||||
|
--]]
|
||||||
|
local function Tag(self, fs, tagstr)
|
||||||
|
if(not fs or not tagstr) then return end
|
||||||
|
|
||||||
|
if(not self.__tags) then
|
||||||
|
self.__tags = {}
|
||||||
|
self.__mousetags = {}
|
||||||
|
tinsert(self.__elements, onShow)
|
||||||
|
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
|
||||||
|
|
||||||
|
for escapeSequence, replacement in pairs(escapeSequences) do
|
||||||
|
while string.find(tagstr, escapeSequence) do
|
||||||
|
tagstr = string.gsub(tagstr, escapeSequence, replacement)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if string.find(tagstr, '%[mouseover%]') then
|
||||||
|
tinsert(self.__mousetags, fs)
|
||||||
|
fs:SetAlpha(0)
|
||||||
|
if not self.__HookFunc then
|
||||||
|
self:HookScript('OnEnter', OnEnter)
|
||||||
|
self:HookScript('OnLeave', OnLeave)
|
||||||
|
self.__HookFunc = true;
|
||||||
|
end
|
||||||
|
tagstr = string.gsub(tagstr, '%[mouseover%]', '')
|
||||||
|
else
|
||||||
|
for index, fontString in pairs(self.__mousetags) do
|
||||||
|
if fontString == fs then
|
||||||
|
self.__mousetags[index] = nil;
|
||||||
|
fs:SetAlpha(1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local containsOnUpdate
|
||||||
|
for tag in string.gmatch(tagstr, _PATTERN) do
|
||||||
|
tag = getTagName(tag)
|
||||||
|
if not tagEvents[tag] then
|
||||||
|
containsOnUpdate = onUpdateDelay[tag] or 0.15;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local func = tagPool[tagstr]
|
||||||
|
if(not func) then
|
||||||
|
local format, numTags = string.gsub(string.gsub(tagstr, '%%', '%%%%'), _PATTERN, '%%s')
|
||||||
|
local args = {}
|
||||||
|
|
||||||
|
for bracket in string.gmatch(tagstr, _PATTERN) do
|
||||||
|
local tagFunc = funcPool[bracket] or tags[string.sub(bracket, 2, -2)]
|
||||||
|
if(not tagFunc) then
|
||||||
|
local tagName, tagStart, tagEnd = getTagName(bracket)
|
||||||
|
|
||||||
|
local tag = tags[tagName]
|
||||||
|
if(tag) then
|
||||||
|
tagStart = tagStart - 2
|
||||||
|
tagEnd = tagEnd + 2
|
||||||
|
|
||||||
|
if(tagStart ~= 0 and tagEnd ~= 0) then
|
||||||
|
local prefix = string.sub(bracket, 2, tagStart)
|
||||||
|
local suffix = string.sub(bracket, tagEnd, -2)
|
||||||
|
|
||||||
|
tagFunc = function(unit, realUnit)
|
||||||
|
local str = tag(unit, realUnit)
|
||||||
|
if(str) then
|
||||||
|
return prefix .. str .. suffix
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif(tagStart ~= 0) then
|
||||||
|
local prefix = string.sub(bracket, 2, tagStart)
|
||||||
|
|
||||||
|
tagFunc = function(unit, realUnit)
|
||||||
|
local str = tag(unit, realUnit)
|
||||||
|
if(str) then
|
||||||
|
return prefix .. str
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif(tagEnd ~= 0) then
|
||||||
|
local suffix = string.sub(bracket, tagEnd, -2)
|
||||||
|
|
||||||
|
tagFunc = function(unit, realUnit)
|
||||||
|
local str = tag(unit, realUnit)
|
||||||
|
if(str) then
|
||||||
|
return str .. suffix
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
funcPool[bracket] = tagFunc
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if(tagFunc) then
|
||||||
|
tinsert(args, tagFunc)
|
||||||
|
else
|
||||||
|
numTags = -1
|
||||||
|
func = function(self)
|
||||||
|
return self:SetText(bracket)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if(numTags == 1) then
|
||||||
|
func = function(self)
|
||||||
|
local parent = self.parent
|
||||||
|
local realUnit
|
||||||
|
if(self.overrideUnit) then
|
||||||
|
realUnit = parent.realUnit
|
||||||
|
end
|
||||||
|
|
||||||
|
_ENV._COLORS = parent.colors
|
||||||
|
return self:SetText(string.format(
|
||||||
|
format,
|
||||||
|
args[1](parent.unit, realUnit) or ''
|
||||||
|
))
|
||||||
|
end
|
||||||
|
elseif(numTags == 2) then
|
||||||
|
func = function(self)
|
||||||
|
local parent = self.parent
|
||||||
|
local unit = parent.unit
|
||||||
|
local realUnit
|
||||||
|
if(self.overrideUnit) then
|
||||||
|
realUnit = parent.realUnit
|
||||||
|
end
|
||||||
|
|
||||||
|
_ENV._COLORS = parent.colors
|
||||||
|
return self:SetText(string.format(
|
||||||
|
format,
|
||||||
|
args[1](unit, realUnit) or '',
|
||||||
|
args[2](unit, realUnit) or ''
|
||||||
|
))
|
||||||
|
end
|
||||||
|
elseif(numTags == 3) then
|
||||||
|
func = function(self)
|
||||||
|
local parent = self.parent
|
||||||
|
local unit = parent.unit
|
||||||
|
local realUnit
|
||||||
|
if(self.overrideUnit) then
|
||||||
|
realUnit = parent.realUnit
|
||||||
|
end
|
||||||
|
|
||||||
|
_ENV._COLORS = parent.colors
|
||||||
|
return self:SetText(string.format(
|
||||||
|
format,
|
||||||
|
args[1](unit, realUnit) or '',
|
||||||
|
args[2](unit, realUnit) or '',
|
||||||
|
args[3](unit, realUnit) or ''
|
||||||
|
))
|
||||||
|
end
|
||||||
|
elseif numTags ~= -1 then
|
||||||
|
func = function(self)
|
||||||
|
local parent = self.parent
|
||||||
|
local unit = parent.unit
|
||||||
|
local realUnit
|
||||||
|
if(self.overrideUnit) then
|
||||||
|
realUnit = parent.realUnit
|
||||||
|
end
|
||||||
|
|
||||||
|
_ENV._COLORS = parent.colors
|
||||||
|
for i, func in next, args do
|
||||||
|
tmp[i] = func(unit, realUnit) or ''
|
||||||
|
end
|
||||||
|
|
||||||
|
-- We do 1, numTags because tmp can hold several unneeded variables.
|
||||||
|
return self:SetText(string.format(format, unpack(tmp, 1, numTags)))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if numTags ~= -1 then
|
||||||
|
tagPool[tagstr] = func
|
||||||
|
end
|
||||||
|
end
|
||||||
|
fs.UpdateTag = func
|
||||||
|
|
||||||
|
local unit = self.unit
|
||||||
|
if(self.__eventless or fs.frequentUpdates) or containsOnUpdate then
|
||||||
|
local timer
|
||||||
|
if(type(fs.frequentUpdates) == 'number') then
|
||||||
|
timer = fs.frequentUpdates
|
||||||
|
elseif containsOnUpdate then
|
||||||
|
timer = containsOnUpdate
|
||||||
|
else
|
||||||
|
timer = .5
|
||||||
|
end
|
||||||
|
|
||||||
|
if(not eventlessUnits[timer]) then eventlessUnits[timer] = {} end
|
||||||
|
tinsert(eventlessUnits[timer], fs)
|
||||||
|
|
||||||
|
createOnUpdate(timer)
|
||||||
|
else
|
||||||
|
registerEvents(fs, tagstr)
|
||||||
|
end
|
||||||
|
|
||||||
|
tinsert(self.__tags, fs)
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[ Tags: frame:Untag(fs)
|
||||||
|
Used to unregister a tag from a unit frame.
|
||||||
|
|
||||||
|
* self - the unit frame from which to unregister the tag
|
||||||
|
* fs - the font string holding the tag (FontString)
|
||||||
|
--]]
|
||||||
|
local function Untag(self, fs)
|
||||||
|
if(not fs) then return end
|
||||||
|
|
||||||
|
unregisterEvents(fs)
|
||||||
|
for _, timers in next, eventlessUnits do
|
||||||
|
for i, fontstr in next, timers do
|
||||||
|
if(fs == fontstr) then
|
||||||
|
tremove(timers, i)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for i, fontstr in next, self.__tags do
|
||||||
|
if(fontstr == fs) then
|
||||||
|
tremove(self.__tags, i)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
fs.UpdateTag = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
oUF.Tags = {
|
||||||
|
Methods = tags,
|
||||||
|
Events = tagEvents,
|
||||||
|
SharedEvents = unitlessEvents,
|
||||||
|
OnUpdateThrottle = onUpdateDelay,
|
||||||
|
}
|
||||||
|
|
||||||
|
oUF:RegisterMetaFunction('Tag', Tag)
|
||||||
|
oUF:RegisterMetaFunction('Untag', Untag)
|
||||||
@@ -0,0 +1,145 @@
|
|||||||
|
local ns = oUF
|
||||||
|
local oUF = ns.oUF
|
||||||
|
local Private = oUF.Private
|
||||||
|
|
||||||
|
local argcheck = Private.argcheck
|
||||||
|
local error = Private.error
|
||||||
|
local frame_metatable = Private.frame_metatable
|
||||||
|
|
||||||
|
-- Original event methods
|
||||||
|
local registerEvent = frame_metatable.__index.RegisterEvent
|
||||||
|
local unregisterEvent = frame_metatable.__index.UnregisterEvent
|
||||||
|
|
||||||
|
function Private.UpdateUnits(frame, unit, realUnit)
|
||||||
|
if(unit == realUnit) then
|
||||||
|
realUnit = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
if(frame.unit ~= unit or frame.realUnit ~= realUnit) then
|
||||||
|
frame.unit = unit
|
||||||
|
frame.realUnit = realUnit
|
||||||
|
frame.id = string.match(unit, '^.-(%d+)')
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function onEvent()
|
||||||
|
if(this:IsVisible() or event == 'UNIT_COMBO_POINTS') then
|
||||||
|
--print(this, event, arg and unpack(arg))
|
||||||
|
--print(this, event, arg1, arg2, arg3, arg4, arg5)
|
||||||
|
|
||||||
|
return this[event](this, event, arg1, arg2, arg3, arg4, arg5)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local event_metatable = {
|
||||||
|
__call = function(funcs, self, ...)
|
||||||
|
for _, func in next, funcs do
|
||||||
|
func(self, unpack(arg))
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
|
--[[ Events: frame:RegisterEvent(event, func, unitless)
|
||||||
|
Used to register a frame for a game event and add an event handler. OnUpdate polled frames are prevented from
|
||||||
|
registering events.
|
||||||
|
|
||||||
|
* self - frame that will be registered for the given event.
|
||||||
|
* event - name of the event to register (string)
|
||||||
|
* func - function that will be executed when the event fires. If a string is passed, then a function by that name
|
||||||
|
must be defined on the frame. Multiple functions can be added for the same frame and event
|
||||||
|
(string or function)
|
||||||
|
* unitless - indicates that the event does not fire for a specific unit, so the event arguments won't be
|
||||||
|
matched to the frame unit(s). Events that do not start with UNIT_ or are not known to be unit events are
|
||||||
|
automatically considered unitless (boolean)
|
||||||
|
--]]
|
||||||
|
function frame_metatable.__index:RegisterEvent(event, func)
|
||||||
|
-- Block OnUpdate polled frames from registering events.
|
||||||
|
-- UNIT_PORTRAIT_UPDATE and UNIT_MODEL_CHANGED which are used for
|
||||||
|
-- portrait updates.
|
||||||
|
if(self.__eventless and event ~= 'UNIT_PORTRAIT_UPDATE' and event ~= 'UNIT_MODEL_CHANGED') then return end
|
||||||
|
|
||||||
|
argcheck(event, 2, 'string')
|
||||||
|
|
||||||
|
if(type(func) == 'string' and type(self[func]) == 'function') then
|
||||||
|
func = self[func]
|
||||||
|
end
|
||||||
|
|
||||||
|
local curev = self[event]
|
||||||
|
local kind = type(curev)
|
||||||
|
if(curev and func) then
|
||||||
|
if(kind == 'function' and curev ~= func) then
|
||||||
|
self[event] = setmetatable({curev, func}, event_metatable)
|
||||||
|
elseif(kind == 'table') then
|
||||||
|
for _, infunc in next, curev do
|
||||||
|
if(infunc == func) then return end
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(curev, func)
|
||||||
|
end
|
||||||
|
elseif(self:IsEventRegistered(event)) then
|
||||||
|
return
|
||||||
|
else
|
||||||
|
if(type(func) == 'function') then
|
||||||
|
self[event] = func
|
||||||
|
elseif(not self[event]) then
|
||||||
|
return error("Style [%s] attempted to register event [%s] on unit [%s] with a handler that doesn't exist.", self.style, event, self.unit or 'unknown')
|
||||||
|
end
|
||||||
|
|
||||||
|
if not self:GetScript('OnEvent') then
|
||||||
|
self:SetScript('OnEvent', onEvent)
|
||||||
|
end
|
||||||
|
|
||||||
|
registerEvent(self, event)
|
||||||
|
self.__registeredEvents[event] = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[ Events: frame:IsEventRegistered(event, func)
|
||||||
|
Used to determine if a game event is registered.
|
||||||
|
|
||||||
|
* self - the frame registered for the event
|
||||||
|
* event - name of the registered event (string)
|
||||||
|
--]]
|
||||||
|
function frame_metatable.__index:IsEventRegistered(event)
|
||||||
|
argcheck(event, 2, 'string')
|
||||||
|
|
||||||
|
return self.__registeredEvents[event] and true or false
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[ Events: frame:UnregisterEvent(event, func)
|
||||||
|
Used to remove a function from the event handler list for a game event.
|
||||||
|
|
||||||
|
* self - the frame registered for the event
|
||||||
|
* event - name of the registered event (string)
|
||||||
|
* func - function to be removed from the list of event handlers. If this is the only handler for the given event, then
|
||||||
|
the frame will be unregistered for the event
|
||||||
|
--]]
|
||||||
|
function frame_metatable.__index:UnregisterEvent(event, func)
|
||||||
|
argcheck(event, 2, 'string')
|
||||||
|
|
||||||
|
local curev = self[event]
|
||||||
|
if(type(curev) == 'table' and func) then
|
||||||
|
for k, infunc in next, curev do
|
||||||
|
if(infunc == func) then
|
||||||
|
table.remove(curev, k)
|
||||||
|
|
||||||
|
local n = getn(curev)
|
||||||
|
if(n == 1) then
|
||||||
|
local _, handler = next(curev)
|
||||||
|
self[event] = handler
|
||||||
|
elseif(n == 0) then
|
||||||
|
-- This should not happen
|
||||||
|
unregisterEvent(self, event)
|
||||||
|
self.__registeredEvents[event] = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif(curev == func) then
|
||||||
|
self[event] = nil
|
||||||
|
unregisterEvent(self, event)
|
||||||
|
self.__registeredEvents[event] = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
local ns = oUF
|
||||||
|
local oUF = ns.oUF
|
||||||
|
local Private = oUF.Private
|
||||||
|
|
||||||
|
local argcheck = Private.argcheck
|
||||||
|
|
||||||
|
local queue = {}
|
||||||
|
local factory = CreateFrame('Frame')
|
||||||
|
factory:SetScript('OnEvent', function()
|
||||||
|
return this[event](this, event, arg and unpack(arg))
|
||||||
|
end)
|
||||||
|
|
||||||
|
factory:RegisterEvent('PLAYER_LOGIN')
|
||||||
|
factory.active = true
|
||||||
|
|
||||||
|
function factory:PLAYER_LOGIN()
|
||||||
|
if(not self.active) then return end
|
||||||
|
|
||||||
|
for _, func in next, queue do
|
||||||
|
func(oUF)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Avoid creating dupes.
|
||||||
|
wipe(queue)
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[ Factory: oUF:Factory(func)
|
||||||
|
Used to call a function directly if the current character is logged in and the factory is active. Else the function is
|
||||||
|
queued up to be executed at a later time (upon PLAYER_LOGIN by default).
|
||||||
|
|
||||||
|
* self - the global oUF object
|
||||||
|
* func - function to be executed or delayed (function)
|
||||||
|
--]]
|
||||||
|
function oUF:Factory(func)
|
||||||
|
argcheck(func, 2, 'function')
|
||||||
|
|
||||||
|
-- Call the function directly if we're active and logged in.
|
||||||
|
if(IsLoggedIn() and factory.active) then
|
||||||
|
return func(self)
|
||||||
|
else
|
||||||
|
table.insert(queue, func)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[ Factory: oUF:EnableFactory()
|
||||||
|
Used to enable the factory.
|
||||||
|
|
||||||
|
* self - the global oUF object
|
||||||
|
--]]
|
||||||
|
function oUF:EnableFactory()
|
||||||
|
factory.active = true
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[ Factory: oUF:DisableFactory()
|
||||||
|
Used to disable the factory.
|
||||||
|
|
||||||
|
* self - the global oUF object
|
||||||
|
--]]
|
||||||
|
function oUF:DisableFactory()
|
||||||
|
factory.active = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[ Factory: oUF:RunFactoryQueue()
|
||||||
|
Used to try to execute queued up functions. The current player must be logged in and the factory must be active for
|
||||||
|
this to succeed.
|
||||||
|
|
||||||
|
* self - the global oUF object
|
||||||
|
--]]
|
||||||
|
function oUF:RunFactoryQueue()
|
||||||
|
factory:PLAYER_LOGIN()
|
||||||
|
end
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
local ns = oUF
|
||||||
|
|
||||||
|
-- It's named Private for a reason!
|
||||||
|
ns.oUF.Private = nil
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
oUF = {}
|
||||||
|
|
||||||
|
local ns = oUF
|
||||||
|
ns.oUF = {}
|
||||||
|
ns.oUF.Private = {}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
<Ui xmlns="http://www.blizzard.com/wow/ui/">
|
||||||
|
<Script file="init.lua"/>
|
||||||
|
<Script file="private.lua"/>
|
||||||
|
<Script file="ouf.lua"/>
|
||||||
|
<Script file="events.lua"/>
|
||||||
|
<Script file="factory.lua"/>
|
||||||
|
<Script file="blizzard.lua"/>
|
||||||
|
<Script file="units.lua"/>
|
||||||
|
<Script file="colors.lua"/>
|
||||||
|
<Script file="finalize.lua"/>
|
||||||
|
|
||||||
|
<Include file="elements\elements.xml"/>
|
||||||
|
|
||||||
|
<Cooldown name="oUF_CooldownFrameTemplate" inherits="CooldownFrameTemplate" drawEdge="true" virtual="true"/>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Sub-object as a child of the parent unit frame:
|
||||||
|
<Button name="oUF_HeaderTargetTemplate" inherits="SecureUnitButtonTemplate" virtual="true">
|
||||||
|
<Frames>
|
||||||
|
<Button name="$parentTarget" inherits="SecureUnitButtonTemplate">
|
||||||
|
<Attributes>
|
||||||
|
<Attribute name="unitsuffix" type="string" value="target"/>
|
||||||
|
<Attribute name="useparent-unit" type="boolean" value="true"/>
|
||||||
|
</Attributes>
|
||||||
|
</Button>
|
||||||
|
</Frames>
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
Separate unit template example:
|
||||||
|
<Button name="oUF_HeaderSeparateSubOjectsTemplate" inherits="SecureUnitButtonTemplate" virtual="true">
|
||||||
|
<Attributes>
|
||||||
|
<Attribute name="oUF-onlyProcessChildren" type="boolean" value="true"/>
|
||||||
|
</Attributes>
|
||||||
|
|
||||||
|
<Frames>
|
||||||
|
<Button name="$parentUnit" inherits="SecureUnitButtonTemplate">
|
||||||
|
<Attributes>
|
||||||
|
<Attribute name="useparent-unit" type="boolean" value="true"/>
|
||||||
|
</Attributes>
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Button name="$parentPet" inherits="SecureUnitButtonTemplate">
|
||||||
|
<Attributes>
|
||||||
|
<Attribute name="unitsuffix" type="string" value="pet"/>
|
||||||
|
<Attribute name="useparent-unit" type="boolean" value="true"/>
|
||||||
|
</Attributes>
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Button name="$parentTarget" inherits="SecureUnitButtonTemplate">
|
||||||
|
<Attributes>
|
||||||
|
<Attribute name="unitsuffix" type="string" value="target"/>
|
||||||
|
<Attribute name="useparent-unit" type="boolean" value="true"/>
|
||||||
|
</Attributes>
|
||||||
|
</Button>
|
||||||
|
</Frames>
|
||||||
|
</Button>
|
||||||
|
-->
|
||||||
|
</Ui>
|
||||||
@@ -0,0 +1,754 @@
|
|||||||
|
local ns = oUF
|
||||||
|
|
||||||
|
local oUF = ns.oUF
|
||||||
|
local Private = oUF.Private
|
||||||
|
|
||||||
|
local argcheck = Private.argcheck
|
||||||
|
|
||||||
|
local print = Private.print
|
||||||
|
local error = Private.error
|
||||||
|
|
||||||
|
local styles, style = {}
|
||||||
|
local callback, units, objects, headers = {}, {}, {}, {}
|
||||||
|
|
||||||
|
local elements = {}
|
||||||
|
local activeElements = {}
|
||||||
|
|
||||||
|
local pairs = pairs
|
||||||
|
|
||||||
|
local unitExistsWatchers = {}
|
||||||
|
local unitExistsCache = setmetatable({},{
|
||||||
|
__index = function(t, k)
|
||||||
|
local v = UnitExists(k) or false
|
||||||
|
t[k] = v
|
||||||
|
return v
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
local function updateUnitWatch(frame)
|
||||||
|
local unit = frame.unit
|
||||||
|
local exists = (unit and unitExistsCache[unit])
|
||||||
|
if exists then
|
||||||
|
frame:Show()
|
||||||
|
else
|
||||||
|
frame:Hide()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local unitWatch = CreateFrame("Frame")
|
||||||
|
unitWatch:Hide()
|
||||||
|
|
||||||
|
local timer = 0
|
||||||
|
unitWatch:SetScript("OnUpdate", function()
|
||||||
|
timer = timer - arg1
|
||||||
|
if timer <= 0 then
|
||||||
|
timer = 0.2
|
||||||
|
|
||||||
|
for k in pairs(unitExistsCache) do
|
||||||
|
unitExistsCache[k] = nil
|
||||||
|
end
|
||||||
|
for frame in pairs(unitExistsWatchers) do
|
||||||
|
updateUnitWatch(frame)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
unitWatch:SetScript("OnEvent", function() timer = 0 end)
|
||||||
|
|
||||||
|
unitWatch:RegisterEvent("PLAYER_TARGET_CHANGED")
|
||||||
|
unitWatch:RegisterEvent("PLAYER_FOCUS_CHANGED")
|
||||||
|
unitWatch:RegisterEvent("PLAYER_REGEN_DISABLED")
|
||||||
|
unitWatch:RegisterEvent("PLAYER_REGEN_ENABLED")
|
||||||
|
unitWatch:RegisterEvent("UNIT_PET")
|
||||||
|
unitWatch:RegisterEvent("RAID_ROSTER_UPDATE")
|
||||||
|
unitWatch:RegisterEvent("PARTY_MEMBERS_CHANGED")
|
||||||
|
|
||||||
|
local function RegisterUnitWatch(frame)
|
||||||
|
unitExistsWatchers[frame] = true
|
||||||
|
unitWatch:Show()
|
||||||
|
updateUnitWatch(frame)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function UnregisterUnitWatch(frame)
|
||||||
|
unitExistsWatchers[frame] = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
-- updating of "invalid" units.
|
||||||
|
local function enableTargetUpdate(object)
|
||||||
|
object.onUpdateFrequency = object.onUpdateFrequency or .5
|
||||||
|
object.__eventless = true
|
||||||
|
|
||||||
|
local total = 0
|
||||||
|
object:SetScript('OnUpdate', function()
|
||||||
|
if not this.unit then
|
||||||
|
return
|
||||||
|
elseif total > this.onUpdateFrequency then
|
||||||
|
this:UpdateAllElements('OnUpdate')
|
||||||
|
total = 0
|
||||||
|
end
|
||||||
|
|
||||||
|
total = total + GetTime()
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
Private.enableTargetUpdate = enableTargetUpdate
|
||||||
|
|
||||||
|
local function updateActiveUnit(self, event, unit)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
local function iterateChildren(...)
|
||||||
|
for i = 1, table.getn(arg) do
|
||||||
|
local obj = arg[i]
|
||||||
|
|
||||||
|
if(type(obj) == 'table' and obj.isChild) then
|
||||||
|
updateActiveUnit(obj, 'iterateChildren')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function onAttributeChanged(self, name, value)
|
||||||
|
if(name == 'unit' and value) then
|
||||||
|
if(self.hasChildren) then
|
||||||
|
iterateChildren(self:GetChildren())
|
||||||
|
end
|
||||||
|
|
||||||
|
if(not self.onlyProcessChildren) then
|
||||||
|
updateActiveUnit(self, 'OnAttributeChanged')
|
||||||
|
end
|
||||||
|
--[[
|
||||||
|
if(self.unit and self.unit == value) then
|
||||||
|
return
|
||||||
|
else
|
||||||
|
if(self.hasChildren) then
|
||||||
|
iterateChildren(self:GetChildren())
|
||||||
|
end
|
||||||
|
end
|
||||||
|
]]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local frame_metatable = {
|
||||||
|
__index = CreateFrame('Button')
|
||||||
|
}
|
||||||
|
Private.frame_metatable = frame_metatable
|
||||||
|
|
||||||
|
for k, v in next, {
|
||||||
|
UpdateElement = function(self, name)
|
||||||
|
local unit = self.unit
|
||||||
|
if(not unit or not UnitExists(unit)) then return end
|
||||||
|
|
||||||
|
local element = elements[name]
|
||||||
|
if(not element or not self:IsElementEnabled(name) or not activeElements[self]) then return end
|
||||||
|
if(element.update) then
|
||||||
|
element.update(self, 'OnShow', unit)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
|
||||||
|
UpdateElement = function(self, name)
|
||||||
|
local unit = self.unit
|
||||||
|
if(not unit or not UnitExists(unit)) then return end
|
||||||
|
|
||||||
|
local element = elements[name]
|
||||||
|
if(not element or not self:IsElementEnabled(name) or not activeElements[self]) then return end
|
||||||
|
if(element.update) then
|
||||||
|
element.update(self, 'OnShow', unit)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
|
||||||
|
--[[ frame:EnableElement(name, unit)
|
||||||
|
Used to activate an element for the given unit frame.
|
||||||
|
|
||||||
|
* self - unit frame for which the element should be enabled
|
||||||
|
* name - name of the element to be enabled (string)
|
||||||
|
* unit - unit to be passed to the element's Enable function. Defaults to the frame's unit (string?)
|
||||||
|
--]]
|
||||||
|
EnableElement = function(self, name, unit)
|
||||||
|
argcheck(name, 2, 'string')
|
||||||
|
argcheck(unit, 3, 'string', 'nil')
|
||||||
|
|
||||||
|
local element = elements[name]
|
||||||
|
if(not element or self:IsElementEnabled(name) or not activeElements[self]) then return end
|
||||||
|
|
||||||
|
if(element.enable(self, unit or self.unit)) then
|
||||||
|
activeElements[self][name] = true
|
||||||
|
|
||||||
|
if(element.update) then
|
||||||
|
table.insert(self.__elements, element.update)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
|
||||||
|
--[[ frame:DisableElement(name)
|
||||||
|
Used to deactivate an element for the given unit frame.
|
||||||
|
|
||||||
|
* self - unit frame for which the element should be disabled
|
||||||
|
* name - name of the element to be disabled (string)
|
||||||
|
--]]
|
||||||
|
DisableElement = function(self, name)
|
||||||
|
argcheck(name, 2, 'string')
|
||||||
|
|
||||||
|
local enabled = self:IsElementEnabled(name)
|
||||||
|
if(not enabled) then return end
|
||||||
|
|
||||||
|
local update = elements[name].update
|
||||||
|
for k, func in next, self.__elements do
|
||||||
|
if(func == update) then
|
||||||
|
table.remove(self.__elements, k)
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
activeElements[self][name] = nil
|
||||||
|
|
||||||
|
-- We need to run a new update cycle in-case we knocked ourself out of sync.
|
||||||
|
-- The main reason we do this is to make sure the full update is completed
|
||||||
|
-- if an element for some reason removes itself _during_ the update
|
||||||
|
-- progress.
|
||||||
|
self:UpdateAllElements('DisableElement')
|
||||||
|
|
||||||
|
return elements[name].disable(self)
|
||||||
|
end,
|
||||||
|
|
||||||
|
--[[ frame:IsElementEnabled(name)
|
||||||
|
Used to check if an element is enabled on the given frame.
|
||||||
|
|
||||||
|
* self - unit frame
|
||||||
|
* name - name of the element (string)
|
||||||
|
--]]
|
||||||
|
IsElementEnabled = function(self, name)
|
||||||
|
argcheck(name, 2, 'string')
|
||||||
|
|
||||||
|
local element = elements[name]
|
||||||
|
if(not element) then return end
|
||||||
|
|
||||||
|
local active = activeElements[self]
|
||||||
|
return active and active[name]
|
||||||
|
end,
|
||||||
|
|
||||||
|
--[[ frame:Enable(asState)
|
||||||
|
Used to toggle the visibility of a unit frame based on the existence of its unit. This is a reference to
|
||||||
|
`RegisterUnitWatch`.
|
||||||
|
|
||||||
|
* self - unit frame
|
||||||
|
* asState - if true, the frame's "state-unitexists" attribute will be set to a boolean value denoting whether the
|
||||||
|
unit exists; if false, the frame will be shown if its unit exists, and hidden if it does not (boolean)
|
||||||
|
--]]
|
||||||
|
Enable = RegisterUnitWatch,
|
||||||
|
--[[ frame:Disable()
|
||||||
|
Used to UnregisterUnitWatch for the given frame and hide it.
|
||||||
|
|
||||||
|
* self - unit frame
|
||||||
|
--]]
|
||||||
|
Disable = function(self)
|
||||||
|
UnregisterUnitWatch(self)
|
||||||
|
self:Hide()
|
||||||
|
end,
|
||||||
|
|
||||||
|
--[[ frame:UpdateAllElements(event)
|
||||||
|
Used to update all enabled elements on the given frame.
|
||||||
|
|
||||||
|
* self - unit frame
|
||||||
|
* event - event name to pass to the elements' update functions (string)
|
||||||
|
--]]
|
||||||
|
UpdateAllElements = function(self, event)
|
||||||
|
local unit = self.unit
|
||||||
|
if(not UnitExists(unit)) then return end
|
||||||
|
|
||||||
|
assert(type(event) == 'string', "Invalid argument 'event' in UpdateAllElements.")
|
||||||
|
|
||||||
|
if(self.PreUpdate) then
|
||||||
|
self:PreUpdate(event)
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, func in next, self.__elements do
|
||||||
|
func(self, event, unit)
|
||||||
|
end
|
||||||
|
|
||||||
|
if(self.PostUpdate) then
|
||||||
|
self:PostUpdate(event)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
} do
|
||||||
|
frame_metatable.__index[k] = v
|
||||||
|
end
|
||||||
|
|
||||||
|
local secureDropdown
|
||||||
|
local function InitializeSecureMenu()
|
||||||
|
local unit = SecureTemplatesDropdown.unit
|
||||||
|
if(not unit) then return end
|
||||||
|
|
||||||
|
local unitType = string.match(unit, '^([a-z]+)[0-9]+$') or unit
|
||||||
|
|
||||||
|
local menu
|
||||||
|
if(unitType == 'party') then
|
||||||
|
menu = 'PARTY'
|
||||||
|
elseif(unitType == 'focus') then
|
||||||
|
menu = 'RAID_TARGET_ICON'
|
||||||
|
-- elseif(unitType == 'arenapet' or unitType == 'arena') then
|
||||||
|
elseif(unitType == 'arena') then
|
||||||
|
menu = 'RAID_TARGET_ICON'
|
||||||
|
elseif(UnitIsUnit(unit, 'player')) then
|
||||||
|
menu = 'SELF'
|
||||||
|
elseif(UnitIsUnit(unit, 'pet')) then
|
||||||
|
menu = 'PET'
|
||||||
|
elseif(UnitIsPlayer(unit)) then
|
||||||
|
if(UnitInRaid(unit)) then
|
||||||
|
menu = 'RAID_PLAYER'
|
||||||
|
elseif(UnitInParty(unit)) then
|
||||||
|
menu = 'PARTY'
|
||||||
|
else
|
||||||
|
menu = 'PLAYER'
|
||||||
|
end
|
||||||
|
elseif(UnitIsUnit(unit, 'target')) then
|
||||||
|
menu = 'RAID_TARGET_ICON'
|
||||||
|
end
|
||||||
|
|
||||||
|
if(menu) then
|
||||||
|
UnitPopup_ShowMenu(SecureTemplatesDropdown, menu, unit)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function togglemenu(self, unit)
|
||||||
|
if(not secureDropdown) then
|
||||||
|
secureDropdown = CreateFrame('Frame', 'SecureTemplatesDropdown', nil, 'UIDropDownMenuTemplate')
|
||||||
|
secureDropdown:SetID(1)
|
||||||
|
|
||||||
|
table.insert(UnitPopupFrames, secureDropdown:GetName())
|
||||||
|
UIDropDownMenu_Initialize(secureDropdown, InitializeSecureMenu, 'MENU')
|
||||||
|
end
|
||||||
|
|
||||||
|
if(secureDropdown.openedFor and secureDropdown.openedFor ~= self) then
|
||||||
|
CloseDropDownMenus()
|
||||||
|
end
|
||||||
|
|
||||||
|
secureDropdown.unit = string.lower(unit)
|
||||||
|
secureDropdown.openedFor = self
|
||||||
|
|
||||||
|
ToggleDropDownMenu(1, nil, secureDropdown, 'cursor')
|
||||||
|
end
|
||||||
|
|
||||||
|
local function onShow()
|
||||||
|
return this:UpdateAllElements('OnShow')
|
||||||
|
end
|
||||||
|
|
||||||
|
local function initObject(unit, style, styleFunc, header, ...)
|
||||||
|
local num = table.getn(arg)
|
||||||
|
for i = 1, num do
|
||||||
|
local object = arg[i]
|
||||||
|
local objectUnit = object.guessUnit or unit
|
||||||
|
local suffix = "ery"
|
||||||
|
|
||||||
|
object.__elements = {}
|
||||||
|
object.__registeredEvents = {}
|
||||||
|
object.style = style
|
||||||
|
object = setmetatable(object, frame_metatable)
|
||||||
|
|
||||||
|
-- Expose the frame through oUF.objects.
|
||||||
|
table.insert(objects, object)
|
||||||
|
|
||||||
|
-- We have to force update the frames when PEW fires.
|
||||||
|
object:RegisterEvent('PLAYER_ENTERING_WORLD', object.UpdateAllElements)
|
||||||
|
|
||||||
|
if(not header) then
|
||||||
|
-- No header means it's a frame created through :Spawn().
|
||||||
|
object.menu = togglemenu
|
||||||
|
object:SetScript("OnClick", function()
|
||||||
|
TargetUnit(unit)
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- Other target units are handled by :HandleUnit().
|
||||||
|
if(suffix == 'target') then
|
||||||
|
enableTargetUpdate(object)
|
||||||
|
else
|
||||||
|
oUF:HandleUnit(object)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- Used to update frames when they change position in a group.
|
||||||
|
object:RegisterEvent('RAID_ROSTER_UPDATE', object.UpdateAllElements)
|
||||||
|
|
||||||
|
if(num > 1) then
|
||||||
|
if(object:GetParent() == header) then
|
||||||
|
object.hasChildren = true
|
||||||
|
else
|
||||||
|
object.isChild = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if(suffix == 'target') then
|
||||||
|
enableTargetUpdate(object)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Private.UpdateUnits(object, objectUnit)
|
||||||
|
|
||||||
|
styleFunc(object, objectUnit, not header)
|
||||||
|
|
||||||
|
--object:SetScript('OnAttributeChanged', onAttributeChanged)
|
||||||
|
object:SetScript('OnShow', onShow)
|
||||||
|
|
||||||
|
activeElements[object] = {}
|
||||||
|
for element in next, elements do
|
||||||
|
object:EnableElement(element, objectUnit)
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, func in next, callback do
|
||||||
|
func(object)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Make Clique kinda happy
|
||||||
|
_G.ClickCastFrames = ClickCastFrames or {}
|
||||||
|
ClickCastFrames[object] = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function walkObject(object, unit)
|
||||||
|
local parent = object:GetParent()
|
||||||
|
local style = parent.style or style
|
||||||
|
local styleFunc = styles[style]
|
||||||
|
|
||||||
|
local header = parent.headerType and parent
|
||||||
|
|
||||||
|
-- Check if we should leave the main frame blank.
|
||||||
|
if(object.onlyProcessChildren) then
|
||||||
|
object.hasChildren = true
|
||||||
|
object:SetScript('OnAttributeChanged', onAttributeChanged)
|
||||||
|
return initObject(unit, style, styleFunc, header, object:GetChildren())
|
||||||
|
end
|
||||||
|
|
||||||
|
return initObject(unit, style, styleFunc, header, object, object:GetChildren())
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[ oUF:RegisterInitCallback(func)
|
||||||
|
Used to add a function to a table to be executed upon unit frame/header initialization.
|
||||||
|
|
||||||
|
* self - the global oUF object
|
||||||
|
* func - function to be added
|
||||||
|
--]]
|
||||||
|
function oUF:RegisterInitCallback(func)
|
||||||
|
table.insert(callback, func)
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[ oUF:RegisterMetaFunction(name, func)
|
||||||
|
Used to make a (table of) function(s) available to all unit frames.
|
||||||
|
|
||||||
|
* self - the global oUF object
|
||||||
|
* name - unique name of the function (string)
|
||||||
|
* func - function or a table of functions (function or table)
|
||||||
|
--]]
|
||||||
|
function oUF:RegisterMetaFunction(name, func)
|
||||||
|
argcheck(name, 2, 'string')
|
||||||
|
argcheck(func, 3, 'function', 'table')
|
||||||
|
|
||||||
|
if(frame_metatable.__index[name]) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
frame_metatable.__index[name] = func
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[ oUF:RegisterStyle(name, func)
|
||||||
|
Used to register a style with oUF. This will also set the active style if it hasn't been set yet.
|
||||||
|
|
||||||
|
* self - the global oUF object
|
||||||
|
* name - name of the style
|
||||||
|
* func - function(s) defining the style (function or table)
|
||||||
|
--]]
|
||||||
|
function oUF:RegisterStyle(name, func)
|
||||||
|
argcheck(name, 2, 'string')
|
||||||
|
argcheck(func, 3, 'function', 'table')
|
||||||
|
|
||||||
|
if(styles[name]) then return error('Style [%s] already registered.', name) end
|
||||||
|
if(not style) then style = name end
|
||||||
|
|
||||||
|
styles[name] = func
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[ oUF:SetActiveStyle(name)
|
||||||
|
Used to set the active style.
|
||||||
|
|
||||||
|
* self - the global oUF object
|
||||||
|
* name - name of the style (string)
|
||||||
|
--]]
|
||||||
|
function oUF:SetActiveStyle(name)
|
||||||
|
argcheck(name, 2, 'string')
|
||||||
|
if(not styles[name]) then return error('Style [%s] does not exist.', name) end
|
||||||
|
|
||||||
|
style = name
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local function iter(_, n)
|
||||||
|
-- don't expose the style functions.
|
||||||
|
return (next(styles, n))
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[ oUF:IterateStyles()
|
||||||
|
Returns an iterator over all registered styles.
|
||||||
|
|
||||||
|
* self - the global oUF object
|
||||||
|
--]]
|
||||||
|
function oUF.IterateStyles()
|
||||||
|
return iter, nil, nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local getCondition
|
||||||
|
do
|
||||||
|
local conditions = {
|
||||||
|
raid40 = '[target=raid26,exists] show;',
|
||||||
|
raid25 = '[target=raid11,exists] show;',
|
||||||
|
raid10 = '[target=raid6,exists] show;',
|
||||||
|
raid = '[group:raid] show;',
|
||||||
|
party = '[group:party,nogroup:raid] show;',
|
||||||
|
solo = '[target=player,exists,nogroup:party] show;',
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCondition(...)
|
||||||
|
local cond = ''
|
||||||
|
|
||||||
|
for i = 1, select('#', arg) do
|
||||||
|
local short = select(i, unpack(arg))
|
||||||
|
|
||||||
|
local condition = conditions[short]
|
||||||
|
if(condition) then
|
||||||
|
cond = cond .. condition
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return cond .. 'hide'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function generateName(unit, ...)
|
||||||
|
local name = 'oUF_' .. style:gsub('^oUF_?', ''):gsub('[^%a%d_]+', '')
|
||||||
|
|
||||||
|
local raid, party, groupFilter
|
||||||
|
for i = 1, select('#', arg), 2 do
|
||||||
|
local att, val = select(i, unpack(arg))
|
||||||
|
if(att == 'showRaid') then
|
||||||
|
raid = true
|
||||||
|
elseif(att == 'showParty') then
|
||||||
|
party = true
|
||||||
|
elseif(att == 'groupFilter') then
|
||||||
|
groupFilter = val
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local append
|
||||||
|
if(raid) then
|
||||||
|
if(groupFilter) then
|
||||||
|
if(type(groupFilter) == 'number' and groupFilter > 0) then
|
||||||
|
append = groupFilter
|
||||||
|
elseif(groupFilter:match('TANK')) then
|
||||||
|
append = 'MainTank'
|
||||||
|
elseif(groupFilter:match('ASSIST')) then
|
||||||
|
append = 'MainAssist'
|
||||||
|
else
|
||||||
|
local _, count = groupFilter:gsub(',', '')
|
||||||
|
if(count == 0) then
|
||||||
|
append = 'Raid' .. groupFilter
|
||||||
|
else
|
||||||
|
append = 'Raid'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
append = 'Raid'
|
||||||
|
end
|
||||||
|
elseif(party) then
|
||||||
|
append = 'Party'
|
||||||
|
elseif(unit) then
|
||||||
|
append = unit:gsub('^%l', string.upper)
|
||||||
|
end
|
||||||
|
|
||||||
|
if(append) then
|
||||||
|
name = name .. append
|
||||||
|
end
|
||||||
|
|
||||||
|
local base = name
|
||||||
|
local i = 2
|
||||||
|
while(_G[name]) do
|
||||||
|
name = base .. i
|
||||||
|
i = i + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
return name
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local function styleProxy(self, frame, ...)
|
||||||
|
return walkObject(_G[frame])
|
||||||
|
end
|
||||||
|
|
||||||
|
-- There has to be an easier way to do this.
|
||||||
|
local initialConfigFunction = function(self)
|
||||||
|
local header = self:GetParent()
|
||||||
|
for i = 1, select('#', self), 1 do
|
||||||
|
local frame = select(i, self)
|
||||||
|
local unit
|
||||||
|
-- There's no need to do anything on frames with onlyProcessChildren
|
||||||
|
if(not frame.onlyProcessChildren) then
|
||||||
|
-- Attempt to guess what the header is set to spawn.
|
||||||
|
local groupFilter = header:GetAttribute('groupFilter')
|
||||||
|
|
||||||
|
if(type(groupFilter) == 'string' and groupFilter:match('MAIN[AT]')) then
|
||||||
|
local role = groupFilter:match('MAIN([AT])')
|
||||||
|
if(role == 'T') then
|
||||||
|
unit = 'maintank'
|
||||||
|
else
|
||||||
|
unit = 'mainassist'
|
||||||
|
end
|
||||||
|
elseif(header:GetAttribute('showRaid')) then
|
||||||
|
unit = 'raid'
|
||||||
|
elseif(header:GetAttribute('showParty')) then
|
||||||
|
unit = 'party'
|
||||||
|
end
|
||||||
|
|
||||||
|
local headerType = header.headerType
|
||||||
|
local suffix = frame:GetAttribute('unitsuffix')
|
||||||
|
if(unit and suffix) then
|
||||||
|
if(headerType == 'pet' and suffix == 'target') then
|
||||||
|
unit = unit .. headerType .. suffix
|
||||||
|
else
|
||||||
|
unit = unit .. suffix
|
||||||
|
end
|
||||||
|
elseif(unit and headerType == 'pet') then
|
||||||
|
unit = unit .. headerType
|
||||||
|
end
|
||||||
|
|
||||||
|
frame.menu = togglemenu
|
||||||
|
frame:SetAttribute('type1', 'target')
|
||||||
|
frame:SetAttribute('type2', 'menu')
|
||||||
|
frame.guessUnit = unit
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
header:styleFunction(self:GetName())
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[ oUF:SpawnHeader(overrideName, template, visibility, ...)
|
||||||
|
Used to create a group header and apply the currently active style to it.
|
||||||
|
|
||||||
|
* self - the global oUF object
|
||||||
|
* overrideName - unique global name to be used for the header. Defaults to an auto-generated name based on the name
|
||||||
|
of the active style and other arguments passed to `:SpawnHeader` (string?)
|
||||||
|
* template - name of a template to be used for creating the header. Defaults to `'SecureGroupHeaderTemplate'`
|
||||||
|
(string?)
|
||||||
|
* visibility - macro conditional(s) which define when to display the header (string).
|
||||||
|
* ... - further argument pairs. Consult [Group Headers](http://wowprogramming.com/docs/secure_template/Group_Headers)
|
||||||
|
for possible values.
|
||||||
|
|
||||||
|
In addition to the standard group headers, oUF implements some of its own attributes. These can be supplied by the
|
||||||
|
layout, but are optional.
|
||||||
|
|
||||||
|
* oUF-initialConfigFunction - can contain code that will be securely run at the end of the initial secure
|
||||||
|
configuration (string?)
|
||||||
|
* oUF-onlyProcessChildren - can be used to force headers to only process children (boolean?)
|
||||||
|
--]]
|
||||||
|
function oUF:SpawnHeader(overrideName, template, visibility, ...)
|
||||||
|
if(not style) then return error('Unable to create frame. No styles have been registered.') end
|
||||||
|
|
||||||
|
template = (template or 'SecureGroupHeaderTemplate')
|
||||||
|
|
||||||
|
local isPetHeader = string.match(template, 'PetHeader')
|
||||||
|
local name = overrideName or generateName(nil, unpack(arg))
|
||||||
|
local header = CreateFrame('Frame', name, UIParent, template)
|
||||||
|
|
||||||
|
header:SetAttribute('template', 'SecureUnitButtonTemplate')
|
||||||
|
for i = 1, select('#', arg), 2 do
|
||||||
|
local att, val = select(i, unpack(arg))
|
||||||
|
if(not att) then break end
|
||||||
|
header:SetAttribute(att, val)
|
||||||
|
end
|
||||||
|
|
||||||
|
header.style = style
|
||||||
|
header.styleFunction = styleProxy
|
||||||
|
header.visibility = visibility
|
||||||
|
|
||||||
|
-- Expose the header through oUF.headers.
|
||||||
|
table.insert(headers, header)
|
||||||
|
|
||||||
|
header.initialConfigFunction = initialConfigFunction
|
||||||
|
header.headerType = isPetHeader and 'pet' or 'group'
|
||||||
|
|
||||||
|
if(header:GetAttribute('showParty')) then
|
||||||
|
self:DisableBlizzard('party')
|
||||||
|
end
|
||||||
|
|
||||||
|
if(visibility) then
|
||||||
|
local type, list = string.split(' ', visibility, 2)
|
||||||
|
if(list and type == 'custom') then
|
||||||
|
RegisterStateDriver(header, 'visibility', list)
|
||||||
|
header.visibility = list
|
||||||
|
else
|
||||||
|
local condition = getCondition(string.split(',', visibility))
|
||||||
|
RegisterStateDriver(header, 'visibility', condition)
|
||||||
|
header.visibility = condition
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return header
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[ oUF:Spawn(unit, overrideName)
|
||||||
|
Used to create a single unit frame and apply the currently active style to it.
|
||||||
|
|
||||||
|
* self - the global oUF object
|
||||||
|
* unit - the frame's unit (string)
|
||||||
|
* overrideName - unique global name to use for the unit frame. Defaults to an auto-generated name based on the unit
|
||||||
|
(string?)
|
||||||
|
--]]
|
||||||
|
function oUF:Spawn(unit, overrideName)
|
||||||
|
argcheck(unit, 2, 'string')
|
||||||
|
if(not style) then return error('Unable to create frame. No styles have been registered.') end
|
||||||
|
|
||||||
|
unit = string.lower(unit)
|
||||||
|
|
||||||
|
local name = overrideName or generateName(unit)
|
||||||
|
local object = CreateFrame('Button', name, UIParent)
|
||||||
|
object:Hide()
|
||||||
|
Private.UpdateUnits(object, unit)
|
||||||
|
|
||||||
|
self:DisableBlizzard(unit)
|
||||||
|
units[unit] = object
|
||||||
|
walkObject(object, unit)
|
||||||
|
|
||||||
|
object.unit = unit
|
||||||
|
|
||||||
|
return object
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[ oUF:AddElement(name, update, enable, disable)
|
||||||
|
Used to register an element with oUF.
|
||||||
|
|
||||||
|
* self - the global oUF object
|
||||||
|
* name - unique name of the element (string)
|
||||||
|
* update - used to update the element (function?)
|
||||||
|
* enable - used to enable the element for a given unit frame and unit (function?)
|
||||||
|
* disable - used to disable the element for a given unit frame (function?)
|
||||||
|
--]]
|
||||||
|
function oUF:AddElement(name, update, enable, disable)
|
||||||
|
argcheck(name, 2, 'string')
|
||||||
|
argcheck(update, 3, 'function', 'nil')
|
||||||
|
argcheck(enable, 4, 'function', 'nil')
|
||||||
|
argcheck(disable, 5, 'function', 'nil')
|
||||||
|
|
||||||
|
if(elements[name]) then return error('Element [%s] is already registered.', name) end
|
||||||
|
elements[name] = {
|
||||||
|
update = update;
|
||||||
|
enable = enable;
|
||||||
|
disable = disable;
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[ oUF.units
|
||||||
|
Array containing all unit frames with existing units created by oUF:Spawn.
|
||||||
|
--]]
|
||||||
|
oUF.units = units
|
||||||
|
--[[ oUF.objects
|
||||||
|
Array containing all unit frames created by `oUF:Spawn`.
|
||||||
|
--]]
|
||||||
|
oUF.objects = objects
|
||||||
|
--[[ oUF.headers
|
||||||
|
Array containing all group headers created by `oUF:SpawnHeader`.
|
||||||
|
--]]
|
||||||
|
oUF.headers = headers
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
local ns = oUF
|
||||||
|
local Private = ns.oUF.Private
|
||||||
|
|
||||||
|
function Private.argcheck(value, num, ...)
|
||||||
|
assert(type(num) == 'number', "Bad argument #2 to 'argcheck' (number expected, got " .. type(num) .. ')')
|
||||||
|
|
||||||
|
for i = 1, select('#', arg) do
|
||||||
|
if(type(value) == select(i, unpack(arg))) then return end
|
||||||
|
end
|
||||||
|
|
||||||
|
local types = strjoin(', ', unpack(arg))
|
||||||
|
local name = string.match(debugstack(2,2,0), ": in function [`<](.-)['>]")
|
||||||
|
error(string.format("Bad argument #%d to '%s' (%s expected, got %s)", num, name, types, type(value)), 3)
|
||||||
|
end
|
||||||
|
|
||||||
|
function Private.print(...)
|
||||||
|
print('|cff33ff99oUF:|r', unpack(arg))
|
||||||
|
end
|
||||||
|
|
||||||
|
function Private.error(...)
|
||||||
|
Private.print('|cffff0000Error:|r ' .. string.format(unpack(arg)))
|
||||||
|
end
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
local ns = oUF
|
||||||
|
local oUF = ns.oUF
|
||||||
|
local Private = oUF.Private
|
||||||
|
|
||||||
|
local enableTargetUpdate = Private.enableTargetUpdate
|
||||||
|
|
||||||
|
-- Handles unit specific actions.
|
||||||
|
function oUF:HandleUnit(object, unit)
|
||||||
|
local unit = object.unit or unit
|
||||||
|
|
||||||
|
if(unit == 'target') then
|
||||||
|
object:RegisterEvent('PLAYER_TARGET_CHANGED', object.UpdateAllElements)
|
||||||
|
elseif(unit == 'mouseover') then
|
||||||
|
object:RegisterEvent('UPDATE_MOUSEOVER_UNIT', object.UpdateAllElements)
|
||||||
|
elseif(unit == 'focus') then
|
||||||
|
object:RegisterEvent('PLAYER_FOCUS_CHANGED', object.UpdateAllElements)
|
||||||
|
elseif(string.match(unit, '%w+target')) then
|
||||||
|
enableTargetUpdate(object)
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
<Include file="Tooltip\Load_Tooltip.xml"/>
|
<Include file="Tooltip\Load_Tooltip.xml"/>
|
||||||
<Include file="DataTexts\Load_DataTexts.xml"/>
|
<Include file="DataTexts\Load_DataTexts.xml"/>
|
||||||
<Include file="ActionBars\Load_ActionBars.xml"/>
|
<Include file="ActionBars\Load_ActionBars.xml"/>
|
||||||
|
<Include file="UnitFrames\Load_UnitFrames.xml"/>
|
||||||
<Include file="Maps\Load_Maps.xml"/>
|
<Include file="Maps\Load_Maps.xml"/>
|
||||||
<Include file="Misc\Load_Misc.xml"/>
|
<Include file="Misc\Load_Misc.xml"/>
|
||||||
<Include file="Chat\Load_Chat.xml"/>
|
<Include file="Chat\Load_Chat.xml"/>
|
||||||
|
|||||||
@@ -0,0 +1,297 @@
|
|||||||
|
local E, L, V, P, G = unpack(ElvUI)
|
||||||
|
local UF = E:GetModule("UnitFrames");
|
||||||
|
local ns = oUF
|
||||||
|
local ElvUF = ns.oUF
|
||||||
|
|
||||||
|
local _G = _G;
|
||||||
|
local setmetatable, getfenv, setfenv = setmetatable, getfenv, setfenv;
|
||||||
|
local type, unpack, select, pairs = type, unpack, select, pairs;
|
||||||
|
local min, random = math.min, math.random;
|
||||||
|
local format = string.format;
|
||||||
|
|
||||||
|
local UnitMana = UnitMana;
|
||||||
|
local UnitManaMax = UnitManaMax;
|
||||||
|
local UnitHealth = UnitHealth;
|
||||||
|
local UnitHealthMax = UnitHealthMax;
|
||||||
|
local UnitName = UnitName;
|
||||||
|
local UnitClass = UnitClass;
|
||||||
|
local InCombatLockdown = InCombatLockdown;
|
||||||
|
local UnregisterUnitWatch = UnregisterUnitWatch;
|
||||||
|
local RegisterUnitWatch = RegisterUnitWatch;
|
||||||
|
local RegisterStateDriver = RegisterStateDriver;
|
||||||
|
local LOCALIZED_CLASS_NAMES_MALE = LOCALIZED_CLASS_NAMES_MALE;
|
||||||
|
local CLASS_SORT_ORDER = CLASS_SORT_ORDER;
|
||||||
|
local MAX_RAID_MEMBERS = MAX_RAID_MEMBERS;
|
||||||
|
|
||||||
|
local attributeBlacklist = {["showRaid"] = true, ["showParty"] = true, ["showSolo"] = true}
|
||||||
|
local configEnv
|
||||||
|
local originalEnvs = {}
|
||||||
|
local overrideFuncs = {}
|
||||||
|
|
||||||
|
local function createConfigEnv()
|
||||||
|
if( configEnv ) then return end
|
||||||
|
configEnv = setmetatable({
|
||||||
|
UnitMana = function (unit, displayType)
|
||||||
|
if(unit:find("target") or unit:find("focus")) then
|
||||||
|
return UnitMana(unit, displayType);
|
||||||
|
end
|
||||||
|
|
||||||
|
return random(1, UnitManaMax(unit, displayType) or 1);
|
||||||
|
end,
|
||||||
|
UnitHealth = function(unit)
|
||||||
|
if(unit:find("target") or unit:find("focus")) then
|
||||||
|
return UnitHealth(unit);
|
||||||
|
end
|
||||||
|
|
||||||
|
return random(1, UnitHealthMax(unit));
|
||||||
|
end,
|
||||||
|
UnitName = function(unit)
|
||||||
|
if(unit:find("target") or unit:find("focus")) then
|
||||||
|
return UnitName(unit);
|
||||||
|
end
|
||||||
|
if(E.CreditsList) then
|
||||||
|
local max = #E.CreditsList;
|
||||||
|
return E.CreditsList[random(1, max)];
|
||||||
|
end
|
||||||
|
return "Test Name";
|
||||||
|
end,
|
||||||
|
UnitClass = function(unit)
|
||||||
|
if(unit:find("target") or unit:find("focus")) then
|
||||||
|
return UnitClass(unit);
|
||||||
|
end
|
||||||
|
|
||||||
|
local classToken = CLASS_SORT_ORDER[random(1, #(CLASS_SORT_ORDER))];
|
||||||
|
return LOCALIZED_CLASS_NAMES_MALE[classToken], classToken;
|
||||||
|
end,
|
||||||
|
Hex = function(r, g, b)
|
||||||
|
if(type(r) == "table") then
|
||||||
|
if(r.r) then r, g, b = r.r, r.g, r.b; else r, g, b = unpack(r); end
|
||||||
|
end
|
||||||
|
return format("|cff%02x%02x%02x", r*255, g*255, b*255);
|
||||||
|
end,
|
||||||
|
ColorGradient = ElvUF.ColorGradient,
|
||||||
|
}, {
|
||||||
|
__index = _G,
|
||||||
|
__newindex = function(_, key, value) _G[key] = value end,
|
||||||
|
})
|
||||||
|
|
||||||
|
overrideFuncs["namecolor"] = ElvUF.Tags.Methods["namecolor"]
|
||||||
|
overrideFuncs["name:veryshort"] = ElvUF.Tags.Methods["name:veryshort"]
|
||||||
|
overrideFuncs["name:short"] = ElvUF.Tags.Methods["name:short"]
|
||||||
|
overrideFuncs["name:medium"] = ElvUF.Tags.Methods["name:medium"]
|
||||||
|
overrideFuncs["name:long"] = ElvUF.Tags.Methods["name:long"]
|
||||||
|
|
||||||
|
overrideFuncs["healthcolor"] = ElvUF.Tags.Methods["healthcolor"]
|
||||||
|
overrideFuncs["health:current"] = ElvUF.Tags.Methods["health:current"]
|
||||||
|
overrideFuncs["health:deficit"] = ElvUF.Tags.Methods["health:deficit"]
|
||||||
|
overrideFuncs["health:current-percent"] = ElvUF.Tags.Methods["health:current-percent"]
|
||||||
|
overrideFuncs["health:current-max"] = ElvUF.Tags.Methods["health:current-max"]
|
||||||
|
overrideFuncs["health:current-max-percent"] = ElvUF.Tags.Methods["health:current-max-percent"]
|
||||||
|
overrideFuncs["health:max"] = ElvUF.Tags.Methods["health:max"]
|
||||||
|
overrideFuncs["health:percent"] = ElvUF.Tags.Methods["health:percent"]
|
||||||
|
|
||||||
|
overrideFuncs["powercolor"] = ElvUF.Tags.Methods["powercolor"]
|
||||||
|
overrideFuncs["power:current"] = ElvUF.Tags.Methods["power:current"]
|
||||||
|
overrideFuncs["power:deficit"] = ElvUF.Tags.Methods["power:deficit"]
|
||||||
|
overrideFuncs["power:current-percent"] = ElvUF.Tags.Methods["power:current-percent"]
|
||||||
|
overrideFuncs["power:current-max"] = ElvUF.Tags.Methods["power:current-max"]
|
||||||
|
overrideFuncs["power:current-max-percent"] = ElvUF.Tags.Methods["power:current-max-percent"]
|
||||||
|
overrideFuncs["power:max"] = ElvUF.Tags.Methods["power:max"]
|
||||||
|
overrideFuncs["power:percent"] = ElvUF.Tags.Methods["power:percent"]
|
||||||
|
end
|
||||||
|
|
||||||
|
function UF:ForceShow(frame)
|
||||||
|
if InCombatLockdown() then return; end
|
||||||
|
if not frame.isForced then
|
||||||
|
frame.oldUnit = frame.unit
|
||||||
|
frame.unit = "player"
|
||||||
|
frame.isForced = true;
|
||||||
|
frame.oldOnUpdate = frame:GetScript("OnUpdate")
|
||||||
|
end
|
||||||
|
|
||||||
|
frame:SetScript("OnUpdate", nil)
|
||||||
|
frame.forceShowAuras = true
|
||||||
|
UnregisterUnitWatch(frame)
|
||||||
|
RegisterUnitWatch(frame, true)
|
||||||
|
|
||||||
|
frame:Show()
|
||||||
|
if frame:IsVisible() and frame.Update then
|
||||||
|
frame:Update()
|
||||||
|
end
|
||||||
|
|
||||||
|
if(_G[frame:GetName().."Target"]) then
|
||||||
|
self:ForceShow(_G[frame:GetName().."Target"]);
|
||||||
|
end
|
||||||
|
|
||||||
|
if(_G[frame:GetName().."Pet"]) then
|
||||||
|
self:ForceShow(_G[frame:GetName().."Pet"]);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function UF:UnforceShow(frame)
|
||||||
|
if InCombatLockdown() then return; end
|
||||||
|
if not frame.isForced then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
frame.forceShowAuras = nil
|
||||||
|
frame.isForced = nil
|
||||||
|
|
||||||
|
-- Ask the SecureStateDriver to show/hide the frame for us
|
||||||
|
UnregisterUnitWatch(frame)
|
||||||
|
RegisterUnitWatch(frame)
|
||||||
|
|
||||||
|
if frame.oldOnUpdate then
|
||||||
|
frame:SetScript("OnUpdate", frame.oldOnUpdate)
|
||||||
|
frame.oldOnUpdate = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
frame.unit = frame.oldUnit or frame.unit
|
||||||
|
-- If we're visible force an update so everything is properly in a
|
||||||
|
-- non-config mode state
|
||||||
|
if frame:IsVisible() and frame.Update then
|
||||||
|
frame:Update()
|
||||||
|
end
|
||||||
|
|
||||||
|
if(_G[frame:GetName().."Target"]) then
|
||||||
|
self:UnforceShow(_G[frame:GetName().."Target"])
|
||||||
|
end
|
||||||
|
|
||||||
|
if(_G[frame:GetName().."Pet"]) then
|
||||||
|
self:UnforceShow(_G[frame:GetName().."Pet"])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function UF:ShowChildUnits(header, ...)
|
||||||
|
header.isForced = true
|
||||||
|
|
||||||
|
for i=1, select("#", ...) do
|
||||||
|
local frame = select(i, ...)
|
||||||
|
frame:RegisterForClicks(nil)
|
||||||
|
frame:SetID(i)
|
||||||
|
frame.TargetGlow:SetAlpha(0)
|
||||||
|
self:ForceShow(frame)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function UF:UnshowChildUnits(header, ...)
|
||||||
|
header.isForced = nil
|
||||||
|
|
||||||
|
for i=1, select("#", ...) do
|
||||||
|
local frame = select(i, ...)
|
||||||
|
frame:RegisterForClicks(self.db.targetOnMouseDown and "AnyDown" or "AnyUp")
|
||||||
|
frame.TargetGlow:SetAlpha(1)
|
||||||
|
self:UnforceShow(frame)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function OnAttributeChanged(self)
|
||||||
|
if not self:GetParent().forceShow and not self.forceShow then return; end
|
||||||
|
if not self:IsShown() then return end
|
||||||
|
|
||||||
|
local db = self.db or self:GetParent().db
|
||||||
|
local maxUnits = MAX_RAID_MEMBERS
|
||||||
|
|
||||||
|
local startingIndex = db.raidWideSorting and -(min(db.numGroups * (db.groupsPerRowCol * 5), maxUnits) + 1) or -4
|
||||||
|
if self:GetAttribute("startingIndex") ~= startingIndex then
|
||||||
|
self:SetAttribute("startingIndex", startingIndex)
|
||||||
|
UF:ShowChildUnits(self, self:GetChildren())
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function UF:HeaderConfig(header, configMode)
|
||||||
|
if InCombatLockdown() then return; end
|
||||||
|
|
||||||
|
createConfigEnv()
|
||||||
|
header.forceShow = configMode
|
||||||
|
header.forceShowAuras = configMode
|
||||||
|
header.isForced = configMode
|
||||||
|
|
||||||
|
if configMode then
|
||||||
|
for _, func in pairs(overrideFuncs) do
|
||||||
|
if type(func) == "function" then
|
||||||
|
if not originalEnvs[func] then
|
||||||
|
originalEnvs[func] = getfenv(func)
|
||||||
|
setfenv(func, configEnv)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
RegisterStateDriver(header, "visibility", "show")
|
||||||
|
else
|
||||||
|
for func, env in pairs(originalEnvs) do
|
||||||
|
setfenv(func, env)
|
||||||
|
originalEnvs[func] = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
RegisterStateDriver(header, "visibility", header.db.visibility)
|
||||||
|
|
||||||
|
if(header:GetScript("OnEvent")) then
|
||||||
|
header:GetScript("OnEvent")(header, "PLAYER_ENTERING_WORLD");
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for i=1, #header.groups do
|
||||||
|
local group = header.groups[i]
|
||||||
|
|
||||||
|
if group:IsShown() then
|
||||||
|
group.forceShow = header.forceShow
|
||||||
|
group.forceShowAuras = header.forceShowAuras
|
||||||
|
group:HookScript("OnAttributeChanged", OnAttributeChanged)
|
||||||
|
if configMode then
|
||||||
|
for key in pairs(attributeBlacklist) do
|
||||||
|
group:SetAttribute(key, nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
OnAttributeChanged(group)
|
||||||
|
|
||||||
|
group:Update()
|
||||||
|
else
|
||||||
|
for key in pairs(attributeBlacklist) do
|
||||||
|
group:SetAttribute(key, true)
|
||||||
|
end
|
||||||
|
|
||||||
|
UF:UnshowChildUnits(group, group:GetChildren())
|
||||||
|
group:SetAttribute("startingIndex", 1)
|
||||||
|
|
||||||
|
group:Update()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
UF["headerFunctions"][header.groupName]:AdjustVisibility(header);
|
||||||
|
end
|
||||||
|
|
||||||
|
function UF:PLAYER_REGEN_DISABLED()
|
||||||
|
for _, header in pairs(UF["headers"]) do
|
||||||
|
if header.forceShow then
|
||||||
|
self:HeaderConfig(header)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, unit in pairs(UF["units"]) do
|
||||||
|
local frame = self[unit]
|
||||||
|
if frame and frame.forceShow then
|
||||||
|
self:UnforceShow(frame)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for i=1, 5 do
|
||||||
|
if self["arena"..i] and self["arena"..i].isForced then
|
||||||
|
self:UnforceShow(self["arena"..i])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for i=1, 4 do
|
||||||
|
if self["boss"..i] and self["boss"..i].isForced then
|
||||||
|
self:UnforceShow(self["boss"..i])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for i=1, 4 do
|
||||||
|
if self["party"..i] and self["party"..i].isForced then
|
||||||
|
self:UnforceShow(self["party"..i])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
UF:RegisterEvent("PLAYER_REGEN_DISABLED")
|
||||||
@@ -0,0 +1,218 @@
|
|||||||
|
local E, L, V, P, G = unpack(ElvUI)
|
||||||
|
local UF = E:GetModule("UnitFrames")
|
||||||
|
|
||||||
|
local random = random
|
||||||
|
|
||||||
|
local CreateFrame = CreateFrame
|
||||||
|
local UnitIsTapped = UnitIsTapped
|
||||||
|
local UnitIsTappedByPlayer = UnitIsTappedByPlayer
|
||||||
|
local UnitReaction = UnitReaction
|
||||||
|
local UnitIsPlayer = UnitIsPlayer
|
||||||
|
local UnitClass = UnitClass
|
||||||
|
local UnitIsDeadOrGhost = UnitIsDeadOrGhost
|
||||||
|
|
||||||
|
local ns = oUF
|
||||||
|
local ElvUF = ns.oUF
|
||||||
|
assert(ElvUF, "ElvUI was unable to locate oUF.")
|
||||||
|
|
||||||
|
function UF:Construct_HealthBar(frame, bg, text, textPos)
|
||||||
|
local health = CreateFrame("StatusBar", nil, frame)
|
||||||
|
UF["statusbars"][health] = true
|
||||||
|
|
||||||
|
health:SetFrameLevel(10)
|
||||||
|
health.PostUpdate = self.PostUpdateHealth
|
||||||
|
|
||||||
|
CreateStatusBarTexturePointer(health)
|
||||||
|
|
||||||
|
if bg then
|
||||||
|
health.bg = health:CreateTexture(nil, "BORDER")
|
||||||
|
health.bg:SetAllPoints()
|
||||||
|
health.bg:SetTexture(E["media"].blankTex)
|
||||||
|
health.bg.multiplier = 0.25
|
||||||
|
end
|
||||||
|
|
||||||
|
if text then
|
||||||
|
health.value = frame.RaisedElementParent:CreateFontString(nil, "OVERLAY")
|
||||||
|
UF:Configure_FontString(health.value)
|
||||||
|
|
||||||
|
local x = -2
|
||||||
|
if textPos == "LEFT" then
|
||||||
|
x = 2
|
||||||
|
end
|
||||||
|
|
||||||
|
health.value:SetPoint(textPos, health, textPos, x, 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
health.colorTapping = true
|
||||||
|
health.colorDisconnected = true
|
||||||
|
E:CreateBackdrop(health, "Default", nil, nil, self.thinBorders, true)
|
||||||
|
|
||||||
|
return health
|
||||||
|
end
|
||||||
|
|
||||||
|
function UF:Configure_HealthBar(frame)
|
||||||
|
if not frame.VARIABLES_SET then return end
|
||||||
|
|
||||||
|
local db = frame.db
|
||||||
|
local health = frame.Health
|
||||||
|
|
||||||
|
health.Smooth = self.db.smoothbars
|
||||||
|
health.SmoothSpeed = self.db.smoothSpeed * 10
|
||||||
|
|
||||||
|
if health.value then
|
||||||
|
local attachPoint = self:GetObjectAnchorPoint(frame, db.health.attachTextTo)
|
||||||
|
health.value:ClearAllPoints()
|
||||||
|
health.value:SetPoint(db.health.position, attachPoint, db.health.position, db.health.xOffset, db.health.yOffset)
|
||||||
|
frame:Tag(health.value, db.health.text_format)
|
||||||
|
end
|
||||||
|
|
||||||
|
health.colorSmooth = nil
|
||||||
|
health.colorHealth = nil
|
||||||
|
health.colorClass = nil
|
||||||
|
health.colorReaction = nil
|
||||||
|
if db.colorOverride and db.colorOverride == "FORCE_ON" then
|
||||||
|
health.colorClass = true
|
||||||
|
health.colorReaction = true
|
||||||
|
elseif db.colorOverride and db.colorOverride == "FORCE_OFF" then
|
||||||
|
if self.db["colors"].colorhealthbyvalue == true then
|
||||||
|
health.colorSmooth = true
|
||||||
|
else
|
||||||
|
health.colorHealth = true
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if self.db.colors.healthclass ~= true then
|
||||||
|
if self.db.colors.colorhealthbyvalue == true then
|
||||||
|
health.colorSmooth = true
|
||||||
|
else
|
||||||
|
health.colorHealth = true
|
||||||
|
end
|
||||||
|
else
|
||||||
|
health.colorClass = (not self.db.colors.forcehealthreaction)
|
||||||
|
health.colorReaction = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
health:ClearAllPoints()
|
||||||
|
if frame.ORIENTATION == "LEFT" then
|
||||||
|
health:SetWidth(frame.UNIT_WIDTH - (frame.BORDER + frame.SPACING) - (frame.HAPPINESS_WIDTH or 0))
|
||||||
|
health:SetHeight(frame.UNIT_HEIGHT - frame.POWERBAR_HEIGHT - (frame.BORDER + frame.SPACING) - frame.CLASSBAR_YOFFSET)
|
||||||
|
|
||||||
|
if frame.USE_POWERBAR_OFFSET then
|
||||||
|
health:SetPoint("TOPRIGHT", frame, "TOPRIGHT", -frame.BORDER - frame.SPACING - frame.POWERBAR_OFFSET - (frame.HAPPINESS_WIDTH or 0), -frame.BORDER - frame.SPACING - frame.CLASSBAR_YOFFSET)
|
||||||
|
health:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT", frame.PORTRAIT_WIDTH + frame.BORDER + frame.SPACING, frame.BORDER + frame.SPACING + frame.POWERBAR_OFFSET)
|
||||||
|
elseif frame.POWERBAR_DETACHED or not frame.USE_POWERBAR or frame.USE_INSET_POWERBAR then
|
||||||
|
health:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT", frame.PORTRAIT_WIDTH + frame.BORDER + frame.SPACING, frame.BORDER + frame.SPACING + frame.BOTTOM_OFFSET)
|
||||||
|
elseif frame.USE_MINI_POWERBAR then
|
||||||
|
health:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT", frame.PORTRAIT_WIDTH + frame.BORDER + frame.SPACING, frame.SPACING + (frame.POWERBAR_HEIGHT/2))
|
||||||
|
else
|
||||||
|
health:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT", frame.PORTRAIT_WIDTH + frame.BORDER + frame.SPACING, frame.BORDER + frame.SPACING + frame.BOTTOM_OFFSET)
|
||||||
|
end
|
||||||
|
elseif frame.ORIENTATION == "RIGHT" then
|
||||||
|
health:SetPoint("TOPLEFT", frame, "TOPLEFT", frame.BORDER + frame.SPACING + (frame.HAPPINESS_WIDTH or 0), -frame.BORDER - frame.SPACING - frame.CLASSBAR_YOFFSET)
|
||||||
|
|
||||||
|
if frame.USE_POWERBAR_OFFSET then
|
||||||
|
health:SetPoint("TOPLEFT", frame, "TOPLEFT", frame.BORDER + frame.SPACING + frame.POWERBAR_OFFSET + (frame.HAPPINESS_WIDTH or 0), -frame.BORDER - frame.SPACING - frame.CLASSBAR_YOFFSET)
|
||||||
|
health:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -frame.PORTRAIT_WIDTH - frame.BORDER - frame.SPACING, frame.BORDER + frame.SPACING + frame.POWERBAR_OFFSET)
|
||||||
|
elseif frame.POWERBAR_DETACHED or not frame.USE_POWERBAR or frame.USE_INSET_POWERBAR then
|
||||||
|
health:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -frame.PORTRAIT_WIDTH - frame.BORDER - frame.SPACING, frame.BORDER + frame.SPACING + frame.BOTTOM_OFFSET)
|
||||||
|
elseif frame.USE_MINI_POWERBAR then
|
||||||
|
health:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -frame.PORTRAIT_WIDTH - frame.BORDER - frame.SPACING, frame.SPACING + (frame.POWERBAR_HEIGHT/2))
|
||||||
|
else
|
||||||
|
health:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -frame.PORTRAIT_WIDTH - frame.BORDER - frame.SPACING, frame.BORDER + frame.SPACING + frame.BOTTOM_OFFSET)
|
||||||
|
end
|
||||||
|
elseif frame.ORIENTATION == "MIDDLE" then
|
||||||
|
health:SetPoint("TOPRIGHT", frame, "TOPRIGHT", -frame.BORDER - frame.SPACING - (frame.HAPPINESS_WIDTH or 0), -frame.BORDER - frame.SPACING - frame.CLASSBAR_YOFFSET)
|
||||||
|
|
||||||
|
if frame.USE_POWERBAR_OFFSET then
|
||||||
|
health:SetPoint("TOPRIGHT", frame, "TOPRIGHT", -frame.BORDER - frame.SPACING - frame.POWERBAR_OFFSET, -frame.BORDER - frame.SPACING - frame.CLASSBAR_YOFFSET)
|
||||||
|
health:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT", frame.BORDER + frame.SPACING + frame.POWERBAR_OFFSET, frame.BORDER + frame.SPACING + frame.POWERBAR_OFFSET)
|
||||||
|
elseif frame.POWERBAR_DETACHED or not frame.USE_POWERBAR or frame.USE_INSET_POWERBAR then
|
||||||
|
health:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT", frame.BORDER + frame.SPACING + frame.POWERBAR_OFFSET, frame.BORDER + frame.SPACING + frame.BOTTOM_OFFSET)
|
||||||
|
elseif frame.USE_MINI_POWERBAR then
|
||||||
|
health:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT", frame.BORDER + frame.SPACING, frame.SPACING + (frame.POWERBAR_HEIGHT/2))
|
||||||
|
else
|
||||||
|
health:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT", frame.PORTRAIT_WIDTH + frame.BORDER + frame.SPACING, frame.BORDER + frame.SPACING + frame.BOTTOM_OFFSET)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
health.bg:ClearAllPoints()
|
||||||
|
if not frame.USE_PORTRAIT_OVERLAY then
|
||||||
|
health.bg:SetParent(health)
|
||||||
|
health.bg:SetAllPoints()
|
||||||
|
else
|
||||||
|
health.bg:SetPoint("BOTTOMLEFT", health.texturePointer, "BOTTOMRIGHT")
|
||||||
|
health.bg:SetPoint("TOPRIGHT", health)
|
||||||
|
health.bg:SetParent(frame.Portrait.overlay)
|
||||||
|
end
|
||||||
|
|
||||||
|
if db.health then
|
||||||
|
if db.health.orientation then
|
||||||
|
health:SetOrientation(db.health.orientation)
|
||||||
|
end
|
||||||
|
|
||||||
|
if db.health.frequentUpdates then
|
||||||
|
health.frequentUpdates = db.health.frequentUpdates
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
UF:ToggleTransparentStatusBar(UF.db.colors.transparentHealth, frame.Health, frame.Health.bg, (frame.USE_PORTRAIT and frame.USE_PORTRAIT_OVERLAY) ~= true)
|
||||||
|
|
||||||
|
frame:UpdateElement("Health")
|
||||||
|
end
|
||||||
|
|
||||||
|
function UF:GetHealthBottomOffset(frame)
|
||||||
|
local bottomOffset = 0
|
||||||
|
if frame.USE_POWERBAR and not frame.POWERBAR_DETACHED and not frame.USE_INSET_POWERBAR then
|
||||||
|
bottomOffset = bottomOffset + frame.POWERBAR_HEIGHT - (frame.BORDER-frame.SPACING)
|
||||||
|
end
|
||||||
|
if frame.USE_INFO_PANEL then
|
||||||
|
bottomOffset = bottomOffset + frame.INFO_PANEL_HEIGHT - (frame.BORDER-frame.SPACING)
|
||||||
|
end
|
||||||
|
|
||||||
|
return bottomOffset
|
||||||
|
end
|
||||||
|
|
||||||
|
function UF:PostUpdateHealth(unit, min, max)
|
||||||
|
local parent = self:GetParent()
|
||||||
|
if parent.isForced then
|
||||||
|
min = random(1, max)
|
||||||
|
self:SetValue(min)
|
||||||
|
end
|
||||||
|
|
||||||
|
local r, g, b = self:GetStatusBarColor()
|
||||||
|
local colors = E.db["unitframe"]["colors"]
|
||||||
|
if ((colors.healthclass == true and colors.colorhealthbyvalue == true) or (colors.colorhealthbyvalue and parent.isForced)) and not (UnitIsTapped(unit) and not UnitIsTappedByPlayer(unit)) then
|
||||||
|
local newr, newg, newb = ElvUF.ColorGradient(min, max, 1, 0, 0, 1, 1, 0, r, g, b)
|
||||||
|
|
||||||
|
self:SetStatusBarColor(newr, newg, newb)
|
||||||
|
if self.bg and self.bg.multiplier then
|
||||||
|
local mu = self.bg.multiplier
|
||||||
|
self.bg:SetVertexColor(newr * mu, newg * mu, newb * mu)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if colors.classbackdrop then
|
||||||
|
local reaction = UnitReaction(unit, "player")
|
||||||
|
local t
|
||||||
|
if UnitIsPlayer(unit) then
|
||||||
|
local _, class = UnitClass(unit)
|
||||||
|
t = parent.colors.class[class]
|
||||||
|
elseif(reaction) then
|
||||||
|
t = parent.colors.reaction[reaction]
|
||||||
|
end
|
||||||
|
|
||||||
|
if t then
|
||||||
|
self.bg:SetVertexColor(t[1], t[2], t[3])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if colors.customhealthbackdrop then
|
||||||
|
local backdrop = colors.health_backdrop
|
||||||
|
self.bg:SetVertexColor(backdrop.r, backdrop.g, backdrop.b)
|
||||||
|
end
|
||||||
|
|
||||||
|
if colors.useDeadBackdrop and UnitIsDeadOrGhost(unit) then
|
||||||
|
local backdrop = colors.health_backdrop_dead
|
||||||
|
self.bg:SetVertexColor(backdrop.r, backdrop.g, backdrop.b)
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
local E, L, V, P, G = unpack(ElvUI)
|
||||||
|
local UF = E:GetModule("UnitFrames")
|
||||||
|
|
||||||
|
function UF:Construct_InfoPanel(frame)
|
||||||
|
local infoPanel = CreateFrame("Frame", nil, frame)
|
||||||
|
infoPanel:SetFrameLevel(7)
|
||||||
|
local thinBorders = self.thinBorders
|
||||||
|
infoPanel:CreateBackdrop("Default", true, nil, thinBorders, true)
|
||||||
|
|
||||||
|
return infoPanel
|
||||||
|
end
|
||||||
|
|
||||||
|
function UF:Configure_InfoPanel(frame)
|
||||||
|
if(not frame.VARIABLES_SET) then return end
|
||||||
|
local db = frame.db
|
||||||
|
|
||||||
|
if(frame.USE_INFO_PANEL) then
|
||||||
|
frame.InfoPanel:Show()
|
||||||
|
frame.InfoPanel:ClearAllPoints()
|
||||||
|
|
||||||
|
if(frame.ORIENTATION == "RIGHT" and not (frame.unitframeType == "arena")) then
|
||||||
|
frame.InfoPanel:Point("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -frame.BORDER - frame.SPACING, frame.BORDER + frame.SPACING)
|
||||||
|
if(frame.USE_POWERBAR and not frame.USE_INSET_POWERBAR and not frame.POWERBAR_DETACHED) then
|
||||||
|
frame.InfoPanel:Point("TOPLEFT", frame.Power.backdrop, "BOTTOMLEFT", frame.BORDER - frame.HAPPINESS_WIDTH, -(frame.SPACING*3))
|
||||||
|
else
|
||||||
|
frame.InfoPanel:Point("TOPLEFT", frame.Health.backdrop, "BOTTOMLEFT", frame.BORDER - frame.HAPPINESS_WIDTH, -(frame.SPACING*3))
|
||||||
|
end
|
||||||
|
else
|
||||||
|
frame.InfoPanel:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT", frame.BORDER + frame.SPACING, frame.BORDER + frame.SPACING)
|
||||||
|
if(frame.USE_POWERBAR and not frame.USE_INSET_POWERBAR and not frame.POWERBAR_DETACHED) then
|
||||||
|
frame.InfoPanel:Point("TOPRIGHT", frame.Power.backdrop, "BOTTOMRIGHT", -frame.BORDER + frame.HAPPINESS_WIDTH, -(frame.SPACING*3))
|
||||||
|
else
|
||||||
|
frame.InfoPanel:Point("TOPRIGHT", frame.Health.backdrop, "BOTTOMRIGHT", -frame.BORDER + frame.HAPPINESS_WIDTH, -(frame.SPACING*3))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local thinBorders = self.thinBorders
|
||||||
|
if(db.infoPanel.transparent) then
|
||||||
|
frame.InfoPanel.backdrop:SetTemplate("Transparent", nil, nil, thinBorders, true)
|
||||||
|
else
|
||||||
|
frame.InfoPanel.backdrop:SetTemplate("Default", true, nil, thinBorders, true)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
frame.InfoPanel:Hide()
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<Ui xmlns="http://www.blizzard.com/wow/ui/">
|
||||||
|
<Script file="Health.lua"/>
|
||||||
|
<Script file="Name.lua"/>
|
||||||
|
<Script file="Portrait.lua"/>
|
||||||
|
<Script file="Power.lua"/>
|
||||||
|
<Script file="InfoPanel.lua"/>
|
||||||
|
</Ui>
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
local E, L, V, P, G = unpack(ElvUI);
|
||||||
|
local UF = E:GetModule("UnitFrames");
|
||||||
|
|
||||||
|
local UnitIsPlayer = UnitIsPlayer
|
||||||
|
|
||||||
|
function UF:Construct_NameText(frame)
|
||||||
|
local name = frame.RaisedElementParent:CreateFontString(nil, "OVERLAY")
|
||||||
|
UF:Configure_FontString(name)
|
||||||
|
name:SetPoint("CENTER", frame.Health)
|
||||||
|
|
||||||
|
return name
|
||||||
|
end
|
||||||
|
|
||||||
|
function UF:UpdateNameSettings(frame, childType)
|
||||||
|
local db = frame.db
|
||||||
|
if childType == "pet" then
|
||||||
|
db = frame.db.petsGroup
|
||||||
|
elseif childType == "target" then
|
||||||
|
db = frame.db.targetsGroup
|
||||||
|
end
|
||||||
|
|
||||||
|
local name = frame.Name
|
||||||
|
if not db.power or not db.power.enable or not db.power.hideonnpc then
|
||||||
|
local attachPoint = self:GetObjectAnchorPoint(frame, db.name.attachTextTo)
|
||||||
|
name:ClearAllPoints()
|
||||||
|
name:SetPoint(db.name.position, attachPoint, db.name.position, db.name.xOffset, db.name.yOffset)
|
||||||
|
end
|
||||||
|
|
||||||
|
frame:Tag(name, db.name.text_format)
|
||||||
|
end
|
||||||
|
|
||||||
|
function UF:PostNamePosition(frame, unit)
|
||||||
|
if not frame.Power.value:IsShown() then return end
|
||||||
|
local db = frame.db
|
||||||
|
if UnitIsPlayer(unit) or (db.power and not db.power.enable) then
|
||||||
|
local position = db.name.position
|
||||||
|
local attachPoint = self:GetObjectAnchorPoint(frame, db.name.attachTextTo)
|
||||||
|
frame.Power.value:SetAlpha(1)
|
||||||
|
|
||||||
|
frame.Name:ClearAllPoints()
|
||||||
|
frame.Name:SetPoint(position, attachPoint, position, db.name.xOffset, db.name.yOffset)
|
||||||
|
else
|
||||||
|
frame.Power.value:SetAlpha(db.power.hideonnpc and 0 or 1)
|
||||||
|
|
||||||
|
frame.Name:ClearAllPoints()
|
||||||
|
frame.Name:SetPoint(frame.Power.value:GetPoint())
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,115 @@
|
|||||||
|
local E, L, V, P, G = unpack(ElvUI);
|
||||||
|
local UF = E:GetModule("UnitFrames");
|
||||||
|
|
||||||
|
local CreateFrame = CreateFrame;
|
||||||
|
|
||||||
|
function UF:Construct_Portrait(frame, type)
|
||||||
|
local portrait;
|
||||||
|
if(type == "texture") then
|
||||||
|
local backdrop = CreateFrame("Frame", nil, frame);
|
||||||
|
portrait = frame:CreateTexture(nil, "OVERLAY");
|
||||||
|
portrait:SetTexCoord(0.15, 0.85, 0.15, 0.85);
|
||||||
|
E:SetOutside(backdrop, portrait);
|
||||||
|
backdrop:SetFrameLevel(frame:GetFrameLevel());
|
||||||
|
E:SetTemplate(backdrop, "Default");
|
||||||
|
portrait.backdrop = backdrop;
|
||||||
|
else
|
||||||
|
portrait = CreateFrame("PlayerModel", nil, frame);
|
||||||
|
E:CreateBackdrop(portrait, "Default", nil, nil, self.thinBorders, true)
|
||||||
|
end
|
||||||
|
|
||||||
|
portrait.PostUpdate = self.PortraitUpdate;
|
||||||
|
|
||||||
|
portrait.overlay = CreateFrame("Frame", nil, frame);
|
||||||
|
portrait.overlay:SetFrameLevel(frame.Health:GetFrameLevel() + 5);
|
||||||
|
|
||||||
|
return portrait;
|
||||||
|
end
|
||||||
|
|
||||||
|
function UF:Configure_Portrait(frame, dontHide)
|
||||||
|
if(not frame.VARIABLES_SET) then return; end
|
||||||
|
local db = frame.db;
|
||||||
|
if(frame.Portrait and not dontHide) then
|
||||||
|
frame.Portrait:Hide();
|
||||||
|
frame.Portrait:ClearAllPoints();
|
||||||
|
frame.Portrait.backdrop:Hide();
|
||||||
|
end
|
||||||
|
frame.Portrait = db.portrait.style == "2D" and frame.Portrait2D or frame.Portrait3D;
|
||||||
|
|
||||||
|
local portrait = frame.Portrait;
|
||||||
|
if(frame.USE_PORTRAIT) then
|
||||||
|
if(not frame:IsElementEnabled("Portrait")) then
|
||||||
|
frame:EnableElement("Portrait", frame.unit);
|
||||||
|
end
|
||||||
|
|
||||||
|
local color = E.db.unitframe.colors.borderColor
|
||||||
|
portrait.backdrop:SetBackdropBorderColor(color.r, color.g, color.b)
|
||||||
|
|
||||||
|
portrait:ClearAllPoints();
|
||||||
|
portrait.backdrop:ClearAllPoints();
|
||||||
|
if(frame.USE_PORTRAIT_OVERLAY) then
|
||||||
|
if(db.portrait.style == "3D") then
|
||||||
|
portrait:SetFrameLevel(frame.Health:GetFrameLevel());
|
||||||
|
else
|
||||||
|
portrait:SetParent(frame.Health);
|
||||||
|
end
|
||||||
|
|
||||||
|
portrait:SetAllPoints(frame.Health);
|
||||||
|
portrait:SetAlpha(0.35);
|
||||||
|
if(not dontHide) then
|
||||||
|
portrait:Show();
|
||||||
|
end
|
||||||
|
portrait.backdrop:Hide();
|
||||||
|
else
|
||||||
|
portrait:SetAlpha(1);
|
||||||
|
if(not dontHide) then
|
||||||
|
portrait:Show();
|
||||||
|
end
|
||||||
|
portrait.backdrop:Show();
|
||||||
|
if(db.portrait.style == "3D") then
|
||||||
|
portrait:SetFrameLevel(frame.Health:GetFrameLevel() - 4);
|
||||||
|
else
|
||||||
|
portrait:SetParent(frame.Health);
|
||||||
|
end
|
||||||
|
|
||||||
|
if(frame.ORIENTATION == "LEFT") then
|
||||||
|
portrait.backdrop:SetPoint("TOPLEFT", frame, "TOPLEFT", frame.SPACING, frame.USE_MINI_CLASSBAR and -(frame.CLASSBAR_YOFFSET+frame.SPACING) or -frame.SPACING);
|
||||||
|
|
||||||
|
if(frame.USE_MINI_POWERBAR or frame.USE_POWERBAR_OFFSET or not frame.USE_POWERBAR or frame.USE_INSET_POWERBAR or frame.POWERBAR_DETACHED) then
|
||||||
|
portrait.backdrop:SetPoint("BOTTOMRIGHT", frame.Health.backdrop, "BOTTOMLEFT", frame.BORDER - frame.SPACING*3, 0);
|
||||||
|
else
|
||||||
|
portrait.backdrop:SetPoint("BOTTOMRIGHT", frame.Power.backdrop, "BOTTOMLEFT", frame.BORDER - frame.SPACING*3, 0);
|
||||||
|
end
|
||||||
|
elseif(frame.ORIENTATION == "RIGHT") then
|
||||||
|
portrait.backdrop:SetPoint("TOPRIGHT", frame, "TOPRIGHT", -frame.SPACING, frame.USE_MINI_CLASSBAR and -(frame.CLASSBAR_YOFFSET+frame.SPACING) or -frame.SPACING);
|
||||||
|
|
||||||
|
if(frame.USE_MINI_POWERBAR or frame.USE_POWERBAR_OFFSET or not frame.USE_POWERBAR or frame.USE_INSET_POWERBAR or frame.POWERBAR_DETACHED) then
|
||||||
|
portrait.backdrop:SetPoint("BOTTOMLEFT", frame.Health.backdrop, "BOTTOMRIGHT", -frame.BORDER + frame.SPACING*3, 0);
|
||||||
|
else
|
||||||
|
portrait.backdrop:SetPoint("BOTTOMLEFT", frame.Power.backdrop, "BOTTOMRIGHT", -frame.BORDER + frame.SPACING*3, 0);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
E:SetInside(portrait, portrait.backdrop, frame.BORDER);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if(frame:IsElementEnabled("Portrait")) then
|
||||||
|
frame:DisableElement("Portrait");
|
||||||
|
portrait:Hide();
|
||||||
|
portrait.backdrop:Hide();
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function UF:PortraitUpdate()
|
||||||
|
local db = self:GetParent().db;
|
||||||
|
if(not db) then return; end
|
||||||
|
|
||||||
|
local portrait = db.portrait;
|
||||||
|
if(portrait.enable and self:GetParent().USE_PORTRAIT_OVERLAY) then
|
||||||
|
self:SetAlpha(0);
|
||||||
|
self:SetAlpha(0.35);
|
||||||
|
else
|
||||||
|
self:SetAlpha(1)
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,228 @@
|
|||||||
|
local E, L, V, P, G = unpack(ElvUI)
|
||||||
|
local UF = E:GetModule("UnitFrames")
|
||||||
|
|
||||||
|
local random = random
|
||||||
|
|
||||||
|
local CreateFrame = CreateFrame
|
||||||
|
|
||||||
|
local ns = oUF
|
||||||
|
local ElvUF = ns.oUF
|
||||||
|
assert(ElvUF, "ElvUI was unable to locate oUF.")
|
||||||
|
|
||||||
|
function UF:Construct_PowerBar(frame, bg, text, textPos)
|
||||||
|
local power = CreateFrame("StatusBar", nil, frame)
|
||||||
|
UF["statusbars"][power] = true
|
||||||
|
|
||||||
|
power.PostUpdate = self.PostUpdatePower
|
||||||
|
|
||||||
|
CreateStatusBarTexturePointer(power)
|
||||||
|
|
||||||
|
if bg then
|
||||||
|
power.bg = power:CreateTexture(nil, "BORDER")
|
||||||
|
power.bg:SetAllPoints()
|
||||||
|
power.bg:SetTexture(E["media"].blankTex)
|
||||||
|
power.bg.multiplier = 0.2
|
||||||
|
end
|
||||||
|
|
||||||
|
if text then
|
||||||
|
power.value = frame.RaisedElementParent:CreateFontString(nil, "OVERLAY")
|
||||||
|
power.value.frequentUpdates = true
|
||||||
|
|
||||||
|
UF:Configure_FontString(power.value)
|
||||||
|
|
||||||
|
local x = -2
|
||||||
|
if textPos == "LEFT" then
|
||||||
|
x = 2
|
||||||
|
end
|
||||||
|
|
||||||
|
power.value:SetPoint(textPos, frame.Health, textPos, x, 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
power.colorDisconnected = false
|
||||||
|
power.colorTapping = false
|
||||||
|
E:CreateBackdrop(power, "Default", nil, nil, self.thinBorders)
|
||||||
|
|
||||||
|
return power
|
||||||
|
end
|
||||||
|
|
||||||
|
function UF:Configure_Power(frame)
|
||||||
|
if not frame.VARIABLES_SET then return end
|
||||||
|
local db = frame.db
|
||||||
|
local power = frame.Power
|
||||||
|
|
||||||
|
if frame.USE_POWERBAR then
|
||||||
|
if not frame:IsElementEnabled("Power") then
|
||||||
|
frame:EnableElement("Power", frame.unit)
|
||||||
|
|
||||||
|
power:Show()
|
||||||
|
end
|
||||||
|
|
||||||
|
power.Smooth = self.db.smoothbars
|
||||||
|
power.SmoothSpeed = self.db.smoothSpeed * 10
|
||||||
|
|
||||||
|
local attachPoint = self:GetObjectAnchorPoint(frame, db.power.attachTextTo)
|
||||||
|
power.value:ClearAllPoints()
|
||||||
|
power.value:SetPoint(db.power.position, attachPoint, db.power.position, db.power.xOffset, db.power.yOffset)
|
||||||
|
frame:Tag(power.value, db.power.text_format)
|
||||||
|
|
||||||
|
if db.power.attachTextTo == "Power" then
|
||||||
|
power.value:SetParent(power)
|
||||||
|
else
|
||||||
|
power.value:SetParent(frame.RaisedElementParent)
|
||||||
|
end
|
||||||
|
|
||||||
|
power.colorClass = nil
|
||||||
|
power.colorReaction = nil
|
||||||
|
power.colorPower = nil
|
||||||
|
if self.db["colors"].powerclass then
|
||||||
|
power.colorClass = true
|
||||||
|
power.colorReaction = true
|
||||||
|
else
|
||||||
|
power.colorPower = true
|
||||||
|
end
|
||||||
|
|
||||||
|
local heightChanged = false
|
||||||
|
if (not self.thinBorders and not E.PixelMode) and frame.POWERBAR_HEIGHT < 7 then
|
||||||
|
frame.POWERBAR_HEIGHT = 7
|
||||||
|
if(db.power) then db.power.height = 7 end
|
||||||
|
heightChanged = true
|
||||||
|
elseif (self.thinBorders or E.PixelMode) and frame.POWERBAR_HEIGHT < 3 then
|
||||||
|
frame.POWERBAR_HEIGHT = 3
|
||||||
|
if db.power then db.power.height = 3 end
|
||||||
|
heightChanged = true
|
||||||
|
end
|
||||||
|
if heightChanged then
|
||||||
|
frame.BOTTOM_OFFSET = UF:GetHealthBottomOffset(frame)
|
||||||
|
UF:Configure_HealthBar(frame)
|
||||||
|
end
|
||||||
|
|
||||||
|
power:ClearAllPoints()
|
||||||
|
if frame.POWERBAR_DETACHED then
|
||||||
|
power:SetWidth(frame.POWERBAR_WIDTH - ((frame.BORDER + frame.SPACING)*2))
|
||||||
|
power:SetHeight(frame.POWERBAR_HEIGHT - ((frame.BORDER + frame.SPACING)*2))
|
||||||
|
if not power.Holder or (power.Holder and not power.Holder.mover) then
|
||||||
|
power.Holder = CreateFrame("Frame", nil, power)
|
||||||
|
power.Holder:SetWidth(frame.POWERBAR_WIDTH)
|
||||||
|
power.Holder:SetHeight(frame.POWERBAR_HEIGHT)
|
||||||
|
power.Holder:SetPoint("BOTTOM", frame, "BOTTOM", 0, -20)
|
||||||
|
power:ClearAllPoints()
|
||||||
|
power:SetPoint("BOTTOMLEFT", power.Holder, "BOTTOMLEFT", frame.BORDER+frame.SPACING, frame.BORDER+frame.SPACING)
|
||||||
|
|
||||||
|
if(frame.unitframeType and frame.unitframeType == "player") then
|
||||||
|
E:CreateMover(power.Holder, "PlayerPowerBarMover", L["Player Powerbar"], nil, nil, nil, "ALL,SOLO")
|
||||||
|
elseif(frame.unitframeType and frame.unitframeType == "target") then
|
||||||
|
E:CreateMover(power.Holder, "TargetPowerBarMover", L["Target Powerbar"], nil, nil, nil, "ALL,SOLO")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
power.Holder:SetWidth(frame.POWERBAR_WIDTH)
|
||||||
|
power.Holder:SetHeight(frame.POWERBAR_HEIGHT)
|
||||||
|
power:ClearAllPoints()
|
||||||
|
power:SetPoint("BOTTOMLEFT", power.Holder, "BOTTOMLEFT", frame.BORDER+frame.SPACING, frame.BORDER+frame.SPACING)
|
||||||
|
power.Holder.mover:SetScale(1)
|
||||||
|
power.Holder.mover:SetAlpha(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
power:SetFrameLevel(50)
|
||||||
|
elseif frame.USE_POWERBAR_OFFSET then
|
||||||
|
if frame.ORIENTATION == "LEFT" then
|
||||||
|
power:SetPoint("TOPRIGHT", frame.Health, "TOPRIGHT", frame.POWERBAR_OFFSET + frame.HAPPINESS_WIDTH, -frame.POWERBAR_OFFSET)
|
||||||
|
power:SetPoint("BOTTOMLEFT", frame.Health, "BOTTOMLEFT", frame.POWERBAR_OFFSET, -frame.POWERBAR_OFFSET)
|
||||||
|
elseif frame.ORIENTATION == "MIDDLE" then
|
||||||
|
power:SetPoint("TOPLEFT", frame, "TOPLEFT", frame.BORDER + frame.SPACING, -frame.POWERBAR_OFFSET -frame.CLASSBAR_YOFFSET)
|
||||||
|
power:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -frame.BORDER - frame.SPACING, frame.BORDER)
|
||||||
|
else
|
||||||
|
power:SetPoint("TOPLEFT", frame.Health, "TOPLEFT", -frame.POWERBAR_OFFSET - frame.HAPPINESS_WIDTH, -frame.POWERBAR_OFFSET)
|
||||||
|
power:SetPoint("BOTTOMRIGHT", frame.Health, "BOTTOMRIGHT", -frame.POWERBAR_OFFSET, -frame.POWERBAR_OFFSET)
|
||||||
|
end
|
||||||
|
power:SetFrameLevel(frame.Health:GetFrameLevel() -5)
|
||||||
|
elseif frame.USE_INSET_POWERBAR then
|
||||||
|
power:SetHeight(frame.POWERBAR_HEIGHT - ((frame.BORDER + frame.SPACING)*2))
|
||||||
|
power:SetPoint("BOTTOMLEFT", frame.Health, "BOTTOMLEFT", frame.BORDER + (frame.BORDER*2), frame.BORDER + (frame.BORDER*2))
|
||||||
|
power:SetPoint("BOTTOMRIGHT", frame.Health, "BOTTOMRIGHT", -(frame.BORDER + (frame.BORDER*2)), frame.BORDER + (frame.BORDER*2))
|
||||||
|
power:SetFrameLevel(50)
|
||||||
|
elseif frame.USE_MINI_POWERBAR then
|
||||||
|
power:SetWidth(frame.POWERBAR_HEIGHT - ((frame.BORDER + frame.SPACING)*2))
|
||||||
|
|
||||||
|
if frame.ORIENTATION == "LEFT" then
|
||||||
|
power:SetWidth(frame.POWERBAR_WIDTH - frame.BORDER*2)
|
||||||
|
power:SetPoint("RIGHT", frame, "BOTTOMRIGHT", -(frame.BORDER*2 + 4) -frame.HAPPINESS_WIDTH, ((frame.POWERBAR_HEIGHT-frame.BORDER)/2))
|
||||||
|
elseif frame.ORIENTATION == "RIGHT" then
|
||||||
|
power:SetWidth(frame.POWERBAR_WIDTH - frame.BORDER*2)
|
||||||
|
power:SetPoint("LEFT", frame, "BOTTOMLEFT", (frame.BORDER*2 + 4) +frame.HAPPINESS_WIDTH, ((frame.POWERBAR_HEIGHT-frame.BORDER)/2))
|
||||||
|
else
|
||||||
|
power:SetPoint("LEFT", frame, "BOTTOMLEFT", (frame.BORDER*2 + 4), ((frame.POWERBAR_HEIGHT-frame.BORDER)/2))
|
||||||
|
power:SetPoint("RIGHT", frame, "BOTTOMRIGHT", -(frame.BORDER*2 + 4) -frame.HAPPINESS_WIDTH, ((frame.POWERBAR_HEIGHT-frame.BORDER)/2))
|
||||||
|
end
|
||||||
|
|
||||||
|
power:SetFrameLevel(50)
|
||||||
|
else
|
||||||
|
power:SetPoint("TOPRIGHT", frame.Health.backdrop, "BOTTOMRIGHT", -frame.BORDER, -frame.SPACING*3)
|
||||||
|
power:SetPoint("TOPLEFT", frame.Health.backdrop, "BOTTOMLEFT", frame.BORDER, -frame.SPACING*3)
|
||||||
|
power:SetHeight(frame.POWERBAR_HEIGHT - ((frame.BORDER + frame.SPACING)*2))
|
||||||
|
|
||||||
|
power:SetFrameLevel(frame.Health:GetFrameLevel() - 5)
|
||||||
|
end
|
||||||
|
|
||||||
|
if not frame.POWERBAR_DETACHED then
|
||||||
|
if power.Holder and power.Holder.mover then
|
||||||
|
power.Holder.mover:SetScale(0.0001)
|
||||||
|
power.Holder.mover:SetAlpha(0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if db.power.strataAndLevel and db.power.strataAndLevel.useCustomStrata then
|
||||||
|
power:SetFrameStrata(db.power.strataAndLevel.frameStrata)
|
||||||
|
else
|
||||||
|
power:SetFrameStrata("LOW")
|
||||||
|
end
|
||||||
|
|
||||||
|
if db.power.strataAndLevel and db.power.strataAndLevel.useCustomLevel then
|
||||||
|
power:SetFrameLevel(db.power.strataAndLevel.frameLevel)
|
||||||
|
power.backdrop:SetFrameLevel(power:GetFrameLevel() - 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
if frame.POWERBAR_DETACHED and db.power.parent == "UIPARENT" then
|
||||||
|
power:SetParent(E.UIParent)
|
||||||
|
else
|
||||||
|
power:SetParent(frame)
|
||||||
|
end
|
||||||
|
elseif frame:IsElementEnabled("Power") then
|
||||||
|
frame:DisableElement("Power")
|
||||||
|
power:Hide()
|
||||||
|
end
|
||||||
|
|
||||||
|
if frame.DruidAltMana then
|
||||||
|
if(db.power.druidMana) then
|
||||||
|
frame:EnableElement("DruidAltMana")
|
||||||
|
else
|
||||||
|
frame:DisableElement("DruidAltMana")
|
||||||
|
frame.DruidAltMana:Hide()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if frame.Power then
|
||||||
|
UF:ToggleTransparentStatusBar(UF.db.colors.transparentPower, frame.Power, frame.Power.bg)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function UF:PostUpdatePower(unit, cur, max)
|
||||||
|
local parent = self:GetParent()
|
||||||
|
|
||||||
|
if parent.isForced then
|
||||||
|
local pType = random(0, 3)
|
||||||
|
local color = ElvUF["colors"].power[pType]
|
||||||
|
cur = random(1, max)
|
||||||
|
self:SetValue(cur)
|
||||||
|
|
||||||
|
if not self.colorClass then
|
||||||
|
self:SetStatusBarColor(color[1], color[2], color[3])
|
||||||
|
local mu = self.bg.multiplier or 1
|
||||||
|
self.bg:SetVertexColor(color[1] * mu, color[2] * mu, color[3] * mu)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local db = parent.db
|
||||||
|
if db and db.power and db.power.hideonnpc then
|
||||||
|
UF:PostNamePosition(parent, unit)
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<Ui xmlns="http://www.blizzard.com/wow/ui/">
|
||||||
|
<Script file="UnitFrames.lua"/>
|
||||||
|
<Script file="Tags.lua"/>
|
||||||
|
<Include file="Elements\Load_Elements.xml"/>
|
||||||
|
<Include file="Units\Load_Units.xml"/>
|
||||||
|
</Ui>
|
||||||
@@ -0,0 +1,552 @@
|
|||||||
|
local E, L, V, P, G = unpack(ElvUI)
|
||||||
|
|
||||||
|
local _G = _G;
|
||||||
|
local floor = math.floor;
|
||||||
|
local format = string.format;
|
||||||
|
|
||||||
|
local GetPVPTimer = GetPVPTimer;
|
||||||
|
local GetTime = GetTime;
|
||||||
|
local UnitClass = UnitClass;
|
||||||
|
local UnitClassification = UnitClassification;
|
||||||
|
local UnitGUID = UnitGUID;
|
||||||
|
local UnitIsAFK = UnitIsAFK;
|
||||||
|
local UnitIsConnected = UnitIsConnected;
|
||||||
|
local UnitIsDND = UnitIsDND;
|
||||||
|
local UnitIsDead = UnitIsDead;
|
||||||
|
local UnitIsDeadOrGhost = UnitIsDeadOrGhost;
|
||||||
|
local UnitIsGhost = UnitIsGhost;
|
||||||
|
local UnitIsPVP = UnitIsPVP;
|
||||||
|
local UnitIsPVPFreeForAll = UnitIsPVPFreeForAll;
|
||||||
|
local UnitIsPlayer = UnitIsPlayer;
|
||||||
|
local UnitLevel = UnitLevel;
|
||||||
|
local UnitMana = UnitMana;
|
||||||
|
local UnitManaMax = UnitManaMax;
|
||||||
|
local UnitPowerType = UnitPowerType;
|
||||||
|
local UnitReaction = UnitReaction;
|
||||||
|
local DEFAULT_AFK_MESSAGE = DEFAULT_AFK_MESSAGE;
|
||||||
|
local PVP = PVP;
|
||||||
|
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
-- Tags
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["afk"] = "PLAYER_FLAGS_CHANGED"
|
||||||
|
ElvUF.Tags.Methods["afk"] = function(unit)
|
||||||
|
local isAFK = UnitIsAFK(unit)
|
||||||
|
if isAFK then
|
||||||
|
return ("|cffFFFFFF[|r|cffFF0000%s|r|cFFFFFFFF]|r"):format(DEFAULT_AFK_MESSAGE)
|
||||||
|
else
|
||||||
|
return ""
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["healthcolor"] = "UNIT_HEALTH UNIT_CONNECTION PLAYER_FLAGS_CHANGED"
|
||||||
|
ElvUF.Tags.Methods["healthcolor"] = function(unit)
|
||||||
|
if UnitIsDeadOrGhost(unit) or not UnitIsConnected(unit) then
|
||||||
|
return Hex(0.84, 0.75, 0.65)
|
||||||
|
else
|
||||||
|
local r, g, b = ElvUF.ColorGradient(UnitHealth(unit), UnitHealthMax(unit), 0.69, 0.31, 0.31, 0.65, 0.63, 0.35, 0.33, 0.59, 0.33)
|
||||||
|
return Hex(r, g, b)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["health:current"] = "UNIT_HEALTH UNIT_MAXHEALTH UNIT_CONNECTION PLAYER_FLAGS_CHANGED"
|
||||||
|
ElvUF.Tags.Methods["health:current"] = function(unit)
|
||||||
|
local status = UnitIsDead(unit) and L["Dead"] or UnitIsGhost(unit) and L["Ghost"] or not UnitIsConnected(unit) and L["Offline"]
|
||||||
|
if (status) then
|
||||||
|
return status
|
||||||
|
else
|
||||||
|
return E:GetFormattedText("CURRENT", UnitHealth(unit), UnitHealthMax(unit))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["health:deficit"] = "UNIT_HEALTH UNIT_MAXHEALTH UNIT_CONNECTION PLAYER_FLAGS_CHANGED"
|
||||||
|
ElvUF.Tags.Methods["health:deficit"] = function(unit)
|
||||||
|
local status = UnitIsDead(unit) and L["Dead"] or UnitIsGhost(unit) and L["Ghost"] or not UnitIsConnected(unit) and L["Offline"]
|
||||||
|
|
||||||
|
if (status) then
|
||||||
|
return status
|
||||||
|
else
|
||||||
|
return E:GetFormattedText("DEFICIT", UnitHealth(unit), UnitHealthMax(unit))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["health:current-percent"] = "UNIT_HEALTH UNIT_MAXHEALTH UNIT_CONNECTION PLAYER_FLAGS_CHANGED"
|
||||||
|
ElvUF.Tags.Methods["health:current-percent"] = function(unit)
|
||||||
|
local status = UnitIsDead(unit) and L["Dead"] or UnitIsGhost(unit) and L["Ghost"] or not UnitIsConnected(unit) and L["Offline"]
|
||||||
|
|
||||||
|
if (status) then
|
||||||
|
return status
|
||||||
|
else
|
||||||
|
return E:GetFormattedText("CURRENT_PERCENT", UnitHealth(unit), UnitHealthMax(unit))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["health:current-max"] = "UNIT_HEALTH UNIT_MAXHEALTH UNIT_CONNECTION PLAYER_FLAGS_CHANGED"
|
||||||
|
ElvUF.Tags.Methods["health:current-max"] = function(unit)
|
||||||
|
local status = UnitIsDead(unit) and L["Dead"] or UnitIsGhost(unit) and L["Ghost"] or not UnitIsConnected(unit) and L["Offline"]
|
||||||
|
|
||||||
|
if (status) then
|
||||||
|
return status
|
||||||
|
else
|
||||||
|
return E:GetFormattedText("CURRENT_MAX", UnitHealth(unit), UnitHealthMax(unit))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["health:current-max-percent"] = "UNIT_HEALTH UNIT_MAXHEALTH UNIT_CONNECTION PLAYER_FLAGS_CHANGED"
|
||||||
|
ElvUF.Tags.Methods["health:current-max-percent"] = function(unit)
|
||||||
|
local status = UnitIsDead(unit) and L["Dead"] or UnitIsGhost(unit) and L["Ghost"] or not UnitIsConnected(unit) and L["Offline"]
|
||||||
|
|
||||||
|
if (status) then
|
||||||
|
return status
|
||||||
|
else
|
||||||
|
return E:GetFormattedText("CURRENT_MAX_PERCENT", UnitHealth(unit), UnitHealthMax(unit))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["health:max"] = "UNIT_MAXHEALTH"
|
||||||
|
ElvUF.Tags.Methods["health:max"] = function(unit)
|
||||||
|
local max = UnitHealthMax(unit)
|
||||||
|
|
||||||
|
return E:GetFormattedText("CURRENT", max, max)
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["health:percent"] = "UNIT_HEALTH UNIT_MAXHEALTH UNIT_CONNECTION PLAYER_FLAGS_CHANGED"
|
||||||
|
ElvUF.Tags.Methods["health:percent"] = function(unit)
|
||||||
|
local status = UnitIsDead(unit) and L["Dead"] or UnitIsGhost(unit) and L["Ghost"] or not UnitIsConnected(unit) and L["Offline"]
|
||||||
|
|
||||||
|
if (status) then
|
||||||
|
return status
|
||||||
|
else
|
||||||
|
return E:GetFormattedText("PERCENT", UnitHealth(unit), UnitHealthMax(unit))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["health:current-nostatus"] = "UNIT_HEALTH UNIT_MAXHEALTH";
|
||||||
|
ElvUF.Tags.Methods["health:current-nostatus"] = function(unit)
|
||||||
|
return E:GetFormattedText("CURRENT", UnitHealth(unit), UnitHealthMax(unit));
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["health:deficit-nostatus"] = "UNIT_HEALTH UNIT_MAXHEALTH";
|
||||||
|
ElvUF.Tags.Methods["health:deficit-nostatus"] = function(unit)
|
||||||
|
return E:GetFormattedText("DEFICIT", UnitHealth(unit), UnitHealthMax(unit));
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["health:current-percent-nostatus"] = "UNIT_HEALTH UNIT_MAXHEALTH";
|
||||||
|
ElvUF.Tags.Methods["health:current-percent-nostatus"] = function(unit)
|
||||||
|
return E:GetFormattedText("CURRENT_PERCENT", UnitHealth(unit), UnitHealthMax(unit));
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["health:current-max-nostatus"] = "UNIT_HEALTH UNIT_MAXHEALTH";
|
||||||
|
ElvUF.Tags.Methods["health:current-max-nostatus"] = function(unit)
|
||||||
|
return E:GetFormattedText("CURRENT_MAX", UnitHealth(unit), UnitHealthMax(unit));
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["health:current-max-percent-nostatus"] = "UNIT_HEALTH UNIT_MAXHEALTH";
|
||||||
|
ElvUF.Tags.Methods["health:current-max-percent-nostatus"] = function(unit)
|
||||||
|
return E:GetFormattedText("CURRENT_MAX_PERCENT", UnitHealth(unit), UnitHealthMax(unit));
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["health:percent-nostatus"] = "UNIT_HEALTH UNIT_MAXHEALTH";
|
||||||
|
ElvUF.Tags.Methods["health:percent-nostatus"] = function(unit)
|
||||||
|
return E:GetFormattedText("PERCENT", UnitHealth(unit), UnitHealthMax(unit));
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["health:deficit-percent:name"] = "UNIT_HEALTH UNIT_MAXHEALTH";
|
||||||
|
ElvUF.Tags.Methods["health:deficit-percent:name"] = function(unit)
|
||||||
|
local currentHealth = UnitHealth(unit)
|
||||||
|
local deficit = UnitHealthMax(unit) - currentHealth;
|
||||||
|
|
||||||
|
if (deficit > 0 and currentHealth > 0) then
|
||||||
|
return _TAGS["health:percent-nostatus"](unit);
|
||||||
|
else
|
||||||
|
return _TAGS["name"](unit);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["health:deficit-percent:name-long"] = "UNIT_HEALTH UNIT_MAXHEALTH"
|
||||||
|
ElvUF.Tags.Methods["health:deficit-percent:name-long"] = function(unit)
|
||||||
|
local currentHealth = UnitHealth(unit)
|
||||||
|
local deficit = UnitHealthMax(unit) - currentHealth
|
||||||
|
|
||||||
|
if (deficit > 0 and currentHealth > 0) then
|
||||||
|
return _TAGS["health:percent-nostatus"](unit)
|
||||||
|
else
|
||||||
|
return _TAGS["name:long"](unit)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["health:deficit-percent:name-medium"] = "UNIT_HEALTH UNIT_MAXHEALTH"
|
||||||
|
ElvUF.Tags.Methods["health:deficit-percent:name-medium"] = function(unit)
|
||||||
|
local currentHealth = UnitHealth(unit)
|
||||||
|
local deficit = UnitHealthMax(unit) - currentHealth
|
||||||
|
|
||||||
|
if (deficit > 0 and currentHealth > 0) then
|
||||||
|
return _TAGS["health:percent-nostatus"](unit)
|
||||||
|
else
|
||||||
|
return _TAGS["name:medium"](unit)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["health:deficit-percent:name-short"] = "UNIT_HEALTH UNIT_MAXHEALTH"
|
||||||
|
ElvUF.Tags.Methods["health:deficit-percent:name-short"] = function(unit)
|
||||||
|
local currentHealth = UnitHealth(unit)
|
||||||
|
local deficit = UnitHealthMax(unit) - currentHealth
|
||||||
|
|
||||||
|
if (deficit > 0 and currentHealth > 0) then
|
||||||
|
return _TAGS["health:percent-nostatus"](unit)
|
||||||
|
else
|
||||||
|
return _TAGS["name:short"](unit)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["health:deficit-percent:name-veryshort"] = "UNIT_HEALTH UNIT_MAXHEALTH"
|
||||||
|
ElvUF.Tags.Methods["health:deficit-percent:name-veryshort"] = function(unit)
|
||||||
|
local currentHealth = UnitHealth(unit)
|
||||||
|
local deficit = UnitHealthMax(unit) - currentHealth
|
||||||
|
|
||||||
|
if (deficit > 0 and currentHealth > 0) then
|
||||||
|
return _TAGS["health:percent-nostatus"](unit)
|
||||||
|
else
|
||||||
|
return _TAGS["name:veryshort"](unit)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["powercolor"] = "UNIT_ENERGY UNIT_FOCUS UNIT_MANA UNIT_RAGE UNIT_RUNIC_POWER UNIT_MAXPOWER"
|
||||||
|
ElvUF.Tags.Methods["powercolor"] = function(unit)
|
||||||
|
local color = ElvUF["colors"].power[UnitPowerType(unit)]
|
||||||
|
if color then
|
||||||
|
return Hex(color[1], color[2], color[3])
|
||||||
|
else
|
||||||
|
return Hex(unpack(ElvUF["colors"].power[0]))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["power:current"] = "UNIT_ENERGY UNIT_FOCUS UNIT_MANA UNIT_RAGE UNIT_RUNIC_POWER UNIT_MAXPOWER"
|
||||||
|
ElvUF.Tags.Methods["power:current"] = function(unit)
|
||||||
|
local min = UnitMana(unit)
|
||||||
|
|
||||||
|
return min == 0 and " " or E:GetFormattedText("CURRENT", min, UnitManaMax(unit))
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["power:current-max"] = "UNIT_ENERGY UNIT_FOCUS UNIT_MANA UNIT_RAGE UNIT_RUNIC_POWER UNIT_MAXPOWER"
|
||||||
|
ElvUF.Tags.Methods["power:current-max"] = function(unit)
|
||||||
|
local min = UnitMana(unit)
|
||||||
|
|
||||||
|
return min == 0 and " " or E:GetFormattedText("CURRENT_MAX", min, UnitManaMax(unit))
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["power:current-percent"] = "UNIT_ENERGY UNIT_FOCUS UNIT_MANA UNIT_RAGE UNIT_RUNIC_POWER UNIT_MAXPOWER"
|
||||||
|
ElvUF.Tags.Methods["power:current-percent"] = function(unit)
|
||||||
|
local min = UnitMana(unit)
|
||||||
|
|
||||||
|
return min == 0 and " " or E:GetFormattedText("CURRENT_PERCENT", min, UnitManaMax(unit))
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["power:current-max-percent"] = "UNIT_ENERGY UNIT_FOCUS UNIT_MANA UNIT_RAGE UNIT_RUNIC_POWER UNIT_MAXPOWER"
|
||||||
|
ElvUF.Tags.Methods["power:current-max-percent"] = function(unit)
|
||||||
|
local min = UnitMana(unit)
|
||||||
|
|
||||||
|
return min == 0 and " " or E:GetFormattedText("CURRENT_MAX_PERCENT", min, UnitManaMax(unit))
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["power:percent"] = "UNIT_ENERGY UNIT_FOCUS UNIT_MANA UNIT_RAGE UNIT_RUNIC_POWER UNIT_MAXPOWER"
|
||||||
|
ElvUF.Tags.Methods["power:percent"] = function(unit)
|
||||||
|
local min = UnitMana(unit)
|
||||||
|
|
||||||
|
return min == 0 and " " or E:GetFormattedText("PERCENT", min, UnitManaMax(unit))
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["power:deficit"] = "UNIT_ENERGY UNIT_FOCUS UNIT_MANA UNIT_RAGE UNIT_RUNIC_POWER UNIT_MAXPOWER"
|
||||||
|
ElvUF.Tags.Methods["power:deficit"] = function(unit)
|
||||||
|
return E:GetFormattedText("DEFICIT", UnitMana(unit), UnitManaMax(unit))
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["power:max"] = "UNIT_MAXENERGY UNIT_MAXFOCUS UNIT_MAXMANA UNIT_MAXRAGE UNIT_MAXRUNIC_POWER"
|
||||||
|
ElvUF.Tags.Methods["power:max"] = function(unit)
|
||||||
|
local max = UnitManaMax(unit)
|
||||||
|
|
||||||
|
return E:GetFormattedText("CURRENT", max, max)
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Methods["manacolor"] = function()
|
||||||
|
local altR, altG, altB = PowerBarColor["MANA"].r, PowerBarColor["MANA"].g, PowerBarColor["MANA"].b
|
||||||
|
local color = ElvUF["colors"].power["MANA"]
|
||||||
|
if color then
|
||||||
|
return Hex(color[1], color[2], color[3])
|
||||||
|
else
|
||||||
|
return Hex(altR, altG, altB)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["mana:current"] = "UNIT_MANA UNIT_MAXMANA"
|
||||||
|
ElvUF.Tags.Methods["mana:current"] = function(unit)
|
||||||
|
local min = UnitMana(unit)
|
||||||
|
|
||||||
|
return min == 0 and " " or E:GetFormattedText("CURRENT", min, UnitManaMax(unit))
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["mana:current-max"] = "UNIT_MANA UNIT_MAXMANA"
|
||||||
|
ElvUF.Tags.Methods["mana:current-max"] = function(unit)
|
||||||
|
local min = UnitMana(unit)
|
||||||
|
|
||||||
|
return min == 0 and " " or E:GetFormattedText("CURRENT_MAX", min, UnitManaMax(unit))
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["mana:current-percent"] = "UNIT_MANA UNIT_MAXMANA"
|
||||||
|
ElvUF.Tags.Methods["mana:current-percent"] = function(unit)
|
||||||
|
local min = UnitMana(unit)
|
||||||
|
|
||||||
|
return min == 0 and " " or E:GetFormattedText("CURRENT_PERCENT", min, UnitManaMax(unit))
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["mana:current-max-percent"] = "UNIT_MANA UNIT_MAXMANA"
|
||||||
|
ElvUF.Tags.Methods["mana:current-max-percent"] = function(unit)
|
||||||
|
local min = UnitMana(unit)
|
||||||
|
|
||||||
|
return min == 0 and " " or E:GetFormattedText("CURRENT_MAX_PERCENT", min, UnitManaMax(unit))
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["mana:percent"] = "UNIT_MANA UNIT_MAXMANA"
|
||||||
|
ElvUF.Tags.Methods["mana:percent"] = function(unit)
|
||||||
|
local min = UnitMana(unit)
|
||||||
|
|
||||||
|
return min == 0 and " " or E:GetFormattedText("PERCENT", min, UnitManaMax(unit))
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["mana:deficit"] = "UNIT_MANA UNIT_MAXMANA"
|
||||||
|
ElvUF.Tags.Methods["mana:deficit"] = function(unit)
|
||||||
|
return E:GetFormattedText("DEFICIT", UnitMana(unit), UnitManaMax(unit))
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["mana:max"] = "UNIT_MAXMANA"
|
||||||
|
ElvUF.Tags.Methods["mana:max"] = function(unit)
|
||||||
|
local max = UnitManaMax(unit)
|
||||||
|
|
||||||
|
return E:GetFormattedText("CURRENT", max, max)
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["difficultycolor"] = "UNIT_LEVEL PLAYER_LEVEL_UP"
|
||||||
|
ElvUF.Tags.Methods["difficultycolor"] = function(unit)
|
||||||
|
local r, g, b = 0.69, 0.31, 0.31
|
||||||
|
local level = UnitLevel(unit)
|
||||||
|
if (level > 1) then
|
||||||
|
local DiffColor = UnitLevel(unit) - UnitLevel("player")
|
||||||
|
if (DiffColor >= 5) then
|
||||||
|
r, g, b = 0.69, 0.31, 0.31
|
||||||
|
elseif (DiffColor >= 3) then
|
||||||
|
r, g, b = 0.71, 0.43, 0.27
|
||||||
|
elseif (DiffColor >= -2) then
|
||||||
|
r, g, b = 0.84, 0.75, 0.65
|
||||||
|
elseif (-DiffColor <= GetQuestGreenRange()) then
|
||||||
|
r, g, b = 0.33, 0.59, 0.33
|
||||||
|
else
|
||||||
|
r, g, b = 0.55, 0.57, 0.61
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return Hex(r, g, b)
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["namecolor"] = "UNIT_NAME_UPDATE"
|
||||||
|
ElvUF.Tags.Methods["namecolor"] = function(unit)
|
||||||
|
local unitReaction = UnitReaction(unit, "player")
|
||||||
|
local _, unitClass = UnitClass(unit)
|
||||||
|
if (UnitIsPlayer(unit)) then
|
||||||
|
local class = ElvUF.colors.class[unitClass]
|
||||||
|
if not class then return "" end
|
||||||
|
return Hex(class[1], class[2], class[3])
|
||||||
|
elseif (unitReaction) then
|
||||||
|
local reaction = ElvUF["colors"].reaction[unitReaction]
|
||||||
|
return Hex(reaction[1], reaction[2], reaction[3])
|
||||||
|
else
|
||||||
|
return "|cFFC2C2C2"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["smartlevel"] = "UNIT_LEVEL PLAYER_LEVEL_UP"
|
||||||
|
ElvUF.Tags.Methods["smartlevel"] = function(unit)
|
||||||
|
local level = UnitLevel(unit)
|
||||||
|
if level == UnitLevel("player") then
|
||||||
|
return ""
|
||||||
|
elseif(level > 0) then
|
||||||
|
return level
|
||||||
|
else
|
||||||
|
return "??"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["name:veryshort"] = "UNIT_NAME_UPDATE"
|
||||||
|
ElvUF.Tags.Methods["name:veryshort"] = function(unit)
|
||||||
|
local name = UnitName(unit)
|
||||||
|
return name ~= nil and E:ShortenString(name, 5) or ""
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["name:short"] = "UNIT_NAME_UPDATE"
|
||||||
|
ElvUF.Tags.Methods["name:short"] = function(unit)
|
||||||
|
local name = UnitName(unit)
|
||||||
|
return name ~= nil and E:ShortenString(name, 10) or ""
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["name:medium"] = "UNIT_NAME_UPDATE"
|
||||||
|
ElvUF.Tags.Methods["name:medium"] = function(unit)
|
||||||
|
local name = UnitName(unit)
|
||||||
|
return name ~= nil and E:ShortenString(name, 15) or ""
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["name:long"] = "UNIT_NAME_UPDATE"
|
||||||
|
ElvUF.Tags.Methods["name:long"] = function(unit)
|
||||||
|
local name = UnitName(unit)
|
||||||
|
return name ~= nil and E:ShortenString(name, 20) or ""
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["name:veryshort:status"] = "UNIT_NAME_UPDATE UNIT_CONNECTION PLAYER_FLAGS_CHANGED UNIT_HEALTH"
|
||||||
|
ElvUF.Tags.Methods["name:veryshort:status"] = function(unit)
|
||||||
|
local status = UnitIsDead(unit) and L["Dead"] or UnitIsGhost(unit) and L["Ghost"] or not UnitIsConnected(unit) and L["Offline"]
|
||||||
|
local name = UnitName(unit)
|
||||||
|
if (status) then
|
||||||
|
return status
|
||||||
|
else
|
||||||
|
return name ~= nil and E:ShortenString(name, 5) or ""
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["name:short:status"] = "UNIT_NAME_UPDATE UNIT_CONNECTION PLAYER_FLAGS_CHANGED UNIT_HEALTH"
|
||||||
|
ElvUF.Tags.Methods["name:short:status"] = function(unit)
|
||||||
|
local status = UnitIsDead(unit) and L["Dead"] or UnitIsGhost(unit) and L["Ghost"] or not UnitIsConnected(unit) and L["Offline"]
|
||||||
|
local name = UnitName(unit)
|
||||||
|
if (status) then
|
||||||
|
return status
|
||||||
|
else
|
||||||
|
return name ~= nil and E:ShortenString(name, 10) or ""
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["name:medium:status"] = "UNIT_NAME_UPDATE UNIT_CONNECTION PLAYER_FLAGS_CHANGED UNIT_HEALTH"
|
||||||
|
ElvUF.Tags.Methods["name:medium:status"] = function(unit)
|
||||||
|
local status = UnitIsDead(unit) and L["Dead"] or UnitIsGhost(unit) and L["Ghost"] or not UnitIsConnected(unit) and L["Offline"]
|
||||||
|
local name = UnitName(unit)
|
||||||
|
if (status) then
|
||||||
|
return status
|
||||||
|
else
|
||||||
|
return name ~= nil and E:ShortenString(name, 15) or ""
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["name:long:status"] = "UNIT_NAME_UPDATE UNIT_CONNECTION PLAYER_FLAGS_CHANGED UNIT_HEALTH"
|
||||||
|
ElvUF.Tags.Methods["name:long:status"] = function(unit)
|
||||||
|
local status = UnitIsDead(unit) and L["Dead"] or UnitIsGhost(unit) and L["Ghost"] or not UnitIsConnected(unit) and L["Offline"]
|
||||||
|
local name = UnitName(unit)
|
||||||
|
if (status) then
|
||||||
|
return status
|
||||||
|
else
|
||||||
|
return name ~= nil and E:ShortenString(name, 20) or ""
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local unitStatus = {}
|
||||||
|
ElvUF.Tags.OnUpdateThrottle["statustimer"] = 1
|
||||||
|
ElvUF.Tags.Methods["statustimer"] = function(unit)
|
||||||
|
if not UnitIsPlayer(unit) then return; end
|
||||||
|
local guid = UnitGUID(unit)
|
||||||
|
if (UnitIsAFK(unit)) then
|
||||||
|
if not unitStatus[guid] or unitStatus[guid] and unitStatus[guid][1] ~= "AFK" then
|
||||||
|
unitStatus[guid] = {"AFK", GetTime()}
|
||||||
|
end
|
||||||
|
elseif(UnitIsDND(unit)) then
|
||||||
|
if not unitStatus[guid] or unitStatus[guid] and unitStatus[guid][1] ~= "DND" then
|
||||||
|
unitStatus[guid] = {"DND", GetTime()}
|
||||||
|
end
|
||||||
|
elseif(UnitIsDead(unit)) or (UnitIsGhost(unit))then
|
||||||
|
if not unitStatus[guid] or unitStatus[guid] and unitStatus[guid][1] ~= "Dead" then
|
||||||
|
unitStatus[guid] = {"Dead", GetTime()}
|
||||||
|
end
|
||||||
|
elseif(not UnitIsConnected(unit)) then
|
||||||
|
if not unitStatus[guid] or unitStatus[guid] and unitStatus[guid][1] ~= "Offline" then
|
||||||
|
unitStatus[guid] = {"Offline", GetTime()}
|
||||||
|
end
|
||||||
|
else
|
||||||
|
unitStatus[guid] = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
if unitStatus[guid] ~= nil then
|
||||||
|
local status = unitStatus[guid][1]
|
||||||
|
local timer = GetTime() - unitStatus[guid][2]
|
||||||
|
local mins = floor(timer / 60)
|
||||||
|
local secs = floor(timer - (mins * 60))
|
||||||
|
return ("%s (%01.f:%02.f)"):format(status, mins, secs)
|
||||||
|
else
|
||||||
|
return ""
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.OnUpdateThrottle["pvptimer"] = 1
|
||||||
|
ElvUF.Tags.Methods["pvptimer"] = function(unit)
|
||||||
|
if (UnitIsPVPFreeForAll(unit) or UnitIsPVP(unit)) then
|
||||||
|
local timer = GetPVPTimer()
|
||||||
|
|
||||||
|
if timer ~= 301000 and timer ~= -1 then
|
||||||
|
local mins = floor((timer / 1000) / 60)
|
||||||
|
local secs = floor((timer / 1000) - (mins * 60))
|
||||||
|
return ("%s (%01.f:%02.f)"):format(PVP, mins, secs)
|
||||||
|
else
|
||||||
|
return PVP
|
||||||
|
end
|
||||||
|
else
|
||||||
|
return ""
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["classificationcolor"] = "UNIT_CLASSIFICATION_CHANGED";
|
||||||
|
ElvUF.Tags.Methods["classificationcolor"] = function(unit)
|
||||||
|
local c = UnitClassification(unit);
|
||||||
|
if(c == "rare" or c == "elite") then
|
||||||
|
return Hex(1, 0.5, 0.25); -- Orange
|
||||||
|
elseif(c == "rareelite" or c == "worldboss") then
|
||||||
|
return Hex(1, 0, 0); -- Red
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["guild"] = "PLAYER_GUILD_UPDATE"
|
||||||
|
ElvUF.Tags.Methods["guild"] = function(unit)
|
||||||
|
local guildName = GetGuildInfo(unit)
|
||||||
|
|
||||||
|
return guildName or ""
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["guild:brackets"] = "PLAYER_GUILD_UPDATE"
|
||||||
|
ElvUF.Tags.Methods["guild:brackets"] = function(unit)
|
||||||
|
local guildName = GetGuildInfo(unit)
|
||||||
|
|
||||||
|
return guildName and format("<%s>", guildName) or ""
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["target:veryshort"] = "UNIT_TARGET"
|
||||||
|
ElvUF.Tags.Methods["target:veryshort"] = function(unit)
|
||||||
|
local targetName = UnitName(unit.."target")
|
||||||
|
return targetName ~= nil and E:ShortenString(targetName, 5) or ""
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["target:short"] = "UNIT_TARGET"
|
||||||
|
ElvUF.Tags.Methods["target:short"] = function(unit)
|
||||||
|
local targetName = UnitName(unit.."target")
|
||||||
|
return targetName ~= nil and E:ShortenString(targetName, 10) or ""
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["target:medium"] = "UNIT_TARGET"
|
||||||
|
ElvUF.Tags.Methods["target:medium"] = function(unit)
|
||||||
|
local targetName = UnitName(unit.."target")
|
||||||
|
return targetName ~= nil and E:ShortenString(targetName, 15) or ""
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["target:long"] = "UNIT_TARGET"
|
||||||
|
ElvUF.Tags.Methods["target:long"] = function(unit)
|
||||||
|
local targetName = UnitName(unit.."target")
|
||||||
|
return targetName ~= nil and E:ShortenString(targetName, 20) or ""
|
||||||
|
end
|
||||||
|
|
||||||
|
ElvUF.Tags.Events["target"] = "UNIT_TARGET"
|
||||||
|
ElvUF.Tags.Methods["target"] = function(unit)
|
||||||
|
local targetName = UnitName(unit.."target")
|
||||||
|
return targetName or ""
|
||||||
|
end
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,10 @@
|
|||||||
|
<Ui xmlns="http://www.blizzard.com/wow/ui/">
|
||||||
|
<Script file="Player.lua"/>
|
||||||
|
<Script file="Target.lua"/>
|
||||||
|
<Script file="TargetTarget.lua"/>
|
||||||
|
<Script file="focus.lua"/>
|
||||||
|
<Script file="focustarget.lua"/>
|
||||||
|
<Script file="pet.lua"/>
|
||||||
|
<Script file="pettarget.lua"/>
|
||||||
|
<Script file="targettargettarget.lua"/>
|
||||||
|
</Ui>
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
local E, L, V, P, G = unpack(ElvUI); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||||
|
local UF = E:GetModule("UnitFrames");
|
||||||
|
|
||||||
|
--Cache global variables
|
||||||
|
--Lua functions
|
||||||
|
local _G = _G
|
||||||
|
|
||||||
|
local ns = oUF
|
||||||
|
local ElvUF = ns.oUF
|
||||||
|
assert(ElvUF, "ElvUI was unable to locate oUF.")
|
||||||
|
|
||||||
|
local CAN_HAVE_CLASSBAR = E.myclass == "DRUID"
|
||||||
|
|
||||||
|
function UF:Construct_PlayerFrame(frame)
|
||||||
|
frame.Health = self:Construct_HealthBar(frame, true, true, "RIGHT")
|
||||||
|
frame.Health.frequentUpdates = true
|
||||||
|
|
||||||
|
frame.Power = self:Construct_PowerBar(frame, true, true, "LEFT")
|
||||||
|
frame.Power.frequentUpdates = true
|
||||||
|
|
||||||
|
frame.Name = self:Construct_NameText(frame)
|
||||||
|
|
||||||
|
frame.Portrait3D = self:Construct_Portrait(frame, "model")
|
||||||
|
frame.Portrait2D = self:Construct_Portrait(frame, "texture")
|
||||||
|
|
||||||
|
frame:SetPoint("BOTTOMLEFT", E.UIParent, "BOTTOM", -413, 68)
|
||||||
|
E:CreateMover(frame, frame:GetName().."Mover", L["Player Frame"], nil, nil, nil, "ALL,SOLO")
|
||||||
|
frame.unitframeType = "player"
|
||||||
|
end
|
||||||
|
|
||||||
|
function UF:Update_PlayerFrame(frame, db)
|
||||||
|
frame.db = db
|
||||||
|
|
||||||
|
do
|
||||||
|
frame.ORIENTATION = db.orientation
|
||||||
|
frame.UNIT_WIDTH = db.width
|
||||||
|
frame.UNIT_HEIGHT = db.infoPanel.enable and (db.height + db.infoPanel.height) or db.height
|
||||||
|
|
||||||
|
frame.USE_POWERBAR = db.power.enable
|
||||||
|
frame.POWERBAR_DETACHED = db.power.detachFromFrame
|
||||||
|
frame.USE_INSET_POWERBAR = not frame.POWERBAR_DETACHED and db.power.width == "inset" and frame.USE_POWERBAR
|
||||||
|
frame.USE_MINI_POWERBAR = (not frame.POWERBAR_DETACHED and db.power.width == "spaced" and frame.USE_POWERBAR)
|
||||||
|
frame.USE_POWERBAR_OFFSET = db.power.offset ~= 0 and frame.USE_POWERBAR and not frame.POWERBAR_DETACHED
|
||||||
|
frame.POWERBAR_OFFSET = frame.USE_POWERBAR_OFFSET and db.power.offset or 0
|
||||||
|
|
||||||
|
frame.POWERBAR_HEIGHT = not frame.USE_POWERBAR and 0 or db.power.height
|
||||||
|
frame.POWERBAR_WIDTH = frame.USE_MINI_POWERBAR and (frame.UNIT_WIDTH - (frame.BORDER*2))/2 or (frame.POWERBAR_DETACHED and db.power.detachedWidth or (frame.UNIT_WIDTH - ((frame.BORDER+frame.SPACING)*2)))
|
||||||
|
|
||||||
|
frame.USE_PORTRAIT = db.portrait and db.portrait.enable
|
||||||
|
frame.USE_PORTRAIT_OVERLAY = frame.USE_PORTRAIT and (db.portrait.overlay or frame.ORIENTATION == "MIDDLE")
|
||||||
|
frame.PORTRAIT_WIDTH = (frame.USE_PORTRAIT_OVERLAY or not frame.USE_PORTRAIT) and 0 or db.portrait.width
|
||||||
|
|
||||||
|
frame.CAN_HAVE_CLASSBAR = CAN_HAVE_CLASSBAR
|
||||||
|
frame.MAX_CLASS_BAR = frame.MAX_CLASS_BAR or UF.classMaxResourceBar[E.myclass] or 0
|
||||||
|
frame.USE_CLASSBAR = db.classbar.enable and frame.CAN_HAVE_CLASSBAR
|
||||||
|
frame.CLASSBAR_SHOWN = frame.CAN_HAVE_CLASSBAR and frame[frame.ClassBar]:IsShown()
|
||||||
|
frame.CLASSBAR_DETACHED = db.classbar.detachFromFrame
|
||||||
|
frame.USE_MINI_CLASSBAR = db.classbar.fill == "spaced" and frame.USE_CLASSBAR
|
||||||
|
frame.CLASSBAR_HEIGHT = frame.USE_CLASSBAR and db.classbar.height or 0
|
||||||
|
frame.CLASSBAR_WIDTH = frame.UNIT_WIDTH - ((frame.BORDER+frame.SPACING)*2) - frame.PORTRAIT_WIDTH -(frame.ORIENTATION == "MIDDLE" and (frame.POWERBAR_OFFSET*2) or frame.POWERBAR_OFFSET)
|
||||||
|
frame.CLASSBAR_YOFFSET = (not frame.USE_CLASSBAR or not frame.CLASSBAR_SHOWN or frame.CLASSBAR_DETACHED) and 0 or (frame.USE_MINI_CLASSBAR and (frame.SPACING+(frame.CLASSBAR_HEIGHT/2)) or (frame.CLASSBAR_HEIGHT - (frame.BORDER-frame.SPACING)))
|
||||||
|
|
||||||
|
frame.USE_INFO_PANEL = not frame.USE_MINI_POWERBAR and not frame.USE_POWERBAR_OFFSET and db.infoPanel.enable
|
||||||
|
frame.INFO_PANEL_HEIGHT = frame.USE_INFO_PANEL and db.infoPanel.height or 0
|
||||||
|
|
||||||
|
frame.HAPPINESS_WIDTH = 0
|
||||||
|
|
||||||
|
frame.BOTTOM_OFFSET = UF:GetHealthBottomOffset(frame)
|
||||||
|
|
||||||
|
frame.VARIABLES_SET = true
|
||||||
|
end
|
||||||
|
|
||||||
|
frame.colors = ElvUF.colors
|
||||||
|
frame.Portrait = frame.Portrait or (db.portrait.style == "2D" and frame.Portrait2D or frame.Portrait3D)
|
||||||
|
--frame:RegisterForClicks(self.db.targetOnMouseDown and "AnyDown" or "AnyUp")
|
||||||
|
|
||||||
|
frame:SetWidth(frame.UNIT_WIDTH)
|
||||||
|
frame:SetHeight(frame.UNIT_HEIGHT)
|
||||||
|
_G[frame:GetName().."Mover"]:SetWidth(frame:GetWidth())
|
||||||
|
_G[frame:GetName().."Mover"]:SetHeight(frame:GetHeight())
|
||||||
|
|
||||||
|
UF:Configure_HealthBar(frame)
|
||||||
|
|
||||||
|
UF:UpdateNameSettings(frame)
|
||||||
|
|
||||||
|
UF:Configure_Power(frame)
|
||||||
|
|
||||||
|
UF:Configure_Portrait(frame)
|
||||||
|
|
||||||
|
E:SetMoverSnapOffset(frame:GetName().."Mover", -(12 + db.castbar.height))
|
||||||
|
frame:UpdateAllElements("ElvUI_UpdateAllElements")
|
||||||
|
end
|
||||||
|
|
||||||
|
tinsert(UF["unitstoload"], "player")
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
local E, L, V, P, G = unpack(ElvUI); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||||
|
local UF = E:GetModule("UnitFrames");
|
||||||
|
|
||||||
|
--Cache global variables
|
||||||
|
--Lua functions
|
||||||
|
local _G = _G
|
||||||
|
|
||||||
|
local ns = oUF
|
||||||
|
local ElvUF = ns.oUF
|
||||||
|
assert(ElvUF, "ElvUI was unable to locate oUF.")
|
||||||
|
|
||||||
|
function UF:Construct_TargetFrame(frame)
|
||||||
|
frame.Health = self:Construct_HealthBar(frame, true, true, "RIGHT")
|
||||||
|
frame.Health.frequentUpdates = true
|
||||||
|
|
||||||
|
frame.Power = self:Construct_PowerBar(frame, true, true, "LEFT")
|
||||||
|
frame.Power.frequentUpdates = true
|
||||||
|
|
||||||
|
frame.Name = self:Construct_NameText(frame)
|
||||||
|
|
||||||
|
frame.Portrait3D = self:Construct_Portrait(frame, "model")
|
||||||
|
frame.Portrait2D = self:Construct_Portrait(frame, "texture")
|
||||||
|
|
||||||
|
frame:SetPoint("BOTTOMRIGHT", E.UIParent, "BOTTOM", 413, 68)
|
||||||
|
E:CreateMover(frame, frame:GetName().."Mover", L["Target Frame"], nil, nil, nil, "ALL,SOLO")
|
||||||
|
frame.unitframeType = "target"
|
||||||
|
end
|
||||||
|
|
||||||
|
function UF:Update_TargetFrame(frame, db)
|
||||||
|
frame.db = db
|
||||||
|
|
||||||
|
do
|
||||||
|
frame.ORIENTATION = db.orientation
|
||||||
|
frame.UNIT_WIDTH = db.width
|
||||||
|
frame.UNIT_HEIGHT = db.infoPanel.enable and (db.height + db.infoPanel.height) or db.height
|
||||||
|
|
||||||
|
frame.USE_POWERBAR = db.power.enable
|
||||||
|
frame.POWERBAR_DETACHED = db.power.detachFromFrame
|
||||||
|
frame.USE_INSET_POWERBAR = not frame.POWERBAR_DETACHED and db.power.width == "inset" and frame.USE_POWERBAR
|
||||||
|
frame.USE_MINI_POWERBAR = (not frame.POWERBAR_DETACHED and db.power.width == "spaced" and frame.USE_POWERBAR)
|
||||||
|
frame.USE_POWERBAR_OFFSET = db.power.offset ~= 0 and frame.USE_POWERBAR and not frame.POWERBAR_DETACHED
|
||||||
|
frame.POWERBAR_OFFSET = frame.USE_POWERBAR_OFFSET and db.power.offset or 0
|
||||||
|
|
||||||
|
frame.POWERBAR_HEIGHT = not frame.USE_POWERBAR and 0 or db.power.height
|
||||||
|
frame.POWERBAR_WIDTH = frame.USE_MINI_POWERBAR and (frame.UNIT_WIDTH - (frame.BORDER*2))/2 or (frame.POWERBAR_DETACHED and db.power.detachedWidth or (frame.UNIT_WIDTH - ((frame.BORDER+frame.SPACING)*2)))
|
||||||
|
|
||||||
|
frame.USE_PORTRAIT = db.portrait and db.portrait.enable
|
||||||
|
frame.USE_PORTRAIT_OVERLAY = frame.USE_PORTRAIT and (db.portrait.overlay or frame.ORIENTATION == "MIDDLE")
|
||||||
|
frame.PORTRAIT_WIDTH = (frame.USE_PORTRAIT_OVERLAY or not frame.USE_PORTRAIT) and 0 or db.portrait.width
|
||||||
|
|
||||||
|
frame.CAN_HAVE_CLASSBAR = db.combobar.enable
|
||||||
|
frame.MAX_CLASS_BAR = MAX_COMBO_POINTS
|
||||||
|
frame.USE_CLASSBAR = db.combobar.enable
|
||||||
|
frame.CLASSBAR_SHOWN = frame.CAN_HAVE_CLASSBAR and frame.ComboPoints and frame.ComboPoints:IsShown()
|
||||||
|
frame.CLASSBAR_DETACHED = db.combobar.detachFromFrame
|
||||||
|
frame.USE_MINI_CLASSBAR = db.combobar.fill == "spaced" and frame.USE_CLASSBAR
|
||||||
|
frame.CLASSBAR_HEIGHT = frame.USE_CLASSBAR and db.combobar.height or 0
|
||||||
|
frame.CLASSBAR_WIDTH = frame.UNIT_WIDTH - ((frame.BORDER+frame.SPACING)*2) - frame.PORTRAIT_WIDTH - frame.POWERBAR_OFFSET
|
||||||
|
frame.CLASSBAR_YOFFSET = (not frame.USE_CLASSBAR or not frame.CLASSBAR_SHOWN or frame.CLASSBAR_DETACHED) and 0 or (frame.USE_MINI_CLASSBAR and (frame.SPACING+(frame.CLASSBAR_HEIGHT/2)) or (frame.CLASSBAR_HEIGHT + frame.SPACING))
|
||||||
|
|
||||||
|
frame.USE_INFO_PANEL = not frame.USE_MINI_POWERBAR and not frame.USE_POWERBAR_OFFSET and db.infoPanel.enable
|
||||||
|
frame.INFO_PANEL_HEIGHT = frame.USE_INFO_PANEL and db.infoPanel.height or 0
|
||||||
|
|
||||||
|
frame.BOTTOM_OFFSET = UF:GetHealthBottomOffset(frame)
|
||||||
|
|
||||||
|
frame.VARIABLES_SET = true
|
||||||
|
end
|
||||||
|
|
||||||
|
frame.colors = ElvUF.colors
|
||||||
|
frame.Portrait = frame.Portrait or (db.portrait.style == "2D" and frame.Portrait2D or frame.Portrait3D)
|
||||||
|
--frame:RegisterForClicks(self.db.targetOnMouseDown and "AnyDown" or "AnyUp")
|
||||||
|
|
||||||
|
frame:SetWidth(frame.UNIT_WIDTH)
|
||||||
|
frame:SetHeight(frame.UNIT_HEIGHT)
|
||||||
|
_G[frame:GetName().."Mover"]:SetWidth(frame:GetWidth())
|
||||||
|
_G[frame:GetName().."Mover"]:SetHeight(frame:GetHeight())
|
||||||
|
|
||||||
|
UF:Configure_HealthBar(frame)
|
||||||
|
|
||||||
|
UF:UpdateNameSettings(frame)
|
||||||
|
|
||||||
|
UF:Configure_Power(frame)
|
||||||
|
|
||||||
|
UF:Configure_Portrait(frame)
|
||||||
|
|
||||||
|
E:SetMoverSnapOffset(frame:GetName().."Mover", -(12 + db.castbar.height))
|
||||||
|
frame:UpdateAllElements("ElvUI_UpdateAllElements")
|
||||||
|
end
|
||||||
|
|
||||||
|
tinsert(UF["unitstoload"], "target")
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
local E, L, V, P, G = unpack(ElvUI); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||||
|
local UF = E:GetModule("UnitFrames");
|
||||||
|
|
||||||
|
--Cache global variables
|
||||||
|
--Lua functions
|
||||||
|
local _G = _G
|
||||||
|
|
||||||
|
local ns = oUF
|
||||||
|
local ElvUF = ns.oUF
|
||||||
|
assert(ElvUF, "ElvUI was unable to locate oUF.")
|
||||||
|
|
||||||
|
function UF:Construct_TargetTargetFrame(frame)
|
||||||
|
frame.Health = self:Construct_HealthBar(frame, true, true, "RIGHT")
|
||||||
|
frame.Power = self:Construct_PowerBar(frame, true, true, "LEFT")
|
||||||
|
frame.Name = self:Construct_NameText(frame)
|
||||||
|
frame.Portrait3D = self:Construct_Portrait(frame, "model")
|
||||||
|
frame.Portrait2D = self:Construct_Portrait(frame, "texture")
|
||||||
|
|
||||||
|
frame:SetPoint("BOTTOM", E.UIParent, "BOTTOM", 0, 75)
|
||||||
|
E:CreateMover(frame, frame:GetName().."Mover", L["TargetTarget Frame"], nil, nil, nil, "ALL,SOLO")
|
||||||
|
frame.unitframeType = "targettarget";
|
||||||
|
end
|
||||||
|
|
||||||
|
function UF:Update_TargetTargetFrame(frame, db)
|
||||||
|
frame.db = db
|
||||||
|
|
||||||
|
do
|
||||||
|
frame.ORIENTATION = db.orientation
|
||||||
|
frame.UNIT_WIDTH = db.width
|
||||||
|
frame.UNIT_HEIGHT = db.infoPanel.enable and (db.height + db.infoPanel.height) or db.height
|
||||||
|
|
||||||
|
frame.USE_POWERBAR = db.power.enable
|
||||||
|
frame.POWERBAR_DETACHED = db.power.detachFromFrame
|
||||||
|
frame.USE_INSET_POWERBAR = not frame.POWERBAR_DETACHED and db.power.width == "inset" and frame.USE_POWERBAR
|
||||||
|
frame.USE_MINI_POWERBAR = (not frame.POWERBAR_DETACHED and db.power.width == "spaced" and frame.USE_POWERBAR)
|
||||||
|
frame.USE_POWERBAR_OFFSET = db.power.offset ~= 0 and frame.USE_POWERBAR and not frame.POWERBAR_DETACHED
|
||||||
|
frame.POWERBAR_OFFSET = frame.USE_POWERBAR_OFFSET and db.power.offset or 0
|
||||||
|
|
||||||
|
frame.POWERBAR_HEIGHT = not frame.USE_POWERBAR and 0 or db.power.height
|
||||||
|
frame.POWERBAR_WIDTH = frame.USE_MINI_POWERBAR and (frame.UNIT_WIDTH - (frame.BORDER*2))/2 or (frame.POWERBAR_DETACHED and db.power.detachedWidth or (frame.UNIT_WIDTH - ((frame.BORDER+frame.SPACING)*2)))
|
||||||
|
|
||||||
|
frame.USE_PORTRAIT = db.portrait and db.portrait.enable
|
||||||
|
frame.USE_PORTRAIT_OVERLAY = frame.USE_PORTRAIT and (db.portrait.overlay or frame.ORIENTATION == "MIDDLE")
|
||||||
|
frame.PORTRAIT_WIDTH = (frame.USE_PORTRAIT_OVERLAY or not frame.USE_PORTRAIT) and 0 or db.portrait.width
|
||||||
|
|
||||||
|
frame.USE_INFO_PANEL = not frame.USE_MINI_POWERBAR and not frame.USE_POWERBAR_OFFSET and db.infoPanel.enable
|
||||||
|
frame.INFO_PANEL_HEIGHT = frame.USE_INFO_PANEL and db.infoPanel.height or 0
|
||||||
|
|
||||||
|
frame.BOTTOM_OFFSET = UF:GetHealthBottomOffset(frame)
|
||||||
|
|
||||||
|
frame.VARIABLES_SET = true
|
||||||
|
end
|
||||||
|
|
||||||
|
frame.colors = ElvUF.colors
|
||||||
|
frame.Portrait = frame.Portrait or (db.portrait.style == "2D" and frame.Portrait2D or frame.Portrait3D)
|
||||||
|
--frame:RegisterForClicks(self.db.targetOnMouseDown and "AnyDown" or "AnyUp")
|
||||||
|
frame:SetWidth(frame.UNIT_WIDTH)
|
||||||
|
frame:SetHeight(frame.UNIT_HEIGHT)
|
||||||
|
_G[frame:GetName().."Mover"]:SetWidth(frame:GetWidth())
|
||||||
|
_G[frame:GetName().."Mover"]:SetHeight(frame:GetHeight())
|
||||||
|
|
||||||
|
UF:Configure_HealthBar(frame)
|
||||||
|
|
||||||
|
UF:UpdateNameSettings(frame)
|
||||||
|
|
||||||
|
UF:Configure_Power(frame)
|
||||||
|
|
||||||
|
UF:Configure_Portrait(frame)
|
||||||
|
|
||||||
|
E:SetMoverSnapOffset(frame:GetName().."Mover", -(12 + self.db["units"].player.castbar.height))
|
||||||
|
frame:UpdateAllElements("ElvUI_UpdateAllElements")
|
||||||
|
end
|
||||||
|
|
||||||
|
tinsert(UF["unitstoload"], "targettarget")
|
||||||
@@ -37,6 +37,18 @@ V["tooltip"] = {
|
|||||||
["enable"] = true
|
["enable"] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
V["unitframe"] = {
|
||||||
|
["enable"] = true,
|
||||||
|
["disabledBlizzardFrames"] = {
|
||||||
|
["player"] = true,
|
||||||
|
["target"] = true,
|
||||||
|
["focus"] = true,
|
||||||
|
["boss"] = true,
|
||||||
|
["arena"] = true,
|
||||||
|
["party"] = true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
V["actionbar"] = {
|
V["actionbar"] = {
|
||||||
["enable"] = true
|
["enable"] = true
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -9,3 +9,4 @@
|
|||||||
Libraries\Load_Libraries.xml
|
Libraries\Load_Libraries.xml
|
||||||
locales\load_locales.xml
|
locales\load_locales.xml
|
||||||
core.lua
|
core.lua
|
||||||
|
UnitFrames.lua
|
||||||
@@ -12,14 +12,15 @@ Very light wrapper library that combines all the AceConfig subcomponents into on
|
|||||||
|
|
||||||
]]
|
]]
|
||||||
|
|
||||||
local cfgreg = LibStub("AceConfigRegistry-3.0-ElvUI")
|
local MAJOR, MINOR = "AceConfig-3.0", 2
|
||||||
local cfgcmd = LibStub("AceConfigCmd-3.0-ElvUI")
|
|
||||||
|
|
||||||
local MAJOR, MINOR = "AceConfig-3.0-ElvUI", 2
|
|
||||||
local AceConfig = LibStub:NewLibrary(MAJOR, MINOR)
|
local AceConfig = LibStub:NewLibrary(MAJOR, MINOR)
|
||||||
|
|
||||||
if not AceConfig then return end
|
if not AceConfig then return end
|
||||||
|
|
||||||
|
AceConfig.embeds = AceConfig.embeds or {}
|
||||||
|
|
||||||
|
local cfgreg = LibStub("AceConfigRegistry-3.0")
|
||||||
|
local cfgcmd = LibStub("AceConfigCmd-3.0")
|
||||||
--TODO: local cfgdlg = LibStub("AceConfigDialog-3.0", true)
|
--TODO: local cfgdlg = LibStub("AceConfigDialog-3.0", true)
|
||||||
--TODO: local cfgdrp = LibStub("AceConfigDropdown-3.0", true)
|
--TODO: local cfgdrp = LibStub("AceConfigDropdown-3.0", true)
|
||||||
|
|
||||||
@@ -43,16 +44,27 @@ local pcall, error, type, pairs = pcall, error, type, pairs
|
|||||||
-- local AceConfig = LibStub("AceConfig-3.0")
|
-- local AceConfig = LibStub("AceConfig-3.0")
|
||||||
-- AceConfig:RegisterOptionsTable("MyAddon", myOptions, {"/myslash", "/my"})
|
-- AceConfig:RegisterOptionsTable("MyAddon", myOptions, {"/myslash", "/my"})
|
||||||
function AceConfig:RegisterOptionsTable(appName, options, slashcmd)
|
function AceConfig:RegisterOptionsTable(appName, options, slashcmd)
|
||||||
|
if self == AceConfig then
|
||||||
|
error([[Usage: RegisterOptionsTable(appName, options[, slashcmd]): 'self' - use your own 'self']], 2)
|
||||||
|
end
|
||||||
local ok,msg = pcall(cfgreg.RegisterOptionsTable, self, appName, options)
|
local ok,msg = pcall(cfgreg.RegisterOptionsTable, self, appName, options)
|
||||||
if not ok then error(msg, 2) end
|
if not ok then error(msg, 2) end
|
||||||
|
|
||||||
if slashcmd then
|
if slashcmd then
|
||||||
if type(slashcmd) == "table" then
|
if type(slashcmd) == "table" then
|
||||||
for _,cmd in pairs(slashcmd) do
|
for _,cmd in pairs(slashcmd) do
|
||||||
cfgcmd:CreateChatCommand(cmd, appName)
|
cfgcmd.CreateChatCommand(self, cmd, appName)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
cfgcmd:CreateChatCommand(slashcmd, appName)
|
cfgcmd.CreateChatCommand(self, slashcmd, appName)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function AceConfig:Embed(target)
|
||||||
|
target["RegisterOptionsTable"] = self["RegisterOptionsTable"]
|
||||||
|
end
|
||||||
|
|
||||||
|
for addon in pairs(AceConfig.embeds) do
|
||||||
|
AceConfig:Embed(addon)
|
||||||
|
end
|
||||||
+185
-118
@@ -14,29 +14,37 @@ REQUIRES: AceConsole-3.0 for command registration (loaded on demand)
|
|||||||
|
|
||||||
-- TODO: plugin args
|
-- TODO: plugin args
|
||||||
|
|
||||||
local cfgreg = LibStub("AceConfigRegistry-3.0-ElvUI")
|
|
||||||
|
|
||||||
local MAJOR, MINOR = "AceConfigCmd-3.0-ElvUI", 2
|
local MAJOR, MINOR = "AceConfigCmd-3.0", 13
|
||||||
local AceConfigCmd = LibStub:NewLibrary(MAJOR, MINOR)
|
local AceConfigCmd = LibStub:NewLibrary(MAJOR, MINOR)
|
||||||
|
|
||||||
if not AceConfigCmd then return end
|
if not AceConfigCmd then return end
|
||||||
|
|
||||||
|
local AceCore = LibStub("AceCore-3.0")
|
||||||
|
local Dispatchers = AceCore.Dispatchers
|
||||||
|
local strtrim = AceCore.strtrim
|
||||||
|
local strsplit = AceCore.strsplit
|
||||||
|
local new, del = AceCore.new, AceCore.del
|
||||||
|
local wipe = AceCore.wipe
|
||||||
|
|
||||||
AceConfigCmd.commands = AceConfigCmd.commands or {}
|
AceConfigCmd.commands = AceConfigCmd.commands or {}
|
||||||
|
AceConfigCmd.embeds = AceConfigCmd.embeds or {}
|
||||||
local commands = AceConfigCmd.commands
|
local commands = AceConfigCmd.commands
|
||||||
|
|
||||||
|
local cfgreg = LibStub("AceConfigRegistry-3.0")
|
||||||
local AceConsole -- LoD
|
local AceConsole -- LoD
|
||||||
local AceConsoleName = "AceConsole-3.0"
|
local AceConsoleName = "AceConsole-3.0"
|
||||||
|
|
||||||
-- Lua APIs
|
-- Lua APIs
|
||||||
local strsub, strsplit, strlower, strmatch, strtrim, strupper = string.sub, string.split, string.lower, string.match, string.trim, string.upper
|
local strbyte, strsub = string.byte, string.sub
|
||||||
local format, tonumber, tostring, len, find, byte = string.format, tonumber, tostring, string.len, string.find, string.byte
|
local strlen, strupper, strlower = string.len, string.upper, string.lower
|
||||||
local tsort, tinsert, tgetn = table.sort, table.insert, table.getn
|
local strfind, strgfind, strgsub = string.find, string.gfind, string.gsub
|
||||||
local select, pairs, next, type, unpack = select, pairs, next, type, unpack
|
|
||||||
local error, assert = error, assert
|
local format = string.format
|
||||||
local mod = math.mod
|
local tsort, tinsert, tgetn, tremove = table.sort, table.insert, table.getn, table.remove
|
||||||
|
|
||||||
-- WoW APIs
|
-- WoW APIs
|
||||||
local _G = getfenv()
|
local _G = AceCore._G
|
||||||
|
|
||||||
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
|
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
|
||||||
-- List them here for Mikk's FindGlobals script
|
-- List them here for Mikk's FindGlobals script
|
||||||
@@ -61,18 +69,7 @@ local handlermsg = "expected a table"
|
|||||||
local functypes = {["function"]=true, ["string"]=true}
|
local functypes = {["function"]=true, ["string"]=true}
|
||||||
local funcmsg = "expected function or member name"
|
local funcmsg = "expected function or member name"
|
||||||
|
|
||||||
|
local pickfirstset = AceCore.pickfirstset
|
||||||
-- pickfirstset() - picks the first non-nil value and returns it
|
|
||||||
|
|
||||||
local function pickfirstset(...)
|
|
||||||
local args = unpack(arg)
|
|
||||||
for i=1,select("#", args) do
|
|
||||||
if select(i,args)~=nil then
|
|
||||||
return select(i,args)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
-- err() - produce real error() regarding malformed options tables etc
|
-- err() - produce real error() regarding malformed options tables etc
|
||||||
|
|
||||||
@@ -92,23 +89,26 @@ end
|
|||||||
|
|
||||||
-- callmethod() - call a given named method (e.g. "get", "set") with given arguments
|
-- callmethod() - call a given named method (e.g. "get", "set") with given arguments
|
||||||
|
|
||||||
local function callmethod(info, inputpos, tab, methodtype, ...)
|
|
||||||
|
|
||||||
|
local function callmethod(info, inputpos, tab, methodtype, argc, a1, a2, a3, a4)
|
||||||
local method = info[methodtype]
|
local method = info[methodtype]
|
||||||
if not method then
|
if not method then
|
||||||
err(info, inputpos, "'"..methodtype.."': not set")
|
err(info, inputpos, "'"..methodtype.."': not set")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
argc = argc or 0
|
||||||
info.arg = tab.arg
|
info.arg = tab.arg
|
||||||
info.option = tab
|
info.option = tab
|
||||||
info.type = tab.type
|
info.type = tab.type
|
||||||
|
|
||||||
if type(method)=="function" then
|
if type(method)=="function" then
|
||||||
return method(info, unpack(arg))
|
return Dispatchers[argc+1](method, info, a1, a2, a3, a4)
|
||||||
elseif type(method)=="string" then
|
elseif type(method)=="string" then
|
||||||
if type(info.handler[method])~="function" then
|
if type(info.handler[method])~="function" then
|
||||||
err(info, inputpos, "'"..methodtype.."': '"..method.."' is not a member function of "..tostring(info.handler))
|
err(info, inputpos, "'"..methodtype.."': '"..method.."' is not a member function of "..tostring(info.handler))
|
||||||
end
|
end
|
||||||
return info.handler[method](info.handler, info, unpack(arg))
|
return Dispatchers[argc+2](info.handler[method], info.handler, info, a1, a2, a3, a4)
|
||||||
else
|
else
|
||||||
assert(false) -- type should have already been checked on read
|
assert(false) -- type should have already been checked on read
|
||||||
end
|
end
|
||||||
@@ -116,7 +116,8 @@ end
|
|||||||
|
|
||||||
-- callfunction() - call a given named function (e.g. "name", "desc") with given arguments
|
-- callfunction() - call a given named function (e.g. "name", "desc") with given arguments
|
||||||
|
|
||||||
local function callfunction(info, tab, methodtype, ...)
|
-- Ace3v: the variable arguments are currently unused, so we removed it
|
||||||
|
local function callfunction(info, tab, methodtype)
|
||||||
local method = tab[methodtype]
|
local method = tab[methodtype]
|
||||||
|
|
||||||
info.arg = tab.arg
|
info.arg = tab.arg
|
||||||
@@ -124,17 +125,18 @@ local function callfunction(info, tab, methodtype, ...)
|
|||||||
info.type = tab.type
|
info.type = tab.type
|
||||||
|
|
||||||
if type(method)=="function" then
|
if type(method)=="function" then
|
||||||
return method(info, unpack(arg))
|
return method(info)
|
||||||
else
|
else
|
||||||
assert(false) -- type should have already been checked on read
|
assert(false) -- type should have already been checked on read
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- do_final() - do the final step (set/execute) along with validation and confirmation
|
-- do_final() - do the final step (set/execute) along with validation and confirmation
|
||||||
|
-- Ace3v: experimental
|
||||||
local function do_final(info, inputpos, tab, methodtype, ...)
|
-- @param argc number of variable arguments
|
||||||
|
local function do_final(info, inputpos, tab, methodtype, argc, a1, a2, a3, a4) -- currently maximum 4 arguments
|
||||||
if info.validate then
|
if info.validate then
|
||||||
local res = callmethod(info,inputpos,tab,"validate",unpack(arg))
|
local res = callmethod(info,inputpos,tab,"validate",argc,a1,a2,a3,a4)
|
||||||
if type(res)=="string" then
|
if type(res)=="string" then
|
||||||
usererr(info, inputpos, "'"..strsub(info.input, inputpos).."' - "..res)
|
usererr(info, inputpos, "'"..strsub(info.input, inputpos).."' - "..res)
|
||||||
return
|
return
|
||||||
@@ -142,7 +144,7 @@ local function do_final(info, inputpos, tab, methodtype, ...)
|
|||||||
end
|
end
|
||||||
-- console ignores .confirm
|
-- console ignores .confirm
|
||||||
|
|
||||||
callmethod(info,inputpos,tab,methodtype, unpack(arg))
|
callmethod(info,inputpos,tab,methodtype,argc,a1,a2,a3,a4)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@@ -165,8 +167,6 @@ end
|
|||||||
|
|
||||||
|
|
||||||
-- iterateargs(tab) - custom iterator that iterates both t.args and t.plugins.*
|
-- iterateargs(tab) - custom iterator that iterates both t.args and t.plugins.*
|
||||||
local dummytable={}
|
|
||||||
|
|
||||||
local function iterateargs(tab)
|
local function iterateargs(tab)
|
||||||
if not tab.plugins then
|
if not tab.plugins then
|
||||||
return pairs(tab.args)
|
return pairs(tab.args)
|
||||||
@@ -191,17 +191,21 @@ local function iterateargs(tab)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function getValueFromTab(info, inputpos, tab, key)
|
||||||
|
local v = tab[key]
|
||||||
|
if type(v) == "function" or type(v) == "string" then
|
||||||
|
info[key] = v
|
||||||
|
v = callmethod(info, inputpos, tab, key)
|
||||||
|
info[key] = nil
|
||||||
|
end
|
||||||
|
return v
|
||||||
|
end
|
||||||
|
|
||||||
local function checkhidden(info, inputpos, tab)
|
local function checkhidden(info, inputpos, tab)
|
||||||
if tab.cmdHidden~=nil then
|
if tab.cmdHidden~=nil then
|
||||||
return tab.cmdHidden
|
return tab.cmdHidden
|
||||||
end
|
end
|
||||||
local hidden = tab.hidden
|
return getValueFromTab(info, inputpos, tab, "hidden")
|
||||||
if type(hidden) == "function" or type(hidden) == "string" then
|
|
||||||
info.hidden = hidden
|
|
||||||
hidden = callmethod(info, inputpos, tab, 'hidden')
|
|
||||||
info.hidden = nil
|
|
||||||
end
|
|
||||||
return hidden
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function showhelp(info, inputpos, tab, depth, noHead)
|
local function showhelp(info, inputpos, tab, depth, noHead)
|
||||||
@@ -209,8 +213,8 @@ local function showhelp(info, inputpos, tab, depth, noHead)
|
|||||||
print("|cff33ff99"..info.appName.."|r: Arguments to |cffffff78/"..info[0].."|r "..strsub(info.input,1,inputpos-1)..":")
|
print("|cff33ff99"..info.appName.."|r: Arguments to |cffffff78/"..info[0].."|r "..strsub(info.input,1,inputpos-1)..":")
|
||||||
end
|
end
|
||||||
|
|
||||||
local sortTbl = {} -- [1..n]=name
|
local sortTbl = new() -- [1..n]=name
|
||||||
local refTbl = {} -- [name]=tableref
|
local refTbl = new() -- [name]=tableref
|
||||||
|
|
||||||
for k,v in iterateargs(tab) do
|
for k,v in iterateargs(tab) do
|
||||||
if not refTbl[k] then -- a plugin overriding something in .args
|
if not refTbl[k] then -- a plugin overriding something in .args
|
||||||
@@ -224,16 +228,16 @@ local function showhelp(info, inputpos, tab, depth, noHead)
|
|||||||
local o2 = refTbl[two].order or 100
|
local o2 = refTbl[two].order or 100
|
||||||
if type(o1) == "function" or type(o1) == "string" then
|
if type(o1) == "function" or type(o1) == "string" then
|
||||||
info.order = o1
|
info.order = o1
|
||||||
info[tgetn(info)+1] = one
|
tinsert(info, one)
|
||||||
o1 = callmethod(info, inputpos, refTbl[one], "order")
|
o1 = callmethod(info, inputpos, refTbl[one], "order")
|
||||||
info[tgetn(info)] = nil
|
tremove(info)
|
||||||
info.order = nil
|
info.order = nil
|
||||||
end
|
end
|
||||||
if type(o2) == "function" or type(o1) == "string" then
|
if type(o2) == "function" or type(o1) == "string" then
|
||||||
info.order = o2
|
info.order = o2
|
||||||
info[tgetn(info)+1] = two
|
tinsert(info, two)
|
||||||
o2 = callmethod(info, inputpos, refTbl[two], "order")
|
o2 = callmethod(info, inputpos, refTbl[two], "order")
|
||||||
info[tgetn(info)] = nil
|
tremove(info)
|
||||||
info.order = nil
|
info.order = nil
|
||||||
end
|
end
|
||||||
if o1<0 and o2<0 then return o1<o2 end
|
if o1<0 and o2<0 then return o1<o2 end
|
||||||
@@ -256,21 +260,22 @@ local function showhelp(info, inputpos, tab, depth, noHead)
|
|||||||
if type(desc) == "function" then
|
if type(desc) == "function" then
|
||||||
desc = callfunction(info, v, 'desc')
|
desc = callfunction(info, v, 'desc')
|
||||||
end
|
end
|
||||||
if v.type == "group" and pickfirstset(v.cmdInline, v.inline, false) then
|
if v.type == "group" and pickfirstset(3, v.cmdInline, v.inline, false) then
|
||||||
print(" "..(desc or name)..":")
|
print(" "..(desc or name)..":")
|
||||||
local oldhandler,oldhandler_at = getparam(info, inputpos, v, depth, "handler", handlertypes, handlermsg)
|
local oldhandler,oldhandler_at = getparam(info, inputpos, v, depth, "handler", handlertypes, handlermsg)
|
||||||
showhelp(info, inputpos, v, depth, true)
|
showhelp(info, inputpos, v, depth, true)
|
||||||
info.handler,info.handler_at = oldhandler,oldhandler_at
|
info.handler,info.handler_at = oldhandler,oldhandler_at
|
||||||
else
|
else
|
||||||
local key = gsub(k, " ", "_")
|
local key = strgsub(k, " ", "_")
|
||||||
print(" |cffffff78"..key.."|r - "..(desc or name or ""))
|
print(" |cffffff78"..key.."|r - "..(desc or name or ""))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
del(sortTbl) -- Ace3v: release the tables
|
||||||
|
del(refTbl)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
local function keybindingValidateFunc(text)
|
local function keybindingValidateFunc(text)
|
||||||
if text == nil or text == "NONE" then
|
if text == nil or text == "NONE" then
|
||||||
return nil
|
return nil
|
||||||
@@ -313,7 +318,7 @@ local function keybindingValidateFunc(text)
|
|||||||
if text == "" then
|
if text == "" then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
if not find(text, "^F%d+$") and text ~= "CAPSLOCK" and len(text) ~= 1 and (byte(text) < 128 or len(text) > 4) and not _G["KEY_" .. text] then
|
if not strfind(text,"^F%d+$") and text ~= "CAPSLOCK" and strlen(text) ~= 1 and (strbyte(text) < 128 or strlen(text) > 4) and not _G["KEY_" .. text] then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
local s = text
|
local s = text
|
||||||
@@ -359,7 +364,7 @@ local function handle(info, inputpos, tab, depth, retfalse)
|
|||||||
if tab.plugins and type(tab.plugins)~="table" then err(info,inputpos) end
|
if tab.plugins and type(tab.plugins)~="table" then err(info,inputpos) end
|
||||||
|
|
||||||
-- grab next arg from input
|
-- grab next arg from input
|
||||||
local _,nextpos,arg = find(info.input, " *([^ ]+) *", inputpos)
|
local _,nextpos,arg = strfind(info.input, " *([^ ]+) *", inputpos)
|
||||||
if not arg then
|
if not arg then
|
||||||
showhelp(info, inputpos, tab, depth)
|
showhelp(info, inputpos, tab, depth)
|
||||||
return
|
return
|
||||||
@@ -371,17 +376,17 @@ local function handle(info, inputpos, tab, depth, retfalse)
|
|||||||
if not(type(k)=="string" and type(v)=="table" and type(v.type)=="string") then err(info,inputpos, "options table child '"..tostring(k).."' is malformed") end
|
if not(type(k)=="string" and type(v)=="table" and type(v.type)=="string") then err(info,inputpos, "options table child '"..tostring(k).."' is malformed") end
|
||||||
|
|
||||||
-- is this child an inline group? if so, traverse into it
|
-- is this child an inline group? if so, traverse into it
|
||||||
if v.type=="group" and pickfirstset(v.cmdInline, v.inline, false) then
|
if v.type=="group" and pickfirstset(3, v.cmdInline, v.inline, false) then
|
||||||
info[depth+1] = k
|
tinsert(info,k)
|
||||||
if handle(info, inputpos, v, depth+1, true)==false then
|
if handle(info, inputpos, v, depth+1, true)==false then
|
||||||
info[depth+1] = nil
|
tremove(info)
|
||||||
-- wasn't found in there, but that's ok, we just keep looking down here
|
-- wasn't found in there, but that's ok, we just keep looking down here
|
||||||
else
|
else
|
||||||
return -- done, name was found in inline group
|
return -- done, name was found in inline group
|
||||||
end
|
end
|
||||||
-- matching name and not a inline group
|
-- matching name and not a inline group
|
||||||
elseif strlower(arg)==strlower(gsub(k, " ", "_")) then
|
elseif strlower(arg)==strlower(strgsub(k, " ", "_")) then
|
||||||
info[depth+1] = k
|
tinsert(info,k)
|
||||||
return handle(info,nextpos,v,depth+1)
|
return handle(info,nextpos,v,depth+1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -414,16 +419,21 @@ local function handle(info, inputpos, tab, depth, retfalse)
|
|||||||
elseif tab.type=="input" then
|
elseif tab.type=="input" then
|
||||||
------------ input --------------------------------------------
|
------------ input --------------------------------------------
|
||||||
|
|
||||||
|
if str=="" and tab.nullable == false then
|
||||||
|
usererr(info, inputpos, "'"..str.."' - " .. L["invalid input"])
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
local res = true
|
local res = true
|
||||||
if tab.pattern then
|
if tab.pattern then
|
||||||
if not(type(tab.pattern)=="string") then err(info, inputpos, "'pattern' - expected a string") end
|
if not(type(tab.pattern)=="string") then err(info, inputpos, "'pattern' - expected a string") end
|
||||||
if not strmatch(str, tab.pattern) then
|
if not strfind(str, tab.pattern) then
|
||||||
usererr(info, inputpos, "'"..str.."' - " .. L["invalid input"])
|
usererr(info, inputpos, "'"..str.."' - " .. L["invalid input"])
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
do_final(info, inputpos, tab, "set", str)
|
do_final(info, inputpos, tab, "set", 1, str)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -462,47 +472,63 @@ local function handle(info, inputpos, tab, depth, retfalse)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
do_final(info, inputpos, tab, "set", b)
|
do_final(info, inputpos, tab, "set", 1, b)
|
||||||
|
|
||||||
|
|
||||||
elseif tab.type=="range" then
|
elseif tab.type=="range" then
|
||||||
------------ range --------------------------------------------
|
------------ range --------------------------------------------
|
||||||
|
local str = strtrim(strlower(str))
|
||||||
|
if str == "" then
|
||||||
|
-- TODO: Show current value
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
local val = tonumber(str)
|
local val = tonumber(str)
|
||||||
if not val then
|
if not val then
|
||||||
usererr(info, inputpos, "'"..str.."' - "..L["expected number"])
|
usererr(info, inputpos, "'"..str.."' - "..L["expected number"])
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
if type(info.step)=="number" then
|
|
||||||
val = val- mod(val, info.step)
|
local step = getValueFromTab(info, inputpos, tab, "step")
|
||||||
|
local min = getValueFromTab(info, inputpos, tab, "min")
|
||||||
|
|
||||||
|
if type(step)=="number" then
|
||||||
|
val = min + math.floor((val-min)/step) * step
|
||||||
end
|
end
|
||||||
if type(info.min)=="number" and val<info.min then
|
|
||||||
usererr(info, inputpos, val.." - "..format(L["must be equal to or higher than %s"], tostring(info.min)) )
|
if type(min)=="number" and val<min then
|
||||||
return
|
usererr(info, inputpos, val.." - "..format(L["must be equal to or higher than %s"], tostring(min)) )
|
||||||
end
|
|
||||||
if type(info.max)=="number" and val>info.max then
|
|
||||||
usererr(info, inputpos, val.." - "..format(L["must be equal to or lower than %s"], tostring(info.max)) )
|
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
do_final(info, inputpos, tab, "set", val)
|
local max = getValueFromTab(info, inputpos, tab, "max")
|
||||||
|
if type(max)=="number" and val>max then
|
||||||
|
usererr(info, inputpos, val.." - "..format(L["must be equal to or lower than %s"], tostring(max)) )
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
do_final(info, inputpos, tab, "set", 1, val)
|
||||||
|
|
||||||
|
|
||||||
elseif tab.type=="select" then
|
elseif tab.type=="select" then
|
||||||
------------ select ------------------------------------
|
------------ select ------------------------------------
|
||||||
local str = strtrim(strlower(str))
|
local str = strtrim(strlower(str))
|
||||||
|
|
||||||
local values = tab.values
|
local values = getValueFromTab(info, inputpos, tab, "values")
|
||||||
if type(values) == "function" or type(values) == "string" then
|
|
||||||
info.values = values
|
|
||||||
values = callmethod(info, inputpos, tab, "values")
|
|
||||||
info.values = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
if str == "" then
|
if str == "" then
|
||||||
local b = callmethod(info, inputpos, tab, "get")
|
-- Ace3v: it is possbile to not have a current value
|
||||||
|
-- we do this only for select but not for multiselect
|
||||||
|
local b = tab.get
|
||||||
|
if type(b) == "function" or type(b) == "string" then
|
||||||
|
b = callmethod(info, inputpos, tab, "get")
|
||||||
|
else
|
||||||
|
b = nil
|
||||||
|
end
|
||||||
|
|
||||||
local fmt = "|cffffff78- [%s]|r %s"
|
local fmt = "|cffffff78- [%s]|r %s"
|
||||||
local fmt_sel = "|cffffff78- [%s]|r %s |cffff0000*|r"
|
local fmt_sel = "|cffffff78- [%s]|r %s |cffff0000*|r"
|
||||||
print(L["Options for |cffffff78"..info[thetn(info)].."|r:"])
|
print(L["Options for |cffffff78"..info[tgetn(info)].."|r:"])
|
||||||
for k, v in pairs(values) do
|
for k, v in pairs(values) do
|
||||||
if b == k then
|
if b == k then
|
||||||
print(format(fmt_sel, k, v))
|
print(format(fmt_sel, k, v))
|
||||||
@@ -510,6 +536,7 @@ local function handle(info, inputpos, tab, depth, retfalse)
|
|||||||
print(format(fmt, k, v))
|
print(format(fmt, k, v))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
if tab.valuesTableDestroyable then del(values) end
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -521,45 +548,42 @@ local function handle(info, inputpos, tab, depth, retfalse)
|
|||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
if tab.valuesTableDestroyable then del(values) end
|
||||||
if not ok then
|
if not ok then
|
||||||
usererr(info, inputpos, "'"..str.."' - "..L["unknown selection"])
|
usererr(info, inputpos, "'"..str.."' - "..L["unknown selection"])
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
do_final(info, inputpos, tab, "set", str)
|
do_final(info, inputpos, tab, "set", 1, str)
|
||||||
|
|
||||||
elseif tab.type=="multiselect" then
|
elseif tab.type=="multiselect" then
|
||||||
------------ multiselect -------------------------------------------
|
------------ multiselect -------------------------------------------
|
||||||
local str = strtrim(strlower(str))
|
local str = strtrim(strlower(str))
|
||||||
|
|
||||||
local values = tab.values
|
local values = getValueFromTab(info, inputpos, tab, "values")
|
||||||
if type(values) == "function" or type(values) == "string" then
|
|
||||||
info.values = values
|
|
||||||
values = callmethod(info, inputpos, tab, "values")
|
|
||||||
info.values = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
if str == "" then
|
if str == "" then
|
||||||
local fmt = "|cffffff78- [%s]|r %s"
|
local fmt = "|cffffff78- [%s]|r %s"
|
||||||
local fmt_sel = "|cffffff78- [%s]|r %s |cffff0000*|r"
|
local fmt_sel = "|cffffff78- [%s]|r %s |cffff0000*|r"
|
||||||
print(L["Options for |cffffff78"..info[tgetn(info)].."|r (multiple possible):"])
|
print(L["Options for |cffffff78"..info[tgetn(info)].."|r (multiple possible):"])
|
||||||
for k, v in pairs(values) do
|
for k, v in pairs(values) do
|
||||||
if callmethod(info, inputpos, tab, "get", k) then
|
if callmethod(info, inputpos, tab, "get", 1, k) then
|
||||||
print(format(fmt_sel, k, v))
|
print(format(fmt_sel, k, v))
|
||||||
else
|
else
|
||||||
print(format(fmt, k, v))
|
print(format(fmt, k, v))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
if tab.valuesTableDestroyable then del(values) end
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
--build a table of the selections, checking that they exist
|
--build a table of the selections, checking that they exist
|
||||||
--parse for =on =off =default in the process
|
--parse for =on =off =default in the process
|
||||||
--table will be key = true for options that should toggle, key = [on|off|default] for options to be set
|
--table will be key = true for options that should toggle, key = [on|off|default] for options to be set
|
||||||
local sels = {}
|
local sels = new()
|
||||||
for v in gmatch(str, "[^ ]+") do
|
for v in strgfind(str, "[^ ]+") do
|
||||||
--parse option=on etc
|
--parse option=on etc
|
||||||
local opt, val = strmatch(v, '(.+)=(.+)')
|
local _, _, opt, val = strfind(v, '(.+)=(.+)')
|
||||||
--get option if toggling
|
--get option if toggling
|
||||||
if not opt then
|
if not opt then
|
||||||
opt = v
|
opt = v
|
||||||
@@ -574,6 +598,7 @@ local function handle(info, inputpos, tab, depth, retfalse)
|
|||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
if tab.valuesTableDestroyable then del(values) end
|
||||||
|
|
||||||
if not ok then
|
if not ok then
|
||||||
usererr(info, inputpos, "'"..opt.."' - "..L["unknown selection"])
|
usererr(info, inputpos, "'"..opt.."' - "..L["unknown selection"])
|
||||||
@@ -591,6 +616,7 @@ local function handle(info, inputpos, tab, depth, retfalse)
|
|||||||
else
|
else
|
||||||
usererr(info, inputpos, format(L["'%s' '%s' - expected 'on' or 'off', or no argument to toggle."], v, val))
|
usererr(info, inputpos, format(L["'%s' '%s' - expected 'on' or 'off', or no argument to toggle."], v, val))
|
||||||
end
|
end
|
||||||
|
del(sels)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@@ -604,7 +630,7 @@ local function handle(info, inputpos, tab, depth, retfalse)
|
|||||||
|
|
||||||
if (val == true) then
|
if (val == true) then
|
||||||
--toggle the option
|
--toggle the option
|
||||||
local b = callmethod(info, inputpos, tab, "get", opt)
|
local b = callmethod(info, inputpos, tab, "get", 1, opt)
|
||||||
|
|
||||||
if tab.tristate then
|
if tab.tristate then
|
||||||
--cycle in true, nil, false order
|
--cycle in true, nil, false order
|
||||||
@@ -630,8 +656,9 @@ local function handle(info, inputpos, tab, depth, retfalse)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
do_final(info, inputpos, tab, "set", opt, newval)
|
do_final(info, inputpos, tab, "set", 2, opt, newval)
|
||||||
end
|
end
|
||||||
|
del(sels)
|
||||||
|
|
||||||
|
|
||||||
elseif tab.type=="color" then
|
elseif tab.type=="color" then
|
||||||
@@ -642,22 +669,17 @@ local function handle(info, inputpos, tab, depth, retfalse)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local r, g, b, a
|
local _, r, g, b, a
|
||||||
|
|
||||||
local hasAlpha = tab.hasAlpha
|
local hasAlpha = getValueFromTab(info, inputpos, tab, 'hasAlpha')
|
||||||
if type(hasAlpha) == "function" or type(hasAlpha) == "string" then
|
|
||||||
info.hasAlpha = hasAlpha
|
|
||||||
hasAlpha = callmethod(info, inputpos, tab, 'hasAlpha')
|
|
||||||
info.hasAlpha = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
if hasAlpha then
|
if hasAlpha then
|
||||||
if len(str) == 8 and find(str, "^%x*$") then
|
if strlen(str) == 8 and strfind(str, "^%x*$") then
|
||||||
--parse a hex string
|
--parse a hex string
|
||||||
r,g,b,a = tonumber(sub(str, 1, 2), 16) / 255, tonumber(sub(str, 3, 4), 16) / 255, tonumber(sub(str, 5, 6), 16) / 255
|
r,g,b,a = tonumber(strsub(str, 1, 2), 16) / 255, tonumber(strsub(str, 3, 4), 16) / 255, tonumber(strsub(str, 5, 6), 16) / 255, tonumber(strsub(str, 7, 8), 16) / 255
|
||||||
else
|
else
|
||||||
--parse seperate values
|
--parse seperate values
|
||||||
r,g,b,a = strmatch(str, "^([%d%.]+) ([%d%.]+) ([%d%.]+) ([%d%.]+)$")
|
_,_,r,g,b,a = strfind(str, "^([%d%.]+) ([%d%.]+) ([%d%.]+) ([%d%.]+)$")
|
||||||
r,g,b,a = tonumber(r), tonumber(g), tonumber(b), tonumber(a)
|
r,g,b,a = tonumber(r), tonumber(g), tonumber(b), tonumber(a)
|
||||||
end
|
end
|
||||||
if not (r and g and b and a) then
|
if not (r and g and b and a) then
|
||||||
@@ -679,12 +701,12 @@ local function handle(info, inputpos, tab, depth, retfalse)
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
a = 1.0
|
a = 1.0
|
||||||
if len(str) == 6 and find(str, "^%x*$") then
|
if strlen(str) == 6 and strfind(str, "^%x*$") then
|
||||||
--parse a hex string
|
--parse a hex string
|
||||||
r,g,b = tonumber(sub(str, 1, 2), 16) / 255, tonumber(sub(str, 3, 4), 16) / 255, tonumber(sub(str, 5, 6), 16) / 255
|
r,g,b = tonumber(strsub(str, 1, 2), 16) / 255, tonumber(strsub(str, 3, 4), 16) / 255, tonumber(strsub(str, 5, 6), 16) / 255
|
||||||
else
|
else
|
||||||
--parse seperate values
|
--parse seperate values
|
||||||
r,g,b = strmatch(str, "^([%d%.]+) ([%d%.]+) ([%d%.]+)$")
|
_,_,r,g,b = strfind(str, "^([%d%.]+) ([%d%.]+) ([%d%.]+)$")
|
||||||
r,g,b = tonumber(r), tonumber(g), tonumber(b)
|
r,g,b = tonumber(r), tonumber(g), tonumber(b)
|
||||||
end
|
end
|
||||||
if not (r and g and b) then
|
if not (r and g and b) then
|
||||||
@@ -704,7 +726,7 @@ local function handle(info, inputpos, tab, depth, retfalse)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
do_final(info, inputpos, tab, "set", r,g,b,a)
|
do_final(info, inputpos, tab, "set", 4, r,g,b,a)
|
||||||
|
|
||||||
elseif tab.type=="keybinding" then
|
elseif tab.type=="keybinding" then
|
||||||
------------ keybinding --------------------------------------------
|
------------ keybinding --------------------------------------------
|
||||||
@@ -719,7 +741,7 @@ local function handle(info, inputpos, tab, depth, retfalse)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
do_final(info, inputpos, tab, "set", value)
|
do_final(info, inputpos, tab, "set", 1, value)
|
||||||
|
|
||||||
elseif tab.type=="description" then
|
elseif tab.type=="description" then
|
||||||
------------ description --------------------
|
------------ description --------------------
|
||||||
@@ -749,6 +771,9 @@ end
|
|||||||
-- LibStub("AceConfigCmd-3.0").HandleCommand(MyAddon, "mychat", "MyOptions", input)
|
-- LibStub("AceConfigCmd-3.0").HandleCommand(MyAddon, "mychat", "MyOptions", input)
|
||||||
-- end
|
-- end
|
||||||
-- end
|
-- end
|
||||||
|
-- Ace3v: experimental, user should copy info table if he wanna reuse it outside
|
||||||
|
-- then handler
|
||||||
|
local info_ = {}
|
||||||
function AceConfigCmd:HandleCommand(slashcmd, appName, input)
|
function AceConfigCmd:HandleCommand(slashcmd, appName, input)
|
||||||
|
|
||||||
local optgetter = cfgreg:GetOptionsTable(appName)
|
local optgetter = cfgreg:GetOptionsTable(appName)
|
||||||
@@ -757,32 +782,65 @@ function AceConfigCmd:HandleCommand(slashcmd, appName, input)
|
|||||||
end
|
end
|
||||||
local options = assert( optgetter("cmd", MAJOR) )
|
local options = assert( optgetter("cmd", MAJOR) )
|
||||||
|
|
||||||
local info = { -- Don't try to recycle this, it gets handed off to callbacks and whatnot
|
-- Ace3v: prevent user from using AceConfigCmd as self
|
||||||
[0] = slashcmd,
|
if self == AceConfigCmd then
|
||||||
appName = appName,
|
error([[Usage: HandleCommand("slashcmd", "appName", "input"): 'self' - use your own 'self']], 2)
|
||||||
options = options,
|
end
|
||||||
input = input,
|
|
||||||
self = self,
|
|
||||||
handler = self,
|
|
||||||
uiType = "cmd",
|
|
||||||
uiName = MAJOR,
|
|
||||||
}
|
|
||||||
|
|
||||||
handle(info, 1, options, 0) -- (info, inputpos, table, depth)
|
--local info = { -- Don't try to recycle this, it gets handed off to callbacks and whatnot
|
||||||
|
-- [0] = slashcmd,
|
||||||
|
-- appName = appName,
|
||||||
|
-- options = options,
|
||||||
|
-- input = input,
|
||||||
|
-- self = self,
|
||||||
|
-- handler = self,
|
||||||
|
-- uiType = "cmd",
|
||||||
|
-- uiName = MAJOR,
|
||||||
|
--}
|
||||||
|
|
||||||
|
wipe(info_)
|
||||||
|
info_[0] = slashcmd
|
||||||
|
info_.appName = appName
|
||||||
|
info_.options = options
|
||||||
|
info_.input = input
|
||||||
|
info_.self = self
|
||||||
|
info_.handler = self
|
||||||
|
info_.uiType = "cmd"
|
||||||
|
info_.uiName = MAJOR
|
||||||
|
|
||||||
|
handle(info_, 1, options, 0) -- (info, inputpos, table, depth)
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Utility function to create a slash command handler.
|
--- Utility function to create a slash command handler.
|
||||||
-- Also registers tab completion with AceTab
|
-- Also registers tab completion with AceTab
|
||||||
-- @param slashcmd The slash command WITHOUT leading slash (only used for error output)
|
-- @param slashcmd The slash command WITHOUT leading slash (only used for error output)
|
||||||
-- @param appName The application name as given to `:RegisterOptionsTable()`
|
-- @param appName The application name as given to `:RegisterOptionsTable()`
|
||||||
function AceConfigCmd:CreateChatCommand(slashcmd, appName)
|
function AceConfigCmd:CreateChatCommand(slashcmd, appName, func)
|
||||||
if not AceConsole then
|
if not AceConsole then
|
||||||
AceConsole = LibStub(AceConsoleName)
|
AceConsole = LibStub(AceConsoleName)
|
||||||
end
|
end
|
||||||
if AceConsole.RegisterChatCommand(self, slashcmd, function(input)
|
|
||||||
|
-- Ace3v: prevent user from using AceConfigCmd as self
|
||||||
|
if self == AceConfigCmd then
|
||||||
|
error([[Usage: CreateChatCommand("slashcmd", "appName"[, "func"]): 'self' - use your own 'self']], 2)
|
||||||
|
end
|
||||||
|
|
||||||
|
local t = type(func)
|
||||||
|
|
||||||
|
-- Ace3v: make it possible to call another function
|
||||||
|
local handler
|
||||||
|
if t == "string" then
|
||||||
|
handler = function(input) self[func](self, input, slashcmd, appName) end
|
||||||
|
elseif t ~= "function" then
|
||||||
|
handler = function(input)
|
||||||
AceConfigCmd.HandleCommand(self, slashcmd, appName, input) -- upgradable
|
AceConfigCmd.HandleCommand(self, slashcmd, appName, input) -- upgradable
|
||||||
end,
|
end
|
||||||
true) then -- succesfully registered so lets get the command -> app table in
|
else
|
||||||
|
handler = func
|
||||||
|
end
|
||||||
|
|
||||||
|
if AceConsole.RegisterChatCommand(self, slashcmd, handler, true) then
|
||||||
|
-- succesfully registered so lets get the command -> app table in
|
||||||
commands[slashcmd] = appName
|
commands[slashcmd] = appName
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -794,3 +852,12 @@ end
|
|||||||
function AceConfigCmd:GetChatCommandOptions(slashcmd)
|
function AceConfigCmd:GetChatCommandOptions(slashcmd)
|
||||||
return commands[slashcmd]
|
return commands[slashcmd]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function AceConfigCmd:Embed(target)
|
||||||
|
target["HandleCommand"] = self["HandleCommand"]
|
||||||
|
target["CreateChatCommand"] = self["CreateChatCommand"]
|
||||||
|
end
|
||||||
|
|
||||||
|
for addon in pairs(AceConfigCmd.embeds) do
|
||||||
|
AceConfigCmd:Embed(addon)
|
||||||
|
end
|
||||||
+179
-237
@@ -1,17 +1,20 @@
|
|||||||
--- AceConfigDialog-3.0 generates AceGUI-3.0 based windows based on option tables.
|
--- AceConfigDialog-3.0 generates AceGUI-3.0 based windows based on option tables.
|
||||||
-- @class file
|
-- @class file
|
||||||
-- @name AceConfigDialog-3.0
|
-- @name AceConfigDialog-3.0
|
||||||
-- @release $Id: AceConfigDialog-3.0.lua 1126 2014-11-10 06:38:01Z nevcairiel $
|
-- @release $Id: AceConfigDialog-3.0.lua 1139 2016-07-03 07:43:51Z nevcairiel $
|
||||||
|
|
||||||
local LibStub = LibStub
|
local LibStub = LibStub
|
||||||
local gui = LibStub("AceGUI-3.0")
|
local MAJOR, MINOR = "AceConfigDialog-3.0", 61
|
||||||
local reg = LibStub("AceConfigRegistry-3.0-ElvUI")
|
|
||||||
|
|
||||||
local MAJOR, MINOR = "AceConfigDialog-3.0-ElvUI", 2
|
|
||||||
local AceConfigDialog, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
|
local AceConfigDialog, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
|
||||||
|
|
||||||
if not AceConfigDialog then return end
|
if not AceConfigDialog then return end
|
||||||
|
|
||||||
|
local AceCore = LibStub("AceCore-3.0")
|
||||||
|
local wipe, strsplit = AceCore.wipe, AceCore.strsplit
|
||||||
|
local safecall = AceCore.safecall
|
||||||
|
local Dispatchers = AceCore.Dispatchers
|
||||||
|
local countargs = AceCore.countargs
|
||||||
|
|
||||||
AceConfigDialog.OpenFrames = AceConfigDialog.OpenFrames or {}
|
AceConfigDialog.OpenFrames = AceConfigDialog.OpenFrames or {}
|
||||||
AceConfigDialog.Status = AceConfigDialog.Status or {}
|
AceConfigDialog.Status = AceConfigDialog.Status or {}
|
||||||
AceConfigDialog.frame = AceConfigDialog.frame or CreateFrame("Frame")
|
AceConfigDialog.frame = AceConfigDialog.frame or CreateFrame("Frame")
|
||||||
@@ -20,67 +23,25 @@ AceConfigDialog.frame.apps = AceConfigDialog.frame.apps or {}
|
|||||||
AceConfigDialog.frame.closing = AceConfigDialog.frame.closing or {}
|
AceConfigDialog.frame.closing = AceConfigDialog.frame.closing or {}
|
||||||
AceConfigDialog.frame.closeAllOverride = AceConfigDialog.frame.closeAllOverride or {}
|
AceConfigDialog.frame.closeAllOverride = AceConfigDialog.frame.closeAllOverride or {}
|
||||||
|
|
||||||
|
local gui = LibStub("AceGUI-3.0")
|
||||||
|
local reg = LibStub("AceConfigRegistry-3.0")
|
||||||
|
|
||||||
-- Lua APIs
|
-- Lua APIs
|
||||||
local tconcat, tgetn, tinsert, tsort, tremove, tsort = table.concat, table.getn, table.insert, table.sort, table.remove, table.sort
|
local tconcat, tinsert, tsort, tremove, tgetn, tsetn = table.concat, table.insert, table.sort, table.remove, table.getn, table.setn
|
||||||
local strmatch, format, strsplit, strupper = string.match, string.format, string.split, string.upper
|
local format, strfind, strupper = string.format, string.find, string.upper
|
||||||
local assert, loadstring, error = assert, loadstring, error
|
local assert, loadstring, error = assert, loadstring, error
|
||||||
local pairs, next, select, type, unpack, wipe, ipairs = pairs, next, select, type, unpack, wipe, ipairs
|
local pairs, next, type, unpack, ipairs = pairs, next, type, unpack, ipairs
|
||||||
local rawset, tostring, tonumber = rawset, tostring, tonumber
|
local rawset, tostring, tonumber = rawset, tostring, tonumber
|
||||||
local math_min, math_max, math_floor = math.min, math.max, math.floor
|
local math_min, math_max, math_floor = math.min, math.max, math.floor
|
||||||
|
|
||||||
local OKAY = OKAY
|
|
||||||
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
|
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
|
||||||
-- List them here for Mikk's FindGlobals script
|
-- List them here for Mikk's FindGlobals script
|
||||||
-- GLOBALS: NORMAL_FONT_COLOR, GameTooltip, StaticPopupDialogs, ACCEPT, CANCEL, StaticPopup_Show
|
-- GLOBALS: NORMAL_FONT_COLOR, GameTooltip, StaticPopupDialogs, ACCEPT, CANCEL, StaticPopup_Show
|
||||||
-- GLOBALS: PlaySound, GameFontHighlight, GameFontHighlightSmall, GameFontHighlightLarge
|
-- GLOBALS: PlaySound, GameFontHighlight, GameFontHighlightSmall, GameFontHighlightLarge
|
||||||
-- GLOBALS: CloseSpecialWindows, InterfaceOptions_AddCategory, geterrorhandler
|
-- GLOBALS: CloseSpecialWindows, InterfaceOptions_AddCategory, geterrorhandler
|
||||||
-- GLOBALS: STATICPOPUP_NUMDIALOGS
|
|
||||||
|
|
||||||
local emptyTbl = {}
|
local emptyTbl = {}
|
||||||
|
|
||||||
--[[
|
|
||||||
xpcall safecall implementation
|
|
||||||
]]
|
|
||||||
local xpcall = xpcall
|
|
||||||
|
|
||||||
local function errorhandler(err)
|
|
||||||
return geterrorhandler()(err)
|
|
||||||
end
|
|
||||||
|
|
||||||
local function CreateDispatcher(argCount)
|
|
||||||
local code = [[
|
|
||||||
local method, ARGS
|
|
||||||
local function call() return method(ARGS) end
|
|
||||||
|
|
||||||
local function dispatch(func, ...)
|
|
||||||
method = func
|
|
||||||
if not method then return end
|
|
||||||
ARGS = unpack(arg)
|
|
||||||
return xpcall(call, function(err) return geterrorhandler()(err) end)
|
|
||||||
end
|
|
||||||
|
|
||||||
return dispatch
|
|
||||||
]]
|
|
||||||
|
|
||||||
local ARGS = {}
|
|
||||||
for i = 1, argCount do ARGS[i] = "arg"..i end
|
|
||||||
code = gsub(code, "ARGS", tconcat(ARGS, ", "))
|
|
||||||
return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(xpcall, errorhandler)
|
|
||||||
end
|
|
||||||
|
|
||||||
local Dispatchers = setmetatable({}, {__index=function(self, argCount)
|
|
||||||
local dispatcher = CreateDispatcher(argCount)
|
|
||||||
rawset(self, argCount, dispatcher)
|
|
||||||
return dispatcher
|
|
||||||
end})
|
|
||||||
Dispatchers[0] = function(func)
|
|
||||||
return xpcall(func, errorhandler)
|
|
||||||
end
|
|
||||||
|
|
||||||
local function safecall(func, ...)
|
|
||||||
return Dispatchers[tgetn(arg)](func, unpack(arg))
|
|
||||||
end
|
|
||||||
|
|
||||||
local width_multiplier = 170
|
local width_multiplier = 170
|
||||||
|
|
||||||
--[[
|
--[[
|
||||||
@@ -122,6 +83,7 @@ do
|
|||||||
for k, v in pairs(t) do
|
for k, v in pairs(t) do
|
||||||
c[k] = v
|
c[k] = v
|
||||||
end
|
end
|
||||||
|
tsetn(c, tgetn(t))
|
||||||
return c
|
return c
|
||||||
end
|
end
|
||||||
function del(t)
|
function del(t)
|
||||||
@@ -139,14 +101,7 @@ do
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- picks the first non-nil value and returns it
|
-- picks the first non-nil value and returns it
|
||||||
local function pickfirstset(...)
|
local pickfirstset = AceCore.pickfirstset
|
||||||
local args = unpack(arg)
|
|
||||||
for i=1,select("#", args) do
|
|
||||||
if select(i,args)~=nil then
|
|
||||||
return select(i,args)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
--gets an option from a given group, checking plugins
|
--gets an option from a given group, checking plugins
|
||||||
local function GetSubOption(group, key)
|
local function GetSubOption(group, key)
|
||||||
@@ -196,11 +151,10 @@ local allIsLiteral = {
|
|||||||
--gets the value for a member that could be a function
|
--gets the value for a member that could be a function
|
||||||
--function refs are called with an info arg
|
--function refs are called with an info arg
|
||||||
--every other type is returned
|
--every other type is returned
|
||||||
local function GetOptionsMemberValue(membername, option, options, path, appName, ...)
|
local function GetOptionsMemberValue(membername, option, options, path, appName, argc, a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||||
--get definition for the member
|
--get definition for the member
|
||||||
local inherits = isInherited[membername]
|
local inherits = isInherited[membername]
|
||||||
|
|
||||||
|
|
||||||
--get the member of the option, traversing the tree if it can be inherited
|
--get the member of the option, traversing the tree if it can be inherited
|
||||||
local member
|
local member
|
||||||
|
|
||||||
@@ -228,11 +182,13 @@ local function GetOptionsMemberValue(membername, option, options, path, appName,
|
|||||||
local group = options
|
local group = options
|
||||||
handler = group.handler or handler
|
handler = group.handler or handler
|
||||||
|
|
||||||
for i = 1, tgetn(path) do
|
local l = tgetn(path)
|
||||||
|
for i = 1, l do
|
||||||
group = GetSubOption(group, path[i])
|
group = GetSubOption(group, path[i])
|
||||||
info[i] = path[i]
|
info[i] = path[i]
|
||||||
handler = group.handler or handler
|
handler = group.handler or handler
|
||||||
end
|
end
|
||||||
|
tsetn(info, l)
|
||||||
|
|
||||||
info.options = options
|
info.options = options
|
||||||
info.appName = appName
|
info.appName = appName
|
||||||
@@ -244,21 +200,22 @@ local function GetOptionsMemberValue(membername, option, options, path, appName,
|
|||||||
info.uiType = "dialog"
|
info.uiType = "dialog"
|
||||||
info.uiName = MAJOR
|
info.uiName = MAJOR
|
||||||
|
|
||||||
local a, b, c ,d, e, f, g, h
|
argc = argc or 0
|
||||||
|
local a, b, c ,d
|
||||||
--using 4 returns for the get of a color type, increase if a type needs more
|
--using 4 returns for the get of a color type, increase if a type needs more
|
||||||
if type(member) == "function" then
|
if type(member) == "function" then
|
||||||
--Call the function
|
--Call the function
|
||||||
a,b,c,d, e, f, g, h = member(info, unpack(arg))
|
a,b,c,d = Dispatchers[argc+1](member,info,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||||
else
|
else
|
||||||
--Call the method
|
--Call the method
|
||||||
if handler and handler[member] then
|
if handler and handler[member] then
|
||||||
a,b,c,d,e, f, g, h = handler[member](handler, info, unpack(arg))
|
a,b,c,d = Dispatchers[argc+2](handler[member],handler,info,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||||
else
|
else
|
||||||
error(format("Method %s doesn't exist in handler for type %s", member, membername))
|
error(format("Method %s doesn't exist in handler for type %s", member, membername))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
del(info)
|
del(info)
|
||||||
return a,b,c,d,e, f, g, h
|
return a,b,c,d
|
||||||
else
|
else
|
||||||
--The value isnt a function to call, return it
|
--The value isnt a function to call, return it
|
||||||
return member
|
return member
|
||||||
@@ -296,12 +253,12 @@ local function CallOptionsFunction(funcname ,option, options, path, appName, ...
|
|||||||
local a, b, c ,d
|
local a, b, c ,d
|
||||||
if type(func) == "string" then
|
if type(func) == "string" then
|
||||||
if handler and handler[func] then
|
if handler and handler[func] then
|
||||||
a,b,c,d = handler[func](handler, info, unpack(arg))
|
a,b,c,d = handler[func](handler, info, ...)
|
||||||
else
|
else
|
||||||
error(string.format("Method %s doesn't exist in handler for type func", func))
|
error(string.format("Method %s doesn't exist in handler for type func", func))
|
||||||
end
|
end
|
||||||
elseif type(func) == "function" then
|
elseif type(func) == "function" then
|
||||||
a,b,c,d = func(info, unpack(arg))
|
a,b,c,d = func(info, ...)
|
||||||
end
|
end
|
||||||
del(info)
|
del(info)
|
||||||
return a,b,c,d
|
return a,b,c,d
|
||||||
@@ -354,10 +311,10 @@ local function BuildSortedOptionsTable(group, keySort, opts, options, path, appN
|
|||||||
tinsert(keySort, k)
|
tinsert(keySort, k)
|
||||||
opts[k] = v
|
opts[k] = v
|
||||||
|
|
||||||
path[tgetn(path)+1] = k
|
tinsert(path,k)
|
||||||
tempOrders[k] = GetOptionsMemberValue("order", v, options, path, appName)
|
tempOrders[k] = GetOptionsMemberValue("order", v, options, path, appName)
|
||||||
tempNames[k] = GetOptionsMemberValue("name", v, options, path, appName)
|
tempNames[k] = GetOptionsMemberValue("name", v, options, path, appName)
|
||||||
path[tgetn(path)] = nil
|
tremove(path)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -368,10 +325,10 @@ local function BuildSortedOptionsTable(group, keySort, opts, options, path, appN
|
|||||||
tinsert(keySort, k)
|
tinsert(keySort, k)
|
||||||
opts[k] = v
|
opts[k] = v
|
||||||
|
|
||||||
path[tgetn(path)+1] = k
|
tinsert(path,k)
|
||||||
tempOrders[k] = GetOptionsMemberValue("order", v, options, path, appName)
|
tempOrders[k] = GetOptionsMemberValue("order", v, options, path, appName)
|
||||||
tempNames[k] = GetOptionsMemberValue("name", v, options, path, appName)
|
tempNames[k] = GetOptionsMemberValue("name", v, options, path, appName)
|
||||||
path[tgetn(path)] = nil
|
tremove(path)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -464,10 +421,11 @@ end
|
|||||||
-- The path specified has to match the keys of the groups in the table.
|
-- The path specified has to match the keys of the groups in the table.
|
||||||
-- @param appName The application name as given to `:RegisterOptionsTable()`
|
-- @param appName The application name as given to `:RegisterOptionsTable()`
|
||||||
-- @param ... The path to the key that should be selected
|
-- @param ... The path to the key that should be selected
|
||||||
function AceConfigDialog:SelectGroup(appName, ...)
|
do
|
||||||
|
local args = {nil,nil,nil,nil,nil,nil,nil,nil,nil,nil}
|
||||||
|
function AceConfigDialog:SelectGroup(appName, a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||||
local path = new()
|
local path = new()
|
||||||
|
|
||||||
|
|
||||||
local app = reg:GetOptionsTable(appName)
|
local app = reg:GetOptionsTable(appName)
|
||||||
if not app then
|
if not app then
|
||||||
error(format("%s isn't registed with AceConfigRegistry, unable to open config", appName), 2)
|
error(format("%s isn't registed with AceConfigRegistry, unable to open config", appName), 2)
|
||||||
@@ -482,8 +440,21 @@ function AceConfigDialog:SelectGroup(appName, ...)
|
|||||||
local treevalue
|
local treevalue
|
||||||
local treestatus
|
local treestatus
|
||||||
|
|
||||||
for n = 1, tgetn(arg) do
|
args[1] = a1
|
||||||
local key = arg[n]
|
args[2] = a2
|
||||||
|
args[3] = a3
|
||||||
|
args[4] = a4
|
||||||
|
args[5] = a5
|
||||||
|
args[6] = a6
|
||||||
|
args[7] = a7
|
||||||
|
args[8] = a8
|
||||||
|
args[9] = a9
|
||||||
|
args[10] = a10
|
||||||
|
for n = 1, 10 do
|
||||||
|
local key = args[n]
|
||||||
|
arg[n] = nil
|
||||||
|
|
||||||
|
if not key then break end
|
||||||
|
|
||||||
if group.childGroups == "tab" or group.childGroups == "select" then
|
if group.childGroups == "tab" or group.childGroups == "select" then
|
||||||
--if this is a tab or select group, select the group
|
--if this is a tab or select group, select the group
|
||||||
@@ -527,6 +498,7 @@ function AceConfigDialog:SelectGroup(appName, ...)
|
|||||||
del(path)
|
del(path)
|
||||||
reg:NotifyChange(appName)
|
reg:NotifyChange(appName)
|
||||||
end
|
end
|
||||||
|
end -- AceConfigDialog:SelectGroup
|
||||||
|
|
||||||
local function OptionOnMouseOver(widget, event)
|
local function OptionOnMouseOver(widget, event)
|
||||||
--show a tooltip/set the status bar to the desc text
|
--show a tooltip/set the status bar to the desc text
|
||||||
@@ -547,13 +519,13 @@ local function OptionOnMouseOver(widget, event)
|
|||||||
GameTooltip:SetText(name, 1, .82, 0, true)
|
GameTooltip:SetText(name, 1, .82, 0, true)
|
||||||
|
|
||||||
if opt.type == "multiselect" then
|
if opt.type == "multiselect" then
|
||||||
GameTooltip:AddLine(user.text, 0.5, 0.5, 0.8, 1)
|
GameTooltip:AddLine(user.text, 0.5, 0.5, 0.8, true)
|
||||||
end
|
end
|
||||||
if type(desc) == "string" then
|
if type(desc) == "string" then
|
||||||
GameTooltip:AddLine(desc, 1, 1, 1, 1)
|
GameTooltip:AddLine(desc, 1, 1, 1, true)
|
||||||
end
|
end
|
||||||
if type(usage) == "string" then
|
if type(usage) == "string" then
|
||||||
GameTooltip:AddLine("Usage: "..usage, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, 1)
|
GameTooltip:AddLine("Usage: "..usage, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, true)
|
||||||
end
|
end
|
||||||
|
|
||||||
GameTooltip:Show()
|
GameTooltip:Show()
|
||||||
@@ -571,7 +543,7 @@ local function GetFuncName(option)
|
|||||||
return "set"
|
return "set"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local function confirmPopup(appName, rootframe, basepath, info, message, func, ...)
|
local function confirmPopup(appName, rootframe, basepath, info, message, func, argc,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||||
if not StaticPopupDialogs["ACECONFIGDIALOG30_CONFIRM_DIALOG"] then
|
if not StaticPopupDialogs["ACECONFIGDIALOG30_CONFIRM_DIALOG"] then
|
||||||
StaticPopupDialogs["ACECONFIGDIALOG30_CONFIRM_DIALOG"] = {}
|
StaticPopupDialogs["ACECONFIGDIALOG30_CONFIRM_DIALOG"] = {}
|
||||||
end
|
end
|
||||||
@@ -585,7 +557,7 @@ local function confirmPopup(appName, rootframe, basepath, info, message, func, .
|
|||||||
t.preferredIndex = STATICPOPUP_NUMDIALOGS
|
t.preferredIndex = STATICPOPUP_NUMDIALOGS
|
||||||
local dialog, oldstrata
|
local dialog, oldstrata
|
||||||
t.OnAccept = function()
|
t.OnAccept = function()
|
||||||
safecall(func, unpack(t))
|
safecall(func, tgetn(t), unpack(t))
|
||||||
if dialog and oldstrata then
|
if dialog and oldstrata then
|
||||||
dialog:SetFrameStrata(oldstrata)
|
dialog:SetFrameStrata(oldstrata)
|
||||||
end
|
end
|
||||||
@@ -599,9 +571,23 @@ local function confirmPopup(appName, rootframe, basepath, info, message, func, .
|
|||||||
AceConfigDialog:Open(appName, rootframe, unpack(basepath or emptyTbl))
|
AceConfigDialog:Open(appName, rootframe, unpack(basepath or emptyTbl))
|
||||||
del(info)
|
del(info)
|
||||||
end
|
end
|
||||||
for i = 1, tgetn(arg) do
|
t[1] = a1
|
||||||
t[i] = arg[i] or false
|
t[2] = a2
|
||||||
|
t[3] = a3
|
||||||
|
t[4] = a4
|
||||||
|
t[5] = a5
|
||||||
|
t[6] = a6
|
||||||
|
t[7] = a7
|
||||||
|
t[8] = a8
|
||||||
|
t[9] = a9
|
||||||
|
t[10] = a10
|
||||||
|
for i=1,argc do
|
||||||
|
t[i] = t[i] or false
|
||||||
end
|
end
|
||||||
|
for i=argc+1,10 do
|
||||||
|
t[i] = nil
|
||||||
|
end
|
||||||
|
tsetn(t,argc)
|
||||||
t.timeout = 0
|
t.timeout = 0
|
||||||
t.whileDead = 1
|
t.whileDead = 1
|
||||||
t.hideOnEscape = 1
|
t.hideOnEscape = 1
|
||||||
@@ -613,32 +599,7 @@ local function confirmPopup(appName, rootframe, basepath, info, message, func, .
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function validationErrorPopup(message)
|
local function ActivateControl(widget, event, argc, a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||||
if not StaticPopupDialogs["ACECONFIGDIALOG30_VALIDATION_ERROR_DIALOG"] then
|
|
||||||
StaticPopupDialogs["ACECONFIGDIALOG30_VALIDATION_ERROR_DIALOG"] = {}
|
|
||||||
end
|
|
||||||
local t = StaticPopupDialogs["ACECONFIGDIALOG30_VALIDATION_ERROR_DIALOG"]
|
|
||||||
t.text = message
|
|
||||||
t.button1 = OKAY
|
|
||||||
t.preferredIndex = STATICPOPUP_NUMDIALOGS
|
|
||||||
local dialog, oldstrata
|
|
||||||
t.OnAccept = function()
|
|
||||||
if dialog and oldstrata then
|
|
||||||
dialog:SetFrameStrata(oldstrata)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
t.timeout = 0
|
|
||||||
t.whileDead = 1
|
|
||||||
t.hideOnEscape = 1
|
|
||||||
|
|
||||||
dialog = StaticPopup_Show("ACECONFIGDIALOG30_VALIDATION_ERROR_DIALOG")
|
|
||||||
if dialog then
|
|
||||||
oldstrata = dialog:GetFrameStrata()
|
|
||||||
dialog:SetFrameStrata("TOOLTIP")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function ActivateControl(widget, event, ...)
|
|
||||||
--This function will call the set / execute handler for the widget
|
--This function will call the set / execute handler for the widget
|
||||||
--widget:GetUserDataTable() contains the needed info
|
--widget:GetUserDataTable() contains the needed info
|
||||||
local user = widget:GetUserDataTable()
|
local user = widget:GetUserDataTable()
|
||||||
@@ -661,7 +622,9 @@ local function ActivateControl(widget, event, ...)
|
|||||||
handler = group.handler or handler
|
handler = group.handler or handler
|
||||||
confirm = group.confirm
|
confirm = group.confirm
|
||||||
validate = group.validate
|
validate = group.validate
|
||||||
for i = 1, tgetn(path) do
|
|
||||||
|
local l = tgetn(path)
|
||||||
|
for i = 1, l do
|
||||||
local v = path[i]
|
local v = path[i]
|
||||||
group = GetSubOption(group, v)
|
group = GetSubOption(group, v)
|
||||||
info[i] = v
|
info[i] = v
|
||||||
@@ -676,6 +639,7 @@ local function ActivateControl(widget, event, ...)
|
|||||||
validate = group.validate
|
validate = group.validate
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
tsetn(info, l)
|
||||||
|
|
||||||
info.options = options
|
info.options = options
|
||||||
info.appName = user.appName
|
info.appName = user.appName
|
||||||
@@ -687,6 +651,7 @@ local function ActivateControl(widget, event, ...)
|
|||||||
info.uiName = MAJOR
|
info.uiName = MAJOR
|
||||||
|
|
||||||
local name
|
local name
|
||||||
|
|
||||||
if type(option.name) == "function" then
|
if type(option.name) == "function" then
|
||||||
name = option.name(info)
|
name = option.name(info)
|
||||||
elseif type(option.name) == "string" then
|
elseif type(option.name) == "string" then
|
||||||
@@ -701,7 +666,7 @@ local function ActivateControl(widget, event, ...)
|
|||||||
|
|
||||||
if option.type == "input" then
|
if option.type == "input" then
|
||||||
if type(pattern)=="string" then
|
if type(pattern)=="string" then
|
||||||
if not strmatch(unpack(arg), pattern) then
|
if not strfind(a1, pattern) then
|
||||||
validated = false
|
validated = false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -711,46 +676,53 @@ local function ActivateControl(widget, event, ...)
|
|||||||
if validated and option.type ~= "execute" then
|
if validated and option.type ~= "execute" then
|
||||||
if type(validate) == "string" then
|
if type(validate) == "string" then
|
||||||
if handler and handler[validate] then
|
if handler and handler[validate] then
|
||||||
success, validated = safecall(handler[validate], handler, info, unpack(arg))
|
success, validated = safecall(handler[validate], argc+2, handler, info, a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||||
if not success then validated = false end
|
if not success then validated = false end
|
||||||
else
|
else
|
||||||
error(format("Method %s doesn't exist in handler for type execute", validate))
|
error(format("Method %s doesn't exist in handler for type execute", validate))
|
||||||
end
|
end
|
||||||
elseif type(validate) == "function" then
|
elseif type(validate) == "function" then
|
||||||
success, validated = safecall(validate, info, unpack(arg))
|
success, validated = safecall(validate, argc+1, info, a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||||
if not success then validated = false end
|
if not success then validated = false end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local rootframe = user.rootframe
|
local rootframe = user.rootframe
|
||||||
if not validated or type(validated) == "string" then
|
if type(validated) == "string" then
|
||||||
if not validated then
|
--validate function returned a message to display
|
||||||
if usage then
|
|
||||||
validated = name..": "..usage
|
|
||||||
else
|
|
||||||
if pattern then
|
|
||||||
validated = name..": Expected "..pattern
|
|
||||||
else
|
|
||||||
validated = name..": Invalid Value"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- show validate message
|
|
||||||
if rootframe.SetStatusText then
|
if rootframe.SetStatusText then
|
||||||
rootframe:SetStatusText(validated)
|
rootframe:SetStatusText(validated)
|
||||||
else
|
else
|
||||||
validationErrorPopup(validated)
|
-- TODO: do something else.
|
||||||
|
end
|
||||||
|
PlaySound("igPlayerInviteDecline")
|
||||||
|
del(info)
|
||||||
|
return true
|
||||||
|
elseif not validated then
|
||||||
|
--validate returned false
|
||||||
|
if rootframe.SetStatusText then
|
||||||
|
if usage then
|
||||||
|
rootframe:SetStatusText(name..": "..usage)
|
||||||
|
else
|
||||||
|
if pattern then
|
||||||
|
rootframe:SetStatusText(name..": Expected "..pattern)
|
||||||
|
else
|
||||||
|
rootframe:SetStatusText(name..": Invalid Value")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- TODO: do something else
|
||||||
end
|
end
|
||||||
PlaySound("igPlayerInviteDecline")
|
PlaySound("igPlayerInviteDecline")
|
||||||
del(info)
|
del(info)
|
||||||
return true
|
return true
|
||||||
else
|
else
|
||||||
|
|
||||||
local confirmText = option.confirmText
|
local confirmText = option.confirmText
|
||||||
--call confirm func/method
|
--call confirm func/method
|
||||||
if type(confirm) == "string" then
|
if type(confirm) == "string" then
|
||||||
if handler and handler[confirm] then
|
if handler and handler[confirm] then
|
||||||
success, confirm = safecall(handler[confirm], handler, info, unpack(arg))
|
success, confirm = safecall(handler[confirm], argc+2, handler, info, a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||||
if success and type(confirm) == "string" then
|
if success and type(confirm) == "string" then
|
||||||
confirmText = confirm
|
confirmText = confirm
|
||||||
confirm = true
|
confirm = true
|
||||||
@@ -761,7 +733,7 @@ local function ActivateControl(widget, event, ...)
|
|||||||
error(format("Method %s doesn't exist in handler for type confirm", confirm))
|
error(format("Method %s doesn't exist in handler for type confirm", confirm))
|
||||||
end
|
end
|
||||||
elseif type(confirm) == "function" then
|
elseif type(confirm) == "function" then
|
||||||
success, confirm = safecall(confirm, info, unpack(arg))
|
success, confirm = safecall(confirm, argc+1, info, a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||||
if success and type(confirm) == "string" then
|
if success and type(confirm) == "string" then
|
||||||
confirmText = confirm
|
confirmText = confirm
|
||||||
confirm = true
|
confirm = true
|
||||||
@@ -796,12 +768,12 @@ local function ActivateControl(widget, event, ...)
|
|||||||
local basepath = user.rootframe:GetUserData("basepath")
|
local basepath = user.rootframe:GetUserData("basepath")
|
||||||
if type(func) == "string" then
|
if type(func) == "string" then
|
||||||
if handler and handler[func] then
|
if handler and handler[func] then
|
||||||
confirmPopup(user.appName, rootframe, basepath, info, confirmText, handler[func], handler, info, unpack(arg))
|
confirmPopup(user.appName, rootframe, basepath, info, confirmText, handler[func], argc+2, handler, info, a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||||
else
|
else
|
||||||
error(format("Method %s doesn't exist in handler for type func", func))
|
error(format("Method %s doesn't exist in handler for type func", func))
|
||||||
end
|
end
|
||||||
elseif type(func) == "function" then
|
elseif type(func) == "function" then
|
||||||
confirmPopup(user.appName, rootframe, basepath, info, confirmText, func, info, unpack(arg))
|
confirmPopup(user.appName, rootframe, basepath, info, confirmText, func, argc+1, info,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||||
end
|
end
|
||||||
--func will be called and info deleted when the confirm dialog is responded to
|
--func will be called and info deleted when the confirm dialog is responded to
|
||||||
return
|
return
|
||||||
@@ -811,16 +783,14 @@ local function ActivateControl(widget, event, ...)
|
|||||||
--call the function
|
--call the function
|
||||||
if type(func) == "string" then
|
if type(func) == "string" then
|
||||||
if handler and handler[func] then
|
if handler and handler[func] then
|
||||||
safecall(handler[func],handler, info, unpack(arg))
|
safecall(handler[func], argc+2, handler, info, a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||||
else
|
else
|
||||||
error(format("Method %s doesn't exist in handler for type func", func))
|
error(format("Method %s doesn't exist in handler for type func", func))
|
||||||
end
|
end
|
||||||
elseif type(func) == "function" then
|
elseif type(func) == "function" then
|
||||||
safecall(func,info, unpack(arg))
|
safecall(func, argc+1, info, a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
local iscustom = user.rootframe:GetUserData("iscustom")
|
local iscustom = user.rootframe:GetUserData("iscustom")
|
||||||
local basepath = user.rootframe:GetUserData("basepath") or emptyTbl
|
local basepath = user.rootframe:GetUserData("basepath") or emptyTbl
|
||||||
--full refresh of the frame, some controls dont cause this on all events
|
--full refresh of the frame, some controls dont cause this on all events
|
||||||
@@ -856,7 +826,7 @@ local function ActivateControl(widget, event, ...)
|
|||||||
del(info)
|
del(info)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function ActivateSlider(widget, event, value)
|
local function ActivateSlider(widget, event, _, value)
|
||||||
local option = widget:GetUserData("option")
|
local option = widget:GetUserData("option")
|
||||||
local min, max, step = option.min or (not option.softMin and 0 or nil), option.max or (not option.softMax and 100 or nil), option.step
|
local min, max, step = option.min or (not option.softMin and 0 or nil), option.max or (not option.softMax and 100 or nil), option.step
|
||||||
if min then
|
if min then
|
||||||
@@ -868,13 +838,13 @@ local function ActivateSlider(widget, event, value)
|
|||||||
if max then
|
if max then
|
||||||
value = math_min(value, max)
|
value = math_min(value, max)
|
||||||
end
|
end
|
||||||
ActivateControl(widget,event,value)
|
ActivateControl(widget,event,1,value)
|
||||||
end
|
end
|
||||||
|
|
||||||
--called from a checkbox that is part of an internally created multiselect group
|
--called from a checkbox that is part of an internally created multiselect group
|
||||||
--this type is safe to refresh on activation of one control
|
--this type is safe to refresh on activation of one control
|
||||||
local function ActivateMultiControl(widget, event, ...)
|
local function ActivateMultiControl(widget, event, argc, a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||||
ActivateControl(widget, event, widget:GetUserData("value"), unpack(arg))
|
ActivateControl(widget, event, argc+1, widget:GetUserData("value"), a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||||
local user = widget:GetUserDataTable()
|
local user = widget:GetUserDataTable()
|
||||||
local iscustom = user.rootframe:GetUserData("iscustom")
|
local iscustom = user.rootframe:GetUserData("iscustom")
|
||||||
local basepath = user.rootframe:GetUserData("basepath") or emptyTbl
|
local basepath = user.rootframe:GetUserData("basepath") or emptyTbl
|
||||||
@@ -885,7 +855,7 @@ local function ActivateMultiControl(widget, event, ...)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function MultiControlOnClosed(widget, event, ...)
|
local function MultiControlOnClosed(widget, event)
|
||||||
local user = widget:GetUserDataTable()
|
local user = widget:GetUserDataTable()
|
||||||
if user.valuechanged then
|
if user.valuechanged then
|
||||||
local iscustom = user.rootframe:GetUserData("iscustom")
|
local iscustom = user.rootframe:GetUserData("iscustom")
|
||||||
@@ -906,7 +876,7 @@ end
|
|||||||
|
|
||||||
local function CheckOptionHidden(option, options, path, appName)
|
local function CheckOptionHidden(option, options, path, appName)
|
||||||
--check for a specific boolean option
|
--check for a specific boolean option
|
||||||
local hidden = pickfirstset(option.dialogHidden,option.guiHidden)
|
local hidden = pickfirstset(2,option.dialogHidden,option.guiHidden)
|
||||||
if hidden ~= nil then
|
if hidden ~= nil then
|
||||||
return hidden
|
return hidden
|
||||||
end
|
end
|
||||||
@@ -916,7 +886,7 @@ end
|
|||||||
|
|
||||||
local function CheckOptionDisabled(option, options, path, appName)
|
local function CheckOptionDisabled(option, options, path, appName)
|
||||||
--check for a specific boolean option
|
--check for a specific boolean option
|
||||||
local disabled = pickfirstset(option.dialogDisabled,option.guiDisabled)
|
local disabled = pickfirstset(2,option.dialogDisabled,option.guiDisabled)
|
||||||
if disabled ~= nil then
|
if disabled ~= nil then
|
||||||
return disabled
|
return disabled
|
||||||
end
|
end
|
||||||
@@ -932,18 +902,18 @@ local function BuildTabs(group, options, path, appName)
|
|||||||
|
|
||||||
BuildSortedOptionsTable(group, keySort, opts, options, path, appName)
|
BuildSortedOptionsTable(group, keySort, opts, options, path, appName)
|
||||||
|
|
||||||
for i = 1, tgetn(keySort) do
|
for i = 1, #keySort do
|
||||||
local k = keySort[i]
|
local k = keySort[i]
|
||||||
local v = opts[k]
|
local v = opts[k]
|
||||||
if v.type == "group" then
|
if v.type == "group" then
|
||||||
path[tgetn(path)+1] = k
|
path[#path+1] = k
|
||||||
local inline = pickfirstset(v.dialogInline,v.guiInline,v.inline, false)
|
local inline = pickfirstset(4,v.dialogInline,v.guiInline,v.inline, false)
|
||||||
local hidden = CheckOptionHidden(v, options, path, appName)
|
local hidden = CheckOptionHidden(v, options, path, appName)
|
||||||
if not inline and not hidden then
|
if not inline and not hidden then
|
||||||
tinsert(tabs, k)
|
tinsert(tabs, k)
|
||||||
text[k] = GetOptionsMemberValue("name", v, options, path, appName)
|
text[k] = GetOptionsMemberValue("name", v, options, path, appName)
|
||||||
end
|
end
|
||||||
path[tgetn(path)] = nil
|
path[#path] = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -965,14 +935,14 @@ local function BuildSelect(group, options, path, appName)
|
|||||||
local k = keySort[i]
|
local k = keySort[i]
|
||||||
local v = opts[k]
|
local v = opts[k]
|
||||||
if v.type == "group" then
|
if v.type == "group" then
|
||||||
path[tgetn(path)+1] = k
|
tinsert(path,k)
|
||||||
local inline = pickfirstset(v.dialogInline,v.guiInline,v.inline, false)
|
local inline = pickfirstset(4,v.dialogInline,v.guiInline,v.inline, false)
|
||||||
local hidden = CheckOptionHidden(v, options, path, appName)
|
local hidden = CheckOptionHidden(v, options, path, appName)
|
||||||
if not inline and not hidden then
|
if not inline and not hidden then
|
||||||
groups[k] = GetOptionsMemberValue("name", v, options, path, appName)
|
groups[k] = GetOptionsMemberValue("name", v, options, path, appName)
|
||||||
tinsert(order, k)
|
tinsert(order, k)
|
||||||
end
|
end
|
||||||
path[tgetn(path)] = nil
|
tremove(path)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -992,8 +962,8 @@ local function BuildSubGroups(group, tree, options, path, appName)
|
|||||||
local k = keySort[i]
|
local k = keySort[i]
|
||||||
local v = opts[k]
|
local v = opts[k]
|
||||||
if v.type == "group" then
|
if v.type == "group" then
|
||||||
path[tgetn(path)+1] = k
|
tinsert(path,k)
|
||||||
local inline = pickfirstset(v.dialogInline,v.guiInline,v.inline, false)
|
local inline = pickfirstset(4,v.dialogInline,v.guiInline,v.inline, false)
|
||||||
local hidden = CheckOptionHidden(v, options, path, appName)
|
local hidden = CheckOptionHidden(v, options, path, appName)
|
||||||
if not inline and not hidden then
|
if not inline and not hidden then
|
||||||
local entry = new()
|
local entry = new()
|
||||||
@@ -1008,7 +978,7 @@ local function BuildSubGroups(group, tree, options, path, appName)
|
|||||||
BuildSubGroups(v,entry, options, path, appName)
|
BuildSubGroups(v,entry, options, path, appName)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
path[tgetn(path)] = nil
|
tremove(path)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1027,8 +997,8 @@ local function BuildGroups(group, options, path, appName, recurse)
|
|||||||
local k = keySort[i]
|
local k = keySort[i]
|
||||||
local v = opts[k]
|
local v = opts[k]
|
||||||
if v.type == "group" then
|
if v.type == "group" then
|
||||||
path[tgetn(path)+1] = k
|
tinsert(path,k)
|
||||||
local inline = pickfirstset(v.dialogInline,v.guiInline,v.inline, false)
|
local inline = pickfirstset(4,v.dialogInline,v.guiInline,v.inline, false)
|
||||||
local hidden = CheckOptionHidden(v, options, path, appName)
|
local hidden = CheckOptionHidden(v, options, path, appName)
|
||||||
if not inline and not hidden then
|
if not inline and not hidden then
|
||||||
local entry = new()
|
local entry = new()
|
||||||
@@ -1041,7 +1011,7 @@ local function BuildGroups(group, options, path, appName, recurse)
|
|||||||
BuildSubGroups(v,entry, options, path, appName)
|
BuildSubGroups(v,entry, options, path, appName)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
path[tgetn(path)] = nil
|
tremove(path)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
del(keySort)
|
del(keySort)
|
||||||
@@ -1051,9 +1021,12 @@ end
|
|||||||
|
|
||||||
local function InjectInfo(control, options, option, path, rootframe, appName)
|
local function InjectInfo(control, options, option, path, rootframe, appName)
|
||||||
local user = control:GetUserDataTable()
|
local user = control:GetUserDataTable()
|
||||||
for i = 1, tgetn(path) do
|
local l = tgetn(path)
|
||||||
|
for i = 1, l do
|
||||||
user[i] = path[i]
|
user[i] = path[i]
|
||||||
end
|
end
|
||||||
|
tsetn(user,l)
|
||||||
|
|
||||||
user.rootframe = rootframe
|
user.rootframe = rootframe
|
||||||
user.option = option
|
user.option = option
|
||||||
user.options = options
|
user.options = options
|
||||||
@@ -1086,7 +1059,7 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
|
|||||||
local name = GetOptionsMemberValue("name", v, options, path, appName)
|
local name = GetOptionsMemberValue("name", v, options, path, appName)
|
||||||
if not hidden then
|
if not hidden then
|
||||||
if v.type == "group" then
|
if v.type == "group" then
|
||||||
if inline or pickfirstset(v.dialogInline,v.guiInline,v.inline, false) then
|
if inline or pickfirstset(4, v.dialogInline,v.guiInline,v.inline, false) then
|
||||||
--Inline group
|
--Inline group
|
||||||
local GroupContainer
|
local GroupContainer
|
||||||
if name and name ~= "" then
|
if name and name ~= "" then
|
||||||
@@ -1134,8 +1107,7 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
|
|||||||
control:SetImageSize(width, height)
|
control:SetImageSize(width, height)
|
||||||
control:SetLabel(name)
|
control:SetLabel(name)
|
||||||
else
|
else
|
||||||
local buttonElvUI = GetOptionsMemberValue("buttonElvUI",v, options, path, appName)
|
control = gui:Create("Button")
|
||||||
control = gui:Create(buttonElvUI and "Button-ElvUI" or "Button")
|
|
||||||
control:SetText(name)
|
control:SetText(name)
|
||||||
end
|
end
|
||||||
control:SetCallback("OnClick",ActivateControl)
|
control:SetCallback("OnClick",ActivateControl)
|
||||||
@@ -1161,12 +1133,7 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
|
|||||||
|
|
||||||
elseif v.type == "toggle" then
|
elseif v.type == "toggle" then
|
||||||
control = gui:Create("CheckBox")
|
control = gui:Create("CheckBox")
|
||||||
control.textWidth = GetOptionsMemberValue("textWidth",v,options,path,appName)
|
|
||||||
control:SetLabel(name)
|
control:SetLabel(name)
|
||||||
if control.textWidth and control.frame and control.text then
|
|
||||||
local textWidth = control.text:GetWidth()+30
|
|
||||||
control.customWidth = (textWidth>=width_multiplier and textWidth<=width_multiplier*1.5) and textWidth
|
|
||||||
end
|
|
||||||
control:SetTriState(v.tristate)
|
control:SetTriState(v.tristate)
|
||||||
local value = GetOptionsMemberValue("get",v, options, path, appName)
|
local value = GetOptionsMemberValue("get",v, options, path, appName)
|
||||||
control:SetValue(value)
|
control:SetValue(value)
|
||||||
@@ -1214,7 +1181,7 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
|
|||||||
local optionValue = GetOptionsMemberValue("get",v, options, path, appName)
|
local optionValue = GetOptionsMemberValue("get",v, options, path, appName)
|
||||||
local t = {}
|
local t = {}
|
||||||
for value, text in pairs(values) do
|
for value, text in pairs(values) do
|
||||||
t[tgetn(t)+1]=value
|
tinsert(t,value)
|
||||||
end
|
end
|
||||||
tsort(t)
|
tsort(t)
|
||||||
for k, value in ipairs(t) do
|
for k, value in ipairs(t) do
|
||||||
@@ -1247,6 +1214,7 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
|
|||||||
if not control then
|
if not control then
|
||||||
geterrorhandler()(format("Invalid Custom Control Type - %s", tostring(controlType)))
|
geterrorhandler()(format("Invalid Custom Control Type - %s", tostring(controlType)))
|
||||||
control = gui:Create("Dropdown")
|
control = gui:Create("Dropdown")
|
||||||
|
|
||||||
end
|
end
|
||||||
local itemType = v.itemControl
|
local itemType = v.itemControl
|
||||||
if itemType and not gui:GetWidgetVersion(itemType) then
|
if itemType and not gui:GetWidgetVersion(itemType) then
|
||||||
@@ -1265,6 +1233,7 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
|
|||||||
|
|
||||||
elseif v.type == "multiselect" then
|
elseif v.type == "multiselect" then
|
||||||
local values = GetOptionsMemberValue("values", v, options, path, appName)
|
local values = GetOptionsMemberValue("values", v, options, path, appName)
|
||||||
|
|
||||||
local disabled = CheckOptionDisabled(v, options, path, appName)
|
local disabled = CheckOptionDisabled(v, options, path, appName)
|
||||||
|
|
||||||
local controlType = v.dialogControl or v.control
|
local controlType = v.dialogControl or v.control
|
||||||
@@ -1303,57 +1272,27 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
|
|||||||
--check:SetTriState(v.tristate)
|
--check:SetTriState(v.tristate)
|
||||||
for i = 1, tgetn(valuesort) do
|
for i = 1, tgetn(valuesort) do
|
||||||
local key = valuesort[i]
|
local key = valuesort[i]
|
||||||
local value = GetOptionsMemberValue("get",v, options, path, appName, key)
|
local value = GetOptionsMemberValue("get", v, options, path, appName, 1, key)
|
||||||
control:SetItemValue(key,value)
|
control:SetItemValue(key,value)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
local width = GetOptionsMemberValue("width",v,options,path,appName)
|
|
||||||
local dragdrop = GetOptionsMemberValue("dragdrop",v,options,path,appName)
|
|
||||||
|
|
||||||
control = gui:Create("InlineGroup")
|
control = gui:Create("InlineGroup")
|
||||||
control:SetLayout("Flow")
|
control:SetLayout("Flow")
|
||||||
control:SetTitle(name)
|
control:SetTitle(name)
|
||||||
control.width = "fill"
|
control.width = "fill"
|
||||||
control:PauseLayout()
|
|
||||||
|
|
||||||
|
control:PauseLayout()
|
||||||
|
local width = GetOptionsMemberValue("width",v,options,path,appName)
|
||||||
for i = 1, tgetn(valuesort) do
|
for i = 1, tgetn(valuesort) do
|
||||||
local value = valuesort[i]
|
local value = valuesort[i]
|
||||||
local text = values[value]
|
local text = values[value]
|
||||||
if dragdrop then
|
|
||||||
local button = gui:Create("Button-ElvUI")
|
|
||||||
button:SetDisabled(disabled)
|
|
||||||
button:SetUserData("value", value)
|
|
||||||
button:SetUserData("text", text)
|
|
||||||
local state = v.stateSwitchGetText and v.stateSwitchGetText(button, text, value)
|
|
||||||
button:SetText(format("|cFF888888%d|r %s", i, state or text))
|
|
||||||
button.stateSwitchOnClick = v.stateSwitchOnClick
|
|
||||||
button.dragOnMouseDown = v.dragOnMouseDown
|
|
||||||
button.dragOnMouseUp = v.dragOnMouseUp
|
|
||||||
button.dragOnEnter = v.dragOnEnter
|
|
||||||
button.dragOnLeave = v.dragOnLeave
|
|
||||||
button.dragOnClick = v.dragOnClick
|
|
||||||
button.dragdrop = true
|
|
||||||
button.ActivateMultiControl = ActivateMultiControl
|
|
||||||
button.value = GetOptionsMemberValue("get",v, options, path, appName, value)
|
|
||||||
InjectInfo(button, options, v, path, rootframe, appName)
|
|
||||||
control:AddChild(button)
|
|
||||||
if width == "double" then
|
|
||||||
button:SetWidth(width_multiplier * 2)
|
|
||||||
elseif width == "half" then
|
|
||||||
button:SetWidth(width_multiplier / 2)
|
|
||||||
elseif width == "full" then
|
|
||||||
button.width = "fill"
|
|
||||||
else
|
|
||||||
button:SetWidth(width_multiplier)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
local check = gui:Create("CheckBox")
|
local check = gui:Create("CheckBox")
|
||||||
check:SetLabel(text)
|
check:SetLabel(text)
|
||||||
check:SetUserData("value", value)
|
check:SetUserData("value", value)
|
||||||
check:SetUserData("text", text)
|
check:SetUserData("text", text)
|
||||||
check:SetDisabled(disabled)
|
check:SetDisabled(disabled)
|
||||||
check:SetTriState(v.tristate)
|
check:SetTriState(v.tristate)
|
||||||
check:SetValue(GetOptionsMemberValue("get",v, options, path, appName, value))
|
check:SetValue(GetOptionsMemberValue("get",v, options, path, appName, 1, value))
|
||||||
check:SetCallback("OnValueChanged",ActivateMultiControl)
|
check:SetCallback("OnValueChanged",ActivateMultiControl)
|
||||||
InjectInfo(check, options, v, path, rootframe, appName)
|
InjectInfo(check, options, v, path, rootframe, appName)
|
||||||
control:AddChild(check)
|
control:AddChild(check)
|
||||||
@@ -1367,7 +1306,6 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
|
|||||||
check:SetWidth(width_multiplier)
|
check:SetWidth(width_multiplier)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
control:ResumeLayout()
|
control:ResumeLayout()
|
||||||
control:DoLayout()
|
control:DoLayout()
|
||||||
|
|
||||||
@@ -1377,7 +1315,7 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
|
|||||||
del(valuesort)
|
del(valuesort)
|
||||||
|
|
||||||
elseif v.type == "color" then
|
elseif v.type == "color" then
|
||||||
control = gui:Create("ColorPicker-ElvUI")
|
control = gui:Create("ColorPicker")
|
||||||
control:SetLabel(name)
|
control:SetLabel(name)
|
||||||
control:SetHasAlpha(GetOptionsMemberValue("hasAlpha",v, options, path, appName))
|
control:SetHasAlpha(GetOptionsMemberValue("hasAlpha",v, options, path, appName))
|
||||||
control:SetColor(GetOptionsMemberValue("get",v, options, path, appName))
|
control:SetColor(GetOptionsMemberValue("get",v, options, path, appName))
|
||||||
@@ -1437,11 +1375,7 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
|
|||||||
|
|
||||||
--Common Init
|
--Common Init
|
||||||
if control then
|
if control then
|
||||||
local customWidth = control.customWidth or GetOptionsMemberValue("customWidth",v,options,path,appName)
|
if control.width ~= "fill" then
|
||||||
if control.width ~= "fill" or customWidth then
|
|
||||||
if customWidth then
|
|
||||||
control:SetWidth(customWidth)
|
|
||||||
else
|
|
||||||
local width = GetOptionsMemberValue("width",v,options,path,appName)
|
local width = GetOptionsMemberValue("width",v,options,path,appName)
|
||||||
if width == "double" then
|
if width == "double" then
|
||||||
control:SetWidth(width_multiplier * 2)
|
control:SetWidth(width_multiplier * 2)
|
||||||
@@ -1453,7 +1387,6 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
|
|||||||
control:SetWidth(width_multiplier)
|
control:SetWidth(width_multiplier)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
if control.SetDisabled then
|
if control.SetDisabled then
|
||||||
local disabled = CheckOptionDisabled(v, options, path, appName)
|
local disabled = CheckOptionDisabled(v, options, path, appName)
|
||||||
control:SetDisabled(disabled)
|
control:SetDisabled(disabled)
|
||||||
@@ -1473,14 +1406,15 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
|
|||||||
del(opts)
|
del(opts)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function BuildPath(path, ...)
|
-- Ace3v: recursive
|
||||||
for i = 1, tgetn(arg) do
|
local function BuildPath(path, a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||||
tinsert(path, arg[i])
|
if a1 then
|
||||||
|
tinsert(path,a1)
|
||||||
|
BuildPath(path,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function TreeOnButtonEnter(widget, event, _, uniquevalue, button)
|
||||||
local function TreeOnButtonEnter(widget, event, uniquevalue, button)
|
|
||||||
local user = widget:GetUserDataTable()
|
local user = widget:GetUserDataTable()
|
||||||
if not user then return end
|
if not user then return end
|
||||||
local options = user.options
|
local options = user.options
|
||||||
@@ -1489,9 +1423,11 @@ local function TreeOnButtonEnter(widget, event, uniquevalue, button)
|
|||||||
local appName = user.appName
|
local appName = user.appName
|
||||||
|
|
||||||
local feedpath = new()
|
local feedpath = new()
|
||||||
for i = 1, tgetn(path) do
|
local l = tgetn(path)
|
||||||
|
for i = 1, l do
|
||||||
feedpath[i] = path[i]
|
feedpath[i] = path[i]
|
||||||
end
|
end
|
||||||
|
tsetn(feedpath,l)
|
||||||
|
|
||||||
BuildPath(feedpath, strsplit("\001", uniquevalue))
|
BuildPath(feedpath, strsplit("\001", uniquevalue))
|
||||||
local group = options
|
local group = options
|
||||||
@@ -1503,35 +1439,37 @@ local function TreeOnButtonEnter(widget, event, uniquevalue, button)
|
|||||||
local name = GetOptionsMemberValue("name", group, options, feedpath, appName)
|
local name = GetOptionsMemberValue("name", group, options, feedpath, appName)
|
||||||
local desc = GetOptionsMemberValue("desc", group, options, feedpath, appName)
|
local desc = GetOptionsMemberValue("desc", group, options, feedpath, appName)
|
||||||
|
|
||||||
GameTooltip:SetOwner(button, "ANCHOR_CURSOR")
|
GameTooltip:SetOwner(button, "ANCHOR_NONE")
|
||||||
if widget.type == "TabGroup" then
|
if widget.type == "TabGroup" then
|
||||||
GameTooltip:SetPoint("BOTTOM",button,"TOP")
|
GameTooltip:SetPoint("BOTTOM",button,"TOP")
|
||||||
else
|
else
|
||||||
GameTooltip:SetPoint("LEFT",button,"RIGHT")
|
GameTooltip:SetPoint("LEFT",button,"RIGHT")
|
||||||
end
|
end
|
||||||
|
|
||||||
GameTooltip:SetText(name, 1, .82, 0, 1)
|
GameTooltip:SetText(name, 1, .82, 0, true)
|
||||||
|
|
||||||
if type(desc) == "string" then
|
if type(desc) == "string" then
|
||||||
GameTooltip:AddLine(desc, 1, 1, 1, 1)
|
GameTooltip:AddLine(desc, 1, 1, 1, true)
|
||||||
end
|
end
|
||||||
|
|
||||||
GameTooltip:Show()
|
GameTooltip:Show()
|
||||||
end
|
end
|
||||||
|
|
||||||
local function TreeOnButtonLeave(widget, event, value, button)
|
local function TreeOnButtonLeave(widget, event, _, value, button)
|
||||||
GameTooltip:Hide()
|
GameTooltip:Hide()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
local function GroupExists(appName, options, path, uniquevalue)
|
local function GroupExists(appName, options, path, uniquevalue)
|
||||||
if not uniquevalue then return false end
|
|
||||||
|
|
||||||
|
if not uniquevalue then return false end
|
||||||
local feedpath = new()
|
local feedpath = new()
|
||||||
local temppath = new()
|
local temppath = new()
|
||||||
for i = 1, tgetn(path) do
|
local l = tgetn(path)
|
||||||
|
for i = 1, l do
|
||||||
feedpath[i] = path[i]
|
feedpath[i] = path[i]
|
||||||
end
|
end
|
||||||
|
tsetn(feedpath,l)
|
||||||
|
|
||||||
BuildPath(feedpath, strsplit("\001", uniquevalue))
|
BuildPath(feedpath, strsplit("\001", uniquevalue))
|
||||||
|
|
||||||
@@ -1552,7 +1490,8 @@ local function GroupExists(appName, options, path, uniquevalue)
|
|||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
local function GroupSelected(widget, event, uniquevalue)
|
local function GroupSelected(widget, event, _, uniquevalue)
|
||||||
|
if not uniquevalue then widget:ReleaseChildren() return end
|
||||||
|
|
||||||
local user = widget:GetUserDataTable()
|
local user = widget:GetUserDataTable()
|
||||||
|
|
||||||
@@ -1562,9 +1501,11 @@ local function GroupSelected(widget, event, uniquevalue)
|
|||||||
local rootframe = user.rootframe
|
local rootframe = user.rootframe
|
||||||
|
|
||||||
local feedpath = new()
|
local feedpath = new()
|
||||||
for i = 1, tgetn(path) do
|
local l = tgetn(path)
|
||||||
|
for i = 1, l do
|
||||||
feedpath[i] = path[i]
|
feedpath[i] = path[i]
|
||||||
end
|
end
|
||||||
|
tsetn(feedpath,l)
|
||||||
|
|
||||||
BuildPath(feedpath, strsplit("\001", uniquevalue))
|
BuildPath(feedpath, strsplit("\001", uniquevalue))
|
||||||
local group = options
|
local group = options
|
||||||
@@ -1572,6 +1513,7 @@ local function GroupSelected(widget, event, uniquevalue)
|
|||||||
group = GetSubOption(group, feedpath[i])
|
group = GetSubOption(group, feedpath[i])
|
||||||
end
|
end
|
||||||
widget:ReleaseChildren()
|
widget:ReleaseChildren()
|
||||||
|
|
||||||
AceConfigDialog:FeedGroup(user.appName,options,widget,rootframe,feedpath)
|
AceConfigDialog:FeedGroup(user.appName,options,widget,rootframe,feedpath)
|
||||||
|
|
||||||
del(feedpath)
|
del(feedpath)
|
||||||
@@ -1596,16 +1538,16 @@ Rules:
|
|||||||
--]]
|
--]]
|
||||||
|
|
||||||
function AceConfigDialog:FeedGroup(appName,options,container,rootframe,path, isRoot)
|
function AceConfigDialog:FeedGroup(appName,options,container,rootframe,path, isRoot)
|
||||||
|
|
||||||
local group = options
|
local group = options
|
||||||
--follow the path to get to the curent group
|
--follow the path to get to the curent group
|
||||||
local inline
|
local inline
|
||||||
local grouptype, parenttype = options.childGroups, "none"
|
local grouptype, parenttype = options.childGroups, "none"
|
||||||
|
|
||||||
|
|
||||||
for i = 1, tgetn(path) do
|
for i = 1, tgetn(path) do
|
||||||
local v = path[i]
|
local v = path[i]
|
||||||
group = GetSubOption(group, v)
|
group = GetSubOption(group, v)
|
||||||
inline = inline or pickfirstset(v.dialogInline,v.guiInline,v.inline, false)
|
inline = inline or pickfirstset(4,group.dialogInline,group.guiInline,group.inline, false)
|
||||||
parenttype = grouptype
|
parenttype = grouptype
|
||||||
grouptype = group.childGroups
|
grouptype = group.childGroups
|
||||||
end
|
end
|
||||||
@@ -1617,14 +1559,14 @@ function AceConfigDialog:FeedGroup(appName,options,container,rootframe,path, isR
|
|||||||
--check if the group has child groups
|
--check if the group has child groups
|
||||||
local hasChildGroups
|
local hasChildGroups
|
||||||
for k, v in pairs(group.args) do
|
for k, v in pairs(group.args) do
|
||||||
if v.type == "group" and not pickfirstset(v.dialogInline,v.guiInline,v.inline, false) and not CheckOptionHidden(v, options, path, appName) then
|
if v.type == "group" and not pickfirstset(4,v.dialogInline,v.guiInline,v.inline, false) and not CheckOptionHidden(v, options, path, appName) then
|
||||||
hasChildGroups = true
|
hasChildGroups = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if group.plugins then
|
if group.plugins then
|
||||||
for plugin, t in pairs(group.plugins) do
|
for plugin, t in pairs(group.plugins) do
|
||||||
for k, v in pairs(t) do
|
for k, v in pairs(t) do
|
||||||
if v.type == "group" and not pickfirstset(v.dialogInline,v.guiInline,v.inline, false) and not CheckOptionHidden(v, options, path, appName) then
|
if v.type == "group" and not pickfirstset(4,v.dialogInline,v.guiInline,v.inline, false) and not CheckOptionHidden(v, options, path, appName) then
|
||||||
hasChildGroups = true
|
hasChildGroups = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -1756,7 +1698,7 @@ end
|
|||||||
local old_CloseSpecialWindows
|
local old_CloseSpecialWindows
|
||||||
|
|
||||||
|
|
||||||
local function RefreshOnUpdate()
|
local function RefreshOnUpdate(this)
|
||||||
for appName in pairs(this.closing) do
|
for appName in pairs(this.closing) do
|
||||||
if AceConfigDialog.OpenFrames[appName] then
|
if AceConfigDialog.OpenFrames[appName] then
|
||||||
AceConfigDialog.OpenFrames[appName]:Hide()
|
AceConfigDialog.OpenFrames[appName]:Hide()
|
||||||
@@ -1850,7 +1792,7 @@ end
|
|||||||
-- @param appName The application name as given to `:RegisterOptionsTable()`
|
-- @param appName The application name as given to `:RegisterOptionsTable()`
|
||||||
-- @param container An optional container frame to feed the options into
|
-- @param container An optional container frame to feed the options into
|
||||||
-- @param ... The path to open after creating the options window (see `:SelectGroup` for details)
|
-- @param ... The path to open after creating the options window (see `:SelectGroup` for details)
|
||||||
function AceConfigDialog:Open(appName, container, ...)
|
function AceConfigDialog:Open(appName, container, a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||||
if not old_CloseSpecialWindows then
|
if not old_CloseSpecialWindows then
|
||||||
old_CloseSpecialWindows = CloseSpecialWindows
|
old_CloseSpecialWindows = CloseSpecialWindows
|
||||||
CloseSpecialWindows = function()
|
CloseSpecialWindows = function()
|
||||||
@@ -1875,9 +1817,7 @@ function AceConfigDialog:Open(appName, container, ...)
|
|||||||
tinsert(path, container)
|
tinsert(path, container)
|
||||||
container = nil
|
container = nil
|
||||||
end
|
end
|
||||||
for n = 1, tgetn(arg) do
|
BuildPath(path, a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||||
tinsert(path, arg[i])
|
|
||||||
end
|
|
||||||
|
|
||||||
local option = options
|
local option = options
|
||||||
if type(container) == "table" and container.type == "BlizOptionsGroup" and tgetn(path) > 0 then
|
if type(container) == "table" and container.type == "BlizOptionsGroup" and tgetn(path) > 0 then
|
||||||
@@ -1886,6 +1826,7 @@ function AceConfigDialog:Open(appName, container, ...)
|
|||||||
end
|
end
|
||||||
name = format("%s - %s", name, GetOptionsMemberValue("name", option, options, path, appName))
|
name = format("%s - %s", name, GetOptionsMemberValue("name", option, options, path, appName))
|
||||||
end
|
end
|
||||||
|
|
||||||
--if a container is given feed into that
|
--if a container is given feed into that
|
||||||
if container then
|
if container then
|
||||||
f = container
|
f = container
|
||||||
@@ -1984,7 +1925,8 @@ function AceConfigDialog:AddToBlizOptions(appName, name, parent, ...)
|
|||||||
local BlizOptions = AceConfigDialog.BlizOptions
|
local BlizOptions = AceConfigDialog.BlizOptions
|
||||||
|
|
||||||
local key = appName
|
local key = appName
|
||||||
for n = 1, tgetn(arg) do
|
local l = tgetn(arg)
|
||||||
|
for n = 1, l do
|
||||||
key = key .. "\001" .. arg[n]
|
key = key .. "\001" .. arg[n]
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1999,10 +1941,10 @@ function AceConfigDialog:AddToBlizOptions(appName, name, parent, ...)
|
|||||||
|
|
||||||
group:SetTitle(name or appName)
|
group:SetTitle(name or appName)
|
||||||
group:SetUserData("appName", appName)
|
group:SetUserData("appName", appName)
|
||||||
if tgetn(arg) > 0 then
|
if l > 0 then
|
||||||
local path = {}
|
local path = {}
|
||||||
for n = 1, tgetn(arg) do
|
for n = 1, l do
|
||||||
tinsert(path, arg[n])
|
tinsert(path, args[n])
|
||||||
end
|
end
|
||||||
group:SetUserData("path", path)
|
group:SetUserData("path", path)
|
||||||
end
|
end
|
||||||
|
|||||||
+37
-47
@@ -8,25 +8,24 @@
|
|||||||
-- :IterateOptionsTables() (and :GetOptionsTable() if only given one argument) return a function reference that the requesting config handling addon must call with valid "uiType", "uiName".
|
-- :IterateOptionsTables() (and :GetOptionsTable() if only given one argument) return a function reference that the requesting config handling addon must call with valid "uiType", "uiName".
|
||||||
-- @class file
|
-- @class file
|
||||||
-- @name AceConfigRegistry-3.0
|
-- @name AceConfigRegistry-3.0
|
||||||
-- @release $Id: AceConfigRegistry-3.0.lua 1105 2013-12-08 22:11:58Z nevcairiel $
|
-- @release $Id: AceConfigRegistry-3.0.lua 1139 2016-07-03 07:43:51Z nevcairiel $
|
||||||
local CallbackHandler = LibStub:GetLibrary("CallbackHandler-1.0")
|
local MAJOR, MINOR = "AceConfigRegistry-3.0", 16
|
||||||
|
|
||||||
local MAJOR, MINOR = "AceConfigRegistry-3.0-ElvUI", 2
|
|
||||||
local AceConfigRegistry = LibStub:NewLibrary(MAJOR, MINOR)
|
local AceConfigRegistry = LibStub:NewLibrary(MAJOR, MINOR)
|
||||||
|
|
||||||
if not AceConfigRegistry then return end
|
if not AceConfigRegistry then return end
|
||||||
|
|
||||||
AceConfigRegistry.tables = AceConfigRegistry.tables or {}
|
AceConfigRegistry.tables = AceConfigRegistry.tables or {}
|
||||||
|
|
||||||
|
local CallbackHandler = LibStub:GetLibrary("CallbackHandler-1.0")
|
||||||
|
|
||||||
if not AceConfigRegistry.callbacks then
|
if not AceConfigRegistry.callbacks then
|
||||||
AceConfigRegistry.callbacks = CallbackHandler:New(AceConfigRegistry)
|
AceConfigRegistry.callbacks = CallbackHandler:New(AceConfigRegistry)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Lua APIs
|
-- Lua APIs
|
||||||
local tinsert, tconcat = table.insert, table.concat
|
local tinsert, tconcat, tgetn = table.insert, table.concat, table.getn
|
||||||
local strfind, strmatch = string.find, string.match
|
local strfind = string.find
|
||||||
local tgetn = table.getn
|
local type, tostring, pairs = type, tostring, pairs
|
||||||
local type, tostring, select, pairs, unpack = type, tostring, select, pairs, unpack
|
|
||||||
local error, assert = error, assert
|
local error, assert = error, assert
|
||||||
|
|
||||||
-----------------------------------------------------------------------
|
-----------------------------------------------------------------------
|
||||||
@@ -41,17 +40,17 @@ AceConfigRegistry.validated = {
|
|||||||
dialog = {},
|
dialog = {},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
local function err(msg, errlvl, ...)
|
local function err(msg, errlvl, ...)
|
||||||
local t = {}
|
local l = tgetn(arg)
|
||||||
for i=tgetn(arg),1,-1 do
|
local i,j = 1,l
|
||||||
tinsert(t, (arg[i]))
|
while i < j do
|
||||||
|
arg[i], arg[j] = arg[j], arg[i]
|
||||||
|
i = i+1
|
||||||
|
j = j-1
|
||||||
end
|
end
|
||||||
error(MAJOR..":ValidateOptionsTable(): "..tconcat(t,".")..msg, errlvl+2)
|
error(MAJOR..":ValidateOptionsTable(): "..tconcat(arg,".")..msg, errlvl+2)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
local isstring={["string"]=true, _="string"}
|
local isstring={["string"]=true, _="string"}
|
||||||
local isstringfunc={["string"]=true,["function"]=true, _="string or funcref"}
|
local isstringfunc={["string"]=true,["function"]=true, _="string or funcref"}
|
||||||
local istable={["table"]=true, _="table"}
|
local istable={["table"]=true, _="table"}
|
||||||
@@ -92,17 +91,6 @@ local basekeys={
|
|||||||
func=optmethodfalse,
|
func=optmethodfalse,
|
||||||
arg={["*"]=true},
|
arg={["*"]=true},
|
||||||
width=optstring,
|
width=optstring,
|
||||||
customWidth=optnumber,
|
|
||||||
textWidth=optmethodbool,
|
|
||||||
buttonElvUI=optmethodbool,
|
|
||||||
dragdrop=optmethodbool,
|
|
||||||
dragOnEnter=optmethodfalse,
|
|
||||||
dragOnLeave=optmethodfalse,
|
|
||||||
dragOnClick=optmethodfalse,
|
|
||||||
dragOnMouseUp=optmethodfalse,
|
|
||||||
dragOnMouseDown=optmethodfalse,
|
|
||||||
stateSwitchOnClick=optmethodfalse,
|
|
||||||
stateSwitchGetText=optmethodfalse,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
local typedkeys={
|
local typedkeys={
|
||||||
@@ -137,6 +125,7 @@ local typedkeys={
|
|||||||
dialogControl=optstring,
|
dialogControl=optstring,
|
||||||
dropdownControl=optstring,
|
dropdownControl=optstring,
|
||||||
multiline=optboolnumber,
|
multiline=optboolnumber,
|
||||||
|
nullable=optbool,
|
||||||
},
|
},
|
||||||
toggle={
|
toggle={
|
||||||
tristate=optbool,
|
tristate=optbool,
|
||||||
@@ -156,6 +145,7 @@ local typedkeys={
|
|||||||
},
|
},
|
||||||
select={
|
select={
|
||||||
values=ismethodtable,
|
values=ismethodtable,
|
||||||
|
valuesTableDestroyable=optbool, -- Ace3v: if the values table is generated by AceCore.new
|
||||||
style={
|
style={
|
||||||
["nil"]=true,
|
["nil"]=true,
|
||||||
["string"]={dropdown=true,radio=true},
|
["string"]={dropdown=true,radio=true},
|
||||||
@@ -168,6 +158,7 @@ local typedkeys={
|
|||||||
},
|
},
|
||||||
multiselect={
|
multiselect={
|
||||||
values=ismethodtable,
|
values=ismethodtable,
|
||||||
|
valuesTableDestroyable=optbool, -- Ace3v: if the values table is generated by AceCore.new
|
||||||
style=optstring,
|
style=optstring,
|
||||||
tristate=optbool,
|
tristate=optbool,
|
||||||
control=optstring,
|
control=optstring,
|
||||||
@@ -176,82 +167,81 @@ local typedkeys={
|
|||||||
},
|
},
|
||||||
color={
|
color={
|
||||||
hasAlpha=optmethodbool,
|
hasAlpha=optmethodbool,
|
||||||
reset=opttable,
|
|
||||||
},
|
},
|
||||||
keybinding={
|
keybinding={
|
||||||
-- TODO
|
-- TODO
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
local function validateKey(k,errlvl,...)
|
local function validateKey(k,errlvl,arg)
|
||||||
errlvl=(errlvl or 0)+1
|
errlvl=(errlvl or 0)+1
|
||||||
if type(k)~="string" then
|
if type(k)~="string" then
|
||||||
err("["..tostring(k).."] - key is not a string", errlvl,unpack(arg))
|
err("["..tostring(k).."] - key is not a string", errlvl, arg)
|
||||||
end
|
end
|
||||||
if strfind(k, "[%c\127]") then
|
if strfind(k, "[%c\127]") then
|
||||||
err("["..tostring(k).."] - key name contained control characters", errlvl,unpack(arg))
|
err("["..tostring(k).."] - key name contained control characters", errlvl, arg)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function validateVal(v, oktypes, errlvl,...)
|
local function validateVal(v, oktypes, errlvl, arg)
|
||||||
errlvl=(errlvl or 0)+1
|
errlvl=(errlvl or 0)+1
|
||||||
local isok=oktypes[type(v)] or oktypes["*"]
|
local isok=oktypes[type(v)] or oktypes["*"]
|
||||||
|
|
||||||
if not isok then
|
if not isok then
|
||||||
err(": expected a "..oktypes._..", got '"..tostring(v).."'", errlvl,unpack(arg))
|
err(": expected a "..oktypes._..", got '"..tostring(v).."'", errlvl, arg)
|
||||||
end
|
end
|
||||||
if type(isok)=="table" then -- isok was a table containing specific values to be tested for!
|
if type(isok)=="table" then -- isok was a table containing specific values to be tested for!
|
||||||
if not isok[v] then
|
if not isok[v] then
|
||||||
err(": did not expect "..type(v).." value '"..tostring(v).."'", errlvl,unpack(arg))
|
err(": did not expect "..type(v).." value '"..tostring(v).."'", errlvl, arg)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function validate(options,errlvl,...)
|
local function validate(options,errlvl,arg)
|
||||||
errlvl=(errlvl or 0)+1
|
errlvl=(errlvl or 0)+1
|
||||||
-- basic consistency
|
-- basic consistency
|
||||||
if type(options)~="table" then
|
if type(options)~="table" then
|
||||||
err(": expected a table, got a "..type(options), errlvl,unpack(arg))
|
err(": expected a table, got a "..type(options), errlvl, arg)
|
||||||
end
|
end
|
||||||
if type(options.type)~="string" then
|
if type(options.type)~="string" then
|
||||||
err(".type: expected a string, got a "..type(options.type), errlvl,unpack(arg))
|
err(".type: expected a string, got a "..type(options.type), errlvl, arg)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- get type and 'typedkeys' member
|
-- get type and 'typedkeys' member
|
||||||
local tk = typedkeys[options.type]
|
local tk = typedkeys[options.type]
|
||||||
if not tk then
|
if not tk then
|
||||||
err(".type: unknown type '"..options.type.."'", errlvl,unpack(arg))
|
err(".type: unknown type '"..options.type.."'", errlvl, arg)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- make sure that all options[] are known parameters
|
-- make sure that all options[] are known parameters
|
||||||
for k,v in pairs(options) do
|
for k,v in pairs(options) do
|
||||||
if not (tk[k] or basekeys[k]) then
|
if not (tk[k] or basekeys[k]) then
|
||||||
err(": unknown parameter", errlvl,tostring(k),unpack(arg))
|
err(": unknown parameter", errlvl,tostring(k), arg)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- verify that required params are there, and that everything is the right type
|
-- verify that required params are there, and that everything is the right type
|
||||||
for k,oktypes in pairs(basekeys) do
|
for k,oktypes in pairs(basekeys) do
|
||||||
validateVal(options[k], oktypes, errlvl,k,unpack(arg))
|
validateVal(options[k], oktypes, errlvl, k, arg)
|
||||||
end
|
end
|
||||||
for k,oktypes in pairs(tk) do
|
for k,oktypes in pairs(tk) do
|
||||||
validateVal(options[k], oktypes, errlvl,k,unpack(arg))
|
validateVal(options[k], oktypes, errlvl, k, arg)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- extra logic for groups
|
-- extra logic for groups
|
||||||
if options.type=="group" then
|
if options.type=="group" then
|
||||||
for k,v in pairs(options.args) do
|
for k,v in pairs(options.args) do
|
||||||
validateKey(k,errlvl,"args",unpack(arg))
|
validateKey(k,errlvl,"args", arg)
|
||||||
validate(v, errlvl,k,"args",unpack(arg))
|
validate(v, errlvl,k,"args", arg)
|
||||||
end
|
end
|
||||||
if options.plugins then
|
if options.plugins then
|
||||||
for plugname,plugin in pairs(options.plugins) do
|
for plugname,plugin in pairs(options.plugins) do
|
||||||
if type(plugin)~="table" then
|
if type(plugin)~="table" then
|
||||||
err(": expected a table, got '"..tostring(plugin).."'", errlvl,tostring(plugname),"plugins",unpack(arg))
|
err(": expected a table, got '"..tostring(plugin).."'", errlvl,tostring(plugname), "plugins", arg)
|
||||||
end
|
end
|
||||||
for k,v in pairs(plugin) do
|
for k,v in pairs(plugin) do
|
||||||
validateKey(k,errlvl,tostring(plugname),"plugins",unpack(arg))
|
validateKey(k,errlvl,tostring(plugname),"plugins",arg)
|
||||||
validate(v, errlvl,k,tostring(plugname),"plugins",unpack(arg))
|
validate(v, errlvl,k,tostring(plugname),"plugins",arg)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -279,7 +269,7 @@ end
|
|||||||
-- @param appName The application name as given to `:RegisterOptionsTable()`
|
-- @param appName The application name as given to `:RegisterOptionsTable()`
|
||||||
function AceConfigRegistry:NotifyChange(appName)
|
function AceConfigRegistry:NotifyChange(appName)
|
||||||
if not AceConfigRegistry.tables[appName] then return end
|
if not AceConfigRegistry.tables[appName] then return end
|
||||||
AceConfigRegistry.callbacks:Fire("ConfigTableChange", appName)
|
AceConfigRegistry.callbacks:Fire("ConfigTableChange", 1, appName)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- -------------------------------------------------------------------
|
-- -------------------------------------------------------------------
|
||||||
@@ -293,7 +283,7 @@ local function validateGetterArgs(uiType, uiName, errlvl)
|
|||||||
if uiType~="cmd" and uiType~="dropdown" and uiType~="dialog" then
|
if uiType~="cmd" and uiType~="dropdown" and uiType~="dialog" then
|
||||||
error(MAJOR..": Requesting options table: 'uiType' - invalid configuration UI type, expected 'cmd', 'dropdown' or 'dialog'", errlvl)
|
error(MAJOR..": Requesting options table: 'uiType' - invalid configuration UI type, expected 'cmd', 'dropdown' or 'dialog'", errlvl)
|
||||||
end
|
end
|
||||||
if not strmatch(uiName, "[A-Za-z]%-[0-9]") then -- Expecting e.g. "MyLib-1.2"
|
if not strfind(uiName, "[A-Za-z]+-[0-9]") then -- Expecting e.g. "MyLib-1.2"
|
||||||
error(MAJOR..": Requesting options table: 'uiName' - badly formatted or missing version number. Expected e.g. 'MyLib-1.2'", errlvl)
|
error(MAJOR..": Requesting options table: 'uiName' - badly formatted or missing version number. Expected e.g. 'MyLib-1.2'", errlvl)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
--- AceDBOptions-3.0 provides a universal AceConfig options screen for managing AceDB-3.0 profiles.
|
--- AceDBOptions-3.0 provides a universal AceConfig options screen for managing AceDB-3.0 profiles.
|
||||||
-- @class file
|
-- @class file
|
||||||
-- @name AceDBOptions-3.0
|
-- @name AceDBOptions-3.0
|
||||||
-- @release $Id: AceDBOptions-3.0.lua 1066 2012-09-18 14:36:49Z nevcairiel $
|
-- @release $Id: AceDBOptions-3.0.lua 1140 2016-07-03 07:53:29Z nevcairiel $
|
||||||
local ACEDBO_MAJOR, ACEDBO_MINOR = "AceDBOptions-3.0", 15
|
local ACEDBO_MAJOR, ACEDBO_MINOR = "AceDBOptions-3.0", 15
|
||||||
local AceDBOptions, oldminor = LibStub:NewLibrary(ACEDBO_MAJOR, ACEDBO_MINOR)
|
local AceDBOptions, oldminor = LibStub:NewLibrary(ACEDBO_MAJOR, ACEDBO_MINOR)
|
||||||
|
|
||||||
if not AceDBOptions then return end -- No upgrade needed
|
if not AceDBOptions then return end -- No upgrade needed
|
||||||
|
|
||||||
|
local AceCore = LibStub("AceCore-3.0")
|
||||||
|
local new, del = AceCore.new, AceCore.del
|
||||||
|
|
||||||
-- Lua APIs
|
-- Lua APIs
|
||||||
local pairs, next = pairs, next
|
local pairs, next = pairs, next
|
||||||
|
|
||||||
@@ -230,7 +233,6 @@ elseif LOCALE == "ptBR" then
|
|||||||
end
|
end
|
||||||
|
|
||||||
local defaultProfiles
|
local defaultProfiles
|
||||||
local tmpprofiles = {}
|
|
||||||
|
|
||||||
-- Get a list of available profiles for the specified database.
|
-- Get a list of available profiles for the specified database.
|
||||||
-- You can specify which profiles to include/exclude in the list using the two boolean parameters listed below.
|
-- You can specify which profiles to include/exclude in the list using the two boolean parameters listed below.
|
||||||
@@ -239,8 +241,8 @@ local tmpprofiles = {}
|
|||||||
-- @param nocurrent If true, then getProfileList will not display the current profile in the list
|
-- @param nocurrent If true, then getProfileList will not display the current profile in the list
|
||||||
-- @return Hashtable of all profiles with the internal name as keys and the display name as value.
|
-- @return Hashtable of all profiles with the internal name as keys and the display name as value.
|
||||||
local function getProfileList(db, common, nocurrent)
|
local function getProfileList(db, common, nocurrent)
|
||||||
local profiles = {}
|
local profiles = new()
|
||||||
|
local tmpprofiles = new()
|
||||||
-- copy existing profiles into the table
|
-- copy existing profiles into the table
|
||||||
local currentProfile = db:GetCurrentProfile()
|
local currentProfile = db:GetCurrentProfile()
|
||||||
for i,v in pairs(db:GetProfiles(tmpprofiles)) do
|
for i,v in pairs(db:GetProfiles(tmpprofiles)) do
|
||||||
@@ -248,6 +250,7 @@ local function getProfileList(db, common, nocurrent)
|
|||||||
profiles[v] = v
|
profiles[v] = v
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
del(tmpprofiles)
|
||||||
|
|
||||||
-- add our default profiles to choose from ( or rename existing profiles)
|
-- add our default profiles to choose from ( or rename existing profiles)
|
||||||
for k,v in pairs(defaultProfiles) do
|
for k,v in pairs(defaultProfiles) do
|
||||||
@@ -290,6 +293,8 @@ end
|
|||||||
"common" - returns all avaialble profiles + some commonly used profiles ("char - realm", "realm", "class", "Default")
|
"common" - returns all avaialble profiles + some commonly used profiles ("char - realm", "realm", "class", "Default")
|
||||||
"both" - common except the active profile
|
"both" - common except the active profile
|
||||||
]]
|
]]
|
||||||
|
-- Ace3v: It is recommanded to destroy the returned table by AceCore.del
|
||||||
|
-- if it is no longer needed
|
||||||
function OptionsHandlerPrototype:ListProfiles(info)
|
function OptionsHandlerPrototype:ListProfiles(info)
|
||||||
local arg = info.arg
|
local arg = info.arg
|
||||||
local profiles
|
local profiles
|
||||||
@@ -308,7 +313,9 @@ end
|
|||||||
|
|
||||||
function OptionsHandlerPrototype:HasNoProfiles(info)
|
function OptionsHandlerPrototype:HasNoProfiles(info)
|
||||||
local profiles = self:ListProfiles(info)
|
local profiles = self:ListProfiles(info)
|
||||||
return ((not next(profiles)) and true or false)
|
local r = (not next(profiles)) and true or false
|
||||||
|
del(profiles)
|
||||||
|
return r
|
||||||
end
|
end
|
||||||
|
|
||||||
--[[ Copy a profile ]]
|
--[[ Copy a profile ]]
|
||||||
@@ -371,8 +378,7 @@ local optionsTable = {
|
|||||||
current = {
|
current = {
|
||||||
order = 11,
|
order = 11,
|
||||||
type = "description",
|
type = "description",
|
||||||
--name = function(info) return L["current"] .. " " .. NORMAL_FONT_COLOR_CODE .. info.handler:GetCurrentProfile() .. FONT_COLOR_CODE_CLOSE end,
|
name = function(info) return L["current"] .. " " .. NORMAL_FONT_COLOR_CODE .. info.handler:GetCurrentProfile() .. FONT_COLOR_CODE_CLOSE end,
|
||||||
name = "t",
|
|
||||||
width = "default",
|
width = "default",
|
||||||
},
|
},
|
||||||
choosedesc = {
|
choosedesc = {
|
||||||
@@ -387,6 +393,7 @@ local optionsTable = {
|
|||||||
order = 30,
|
order = 30,
|
||||||
get = false,
|
get = false,
|
||||||
set = "SetProfile",
|
set = "SetProfile",
|
||||||
|
nullable = false, -- Ace3v: we do not want a null or empty value
|
||||||
},
|
},
|
||||||
choose = {
|
choose = {
|
||||||
name = L["choose"],
|
name = L["choose"],
|
||||||
@@ -396,6 +403,7 @@ local optionsTable = {
|
|||||||
get = "GetCurrentProfile",
|
get = "GetCurrentProfile",
|
||||||
set = "SetProfile",
|
set = "SetProfile",
|
||||||
values = "ListProfiles",
|
values = "ListProfiles",
|
||||||
|
valuesTableDestroyable = true,
|
||||||
arg = "common",
|
arg = "common",
|
||||||
},
|
},
|
||||||
copydesc = {
|
copydesc = {
|
||||||
@@ -411,6 +419,7 @@ local optionsTable = {
|
|||||||
get = false,
|
get = false,
|
||||||
set = "CopyProfile",
|
set = "CopyProfile",
|
||||||
values = "ListProfiles",
|
values = "ListProfiles",
|
||||||
|
valuesTableDestroyable = true,
|
||||||
disabled = "HasNoProfiles",
|
disabled = "HasNoProfiles",
|
||||||
arg = "nocurrent",
|
arg = "nocurrent",
|
||||||
},
|
},
|
||||||
@@ -427,6 +436,7 @@ local optionsTable = {
|
|||||||
get = false,
|
get = false,
|
||||||
set = "DeleteProfile",
|
set = "DeleteProfile",
|
||||||
values = "ListProfiles",
|
values = "ListProfiles",
|
||||||
|
valuesTableDestroyable = true,
|
||||||
disabled = "HasNoProfiles",
|
disabled = "HasNoProfiles",
|
||||||
arg = "nocurrent",
|
arg = "nocurrent",
|
||||||
confirm = true,
|
confirm = true,
|
||||||
|
|||||||
@@ -30,13 +30,17 @@ local AceGUI, oldminor = LibStub:NewLibrary(ACEGUI_MAJOR, ACEGUI_MINOR)
|
|||||||
|
|
||||||
if not AceGUI then return end -- No upgrade needed
|
if not AceGUI then return end -- No upgrade needed
|
||||||
|
|
||||||
|
local AceCore = LibStub("AceCore-3.0")
|
||||||
|
local hooksecurefunc = AceCore.hooksecurefunc
|
||||||
|
local safecall = AceCore.safecall
|
||||||
|
|
||||||
-- Lua APIs
|
-- Lua APIs
|
||||||
local tconcat, tgetn, tremove, tinsert = table.concat, table.getn,table.remove, table.insert
|
local tconcat, tremove, tinsert, tgetn, tsetn = table.concat, table.remove, table.insert, table.getn, table.setn
|
||||||
local gsub, strupper = string.gsub, string.upper
|
local pairs, next, type = pairs, next, type
|
||||||
local select, pairs, next, type = select, pairs, next, type
|
|
||||||
local error, assert, loadstring = error, assert, loadstring
|
local error, assert, loadstring = error, assert, loadstring
|
||||||
local setmetatable, rawget, rawset = setmetatable, rawget, rawset
|
local setmetatable, rawget, rawset = setmetatable, rawget, rawset
|
||||||
local math_max = math.max
|
local math_max = math.max
|
||||||
|
local strupper, strfmt = string.upper, string.format
|
||||||
|
|
||||||
-- WoW APIs
|
-- WoW APIs
|
||||||
local UIParent = UIParent
|
local UIParent = UIParent
|
||||||
@@ -52,73 +56,17 @@ AceGUI.LayoutRegistry = AceGUI.LayoutRegistry or {}
|
|||||||
AceGUI.WidgetBase = AceGUI.WidgetBase or {}
|
AceGUI.WidgetBase = AceGUI.WidgetBase or {}
|
||||||
AceGUI.WidgetContainerBase = AceGUI.WidgetContainerBase or {}
|
AceGUI.WidgetContainerBase = AceGUI.WidgetContainerBase or {}
|
||||||
AceGUI.WidgetVersions = AceGUI.WidgetVersions or {}
|
AceGUI.WidgetVersions = AceGUI.WidgetVersions or {}
|
||||||
|
AceGUI.HookedFunctions = AceGUI.HookedFunctions or {}
|
||||||
|
|
||||||
-- local upvalues
|
-- local upvalues
|
||||||
local WidgetRegistry = AceGUI.WidgetRegistry
|
local WidgetRegistry = AceGUI.WidgetRegistry
|
||||||
local LayoutRegistry = AceGUI.LayoutRegistry
|
local LayoutRegistry = AceGUI.LayoutRegistry
|
||||||
local WidgetVersions = AceGUI.WidgetVersions
|
local WidgetVersions = AceGUI.WidgetVersions
|
||||||
|
local HookedFunctions = AceGUI.HookedFunctions
|
||||||
--[[
|
|
||||||
xpcall safecall implementation
|
|
||||||
]]
|
|
||||||
local xpcall = xpcall
|
|
||||||
|
|
||||||
local function errorhandler(err)
|
|
||||||
return geterrorhandler()(err)
|
|
||||||
end
|
|
||||||
|
|
||||||
local function CreateDispatcher(argCount)
|
|
||||||
local code = [[
|
|
||||||
local method, ARGS
|
|
||||||
local function call() return method(ARGS) end
|
|
||||||
|
|
||||||
local function dispatch(func, ...)
|
|
||||||
method = func
|
|
||||||
if not method then return end
|
|
||||||
ARGS = unpack(arg)
|
|
||||||
return xpcall(call, function(err) return geterrorhandler()(err) end)
|
|
||||||
end
|
|
||||||
|
|
||||||
return dispatch
|
|
||||||
]]
|
|
||||||
|
|
||||||
local ARGS = {}
|
|
||||||
for i = 1, argCount do ARGS[i] = "arg"..i end
|
|
||||||
code = gsub(code, "ARGS", tconcat(ARGS, ", "))
|
|
||||||
return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(xpcall, errorhandler)
|
|
||||||
end
|
|
||||||
|
|
||||||
local Dispatchers = setmetatable({}, {__index=function(self, argCount)
|
|
||||||
local dispatcher = CreateDispatcher(argCount)
|
|
||||||
rawset(self, argCount, dispatcher)
|
|
||||||
return dispatcher
|
|
||||||
end})
|
|
||||||
Dispatchers[0] = function(func)
|
|
||||||
return xpcall(func, errorhandler)
|
|
||||||
end
|
|
||||||
|
|
||||||
local function safecall(func, ...)
|
|
||||||
return Dispatchers[tgetn(arg)](func, unpack(arg))
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Recycling functions
|
-- Recycling functions
|
||||||
local newWidget, delWidget
|
local newWidget, delWidget
|
||||||
do
|
do
|
||||||
-- Version Upgrade in Minor 29
|
|
||||||
-- Internal Storage of the objects changed, from an array table
|
|
||||||
-- to a hash table, and additionally we introduced versioning on
|
|
||||||
-- the widgets which would discard all widgets from a pre-29 version
|
|
||||||
-- anyway, so we just clear the storage now, and don't try to
|
|
||||||
-- convert the storage tables to the new format.
|
|
||||||
-- This should generally not cause *many* widgets to end up in trash,
|
|
||||||
-- since once dialogs are opened, all addons should be loaded already
|
|
||||||
-- and AceGUI should be on the latest version available on the users
|
|
||||||
-- setup.
|
|
||||||
-- -- nevcairiel - Nov 2nd, 2009
|
|
||||||
if oldminor and oldminor < 29 and AceGUI.objPools then
|
|
||||||
AceGUI.objPools = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
AceGUI.objPools = AceGUI.objPools or {}
|
AceGUI.objPools = AceGUI.objPools or {}
|
||||||
local objPools = AceGUI.objPools
|
local objPools = AceGUI.objPools
|
||||||
--Returns a new instance, if none are available either returns a new table or calls the given contructor
|
--Returns a new instance, if none are available either returns a new table or calls the given contructor
|
||||||
@@ -157,6 +105,35 @@ do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Ace3v: when a container contains many children, we can only use the variable arguments
|
||||||
|
local function _fixlevels(parent, ...)
|
||||||
|
local lv = parent:GetFrameLevel() + 1
|
||||||
|
for i = 1, tgetn(arg) do
|
||||||
|
local child = arg[i]
|
||||||
|
child:SetFrameLevel(lv)
|
||||||
|
_fixlevels(child, child:GetChildren())
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function fixlevels(parent)
|
||||||
|
return _fixlevels(parent, parent:GetChildren())
|
||||||
|
end
|
||||||
|
AceGUI.fixlevels = fixlevels
|
||||||
|
|
||||||
|
-- Ace3v: attention! this function is recursive
|
||||||
|
local function _fixstrata(strata, parent, ...)
|
||||||
|
parent:SetFrameStrata(strata)
|
||||||
|
for i = 1, tgetn(arg) do
|
||||||
|
local child = arg[i]
|
||||||
|
_fixstrata(strata, child, child:GetChildren())
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function fixstrata(strata, parent)
|
||||||
|
return _fixstrata(strata, parent, parent:GetChildren())
|
||||||
|
end
|
||||||
|
AceGUI.fixstrata = fixstrata
|
||||||
|
|
||||||
|
|
||||||
-------------------
|
-------------------
|
||||||
-- API Functions --
|
-- API Functions --
|
||||||
@@ -173,27 +150,15 @@ function AceGUI:Create(type)
|
|||||||
if WidgetRegistry[type] then
|
if WidgetRegistry[type] then
|
||||||
local widget = newWidget(type)
|
local widget = newWidget(type)
|
||||||
|
|
||||||
if rawget(widget, "Acquire") then
|
|
||||||
widget.OnAcquire = widget.Acquire
|
|
||||||
widget.Acquire = nil
|
|
||||||
elseif rawget(widget, "Aquire") then
|
|
||||||
widget.OnAcquire = widget.Aquire
|
|
||||||
widget.Aquire = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
if rawget(widget, "Release") then
|
|
||||||
widget.OnRelease = rawget(widget, "Release")
|
|
||||||
widget.Release = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
if widget.OnAcquire then
|
if widget.OnAcquire then
|
||||||
widget:OnAcquire()
|
widget:OnAcquire()
|
||||||
else
|
else
|
||||||
error(format("Widget type %s doesn't supply an OnAcquire Function", type))
|
error(strfmt("Widget type %s doesn't supply an OnAcquire Function", type))
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Set the default Layout ("List")
|
-- Set the default Layout ("List")
|
||||||
safecall(widget.SetLayout, widget, "List")
|
safecall(widget.SetLayout, 2, widget, "List")
|
||||||
safecall(widget.ResumeLayout, widget)
|
safecall(widget.ResumeLayout, 1, widget)
|
||||||
return widget
|
return widget
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -204,14 +169,14 @@ end
|
|||||||
-- If this widget is a Container-Widget, all of its Child-Widgets will be releases as well.
|
-- If this widget is a Container-Widget, all of its Child-Widgets will be releases as well.
|
||||||
-- @param widget The widget to release
|
-- @param widget The widget to release
|
||||||
function AceGUI:Release(widget)
|
function AceGUI:Release(widget)
|
||||||
safecall(widget.PauseLayout, widget)
|
safecall(widget.PauseLayout, 1, widget)
|
||||||
widget:Fire("OnRelease")
|
widget:Fire("OnRelease")
|
||||||
safecall(widget.ReleaseChildren, widget)
|
safecall(widget.ReleaseChildren, 1, widget)
|
||||||
|
|
||||||
if widget.OnRelease then
|
if widget.OnRelease then
|
||||||
widget:OnRelease()
|
widget:OnRelease()
|
||||||
-- else
|
-- else
|
||||||
-- error(format("Widget type %s doesn't supply an OnRelease Function", widget.type))
|
-- error(strfmt("Widget type %s doesn't supply an OnRelease Function", widget.type))
|
||||||
end
|
end
|
||||||
for k in pairs(widget.userdata) do
|
for k in pairs(widget.userdata) do
|
||||||
widget.userdata[k] = nil
|
widget.userdata[k] = nil
|
||||||
@@ -246,7 +211,7 @@ end
|
|||||||
-- @param widget The widget that should be focused
|
-- @param widget The widget that should be focused
|
||||||
function AceGUI:SetFocus(widget)
|
function AceGUI:SetFocus(widget)
|
||||||
if self.FocusedWidget and self.FocusedWidget ~= widget then
|
if self.FocusedWidget and self.FocusedWidget ~= widget then
|
||||||
safecall(self.FocusedWidget.ClearFocus, self.FocusedWidget)
|
safecall(self.FocusedWidget.ClearFocus, 1, self.FocusedWidget)
|
||||||
end
|
end
|
||||||
self.FocusedWidget = widget
|
self.FocusedWidget = widget
|
||||||
end
|
end
|
||||||
@@ -256,7 +221,7 @@ end
|
|||||||
-- e.g. titlebar of a frame being clicked
|
-- e.g. titlebar of a frame being clicked
|
||||||
function AceGUI:ClearFocus()
|
function AceGUI:ClearFocus()
|
||||||
if self.FocusedWidget then
|
if self.FocusedWidget then
|
||||||
safecall(self.FocusedWidget.ClearFocus, self.FocusedWidget)
|
safecall(self.FocusedWidget.ClearFocus, 1, self.FocusedWidget)
|
||||||
self.FocusedWidget = nil
|
self.FocusedWidget = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -301,6 +266,7 @@ do
|
|||||||
frame:SetParent(nil)
|
frame:SetParent(nil)
|
||||||
frame:SetParent(parent.content)
|
frame:SetParent(parent.content)
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
|
fixlevels(frame)
|
||||||
end
|
end
|
||||||
|
|
||||||
WidgetBase.SetCallback = function(self, name, func)
|
WidgetBase.SetCallback = function(self, name, func)
|
||||||
@@ -309,9 +275,11 @@ do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
WidgetBase.Fire = function(self, name, ...)
|
WidgetBase.Fire = function(self,name,argc,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||||
if self.events[name] then
|
argc = argc or 0
|
||||||
local success, ret = safecall(self.events[name], self, name, unpack(arg))
|
local func = self.events[name]
|
||||||
|
if func then
|
||||||
|
local success, ret = safecall(func,argc+3,self,name,argc,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||||
if success then
|
if success then
|
||||||
return ret
|
return ret
|
||||||
end
|
end
|
||||||
@@ -362,8 +330,8 @@ do
|
|||||||
AceGUI:Release(self)
|
AceGUI:Release(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
WidgetBase.SetPoint = function(self, ...)
|
WidgetBase.SetPoint = function(self,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||||
return self.frame:SetPoint(unpack(arg))
|
return self.frame:SetPoint(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||||
end
|
end
|
||||||
|
|
||||||
WidgetBase.ClearAllPoints = function(self)
|
WidgetBase.ClearAllPoints = function(self)
|
||||||
@@ -374,8 +342,8 @@ do
|
|||||||
return self.frame:GetNumPoints()
|
return self.frame:GetNumPoints()
|
||||||
end
|
end
|
||||||
|
|
||||||
WidgetBase.GetPoint = function(self, ...)
|
WidgetBase.GetPoint = function(self,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||||
return self.frame:GetPoint(unpack(arg))
|
return self.frame:GetPoint(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||||
end
|
end
|
||||||
|
|
||||||
WidgetBase.GetUserDataTable = function(self)
|
WidgetBase.GetUserDataTable = function(self)
|
||||||
@@ -433,7 +401,7 @@ do
|
|||||||
if self.LayoutPaused then
|
if self.LayoutPaused then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
safecall(self.LayoutFunc, self.content, self.children)
|
safecall(self.LayoutFunc, 2, self.content, self.children)
|
||||||
end
|
end
|
||||||
|
|
||||||
--call this function to layout, makes sure layed out objects get a frame to get sizes etc
|
--call this function to layout, makes sure layed out objects get a frame to get sizes etc
|
||||||
@@ -462,21 +430,48 @@ do
|
|||||||
self:DoLayout()
|
self:DoLayout()
|
||||||
end
|
end
|
||||||
|
|
||||||
WidgetContainerBase.AddChildren = function(self, ...)
|
do
|
||||||
for i = 1, tgetn(arg) do
|
local args = {nil,nil,nil,nil,nil,nil,nil,nil,nil,nil}
|
||||||
local child = arg[i]
|
WidgetContainerBase.AddChildren = function(self,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||||
|
args[1] = a1
|
||||||
|
args[2] = a2
|
||||||
|
args[3] = a3
|
||||||
|
args[4] = a4
|
||||||
|
args[5] = a5
|
||||||
|
args[6] = a6
|
||||||
|
args[7] = a7
|
||||||
|
args[8] = a8
|
||||||
|
args[9] = a9
|
||||||
|
args[10] = a10
|
||||||
|
for i = 1,10 do
|
||||||
|
local child = args[i]
|
||||||
|
arg[i] = nil
|
||||||
|
|
||||||
|
if not child then break end
|
||||||
tinsert(self.children, child)
|
tinsert(self.children, child)
|
||||||
child:SetParent(self)
|
child:SetParent(self)
|
||||||
child.frame:Show()
|
child.frame:Show()
|
||||||
end
|
end
|
||||||
self:DoLayout()
|
self:DoLayout()
|
||||||
end
|
end
|
||||||
|
end -- WidgetContainerBase.AddChildren
|
||||||
|
|
||||||
WidgetContainerBase.ReleaseChildren = function(self)
|
WidgetContainerBase.ReleaseChildren = function(self)
|
||||||
local children = self.children
|
local children = self.children
|
||||||
for i = 1,tgetn(children) do
|
for i = 1,tgetn(children) do
|
||||||
AceGUI:Release(children[i])
|
AceGUI:Release(tremove(children))
|
||||||
children[i] = nil
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
WidgetContainerBase.SetParent = function(self, parent)
|
||||||
|
WidgetBase.SetParent(self, parent)
|
||||||
|
|
||||||
|
local lv = self.frame:GetFrameLevel()
|
||||||
|
self.content:SetFrameLevel(lv+1)
|
||||||
|
local children = self.children
|
||||||
|
for i = 1,tgetn(children) do
|
||||||
|
local child = children[i]
|
||||||
|
child:SetParent(self)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -573,7 +568,7 @@ end
|
|||||||
function AceGUI:RegisterLayout(Name, LayoutFunc)
|
function AceGUI:RegisterLayout(Name, LayoutFunc)
|
||||||
assert(type(LayoutFunc) == "function")
|
assert(type(LayoutFunc) == "function")
|
||||||
if type(Name) == "string" then
|
if type(Name) == "string" then
|
||||||
Name = strupper(Name)
|
Name = string.upper(Name)
|
||||||
end
|
end
|
||||||
LayoutRegistry[Name] = LayoutFunc
|
LayoutRegistry[Name] = LayoutFunc
|
||||||
end
|
end
|
||||||
@@ -658,7 +653,7 @@ AceGUI:RegisterLayout("List",
|
|||||||
|
|
||||||
height = height + (frame.height or frame:GetHeight() or 0)
|
height = height + (frame.height or frame:GetHeight() or 0)
|
||||||
end
|
end
|
||||||
safecall(content.obj.LayoutFinished, content.obj, nil, height)
|
safecall(content.obj.LayoutFinished, 3, content.obj, nil, height)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- A single control fills the whole content area
|
-- A single control fills the whole content area
|
||||||
@@ -669,14 +664,15 @@ AceGUI:RegisterLayout("Fill",
|
|||||||
children[1]:SetHeight(content:GetHeight() or 0)
|
children[1]:SetHeight(content:GetHeight() or 0)
|
||||||
children[1].frame:SetAllPoints(content)
|
children[1].frame:SetAllPoints(content)
|
||||||
children[1].frame:Show()
|
children[1].frame:Show()
|
||||||
safecall(content.obj.LayoutFinished, content.obj, nil, children[1].frame:GetHeight())
|
safecall(content.obj.LayoutFinished, 3, content.obj, nil, children[1].frame:GetHeight())
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
-- Ace3v: currently only a1 used
|
||||||
local layoutrecursionblock = nil
|
local layoutrecursionblock = nil
|
||||||
local function safelayoutcall(object, func, ...)
|
local function safelayoutcall(object, func, a1)
|
||||||
layoutrecursionblock = true
|
layoutrecursionblock = true
|
||||||
object[func](object, unpack(arg))
|
object[func](object, a1)
|
||||||
layoutrecursionblock = nil
|
layoutrecursionblock = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -809,5 +805,5 @@ AceGUI:RegisterLayout("Flow",
|
|||||||
end
|
end
|
||||||
|
|
||||||
height = height + rowheight + 3
|
height = height + rowheight + 3
|
||||||
safecall(content.obj.LayoutFinished, content.obj, nil, height)
|
safecall(content.obj.LayoutFinished, 3, content.obj, nil, height)
|
||||||
end)
|
end)
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
|
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
|
||||||
..\FrameXML\UI.xsd">
|
..\FrameXML\UI.xsd">
|
||||||
<Script file="AceGUI-3.0.lua"/>
|
<Script file="AceGUI-3.0.lua"/>
|
||||||
<Include file="widgets\widgets.xml"/>
|
|
||||||
</Ui>
|
</Ui>
|
||||||
|
|||||||
+3
-3
@@ -15,11 +15,11 @@ local CreateFrame = CreateFrame
|
|||||||
--[[-----------------------------------------------------------------------------
|
--[[-----------------------------------------------------------------------------
|
||||||
Scripts
|
Scripts
|
||||||
-------------------------------------------------------------------------------]]
|
-------------------------------------------------------------------------------]]
|
||||||
local function SelectedGroup(self, event, value)
|
local function SelectedGroup(self, event, _, value)
|
||||||
local group = self.parentgroup
|
local group = self.parentgroup
|
||||||
local status = group.status or group.localstatus
|
local status = group.status or group.localstatus
|
||||||
status.selected = value
|
status.selected = value
|
||||||
self.parentgroup:Fire("OnGroupSelected", value)
|
self.parentgroup:Fire("OnGroupSelected", 1, value)
|
||||||
end
|
end
|
||||||
|
|
||||||
--[[-----------------------------------------------------------------------------
|
--[[-----------------------------------------------------------------------------
|
||||||
@@ -63,7 +63,7 @@ local methods = {
|
|||||||
self.dropdown:SetValue(group)
|
self.dropdown:SetValue(group)
|
||||||
local status = self.status or self.localstatus
|
local status = self.status or self.localstatus
|
||||||
status.selected = group
|
status.selected = group
|
||||||
self:Fire("OnGroupSelected", group)
|
self:Fire("OnGroupSelected", 1, group)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
["OnWidthSet"] = function(self, width)
|
["OnWidthSet"] = function(self, width)
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
--[[-----------------------------------------------------------------------------
|
--[[-----------------------------------------------------------------------------
|
||||||
Frame Container
|
Frame Container
|
||||||
-------------------------------------------------------------------------------]]
|
-------------------------------------------------------------------------------]]
|
||||||
local Type, Version = "Frame", 26
|
local Type, Version = "Frame", 24
|
||||||
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
||||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||||
|
|
||||||
|
local AceCore = LibStub("AceCore-3.0")
|
||||||
|
local wipe = AceCore.wipe
|
||||||
|
|
||||||
-- Lua APIs
|
-- Lua APIs
|
||||||
local pairs, assert, type = pairs, assert, type
|
local pairs, assert, type = pairs, assert, type
|
||||||
local wipe = table.wipe
|
|
||||||
|
|
||||||
-- WoW APIs
|
-- WoW APIs
|
||||||
local PlaySound = PlaySound
|
local PlaySound = PlaySound
|
||||||
@@ -25,10 +27,6 @@ local function Button_OnClick()
|
|||||||
this.obj:Hide()
|
this.obj:Hide()
|
||||||
end
|
end
|
||||||
|
|
||||||
local function Frame_OnShow()
|
|
||||||
this.obj:Fire("OnShow")
|
|
||||||
end
|
|
||||||
|
|
||||||
local function Frame_OnClose()
|
local function Frame_OnClose()
|
||||||
this.obj:Fire("OnClose")
|
this.obj:Fire("OnClose")
|
||||||
end
|
end
|
||||||
@@ -190,7 +188,6 @@ local function Constructor()
|
|||||||
frame:SetBackdropColor(0, 0, 0, 1)
|
frame:SetBackdropColor(0, 0, 0, 1)
|
||||||
frame:SetMinResize(400, 200)
|
frame:SetMinResize(400, 200)
|
||||||
frame:SetToplevel(true)
|
frame:SetToplevel(true)
|
||||||
frame:SetScript("OnShow", Frame_OnShow)
|
|
||||||
frame:SetScript("OnHide", Frame_OnClose)
|
frame:SetScript("OnHide", Frame_OnClose)
|
||||||
frame:SetScript("OnMouseDown", Frame_OnMouseDown)
|
frame:SetScript("OnMouseDown", Frame_OnMouseDown)
|
||||||
|
|
||||||
@@ -248,6 +245,7 @@ local function Constructor()
|
|||||||
titlebg_r:SetWidth(30)
|
titlebg_r:SetWidth(30)
|
||||||
titlebg_r:SetHeight(40)
|
titlebg_r:SetHeight(40)
|
||||||
|
|
||||||
|
-- bottom right sizer
|
||||||
local sizer_se = CreateFrame("Frame", nil, frame)
|
local sizer_se = CreateFrame("Frame", nil, frame)
|
||||||
sizer_se:SetPoint("BOTTOMRIGHT", 0, 0)
|
sizer_se:SetPoint("BOTTOMRIGHT", 0, 0)
|
||||||
sizer_se:SetWidth(25)
|
sizer_se:SetWidth(25)
|
||||||
|
|||||||
+30
-21
@@ -6,9 +6,12 @@ local Type, Version = "ScrollFrame", 24
|
|||||||
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
||||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||||
|
|
||||||
|
local fixlevels = AceGUI.fixlevels
|
||||||
|
|
||||||
-- Lua APIs
|
-- Lua APIs
|
||||||
local pairs, assert, type = pairs, assert, type
|
local pairs, assert, type = pairs, assert, type
|
||||||
local min, max, floor, abs = math.min, math.max, math.floor, math.abs
|
local min, max, floor, abs = math.min, math.max, math.floor, math.abs
|
||||||
|
local format = string.format
|
||||||
|
|
||||||
-- WoW APIs
|
-- WoW APIs
|
||||||
local CreateFrame, UIParent = CreateFrame, UIParent
|
local CreateFrame, UIParent = CreateFrame, UIParent
|
||||||
@@ -24,16 +27,16 @@ end
|
|||||||
--[[-----------------------------------------------------------------------------
|
--[[-----------------------------------------------------------------------------
|
||||||
Scripts
|
Scripts
|
||||||
-------------------------------------------------------------------------------]]
|
-------------------------------------------------------------------------------]]
|
||||||
local function ScrollFrame_OnMouseWheel(frame, value)
|
local function ScrollFrame_OnMouseWheel()
|
||||||
frame.obj:MoveScroll(value)
|
this.obj:MoveScroll(arg1)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function ScrollFrame_OnSizeChanged()
|
local function ScrollFrame_OnSizeChanged()
|
||||||
this:SetScript("OnUpdate", FixScrollOnUpdate)
|
this:SetScript("OnUpdate", FixScrollOnUpdate)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function ScrollBar_OnScrollValueChanged(frame, value)
|
local function ScrollBar_OnScrollValueChanged()
|
||||||
frame.obj:SetScroll(value)
|
this.obj:SetScroll(arg1)
|
||||||
end
|
end
|
||||||
|
|
||||||
--[[-----------------------------------------------------------------------------
|
--[[-----------------------------------------------------------------------------
|
||||||
@@ -89,40 +92,46 @@ local methods = {
|
|||||||
end,
|
end,
|
||||||
|
|
||||||
["FixScroll"] = function(self)
|
["FixScroll"] = function(self)
|
||||||
|
|
||||||
if self.updateLock then return end
|
if self.updateLock then return end
|
||||||
self.updateLock = true
|
self.updateLock = true
|
||||||
local status = self.status or self.localstatus
|
local status = self.status or self.localstatus
|
||||||
local height, viewheight = self.scrollframe:GetHeight(), self.content:GetHeight()
|
local scrollframe, content, scrollbar = self.scrollframe, self.content, self.scrollbar
|
||||||
|
local viewheight, height = self.scrollframe:GetHeight(), self.content:GetHeight()
|
||||||
local offset = status.offset or 0
|
local offset = status.offset or 0
|
||||||
local curvalue = self.scrollbar:GetValue()
|
local curvalue = scrollbar:GetValue()
|
||||||
-- Give us a margin of error of 2 pixels to stop some conditions that i would blame on floating point inaccuracys
|
-- Give us a margin of error of 2 pixels to stop some conditions that i would blame on floating point inaccuracys
|
||||||
-- No-one is going to miss 2 pixels at the bottom of the frame, anyhow!
|
-- No-one is going to miss 2 pixels at the bottom of the frame, anyhow!
|
||||||
if viewheight < height + 2 then
|
|
||||||
|
if height < viewheight + 2 then
|
||||||
if self.scrollBarShown then
|
if self.scrollBarShown then
|
||||||
self.scrollBarShown = nil
|
self.scrollBarShown = nil
|
||||||
self.scrollbar:Hide()
|
scrollbar:Hide()
|
||||||
self.scrollbar:SetValue(0)
|
scrollbar:SetValue(0)
|
||||||
self.scrollframe:SetPoint("BOTTOMRIGHT", 0, 0)
|
scrollframe:SetPoint("BOTTOMRIGHT",0,0)
|
||||||
self:DoLayout()
|
self:DoLayout()
|
||||||
end
|
end
|
||||||
|
offset = 0
|
||||||
else
|
else
|
||||||
if not self.scrollBarShown then
|
if not self.scrollBarShown then
|
||||||
self.scrollBarShown = true
|
self.scrollBarShown = true
|
||||||
self.scrollbar:Show()
|
scrollbar:Show()
|
||||||
self.scrollframe:SetPoint("BOTTOMRIGHT", -20, 0)
|
scrollframe:SetPoint("BOTTOMRIGHT", -20, 0)
|
||||||
self:DoLayout()
|
self:DoLayout()
|
||||||
end
|
end
|
||||||
local value = (offset / (viewheight - height) * 1000)
|
local value = (offset / (height - viewheight) * 1000)
|
||||||
if value > 1000 then value = 1000 end
|
if value > 1000 then
|
||||||
self.scrollbar:SetValue(value)
|
value = 1000
|
||||||
|
offset = height - viewheight
|
||||||
|
end
|
||||||
|
scrollbar:SetValue(value)
|
||||||
self:SetScroll(value)
|
self:SetScroll(value)
|
||||||
if value < 1000 then
|
end
|
||||||
self.content:ClearAllPoints()
|
|
||||||
self.content:SetPoint("TOPLEFT", 0, offset)
|
|
||||||
self.content:SetPoint("TOPRIGHT", 0, offset)
|
|
||||||
status.offset = offset
|
status.offset = offset
|
||||||
end
|
scrollframe:SetScrollChild(content)
|
||||||
end
|
content:ClearAllPoints()
|
||||||
|
content:SetPoint("TOPLEFT", 0, offset)
|
||||||
|
content:SetPoint("TOPRIGHT", 0, offset)
|
||||||
self.updateLock = nil
|
self.updateLock = nil
|
||||||
end,
|
end,
|
||||||
|
|
||||||
|
|||||||
+63
-36
@@ -2,18 +2,22 @@
|
|||||||
TabGroup Container
|
TabGroup Container
|
||||||
Container that uses tabs on top to switch between groups.
|
Container that uses tabs on top to switch between groups.
|
||||||
-------------------------------------------------------------------------------]]
|
-------------------------------------------------------------------------------]]
|
||||||
local Type, Version = "TabGroup", 36
|
local Type, Version = "TabGroup", 35
|
||||||
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
||||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||||
|
|
||||||
|
local AceCore = LibStub("AceCore-3.0")
|
||||||
|
local wipe = AceCore.wipe
|
||||||
|
|
||||||
-- Lua APIs
|
-- Lua APIs
|
||||||
local pairs, ipairs, assert, type, wipe = pairs, ipairs, assert, type, wipe
|
local pairs, ipairs, assert, type, wipe = pairs, ipairs, assert, type, wipe
|
||||||
local tgetn = table.getn
|
local tgetn = table.getn
|
||||||
|
local strfmt = string.format
|
||||||
|
|
||||||
-- WoW APIs
|
-- WoW APIs
|
||||||
local PlaySound = PlaySound
|
local PlaySound = PlaySound
|
||||||
local CreateFrame, UIParent = CreateFrame, UIParent
|
local CreateFrame, UIParent = CreateFrame, UIParent
|
||||||
local _G = _G
|
local _G = AceCore._G
|
||||||
|
|
||||||
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
|
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
|
||||||
-- List them here for Mikk's FindGlobals script
|
-- List them here for Mikk's FindGlobals script
|
||||||
@@ -30,57 +34,60 @@ Support functions
|
|||||||
local function UpdateTabLook(frame)
|
local function UpdateTabLook(frame)
|
||||||
if frame.disabled then
|
if frame.disabled then
|
||||||
PanelTemplates_SetDisabledTabState(frame)
|
PanelTemplates_SetDisabledTabState(frame)
|
||||||
|
frame:SetAlpha(0.5)
|
||||||
elseif frame.selected then
|
elseif frame.selected then
|
||||||
PanelTemplates_SelectTab(frame)
|
PanelTemplates_SelectTab(frame)
|
||||||
|
frame:SetAlpha(1)
|
||||||
else
|
else
|
||||||
PanelTemplates_DeselectTab(frame)
|
PanelTemplates_DeselectTab(frame)
|
||||||
|
frame:SetAlpha(0.5)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function Tab_SetText(frame, text)
|
local function Tab_SetText(tab, text)
|
||||||
frame:_SetText(text)
|
tab:_SetText(text)
|
||||||
local width = frame.obj.frame.width or frame.obj.frame:GetWidth() or 0
|
local width = tab.obj.frame.width or tab.obj.frame:GetWidth() or 0
|
||||||
PanelTemplates_TabResize(frame, 0, nil, width, frame:GetFontString():GetStringWidth())
|
PanelTemplates_TabResize(0, tab, nil, width)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function Tab_SetSelected(frame, selected)
|
local function Tab_SetSelected(tab, selected)
|
||||||
frame.selected = selected
|
tab.selected = selected
|
||||||
UpdateTabLook(frame)
|
UpdateTabLook(tab)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function Tab_SetDisabled(frame, disabled)
|
local function Tab_SetDisabled(tab, disabled)
|
||||||
frame.disabled = disabled
|
tab.disabled = disabled
|
||||||
UpdateTabLook(frame)
|
UpdateTabLook(tab)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function BuildTabsOnUpdate(frame)
|
local function BuildTabsOnUpdate()
|
||||||
local self = frame.obj
|
local self = this.obj
|
||||||
self:BuildTabs()
|
self:BuildTabs()
|
||||||
frame:SetScript("OnUpdate", nil)
|
this:SetScript("OnUpdate", nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
--[[-----------------------------------------------------------------------------
|
--[[-----------------------------------------------------------------------------
|
||||||
Scripts
|
Scripts
|
||||||
-------------------------------------------------------------------------------]]
|
-------------------------------------------------------------------------------]]
|
||||||
local function Tab_OnClick(frame)
|
local function Tab_OnClick()
|
||||||
if not (frame.selected or frame.disabled) then
|
if not (this.selected or this.disabled) then
|
||||||
PlaySound("igCharacterInfoTab")
|
PlaySound("igCharacterInfoTab")
|
||||||
frame.obj:SelectTab(frame.value)
|
this.obj:SelectTab(this.value)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function Tab_OnEnter(frame)
|
local function Tab_OnEnter()
|
||||||
local self = frame.obj
|
local self = this.obj
|
||||||
self:Fire("OnTabEnter", self.tabs[frame.id].value, frame)
|
self:Fire("OnTabEnter", 2, self.tabs[this.id].value, this)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function Tab_OnLeave(frame)
|
local function Tab_OnLeave()
|
||||||
local self = frame.obj
|
local self = this.obj
|
||||||
self:Fire("OnTabLeave", self.tabs[frame.id].value, frame)
|
self:Fire("OnTabLeave", 2, self.tabs[this.id].value, this)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function Tab_OnShow(frame)
|
local function Tab_OnShow()
|
||||||
_G[frame:GetName().."HighlightTexture"]:SetWidth(frame:GetTextWidth() + 30)
|
_G[this:GetName().."HighlightTexture"]:SetWidth(this:GetTextWidth() + 30)
|
||||||
end
|
end
|
||||||
|
|
||||||
--[[-----------------------------------------------------------------------------
|
--[[-----------------------------------------------------------------------------
|
||||||
@@ -103,16 +110,31 @@ local methods = {
|
|||||||
end,
|
end,
|
||||||
|
|
||||||
["CreateTab"] = function(self, id)
|
["CreateTab"] = function(self, id)
|
||||||
local tabname = format("AceGUITabGroup%dTab%d", self.num, id)
|
local tabname = strfmt("AceGUITabGroup%dTab%d", self.num, id)
|
||||||
local tab = CreateFrame("Button", tabname, self.border, "OptionsFrameTabButtonTemplate")
|
local tab = CreateFrame("Button", tabname, self.border, "TabButtonTemplate")
|
||||||
|
-- Normal texture
|
||||||
|
local texture = getglobal(tabname.."Left")
|
||||||
|
texture:SetTexture("Interface\\ChatFrame\\ChatFrameTab")
|
||||||
|
texture:ClearAllPoints()
|
||||||
|
texture:SetPoint("BOTTOMLEFT", tab,"BOTTOMLEFT")
|
||||||
|
texture:SetPoint("TOPLEFT", tab,"TOPLEFT")
|
||||||
|
texture = getglobal(tabname.."Middle")
|
||||||
|
texture:SetTexture("Interface\\ChatFrame\\ChatFrameTab")
|
||||||
|
texture = getglobal(tabname.."Right")
|
||||||
|
texture:SetTexture("Interface\\ChatFrame\\ChatFrameTab")
|
||||||
|
-- Disabled texture
|
||||||
|
texture = getglobal(tabname.."LeftDisabled")
|
||||||
|
texture:SetTexture("Interface\\ChatFrame\\ChatFrameTab")
|
||||||
|
texture:SetPoint("BOTTOMLEFT", tab,"BOTTOMLEFT")
|
||||||
|
texture:SetPoint("TOPLEFT", tab,"TOPLEFT")
|
||||||
|
texture = getglobal(tabname.."MiddleDisabled")
|
||||||
|
texture:SetTexture("Interface\\ChatFrame\\ChatFrameTab")
|
||||||
|
texture = getglobal(tabname.."RightDisabled")
|
||||||
|
texture:SetTexture("Interface\\ChatFrame\\ChatFrameTab")
|
||||||
|
|
||||||
tab.obj = self
|
tab.obj = self
|
||||||
tab.id = id
|
tab.id = id
|
||||||
|
|
||||||
tab.text = _G[tabname .. "Text"]
|
|
||||||
tab.text:ClearAllPoints()
|
|
||||||
tab.text:SetPoint("LEFT", 14, -3)
|
|
||||||
tab.text:SetPoint("RIGHT", -12, -3)
|
|
||||||
|
|
||||||
tab:SetScript("OnClick", Tab_OnClick)
|
tab:SetScript("OnClick", Tab_OnClick)
|
||||||
tab:SetScript("OnEnter", Tab_OnEnter)
|
tab:SetScript("OnEnter", Tab_OnEnter)
|
||||||
tab:SetScript("OnLeave", Tab_OnLeave)
|
tab:SetScript("OnLeave", Tab_OnLeave)
|
||||||
@@ -154,7 +176,7 @@ local methods = {
|
|||||||
end
|
end
|
||||||
status.selected = value
|
status.selected = value
|
||||||
if found then
|
if found then
|
||||||
self:Fire("OnGroupSelected",value)
|
self:Fire("OnGroupSelected",1,value)
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
|
||||||
@@ -187,9 +209,14 @@ local methods = {
|
|||||||
end
|
end
|
||||||
|
|
||||||
tab:Show()
|
tab:Show()
|
||||||
|
if type(v) == "table" then
|
||||||
tab:SetText(v.text)
|
tab:SetText(v.text)
|
||||||
tab:SetDisabled(v.disabled)
|
tab:SetDisabled(v.disabled)
|
||||||
tab.value = v.value
|
tab.value = v.value
|
||||||
|
elseif type(v) == "string" then
|
||||||
|
tab:SetText(v)
|
||||||
|
tab.value = v
|
||||||
|
end
|
||||||
|
|
||||||
widths[i] = tab:GetWidth() - 6 --tabs are anchored 10 pixels from the right side of the previous one to reduce spacing, but add a fixed 4px padding for the text
|
widths[i] = tab:GetWidth() - 6 --tabs are anchored 10 pixels from the right side of the previous one to reduce spacing, but add a fixed 4px padding for the text
|
||||||
end
|
end
|
||||||
@@ -257,12 +284,12 @@ local methods = {
|
|||||||
end
|
end
|
||||||
|
|
||||||
for i = starttab, endtab do
|
for i = starttab, endtab do
|
||||||
PanelTemplates_TabResize(tabs[i], padding + 4, nil, width, tabs[i]:GetFontString():GetStringWidth())
|
PanelTemplates_TabResize(padding + 4, tabs[i], nil, width)
|
||||||
end
|
end
|
||||||
starttab = endtab + 1
|
starttab = endtab + 1
|
||||||
end
|
end
|
||||||
|
|
||||||
self.borderoffset = (hastitle and 17 or 10)+((numrows)*20)
|
self.borderoffset = (hastitle and 17 or 10)+((numrows)*20)+7
|
||||||
self.border:SetPoint("TOPLEFT", 1, -self.borderoffset)
|
self.border:SetPoint("TOPLEFT", 1, -self.borderoffset)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
|
|||||||
+128
-71
@@ -6,12 +6,15 @@ local Type, Version = "TreeGroup", 40
|
|||||||
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
||||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||||
|
|
||||||
|
local AceCore = LibStub("AceCore-3.0")
|
||||||
|
local strsplit = AceCore.strsplit
|
||||||
|
local _G = AceCore._G
|
||||||
|
|
||||||
-- Lua APIs
|
-- Lua APIs
|
||||||
local next, pairs, ipairs, assert, type = next, pairs, ipairs, assert, type
|
local next, pairs, ipairs, assert, type = next, pairs, ipairs, assert, type
|
||||||
local math_min, math_max, floor = math.min, math.max, floor
|
local math_min, math_max, floor = math.min, math.max, floor
|
||||||
local select, tremove, unpack, tconcat = select, table.remove, unpack, table.concat
|
local tgetn, tremove, unpack, tconcat = table.getn, table.remove, unpack, table.concat
|
||||||
local strsplit = string.split
|
local strfmt = string.format
|
||||||
local tgetn = table.getn
|
|
||||||
|
|
||||||
-- WoW APIs
|
-- WoW APIs
|
||||||
local CreateFrame, UIParent = CreateFrame, UIParent
|
local CreateFrame, UIParent = CreateFrame, UIParent
|
||||||
@@ -81,12 +84,13 @@ local function UpdateButton(button, treeline, selected, canExpand, isExpanded)
|
|||||||
local normalTexture = button:GetNormalTexture()
|
local normalTexture = button:GetNormalTexture()
|
||||||
local line = button.line
|
local line = button.line
|
||||||
button.level = level
|
button.level = level
|
||||||
|
|
||||||
if ( level == 1 ) then
|
if ( level == 1 ) then
|
||||||
button:SetNormalFontObject("GameFontNormal")
|
button.text:SetFontObject("GameFontNormal")
|
||||||
button:SetHighlightFontObject("GameFontHighlight")
|
button:SetHighlightFontObject("GameFontHighlight")
|
||||||
button.text:SetPoint("LEFT", (icon and 16 or 0) + 8, 2)
|
button.text:SetPoint("LEFT", (icon and 16 or 0) + 8, 2)
|
||||||
else
|
else
|
||||||
button:SetNormalFontObject("GameFontHighlightSmall")
|
button.text:SetFontObject("GameFontHighlightSmall")
|
||||||
button:SetHighlightFontObject("GameFontHighlightSmall")
|
button:SetHighlightFontObject("GameFontHighlightSmall")
|
||||||
button.text:SetPoint("LEFT", (icon and 16 or 0) + 8 * level, 2)
|
button.text:SetPoint("LEFT", (icon and 16 or 0) + 8 * level, 2)
|
||||||
end
|
end
|
||||||
@@ -156,134 +160,143 @@ local function addLine(self, v, tree, level, parent)
|
|||||||
else
|
else
|
||||||
line.hasChildren = nil
|
line.hasChildren = nil
|
||||||
end
|
end
|
||||||
self.lines[tgetn(self.lines)+1] = line
|
tinsert(self.lines, line)
|
||||||
return line
|
return line
|
||||||
end
|
end
|
||||||
|
|
||||||
--fire an update after one frame to catch the treeframes height
|
--fire an update after one frame to catch the treeframes height
|
||||||
local function FirstFrameUpdate(frame)
|
local function FirstFrameUpdate()
|
||||||
local self = frame.obj
|
local self = this.obj
|
||||||
frame:SetScript("OnUpdate", nil)
|
this:SetScript("OnUpdate", nil)
|
||||||
self:RefreshTree()
|
self:RefreshTree()
|
||||||
end
|
end
|
||||||
|
|
||||||
local function BuildUniqueValue(...)
|
local BuildUniqueValue
|
||||||
local n = select('#', arg)
|
do
|
||||||
if n == 1 then
|
local args = {nil,nil,nil,nil,nil,nil,nil,nil,nil,nil}
|
||||||
return arg1
|
function BuildUniqueValue(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||||
else
|
args[1] = a1
|
||||||
return (unpack(arg)).."\001"..BuildUniqueValue(select(2,arg))
|
args[2] = a2
|
||||||
|
args[3] = a3
|
||||||
|
args[4] = a4
|
||||||
|
args[5] = a5
|
||||||
|
args[6] = a6
|
||||||
|
args[7] = a7
|
||||||
|
args[8] = a8
|
||||||
|
args[9] = a9
|
||||||
|
args[10] = a10
|
||||||
|
return tconcat(tmp, "\001", 1, tgetn(args))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--[[-----------------------------------------------------------------------------
|
--[[-----------------------------------------------------------------------------
|
||||||
Scripts
|
Scripts
|
||||||
-------------------------------------------------------------------------------]]
|
-------------------------------------------------------------------------------]]
|
||||||
local function Expand_OnClick(frame)
|
local function Expand_OnClick()
|
||||||
local button = frame.button
|
local button = this.button
|
||||||
local self = button.obj
|
local self = button.obj
|
||||||
local status = (self.status or self.localstatus).groups
|
local status = (self.status or self.localstatus).groups
|
||||||
status[button.uniquevalue] = not status[button.uniquevalue]
|
status[button.uniquevalue] = not status[button.uniquevalue]
|
||||||
self:RefreshTree()
|
self:RefreshTree()
|
||||||
end
|
end
|
||||||
|
|
||||||
local function Button_OnClick(frame)
|
local function Button_OnClick()
|
||||||
local self = frame.obj
|
local self = this.obj
|
||||||
self:Fire("OnClick", frame.uniquevalue, frame.selected)
|
self:Fire("OnClick", 2, this.uniquevalue, this.selected)
|
||||||
if not frame.selected then
|
if not this.selected then
|
||||||
self:SetSelected(frame.uniquevalue)
|
self:SetSelected(this.uniquevalue)
|
||||||
frame.selected = true
|
this.selected = true
|
||||||
frame:LockHighlight()
|
this:LockHighlight()
|
||||||
self:RefreshTree()
|
self:RefreshTree()
|
||||||
end
|
end
|
||||||
AceGUI:ClearFocus()
|
AceGUI:ClearFocus()
|
||||||
end
|
end
|
||||||
|
|
||||||
local function Button_OnDoubleClick(button)
|
local function Button_OnDoubleClick()
|
||||||
local self = button.obj
|
local self = this.obj
|
||||||
local status = self.status or self.localstatus
|
local status = self.status or self.localstatus
|
||||||
local status = (self.status or self.localstatus).groups
|
local status = (self.status or self.localstatus).groups
|
||||||
status[button.uniquevalue] = not status[button.uniquevalue]
|
status[this.uniquevalue] = not status[this.uniquevalue]
|
||||||
self:RefreshTree()
|
self:RefreshTree()
|
||||||
end
|
end
|
||||||
|
|
||||||
local function Button_OnEnter(frame)
|
local function Button_OnEnter()
|
||||||
local self = frame.obj
|
local self = this.obj
|
||||||
self:Fire("OnButtonEnter", frame.uniquevalue, frame)
|
self:Fire("OnButtonEnter", 2, this.uniquevalue, this)
|
||||||
|
|
||||||
if self.enabletooltips then
|
if self.enabletooltips then
|
||||||
GameTooltip:SetOwner(frame, "ANCHOR_NONE")
|
GameTooltip:SetOwner(this, "ANCHOR_NONE")
|
||||||
GameTooltip:SetPoint("LEFT",frame,"RIGHT")
|
GameTooltip:SetPoint("LEFT",this,"RIGHT")
|
||||||
GameTooltip:SetText(frame.text:GetText() or "", 1, .82, 0, 1)
|
GameTooltip:SetText(this.text:GetText() or "", 1, .82, 0, true)
|
||||||
|
|
||||||
GameTooltip:Show()
|
GameTooltip:Show()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function Button_OnLeave(frame)
|
local function Button_OnLeave()
|
||||||
local self = frame.obj
|
local self = this.obj
|
||||||
self:Fire("OnButtonLeave", frame.uniquevalue, frame)
|
self:Fire("OnButtonLeave", 2, this.uniquevalue, this)
|
||||||
|
|
||||||
if self.enabletooltips then
|
if self.enabletooltips then
|
||||||
GameTooltip:Hide()
|
GameTooltip:Hide()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function OnScrollValueChanged(frame, value)
|
local function OnScrollValueChanged()
|
||||||
if frame.obj.noupdate then return end
|
if this.obj.noupdate then return end
|
||||||
local self = frame.obj
|
local self = this.obj
|
||||||
local status = self.status or self.localstatus
|
local status = self.status or self.localstatus
|
||||||
status.scrollvalue = floor(value + 0.5)
|
status.scrollvalue = floor(arg1 + 0.5)
|
||||||
self:RefreshTree()
|
self:RefreshTree()
|
||||||
AceGUI:ClearFocus()
|
AceGUI:ClearFocus()
|
||||||
end
|
end
|
||||||
|
|
||||||
local function Tree_OnSizeChanged(frame)
|
local function Tree_OnSizeChanged()
|
||||||
frame.obj:RefreshTree()
|
this.obj:RefreshTree()
|
||||||
end
|
end
|
||||||
|
|
||||||
local function Tree_OnMouseWheel(frame, delta)
|
local function Tree_OnMouseWheel()
|
||||||
local self = frame.obj
|
local self = this.obj
|
||||||
if self.showscroll then
|
if self.showscroll then
|
||||||
local scrollbar = self.scrollbar
|
local scrollbar = self.scrollbar
|
||||||
local min, max = scrollbar:GetMinMaxValues()
|
local min, max = scrollbar:GetMinMaxValues()
|
||||||
local value = scrollbar:GetValue()
|
local value = scrollbar:GetValue()
|
||||||
local newvalue = math_min(max,math_max(min,value - delta))
|
local newvalue = math_min(max,math_max(min,value - arg1))
|
||||||
if value ~= newvalue then
|
if value ~= newvalue then
|
||||||
scrollbar:SetValue(newvalue)
|
scrollbar:SetValue(newvalue)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function Dragger_OnLeave(frame)
|
local function Dragger_OnLeave()
|
||||||
frame:SetBackdropColor(1, 1, 1, 0)
|
this:SetBackdropColor(1, 1, 1, 0)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function Dragger_OnEnter(frame)
|
local function Dragger_OnEnter()
|
||||||
frame:SetBackdropColor(1, 1, 1, 0.8)
|
this:SetBackdropColor(1, 1, 1, 0.8)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function Dragger_OnMouseDown(frame)
|
local function Dragger_OnMouseDown()
|
||||||
local treeframe = frame:GetParent()
|
local treeframe = this:GetParent()
|
||||||
treeframe:StartSizing("RIGHT")
|
treeframe:StartSizing("RIGHT")
|
||||||
end
|
end
|
||||||
|
|
||||||
local function Dragger_OnMouseUp(frame)
|
local function Dragger_OnMouseUp()
|
||||||
local treeframe = frame:GetParent()
|
local treeframe = this:GetParent()
|
||||||
local self = treeframe.obj
|
local self = treeframe.obj
|
||||||
local frame = treeframe:GetParent()
|
local this = treeframe:GetParent()
|
||||||
treeframe:StopMovingOrSizing()
|
treeframe:StopMovingOrSizing()
|
||||||
--treeframe:SetScript("OnUpdate", nil)
|
--treeframe:SetScript("OnUpdate", nil)
|
||||||
treeframe:SetUserPlaced(false)
|
treeframe:SetUserPlaced(false)
|
||||||
--Without this :GetHeight will get stuck on the current height, causing the tree contents to not resize
|
--Without this :GetHeight will get stuck on the current height, causing the tree contents to not resize
|
||||||
treeframe:SetHeight(0)
|
treeframe:SetHeight(0)
|
||||||
treeframe:SetPoint("TOPLEFT", frame, "TOPLEFT",0,0)
|
treeframe:SetPoint("TOPLEFT", this, "TOPLEFT",0,0)
|
||||||
treeframe:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT",0,0)
|
treeframe:SetPoint("BOTTOMLEFT", this, "BOTTOMLEFT",0,0)
|
||||||
|
|
||||||
local status = self.status or self.localstatus
|
local status = self.status or self.localstatus
|
||||||
status.treewidth = treeframe:GetWidth()
|
status.treewidth = treeframe:GetWidth()
|
||||||
|
|
||||||
treeframe.obj:Fire("OnTreeResize",treeframe:GetWidth())
|
treeframe.obj:Fire("OnTreeResize", 1, treeframe:GetWidth())
|
||||||
-- recalculate the content width
|
-- recalculate the content width
|
||||||
treeframe.obj:OnWidthSet(status.fullwidth)
|
treeframe.obj:OnWidthSet(status.fullwidth)
|
||||||
-- update the layout of the content
|
-- update the layout of the content
|
||||||
@@ -293,7 +306,10 @@ end
|
|||||||
--[[-----------------------------------------------------------------------------
|
--[[-----------------------------------------------------------------------------
|
||||||
Methods
|
Methods
|
||||||
-------------------------------------------------------------------------------]]
|
-------------------------------------------------------------------------------]]
|
||||||
local methods = {
|
local methods
|
||||||
|
do
|
||||||
|
local select_args = {nil,nil,nil,nil,nil,nil,nil,nil,nil,nil}
|
||||||
|
methods = {
|
||||||
["OnAcquire"] = function(self)
|
["OnAcquire"] = function(self)
|
||||||
self:SetTreeWidth(DEFAULT_TREE_WIDTH, DEFAULT_TREE_SIZABLE)
|
self:SetTreeWidth(DEFAULT_TREE_WIDTH, DEFAULT_TREE_SIZABLE)
|
||||||
self:EnableButtonTooltips(true)
|
self:EnableButtonTooltips(true)
|
||||||
@@ -322,8 +338,39 @@ local methods = {
|
|||||||
|
|
||||||
["CreateButton"] = function(self)
|
["CreateButton"] = function(self)
|
||||||
local num = AceGUI:GetNextWidgetNum("TreeGroupButton")
|
local num = AceGUI:GetNextWidgetNum("TreeGroupButton")
|
||||||
local button = CreateFrame("Button", format("AceGUI30TreeButton%d", num), self.treeframe, "OptionsListButtonTemplate")
|
|
||||||
|
local button = CreateFrame("Button", strfmt("AceGUI30TreeButton%d", num), self.treeframe)
|
||||||
button.obj = self
|
button.obj = self
|
||||||
|
button:SetWidth(175)
|
||||||
|
button:SetHeight(18)
|
||||||
|
|
||||||
|
local toggle = CreateFrame("Button", nil, button)
|
||||||
|
toggle.obj = button
|
||||||
|
button.toggle = toggle
|
||||||
|
toggle:SetWidth(14)
|
||||||
|
toggle:SetHeight(14)
|
||||||
|
toggle:ClearAllPoints()
|
||||||
|
toggle:SetPoint("TOPRIGHT", button, "TOPRIGHT", -6, -1)
|
||||||
|
toggle:SetScript("OnClick", Button_OnClick)
|
||||||
|
toggle:SetNormalTexture("Interface\\Buttons\\UI-MinusButton-UP")
|
||||||
|
toggle:SetPushedTexture("Interface\\Buttons\\UI-MinusButton-DOWN")
|
||||||
|
toggle:SetHighlightTexture("Interface\Buttons\UI-PlusButton-Hilight", "ADD")
|
||||||
|
|
||||||
|
local text = button:CreateFontString()
|
||||||
|
button.text = text
|
||||||
|
text:SetFontObject(GameFontNormal)
|
||||||
|
button:SetHighlightFontObject(GameFontHighlight)
|
||||||
|
text:SetPoint("RIGHT", toggle, "LEFT", -2, 0);
|
||||||
|
text:SetJustifyH("LEFT")
|
||||||
|
|
||||||
|
local highlight = button:CreateTexture(nil, "HIGHLIGHT");
|
||||||
|
button.highlight = highlight
|
||||||
|
highlight:SetTexture("Interface\\QuestFrame\\UI-QuestLogTitleHighlight")
|
||||||
|
highlight:SetBlendMode("ADD")
|
||||||
|
highlight:SetVertexColor(.196, .388, .8);
|
||||||
|
highlight:ClearAllPoints()
|
||||||
|
highlight:SetPoint("TOPLEFT",0,1)
|
||||||
|
highlight:SetPoint("BOTTOMRIGHT",0,1)
|
||||||
|
|
||||||
local icon = button:CreateTexture(nil, "OVERLAY")
|
local icon = button:CreateTexture(nil, "OVERLAY")
|
||||||
icon:SetWidth(14)
|
icon:SetWidth(14)
|
||||||
@@ -506,25 +553,34 @@ local methods = {
|
|||||||
local status = self.status or self.localstatus
|
local status = self.status or self.localstatus
|
||||||
if status.selected ~= value then
|
if status.selected ~= value then
|
||||||
status.selected = value
|
status.selected = value
|
||||||
self:Fire("OnGroupSelected", value)
|
self:Fire("OnGroupSelected", 1, value)
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
|
||||||
["Select"] = function(self, uniquevalue, ...)
|
["Select"] = function(self, uniquevalue, a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||||
self.filter = false
|
self.filter = false
|
||||||
local status = self.status or self.localstatus
|
local status = self.status or self.localstatus
|
||||||
local groups = status.groups
|
local groups = status.groups
|
||||||
local path = {unpack(arg)}
|
select_args[1] = a1
|
||||||
for i = 1, tgetn(path) do
|
select_args[2] = a2
|
||||||
groups[tconcat(path, "\001", 1, i)] = true
|
select_args[3] = a3
|
||||||
|
select_args[4] = a4
|
||||||
|
select_args[5] = a5
|
||||||
|
select_args[6] = a6
|
||||||
|
select_args[7] = a7
|
||||||
|
select_args[8] = a8
|
||||||
|
select_args[9] = a9
|
||||||
|
select_args[10] = a10
|
||||||
|
for i = 1, tgetn(select_args) do
|
||||||
|
groups[tconcat(select_args, "\001", 1, i)] = true
|
||||||
end
|
end
|
||||||
status.selected = uniquevalue
|
status.selected = uniquevalue
|
||||||
self:RefreshTree(true)
|
self:RefreshTree(true)
|
||||||
self:Fire("OnGroupSelected", uniquevalue)
|
self:Fire("OnGroupSelected", 1, uniquevalue)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
["SelectByPath"] = function(self, ...)
|
["SelectByPath"] = function(self, a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||||
self:Select(BuildUniqueValue(unpack(arg)), unpack(arg))
|
self:Select(BuildUniqueValue(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10), a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
["SelectByValue"] = function(self, uniquevalue)
|
["SelectByValue"] = function(self, uniquevalue)
|
||||||
@@ -612,6 +668,7 @@ local methods = {
|
|||||||
self:SetHeight((height or 0) + 20)
|
self:SetHeight((height or 0) + 20)
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
end -- method
|
||||||
|
|
||||||
--[[-----------------------------------------------------------------------------
|
--[[-----------------------------------------------------------------------------
|
||||||
Constructor
|
Constructor
|
||||||
@@ -635,8 +692,8 @@ local function Constructor()
|
|||||||
local frame = CreateFrame("Frame", nil, UIParent)
|
local frame = CreateFrame("Frame", nil, UIParent)
|
||||||
|
|
||||||
local treeframe = CreateFrame("Frame", nil, frame)
|
local treeframe = CreateFrame("Frame", nil, frame)
|
||||||
treeframe:SetPoint("TOPLEFT")
|
treeframe:SetPoint("TOPLEFT", 0, 0)
|
||||||
treeframe:SetPoint("BOTTOMLEFT")
|
treeframe:SetPoint("BOTTOMLEFT", 0, 0)
|
||||||
treeframe:SetWidth(DEFAULT_TREE_WIDTH)
|
treeframe:SetWidth(DEFAULT_TREE_WIDTH)
|
||||||
treeframe:EnableMouseWheel(true)
|
treeframe:EnableMouseWheel(true)
|
||||||
treeframe:SetBackdrop(PaneBackdrop)
|
treeframe:SetBackdrop(PaneBackdrop)
|
||||||
@@ -660,7 +717,7 @@ local function Constructor()
|
|||||||
dragger:SetScript("OnMouseDown", Dragger_OnMouseDown)
|
dragger:SetScript("OnMouseDown", Dragger_OnMouseDown)
|
||||||
dragger:SetScript("OnMouseUp", Dragger_OnMouseUp)
|
dragger:SetScript("OnMouseUp", Dragger_OnMouseUp)
|
||||||
|
|
||||||
local scrollbar = CreateFrame("Slider", format("AceConfigDialogTreeGroup%dScrollBar", num), treeframe, "UIPanelScrollBarTemplate")
|
local scrollbar = CreateFrame("Slider", strfmt("AceConfigDialogTreeGroup%dScrollBar", num), treeframe, "UIPanelScrollBarTemplate")
|
||||||
scrollbar:SetScript("OnValueChanged", nil)
|
scrollbar:SetScript("OnValueChanged", nil)
|
||||||
scrollbar:SetPoint("TOPRIGHT", -10, -26)
|
scrollbar:SetPoint("TOPRIGHT", -10, -26)
|
||||||
scrollbar:SetPoint("BOTTOMRIGHT", -10, 26)
|
scrollbar:SetPoint("BOTTOMRIGHT", -10, 26)
|
||||||
@@ -676,7 +733,7 @@ local function Constructor()
|
|||||||
|
|
||||||
local border = CreateFrame("Frame",nil,frame)
|
local border = CreateFrame("Frame",nil,frame)
|
||||||
border:SetPoint("TOPLEFT", treeframe, "TOPRIGHT")
|
border:SetPoint("TOPLEFT", treeframe, "TOPRIGHT")
|
||||||
border:SetPoint("BOTTOMRIGHT")
|
border:SetPoint("BOTTOMRIGHT", 0, 0)
|
||||||
border:SetBackdrop(PaneBackdrop)
|
border:SetBackdrop(PaneBackdrop)
|
||||||
border:SetBackdropColor(0.1, 0.1, 0.1, 0.5)
|
border:SetBackdropColor(0.1, 0.1, 0.1, 0.5)
|
||||||
border:SetBackdropBorderColor(0.4, 0.4, 0.4)
|
border:SetBackdropBorderColor(0.4, 0.4, 0.4)
|
||||||
|
|||||||
@@ -21,31 +21,27 @@ local CreateFrame, UIParent = CreateFrame, UIParent
|
|||||||
]]
|
]]
|
||||||
do
|
do
|
||||||
local Type = "Window"
|
local Type = "Window"
|
||||||
local Version = 6
|
local Version = 4
|
||||||
|
|
||||||
local function frameOnShow(this)
|
local function frameOnClose()
|
||||||
this.obj:Fire("OnShow")
|
|
||||||
end
|
|
||||||
|
|
||||||
local function frameOnClose(this)
|
|
||||||
this.obj:Fire("OnClose")
|
this.obj:Fire("OnClose")
|
||||||
end
|
end
|
||||||
|
|
||||||
local function closeOnClick(this)
|
local function closeOnClick()
|
||||||
PlaySound("gsTitleOptionExit")
|
PlaySound("gsTitleOptionExit")
|
||||||
this.obj:Hide()
|
this.obj:Hide()
|
||||||
end
|
end
|
||||||
|
|
||||||
local function frameOnMouseDown(this)
|
local function frameOnMouseDown()
|
||||||
AceGUI:ClearFocus()
|
AceGUI:ClearFocus()
|
||||||
end
|
end
|
||||||
|
|
||||||
local function titleOnMouseDown(this)
|
local function titleOnMouseDown()
|
||||||
this:GetParent():StartMoving()
|
this:GetParent():StartMoving()
|
||||||
AceGUI:ClearFocus()
|
AceGUI:ClearFocus()
|
||||||
end
|
end
|
||||||
|
|
||||||
local function frameOnMouseUp(this)
|
local function frameOnMouseUp()
|
||||||
local frame = this:GetParent()
|
local frame = this:GetParent()
|
||||||
frame:StopMovingOrSizing()
|
frame:StopMovingOrSizing()
|
||||||
local self = frame.obj
|
local self = frame.obj
|
||||||
@@ -56,22 +52,22 @@ do
|
|||||||
status.left = frame:GetLeft()
|
status.left = frame:GetLeft()
|
||||||
end
|
end
|
||||||
|
|
||||||
local function sizerseOnMouseDown(this)
|
local function sizerseOnMouseDown()
|
||||||
this:GetParent():StartSizing("BOTTOMRIGHT")
|
this:GetParent():StartSizing("BOTTOMRIGHT")
|
||||||
AceGUI:ClearFocus()
|
AceGUI:ClearFocus()
|
||||||
end
|
end
|
||||||
|
|
||||||
local function sizersOnMouseDown(this)
|
local function sizersOnMouseDown()
|
||||||
this:GetParent():StartSizing("BOTTOM")
|
this:GetParent():StartSizing("BOTTOM")
|
||||||
AceGUI:ClearFocus()
|
AceGUI:ClearFocus()
|
||||||
end
|
end
|
||||||
|
|
||||||
local function sizereOnMouseDown(this)
|
local function sizereOnMouseDown()
|
||||||
this:GetParent():StartSizing("RIGHT")
|
this:GetParent():StartSizing("RIGHT")
|
||||||
AceGUI:ClearFocus()
|
AceGUI:ClearFocus()
|
||||||
end
|
end
|
||||||
|
|
||||||
local function sizerOnMouseUp(this)
|
local function sizerOnMouseUp()
|
||||||
this:GetParent():StopMovingOrSizing()
|
this:GetParent():StopMovingOrSizing()
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -184,7 +180,6 @@ do
|
|||||||
frame:SetFrameStrata("FULLSCREEN_DIALOG")
|
frame:SetFrameStrata("FULLSCREEN_DIALOG")
|
||||||
frame:SetScript("OnMouseDown", frameOnMouseDown)
|
frame:SetScript("OnMouseDown", frameOnMouseDown)
|
||||||
|
|
||||||
frame:SetScript("OnShow",frameOnShow)
|
|
||||||
frame:SetScript("OnHide",frameOnClose)
|
frame:SetScript("OnHide",frameOnClose)
|
||||||
frame:SetMinResize(240,240)
|
frame:SetMinResize(240,240)
|
||||||
frame:SetToplevel(true)
|
frame:SetToplevel(true)
|
||||||
|
|||||||
@@ -2,24 +2,27 @@
|
|||||||
Button Widget
|
Button Widget
|
||||||
Graphical Button.
|
Graphical Button.
|
||||||
-------------------------------------------------------------------------------]]
|
-------------------------------------------------------------------------------]]
|
||||||
local Type, Version = "Button", 24
|
local Type, Version = "Button", 23
|
||||||
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
||||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||||
|
|
||||||
|
local AceCore = LibStub("AceCore-3.0")
|
||||||
|
|
||||||
-- Lua APIs
|
-- Lua APIs
|
||||||
local pairs, unpack = pairs, unpack
|
local pairs = pairs
|
||||||
|
|
||||||
-- WoW APIs
|
-- WoW APIs
|
||||||
local _G = _G
|
local _G = AceCore._G
|
||||||
local PlaySound, CreateFrame, UIParent = PlaySound, CreateFrame, UIParent
|
local PlaySound, CreateFrame, UIParent = PlaySound, CreateFrame, UIParent
|
||||||
|
|
||||||
--[[-----------------------------------------------------------------------------
|
--[[-----------------------------------------------------------------------------
|
||||||
Scripts
|
Scripts
|
||||||
-------------------------------------------------------------------------------]]
|
-------------------------------------------------------------------------------]]
|
||||||
|
-- arg1 is the button for OnClick event
|
||||||
local function Button_OnClick()
|
local function Button_OnClick()
|
||||||
AceGUI:ClearFocus()
|
AceGUI:ClearFocus()
|
||||||
PlaySound("igMainMenuOption")
|
PlaySound("igMainMenuOption")
|
||||||
this.obj:Fire("OnClick", unpack(arg))
|
this.obj:Fire("OnClick", 1, arg1)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function Control_OnEnter()
|
local function Control_OnEnter()
|
||||||
@@ -74,7 +77,7 @@ Constructor
|
|||||||
-------------------------------------------------------------------------------]]
|
-------------------------------------------------------------------------------]]
|
||||||
local function Constructor()
|
local function Constructor()
|
||||||
local name = "AceGUI30Button" .. AceGUI:GetNextWidgetNum(Type)
|
local name = "AceGUI30Button" .. AceGUI:GetNextWidgetNum(Type)
|
||||||
local frame = CreateFrame("Button", name, UIParent, "UIPanelButtonTemplate")
|
local frame = CreateFrame("Button", name, UIParent, "UIPanelButtonTemplate2")
|
||||||
frame:Hide()
|
frame:Hide()
|
||||||
|
|
||||||
frame:EnableMouse(true)
|
frame:EnableMouse(true)
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
--[[-----------------------------------------------------------------------------
|
--[[-----------------------------------------------------------------------------
|
||||||
Checkbox Widget
|
Checkbox Widget
|
||||||
-------------------------------------------------------------------------------]]
|
-------------------------------------------------------------------------------]]
|
||||||
local Type, Version = "CheckBox", 23
|
local Type, Version = "CheckBox", 22
|
||||||
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
||||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||||
|
|
||||||
-- Lua APIs
|
-- Lua APIs
|
||||||
local select, pairs, unpack = select, pairs, unpack
|
local pairs = pairs
|
||||||
|
|
||||||
-- WoW APIs
|
-- WoW APIs
|
||||||
local PlaySound = PlaySound
|
local PlaySound = PlaySound
|
||||||
@@ -55,6 +55,7 @@ local function CheckBox_OnMouseDown()
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function CheckBox_OnMouseUp()
|
local function CheckBox_OnMouseUp()
|
||||||
|
|
||||||
local self = this.obj
|
local self = this.obj
|
||||||
if not self.disabled then
|
if not self.disabled then
|
||||||
self:ToggleChecked()
|
self:ToggleChecked()
|
||||||
@@ -65,7 +66,7 @@ local function CheckBox_OnMouseUp()
|
|||||||
PlaySound("igMainMenuOptionCheckBoxOff")
|
PlaySound("igMainMenuOptionCheckBoxOff")
|
||||||
end
|
end
|
||||||
|
|
||||||
self:Fire("OnValueChanged", self.checked)
|
self:Fire("OnValueChanged", 1, self.checked)
|
||||||
AlignImage(self)
|
AlignImage(self)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -172,6 +173,7 @@ local methods = {
|
|||||||
highlight:SetTexture("Interface\\Buttons\\UI-CheckBox-Highlight")
|
highlight:SetTexture("Interface\\Buttons\\UI-CheckBox-Highlight")
|
||||||
highlight:SetTexCoord(0, 1, 0, 1)
|
highlight:SetTexCoord(0, 1, 0, 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
checkbg:SetHeight(size)
|
checkbg:SetHeight(size)
|
||||||
checkbg:SetWidth(size)
|
checkbg:SetWidth(size)
|
||||||
end,
|
end,
|
||||||
@@ -221,14 +223,13 @@ local methods = {
|
|||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
|
||||||
["SetImage"] = function(self, path, ...)
|
["SetImage"] = function(self, path, a1,a2,a3,a4,a5,a6,a7,a8)
|
||||||
local image = self.image
|
local image = self.image
|
||||||
image:SetTexture(path)
|
image:SetTexture(path)
|
||||||
|
|
||||||
if image:GetTexture() then
|
if image:GetTexture() then
|
||||||
local n = select("#", arg)
|
if a4 or a8 then
|
||||||
if n == 4 or n == 8 then
|
image:SetTexCoord(a1,a2,a3,a4,a5,a6,a7,a8)
|
||||||
image:SetTexCoord(unpack(arg))
|
|
||||||
else
|
else
|
||||||
image:SetTexCoord(0, 1, 0, 1)
|
image:SetTexCoord(0, 1, 0, 1)
|
||||||
end
|
end
|
||||||
@@ -261,7 +262,7 @@ local function Constructor()
|
|||||||
check:SetTexture("Interface\\Buttons\\UI-CheckBox-Check")
|
check:SetTexture("Interface\\Buttons\\UI-CheckBox-Check")
|
||||||
|
|
||||||
local text = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
|
local text = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
|
||||||
text:SetJustifyH("LEFT", 0, 0)
|
text:SetJustifyH("LEFT")
|
||||||
text:SetHeight(18)
|
text:SetHeight(18)
|
||||||
text:SetPoint("LEFT", checkbg, "RIGHT")
|
text:SetPoint("LEFT", checkbg, "RIGHT")
|
||||||
text:SetPoint("RIGHT",0,0)
|
text:SetPoint("RIGHT",0,0)
|
||||||
|
|||||||
+13
-26
@@ -1,7 +1,7 @@
|
|||||||
--[[-----------------------------------------------------------------------------
|
--[[-----------------------------------------------------------------------------
|
||||||
ColorPicker Widget
|
ColorPicker Widget
|
||||||
-------------------------------------------------------------------------------]]
|
-------------------------------------------------------------------------------]]
|
||||||
local Type, Version = "ColorPicker-ElvUI", 1
|
local Type, Version = "ColorPicker", 23
|
||||||
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
||||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||||
|
|
||||||
@@ -25,12 +25,12 @@ local function ColorCallback(self, r, g, b, a, isAlpha)
|
|||||||
self:SetColor(r, g, b, a)
|
self:SetColor(r, g, b, a)
|
||||||
if ColorPickerFrame:IsVisible() then
|
if ColorPickerFrame:IsVisible() then
|
||||||
--colorpicker is still open
|
--colorpicker is still open
|
||||||
self:Fire("OnValueChanged", r, g, b, a)
|
self:Fire("OnValueChanged", 4, r, g, b, a)
|
||||||
else
|
else
|
||||||
--colorpicker is closed, color callback is first, ignore it,
|
--colorpicker is closed, color callback is first, ignore it,
|
||||||
--alpha callback is the final call after it closes so confirm now
|
--alpha callback is the final call after it closes so confirm now
|
||||||
if isAlpha then
|
if isAlpha then
|
||||||
self:Fire("OnValueConfirmed", r, g, b, a)
|
self:Fire("OnValueConfirmed", 4, r, g, b, a)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -38,20 +38,19 @@ end
|
|||||||
--[[-----------------------------------------------------------------------------
|
--[[-----------------------------------------------------------------------------
|
||||||
Scripts
|
Scripts
|
||||||
-------------------------------------------------------------------------------]]
|
-------------------------------------------------------------------------------]]
|
||||||
local function Control_OnEnter(frame)
|
local function Control_OnEnter()
|
||||||
frame.obj:Fire("OnEnter")
|
this.obj:Fire("OnEnter")
|
||||||
end
|
end
|
||||||
|
|
||||||
local function Control_OnLeave(frame)
|
local function Control_OnLeave()
|
||||||
frame.obj:Fire("OnLeave")
|
this.obj:Fire("OnLeave")
|
||||||
end
|
end
|
||||||
|
|
||||||
local function ColorSwatch_OnClick(frame)
|
local function ColorSwatch_OnClick()
|
||||||
HideUIPanel(ColorPickerFrame)
|
HideUIPanel(ColorPickerFrame)
|
||||||
local self = frame.obj
|
local self = this.obj
|
||||||
if not self.disabled then
|
if not self.disabled then
|
||||||
ColorPickerFrame:SetFrameStrata("FULLSCREEN_DIALOG")
|
ColorPickerFrame:SetFrameStrata("FULLSCREEN_DIALOG")
|
||||||
ColorPickerFrame:SetFrameLevel(frame:GetFrameLevel() + 10)
|
|
||||||
ColorPickerFrame:SetClampedToScreen(true)
|
ColorPickerFrame:SetClampedToScreen(true)
|
||||||
|
|
||||||
ColorPickerFrame.func = function()
|
ColorPickerFrame.func = function()
|
||||||
@@ -67,20 +66,12 @@ local function ColorSwatch_OnClick(frame)
|
|||||||
ColorCallback(self, r, g, b, a, true)
|
ColorCallback(self, r, g, b, a, true)
|
||||||
end
|
end
|
||||||
|
|
||||||
local r, g, b, a, dR, dG, dB, dA = self.r, self.g, self.b, self.a, self.dR, self.dG, self.dB, self.dA
|
local r, g, b, a = self.r, self.g, self.b, self.a
|
||||||
if self.HasAlpha then
|
if self.HasAlpha then
|
||||||
ColorPickerFrame.opacity = 1 - (a or 0)
|
ColorPickerFrame.opacity = 1 - (a or 0)
|
||||||
end
|
end
|
||||||
ColorPickerFrame:SetColorRGB(r, g, b)
|
ColorPickerFrame:SetColorRGB(r, g, b)
|
||||||
|
|
||||||
if(ColorPPDefault and self.dR and self.dG and self.dB) then
|
|
||||||
local alpha = 1
|
|
||||||
if(self.dA) then
|
|
||||||
alpha = 1 - self.dA
|
|
||||||
end
|
|
||||||
ColorPPDefault.colors = {r = self.dR, g = self.dG, b = self.dB, a = alpha}
|
|
||||||
end
|
|
||||||
|
|
||||||
ColorPickerFrame.cancelFunc = function()
|
ColorPickerFrame.cancelFunc = function()
|
||||||
ColorCallback(self, r, g, b, a, true)
|
ColorCallback(self, r, g, b, a, true)
|
||||||
end
|
end
|
||||||
@@ -109,15 +100,11 @@ local methods = {
|
|||||||
self.text:SetText(text)
|
self.text:SetText(text)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
["SetColor"] = function(self, r, g, b, a, defaultR, defaultG, defaultB, defaultA)
|
["SetColor"] = function(self, r, g, b, a)
|
||||||
self.r = r
|
self.r = r
|
||||||
self.g = g
|
self.g = g
|
||||||
self.b = b
|
self.b = b
|
||||||
self.a = a or 1
|
self.a = a or 1
|
||||||
self.dR = defaultR
|
|
||||||
self.dG = defaultG
|
|
||||||
self.dB = defaultB
|
|
||||||
self.dA = defaultA
|
|
||||||
self.colorSwatch:SetVertexColor(r, g, b, a)
|
self.colorSwatch:SetVertexColor(r, g, b, a)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
@@ -153,7 +140,7 @@ local function Constructor()
|
|||||||
colorSwatch:SetWidth(19)
|
colorSwatch:SetWidth(19)
|
||||||
colorSwatch:SetHeight(19)
|
colorSwatch:SetHeight(19)
|
||||||
colorSwatch:SetTexture("Interface\\ChatFrame\\ChatFrameColorSwatch")
|
colorSwatch:SetTexture("Interface\\ChatFrame\\ChatFrameColorSwatch")
|
||||||
colorSwatch:SetPoint("LEFT")
|
colorSwatch:SetPoint("LEFT",0,0)
|
||||||
|
|
||||||
local texture = frame:CreateTexture(nil, "BACKGROUND")
|
local texture = frame:CreateTexture(nil, "BACKGROUND")
|
||||||
texture:SetWidth(16)
|
texture:SetWidth(16)
|
||||||
@@ -177,7 +164,7 @@ local function Constructor()
|
|||||||
text:SetJustifyH("LEFT")
|
text:SetJustifyH("LEFT")
|
||||||
text:SetTextColor(1, 1, 1)
|
text:SetTextColor(1, 1, 1)
|
||||||
text:SetPoint("LEFT", colorSwatch, "RIGHT", 2, 0)
|
text:SetPoint("LEFT", colorSwatch, "RIGHT", 2, 0)
|
||||||
text:SetPoint("RIGHT")
|
text:SetPoint("RIGHT",0,0)
|
||||||
|
|
||||||
--local highlight = frame:CreateTexture(nil, "HIGHLIGHT")
|
--local highlight = frame:CreateTexture(nil, "HIGHLIGHT")
|
||||||
--highlight:SetTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight")
|
--highlight:SetTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight")
|
||||||
|
|||||||
+22
-36
@@ -1,35 +1,19 @@
|
|||||||
--[[ $Id: AceGUIWidget-DropDown-Items.lua 1153 2016-11-20 09:57:15Z nevcairiel $ ]]--
|
--[[ $Id: AceGUIWidget-DropDown-Items.lua 1137 2016-05-15 10:57:36Z nevcairiel $ ]]--
|
||||||
|
|
||||||
local AceGUI = LibStub("AceGUI-3.0")
|
local AceGUI = LibStub("AceGUI-3.0")
|
||||||
|
|
||||||
|
local IsLegion = false
|
||||||
|
|
||||||
-- Lua APIs
|
-- Lua APIs
|
||||||
local select, assert = select, assert
|
local assert = assert
|
||||||
|
local tgetn = table.getn
|
||||||
|
|
||||||
-- WoW APIs
|
-- WoW APIs
|
||||||
local PlaySound = PlaySound
|
local PlaySound = PlaySound
|
||||||
local CreateFrame = CreateFrame
|
local CreateFrame = CreateFrame
|
||||||
|
|
||||||
local function fixlevels(parent,...)
|
local fixlevels = AceGUI.fixlevels
|
||||||
local i = 1
|
local fixstrata = AceGUI.fixstrata
|
||||||
local child = select(i, arg)
|
|
||||||
while child do
|
|
||||||
child:SetFrameLevel(parent:GetFrameLevel()+1)
|
|
||||||
fixlevels(child, child:GetChildren())
|
|
||||||
i = i + 1
|
|
||||||
child = select(i, arg)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function fixstrata(strata, parent, ...)
|
|
||||||
local i = 1
|
|
||||||
local child = select(i, arg)
|
|
||||||
parent:SetFrameStrata(strata)
|
|
||||||
while child do
|
|
||||||
fixstrata(strata, child, child:GetChildren())
|
|
||||||
i = i + 1
|
|
||||||
child = select(i, arg)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- ItemBase is the base "class" for all dropdown items.
|
-- ItemBase is the base "class" for all dropdown items.
|
||||||
-- Each item has to use ItemBase.Create(widgetType) to
|
-- Each item has to use ItemBase.Create(widgetType) to
|
||||||
@@ -45,7 +29,7 @@ local ItemBase = {
|
|||||||
counter = 0,
|
counter = 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
function ItemBase.Frame_OnEnter(this)
|
function ItemBase.Frame_OnEnter()
|
||||||
local self = this.obj
|
local self = this.obj
|
||||||
|
|
||||||
if self.useHighlight then
|
if self.useHighlight then
|
||||||
@@ -58,7 +42,7 @@ function ItemBase.Frame_OnEnter(this)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function ItemBase.Frame_OnLeave(this)
|
function ItemBase.Frame_OnLeave()
|
||||||
local self = this.obj
|
local self = this.obj
|
||||||
|
|
||||||
self.highlight:Hide()
|
self.highlight:Hide()
|
||||||
@@ -91,9 +75,10 @@ function ItemBase.SetPullout(self, pullout)
|
|||||||
self.pullout = pullout
|
self.pullout = pullout
|
||||||
|
|
||||||
self.frame:SetParent(nil)
|
self.frame:SetParent(nil)
|
||||||
self.frame:SetParent(pullout.itemFrame)
|
local itemFrame = pullout.itemFrame
|
||||||
self.parent = pullout.itemFrame
|
self.frame:SetParent(itemFrame)
|
||||||
fixlevels(pullout.itemFrame, pullout.itemFrame:GetChildren())
|
self.parent = itemFrame
|
||||||
|
fixlevels(itemFrame)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- exported
|
-- exported
|
||||||
@@ -107,8 +92,8 @@ function ItemBase.GetText(self)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- exported
|
-- exported
|
||||||
function ItemBase.SetPoint(self, ...)
|
function ItemBase.SetPoint(self, a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||||
self.frame:SetPoint(unpack(arg))
|
self.frame:SetPoint(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- exported
|
-- exported
|
||||||
@@ -257,7 +242,7 @@ do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function OnLeave(this)
|
local function OnLeave()
|
||||||
local self = this.obj
|
local self = this.obj
|
||||||
self:Fire("OnLeave")
|
self:Fire("OnLeave")
|
||||||
|
|
||||||
@@ -323,7 +308,7 @@ end
|
|||||||
-- Does not close the pullout on click.
|
-- Does not close the pullout on click.
|
||||||
do
|
do
|
||||||
local widgetType = "Dropdown-Item-Toggle"
|
local widgetType = "Dropdown-Item-Toggle"
|
||||||
local widgetVersion = 4
|
local widgetVersion = 3
|
||||||
|
|
||||||
local function UpdateToggle(self)
|
local function UpdateToggle(self)
|
||||||
if self.value then
|
if self.value then
|
||||||
@@ -338,7 +323,7 @@ do
|
|||||||
self:SetValue(nil)
|
self:SetValue(nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function Frame_OnClick(this, button)
|
local function Frame_OnClick()
|
||||||
local self = this.obj
|
local self = this.obj
|
||||||
if self.disabled then return end
|
if self.disabled then return end
|
||||||
self.value = not self.value
|
self.value = not self.value
|
||||||
@@ -348,7 +333,7 @@ do
|
|||||||
PlaySound("igMainMenuOptionCheckBoxOff")
|
PlaySound("igMainMenuOptionCheckBoxOff")
|
||||||
end
|
end
|
||||||
UpdateToggle(self)
|
UpdateToggle(self)
|
||||||
self:Fire("OnValueChanged", self.value)
|
self:Fire("OnValueChanged", 1, self.value)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- exported
|
-- exported
|
||||||
@@ -385,7 +370,7 @@ do
|
|||||||
local widgetType = "Dropdown-Item-Menu"
|
local widgetType = "Dropdown-Item-Menu"
|
||||||
local widgetVersion = 2
|
local widgetVersion = 2
|
||||||
|
|
||||||
local function OnEnter(this)
|
local function OnEnter()
|
||||||
local self = this.obj
|
local self = this.obj
|
||||||
self:Fire("OnEnter")
|
self:Fire("OnEnter")
|
||||||
|
|
||||||
@@ -400,7 +385,7 @@ do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function OnHide(this)
|
local function OnHide()
|
||||||
local self = this.obj
|
local self = this.obj
|
||||||
if self.submenu then
|
if self.submenu then
|
||||||
self.submenu:Close()
|
self.submenu:Close()
|
||||||
@@ -456,6 +441,7 @@ do
|
|||||||
local line = self.frame:CreateTexture(nil, "OVERLAY")
|
local line = self.frame:CreateTexture(nil, "OVERLAY")
|
||||||
line:SetHeight(1)
|
line:SetHeight(1)
|
||||||
line:SetTexture(.5, .5, .5)
|
line:SetTexture(.5, .5, .5)
|
||||||
|
|
||||||
line:SetPoint("LEFT", self.frame, "LEFT", 10, 0)
|
line:SetPoint("LEFT", self.frame, "LEFT", 10, 0)
|
||||||
line:SetPoint("RIGHT", self.frame, "RIGHT", -10, 0)
|
line:SetPoint("RIGHT", self.frame, "RIGHT", -10, 0)
|
||||||
|
|
||||||
|
|||||||
@@ -1,41 +1,24 @@
|
|||||||
--[[ $Id: AceGUIWidget-DropDown.lua 1116 2014-10-12 08:15:46Z nevcairiel $ ]]--
|
--[[ $Id: AceGUIWidget-DropDown.lua 1116 2014-10-12 08:15:46Z nevcairiel $ ]]--
|
||||||
local AceGUI = LibStub("AceGUI-3.0")
|
local AceGUI = LibStub("AceGUI-3.0")
|
||||||
|
|
||||||
|
local AceCore = LibStub("AceCore-3.0")
|
||||||
|
|
||||||
-- Lua APIs
|
-- Lua APIs
|
||||||
local min, max, floor = math.min, math.max, math.floor
|
local min, max, floor = math.min, math.max, math.floor
|
||||||
local select, pairs, ipairs, type = select, pairs, ipairs, type
|
local pairs, ipairs, type = pairs, ipairs, type
|
||||||
local tgetn, tsort = table.getn, table.sort
|
local tsort, tinsert, tgetn, tsetn = table.sort, table.insert, table.getn, table.setn
|
||||||
|
|
||||||
-- WoW APIs
|
-- WoW APIs
|
||||||
local PlaySound = PlaySound
|
local PlaySound = PlaySound
|
||||||
local UIParent, CreateFrame = UIParent, CreateFrame
|
local UIParent, CreateFrame = UIParent, CreateFrame
|
||||||
local _G = _G
|
local _G = AceCore._G
|
||||||
|
|
||||||
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
|
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
|
||||||
-- List them here for Mikk's FindGlobals script
|
-- List them here for Mikk's FindGlobals script
|
||||||
-- GLOBALS: CLOSE
|
-- GLOBALS: CLOSE
|
||||||
|
|
||||||
local function fixlevels(parent,...)
|
local fixlevels = AceGUI.fixlevels
|
||||||
local i = 1
|
local fixstrata = AceGUI.fixstrata
|
||||||
local child = select(i, arg)
|
|
||||||
while child do
|
|
||||||
child:SetFrameLevel(parent:GetFrameLevel()+1)
|
|
||||||
fixlevels(child, child:GetChildren())
|
|
||||||
i = i + 1
|
|
||||||
child = select(i, arg)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function fixstrata(strata, parent, ...)
|
|
||||||
local i = 1
|
|
||||||
local child = select(i, arg)
|
|
||||||
parent:SetFrameStrata(strata)
|
|
||||||
while child do
|
|
||||||
fixstrata(strata, child, child:GetChildren())
|
|
||||||
i = i + 1
|
|
||||||
child = select(i, arg)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
do
|
do
|
||||||
local widgetType = "Dropdown-Pullout"
|
local widgetType = "Dropdown-Pullout"
|
||||||
@@ -76,15 +59,15 @@ do
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- See the note in Constructor() for each scroll related function
|
-- See the note in Constructor() for each scroll related function
|
||||||
local function OnMouseWheel(this, value)
|
local function OnMouseWheel()
|
||||||
this.obj:MoveScroll(value)
|
this.obj:MoveScroll(arg1)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function OnScrollValueChanged(this, value)
|
local function OnScrollValueChanged()
|
||||||
this.obj:SetScroll(value)
|
this.obj:SetScroll(arg1)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function OnSizeChanged(this)
|
local function OnSizeChanged()
|
||||||
this.obj:FixScroll()
|
this.obj:FixScroll()
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -169,7 +152,7 @@ do
|
|||||||
|
|
||||||
-- exported
|
-- exported
|
||||||
local function AddItem(self, item)
|
local function AddItem(self, item)
|
||||||
self.items[tgetn(self.items) + 1] = item
|
tinsert(self.items, item)
|
||||||
|
|
||||||
local h = tgetn(self.items) * 16
|
local h = tgetn(self.items) * 16
|
||||||
self.itemFrame:SetHeight(h)
|
self.itemFrame:SetHeight(h)
|
||||||
@@ -204,7 +187,7 @@ do
|
|||||||
height = height + 16
|
height = height + 16
|
||||||
end
|
end
|
||||||
itemFrame:SetHeight(height)
|
itemFrame:SetHeight(height)
|
||||||
fixstrata("TOOLTIP", frame, frame:GetChildren())
|
fixstrata("TOOLTIP", frame)
|
||||||
frame:Show()
|
frame:Show()
|
||||||
self:Fire("OnOpen")
|
self:Fire("OnOpen")
|
||||||
end
|
end
|
||||||
@@ -222,6 +205,7 @@ do
|
|||||||
AceGUI:Release(item)
|
AceGUI:Release(item)
|
||||||
items[i] = nil
|
items[i] = nil
|
||||||
end
|
end
|
||||||
|
tsetn(items,0)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- exported
|
-- exported
|
||||||
@@ -356,30 +340,30 @@ end
|
|||||||
|
|
||||||
do
|
do
|
||||||
local widgetType = "Dropdown"
|
local widgetType = "Dropdown"
|
||||||
local widgetVersion = 31
|
local widgetVersion = 30
|
||||||
|
|
||||||
--[[ Static data ]]--
|
--[[ Static data ]]--
|
||||||
|
|
||||||
--[[ UI event handler ]]--
|
--[[ UI event handler ]]--
|
||||||
|
|
||||||
local function Control_OnEnter(this)
|
local function Control_OnEnter()
|
||||||
this.obj.button:LockHighlight()
|
this.obj.button:LockHighlight()
|
||||||
this.obj:Fire("OnEnter")
|
this.obj:Fire("OnEnter")
|
||||||
end
|
end
|
||||||
|
|
||||||
local function Control_OnLeave(this)
|
local function Control_OnLeave()
|
||||||
this.obj.button:UnlockHighlight()
|
this.obj.button:UnlockHighlight()
|
||||||
this.obj:Fire("OnLeave")
|
this.obj:Fire("OnLeave")
|
||||||
end
|
end
|
||||||
|
|
||||||
local function Dropdown_OnHide(this)
|
local function Dropdown_OnHide()
|
||||||
local self = this.obj
|
local self = this.obj
|
||||||
if self.open then
|
if self.open then
|
||||||
self.pullout:Close()
|
self.pullout:Close()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function Dropdown_TogglePullout(this)
|
local function Dropdown_TogglePullout()
|
||||||
local self = this.obj
|
local self = this.obj
|
||||||
PlaySound("igMainMenuOptionCheckBoxOn") -- missleading name, but the Blizzard code uses this sound
|
PlaySound("igMainMenuOptionCheckBoxOn") -- missleading name, but the Blizzard code uses this sound
|
||||||
if self.open then
|
if self.open then
|
||||||
@@ -430,17 +414,20 @@ do
|
|||||||
self:SetText(text)
|
self:SetText(text)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function OnItemValueChanged(this, event, checked)
|
local function OnItemValueChanged(this, event, _, checked)
|
||||||
local self = this.userdata.obj
|
local self = this.userdata.obj
|
||||||
|
|
||||||
if self.multiselect then
|
if self.multiselect then
|
||||||
self:Fire("OnValueChanged", this.userdata.value, checked)
|
self:Fire("OnValueChanged", 2, this.userdata.value, checked)
|
||||||
ShowMultiText(self)
|
ShowMultiText(self)
|
||||||
else
|
else
|
||||||
if checked then
|
if checked then
|
||||||
self:SetValue(this.userdata.value)
|
self:SetValue(this.userdata.value)
|
||||||
self:Fire("OnValueChanged", this.userdata.value)
|
self:Fire("OnValueChanged", 1, this.userdata.value)
|
||||||
|
this:SetValue(false)
|
||||||
else
|
else
|
||||||
|
self:SetValue(nil)
|
||||||
|
self:Fire("OnValueChanged", 1, nil)
|
||||||
this:SetValue(true)
|
this:SetValue(true)
|
||||||
end
|
end
|
||||||
if self.open then
|
if self.open then
|
||||||
@@ -459,7 +446,8 @@ do
|
|||||||
pullout:SetCallback("OnClose", OnPulloutClose)
|
pullout:SetCallback("OnClose", OnPulloutClose)
|
||||||
pullout:SetCallback("OnOpen", OnPulloutOpen)
|
pullout:SetCallback("OnOpen", OnPulloutOpen)
|
||||||
self.pullout.frame:SetFrameLevel(self.frame:GetFrameLevel() + 1)
|
self.pullout.frame:SetFrameLevel(self.frame:GetFrameLevel() + 1)
|
||||||
fixlevels(self.pullout.frame, self.pullout.frame:GetChildren())
|
local frame = self.pullout.frame
|
||||||
|
fixlevels(frame)
|
||||||
|
|
||||||
self:SetHeight(44)
|
self:SetHeight(44)
|
||||||
self:SetWidth(200)
|
self:SetWidth(200)
|
||||||
@@ -571,7 +559,7 @@ do
|
|||||||
local function AddListItem(self, value, text, itemType)
|
local function AddListItem(self, value, text, itemType)
|
||||||
if not itemType then itemType = "Dropdown-Item-Toggle" end
|
if not itemType then itemType = "Dropdown-Item-Toggle" end
|
||||||
local exists = AceGUI:GetWidgetVersion(itemType)
|
local exists = AceGUI:GetWidgetVersion(itemType)
|
||||||
if not exists then error(format("The given item type, %q, does not exist within AceGUI-3.0", tostring(itemType)), 2) end
|
if not exists then error(("The given item type, %q, does not exist within AceGUI-3.0"):format(tostring(itemType)), 2) end
|
||||||
|
|
||||||
local item = AceGUI:Create(itemType)
|
local item = AceGUI:Create(itemType)
|
||||||
item:SetText(text)
|
item:SetText(text)
|
||||||
@@ -600,7 +588,7 @@ do
|
|||||||
|
|
||||||
if type(order) ~= "table" then
|
if type(order) ~= "table" then
|
||||||
for v in pairs(list) do
|
for v in pairs(list) do
|
||||||
sortlist[tgetn(sortlist) + 1] = v
|
tinsert(sortlist, v)
|
||||||
end
|
end
|
||||||
tsort(sortlist)
|
tsort(sortlist)
|
||||||
|
|
||||||
@@ -608,6 +596,7 @@ do
|
|||||||
AddListItem(self, key, list[key], itemType)
|
AddListItem(self, key, list[key], itemType)
|
||||||
sortlist[i] = nil
|
sortlist[i] = nil
|
||||||
end
|
end
|
||||||
|
tsetn(sortlist,0)
|
||||||
else
|
else
|
||||||
for i, key in ipairs(order) do
|
for i, key in ipairs(order) do
|
||||||
AddListItem(self, key, list[key], itemType)
|
AddListItem(self, key, list[key], itemType)
|
||||||
|
|||||||
@@ -1,18 +1,23 @@
|
|||||||
--[[-----------------------------------------------------------------------------
|
--[[-----------------------------------------------------------------------------
|
||||||
EditBox Widget
|
EditBox Widget
|
||||||
-------------------------------------------------------------------------------]]
|
-------------------------------------------------------------------------------]]
|
||||||
local Type, Version = "EditBox", 27
|
local Type, Version = "EditBox", 26
|
||||||
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
||||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||||
|
|
||||||
|
local AceCore = LibStub("AceCore-3.0")
|
||||||
|
local hooksecurefunc = AceCore.hooksecurefunc
|
||||||
|
local _G = AceCore._G
|
||||||
|
local GetCursorInfo = _G.GetCursorInfo
|
||||||
|
|
||||||
-- Lua APIs
|
-- Lua APIs
|
||||||
local tostring, pairs, unpack = tostring, pairs, unpack
|
local tostring, pairs = tostring, pairs
|
||||||
|
|
||||||
-- WoW APIs
|
-- WoW APIs
|
||||||
local PlaySound = PlaySound
|
local PlaySound = PlaySound
|
||||||
local GetCursorInfo, ClearCursor, GetSpellInfo = GetCursorInfo, ClearCursor, GetSpellInfo
|
local GetCursorInfo, ClearCursor, GetSpellInfo = GetCursorInfo, ClearCursor, GetSpellInfo
|
||||||
local CreateFrame, UIParent = CreateFrame, UIParent
|
local CreateFrame, UIParent = CreateFrame, UIParent
|
||||||
local _G = _G
|
local strlen = string.len
|
||||||
|
|
||||||
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
|
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
|
||||||
-- List them here for Mikk's FindGlobals script
|
-- List them here for Mikk's FindGlobals script
|
||||||
@@ -116,7 +121,7 @@ end
|
|||||||
function _G.AceGUIEditBoxInsertLink(text)
|
function _G.AceGUIEditBoxInsertLink(text)
|
||||||
for i = 1, AceGUI:GetWidgetCount(Type) do
|
for i = 1, AceGUI:GetWidgetCount(Type) do
|
||||||
local editbox = _G["AceGUI-3.0EditBox"..i]
|
local editbox = _G["AceGUI-3.0EditBox"..i]
|
||||||
if editbox and editbox:IsVisible() and editbox:HasFocus() then
|
if editbox and editbox:IsVisible() and editbox.hasfocus then
|
||||||
editbox:Insert(text)
|
editbox:Insert(text)
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
@@ -138,73 +143,82 @@ end
|
|||||||
--[[-----------------------------------------------------------------------------
|
--[[-----------------------------------------------------------------------------
|
||||||
Scripts
|
Scripts
|
||||||
-------------------------------------------------------------------------------]]
|
-------------------------------------------------------------------------------]]
|
||||||
local function Control_OnEnter(frame)
|
local function Control_OnEnter()
|
||||||
frame.obj:Fire("OnEnter")
|
this.obj:Fire("OnEnter")
|
||||||
end
|
end
|
||||||
|
|
||||||
local function Control_OnLeave(frame)
|
local function Control_OnLeave()
|
||||||
frame.obj:Fire("OnLeave")
|
this.obj:Fire("OnLeave")
|
||||||
end
|
end
|
||||||
|
|
||||||
local function Frame_OnShowFocus(frame)
|
local function Frame_OnShowFocus()
|
||||||
frame.obj.editbox:SetFocus()
|
this.obj.editbox:SetFocus()
|
||||||
frame:SetScript("OnShow", nil)
|
this:SetScript("OnShow", nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function EditBox_OnEscapePressed(frame)
|
local function EditBox_OnEscapePressed()
|
||||||
AceGUI:ClearFocus()
|
AceGUI:ClearFocus()
|
||||||
end
|
end
|
||||||
|
|
||||||
local function EditBox_OnEnterPressed(frame)
|
local function EditBox_OnEnterPressed()
|
||||||
local self = frame.obj
|
local self = this.obj
|
||||||
local value = frame:GetText()
|
local value = this:GetText()
|
||||||
local cancel = self:Fire("OnEnterPressed", value)
|
local cancel = self:Fire("OnEnterPressed", 1, value)
|
||||||
if not cancel then
|
if not cancel then
|
||||||
PlaySound("igMainMenuOptionCheckBoxOn")
|
PlaySound("igMainMenuOptionCheckBoxOn")
|
||||||
HideButton(self)
|
HideButton(self)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function EditBox_OnReceiveDrag(frame)
|
local function EditBox_OnReceiveDrag()
|
||||||
local self = frame.obj
|
if not GetCursorInfo then return end
|
||||||
|
local self = this.obj
|
||||||
local type, id, info = GetCursorInfo()
|
local type, id, info = GetCursorInfo()
|
||||||
if type == "item" then
|
if type == "item" then
|
||||||
self:SetText(info)
|
self:SetText(info)
|
||||||
self:Fire("OnEnterPressed", info)
|
self:Fire("OnEnterPressed", 1, info)
|
||||||
ClearCursor()
|
ClearCursor()
|
||||||
elseif type == "spell" then
|
elseif type == "spell" then
|
||||||
local name = GetSpellInfo(id, info)
|
local spell, rank = GetSpellName(id, info)
|
||||||
self:SetText(name)
|
if rank ~= "" then spell = spell.."("..rank..")" end
|
||||||
self:Fire("OnEnterPressed", name)
|
self:SetText(spell)
|
||||||
|
self:Fire("OnEnterPressed", 1, spell)
|
||||||
ClearCursor()
|
ClearCursor()
|
||||||
elseif type == "macro" then
|
elseif type == "macro" then
|
||||||
local name = GetMacroInfo(id)
|
local name = GetMacroInfo(id)
|
||||||
self:SetText(name)
|
self:SetText(name)
|
||||||
self:Fire("OnEnterPressed", name)
|
self:Fire("OnEnterPressed", 1, name)
|
||||||
ClearCursor()
|
ClearCursor()
|
||||||
end
|
end
|
||||||
HideButton(self)
|
HideButton(self)
|
||||||
AceGUI:ClearFocus()
|
AceGUI:ClearFocus()
|
||||||
end
|
end
|
||||||
|
|
||||||
local function EditBox_OnTextChanged(frame)
|
|
||||||
local self = frame.obj
|
local function EditBox_OnTextChanged()
|
||||||
local value = frame:GetText()
|
local self = this.obj
|
||||||
|
local value = this:GetText()
|
||||||
if tostring(value) ~= tostring(self.lasttext) then
|
if tostring(value) ~= tostring(self.lasttext) then
|
||||||
self:Fire("OnTextChanged", value)
|
self:Fire("OnTextChanged", 1, value)
|
||||||
self.lasttext = value
|
self.lasttext = value
|
||||||
ShowButton(self)
|
ShowButton(self)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function EditBox_OnFocusGained(frame)
|
local function EditBox_OnFocusGained()
|
||||||
AceGUI:SetFocus(frame.obj)
|
this.hasfocus = true
|
||||||
|
AceGUI:SetFocus(this.obj)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function Button_OnClick(frame)
|
local function EditBox_OnFocusLost()
|
||||||
local editbox = frame.obj.editbox
|
this.hasfocus = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Button_OnClick()
|
||||||
|
local editbox = this.obj.editbox
|
||||||
editbox:ClearFocus()
|
editbox:ClearFocus()
|
||||||
EditBox_OnEnterPressed(editbox)
|
this = editbox -- Ace3v: this is kinda hack here
|
||||||
|
EditBox_OnEnterPressed()
|
||||||
end
|
end
|
||||||
|
|
||||||
--[[-----------------------------------------------------------------------------
|
--[[-----------------------------------------------------------------------------
|
||||||
@@ -242,7 +256,7 @@ local methods = {
|
|||||||
["SetText"] = function(self, text)
|
["SetText"] = function(self, text)
|
||||||
self.lasttext = text or ""
|
self.lasttext = text or ""
|
||||||
self.editbox:SetText(text or "")
|
self.editbox:SetText(text or "")
|
||||||
self.editbox:SetCursorPosition(0)
|
self.editbox:HighlightText(0)
|
||||||
HideButton(self)
|
HideButton(self)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
@@ -313,10 +327,11 @@ local function Constructor()
|
|||||||
editbox:SetScript("OnReceiveDrag", EditBox_OnReceiveDrag)
|
editbox:SetScript("OnReceiveDrag", EditBox_OnReceiveDrag)
|
||||||
editbox:SetScript("OnMouseDown", EditBox_OnReceiveDrag)
|
editbox:SetScript("OnMouseDown", EditBox_OnReceiveDrag)
|
||||||
editbox:SetScript("OnEditFocusGained", EditBox_OnFocusGained)
|
editbox:SetScript("OnEditFocusGained", EditBox_OnFocusGained)
|
||||||
|
editbox:SetScript("OnEditFocusLost", EditBox_OnFocusLost)
|
||||||
editbox:SetTextInsets(0, 0, 3, 3)
|
editbox:SetTextInsets(0, 0, 3, 3)
|
||||||
editbox:SetMaxLetters(256)
|
editbox:SetMaxLetters(256)
|
||||||
editbox:SetPoint("BOTTOMLEFT", 6, 0)
|
editbox:SetPoint("BOTTOMLEFT", 6, 0)
|
||||||
editbox:SetPoint("BOTTOMRIGHT")
|
editbox:SetPoint("BOTTOMRIGHT", 0, 0)
|
||||||
editbox:SetHeight(19)
|
editbox:SetHeight(19)
|
||||||
|
|
||||||
local label = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
|
local label = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ local function Constructor()
|
|||||||
local label = frame:CreateFontString(nil, "BACKGROUND", "GameFontNormal")
|
local label = frame:CreateFontString(nil, "BACKGROUND", "GameFontNormal")
|
||||||
label:SetPoint("TOP",0,0)
|
label:SetPoint("TOP",0,0)
|
||||||
label:SetPoint("BOTTOM",0,0)
|
label:SetPoint("BOTTOM",0,0)
|
||||||
label:SetJustifyH("CENTER", 0, 0)
|
label:SetJustifyH("CENTER")
|
||||||
|
|
||||||
local left = frame:CreateTexture(nil, "BACKGROUND")
|
local left = frame:CreateTexture(nil, "BACKGROUND")
|
||||||
left:SetHeight(8)
|
left:SetHeight(8)
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
|||||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||||
|
|
||||||
-- Lua APIs
|
-- Lua APIs
|
||||||
local select, pairs, print, unpack = select, pairs, print, unpack
|
local pairs, print = pairs, print
|
||||||
|
|
||||||
-- WoW APIs
|
-- WoW APIs
|
||||||
local CreateFrame, UIParent = CreateFrame, UIParent
|
local CreateFrame, UIParent = CreateFrame, UIParent
|
||||||
@@ -14,16 +14,16 @@ local CreateFrame, UIParent = CreateFrame, UIParent
|
|||||||
--[[-----------------------------------------------------------------------------
|
--[[-----------------------------------------------------------------------------
|
||||||
Scripts
|
Scripts
|
||||||
-------------------------------------------------------------------------------]]
|
-------------------------------------------------------------------------------]]
|
||||||
local function Control_OnEnter(frame)
|
local function Control_OnEnter()
|
||||||
frame.obj:Fire("OnEnter")
|
this.obj:Fire("OnEnter")
|
||||||
end
|
end
|
||||||
|
|
||||||
local function Control_OnLeave(frame)
|
local function Control_OnLeave()
|
||||||
frame.obj:Fire("OnLeave")
|
this.obj:Fire("OnLeave")
|
||||||
end
|
end
|
||||||
|
|
||||||
local function Button_OnClick(frame, button)
|
local function Button_OnClick()
|
||||||
frame.obj:Fire("OnClick", button)
|
this.obj:Fire("OnClick", 1, arg1)
|
||||||
AceGUI:ClearFocus()
|
AceGUI:ClearFocus()
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -53,14 +53,13 @@ local methods = {
|
|||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
|
||||||
["SetImage"] = function(self, path, ...)
|
["SetImage"] = function(self, path, a1,a2,a3,a4,a5,a6,a7,a8)
|
||||||
local image = self.image
|
local image = self.image
|
||||||
image:SetTexture(path)
|
image:SetTexture(path)
|
||||||
|
|
||||||
if image:GetTexture() then
|
if image:GetTexture() then
|
||||||
local n = select("#", arg)
|
if a4 or a8 then
|
||||||
if n == 4 or n == 8 then
|
image:SetTexCoord(a1,a2,a3,a4,a5,a6,a7,a8)
|
||||||
image:SetTexCoord(unpack(arg))
|
|
||||||
else
|
else
|
||||||
image:SetTexCoord(0, 1, 0, 1)
|
image:SetTexCoord(0, 1, 0, 1)
|
||||||
end
|
end
|
||||||
@@ -132,7 +131,7 @@ local function Constructor()
|
|||||||
widget[method] = func
|
widget[method] = func
|
||||||
end
|
end
|
||||||
|
|
||||||
widget.SetText = function(self, ...) print("AceGUI-3.0-Icon: SetText is deprecated! Use SetLabel instead!"); self:SetLabel(unpack(arg)) end
|
widget.SetText = function(self,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) print("AceGUI-3.0-Icon: SetText is deprecated! Use SetLabel instead!"); self:SetLabel(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) end
|
||||||
|
|
||||||
return AceGUI:RegisterAsWidget(widget)
|
return AceGUI:RegisterAsWidget(widget)
|
||||||
end
|
end
|
||||||
|
|||||||
+13
-14
@@ -1,12 +1,12 @@
|
|||||||
--[[-----------------------------------------------------------------------------
|
--[[-----------------------------------------------------------------------------
|
||||||
InteractiveLabel Widget
|
InteractiveLabel Widget
|
||||||
-------------------------------------------------------------------------------]]
|
-------------------------------------------------------------------------------]]
|
||||||
local Type, Version = "InteractiveLabel", 21
|
local Type, Version = "InteractiveLabel", 20
|
||||||
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
||||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||||
|
|
||||||
-- Lua APIs
|
-- Lua APIs
|
||||||
local select, pairs, unpack = select, pairs, unpack
|
local pairs = pairs
|
||||||
|
|
||||||
-- WoW APIs
|
-- WoW APIs
|
||||||
local CreateFrame, UIParent = CreateFrame, UIParent
|
local CreateFrame, UIParent = CreateFrame, UIParent
|
||||||
@@ -18,16 +18,16 @@ local CreateFrame, UIParent = CreateFrame, UIParent
|
|||||||
--[[-----------------------------------------------------------------------------
|
--[[-----------------------------------------------------------------------------
|
||||||
Scripts
|
Scripts
|
||||||
-------------------------------------------------------------------------------]]
|
-------------------------------------------------------------------------------]]
|
||||||
local function Control_OnEnter(frame)
|
local function Control_OnEnter()
|
||||||
frame.obj:Fire("OnEnter")
|
this.obj:Fire("OnEnter")
|
||||||
end
|
end
|
||||||
|
|
||||||
local function Control_OnLeave(frame)
|
local function Control_OnLeave()
|
||||||
frame.obj:Fire("OnLeave")
|
this.obj:Fire("OnLeave")
|
||||||
end
|
end
|
||||||
|
|
||||||
local function Label_OnClick(frame, button)
|
local function Label_OnClick()
|
||||||
frame.obj:Fire("OnClick", button)
|
this.obj:Fire("OnClick", 1, arg1)
|
||||||
AceGUI:ClearFocus()
|
AceGUI:ClearFocus()
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -44,14 +44,13 @@ local methods = {
|
|||||||
|
|
||||||
-- ["OnRelease"] = nil,
|
-- ["OnRelease"] = nil,
|
||||||
|
|
||||||
["SetHighlight"] = function(self, ...)
|
["SetHighlight"] = function(self, a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||||
self.highlight:SetTexture(unpack(arg))
|
self.highlight:SetTexture(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
["SetHighlightTexCoord"] = function(self, ...)
|
["SetHighlightTexCoord"] = function(self, a1,a2,a3,a4,a5,a6,a7,a8)
|
||||||
local c = select("#", arg)
|
if a4 or a8 then
|
||||||
if c == 4 or c == 8 then
|
self.highlight:SetTexCoord(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||||
self.highlight:SetTexCoord(unpack(arg))
|
|
||||||
else
|
else
|
||||||
self.highlight:SetTexCoord(0, 1, 0, 1)
|
self.highlight:SetTexCoord(0, 1, 0, 1)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -21,44 +21,32 @@ local CreateFrame, UIParent = CreateFrame, UIParent
|
|||||||
Scripts
|
Scripts
|
||||||
-------------------------------------------------------------------------------]]
|
-------------------------------------------------------------------------------]]
|
||||||
|
|
||||||
local function Control_OnEnter(frame)
|
local function Control_OnEnter()
|
||||||
frame.obj:Fire("OnEnter")
|
this.obj:Fire("OnEnter")
|
||||||
end
|
end
|
||||||
|
|
||||||
local function Control_OnLeave(frame)
|
local function Control_OnLeave()
|
||||||
frame.obj:Fire("OnLeave")
|
this.obj:Fire("OnLeave")
|
||||||
end
|
end
|
||||||
|
|
||||||
local function Keybinding_OnClick(frame, button)
|
local function Keybinding_OnHide()
|
||||||
if button == "LeftButton" or button == "RightButton" then
|
local self = this.obj
|
||||||
local self = frame.obj
|
this:EnableKeyboard(false)
|
||||||
if self.waitingForKey then
|
this:EnableMouseWheel(false)
|
||||||
frame:EnableKeyboard(false)
|
|
||||||
frame:EnableMouseWheel(false)
|
|
||||||
self.msgframe:Hide()
|
self.msgframe:Hide()
|
||||||
frame:UnlockHighlight()
|
this:UnlockHighlight()
|
||||||
self.waitingForKey = nil
|
self.waitingForKey = nil
|
||||||
else
|
|
||||||
frame:EnableKeyboard(true)
|
|
||||||
frame:EnableMouseWheel(true)
|
|
||||||
self.msgframe:Show()
|
|
||||||
frame:LockHighlight()
|
|
||||||
self.waitingForKey = true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
AceGUI:ClearFocus()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local ignoreKeys = {
|
local ignoreKeys = {
|
||||||
["BUTTON1"] = true, ["BUTTON2"] = true,
|
["BUTTON1"] = true, ["BUTTON2"] = true,
|
||||||
["UNKNOWN"] = true,
|
["UNKNOWN"] = true,
|
||||||
["LSHIFT"] = true, ["LCTRL"] = true, ["LALT"] = true,
|
["SHIFT"] = true, ["CTRL"] = true, ["ALT"] = true,
|
||||||
["RSHIFT"] = true, ["RCTRL"] = true, ["RALT"] = true,
|
|
||||||
}
|
}
|
||||||
local function Keybinding_OnKeyDown(frame, key)
|
local function Keybinding_OnKeyDown()
|
||||||
local self = frame.obj
|
local self = this.obj
|
||||||
if self.waitingForKey then
|
if self.waitingForKey then
|
||||||
local keyPressed = key
|
local keyPressed = arg1
|
||||||
if keyPressed == "ESCAPE" then
|
if keyPressed == "ESCAPE" then
|
||||||
keyPressed = ""
|
keyPressed = ""
|
||||||
else
|
else
|
||||||
@@ -74,40 +62,58 @@ local function Keybinding_OnKeyDown(frame, key)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
frame:EnableKeyboard(false)
|
this:EnableKeyboard(false)
|
||||||
frame:EnableMouseWheel(false)
|
this:EnableMouseWheel(false)
|
||||||
self.msgframe:Hide()
|
self.msgframe:Hide()
|
||||||
frame:UnlockHighlight()
|
this:UnlockHighlight()
|
||||||
self.waitingForKey = nil
|
self.waitingForKey = nil
|
||||||
|
|
||||||
if not self.disabled then
|
if not self.disabled then
|
||||||
self:SetKey(keyPressed)
|
self:SetKey(keyPressed)
|
||||||
self:Fire("OnKeyChanged", keyPressed)
|
self:Fire("OnKeyChanged", 1, keyPressed)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function Keybinding_OnMouseDown(frame, button)
|
local function Keybinding_OnMouseDown()
|
||||||
if button == "LeftButton" or button == "RightButton" then
|
getglobal(this:GetName().."Left"):SetTexture("Interface\\Buttons\\UI-Panel-Button-Down");
|
||||||
return
|
getglobal(this:GetName().."Middle"):SetTexture("Interface\\Buttons\\UI-Panel-Button-Down");
|
||||||
elseif button == "MiddleButton" then
|
getglobal(this:GetName().."Right"):SetTexture("Interface\\Buttons\\UI-Panel-Button-Down");
|
||||||
button = "BUTTON3"
|
|
||||||
elseif button == "Button4" then
|
|
||||||
button = "BUTTON4"
|
|
||||||
elseif button == "Button5" then
|
|
||||||
button = "BUTTON5"
|
|
||||||
end
|
|
||||||
Keybinding_OnKeyDown(frame, button)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function Keybinding_OnMouseWheel(frame, direction)
|
local function Keybinding_OnMouseUp()
|
||||||
local button
|
getglobal(this:GetName().."Left"):SetTexture("Interface\\Buttons\\UI-Panel-Button-Up");
|
||||||
if direction >= 0 then
|
getglobal(this:GetName().."Middle"):SetTexture("Interface\\Buttons\\UI-Panel-Button-Up");
|
||||||
button = "MOUSEWHEELUP"
|
getglobal(this:GetName().."Right"):SetTexture("Interface\\Buttons\\UI-Panel-Button-Up");
|
||||||
|
local self = this.obj
|
||||||
|
if MouseIsOver(this) and not self.disabled then
|
||||||
|
if self.waitingForKey then
|
||||||
|
if arg1 ~= "LeftButton" and arg1 ~= "RightButton" then
|
||||||
|
Keybinding_OnKeyDown()
|
||||||
|
end
|
||||||
|
this:EnableKeyboard(false)
|
||||||
|
this:EnableMouseWheel(false)
|
||||||
|
self.msgframe:Hide()
|
||||||
|
this:UnlockHighlight()
|
||||||
|
self.waitingForKey = nil
|
||||||
else
|
else
|
||||||
button = "MOUSEWHEELDOWN"
|
this:EnableKeyboard(true)
|
||||||
|
this:EnableMouseWheel(true)
|
||||||
|
self.msgframe:Show()
|
||||||
|
this:LockHighlight()
|
||||||
|
self.waitingForKey = true
|
||||||
end
|
end
|
||||||
Keybinding_OnKeyDown(frame, button)
|
end
|
||||||
|
AceGUI:ClearFocus()
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Keybinding_OnMouseWheel()
|
||||||
|
if arg1 >= 0 then
|
||||||
|
arg1 = "MOUSEWHEELUP"
|
||||||
|
else
|
||||||
|
arg1 = "MOUSEWHEELDOWN"
|
||||||
|
end
|
||||||
|
Keybinding_OnKeyDown()
|
||||||
end
|
end
|
||||||
|
|
||||||
--[[-----------------------------------------------------------------------------
|
--[[-----------------------------------------------------------------------------
|
||||||
@@ -141,10 +147,10 @@ local methods = {
|
|||||||
["SetKey"] = function(self, key)
|
["SetKey"] = function(self, key)
|
||||||
if (key or "") == "" then
|
if (key or "") == "" then
|
||||||
self.button:SetText(NOT_BOUND)
|
self.button:SetText(NOT_BOUND)
|
||||||
self.button:SetNormalFontObject("GameFontNormal")
|
self.text:SetFontObject("GameFontNormal")
|
||||||
else
|
else
|
||||||
self.button:SetText(key)
|
self.button:SetText(key)
|
||||||
self.button:SetNormalFontObject("GameFontHighlight")
|
self.text:SetFontObject("GameFontHighlight")
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
|
||||||
@@ -179,28 +185,31 @@ local ControlBackdrop = {
|
|||||||
insets = { left = 3, right = 3, top = 3, bottom = 3 }
|
insets = { left = 3, right = 3, top = 3, bottom = 3 }
|
||||||
}
|
}
|
||||||
|
|
||||||
local function keybindingMsgFixWidth(frame)
|
local function keybindingMsgFixWidth()
|
||||||
frame:SetWidth(frame.msg:GetWidth() + 10)
|
this:SetWidth(this.msg:GetWidth() + 10)
|
||||||
frame:SetScript("OnUpdate", nil)
|
this:SetScript("OnUpdate", nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function Constructor()
|
local function Constructor()
|
||||||
local name = "AceGUI30KeybindingButton" .. AceGUI:GetNextWidgetNum(Type)
|
local name = "AceGUI30KeybindingButton" .. AceGUI:GetNextWidgetNum(Type)
|
||||||
|
|
||||||
local frame = CreateFrame("Frame", nil, UIParent)
|
local frame = CreateFrame("Frame", nil, UIParent)
|
||||||
local button = CreateFrame("Button", name, frame, "UIPanelButtonTemplate")
|
local button = CreateFrame("Button", name, frame, "UIPanelButtonTemplate2")
|
||||||
|
|
||||||
button:EnableMouse(true)
|
button:EnableMouse(true)
|
||||||
button:EnableMouseWheel(false)
|
button:EnableMouseWheel(false)
|
||||||
button:RegisterForClicks("AnyDown")
|
|
||||||
button:SetScript("OnEnter", Control_OnEnter)
|
button:SetScript("OnEnter", Control_OnEnter)
|
||||||
button:SetScript("OnLeave", Control_OnLeave)
|
button:SetScript("OnLeave", Control_OnLeave)
|
||||||
button:SetScript("OnClick", Keybinding_OnClick)
|
|
||||||
button:SetScript("OnKeyDown", Keybinding_OnKeyDown)
|
button:SetScript("OnKeyDown", Keybinding_OnKeyDown)
|
||||||
|
button:RegisterForClicks("AnyDown","AnyUp")
|
||||||
|
-- Ace3v: RegisterForClicks means OnClick will not be triggered, so use OnKeyDown and OnKeyUp
|
||||||
button:SetScript("OnMouseDown", Keybinding_OnMouseDown)
|
button:SetScript("OnMouseDown", Keybinding_OnMouseDown)
|
||||||
|
button:SetScript("OnMouseUp", Keybinding_OnMouseUp)
|
||||||
button:SetScript("OnMouseWheel", Keybinding_OnMouseWheel)
|
button:SetScript("OnMouseWheel", Keybinding_OnMouseWheel)
|
||||||
button:SetPoint("BOTTOMLEFT")
|
button:SetScript("OnHide", Keybinding_OnHide)
|
||||||
button:SetPoint("BOTTOMRIGHT")
|
button:SetPoint("BOTTOMLEFT",0,0)
|
||||||
|
button:SetPoint("BOTTOMRIGHT",0,0)
|
||||||
button:SetHeight(24)
|
button:SetHeight(24)
|
||||||
button:EnableKeyboard(false)
|
button:EnableKeyboard(false)
|
||||||
|
|
||||||
@@ -209,8 +218,8 @@ local function Constructor()
|
|||||||
text:SetPoint("RIGHT", -7, 0)
|
text:SetPoint("RIGHT", -7, 0)
|
||||||
|
|
||||||
local label = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
|
local label = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
|
||||||
label:SetPoint("TOPLEFT")
|
label:SetPoint("TOPLEFT",0,0)
|
||||||
label:SetPoint("TOPRIGHT")
|
label:SetPoint("TOPRIGHT",0,0)
|
||||||
label:SetJustifyH("CENTER")
|
label:SetJustifyH("CENTER")
|
||||||
label:SetHeight(18)
|
label:SetHeight(18)
|
||||||
|
|
||||||
@@ -236,7 +245,8 @@ local function Constructor()
|
|||||||
msgframe = msgframe,
|
msgframe = msgframe,
|
||||||
frame = frame,
|
frame = frame,
|
||||||
alignoffset = 30,
|
alignoffset = 30,
|
||||||
type = Type
|
type = Type,
|
||||||
|
text = text
|
||||||
}
|
}
|
||||||
for method, func in pairs(methods) do
|
for method, func in pairs(methods) do
|
||||||
widget[method] = func
|
widget[method] = func
|
||||||
|
|||||||
@@ -2,12 +2,12 @@
|
|||||||
Label Widget
|
Label Widget
|
||||||
Displays text and optionally an icon.
|
Displays text and optionally an icon.
|
||||||
-------------------------------------------------------------------------------]]
|
-------------------------------------------------------------------------------]]
|
||||||
local Type, Version = "Label", 24
|
local Type, Version = "Label", 23
|
||||||
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
||||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||||
|
|
||||||
-- Lua APIs
|
-- Lua APIs
|
||||||
local max, select, pairs, unpack = math.max, select, pairs, unpack
|
local max, pairs = math.max, pairs
|
||||||
|
|
||||||
-- WoW APIs
|
-- WoW APIs
|
||||||
local CreateFrame, UIParent = CreateFrame, UIParent
|
local CreateFrame, UIParent = CreateFrame, UIParent
|
||||||
@@ -35,14 +35,14 @@ local function UpdateImageAnchor(self)
|
|||||||
local imagewidth = image:GetWidth()
|
local imagewidth = image:GetWidth()
|
||||||
if (width - imagewidth) < 200 or (label:GetText() or "") == "" then
|
if (width - imagewidth) < 200 or (label:GetText() or "") == "" then
|
||||||
-- image goes on top centered when less than 200 width for the text, or if there is no text
|
-- image goes on top centered when less than 200 width for the text, or if there is no text
|
||||||
image:SetPoint("TOP")
|
image:SetPoint("TOP",0,0)
|
||||||
label:SetPoint("TOP", image, "BOTTOM")
|
label:SetPoint("TOP", image, "BOTTOM")
|
||||||
label:SetPoint("LEFT")
|
label:SetPoint("LEFT",0,0)
|
||||||
label:SetWidth(width)
|
label:SetWidth(width)
|
||||||
height = image:GetHeight() + label:GetHeight()
|
height = image:GetHeight() + label:GetHeight()
|
||||||
else
|
else
|
||||||
-- image on the left
|
-- image on the left
|
||||||
image:SetPoint("TOPLEFT")
|
image:SetPoint("TOPLEFT",0,0)
|
||||||
if image:GetHeight() > label:GetHeight() then
|
if image:GetHeight() > label:GetHeight() then
|
||||||
label:SetPoint("LEFT", image, "RIGHT", 4, 0)
|
label:SetPoint("LEFT", image, "RIGHT", 4, 0)
|
||||||
else
|
else
|
||||||
@@ -53,7 +53,7 @@ local function UpdateImageAnchor(self)
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
-- no image shown
|
-- no image shown
|
||||||
label:SetPoint("TOPLEFT")
|
label:SetPoint("TOPLEFT",0,0)
|
||||||
label:SetWidth(width)
|
label:SetWidth(width)
|
||||||
height = label:GetHeight()
|
height = label:GetHeight()
|
||||||
end
|
end
|
||||||
@@ -78,8 +78,6 @@ local methods = {
|
|||||||
self:SetImageSize(16, 16)
|
self:SetImageSize(16, 16)
|
||||||
self:SetColor()
|
self:SetColor()
|
||||||
self:SetFontObject()
|
self:SetFontObject()
|
||||||
self:SetJustifyH("LEFT")
|
|
||||||
self:SetJustifyV("TOP")
|
|
||||||
|
|
||||||
-- reset the flag
|
-- reset the flag
|
||||||
self.resizing = nil
|
self.resizing = nil
|
||||||
@@ -105,15 +103,14 @@ local methods = {
|
|||||||
self.label:SetVertexColor(r, g, b)
|
self.label:SetVertexColor(r, g, b)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
["SetImage"] = function(self, path, ...)
|
["SetImage"] = function(self, path, a1,a2,a3,a4,a5,a6,a7,a8)
|
||||||
local image = self.image
|
local image = self.image
|
||||||
image:SetTexture(path)
|
image:SetTexture(path)
|
||||||
|
|
||||||
if image:GetTexture() then
|
if image:GetTexture() then
|
||||||
self.imageshown = true
|
self.imageshown = true
|
||||||
local n = select("#", arg)
|
if a4 or a8 then
|
||||||
if n == 4 or n == 8 then
|
image:SetTexCoord(a1,a2,a3,a4,a5,a6,a7,a8)
|
||||||
image:SetTexCoord(unpack(arg))
|
|
||||||
else
|
else
|
||||||
image:SetTexCoord(0, 1, 0, 1)
|
image:SetTexCoord(0, 1, 0, 1)
|
||||||
end
|
end
|
||||||
@@ -136,14 +133,6 @@ local methods = {
|
|||||||
self.image:SetHeight(height)
|
self.image:SetHeight(height)
|
||||||
UpdateImageAnchor(self)
|
UpdateImageAnchor(self)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
["SetJustifyH"] = function(self, justifyH)
|
|
||||||
self.label:SetJustifyH(justifyH)
|
|
||||||
end,
|
|
||||||
|
|
||||||
["SetJustifyV"] = function(self, justifyV)
|
|
||||||
self.label:SetJustifyV(justifyV)
|
|
||||||
end,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
--[[-----------------------------------------------------------------------------
|
--[[-----------------------------------------------------------------------------
|
||||||
@@ -154,6 +143,9 @@ local function Constructor()
|
|||||||
frame:Hide()
|
frame:Hide()
|
||||||
|
|
||||||
local label = frame:CreateFontString(nil, "BACKGROUND", "GameFontHighlightSmall")
|
local label = frame:CreateFontString(nil, "BACKGROUND", "GameFontHighlightSmall")
|
||||||
|
label:SetJustifyH("LEFT")
|
||||||
|
label:SetJustifyV("TOP")
|
||||||
|
|
||||||
local image = frame:CreateTexture(nil, "BACKGROUND")
|
local image = frame:CreateTexture(nil, "BACKGROUND")
|
||||||
|
|
||||||
-- create widget
|
-- create widget
|
||||||
|
|||||||
+88
-66
@@ -2,13 +2,17 @@ local Type, Version = "MultiLineEditBox", 28
|
|||||||
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
||||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||||
|
|
||||||
|
local AceCore = LibStub("AceCore-3.0")
|
||||||
|
local hooksecurefunc = AceCore.hooksecurefunc
|
||||||
|
|
||||||
-- Lua APIs
|
-- Lua APIs
|
||||||
local pairs, unpack = pairs, unpack
|
local strfmt = string.format
|
||||||
|
local pairs = pairs
|
||||||
|
|
||||||
-- WoW APIs
|
-- WoW APIs
|
||||||
local GetCursorInfo, GetSpellInfo, ClearCursor = GetCursorInfo, GetSpellInfo, ClearCursor
|
local GetCursorInfo, GetSpellInfo, ClearCursor = GetCursorInfo, GetSpellInfo, ClearCursor
|
||||||
local CreateFrame, UIParent = CreateFrame, UIParent
|
local CreateFrame, UIParent = CreateFrame, UIParent
|
||||||
local _G = _G
|
local _G = AceCore._G
|
||||||
|
|
||||||
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
|
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
|
||||||
-- List them here for Mikk's FindGlobals script
|
-- List them here for Mikk's FindGlobals script
|
||||||
@@ -17,7 +21,6 @@ local _G = _G
|
|||||||
--[[-----------------------------------------------------------------------------
|
--[[-----------------------------------------------------------------------------
|
||||||
Support functions
|
Support functions
|
||||||
-------------------------------------------------------------------------------]]
|
-------------------------------------------------------------------------------]]
|
||||||
|
|
||||||
if not AceGUIMultiLineEditBoxInsertLink then
|
if not AceGUIMultiLineEditBoxInsertLink then
|
||||||
-- upgradeable hook
|
-- upgradeable hook
|
||||||
hooksecurefunc("BankFrameItemButtonGeneric_OnClick",
|
hooksecurefunc("BankFrameItemButtonGeneric_OnClick",
|
||||||
@@ -112,15 +115,14 @@ end
|
|||||||
|
|
||||||
function _G.AceGUIMultiLineEditBoxInsertLink(text)
|
function _G.AceGUIMultiLineEditBoxInsertLink(text)
|
||||||
for i = 1, AceGUI:GetWidgetCount(Type) do
|
for i = 1, AceGUI:GetWidgetCount(Type) do
|
||||||
local editbox = _G[format("MultiLineEditBox%uEdit", i)]
|
local editbox = _G[strfmt("MultiLineEditBox%uEdit",i)]
|
||||||
if editbox and editbox:IsVisible() and editbox:HasFocus() then
|
if editbox and editbox:IsVisible() and editbox.hasfocus then
|
||||||
editbox:Insert(text)
|
editbox:Insert(text)
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
local function Layout(self)
|
local function Layout(self)
|
||||||
self:SetHeight(self.numlines * 14 + (self.disablebutton and 19 or 41) + self.labelHeight)
|
self:SetHeight(self.numlines * 14 + (self.disablebutton and 19 or 41) + self.labelHeight)
|
||||||
|
|
||||||
@@ -142,104 +144,122 @@ end
|
|||||||
--[[-----------------------------------------------------------------------------
|
--[[-----------------------------------------------------------------------------
|
||||||
Scripts
|
Scripts
|
||||||
-------------------------------------------------------------------------------]]
|
-------------------------------------------------------------------------------]]
|
||||||
local function OnClick(self) -- Button
|
local function OnClick() -- Button
|
||||||
self = self.obj
|
local self = this.obj
|
||||||
self.editBox:ClearFocus()
|
self.editBox:ClearFocus()
|
||||||
if not self:Fire("OnEnterPressed", self.editBox:GetText()) then
|
if not self:Fire("OnEnterPressed", 1, self.editBox:GetText()) then
|
||||||
self.button:Disable()
|
self.button:Disable()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function OnCursorChanged(self, _, y, _, cursorHeight) -- EditBox
|
local function OnCursorChanged() -- EditBox
|
||||||
self, y = self.obj.scrollFrame, -y
|
|
||||||
|
local self, y = this.obj.scrollFrame, -arg2
|
||||||
local offset = self:GetVerticalScroll()
|
local offset = self:GetVerticalScroll()
|
||||||
if y < offset then
|
if y < offset then
|
||||||
self:SetVerticalScroll(y)
|
self:SetVerticalScroll(y)
|
||||||
else
|
else
|
||||||
y = y + cursorHeight - self:GetHeight()
|
y = y + arg4 - self:GetHeight()
|
||||||
if y > offset then
|
if y > offset then
|
||||||
self:SetVerticalScroll(y)
|
self:SetVerticalScroll(y)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function OnEditFocusLost(self) -- EditBox
|
local function OnEditFocusLost() -- EditBox
|
||||||
self:HighlightText(0, 0)
|
this.hasfocus = nil
|
||||||
self.obj:Fire("OnEditFocusLost")
|
this:HighlightText(0, 0)
|
||||||
|
this.obj:Fire("OnEditFocusLost")
|
||||||
end
|
end
|
||||||
|
|
||||||
local function OnEnter(self) -- EditBox / ScrollFrame
|
local function OnEnter() -- EditBox / ScrollFrame
|
||||||
self = self.obj
|
local self = this.obj
|
||||||
if not self.entered then
|
if not self.entered then
|
||||||
self.entered = true
|
self.entered = true
|
||||||
self:Fire("OnEnter")
|
self:Fire("OnEnter")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function OnLeave(self) -- EditBox / ScrollFrame
|
local function OnLeave() -- EditBox / ScrollFrame
|
||||||
self = self.obj
|
local self = this.obj
|
||||||
if self.entered then
|
if self.entered then
|
||||||
self.entered = nil
|
self.entered = nil
|
||||||
self:Fire("OnLeave")
|
self:Fire("OnLeave")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function OnMouseUp(self) -- ScrollFrame
|
local function OnMouseUp() -- ScrollFrame
|
||||||
self = self.obj.editBox
|
local self = this.obj.editBox
|
||||||
self:SetFocus()
|
self:SetFocus()
|
||||||
self:SetCursorPosition(self:GetNumLetters())
|
local n = self:GetNumLetters()
|
||||||
|
self:HighlightText(n,n)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function OnReceiveDrag(self) -- EditBox / ScrollFrame
|
local function OnReceiveDrag() -- EditBox / ScrollFrame
|
||||||
|
if not GetCursorInfo then return end
|
||||||
local type, id, info = GetCursorInfo()
|
local type, id, info = GetCursorInfo()
|
||||||
if type == "spell" then
|
if type == "spell" then
|
||||||
info = GetSpellInfo(id, info)
|
local spell, rank = GetSpellName(id, info)
|
||||||
|
if rank ~= "" then spell = spell.."("..rank..")" end
|
||||||
|
info = spell
|
||||||
elseif type ~= "item" then
|
elseif type ~= "item" then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
ClearCursor()
|
ClearCursor()
|
||||||
self = self.obj
|
local self = this.obj
|
||||||
local editBox = self.editBox
|
local editBox = self.editBox
|
||||||
if not editBox:HasFocus() then
|
if not this.hasfocus then
|
||||||
|
this.hasfocus = true
|
||||||
editBox:SetFocus()
|
editBox:SetFocus()
|
||||||
editBox:SetCursorPosition(editBox:GetNumLetters())
|
local n = editBox:GetNumLetters()
|
||||||
|
editBox:HighlightText(n,n)
|
||||||
end
|
end
|
||||||
editBox:Insert(info)
|
editBox:Insert(info)
|
||||||
self.button:Enable()
|
self.button:Enable()
|
||||||
end
|
end
|
||||||
|
|
||||||
local function OnSizeChanged(self, width, height) -- ScrollFrame
|
local function OnSizeChanged() -- ScrollFrame
|
||||||
self.obj.editBox:SetWidth(width)
|
this.obj.editBox:SetWidth(arg1)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function OnTextChanged(self, userInput) -- EditBox
|
local function OnTextChanged() -- EditBox
|
||||||
if userInput then
|
local self = this.obj
|
||||||
self = self.obj
|
local value = this:GetText()
|
||||||
self:Fire("OnTextChanged", self.editBox:GetText())
|
if tostring(value) ~= tostring(self.lasttext) then
|
||||||
|
self:Fire("OnTextChanged", 1, value)
|
||||||
|
self.lasttext = value
|
||||||
self.button:Enable()
|
self.button:Enable()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function OnTextSet(self) -- EditBox
|
local function OnTextSet() -- EditBox
|
||||||
self:HighlightText(0, 0)
|
this:HighlightText(0, 0)
|
||||||
self:SetCursorPosition(self:GetNumLetters())
|
this.obj.button:Disable()
|
||||||
self:SetCursorPosition(0)
|
|
||||||
self.obj.button:Disable()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function OnVerticalScroll(self, offset) -- ScrollFrame
|
local function OnVerticalScroll() -- ScrollFrame
|
||||||
local editBox = self.obj.editBox
|
local self = this.obj
|
||||||
editBox:SetHitRectInsets(0, 0, offset, editBox:GetHeight() - offset - self:GetHeight())
|
local editBox = self.editBox
|
||||||
|
editBox:SetHitRectInsets(0, 0, arg1, editBox:GetHeight() - arg1 - this:GetHeight())
|
||||||
|
|
||||||
|
self.scrollFrame:SetScrollChild(self.editBox)
|
||||||
|
self.editBox:SetPoint("TOPLEFT",0,arg1)
|
||||||
|
self.editBox:SetPoint("TOPRIGHT",0,arg1)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function OnShowFocus(frame)
|
local function OnShowFocus()
|
||||||
frame.obj.editBox:SetFocus()
|
this.obj.editBox:SetFocus()
|
||||||
frame:SetScript("OnShow", nil)
|
this:SetScript("OnShow", nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function OnEditFocusGained(frame)
|
local function OnEditFocusGained()
|
||||||
AceGUI:SetFocus(frame.obj)
|
this.hasfocus = true
|
||||||
frame.obj:Fire("OnEditFocusGained")
|
AceGUI:SetFocus(this.obj)
|
||||||
|
this.obj:Fire("OnEditFocusGained")
|
||||||
|
end
|
||||||
|
|
||||||
|
local function OnEscapePressed() -- EditBox
|
||||||
|
AceGUI:ClearFocus()
|
||||||
end
|
end
|
||||||
|
|
||||||
--[[-----------------------------------------------------------------------------
|
--[[-----------------------------------------------------------------------------
|
||||||
@@ -300,7 +320,10 @@ local methods = {
|
|||||||
end,
|
end,
|
||||||
|
|
||||||
["SetText"] = function(self, text)
|
["SetText"] = function(self, text)
|
||||||
self.editBox:SetText(text)
|
self.lasttext = text or ""
|
||||||
|
self.editBox:SetText(text or "")
|
||||||
|
self.editBox:HighlightText(0)
|
||||||
|
self.button:Disable()
|
||||||
end,
|
end,
|
||||||
|
|
||||||
["GetText"] = function(self)
|
["GetText"] = function(self)
|
||||||
@@ -336,16 +359,6 @@ local methods = {
|
|||||||
["HighlightText"] = function(self, from, to)
|
["HighlightText"] = function(self, from, to)
|
||||||
self.editBox:HighlightText(from, to)
|
self.editBox:HighlightText(from, to)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
["GetCursorPosition"] = function(self)
|
|
||||||
return self.editBox:GetCursorPosition()
|
|
||||||
end,
|
|
||||||
|
|
||||||
["SetCursorPosition"] = function(self, ...)
|
|
||||||
return self.editBox:SetCursorPosition(unpack(arg))
|
|
||||||
end,
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
--[[-----------------------------------------------------------------------------
|
--[[-----------------------------------------------------------------------------
|
||||||
@@ -370,7 +383,7 @@ local function Constructor()
|
|||||||
label:SetText(ACCEPT)
|
label:SetText(ACCEPT)
|
||||||
label:SetHeight(10)
|
label:SetHeight(10)
|
||||||
|
|
||||||
local button = CreateFrame("Button", format("%s%dButton", Type, widgetNum), frame, "UIPanelButtonTemplate")
|
local button = CreateFrame("Button", strfmt("%s%dButton", Type, widgetNum), frame, "UIPanelButtonTemplate")
|
||||||
button:SetPoint("BOTTOMLEFT", 0, 4)
|
button:SetPoint("BOTTOMLEFT", 0, 4)
|
||||||
button:SetHeight(22)
|
button:SetHeight(22)
|
||||||
button:SetWidth(label:GetStringWidth() + 24)
|
button:SetWidth(label:GetStringWidth() + 24)
|
||||||
@@ -389,7 +402,7 @@ local function Constructor()
|
|||||||
scrollBG:SetBackdropColor(0, 0, 0)
|
scrollBG:SetBackdropColor(0, 0, 0)
|
||||||
scrollBG:SetBackdropBorderColor(0.4, 0.4, 0.4)
|
scrollBG:SetBackdropBorderColor(0.4, 0.4, 0.4)
|
||||||
|
|
||||||
local scrollFrame = CreateFrame("ScrollFrame", format("%s%dScrollFrame", Type, widgetNum), frame, "UIPanelScrollFrameTemplate")
|
local scrollFrame = CreateFrame("ScrollFrame", strfmt("%s%dScrollFrame", Type, widgetNum), frame, "UIPanelScrollFrameTemplate")
|
||||||
|
|
||||||
local scrollBar = _G[scrollFrame:GetName() .. "ScrollBar"]
|
local scrollBar = _G[scrollFrame:GetName() .. "ScrollBar"]
|
||||||
scrollBar:ClearAllPoints()
|
scrollBar:ClearAllPoints()
|
||||||
@@ -407,19 +420,26 @@ local function Constructor()
|
|||||||
scrollFrame:SetScript("OnMouseUp", OnMouseUp)
|
scrollFrame:SetScript("OnMouseUp", OnMouseUp)
|
||||||
scrollFrame:SetScript("OnReceiveDrag", OnReceiveDrag)
|
scrollFrame:SetScript("OnReceiveDrag", OnReceiveDrag)
|
||||||
scrollFrame:SetScript("OnSizeChanged", OnSizeChanged)
|
scrollFrame:SetScript("OnSizeChanged", OnSizeChanged)
|
||||||
scrollFrame:HookScript("OnVerticalScroll", OnVerticalScroll)
|
local old = scrollFrame:GetScript("OnVerticalScroll");
|
||||||
|
if old then
|
||||||
|
scrollFrame:SetScript("OnVerticalScroll", function()
|
||||||
|
old()
|
||||||
|
OnVerticalScroll()
|
||||||
|
end)
|
||||||
|
else
|
||||||
|
scrollFrame:SetScript("OnVerticalScroll", OnVerticalScroll)
|
||||||
|
end
|
||||||
|
|
||||||
local editBox = CreateFrame("EditBox", format("%s%dEdit", Type, widgetNum), scrollFrame)
|
local editBox = CreateFrame("EditBox", strfmt("%s%dEdit", Type, widgetNum), scrollFrame)
|
||||||
editBox:SetAllPoints()
|
|
||||||
editBox:SetFontObject(ChatFontNormal)
|
editBox:SetFontObject(ChatFontNormal)
|
||||||
editBox:SetMultiLine(true)
|
editBox:SetMultiLine(true)
|
||||||
editBox:EnableMouse(true)
|
editBox:EnableMouse(true)
|
||||||
editBox:SetAutoFocus(false)
|
editBox:SetAutoFocus(false)
|
||||||
editBox:SetCountInvisibleLetters(false)
|
--editBox:SetCountInvisibleLetters(false)
|
||||||
editBox:SetScript("OnCursorChanged", OnCursorChanged)
|
editBox:SetScript("OnCursorChanged", OnCursorChanged)
|
||||||
editBox:SetScript("OnEditFocusLost", OnEditFocusLost)
|
editBox:SetScript("OnEditFocusLost", OnEditFocusLost)
|
||||||
editBox:SetScript("OnEnter", OnEnter)
|
editBox:SetScript("OnEnter", OnEnter)
|
||||||
editBox:SetScript("OnEscapePressed", editBox.ClearFocus)
|
editBox:SetScript("OnEscapePressed", OnEscapePressed)
|
||||||
editBox:SetScript("OnLeave", OnLeave)
|
editBox:SetScript("OnLeave", OnLeave)
|
||||||
editBox:SetScript("OnMouseDown", OnReceiveDrag)
|
editBox:SetScript("OnMouseDown", OnReceiveDrag)
|
||||||
editBox:SetScript("OnReceiveDrag", OnReceiveDrag)
|
editBox:SetScript("OnReceiveDrag", OnReceiveDrag)
|
||||||
@@ -427,8 +447,10 @@ local function Constructor()
|
|||||||
editBox:SetScript("OnTextSet", OnTextSet)
|
editBox:SetScript("OnTextSet", OnTextSet)
|
||||||
editBox:SetScript("OnEditFocusGained", OnEditFocusGained)
|
editBox:SetScript("OnEditFocusGained", OnEditFocusGained)
|
||||||
|
|
||||||
|
-- Ace3v: the orders are important here
|
||||||
scrollFrame:SetScrollChild(editBox)
|
scrollFrame:SetScrollChild(editBox)
|
||||||
|
editBox:SetPoint("TOPLEFT",0,0)
|
||||||
|
editBox:SetPoint("TOPRIGHT",0,0)
|
||||||
|
|
||||||
local widget = {
|
local widget = {
|
||||||
button = button,
|
button = button,
|
||||||
|
|||||||
@@ -2,13 +2,12 @@
|
|||||||
Slider Widget
|
Slider Widget
|
||||||
Graphical Slider, like, for Range values.
|
Graphical Slider, like, for Range values.
|
||||||
-------------------------------------------------------------------------------]]
|
-------------------------------------------------------------------------------]]
|
||||||
local Type, Version = "Slider", 22
|
local Type, Version = "Slider", 21
|
||||||
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
||||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||||
|
|
||||||
-- Lua APIs
|
-- Lua APIs
|
||||||
local min, max, floor = math.min, math.max, math.floor
|
local min, max, floor = math.min, math.max, math.floor
|
||||||
local gsub = string.gsub
|
|
||||||
local tonumber, pairs = tonumber, pairs
|
local tonumber, pairs = tonumber, pairs
|
||||||
|
|
||||||
-- WoW APIs
|
-- WoW APIs
|
||||||
@@ -25,7 +24,7 @@ Support functions
|
|||||||
local function UpdateText(self)
|
local function UpdateText(self)
|
||||||
local value = self.value or 0
|
local value = self.value or 0
|
||||||
if self.ispercent then
|
if self.ispercent then
|
||||||
self.editbox:SetText(format("%s%%", floor(value * 1000 + 0.5) / 10))
|
self.editbox:SetText(("%s%%"):format(floor(value * 1000 + 0.5) / 10))
|
||||||
else
|
else
|
||||||
self.editbox:SetText(floor(value * 100 + 0.5) / 100)
|
self.editbox:SetText(floor(value * 100 + 0.5) / 100)
|
||||||
end
|
end
|
||||||
@@ -34,8 +33,8 @@ end
|
|||||||
local function UpdateLabels(self)
|
local function UpdateLabels(self)
|
||||||
local min, max = (self.min or 0), (self.max or 100)
|
local min, max = (self.min or 0), (self.max or 100)
|
||||||
if self.ispercent then
|
if self.ispercent then
|
||||||
self.lowtext:SetText(format("%s%%", (min * 100)))
|
self.lowtext:SetFormattedText("%s%%", (min * 100))
|
||||||
self.hightext:SetText(format("%s%%", (max * 100)))
|
self.hightext:SetFormattedText("%s%%", (max * 100))
|
||||||
else
|
else
|
||||||
self.lowtext:SetText(min)
|
self.lowtext:SetText(min)
|
||||||
self.hightext:SetText(max)
|
self.hightext:SetText(max)
|
||||||
@@ -68,7 +67,7 @@ local function Slider_OnValueChanged()
|
|||||||
end
|
end
|
||||||
if newvalue ~= self.value and not self.disabled then
|
if newvalue ~= self.value and not self.disabled then
|
||||||
self.value = newvalue
|
self.value = newvalue
|
||||||
self:Fire("OnValueChanged", newvalue)
|
self:Fire("OnValueChanged", 1, newvalue)
|
||||||
end
|
end
|
||||||
if self.value then
|
if self.value then
|
||||||
UpdateText(self)
|
UpdateText(self)
|
||||||
@@ -78,7 +77,7 @@ end
|
|||||||
|
|
||||||
local function Slider_OnMouseUp()
|
local function Slider_OnMouseUp()
|
||||||
local self = this.obj
|
local self = this.obj
|
||||||
self:Fire("OnMouseUp", self.value)
|
self:Fire("OnMouseUp", 1, self.value)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function Slider_OnMouseWheel()
|
local function Slider_OnMouseWheel()
|
||||||
@@ -102,7 +101,7 @@ local function EditBox_OnEnterPressed()
|
|||||||
local self = this.obj
|
local self = this.obj
|
||||||
local value = this:GetText()
|
local value = this:GetText()
|
||||||
if self.ispercent then
|
if self.ispercent then
|
||||||
value = gsub(value, '%%', '')
|
value = value:gsub('%%', '')
|
||||||
value = tonumber(value) / 100
|
value = tonumber(value) / 100
|
||||||
else
|
else
|
||||||
value = tonumber(value)
|
value = tonumber(value)
|
||||||
@@ -111,7 +110,7 @@ local function EditBox_OnEnterPressed()
|
|||||||
if value then
|
if value then
|
||||||
PlaySound("igMainMenuOptionCheckBoxOn")
|
PlaySound("igMainMenuOptionCheckBoxOn")
|
||||||
self.slider:SetValue(value)
|
self.slider:SetValue(value)
|
||||||
self:Fire("OnMouseUp", value)
|
self:Fire("OnMouseUp", 1, value)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
<Script file="AceGUIContainer-Window.lua"/>
|
<Script file="AceGUIContainer-Window.lua"/>
|
||||||
<!-- Widgets -->
|
<!-- Widgets -->
|
||||||
<Script file="AceGUIWidget-Button.lua"/>
|
<Script file="AceGUIWidget-Button.lua"/>
|
||||||
<Script file="AceGUIWidget-Button-ElvUI.lua"/>
|
|
||||||
<Script file="AceGUIWidget-CheckBox.lua"/>
|
<Script file="AceGUIWidget-CheckBox.lua"/>
|
||||||
<Script file="AceGUIWidget-ColorPicker.lua"/>
|
<Script file="AceGUIWidget-ColorPicker.lua"/>
|
||||||
<Script file="AceGUIWidget-DropDown.lua"/>
|
<Script file="AceGUIWidget-DropDown.lua"/>
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
<Ui xmlns="http://www.blizzard.com/wow/ui/">
<Include file="AceGUI-3.0\AceGUI-3.0.xml"/>
<Include file="AceConfig-3.0\AceConfig-3.0.xml"/>
<Include file="AceDBOptions-3.0\AceDBOptions-3.0.xml"/>
<Include file="AceGUI-3.0-SharedMediaWidgets\widget.xml"/>
</Ui>
|
<Ui xmlns="http://www.blizzard.com/wow/ui/">
<Include file="AceGUI-3.0\AceGUI-3.0.xml"/>
<Include file="AceGUI-3.0\widgets\widgets.xml"/>
<Include file="AceConfig-3.0\AceConfig-3.0.xml"/>
<Include file="AceDBOptions-3.0\AceDBOptions-3.0.xml"/>
<Include file="AceGUI-3.0-SharedMediaWidgets\widget.xml"/>
</Ui>
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -14,11 +14,11 @@ local UnitName = UnitName;
|
|||||||
|
|
||||||
local DEFAULT_WIDTH = 890;
|
local DEFAULT_WIDTH = 890;
|
||||||
local DEFAULT_HEIGHT = 651;
|
local DEFAULT_HEIGHT = 651;
|
||||||
local AC = LibStub("AceConfig-3.0-ElvUI");
|
local AC = LibStub("AceConfig-3.0");
|
||||||
local ACD = LibStub("AceConfigDialog-3.0-ElvUI");
|
local ACD = LibStub("AceConfigDialog-3.0");
|
||||||
local ACR = LibStub("AceConfigRegistry-3.0-ElvUI");
|
local ACR = LibStub("AceConfigRegistry-3.0");
|
||||||
|
|
||||||
AC:RegisterOptionsTable("ElvUI", E.Options);
|
AC.RegisterOptionsTable(E, "ElvUI", E.Options);
|
||||||
ACD:SetDefaultSize("ElvUI", DEFAULT_WIDTH, DEFAULT_HEIGHT);
|
ACD:SetDefaultSize("ElvUI", DEFAULT_WIDTH, DEFAULT_HEIGHT);
|
||||||
|
|
||||||
function E:RefreshGUI()
|
function E:RefreshGUI()
|
||||||
|
|||||||
Reference in New Issue
Block a user